Skip to content

Commit d127814

Browse files
implementing cbor message decoder following cloud utils definition
1 parent 134308b commit d127814

File tree

4 files changed

+237
-319
lines changed

4 files changed

+237
-319
lines changed

src/cbor/IoTCloudMessageDecoder.cpp

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
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+
return MessageDecoder::Status::Error;
85+
}
86+
87+
int64_t val = 0;
88+
if (cbor_value_get_int64(iter, &val) != CborNoError) {
89+
return MessageDecoder::Status::Error;
90+
}
91+
92+
setTz->params.offset = static_cast<int32_t>(val);
93+
94+
// Next
95+
if (cbor_value_advance(iter) != CborNoError) {
96+
return MessageDecoder::Status::Error;
97+
}
98+
99+
// Get until
100+
if (!cbor_value_is_integer(iter)) {
101+
return MessageDecoder::Status::Error;
102+
}
103+
104+
uint64_t val1 = 0;
105+
if (cbor_value_get_uint64(iter, &val1) != CborNoError) {
106+
return MessageDecoder::Status::Error;
107+
}
108+
109+
setTz->params.until = static_cast<uint32_t>(val1);
110+
111+
return MessageDecoder::Status::Complete;
112+
}
113+
114+
MessageDecoder::Status LastValuesUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
115+
LastValuesUpdateCmd * setLv = (LastValuesUpdateCmd *) msg;
116+
117+
if(!cbor_value_is_byte_string(iter)) {
118+
return MessageDecoder::Status::Error;
119+
}
120+
121+
// Cortex M0 is not able to assign a value to pointed memory that is not 32bit aligned
122+
// we use a support variable to cope with that
123+
size_t s;
124+
125+
// NOTE: cbor_value_dup_byte_string calls malloc and assigns it to the second parameter of the call,
126+
// free must be called. Free has to be called only if decode succeeds.
127+
// Read tinyCbor documentation for more information.
128+
if (cbor_value_dup_byte_string(iter, &setLv->params.last_values, &s, NULL) != CborNoError) {
129+
return MessageDecoder::Status::Error;
130+
}
131+
132+
setLv->params.length = s;
133+
134+
return MessageDecoder::Status::Complete;
135+
}
136+
137+
MessageDecoder::Status OtaUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
138+
CborError error = CborNoError;
139+
OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) msg;
140+
141+
// Message is composed 4 parameters: id, url, initialSha, finalSha
142+
if (!copyCBORByteToArray(iter, ota->params.id, sizeof(ota->params.id))) {
143+
return MessageDecoder::Status::Error;
144+
}
145+
146+
error = cbor_value_advance(iter);
147+
148+
if ((error != CborNoError) || !copyCBORStringToArray(iter, ota->params.url, sizeof(ota->params.url))) {
149+
return MessageDecoder::Status::Error;
150+
}
151+
152+
error = cbor_value_advance(iter);
153+
154+
if ((error != CborNoError) || !copyCBORByteToArray(iter, ota->params.initialSha256, sizeof(ota->params.initialSha256))) {
155+
return MessageDecoder::Status::Error;
156+
}
157+
158+
error = cbor_value_advance(iter);
159+
160+
if ((error != CborNoError) || !copyCBORByteToArray(iter, ota->params.finalSha256, sizeof(ota->params.finalSha256))) {
161+
return MessageDecoder::Status::Error;
162+
}
163+
164+
return MessageDecoder::Status::Complete;
165+
}
166+
167+
static OtaUpdateCommandDecoder otaUpdateCommandDecoder;
168+
static ThingUpdateCommandDecoder thingUpdateCommandDecoder;
169+
static ThingDetachCommandDecoder thingDetachCommandDecoder;
170+
static LastValuesUpdateCommandDecoder lastValuesUpdateCommandDecoder;
171+
static TimezoneCommandDownDecoder timezoneCommandDownDecoder;

src/cbor/IoTCloudMessageDecoder.h

Lines changed: 66 additions & 0 deletions
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)