Skip to content

Commit 78507df

Browse files
implementing cbor message decoder following cloud utils definition
1 parent 7c048bf commit 78507df

File tree

4 files changed

+231
-319
lines changed

4 files changed

+231
-319
lines changed

src/cbor/IoTCloudMessageDecoder.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
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+
static inline bool copyCBORStringToArray(CborValue * param, char * dest, size_t dest_size) {
21+
if (cbor_value_is_text_string(param)) {
22+
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
23+
if(_cbor_value_copy_string(param, dest, &dest_size, NULL) == CborNoError) {
24+
return true;
25+
}
26+
}
27+
28+
return false;
29+
}
30+
31+
static inline size_t copyCBORByteToArray(CborValue * param, uint8_t * dest, size_t dest_size) {
32+
if (cbor_value_is_byte_string(param)) {
33+
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
34+
if(_cbor_value_copy_string(param, dest, &dest_size, NULL) == CborNoError) {
35+
return dest_size;
36+
}
37+
}
38+
39+
return 0;
40+
}
41+
42+
/******************************************************************************
43+
MESSAGE DECODE FUNCTIONS
44+
******************************************************************************/
45+
46+
MessageDecoder::Status ThingUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
47+
ThingUpdateCmd * thingCommand = (ThingUpdateCmd *) msg;
48+
49+
// Message is composed of a single parameter, a string (thing_id)
50+
if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
51+
return MessageDecoder::Status::Error;
52+
}
53+
54+
return MessageDecoder::Status::Complete;
55+
}
56+
57+
MessageDecoder::Status ThingDetachCommandDecoder::decode(CborValue* iter, Message *msg) {
58+
ThingDetachCmd * thingCommand = (ThingDetachCmd *) msg;
59+
60+
// Message is composed of a single parameter, a string (thing_id)
61+
if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
62+
return MessageDecoder::Status::Error;
63+
}
64+
65+
return MessageDecoder::Status::Complete;
66+
}
67+
68+
MessageDecoder::Status TimezoneCommandDownDecoder::decode(CborValue* iter, Message *msg) {
69+
TimezoneCommandDown * setTz = (TimezoneCommandDown *) msg;
70+
71+
// Message is composed of 2 parameters, offset 32-bit signed integer and until 32-bit unsigned integer
72+
// Get offset
73+
if (!cbor_value_is_integer(iter)) {
74+
return MessageDecoder::Status::Error;
75+
}
76+
77+
int64_t val = 0;
78+
if (cbor_value_get_int64(iter, &val) != CborNoError) {
79+
return MessageDecoder::Status::Error;
80+
}
81+
82+
setTz->params.offset = static_cast<int32_t>(val);
83+
84+
// Next
85+
if (cbor_value_advance(iter) != CborNoError) {
86+
return MessageDecoder::Status::Error;
87+
}
88+
89+
// Get until
90+
if (!cbor_value_is_integer(iter)) {
91+
return MessageDecoder::Status::Error;
92+
}
93+
94+
uint64_t val1 = 0;
95+
if (cbor_value_get_uint64(iter, &val1) != CborNoError) {
96+
return MessageDecoder::Status::Error;
97+
}
98+
99+
setTz->params.until = static_cast<uint32_t>(val1);
100+
101+
return MessageDecoder::Status::Complete;
102+
}
103+
104+
MessageDecoder::Status LastValuesUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
105+
LastValuesUpdateCmd * setLv = (LastValuesUpdateCmd *) msg;
106+
107+
if(!cbor_value_is_byte_string(iter)) {
108+
return MessageDecoder::Status::Error;
109+
}
110+
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+
115+
// NOTE: cbor_value_dup_byte_string calls malloc and assigns it to the second parameter of the call,
116+
// free must be called. Free has to be called only if decode succeeds.
117+
// Read tinyCbor documentation for more information.
118+
if (cbor_value_dup_byte_string(iter, &setLv->params.last_values, &s, NULL) != CborNoError) {
119+
return MessageDecoder::Status::Error;
120+
}
121+
122+
setLv->params.length = s;
123+
124+
return MessageDecoder::Status::Complete;
125+
}
126+
127+
MessageDecoder::Status OtaUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
128+
CborError error = CborNoError;
129+
OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) msg;
130+
131+
// Message is composed 4 parameters: id, url, initialSha, finalSha
132+
if (!copyCBORByteToArray(iter, ota->params.id, sizeof(ota->params.id))) {
133+
return MessageDecoder::Status::Error;
134+
}
135+
136+
error = cbor_value_advance(iter);
137+
138+
if ((error != CborNoError) || !copyCBORStringToArray(iter, ota->params.url, sizeof(ota->params.url))) {
139+
return MessageDecoder::Status::Error;
140+
}
141+
142+
error = cbor_value_advance(iter);
143+
144+
if ((error != CborNoError) ||
145+
copyCBORByteToArray(iter, ota->params.initialSha256,
146+
sizeof(ota->params.initialSha256)) != sizeof(ota->params.initialSha256)) {
147+
return MessageDecoder::Status::Error;
148+
}
149+
150+
error = cbor_value_advance(iter);
151+
152+
if ((error != CborNoError) ||
153+
copyCBORByteToArray(iter, ota->params.finalSha256,
154+
sizeof(ota->params.finalSha256)) != sizeof(ota->params.finalSha256)) {
155+
return MessageDecoder::Status::Error;
156+
}
157+
158+
return MessageDecoder::Status::Complete;
159+
}
160+
161+
static OtaUpdateCommandDecoder otaUpdateCommandDecoder;
162+
static ThingUpdateCommandDecoder thingUpdateCommandDecoder;
163+
static ThingDetachCommandDecoder thingDetachCommandDecoder;
164+
static LastValuesUpdateCommandDecoder lastValuesUpdateCommandDecoder;
165+
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)