Skip to content

Commit dd66405

Browse files
implementing cbor message decoder following cloud utils definition
1 parent 965ed17 commit dd66405

File tree

4 files changed

+224
-319
lines changed

4 files changed

+224
-319
lines changed

src/cbor/IoTCloudMessageDecoder.cpp

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
This file is part of the ArduinoIoTCloud library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
/******************************************************************************
12+
INCLUDE
13+
******************************************************************************/
14+
15+
#include <Arduino.h>
16+
17+
#include "IoTCloudMessageDecoder.h"
18+
#include <AIoTC_Config.h>
19+
20+
/******************************************************************************
21+
PUBLIC MEMBER FUNCTIONS
22+
******************************************************************************/
23+
24+
/******************************************************************************
25+
PRIVATE MEMBER FUNCTIONS
26+
******************************************************************************/
27+
28+
static bool copyCBORStringToArray(CborValue * param, char * dest, size_t dest_size) {
29+
if (cbor_value_is_text_string(param)) {
30+
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
31+
if(_cbor_value_copy_string(param, dest, &dest_size, NULL) == CborNoError) {
32+
return true;
33+
}
34+
}
35+
36+
return false;
37+
}
38+
39+
// FIXME dest_size should be also returned, the copied byte array can have a different size from the starting one
40+
// for the time being we need this on SHA256 only
41+
static bool copyCBORByteToArray(CborValue * param, uint8_t * dest, size_t dest_size) {
42+
if (cbor_value_is_byte_string(param)) {
43+
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
44+
if(_cbor_value_copy_string(param, dest, &dest_size, NULL) == CborNoError) {
45+
return true;
46+
}
47+
}
48+
49+
return false;
50+
}
51+
52+
/******************************************************************************
53+
MESSAGE DECODE FUNCTIONS
54+
******************************************************************************/
55+
56+
MessageDecoder::Status ThingUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
57+
ThingUpdateCmd * thingCommand = (ThingUpdateCmd *) msg;
58+
59+
// Message is composed of a single parameter, a string (thing_id)
60+
if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
61+
return MessageDecoder::Status::Error;
62+
}
63+
64+
return MessageDecoder::Status::Complete;
65+
}
66+
67+
MessageDecoder::Status ThingDetachCommandDecoder::decode(CborValue* iter, Message *msg) {
68+
ThingDetachCmd * thingCommand = (ThingDetachCmd *) msg;
69+
70+
// Message is composed of a single parameter, a string (thing_id)
71+
if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
72+
return MessageDecoder::Status::Error;
73+
}
74+
75+
return MessageDecoder::Status::Complete;
76+
}
77+
78+
MessageDecoder::Status TimezoneCommandDownDecoder::decode(CborValue* iter, Message *msg) {
79+
TimezoneCommandDown * setTz = (TimezoneCommandDown *) msg;
80+
81+
// Message is composed of 2 parameters, offset 32-bit signed integer and until 32-bit unsigned integer
82+
// Get offset
83+
if (cbor_value_is_integer(iter)) {
84+
int64_t val = 0;
85+
if (cbor_value_get_int64(iter, &val) == CborNoError) {
86+
setTz->params.offset = static_cast<int32_t>(val);
87+
}
88+
}
89+
90+
// Next
91+
if (cbor_value_advance(iter) != CborNoError) {
92+
return MessageDecoder::Status::Error;
93+
}
94+
95+
// Get until
96+
if (cbor_value_is_integer(iter)) {
97+
uint64_t val = 0;
98+
if (cbor_value_get_uint64(iter, &val) == CborNoError) {
99+
setTz->params.until = static_cast<uint32_t>(val);
100+
}
101+
}
102+
103+
return MessageDecoder::Status::Complete;
104+
}
105+
106+
MessageDecoder::Status LastValuesUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
107+
LastValuesUpdateCmd * setLv = (LastValuesUpdateCmd *) msg;
108+
109+
// Message is composed by a single parameter, a variable length byte array.
110+
if (cbor_value_is_byte_string(iter)) {
111+
// Cortex M0 is not able to assign a value to pointed memory that is not 32bit aligned
112+
// we use a support variable to cope with that
113+
size_t s;
114+
if (cbor_value_dup_byte_string(iter, &setLv->params.last_values, &s, NULL) != CborNoError) {
115+
return MessageDecoder::Status::Error;
116+
}
117+
118+
setLv->params.length = s;
119+
}
120+
121+
return MessageDecoder::Status::Complete;
122+
}
123+
124+
MessageDecoder::Status OtaUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
125+
CborError error = CborNoError;
126+
OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) msg;
127+
128+
// Message is composed 4 parameters: id, url, initialSha, finalSha
129+
if (!copyCBORByteToArray(iter, ota->params.id, sizeof(ota->params.id))) {
130+
return MessageDecoder::Status::Error;
131+
}
132+
133+
error = cbor_value_advance(iter);
134+
135+
if ((error != CborNoError) || !copyCBORStringToArray(iter, ota->params.url, sizeof(ota->params.url))) {
136+
return MessageDecoder::Status::Error;
137+
}
138+
139+
error = cbor_value_advance(iter);
140+
141+
if ((error != CborNoError) || !copyCBORByteToArray(iter, ota->params.initialSha256, sizeof(ota->params.initialSha256))) {
142+
return MessageDecoder::Status::Error;
143+
}
144+
145+
error = cbor_value_advance(iter);
146+
147+
if ((error != CborNoError) || !copyCBORByteToArray(iter, ota->params.finalSha256, sizeof(ota->params.finalSha256))) {
148+
return MessageDecoder::Status::Error;
149+
}
150+
151+
return MessageDecoder::Status::Complete;
152+
}
153+
154+
static OtaUpdateCommandDecoder otaUpdateCommandDecoder;
155+
static ThingUpdateCommandDecoder thingUpdateCommandDecoder;
156+
static ThingDetachCommandDecoder thingDetachCommandDecoder;
157+
static LastValuesUpdateCommandDecoder lastValuesUpdateCommandDecoder;
158+
static TimezoneCommandDownDecoder timezoneCommandDownDecoder;

src/cbor/IoTCloudMessageDecoder.h

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
This file is part of the ArduinoIoTCloud library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#ifndef ARDUINO_CBOR_MESSAGE_DECODER_H_
12+
#define ARDUINO_CBOR_MESSAGE_DECODER_H_
13+
14+
/******************************************************************************
15+
INCLUDE
16+
******************************************************************************/
17+
18+
#include "./CBOR.h"
19+
#include <cbor/MessageDecoder.h>
20+
#include "message/Commands.h"
21+
22+
/******************************************************************************
23+
CLASS DECLARATION
24+
******************************************************************************/
25+
26+
class OtaUpdateCommandDecoder: public CBORMessageDecoderInterface {
27+
public:
28+
OtaUpdateCommandDecoder()
29+
: CBORMessageDecoderInterface(CBOROtaUpdateCmdDown, OtaUpdateCmdDownId) {}
30+
protected:
31+
MessageDecoder::Status decode(CborValue* iter, Message *msg) override;
32+
};
33+
34+
class ThingUpdateCommandDecoder: public CBORMessageDecoderInterface {
35+
public:
36+
ThingUpdateCommandDecoder()
37+
: CBORMessageDecoderInterface(CBORThingUpdateCmd, ThingUpdateCmdId) {}
38+
protected:
39+
MessageDecoder::Status decode(CborValue* iter, Message *msg) override;
40+
};
41+
42+
class ThingDetachCommandDecoder: public CBORMessageDecoderInterface {
43+
public:
44+
ThingDetachCommandDecoder()
45+
: CBORMessageDecoderInterface(CBORThingDetachCmd, ThingDetachCmdId) {}
46+
protected:
47+
MessageDecoder::Status decode(CborValue* iter, Message *msg) override;
48+
};
49+
50+
class LastValuesUpdateCommandDecoder: public CBORMessageDecoderInterface {
51+
public:
52+
LastValuesUpdateCommandDecoder()
53+
: CBORMessageDecoderInterface(CBORLastValuesUpdate, LastValuesUpdateCmdId) {}
54+
protected:
55+
MessageDecoder::Status decode(CborValue* iter, Message *msg) override;
56+
};
57+
58+
class TimezoneCommandDownDecoder: public CBORMessageDecoderInterface {
59+
public:
60+
TimezoneCommandDownDecoder()
61+
: CBORMessageDecoderInterface(CBORTimezoneCommandDown, TimezoneCommandDownId) {}
62+
protected:
63+
MessageDecoder::Status decode(CborValue* iter, Message *msg) override;
64+
};
65+
66+
#endif /* ARDUINO_CBOR_MESSAGE_DECODER_H_ */

0 commit comments

Comments
 (0)