14
14
15
15
#include < Arduino.h>
16
16
17
- #undef max
18
- #undef min
19
- #include < algorithm>
20
-
21
17
#include " MessageDecoder.h"
22
18
#include < AIoTC_Config.h>
23
19
24
20
/* *****************************************************************************
25
21
PUBLIC MEMBER FUNCTIONS
26
22
******************************************************************************/
27
23
28
- Decoder::Status CBORMessageDecoder::decode (Message * message, uint8_t const * const payload, size_t & length)
29
- {
30
- CborValue main_iter, array_iter;
31
- CborTag tag;
32
- CborParser parser;
33
-
34
- if (cbor_parser_init (payload, length, 0 , &parser, &main_iter) != CborNoError)
35
- return Decoder::Status::Error;
36
-
37
- if (main_iter.type != CborTagType)
38
- return Decoder::Status::Error;
39
-
40
- if (cbor_value_get_tag (&main_iter, &tag) == CborNoError) {
41
- message->id = toCommandId (CBORCommandTag (tag));
42
- }
43
-
44
- if (cbor_value_advance (&main_iter) != CborNoError) {
45
- return Decoder::Status::Error;
46
- }
47
-
48
- ArrayParserState current_state = ArrayParserState::EnterArray,
49
- next_state = ArrayParserState::Error;
50
-
51
- while (current_state != ArrayParserState::Complete) {
52
- switch (current_state) {
53
- case ArrayParserState::EnterArray : next_state = handle_EnterArray (&main_iter, &array_iter); break ;
54
- case ArrayParserState::ParseParam : next_state = handle_Param (&array_iter, message); break ;
55
- case ArrayParserState::LeaveArray : next_state = handle_LeaveArray (&main_iter, &array_iter); break ;
56
- case ArrayParserState::Complete : return Decoder::Status::Complete;
57
- case ArrayParserState::MessageNotSupported : return Decoder::Status::Error;
58
- case ArrayParserState::Error : return Decoder::Status::Error;
59
- }
60
-
61
- current_state = next_state;
62
- }
63
-
64
- return Decoder::Status::Complete;
65
- }
66
-
67
24
/* *****************************************************************************
68
25
PRIVATE MEMBER FUNCTIONS
69
26
******************************************************************************/
70
27
71
- bool copyCBORStringToArray (CborValue * param, char * dest, size_t dest_size) {
28
+ static bool copyCBORStringToArray (CborValue * param, char * dest, size_t dest_size) {
72
29
if (cbor_value_is_text_string (param)) {
73
30
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
74
31
if (_cbor_value_copy_string (param, dest, &dest_size, NULL ) == CborNoError) {
@@ -81,7 +38,7 @@ bool copyCBORStringToArray(CborValue * param, char * dest, size_t dest_size) {
81
38
82
39
// FIXME dest_size should be also returned, the copied byte array can have a different size from the starting one
83
40
// for the time being we need this on SHA256 only
84
- bool copyCBORByteToArray (CborValue * param, uint8_t * dest, size_t dest_size) {
41
+ static bool copyCBORByteToArray (CborValue * param, uint8_t * dest, size_t dest_size) {
85
42
if (cbor_value_is_byte_string (param)) {
86
43
// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
87
44
if (_cbor_value_copy_string (param, dest, &dest_size, NULL ) == CborNoError) {
@@ -92,153 +49,110 @@ bool copyCBORByteToArray(CborValue * param, uint8_t * dest, size_t dest_size) {
92
49
return false ;
93
50
}
94
51
95
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::handle_EnterArray (CborValue * main_iter, CborValue * array_iter) {
96
- ArrayParserState next_state = ArrayParserState::Error;
97
- if (cbor_value_get_type (main_iter) == CborArrayType) {
98
- if (cbor_value_enter_container (main_iter, array_iter) == CborNoError) {
99
- next_state = ArrayParserState::ParseParam;
100
- }
101
- }
102
-
103
- return next_state;
104
- }
105
-
106
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::handle_LeaveArray (CborValue * main_iter, CborValue * array_iter) {
107
- // Advance to the next parameter (the last one in the array)
108
- if (cbor_value_advance (array_iter) == CborNoError) {
109
- // Leave the array
110
- if (cbor_value_leave_container (main_iter, array_iter) == CborNoError) {
111
- return ArrayParserState::Complete;
112
- }
113
- }
114
-
115
- return ArrayParserState::Error;
116
- }
117
-
118
52
/* *****************************************************************************
119
53
MESSAGE DECODE FUNCTIONS
120
54
******************************************************************************/
121
55
122
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeThingUpdateCmd (CborValue * param , Message * message ) {
123
- ThingUpdateCmd * thingCommand = (ThingUpdateCmd *) message ;
56
+ Decoder::Status ThingUpdateCommandDecoder::decode (CborValue* iter , Message *msg ) {
57
+ ThingUpdateCmd * thingCommand = (ThingUpdateCmd *) msg ;
124
58
125
59
// Message is composed of a single parameter, a string (thing_id)
126
- if (!copyCBORStringToArray (param , thingCommand->params .thing_id , sizeof (thingCommand->params .thing_id ))) {
127
- return ArrayParserState ::Error;
60
+ if (!copyCBORStringToArray (iter , thingCommand->params .thing_id , sizeof (thingCommand->params .thing_id ))) {
61
+ return Decoder::Status ::Error;
128
62
}
129
63
130
- return ArrayParserState::LeaveArray ;
64
+ return Decoder::Status::Complete ;
131
65
}
132
66
133
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeThingDetachCmd (CborValue * param , Message * message ) {
134
- ThingDetachCmd * thingCommand = (ThingDetachCmd *) message ;
67
+ Decoder::Status ThingDetachCommandDecoder::decode (CborValue* iter , Message *msg ) {
68
+ ThingDetachCmd * thingCommand = (ThingDetachCmd *) msg ;
135
69
136
70
// Message is composed of a single parameter, a string (thing_id)
137
- if (!copyCBORStringToArray (param , thingCommand->params .thing_id , sizeof (thingCommand->params .thing_id ))) {
138
- return ArrayParserState ::Error;
71
+ if (!copyCBORStringToArray (iter , thingCommand->params .thing_id , sizeof (thingCommand->params .thing_id ))) {
72
+ return Decoder::Status ::Error;
139
73
}
140
74
141
- return ArrayParserState::LeaveArray ;
75
+ return Decoder::Status::Complete ;
142
76
}
143
77
144
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeTimezoneCommandDown (CborValue * param , Message * message ) {
145
- TimezoneCommandDown * setTz = (TimezoneCommandDown *) message ;
78
+ Decoder::Status TimezoneCommandDownDecoder::decode (CborValue* iter , Message *msg ) {
79
+ TimezoneCommandDown * setTz = (TimezoneCommandDown *) msg ;
146
80
147
81
// Message is composed of 2 parameters, offset 32-bit signed integer and until 32-bit unsigned integer
148
82
// Get offset
149
- if (cbor_value_is_integer (param )) {
83
+ if (cbor_value_is_integer (iter )) {
150
84
int64_t val = 0 ;
151
- if (cbor_value_get_int64 (param , &val) == CborNoError) {
85
+ if (cbor_value_get_int64 (iter , &val) == CborNoError) {
152
86
setTz->params .offset = static_cast <int32_t >(val);
153
87
}
154
88
}
155
89
156
90
// Next
157
- if (cbor_value_advance (param ) != CborNoError) {
158
- return ArrayParserState ::Error;
91
+ if (cbor_value_advance (iter ) != CborNoError) {
92
+ return Decoder::Status ::Error;
159
93
}
160
94
161
95
// Get until
162
- if (cbor_value_is_integer (param )) {
96
+ if (cbor_value_is_integer (iter )) {
163
97
uint64_t val = 0 ;
164
- if (cbor_value_get_uint64 (param , &val) == CborNoError) {
98
+ if (cbor_value_get_uint64 (iter , &val) == CborNoError) {
165
99
setTz->params .until = static_cast <uint32_t >(val);
166
100
}
167
101
}
168
102
169
- return ArrayParserState::LeaveArray ;
103
+ return Decoder::Status::Complete ;
170
104
}
171
105
172
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeLastValuesUpdateCmd (CborValue * param , Message * message ) {
173
- LastValuesUpdateCmd * setLv = (LastValuesUpdateCmd *) message ;
106
+ Decoder::Status LastValuesUpdateCommandDecoder::decode (CborValue* iter , Message *msg ) {
107
+ LastValuesUpdateCmd * setLv = (LastValuesUpdateCmd *) msg ;
174
108
175
109
// Message is composed by a single parameter, a variable length byte array.
176
- if (cbor_value_is_byte_string (param )) {
110
+ if (cbor_value_is_byte_string (iter )) {
177
111
// Cortex M0 is not able to assign a value to pointed memory that is not 32bit aligned
178
112
// we use a support variable to cope with that
179
113
size_t s;
180
- if (cbor_value_dup_byte_string (param , &setLv->params .last_values , &s, NULL ) != CborNoError) {
181
- return ArrayParserState ::Error;
114
+ if (cbor_value_dup_byte_string (iter , &setLv->params .last_values , &s, NULL ) != CborNoError) {
115
+ return Decoder::Status ::Error;
182
116
}
183
117
184
118
setLv->params .length = s;
185
119
}
186
120
187
- return ArrayParserState::LeaveArray ;
121
+ return Decoder::Status::Complete ;
188
122
}
189
123
190
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeOtaUpdateCmdDown (CborValue * param , Message * message ) {
124
+ Decoder::Status OtaUpdateCommandDecoder::decode (CborValue* iter , Message *msg ) {
191
125
CborError error = CborNoError;
192
- OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) message ;
126
+ OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) msg ;
193
127
194
128
// Message is composed 4 parameters: id, url, initialSha, finalSha
195
- if (!copyCBORByteToArray (param , ota->params .id , sizeof (ota->params .id ))) {
196
- return ArrayParserState ::Error;
129
+ if (!copyCBORByteToArray (iter , ota->params .id , sizeof (ota->params .id ))) {
130
+ return Decoder::Status ::Error;
197
131
}
198
132
199
- error = cbor_value_advance (param );
133
+ error = cbor_value_advance (iter );
200
134
201
- if ((error != CborNoError) || !copyCBORStringToArray (param , ota->params .url , sizeof (ota->params .url ))) {
202
- return ArrayParserState ::Error;
135
+ if ((error != CborNoError) || !copyCBORStringToArray (iter , ota->params .url , sizeof (ota->params .url ))) {
136
+ return Decoder::Status ::Error;
203
137
}
204
138
205
- error = cbor_value_advance (param );
139
+ error = cbor_value_advance (iter );
206
140
207
- if ((error != CborNoError) || !copyCBORByteToArray (param , ota->params .initialSha256 , sizeof (ota->params .initialSha256 ))) {
208
- return ArrayParserState ::Error;
141
+ if ((error != CborNoError) || !copyCBORByteToArray (iter , ota->params .initialSha256 , sizeof (ota->params .initialSha256 ))) {
142
+ return Decoder::Status ::Error;
209
143
}
210
144
211
- error = cbor_value_advance (param );
145
+ error = cbor_value_advance (iter );
212
146
213
- if ((error != CborNoError) || !copyCBORByteToArray (param , ota->params .finalSha256 , sizeof (ota->params .finalSha256 ))) {
214
- return ArrayParserState ::Error;
147
+ if ((error != CborNoError) || !copyCBORByteToArray (iter , ota->params .finalSha256 , sizeof (ota->params .finalSha256 ))) {
148
+ return Decoder::Status ::Error;
215
149
}
216
150
217
- return ArrayParserState::LeaveArray ;
151
+ return Decoder::Status::Complete ;
218
152
}
219
153
220
- CBORMessageDecoder::ArrayParserState CBORMessageDecoder::handle_Param (CborValue * param, Message * message) {
221
-
222
- switch (message->id )
223
- {
224
- case CommandId::ThingUpdateCmdId:
225
- return CBORMessageDecoder::decodeThingUpdateCmd (param, message);
226
-
227
- case CommandId::ThingDetachCmdId:
228
- return CBORMessageDecoder::decodeThingDetachCmd (param, message);
229
-
230
- case CommandId::TimezoneCommandDownId:
231
- return CBORMessageDecoder::decodeTimezoneCommandDown (param, message);
232
-
233
- case CommandId::LastValuesUpdateCmdId:
234
- return CBORMessageDecoder::decodeLastValuesUpdateCmd (param, message);
235
-
236
- case CommandId::OtaUpdateCmdDownId:
237
- return CBORMessageDecoder::decodeOtaUpdateCmdDown (param, message);
238
-
239
- default :
240
- return ArrayParserState::MessageNotSupported;
241
- }
242
-
243
- return ArrayParserState::LeaveArray;
244
- }
154
+ static OtaUpdateCommandDecoder otaUpdateCommandDecoder;
155
+ static ThingUpdateCommandDecoder thingUpdateCommandDecoder;
156
+ static ThingDetachCommandDecoder thingDetachCommandDecoder;
157
+ static LastValuesUpdateCommandDecoder lastValuesUpdateCommandDecoder;
158
+ static TimezoneCommandDownDecoder timezoneCommandDownDecoder;
0 commit comments