Skip to content

Commit c6899ed

Browse files
authored
Reapplying changes of PR #11 (refactoring) (8d773a4) ... (#20)
* Removing enum class CloudProtocol since the 'decode' function decodes both V1/V2 and encoding will only happen in V2 anymore. Decoding for V2 shall be removed at a later point in time * Reapplying changes of PR #11 (refactoring)(8d773a4c2d8360fedd2cf6b881630baf98338cc6) which somehow got lost in the merges
1 parent cbe49da commit c6899ed

File tree

2 files changed

+137
-164
lines changed

2 files changed

+137
-164
lines changed

ArduinoCloudThing.cpp

+109-150
Original file line numberDiff line numberDiff line change
@@ -87,31 +87,30 @@ int ArduinoCloudThing::encode(uint8_t * data, size_t const size) {
8787
// time interval may be elapsed or property may be changed
8888
int const num_changed_properties = _property_cont.getNumOfChangedProperties();
8989

90-
if (num_changed_properties > 0) {
91-
CborError err;
92-
CborEncoder encoder, arrayEncoder;
93-
94-
cbor_encoder_init(&encoder, data, size, 0);
95-
// create a cbor array containing the property that should be updated.
96-
err = cbor_encoder_create_array(&encoder, &arrayEncoder, num_changed_properties);
97-
if (err) {
98-
//Serial.println(cbor_error_string(err));
99-
return -1;
100-
}
90+
if(num_changed_properties > 0) {
91+
CborEncoder encoder, arrayEncoder;
10192

102-
_property_cont.appendChangedProperties(&arrayEncoder);
93+
cbor_encoder_init(&encoder, data, size, 0);
10394

104-
err = cbor_encoder_close_container(&encoder, &arrayEncoder);
95+
if(cbor_encoder_create_array(&encoder, &arrayEncoder, num_changed_properties) != CborNoError) {
96+
return -1;
97+
}
10598

106-
// return the number of byte of the CBOR encoded array
107-
return cbor_encoder_get_buffer_size(&encoder, data);
108-
}
99+
_property_cont.appendChangedProperties(&arrayEncoder);
100+
101+
if(cbor_encoder_close_container(&encoder, &arrayEncoder) != CborNoError) {
102+
return -1;
103+
}
109104

110105
#if defined(DEBUG_MEMORY) && defined(ARDUINO_ARCH_SAMD)
111-
PrintFreeRam();
106+
PrintFreeRam();
112107
#endif
113-
// If nothing has to be sent, return diff, that is 0 in this case
114-
return num_changed_properties;
108+
int const bytes_encoded = cbor_encoder_get_buffer_size(&encoder, data);
109+
return bytes_encoded;
110+
}
111+
else {
112+
return num_changed_properties;
113+
}
115114
}
116115

117116
ArduinoCloudProperty<bool> & ArduinoCloudThing::addPropertyReal(bool & property, String const & name, Permission const permission) {
@@ -174,7 +173,7 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt
174173
if(cbor_value_enter_container(&array_iter, &map_iter) != CborNoError)
175174
return;
176175

177-
MapData map_data;
176+
CborMapData map_data;
178177
MapParserState current_state = MapParserState::EnterMap,
179178
next_state;
180179

@@ -205,12 +204,12 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt
205204
* PRIVATE MEMBER FUNCTIONS
206205
******************************************************************************/
207206

208-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_EnterMap(CborValue * map_iter, CborValue * value_iter, MapData * map_data) {
207+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data) {
209208
MapParserState next_state = MapParserState::Error;
210209

211210
if(cbor_value_get_type(map_iter) == CborMapType) {
212211
if(cbor_value_enter_container(map_iter, value_iter) == CborNoError) {
213-
resetMapData(map_data);
212+
map_data->reset();
214213
next_state = MapParserState::MapKey;
215214
}
216215
}
@@ -229,40 +228,41 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_MapKey(CborValue * v
229228
* Example [{"n": "temperature", "v": 25}]
230229
*/
231230
else if(cbor_value_is_text_string(value_iter)) {
232-
char * val = 0;
233-
size_t val_size = 0;
234-
if(cbor_value_dup_text_string(value_iter, &val, &val_size, value_iter) == CborNoError) {
235-
if (strcmp(val, "n" ) == 0) next_state = MapParserState::Name;
236-
else if(strcmp(val, "bver") == 0) next_state = MapParserState::BaseVersion;
237-
else if(strcmp(val, "bn" ) == 0) next_state = MapParserState::BaseName;
238-
else if(strcmp(val, "bt" ) == 0) next_state = MapParserState::BaseTime;
239-
else if(strcmp(val, "v" ) == 0) next_state = MapParserState::Value;
240-
else if(strcmp(val, "vs" ) == 0) next_state = MapParserState::StringValue;
241-
else if(strcmp(val, "vb" ) == 0) next_state = MapParserState::BooleanValue;
242-
else if(strcmp(val, "t" ) == 0) next_state = MapParserState::Time;
243-
else next_state = MapParserState::UndefinedKey;
244-
free(val);
245-
}
231+
char * val = 0;
232+
size_t val_size = 0;
233+
if(cbor_value_dup_text_string(value_iter, &val, &val_size, value_iter) == CborNoError) {
234+
if (strcmp(val, "n" ) == 0) next_state = MapParserState::Name;
235+
else if(strcmp(val, "bver") == 0) next_state = MapParserState::BaseVersion;
236+
else if(strcmp(val, "bn" ) == 0) next_state = MapParserState::BaseName;
237+
else if(strcmp(val, "bt" ) == 0) next_state = MapParserState::BaseTime;
238+
else if(strcmp(val, "v" ) == 0) next_state = MapParserState::Value;
239+
else if(strcmp(val, "vs" ) == 0) next_state = MapParserState::StringValue;
240+
else if(strcmp(val, "vb" ) == 0) next_state = MapParserState::BooleanValue;
241+
else if(strcmp(val, "t" ) == 0) next_state = MapParserState::Time;
242+
else next_state = MapParserState::UndefinedKey;
243+
free(val);
244+
}
246245
}
247246
/* If the key is a number means that the Map use the CBOR Label (protocol V2)
248247
* Example [{0: "temperature", 2: 25}]
249248
*/
250249
else if (cbor_value_is_integer(value_iter)) {
251-
int val = 0;
252-
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
253-
if(cbor_value_advance(value_iter) == CborNoError) {
254-
if (val == static_cast<int>(CborIntegerMapKey::Name )) next_state = MapParserState::Name;
255-
else if(val == static_cast<int>(CborIntegerMapKey::BaseVersion )) next_state = MapParserState::BaseVersion;
256-
else if(val == static_cast<int>(CborIntegerMapKey::BaseName )) next_state = MapParserState::BaseName;
257-
else if(val == static_cast<int>(CborIntegerMapKey::BaseTime )) next_state = MapParserState::BaseTime;
258-
else if(val == static_cast<int>(CborIntegerMapKey::Value )) next_state = MapParserState::Value;
259-
else if(val == static_cast<int>(CborIntegerMapKey::StringValue )) next_state = MapParserState::StringValue;
260-
else if(val == static_cast<int>(CborIntegerMapKey::BooleanValue)) next_state = MapParserState::BooleanValue;
261-
else if(val == static_cast<int>(CborIntegerMapKey::Time )) next_state = MapParserState::Time;
262-
else next_state = MapParserState::UndefinedKey;
263-
}
264-
}
250+
int val = 0;
251+
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
252+
if(cbor_value_advance(value_iter) == CborNoError) {
253+
if (val == static_cast<int>(CborIntegerMapKey::Name )) next_state = MapParserState::Name;
254+
else if(val == static_cast<int>(CborIntegerMapKey::BaseVersion )) next_state = MapParserState::BaseVersion;
255+
else if(val == static_cast<int>(CborIntegerMapKey::BaseName )) next_state = MapParserState::BaseName;
256+
else if(val == static_cast<int>(CborIntegerMapKey::BaseTime )) next_state = MapParserState::BaseTime;
257+
else if(val == static_cast<int>(CborIntegerMapKey::Value )) next_state = MapParserState::Value;
258+
else if(val == static_cast<int>(CborIntegerMapKey::StringValue )) next_state = MapParserState::StringValue;
259+
else if(val == static_cast<int>(CborIntegerMapKey::BooleanValue)) next_state = MapParserState::BooleanValue;
260+
else if(val == static_cast<int>(CborIntegerMapKey::Time )) next_state = MapParserState::Time;
261+
else next_state = MapParserState::UndefinedKey;
262+
}
263+
}
265264
}
265+
266266
return next_state;
267267
}
268268

@@ -276,13 +276,14 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_UndefinedKey(CborVal
276276
return next_state;
277277
}
278278

279-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseVersion(CborValue * value_iter, MapData * map_data) {
279+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseVersion(CborValue * value_iter, CborMapData * map_data) {
280280
MapParserState next_state = MapParserState::Error;
281281

282282
if(cbor_value_is_integer(value_iter)) {
283283
int val = 0;
284284
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
285285
map_data->base_version.set(val);
286+
286287
if(cbor_value_advance(value_iter) == CborNoError) {
287288
next_state = MapParserState::MapKey;
288289
}
@@ -292,7 +293,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseVersion(CborValu
292293
return next_state;
293294
}
294295

295-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseName(CborValue * value_iter, MapData * map_data) {
296+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseName(CborValue * value_iter, CborMapData * map_data) {
296297
MapParserState next_state = MapParserState::Error;
297298

298299
if(cbor_value_is_text_string(value_iter)) {
@@ -308,45 +309,22 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseName(CborValue *
308309
return next_state;
309310
}
310311

311-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseTime(CborValue * value_iter, MapData * map_data) {
312+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseTime(CborValue * value_iter, CborMapData * map_data) {
312313
MapParserState next_state = MapParserState::Error;
313314

314-
if(cbor_value_is_integer(value_iter)) {
315-
int val = 0;
316-
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
317-
map_data->base_time.set(static_cast<double>(val));
318-
}
319-
}
320-
321-
if(cbor_value_is_double(value_iter)) {
322-
double val = 0.0;
323-
if(cbor_value_get_double(value_iter, &val) == CborNoError) {
324-
map_data->base_time.set(val);
325-
}
326-
}
327-
328-
if(cbor_value_is_float(value_iter)) {
329-
float val = 0.0;
330-
if(cbor_value_get_float(value_iter, &val) == CborNoError) {
331-
map_data->base_time.set(static_cast<double>(val));
332-
}
333-
}
315+
double val = 0.0;
316+
if(ifNumericConvertToDouble(value_iter, &val)) {
317+
map_data->base_time.set(val);
334318

335-
if(cbor_value_is_half_float(value_iter)) {
336-
uint16_t val = 0;
337-
if(cbor_value_get_half_float(value_iter, &val) == CborNoError) {
338-
map_data->base_time.set(static_cast<double>(convertCborHalfFloatToDouble(val)));
319+
if(cbor_value_advance(value_iter) == CborNoError) {
320+
next_state = MapParserState::MapKey;
339321
}
340322
}
341323

342-
if(cbor_value_advance(value_iter) == CborNoError) {
343-
next_state = MapParserState::MapKey;
344-
}
345-
346324
return next_state;
347325
}
348326

349-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * value_iter, MapData * map_data) {
327+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * value_iter, CborMapData * map_data) {
350328
MapParserState next_state = MapParserState::Error;
351329

352330
if(cbor_value_is_text_string(value_iter)) {
@@ -362,42 +340,22 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * val
362340
return next_state;
363341
}
364342

365-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Value(CborValue * value_iter, MapData * map_data) {
343+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Value(CborValue * value_iter, CborMapData * map_data) {
366344
MapParserState next_state = MapParserState::Error;
367345

368-
if(value_iter->type == CborIntegerType) {
369-
int val = 0;
370-
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
371-
map_data->val.set(static_cast<float>(val));
372-
}
373-
}
374-
else if(value_iter->type == CborDoubleType) {
375-
double val = 0.0;
376-
if(cbor_value_get_double(value_iter, &val) == CborNoError) {
377-
map_data->val.set(static_cast<float>(val));
378-
}
379-
}
380-
else if(value_iter->type == CborFloatType) {
381-
float val = 0.0f;
382-
if(cbor_value_get_float(value_iter, &val) == CborNoError) {
383-
map_data->val.set(val);
384-
}
385-
}
386-
else if(value_iter->type == CborHalfFloatType) {
387-
uint16_t val = 0;
388-
if(cbor_value_get_half_float(value_iter, &val) == CborNoError) {
389-
map_data->val.set(static_cast<float>(convertCborHalfFloatToDouble(val)));
390-
}
391-
}
346+
double val = 0.0;
347+
if(ifNumericConvertToDouble(value_iter, &val)) {
348+
map_data->val.set(val);
392349

393-
if(cbor_value_advance(value_iter) == CborNoError) {
394-
next_state = MapParserState::MapKey;
350+
if(cbor_value_advance(value_iter) == CborNoError) {
351+
next_state = MapParserState::MapKey;
352+
}
395353
}
396354

397355
return next_state;
398356
}
399357

400-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_StringValue(CborValue * value_iter, MapData * map_data) {
358+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_StringValue(CborValue * value_iter, CborMapData * map_data) {
401359
MapParserState next_state = MapParserState::Error;
402360

403361
if(cbor_value_is_text_string(value_iter)) {
@@ -413,12 +371,13 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_StringValue(CborValu
413371
return next_state;
414372
}
415373

416-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BooleanValue(CborValue * value_iter, MapData * map_data) {
374+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BooleanValue(CborValue * value_iter, CborMapData * map_data) {
417375
MapParserState next_state = MapParserState::Error;
418376

419377
bool val = false;
420378
if(cbor_value_get_boolean(value_iter, &val) == CborNoError) {
421379
map_data->bool_val.set(val);
380+
422381
if(cbor_value_advance(value_iter) == CborNoError) {
423382
next_state = MapParserState::MapKey;
424383
}
@@ -427,45 +386,22 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BooleanValue(CborVal
427386
return next_state;
428387
}
429388

430-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Time(CborValue * value_iter, MapData * map_data) {
389+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Time(CborValue * value_iter, CborMapData * map_data) {
431390
MapParserState next_state = MapParserState::Error;
432391

433-
if(cbor_value_is_integer(value_iter)) {
434-
int val = 0;
435-
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
436-
map_data->time.set(static_cast<double>(val));
437-
}
438-
}
439-
440-
if(cbor_value_is_double(value_iter)) {
441-
double val = 0.0;
442-
if(cbor_value_get_double(value_iter, &val) == CborNoError) {
443-
map_data->time.set(val);
444-
}
445-
}
446-
447-
if(cbor_value_is_float(value_iter)) {
448-
float val = 0.0;
449-
if(cbor_value_get_float(value_iter, &val) == CborNoError) {
450-
map_data->time.set(static_cast<double>(val));
451-
}
452-
}
392+
double val = 0.0;
393+
if(ifNumericConvertToDouble(value_iter, &val)) {
394+
map_data->time.set(val);
453395

454-
if(cbor_value_is_half_float(value_iter)) {
455-
uint16_t val = 0;
456-
if(cbor_value_get_half_float(value_iter, &val) == CborNoError) {
457-
map_data->time.set(static_cast<double>(convertCborHalfFloatToDouble(val)));
396+
if(cbor_value_advance(value_iter) == CborNoError) {
397+
next_state = MapParserState::MapKey;
458398
}
459399
}
460400

461-
if(cbor_value_advance(value_iter) == CborNoError) {
462-
next_state = MapParserState::MapKey;
463-
}
464-
465401
return next_state;
466402
}
467403

468-
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, MapData const * const map_data) {
404+
ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData const * const map_data) {
469405
MapParserState next_state = MapParserState::Error;
470406

471407
/* Update the property containers depending on the parsed data */
@@ -521,15 +457,38 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue *
521457
return next_state;
522458
}
523459

524-
void ArduinoCloudThing::resetMapData(MapData * map_data) {
525-
map_data->base_version.reset();
526-
map_data->base_name.reset ();
527-
map_data->base_time.reset ();
528-
map_data->name.reset ();
529-
map_data->val.reset ();
530-
map_data->str_val.reset ();
531-
map_data->bool_val.reset ();
532-
map_data->time.reset ();
460+
bool ArduinoCloudThing::ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val) {
461+
462+
if(cbor_value_is_integer(value_iter)) {
463+
int val = 0;
464+
if(cbor_value_get_int(value_iter, &val) == CborNoError) {
465+
*numeric_val = static_cast<double>(val);
466+
return true;
467+
}
468+
}
469+
else if(cbor_value_is_double(value_iter)) {
470+
double val = 0.0;
471+
if(cbor_value_get_double(value_iter, &val) == CborNoError) {
472+
*numeric_val = val;
473+
return true;
474+
}
475+
}
476+
else if(cbor_value_is_float(value_iter)) {
477+
float val = 0.0;
478+
if(cbor_value_get_float(value_iter, &val) == CborNoError) {
479+
*numeric_val = static_cast<double>(val);
480+
return true;
481+
}
482+
}
483+
else if(cbor_value_is_half_float(value_iter)) {
484+
uint16_t val = 0;
485+
if(cbor_value_get_half_float(value_iter, &val) == CborNoError) {
486+
*numeric_val = static_cast<double>(convertCborHalfFloatToDouble(val));
487+
return true;
488+
}
489+
}
490+
491+
return false;
533492
}
534493

535494
/* Source Idea from https://tools.ietf.org/html/rfc7049 : Page: 50 */

0 commit comments

Comments
 (0)