From dfcc74a7820826a614009723747c1eaee8d04c38 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 06:41:29 +0200 Subject: [PATCH 1/6] Extracting CBOR encode functionality into static class CBOREncoder --- src/ArduinoIoTCloudLPWAN.cpp | 4 ++- src/ArduinoIoTCloudTCP.cpp | 4 ++- src/cbor/ArduinoCloudThing.cpp | 24 ---------------- src/cbor/ArduinoCloudThing.h | 3 -- src/cbor/CBOREncoder.cpp | 51 ++++++++++++++++++++++++++++++++++ src/cbor/CBOREncoder.h | 47 +++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 src/cbor/CBOREncoder.cpp create mode 100644 src/cbor/CBOREncoder.h diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 3cc166a72..9bcb80fee 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -25,6 +25,8 @@ #include +#include "cbor/CBOREncoder.h" + /****************************************************************************** CONSTANTS ******************************************************************************/ @@ -126,7 +128,7 @@ void ArduinoIoTCloudLPWAN::disconnect() void ArduinoIoTCloudLPWAN::sendPropertiesToCloud() { uint8_t data[CBOR_LORA_MSG_MAX_SIZE]; - int const length = _thing.encode(data, sizeof(data), true); + int const length = CBOREncoder::encode(_property_container, data, sizeof(data), true); if (length > 0) { writeProperties(data, length); } diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 281957c1a..4efe6ed09 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -29,6 +29,8 @@ #include "tls/utility/CryptoUtil.h" #endif +#include "cbor/CBOREncoder.h" + /****************************************************************************** GLOBAL VARIABLES ******************************************************************************/ @@ -284,7 +286,7 @@ void ArduinoIoTCloudTCP::handleMessage(int length) void ArduinoIoTCloudTCP::sendPropertiesToCloud() { uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE]; - int const length = _thing.encode(data, sizeof(data)); + int const length = CBOREncoder::encode(_property_container, data, sizeof(data)); if (length > 0) { /* If properties have been encoded store them in the back-up buffer diff --git a/src/cbor/ArduinoCloudThing.cpp b/src/cbor/ArduinoCloudThing.cpp index 419c3de90..9bfb50902 100644 --- a/src/cbor/ArduinoCloudThing.cpp +++ b/src/cbor/ArduinoCloudThing.cpp @@ -48,30 +48,6 @@ void ArduinoCloudThing::begin(PropertyContainer * property_container) _property_container = property_container; } -int ArduinoCloudThing::encode(uint8_t * data, size_t const size, bool lightPayload) { - - // check if backing storage and cloud has diverged - // time interval may be elapsed or property may be changed - CborEncoder encoder, arrayEncoder; - - cbor_encoder_init(&encoder, data, size, 0); - - if (cbor_encoder_create_array(&encoder, &arrayEncoder, CborIndefiniteLength) != CborNoError) { - return -1; - } - - if (appendChangedProperties(*_property_container, &arrayEncoder, lightPayload) < 1) { - return -1; - } - - if (cbor_encoder_close_container(&encoder, &arrayEncoder) != CborNoError) { - return -1; - } - - int const bytes_encoded = cbor_encoder_get_buffer_size(&encoder, data); - return bytes_encoded; -} - void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const length, bool isSyncMessage) { _isSyncMessage = isSyncMessage; diff --git a/src/cbor/ArduinoCloudThing.h b/src/cbor/ArduinoCloudThing.h index 5ef9b0ae2..023d6cb3a 100644 --- a/src/cbor/ArduinoCloudThing.h +++ b/src/cbor/ArduinoCloudThing.h @@ -81,9 +81,6 @@ class ArduinoCloudThing { void begin(PropertyContainer * property_container); - /* encode return > 0 if a property has changed and encodes the changed properties in CBOR format into the provided buffer */ - /* if lightPayload is true the integer identifier of the property will be encoded in the message instead of the property name in order to reduce the size of the message payload*/ - int encode(uint8_t * data, size_t const size, bool lightPayload = false); /* decode a CBOR payload received from the cloud */ void decode(uint8_t const * const payload, size_t const length, bool isSyncMessage = false); diff --git a/src/cbor/CBOREncoder.cpp b/src/cbor/CBOREncoder.cpp new file mode 100644 index 000000000..6de4d487d --- /dev/null +++ b/src/cbor/CBOREncoder.cpp @@ -0,0 +1,51 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + +#include "CBOREncoder.h" + +#include "lib/tinycbor/cbor-lib.h" + +/****************************************************************************** + * PUBLIC MEMBER FUNCTIONS + ******************************************************************************/ + +int CBOREncoder::encode(PropertyContainer & property_container, uint8_t * data, size_t const size, bool lightPayload) +{ + CborEncoder encoder, arrayEncoder; + + cbor_encoder_init(&encoder, data, size, 0); + + if (cbor_encoder_create_array(&encoder, &arrayEncoder, CborIndefiniteLength) != CborNoError) + return -1; + + /* Check if backing storage and cloud has diverged + * time interval may be elapsed or property may be changed + * and if that's the case encode the property into the CBOR. + */ + if (appendChangedProperties(property_container, &arrayEncoder, lightPayload) < 1) + return -1; + + if (cbor_encoder_close_container(&encoder, &arrayEncoder) != CborNoError) + return -1; + + int const bytes_encoded = cbor_encoder_get_buffer_size(&encoder, data); + return bytes_encoded; +} diff --git a/src/cbor/CBOREncoder.h b/src/cbor/CBOREncoder.h new file mode 100644 index 000000000..90aff85c9 --- /dev/null +++ b/src/cbor/CBOREncoder.h @@ -0,0 +1,47 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_CBOR_CBOR_ENCODER_H_ +#define ARDUINO_CBOR_CBOR_ENCODER_H_ + +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + +#include "../property/PropertyContainer.h" + +/****************************************************************************** + * CLASS DECLARATION + ******************************************************************************/ + +class CBOREncoder +{ + +public: + + /* encode return > 0 if a property has changed and encodes the changed properties in CBOR format into the provided buffer */ + /* if lightPayload is true the integer identifier of the property will be encoded in the message instead of the property name in order to reduce the size of the message payload*/ + static int encode(PropertyContainer & property_container, uint8_t * data, size_t const size, bool lightPayload = false); + +private: + + CBOREncoder() { } + CBOREncoder(CborEncoder const &) { } + +}; + +#endif /* ARDUINO_CBOR_CBOR_ENCODER_H_ */ From 8c1da19d0f15402100f2d32a7644710c0fbdf82b Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 06:42:18 +0200 Subject: [PATCH 2/6] Adjusting unit tests after extracting cbor encode functionality --- extras/test/CMakeLists.txt | 1 + extras/test/include/util/CBORTestUtil.h | 4 +- extras/test/src/test_callback.cpp | 4 +- extras/test/src/test_encode.cpp | 72 +++++++++---------- extras/test/src/test_publishEvery.cpp | 10 +-- extras/test/src/test_publishOnChange.cpp | 6 +- .../src/test_publishOnChangeRateLimit.cpp | 10 +-- extras/test/src/test_writeOnly.cpp | 2 +- extras/test/src/util/CBORTestUtil.cpp | 6 +- 9 files changed, 59 insertions(+), 56 deletions(-) diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt index ac113d2e8..2e95a3ae2 100644 --- a/extras/test/CMakeLists.txt +++ b/extras/test/CMakeLists.txt @@ -56,6 +56,7 @@ set(TEST_DUT_SRCS ../../src/property/Property.cpp ../../src/property/PropertyContainer.cpp ../../src/cbor/ArduinoCloudThing.cpp + ../../src/cbor/CBOREncoder.cpp ../../src/cbor/lib/tinycbor/src/cborencoder.c ../../src/cbor/lib/tinycbor/src/cborencoder_close_container_checked.c ../../src/cbor/lib/tinycbor/src/cborerrorstrings.c diff --git a/extras/test/include/util/CBORTestUtil.h b/extras/test/include/util/CBORTestUtil.h index 8aace645e..5e25dcc86 100644 --- a/extras/test/include/util/CBORTestUtil.h +++ b/extras/test/include/util/CBORTestUtil.h @@ -9,7 +9,7 @@ INCLUDE **************************************************************************************/ -#include +#include #include @@ -24,7 +24,7 @@ namespace cbor PROTOTYPES **************************************************************************************/ -std::vector encode(ArduinoCloudThing & thing, bool lightPayload = false); +std::vector encode(PropertyContainer & property_container, bool lightPayload = false); void print(std::vector const & vect); /************************************************************************************** diff --git a/extras/test/src/test_callback.cpp b/extras/test/src/test_callback.cpp index 1a345a37c..cfc81bcf2 100644 --- a/extras/test/src/test_callback.cpp +++ b/extras/test/src/test_callback.cpp @@ -73,7 +73,7 @@ SCENARIO("A (boolean) property is manipulated in the callback to its origin stat PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); addPropertyToContainer(property_container, switch_turned_on, "switch_turned_on", Permission::ReadWrite).onUpdate(switch_callback); @@ -91,7 +91,7 @@ SCENARIO("A (boolean) property is manipulated in the callback to its origin stat /* [{0: "switch_turned_on", 4: false}] = 9F A2 00 70 73 77 69 74 63 68 5F 74 75 72 6E 65 64 5F 6F 6E 04 F4 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x70, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5F, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x5F, 0x6F, 0x6E, 0x04, 0xF4, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } diff --git a/extras/test/src/test_encode.cpp b/extras/test/src/test_encode.cpp index 3302d9f01..2045e7a47 100644 --- a/extras/test/src/test_encode.cpp +++ b/extras/test/src/test_encode.cpp @@ -29,14 +29,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudBool test = true; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -49,7 +49,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudBool test = true; /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ @@ -57,7 +57,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: 1, 4: true}] = 9F A2 00 01 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x01, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing, true); + std::vector const actual = cbor::encode(property_container, true); REQUIRE(actual == expected); } } @@ -69,14 +69,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudInt int_test = 123; addPropertyToContainer(property_container, int_test, "test", Permission::ReadWrite); /* [{0: "test", 3: 123}] = 9F A2 00 64 74 65 73 74 02 18 7B FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x18, 0x7B, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -88,14 +88,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudFloat float_test = 3.14159; addPropertyToContainer(property_container, float_test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.141590118408203}] = 9F A2 00 64 74 65 73 74 02 FA 40 49 0F D0 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x49, 0x0F, 0xD0, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -107,7 +107,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudString string_test; string_test = "test"; @@ -115,7 +115,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 3: "test"}] = 9F A2 00 64 74 65 73 74 03 64 74 65 73 74 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x64, 0x74, 0x65, 0x73, 0x74, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -127,14 +127,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudLocation location_test = CloudLocation(2.0f, 3.0f); addPropertyToContainer(property_container, location_test, "test", Permission::ReadWrite); /* [{0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 9F A2 00 68 74 65 73 74 3A 6C 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 FA 40 40 00 00 FF*/ std::vector const expected = { 0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0xFA, 0x40, 0x40, 0x00, 0x00, 0xFF }; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -146,14 +146,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); /* [{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 9F A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -166,7 +166,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); /*The property is added with identifier 1 that will be used instead of the string "name" as property identifier */ @@ -174,7 +174,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: 257, 2: 2.0},{0: 513, 2: 2.0},{0: 769, 2: 2.0}] = 9F A2 00 19 01 01 02 FA 40 00 00 00 A2 00 19 02 01 02 FA 40 00 00 00 A2 00 19 03 01 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x19, 0x01, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x02, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x03, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; - std::vector const actual = cbor::encode(thing, true); + std::vector const actual = cbor::encode(property_container, true); REQUIRE(actual == expected); } } @@ -186,14 +186,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudColoredLight color_test = CloudColoredLight(true, 2.0, 2.0, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -205,14 +205,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudTelevision tv_test = CloudTelevision(true, 50, false, PlaybackCommands::Play, InputValue::TV, 7); addPropertyToContainer(property_container, tv_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:vol", 2: 50},{0: "test:mut", 2: false},{0: "test:pbc", 2: 3},{0: "test:inp", 2: 55},{0: "test:cha", 2: 7}] = 9F A2 00 68 74 65 73 74 3A 73 77 69 04 F5 A2 00 68 74 65 73 74 3A 76 6F 6C 02 18 32 A2 00 68 74 65 73 74 3A 6D 75 74 04 F4 A2 00 68 74 65 73 74 3A 70 62 63 02 03 A2 00 68 74 65 73 74 3A 69 6E 70 02 18 37 A2 00 68 74 65 73 74 3A 63 68 61 02 07 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x76, 0x6F, 0x6C, 0x02, 0x18, 0x32, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6D, 0x75, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x70, 0x62, 0x63, 0x02, 0x03, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x69, 0x6E, 0x70, 0x02, 0x18, 0x37, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x02, 0x07, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -224,14 +224,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudDimmedLight color_test = CloudDimmedLight(true, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 0.0},{0: "test:sat", 2: 0.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 00 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 00 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -243,7 +243,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudLight test; test = true; @@ -251,7 +251,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -263,7 +263,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudContactSensor test; test = true; @@ -271,7 +271,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -283,7 +283,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudMotionSensor test; test = true; @@ -291,7 +291,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -303,7 +303,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudSmartPlug test; test = true; @@ -311,7 +311,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -323,7 +323,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudTemperature float_test; float_test = 3.14159; @@ -331,7 +331,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 2: 3.141590118408203}] = 9F A2 00 64 74 65 73 74 02 FA 40 49 0F D0 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x49, 0x0F, 0xD0, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -343,7 +343,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") PropertyContainer property_container; ArduinoCloudThing thing; thing.begin(&property_container); - cbor::encode(thing); + cbor::encode(property_container); CloudSwitch test; test = true; @@ -351,7 +351,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -379,7 +379,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") = 9F A2 00 68 69 6E 74 5F 74 65 73 74 02 01 A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA 40 00 00 00 A2 00 68 73 74 72 5F 74 65 73 74 03 68 73 74 72 5F 74 65 73 74 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x69, 0x6E, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01, 0xA2, 0x00, 0x69, 0x62, 0x6F, 0x6F, 0x6C, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x6A, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x03, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } @@ -414,7 +414,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") = 9F A2 00 68 69 6E 74 5F 74 65 73 74 02 01 A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA 40 00 00 00 A2 00 68 73 74 72 5F 74 65 73 74 03 68 73 74 72 5F 74 65 73 74 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x69, 0x6E, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01, 0xA2, 0x00, 0x69, 0x62, 0x6F, 0x6F, 0x6C, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x6A, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x03, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0xFF}; - std::vector const actual = cbor::encode(thing); + std::vector const actual = cbor::encode(property_container); REQUIRE(actual == expected); } } diff --git a/extras/test/src/test_publishEvery.cpp b/extras/test/src/test_publishEvery.cpp index 594f0bf36..cc432b178 100644 --- a/extras/test/src/test_publishEvery.cpp +++ b/extras/test/src/test_publishEvery.cpp @@ -31,23 +31,23 @@ SCENARIO("A Arduino cloud property is published periodically", "[ArduinoCloudThi WHEN("t = 0 ms, publish interval = 1000 ms, 1st call to 'encode'") { set_millis(0); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); WHEN("t = 999 ms") { set_millis(999); THEN("'encode' should not encode the property") { - REQUIRE(cbor::encode(thing).size() == 0); + REQUIRE(cbor::encode(property_container).size() == 0); WHEN("t = 1000 ms") { set_millis(1000); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); WHEN("t = 1999 ms") { set_millis(1999); THEN("'encode' should not encode the property") { - REQUIRE(cbor::encode(thing).size() == 0); + REQUIRE(cbor::encode(property_container).size() == 0); WHEN("t = 2000 ms") { set_millis(2000); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); } } } diff --git a/extras/test/src/test_publishOnChange.cpp b/extras/test/src/test_publishOnChange.cpp index 5f14bcd49..092c449f3 100644 --- a/extras/test/src/test_publishOnChange.cpp +++ b/extras/test/src/test_publishOnChange.cpp @@ -30,15 +30,15 @@ SCENARIO("A Arduino cloud property is published on value change", "[ArduinoCloud WHEN("test = 10, delta = 6, the property is encoded for the 1st time") { THEN("The property should be encoded") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); WHEN("test +=4 -> test = 14") { test += 4; THEN("Since the increment since the last update (4) is smaller than the delta of 6 the property should not be encoded") { - REQUIRE(cbor::encode(thing).size() == 0); + REQUIRE(cbor::encode(property_container).size() == 0); WHEN("test +=4 -> test = 18") { test += 4; THEN("Since the increment since the last update (8) is greater than the delta of 6 the property should be encoded") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); } } } diff --git a/extras/test/src/test_publishOnChangeRateLimit.cpp b/extras/test/src/test_publishOnChangeRateLimit.cpp index 386affe07..7cba892a6 100644 --- a/extras/test/src/test_publishOnChangeRateLimit.cpp +++ b/extras/test/src/test_publishOnChangeRateLimit.cpp @@ -32,27 +32,27 @@ SCENARIO("A Arduino cloud property is published on value change but the update r WHEN("t = 0 ms, min time between updates = 500 ms, property not modified, 1st call to 'encode'") { set_millis(0); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); WHEN("t = 499 ms, property modified") { test++; set_millis(499); THEN("'encode' should not encode any property") { - REQUIRE(cbor::encode(thing).size() == 0); + REQUIRE(cbor::encode(property_container).size() == 0); WHEN("t = 500 ms, property modified") { test++; set_millis(500); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); WHEN("t = 999 ms, property modified") { test++; set_millis(999); THEN("'encode' should not encode any property") { - REQUIRE(cbor::encode(thing).size() == 0); + REQUIRE(cbor::encode(property_container).size() == 0); WHEN("t = 1000 ms, property modified") { test++; set_millis(1000); THEN("'encode' should encode the property") { - REQUIRE(cbor::encode(thing).size() != 0); + REQUIRE(cbor::encode(property_container).size() != 0); } } } diff --git a/extras/test/src/test_writeOnly.cpp b/extras/test/src/test_writeOnly.cpp index d041e6836..441c6a178 100644 --- a/extras/test/src/test_writeOnly.cpp +++ b/extras/test/src/test_writeOnly.cpp @@ -25,7 +25,7 @@ SCENARIO("A Arduino cloud property is marked 'write only'", "[ArduinoCloudThing: CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::Write); - REQUIRE(cbor::encode(thing).size() == 0); /* Since 'test' is 'write only' it should not be encoded */ + REQUIRE(cbor::encode(property_container).size() == 0); /* Since 'test' is 'write only' it should not be encoded */ /************************************************************************************/ } diff --git a/extras/test/src/util/CBORTestUtil.cpp b/extras/test/src/util/CBORTestUtil.cpp index 2599fc453..b2bd1f751 100644 --- a/extras/test/src/util/CBORTestUtil.cpp +++ b/extras/test/src/util/CBORTestUtil.cpp @@ -11,6 +11,8 @@ #include #include +#include + /************************************************************************************** NAMESPACE **************************************************************************************/ @@ -22,9 +24,9 @@ namespace cbor PUBLIC FUNCTIONS **************************************************************************************/ -std::vector encode(ArduinoCloudThing & thing, bool lightPayload) { +std::vector encode(PropertyContainer & property_container, bool lightPayload) { uint8_t buf[200] = {0}; - int const bytes_buf = thing.encode(buf, 200, lightPayload); + int const bytes_buf = CBOREncoder::encode(property_container, buf, 200, lightPayload); if (bytes_buf == -1) { return std::vector(); } else { From c7540991ae05bae8a336e2157e7e1120ce9aa504 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 06:49:47 +0200 Subject: [PATCH 3/6] Extracting constants and device sync functions to modules where they belong better than to ArduinoCloudThing --- extras/test/CMakeLists.txt | 1 + extras/test/src/test_publishEvery.cpp | 1 + src/AIoTC_Const.h | 34 +++++++++++++++++++++++++++ src/ArduinoIoTCloud.h | 3 +++ src/cbor/ArduinoCloudThing.cpp | 15 ------------ src/cbor/ArduinoCloudThing.h | 24 ------------------- src/property/Property.cpp | 20 ++++++++++++++++ src/property/Property.h | 11 +++++++++ 8 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 src/AIoTC_Const.h diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt index 2e95a3ae2..556ed7a8c 100644 --- a/extras/test/CMakeLists.txt +++ b/extras/test/CMakeLists.txt @@ -9,6 +9,7 @@ project(testArduinoIoTCloud) ########################################################################## include_directories(include) +include_directories(../../src) include_directories(../../src/cbor) include_directories(../../src/property) include_directories(../../src/utility/ota) diff --git a/extras/test/src/test_publishEvery.cpp b/extras/test/src/test_publishEvery.cpp index cc432b178..89f2ce6a8 100644 --- a/extras/test/src/test_publishEvery.cpp +++ b/extras/test/src/test_publishEvery.cpp @@ -9,6 +9,7 @@ #include #include +#include #include /************************************************************************************** diff --git a/src/AIoTC_Const.h b/src/AIoTC_Const.h new file mode 100644 index 000000000..c6249ebe8 --- /dev/null +++ b/src/AIoTC_Const.h @@ -0,0 +1,34 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_AIOTC_CONST_H_ +#define ARDUINO_AIOTC_CONST_H_ + +/****************************************************************************** + CONSTANTS + ******************************************************************************/ + +static bool const ON = true; +static bool const OFF = false; + +static long const ON_CHANGE = -1; +static long const SECONDS = 1; +static long const MINUTES = 60; +static long const HOURS = 3600; +static long const DAYS = 86400; + +#endif /* ARDUINO_AIOTC_CONST_H_ */ diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index c15bc50dd..17a03a1cb 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -27,8 +27,11 @@ #include #include +#include "AIoTC_Const.h" + #include "cbor/ArduinoCloudThing.h" +#include "property/Property.h" #include "property/PropertyContainer.h" #include "property/types/CloudWrapperBool.h" #include "property/types/CloudWrapperFloat.h" diff --git a/src/cbor/ArduinoCloudThing.cpp b/src/cbor/ArduinoCloudThing.cpp index 9bfb50902..6b2351d07 100644 --- a/src/cbor/ArduinoCloudThing.cpp +++ b/src/cbor/ArduinoCloudThing.cpp @@ -418,18 +418,3 @@ double ArduinoCloudThing::convertCborHalfFloatToDouble(uint16_t const half_val) } return half_val & 0x8000 ? -val : val; } - -void onAutoSync(Property & property) { - if (property.getLastCloudChangeTimestamp() > property.getLastLocalChangeTimestamp()) { - property.fromCloudToLocal(); - property.execCallbackOnChange(); - } -} - -void onForceCloudSync(Property & property) { - property.fromCloudToLocal(); - property.execCallbackOnChange(); -} - -void onForceDeviceSync(Property & /* property */) { -} diff --git a/src/cbor/ArduinoCloudThing.h b/src/cbor/ArduinoCloudThing.h index 023d6cb3a..77d6c44f2 100644 --- a/src/cbor/ArduinoCloudThing.h +++ b/src/cbor/ArduinoCloudThing.h @@ -46,30 +46,6 @@ #include "../property/types/automation/CloudTemperature.h" #include "../property/types/automation/CloudTelevision.h" -/****************************************************************************** - CONSTANTS - ******************************************************************************/ - -static bool const ON = true; -static bool const OFF = false; - -static long const ON_CHANGE = -1; -static long const SECONDS = 1; -static long const MINUTES = 60; -static long const HOURS = 3600; -static long const DAYS = 86400; - -/****************************************************************************** - SYNCHRONIZATION CALLBACKS - ******************************************************************************/ - -void onAutoSync(Property & property); -#define MOST_RECENT_WINS onAutoSync -void onForceCloudSync(Property & property); -#define CLOUD_WINS onForceCloudSync -void onForceDeviceSync(Property & property); -#define DEVICE_WINS onForceDeviceSync // The device property value is already the correct one. The cloud property value will be synchronized at the next update cycle. - /****************************************************************************** CLASS DECLARATION ******************************************************************************/ diff --git a/src/property/Property.cpp b/src/property/Property.cpp index 7870534bf..e1e14b700 100644 --- a/src/property/Property.cpp +++ b/src/property/Property.cpp @@ -325,3 +325,23 @@ unsigned long Property::getLastLocalChangeTimestamp() { void Property::setIdentifier(int identifier) { _identifier = identifier; } + +/****************************************************************************** + SYNCHRONIZATION CALLBACKS + ******************************************************************************/ + +void onAutoSync(Property & property) { + if (property.getLastCloudChangeTimestamp() > property.getLastLocalChangeTimestamp()) { + property.fromCloudToLocal(); + property.execCallbackOnChange(); + } +} + +void onForceCloudSync(Property & property) { + property.fromCloudToLocal(); + property.execCallbackOnChange(); +} + +void onForceDeviceSync(Property & /* property */) { + +} diff --git a/src/property/Property.h b/src/property/Property.h index e89d543ba..e238dd7e8 100644 --- a/src/property/Property.h +++ b/src/property/Property.h @@ -235,4 +235,15 @@ inline bool operator == (Property const & lhs, Property const & rhs) { return (lhs.name() == rhs.name()); } +/****************************************************************************** + SYNCHRONIZATION CALLBACKS + ******************************************************************************/ + +void onAutoSync(Property & property); +#define MOST_RECENT_WINS onAutoSync +void onForceCloudSync(Property & property); +#define CLOUD_WINS onForceCloudSync +void onForceDeviceSync(Property & property); +#define DEVICE_WINS onForceDeviceSync // The device property value is already the correct one. The cloud property value will be synchronized at the next update cycle. + #endif /* ARDUINO_CLOUD_PROPERTY_HPP_ */ From d49b5d4f2e4a3b6ae0202971a8188a12009eb59b Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 07:46:56 +0200 Subject: [PATCH 4/6] Renaming ArduinoCloudThing into CBORDecoder and turn it into a purely static class --- src/ArduinoIoTCloud.h | 3 +- src/ArduinoIoTCloudLPWAN.cpp | 3 +- src/ArduinoIoTCloudTCP.cpp | 6 +- src/cbor/ArduinoCloudThing.h | 111 ----------------- ...{ArduinoCloudThing.cpp => CBORDecoder.cpp} | 115 +++++++----------- src/cbor/CBORDecoder.h | 85 +++++++++++++ src/property/PropertyContainer.h | 18 +++ 7 files changed, 154 insertions(+), 187 deletions(-) delete mode 100644 src/cbor/ArduinoCloudThing.h rename src/cbor/{ArduinoCloudThing.cpp => CBORDecoder.cpp} (73%) create mode 100644 src/cbor/CBORDecoder.h diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 17a03a1cb..565f3fa2e 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -29,7 +29,7 @@ #include "AIoTC_Const.h" -#include "cbor/ArduinoCloudThing.h" +#include "cbor/CBORDecoder.h" #include "property/Property.h" #include "property/PropertyContainer.h" @@ -146,7 +146,6 @@ class ArduinoIoTCloudClass inline ArduinoIoTConnectionStatus getIoTStatus() { return _iot_status; } ConnectionHandler * _connection = nullptr; - ArduinoCloudThing _thing; PropertyContainer _property_container; ArduinoIoTConnectionStatus _iot_status = ArduinoIoTConnectionStatus::IDLE; diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 9bcb80fee..acf840ef4 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -58,7 +58,6 @@ int ArduinoIoTCloudLPWAN::begin(ConnectionHandler& connection, bool retry) { _connection = &connection; _retryEnable = retry; - _thing.begin(&_property_container); return 1; } @@ -93,7 +92,7 @@ void ArduinoIoTCloudLPWAN::update() msgBuf[i++] = _connection->read(); } - _thing.decode(msgBuf, sizeof(msgBuf)); + CBORDecoder::decode(_property_container, msgBuf, sizeof(msgBuf)); } sendPropertiesToCloud(); diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 4efe6ed09..0a075156a 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -134,8 +134,6 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort) _dataTopicIn = getTopic_datain(); _ota_topic_in = getTopic_ota_in(); - _thing.begin(&_property_container); - printConnectionStatus(_iot_status); return 1; @@ -269,10 +267,10 @@ void ArduinoIoTCloudTCP::handleMessage(int length) CloudSerial.appendStdin((uint8_t*)bytes, length); } if (_dataTopicIn == topic) { - _thing.decode((uint8_t*)bytes, length); + CBORDecoder::decode(_property_container, (uint8_t*)bytes, length); } if ((_shadowTopicIn == topic) && _syncStatus == ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES) { - _thing.decode((uint8_t*)bytes, length, true); + CBORDecoder::decode(_property_container, (uint8_t*)bytes, length, true); sendPropertiesToCloud(); _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_VALUES_PROCESSED; } diff --git a/src/cbor/ArduinoCloudThing.h b/src/cbor/ArduinoCloudThing.h deleted file mode 100644 index 77d6c44f2..000000000 --- a/src/cbor/ArduinoCloudThing.h +++ /dev/null @@ -1,111 +0,0 @@ -// -// This file is part of ArduinoCloudThing -// -// Copyright 2019 ARDUINO SA (http://www.arduino.cc/) -// -// This software is released under the GNU General Public License version 3, -// which covers the main part of ArduinoCloudThing. -// The terms of this license can be found at: -// https://www.gnu.org/licenses/gpl-3.0.en.html -// -// You can be released from the requirements of the above licenses by purchasing -// a commercial license. Buying such a license is mandatory if you want to modify or -// otherwise use the software for commercial activities involving the Arduino -// software without disclosing the source code of your own applications. To purchase -// a commercial license, send an email to license@arduino.cc. -// - -#ifndef ARDUINO_CLOUD_THING_H_ -#define ARDUINO_CLOUD_THING_H_ - -/****************************************************************************** - INCLUDE - ******************************************************************************/ - -#undef max -#undef min -#include - -#include "../property/PropertyContainer.h" - -#include "../property/types/CloudBool.h" -#include "../property/types/CloudFloat.h" -#include "../property/types/CloudInt.h" -#include "../property/types/CloudString.h" -#include "../property/types/CloudLocation.h" -#include "../property/types/CloudColor.h" -#include "../property/types/CloudWrapperBase.h" - -#include "../property/types/automation/CloudColoredLight.h" -#include "../property/types/automation/CloudContactSensor.h" -#include "../property/types/automation/CloudDimmedLight.h" -#include "../property/types/automation/CloudLight.h" -#include "../property/types/automation/CloudMotionSensor.h" -#include "../property/types/automation/CloudSmartPlug.h" -#include "../property/types/automation/CloudSwitch.h" -#include "../property/types/automation/CloudTemperature.h" -#include "../property/types/automation/CloudTelevision.h" - -/****************************************************************************** - CLASS DECLARATION - ******************************************************************************/ - -class ArduinoCloudThing { - - public: - ArduinoCloudThing(); - - void begin(PropertyContainer * property_container); - - /* decode a CBOR payload received from the cloud */ - void decode(uint8_t const * const payload, size_t const length, bool isSyncMessage = false); - - - private: - PropertyContainer * _property_container; - /* Indicates the if the message received to be decoded is a response to the getLastValues inquiry */ - bool _isSyncMessage; - /* List of map data that will hold all the attributes of a property */ - std::list _map_data_list; - /* Current property name during decoding: use to look for a new property in the senml value array */ - String _currentPropertyName; - unsigned long _currentPropertyBaseTime, - _currentPropertyTime; - - enum class MapParserState { - EnterMap, - MapKey, - UndefinedKey, - BaseVersion, - BaseName, - BaseTime, - Name, - Value, - StringValue, - BooleanValue, - Time, - LeaveMap, - Complete, - Error - }; - - MapParserState handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data); - MapParserState handle_MapKey(CborValue * value_iter); - MapParserState handle_UndefinedKey(CborValue * value_iter); - MapParserState handle_BaseVersion(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_BaseName(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_BaseTime(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_Name(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_Value(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_StringValue(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_BooleanValue(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_Time(CborValue * value_iter, CborMapData * map_data); - MapParserState handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data); - - static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val); - static double convertCborHalfFloatToDouble(uint16_t const half_val); - void freeMapDataList(std::list * map_data_list); - -}; - -#endif /* ARDUINO_CLOUD_THING_H_ */ diff --git a/src/cbor/ArduinoCloudThing.cpp b/src/cbor/CBORDecoder.cpp similarity index 73% rename from src/cbor/ArduinoCloudThing.cpp rename to src/cbor/CBORDecoder.cpp index 6b2351d07..f2f431905 100644 --- a/src/cbor/ArduinoCloudThing.cpp +++ b/src/cbor/CBORDecoder.cpp @@ -1,10 +1,10 @@ // -// This file is part of ArduinoCloudThing +// This file is part of CBORDecoder // // Copyright 2019 ARDUINO SA (http://www.arduino.cc/) // // This software is released under the GNU General Public License version 3, -// which covers the main part of ArduinoCloudThing. +// which covers the main part of CBORDecoder. // The terms of this license can be found at: // https://www.gnu.org/licenses/gpl-3.0.en.html // @@ -25,53 +25,32 @@ #undef min #include -#include "ArduinoCloudThing.h" - -/****************************************************************************** - CTOR/DTOR - ******************************************************************************/ - -ArduinoCloudThing::ArduinoCloudThing() : - _property_container{nullptr}, - _isSyncMessage(false), - _currentPropertyName(""), - _currentPropertyBaseTime(0), - _currentPropertyTime(0) -{} +#include "CBORDecoder.h" /****************************************************************************** PUBLIC MEMBER FUNCTIONS ******************************************************************************/ -void ArduinoCloudThing::begin(PropertyContainer * property_container) +void CBORDecoder::decode(PropertyContainer & property_container, uint8_t const * const payload, size_t const length, bool isSyncMessage) { - _property_container = property_container; -} - -void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const length, bool isSyncMessage) { - _isSyncMessage = isSyncMessage; - CborParser parser; - CborValue array_iter, - map_iter, - value_iter; - - if (cbor_parser_init(payload, length, 0, &parser, &array_iter) != CborNoError) { + CborValue array_iter, map_iter,value_iter; + /* List of map data that will hold all the attributes of a property */ + std::list map_data_list; + /* Current property name during decoding: use to look for a new property in the senml value array */ + String current_property_name; + unsigned long current_property_base_time{0}, current_property_time{0}; + + if (cbor_parser_init(payload, length, 0, &parser, &array_iter) != CborNoError) return; - } - if (array_iter.type != CborArrayType) { + if (array_iter.type != CborArrayType) return; - } - if (cbor_value_enter_container(&array_iter, &map_iter) != CborNoError) { + if (cbor_value_enter_container(&array_iter, &map_iter) != CborNoError) return; - } - - CborMapData *map_data = nullptr; - _map_data_list.clear(); - _currentPropertyName = ""; + CborMapData * map_data = nullptr; MapParserState current_state = MapParserState::EnterMap, next_state = MapParserState::Error; @@ -86,13 +65,13 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt case MapParserState::BaseName : next_state = handle_BaseName(&value_iter, map_data); break; case MapParserState::BaseTime : next_state = handle_BaseTime(&value_iter, map_data); break; case MapParserState::Time : next_state = handle_Time(&value_iter, map_data); break; - case MapParserState::Name : next_state = handle_Name(&value_iter, map_data); break; + case MapParserState::Name : next_state = handle_Name(&value_iter, map_data, property_container); break; case MapParserState::Value : next_state = handle_Value(&value_iter, map_data); break; case MapParserState::StringValue : next_state = handle_StringValue(&value_iter, map_data); break; case MapParserState::BooleanValue : next_state = handle_BooleanValue(&value_iter, map_data); break; - case MapParserState::LeaveMap : next_state = handle_LeaveMap(&map_iter, &value_iter, map_data); break; - case MapParserState::Complete : /* Nothing to do */ break; - case MapParserState::Error : return; break; + case MapParserState::LeaveMap : next_state = handle_LeaveMap(&map_iter, &value_iter, map_data, property_container, current_property_name, current_property_base_time, current_property_time, isSyncMessage, map_data_list); break; + case MapParserState::Complete : /* Nothing to do */ break; + case MapParserState::Error : return; break; } current_state = next_state; @@ -103,7 +82,7 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt PRIVATE MEMBER FUNCTIONS ******************************************************************************/ -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_get_type(map_iter) == CborMapType) { @@ -116,7 +95,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_EnterMap(CborValue * return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_MapKey(CborValue * value_iter) { +CBORDecoder::MapParserState CBORDecoder::handle_MapKey(CborValue * value_iter) { MapParserState next_state = MapParserState::Error; if (cbor_value_at_end(value_iter)) { @@ -155,7 +134,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_MapKey(CborValue * v return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_UndefinedKey(CborValue * value_iter) { +CBORDecoder::MapParserState CBORDecoder::handle_UndefinedKey(CborValue * value_iter) { MapParserState next_state = MapParserState::Error; if (cbor_value_advance(value_iter) == CborNoError) { @@ -165,7 +144,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_UndefinedKey(CborVal return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseVersion(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseVersion(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_integer(value_iter)) { @@ -182,7 +161,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseVersion(CborValu return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseName(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseName(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { @@ -198,7 +177,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseName(CborValue * return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseTime(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseTime(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; @@ -213,7 +192,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BaseTime(CborValue * return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_Name(CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { @@ -240,7 +219,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * val map_data->name_identifier.set(val & 255); map_data->attribute_identifier.set(val >> 8); map_data->light_payload.set(true); - String name = getPropertyNameByIdentifier(*_property_container, val); + String name = getPropertyNameByIdentifier(property_container, val); map_data->name.set(name); @@ -255,7 +234,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Name(CborValue * val return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Value(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_Value(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; @@ -270,7 +249,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Value(CborValue * va return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_StringValue(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_StringValue(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { @@ -286,7 +265,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_StringValue(CborValu return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BooleanValue(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BooleanValue(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; bool val = false; @@ -301,7 +280,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_BooleanValue(CborVal return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Time(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_Time(CborValue * value_iter, CborMapData * map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; @@ -316,7 +295,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_Time(CborValue * val return next_state; } -ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list) { MapParserState next_state = MapParserState::Error; if (map_data->name.isSet()) { String propertyName; @@ -327,23 +306,23 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * propertyName = map_data->name.get(); } - if (_currentPropertyName != "" && propertyName != _currentPropertyName) { + if (current_property_name != "" && propertyName != current_property_name) { /* Update the property containers depending on the parsed data */ - updateProperty(*_property_container, _currentPropertyName, _currentPropertyBaseTime + _currentPropertyTime, _isSyncMessage, &_map_data_list); + updateProperty(property_container, current_property_name, current_property_base_time + current_property_time, is_sync_message, &map_data_list); /* Reset current property data */ - freeMapDataList(&_map_data_list); - _currentPropertyBaseTime = 0; - _currentPropertyTime = 0; + freeMapDataList(&map_data_list); + current_property_base_time = 0; + current_property_time = 0; } /* Compute the cloud change event baseTime and Time */ if (map_data->base_time.isSet()) { - _currentPropertyBaseTime = (unsigned long)(map_data->base_time.get()); + current_property_base_time = (unsigned long)(map_data->base_time.get()); } - if (map_data->time.isSet() && (map_data->time.get() > _currentPropertyTime)) { - _currentPropertyTime = (unsigned long)map_data->time.get(); + if (map_data->time.isSet() && (map_data->time.get() > current_property_time)) { + current_property_time = (unsigned long)map_data->time.get(); } - _map_data_list.push_back(map_data); - _currentPropertyName = propertyName; + map_data_list.push_back(map_data); + current_property_name = propertyName; } /* Transition into the next map if available, otherwise finish */ @@ -352,9 +331,9 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * next_state = MapParserState::EnterMap; } else { /* Update the property containers depending on the parsed data */ - updateProperty(*_property_container, _currentPropertyName, _currentPropertyBaseTime + _currentPropertyTime, _isSyncMessage, &_map_data_list); + updateProperty(property_container, current_property_name, current_property_base_time + current_property_time, is_sync_message, &map_data_list); /* Reset last property data */ - freeMapDataList(&_map_data_list); + freeMapDataList(&map_data_list); next_state = MapParserState::Complete; } } @@ -362,7 +341,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * return next_state; } -void ArduinoCloudThing::freeMapDataList(std::list * map_data_list) +void CBORDecoder::freeMapDataList(std::list * map_data_list) { std::for_each(map_data_list->begin(), map_data_list->end(), @@ -373,7 +352,7 @@ void ArduinoCloudThing::freeMapDataList(std::list * map_data_list map_data_list->clear(); } -bool ArduinoCloudThing::ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val) { +bool CBORDecoder::ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val) { if (cbor_value_is_integer(value_iter)) { int64_t val = 0; @@ -405,7 +384,7 @@ bool ArduinoCloudThing::ifNumericConvertToDouble(CborValue * value_iter, double } /* Source Idea from https://tools.ietf.org/html/rfc7049 : Page: 50 */ -double ArduinoCloudThing::convertCborHalfFloatToDouble(uint16_t const half_val) { +double CBORDecoder::convertCborHalfFloatToDouble(uint16_t const half_val) { int exp = (half_val >> 10) & 0x1f; int mant = half_val & 0x3ff; double val; diff --git a/src/cbor/CBORDecoder.h b/src/cbor/CBORDecoder.h new file mode 100644 index 000000000..796ca5eed --- /dev/null +++ b/src/cbor/CBORDecoder.h @@ -0,0 +1,85 @@ +// +// This file is part of ArduinoCloudThing +// +// Copyright 2019 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of ArduinoCloudThing. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to modify or +// otherwise use the software for commercial activities involving the Arduino +// software without disclosing the source code of your own applications. To purchase +// a commercial license, send an email to license@arduino.cc. +// + +#ifndef ARDUINO_CBOR_CBOR_DECODER_H_ +#define ARDUINO_CBOR_CBOR_DECODER_H_ + +/****************************************************************************** + INCLUDE + ******************************************************************************/ + +#undef max +#undef min +#include + +#include "../property/PropertyContainer.h" + +/****************************************************************************** + CLASS DECLARATION + ******************************************************************************/ + +class CBORDecoder +{ + +public: + + /* decode a CBOR payload received from the cloud */ + static void decode(PropertyContainer & property_container, uint8_t const * const payload, size_t const length, bool isSyncMessage = false); + + +private: + + CBORDecoder() { } + CBORDecoder(CBORDecoder const &) { } + + enum class MapParserState { + EnterMap, + MapKey, + UndefinedKey, + BaseVersion, + BaseName, + BaseTime, + Name, + Value, + StringValue, + BooleanValue, + Time, + LeaveMap, + Complete, + Error + }; + + static MapParserState handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data); + static MapParserState handle_MapKey(CborValue * value_iter); + static MapParserState handle_UndefinedKey(CborValue * value_iter); + static MapParserState handle_BaseVersion(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_BaseName(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_BaseTime(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_Name(CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container); + static MapParserState handle_Value(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_StringValue(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_BooleanValue(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_Time(CborValue * value_iter, CborMapData * map_data); + static MapParserState handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list); + + static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val); + static double convertCborHalfFloatToDouble(uint16_t const half_val); + static void freeMapDataList(std::list * map_data_list); + +}; + +#endif /* ARDUINO_CBOR_CBOR_DECODER_H_ */ diff --git a/src/property/PropertyContainer.h b/src/property/PropertyContainer.h index 7047bd0ba..400d9ae82 100644 --- a/src/property/PropertyContainer.h +++ b/src/property/PropertyContainer.h @@ -28,6 +28,24 @@ #undef min #include +#include "types/CloudBool.h" +#include "types/CloudFloat.h" +#include "types/CloudInt.h" +#include "types/CloudString.h" +#include "types/CloudLocation.h" +#include "types/CloudColor.h" +#include "types/CloudWrapperBase.h" + +#include "types/automation/CloudColoredLight.h" +#include "types/automation/CloudContactSensor.h" +#include "types/automation/CloudDimmedLight.h" +#include "types/automation/CloudLight.h" +#include "types/automation/CloudMotionSensor.h" +#include "types/automation/CloudSmartPlug.h" +#include "types/automation/CloudSwitch.h" +#include "types/automation/CloudTemperature.h" +#include "types/automation/CloudTelevision.h" + /****************************************************************************** DECLARATION OF getTime ******************************************************************************/ From 57c374c0966e86cbdf7628fdc6519babdeb9af05 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 07:47:11 +0200 Subject: [PATCH 5/6] Updating unit tests accordingly --- extras/test/CMakeLists.txt | 2 +- extras/test/src/test_CloudColor.cpp | 3 +- extras/test/src/test_CloudLocation.cpp | 2 +- extras/test/src/test_callback.cpp | 68 +++---- extras/test/src/test_decode.cpp | 171 ++++++------------ extras/test/src/test_encode.cpp | 77 ++------ extras/test/src/test_publishEvery.cpp | 5 +- extras/test/src/test_publishOnChange.cpp | 5 +- .../src/test_publishOnChangeRateLimit.cpp | 5 +- extras/test/src/test_readOnly.cpp | 10 +- extras/test/src/test_writeOnly.cpp | 8 +- 11 files changed, 116 insertions(+), 240 deletions(-) diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt index 556ed7a8c..0e680a94a 100644 --- a/extras/test/CMakeLists.txt +++ b/extras/test/CMakeLists.txt @@ -56,7 +56,7 @@ set(TEST_DUT_SRCS ../../src/property/Property.cpp ../../src/property/PropertyContainer.cpp - ../../src/cbor/ArduinoCloudThing.cpp + ../../src/cbor/CBORDecoder.cpp ../../src/cbor/CBOREncoder.cpp ../../src/cbor/lib/tinycbor/src/cborencoder.c ../../src/cbor/lib/tinycbor/src/cborencoder_close_container_checked.c diff --git a/extras/test/src/test_CloudColor.cpp b/extras/test/src/test_CloudColor.cpp index 8d3f2d873..b621eff28 100644 --- a/extras/test/src/test_CloudColor.cpp +++ b/extras/test/src/test_CloudColor.cpp @@ -9,7 +9,8 @@ #include #include -#include + +#include /************************************************************************************** TEST CODE diff --git a/extras/test/src/test_CloudLocation.cpp b/extras/test/src/test_CloudLocation.cpp index 63c71fd88..079bfaff9 100644 --- a/extras/test/src/test_CloudLocation.cpp +++ b/extras/test/src/test_CloudLocation.cpp @@ -8,7 +8,7 @@ #include -#include +#include /************************************************************************************** TEST CODE diff --git a/extras/test/src/test_callback.cpp b/extras/test/src/test_callback.cpp index cfc81bcf2..1a97832df 100644 --- a/extras/test/src/test_callback.cpp +++ b/extras/test/src/test_callback.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "types/CloudWrapperBool.h" @@ -41,16 +41,14 @@ SCENARIO("A callback is registered via 'onUpdate' to be called on property chang GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 10; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(externalCallbackV2); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(callback_called_protocol_v2 == true); } @@ -71,16 +69,14 @@ void switch_callback() { SCENARIO("A (boolean) property is manipulated in the callback to its origin state", "[ArduinoCloudThing::decode]") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); addPropertyToContainer(property_container, switch_turned_on, "switch_turned_on", Permission::ReadWrite).onUpdate(switch_callback); /* [{0: "switch_turned_on", 4: true}] = 81 A2 00 70 73 77 69 74 63 68 5F 74 75 72 6E 65 64 5F 6F 6E 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x70, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5F, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x5F, 0x6F, 0x6E, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(switch_callback_called == true); @@ -117,9 +113,7 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test.setLastLocalChangeTimestamp(1550138809); @@ -127,7 +121,7 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == true); @@ -145,9 +139,7 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; test.setLastLocalChangeTimestamp(1550138811); @@ -155,7 +147,7 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == false); @@ -172,9 +164,7 @@ SCENARIO("Primitive property: After a connection/reconnection an incoming cbor p change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, *p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; updateTimestampOnLocallyChangedProperties(property_container); @@ -184,7 +174,7 @@ SCENARIO("Primitive property: After a connection/reconnection an incoming cbor p /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == true); @@ -203,9 +193,7 @@ SCENARIO("Primitive property: After a connection/reconnection an incoming cbor p change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, *p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; updateTimestampOnLocallyChangedProperties(property_container); @@ -215,7 +203,7 @@ SCENARIO("Primitive property: After a connection/reconnection an incoming cbor p /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == false); @@ -231,9 +219,7 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); location_test.setLastLocalChangeTimestamp(1550138809); @@ -241,7 +227,7 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl uint8_t const payload[] = { 0x82, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0x02, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0x03 }; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == true); @@ -263,9 +249,7 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); location_test.setLastLocalChangeTimestamp(1550138811); @@ -273,7 +257,7 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl uint8_t const payload[] = { 0x82, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0x02, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0x03 }; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == false); @@ -301,15 +285,13 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_device_sync_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == false); @@ -334,15 +316,13 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_cloud_sync_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == true); REQUIRE(change_callback_called == true); @@ -361,15 +341,13 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed. change_callback_called = false; PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + addPropertyToContainer(property_container, test, "test", Permission::ReadWrite).onUpdate(change_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length, true); + CBORDecoder::decode(property_container, payload, payload_length, true); REQUIRE(sync_callback_called == false); REQUIRE(change_callback_called == false); diff --git a/extras/test/src/test_decode.cpp b/extras/test/src/test_decode.cpp index e4093460e..19a9a54eb 100644 --- a/extras/test/src/test_decode.cpp +++ b/extras/test/src/test_decode.cpp @@ -11,7 +11,8 @@ #include #include -#include + +#include #include "types/CloudWrapperBool.h" #include "types/CloudWrapperFloat.h" #include "types/CloudWrapperInt.h" @@ -36,16 +37,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A boolean property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudBool test = true; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{0: "test", 4: false}] = 81 A2 00 64 74 65 73 74 04 F4 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF4}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == false); } @@ -57,9 +56,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /*An integer identifier has been encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudBool test = true; /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ addPropertyToContainer(property_container, test, "test", Permission::ReadWrite, 1); @@ -67,7 +64,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: 1, 4: false}] = 81 A2 00 01 04 F4 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x01, 0x04, 0xF4}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == false); } @@ -78,31 +75,27 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A int property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == 7); } GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{0: "test", 2: -7}] = 81 A2 00 64 74 65 73 74 02 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x26}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == -7); } @@ -113,16 +106,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A float property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudFloat test = 0.0f; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.1459}] = 81 A2 00 64 74 65 73 74 02 FB 40 09 2A CD 9E 83 E4 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFB, 0x40, 0x09, 0x2A, 0xCD, 0x9E, 0x83, 0xE4, 0x26}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == Approx(3.1459).epsilon(0.01)); } @@ -133,16 +124,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A String property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudString str_test; str_test = "test"; addPropertyToContainer(property_container, str_test, "test", Permission::ReadWrite); /* [{0: "test", 3: "testtt"}] = 81 A2 00 64 74 65 73 74 03 66 74 65 73 74 74 74 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x66, 0x74, 0x65, 0x73, 0x74, 0x74, 0x74}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(str_test == "testtt"); } @@ -153,15 +142,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Location property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudLocation location_test = CloudLocation(0, 1); addPropertyToContainer(property_container, location_test, "test", Permission::ReadWrite); /* [{0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 82 A2 00 68 74 65 73 74 3A 6C 61 74 02 02 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 03*/ uint8_t const payload[] = { 0x82, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0x02, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0x03 }; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); Location location_compare = Location(2, 3); Location value_location_test = location_test.getValue(); REQUIRE(value_location_test.lat == location_compare.lat); @@ -174,16 +161,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Color property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudColor color_test = CloudColor(0.0, 0.0, 0.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); /* [{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x83, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); Color color_compare = Color(2.0, 2.0, 2.0); Color value_color_test = color_test.getValue(); @@ -201,9 +186,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /*An integer identifier has been encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudColor color_test = CloudColor(0.0, 0.0, 0.0); /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ @@ -211,7 +194,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: 257, 2: 2.0},{0: 513, 2: 2.0},{0: 769, 2: 2.0}] = 83 A2 00 19 01 01 02 FA 40 00 00 00 A2 00 19 02 01 02 FA 40 00 00 00 A2 00 19 03 01 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x83, 0xA2, 0x00, 0x19, 0x01, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x02, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x03, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); Color color_compare = Color(2.0, 2.0, 2.0); Color value_color_test = color_test.getValue(); @@ -228,16 +211,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A ColoredLight property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudColoredLight color_test = CloudColoredLight(false, 0.0, 0.0, 0.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); ColoredLight color_compare = ColoredLight(true, 2.0, 2.0, 2.0); ColoredLight value_color_test = color_test.getValue(); @@ -255,9 +236,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Television property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudTelevision tv_test = CloudTelevision(false, 0, false, PlaybackCommands::Stop, InputValue::AUX1, 0); @@ -265,7 +244,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test:swi", 4: true},{0: "test:vol", 2: 50},{0: "test:mut", 2: false},{0: "test:pbc", 2: 3},{0: "test:inp", 2: 55},{0: "test:cha", 2: 7}] = 9F A2 00 68 74 65 73 74 3A 73 77 69 04 F5 A2 00 68 74 65 73 74 3A 76 6F 6C 02 18 32 A2 00 68 74 65 73 74 3A 6D 75 74 04 F4 A2 00 68 74 65 73 74 3A 70 62 63 02 03 A2 00 68 74 65 73 74 3A 69 6E 70 02 18 37 A2 00 68 74 65 73 74 3A 63 68 61 02 07 FF */ uint8_t const payload[] = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x76, 0x6F, 0x6C, 0x02, 0x18, 0x32, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6D, 0x75, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x70, 0x62, 0x63, 0x02, 0x03, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x69, 0x6E, 0x70, 0x02, 0x18, 0x37, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x02, 0x07, 0xFF}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); Television tv_compare = Television(true, 50, false, PlaybackCommands::Play, InputValue::TV, 7); Television value_tv_test = tv_test.getValue(); @@ -285,16 +264,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A DimmedLight property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudDimmedLight light_test = CloudDimmedLight(false, 0.0); addPropertyToContainer(property_container, light_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x82, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); DimmedLight light_compare = DimmedLight(true, 2.0); DimmedLight value_light_test = light_test.getValue(); @@ -310,9 +287,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Light property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudLight light_test; light_test = false; @@ -320,7 +295,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(light_test == true); } @@ -331,9 +306,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A ContactSensor property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudContactSensor contact_test; contact_test = false; @@ -341,7 +314,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(contact_test == true); } @@ -352,9 +325,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A MotionSensor property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudMotionSensor motion_test; motion_test = false; @@ -362,7 +333,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(motion_test == true); } @@ -373,9 +344,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A SmartPlug property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudSmartPlug plug_test; plug_test = false; @@ -383,7 +352,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(plug_test == true); } @@ -394,9 +363,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Switch property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudSwitch switch_test; switch_test = false; @@ -404,7 +371,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(switch_test == true); } @@ -415,9 +382,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Temperature property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudTemperature test; test = 0.0f; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); @@ -425,7 +390,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /* [{0: "test", 2: 3.1459}] = 81 A2 00 64 74 65 73 74 02 FB 40 09 2A CD 9E 83 E4 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFB, 0x40, 0x09, 0x2A, 0xCD, 0x9E, 0x83, 0xE4, 0x26}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == Approx(3.1459).epsilon(0.01)); } @@ -437,9 +402,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") GIVEN("CloudProtocol::V2") { WHEN("Multiple properties of different type are changed via CBOR message") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudBool bool_test = false; CloudInt int_test = 1; CloudFloat float_test = 2.0f; @@ -455,7 +418,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x69, 0x62, 0x6F, 0x6F, 0x6C, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x69, 0x6E, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0x0A, 0xA2, 0x00, 0x6A, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0xF9, 0x4D, 0x00, 0xA2, 0x00, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6D, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6E, 0x6F}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(bool_test == true); REQUIRE(int_test == 10); @@ -467,9 +430,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("Multiple properties of different type are synchronized via CBOR message. FORCE_CLOUD_SYNC is passed as synchronization function and as a consequence values contained in the incoming message are stored in the properties") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudBool bool_test = false; CloudInt int_test = 1; CloudFloat float_test = 2.0f; @@ -485,7 +446,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x69, 0x62, 0x6F, 0x6F, 0x6C, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x69, 0x6E, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0x0A, 0xA2, 0x00, 0x6A, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0xF9, 0x4D, 0x00, 0xA2, 0x00, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6D, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6E, 0x6F}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t), true); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t), true); REQUIRE(bool_test == true); REQUIRE(int_test == 10); @@ -497,9 +458,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("Multiple primitive properties of different type are synchronized via CBOR message. FORCE_CLOUD_SYNC is passed as synchronization function and as a consequence values contained in the incoming message are stored in the properties") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + int int_test = 1; bool bool_test = false; float float_test = 2.0f; @@ -522,7 +481,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x69, 0x62, 0x6F, 0x6F, 0x6C, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x69, 0x6E, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0x0A, 0xA2, 0x00, 0x6A, 0x66, 0x6C, 0x6F, 0x61, 0x74, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x02, 0xF9, 0x4D, 0x00, 0xA2, 0x00, 0x68, 0x73, 0x74, 0x72, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x03, 0x6D, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6E, 0x6F}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t), true); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t), true); REQUIRE(bool_test == true); REQUIRE(int_test == 10); @@ -534,9 +493,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("Multiple String properties are changed via CBOR message") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudString str_1("hello"), str_2("arduino"), str_3("cloud"), @@ -551,7 +508,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") = 84 A2 00 65 73 74 72 5F 31 03 68 49 27 64 20 6C 69 6B 65 A2 00 65 73 74 72 5F 32 03 61 61 A2 00 65 73 74 72 5F 33 03 63 63 75 70 A2 00 65 73 74 72 5F 34 03 69 6F 66 20 63 6F 66 66 65 65 */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x65, 0x73, 0x74, 0x72, 0x5F, 0x31, 0x03, 0x68, 0x49, 0x27, 0x64, 0x20, 0x6C, 0x69, 0x6B, 0x65, 0xA2, 0x00, 0x65, 0x73, 0x74, 0x72, 0x5F, 0x32, 0x03, 0x61, 0x61, 0xA2, 0x00, 0x65, 0x73, 0x74, 0x72, 0x5F, 0x33, 0x03, 0x63, 0x63, 0x75, 0x70, 0xA2, 0x00, 0x65, 0x73, 0x74, 0x72, 0x5F, 0x34, 0x03, 0x69, 0x6F, 0x66, 0x20, 0x63, 0x6F, 0x66, 0x66, 0x65, 0x65}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(str_1 == "I'd like"); REQUIRE(str_2 == "a"); @@ -566,15 +523,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR base name is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudString str = "hello"; addPropertyToContainer(property_container, str, "test", Permission::ReadWrite); /* [{-2: "some-test-base-name", 0: "test", 3: "test"}] = 81 A3 21 73 73 6F 6D 65 2D 74 65 73 74 2D 62 61 73 65 2D 6E 61 6D 65 00 64 74 65 73 74 03 64 74 65 73 74 */ uint8_t const payload[] = {0x81, 0xA3, 0x21, 0x73, 0x73, 0x6F, 0x6D, 0x65, 0x2D, 0x74, 0x65, 0x73, 0x74, 0x2D, 0x62, 0x61, 0x73, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x64, 0x74, 0x65, 0x73, 0x74}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(str == "test"); } @@ -585,15 +540,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR base time is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{-3: 123.456, 0: "test", 2: 1}] = 81 A3 22 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(test == 1); } @@ -604,15 +557,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR time is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{6: 123.456, 0: "test", 2: 1}] = 81 A3 06 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x06, 0xFB, 0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(test == 1); } @@ -623,15 +574,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR BaseVersion is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{-1: 1, 0: "test", 2: 1}] = 81 A3 20 01 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x20, 0x01, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(test == 1); } @@ -642,9 +591,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR BaseName, BaseTime and Time is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); @@ -652,7 +599,7 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") 81 A5 21 69 62 61 73 65 2D 6E 61 6D 65 22 FB 40 84 72 91 68 72 B0 21 06 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA5, 0x21, 0x69, 0x62, 0x61, 0x73, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0xFB, 0x40, 0x84, 0x72, 0x91, 0x68, 0x72, 0xB0, 0x21, 0x06, 0xFB, 0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(test == 1); } @@ -663,15 +610,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a invalid CBOR key is parsed") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); /* [{123: 123, 0: "test", 2: 1}] = 81 A3 18 7B 18 7B 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x18, 0x7B, 0x18, 0x7B, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; - thing.decode(payload, sizeof(payload) / sizeof(uint8_t)); + CBORDecoder::decode(property_container, payload, sizeof(payload) / sizeof(uint8_t)); REQUIRE(test == 1); } diff --git a/extras/test/src/test_encode.cpp b/extras/test/src/test_encode.cpp index 2045e7a47..063a97daa 100644 --- a/extras/test/src/test_encode.cpp +++ b/extras/test/src/test_encode.cpp @@ -11,7 +11,6 @@ #include #include -#include #include "types/CloudWrapperBool.h" #include "types/CloudWrapperFloat.h" #include "types/CloudWrapperInt.h" @@ -27,9 +26,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'bool' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudBool test = true; addPropertyToContainer(property_container, test, "test", Permission::ReadWrite); @@ -47,9 +44,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /*An integer identifier must be instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudBool test = true; /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ @@ -67,9 +62,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'int' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudInt int_test = 123; addPropertyToContainer(property_container, int_test, "test", Permission::ReadWrite); @@ -86,9 +79,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'float' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudFloat float_test = 3.14159; addPropertyToContainer(property_container, float_test, "test", Permission::ReadWrite); @@ -105,9 +96,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'String' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudString string_test; string_test = "test"; @@ -125,9 +114,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Location' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudLocation location_test = CloudLocation(2.0f, 3.0f); addPropertyToContainer(property_container, location_test, "test", Permission::ReadWrite); @@ -144,9 +131,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Color' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); @@ -164,9 +149,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") /*An integer identifier must be encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); /*The property is added with identifier 1 that will be used instead of the string "name" as property identifier */ @@ -184,9 +167,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'ColoredLight' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudColoredLight color_test = CloudColoredLight(true, 2.0, 2.0, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); @@ -203,9 +184,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Television' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudTelevision tv_test = CloudTelevision(true, 50, false, PlaybackCommands::Play, InputValue::TV, 7); addPropertyToContainer(property_container, tv_test, "test", Permission::ReadWrite); @@ -222,9 +201,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'DimmedLight' property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudDimmedLight color_test = CloudDimmedLight(true, 2.0); addPropertyToContainer(property_container, color_test, "test", Permission::ReadWrite); @@ -241,9 +218,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A light property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudLight test; test = true; @@ -261,9 +236,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A contact sensor property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudContactSensor test; test = true; @@ -281,9 +254,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A motion sensor property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudMotionSensor test; test = true; @@ -301,9 +272,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A smart plug property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudSmartPlug test; test = true; @@ -321,9 +290,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A Temperature property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudTemperature float_test; float_test = 3.14159; @@ -341,9 +308,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A switch property is added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - cbor::encode(property_container); + cbor::encode(property_container); CloudSwitch test; test = true; @@ -361,9 +326,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("Multiple properties are added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt int_test = 1; CloudBool bool_test = false; CloudFloat float_test = 2.0f; @@ -389,9 +352,7 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("Multiple primitive properties are added") { GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + int int_test = 1; bool bool_test = false; float float_test = 2.0f; diff --git a/extras/test/src/test_publishEvery.cpp b/extras/test/src/test_publishEvery.cpp index 89f2ce6a8..7d9886b3e 100644 --- a/extras/test/src/test_publishEvery.cpp +++ b/extras/test/src/test_publishEvery.cpp @@ -10,7 +10,6 @@ #include #include -#include /************************************************************************************** TEST CODE @@ -21,9 +20,7 @@ SCENARIO("A Arduino cloud property is published periodically", "[ArduinoCloudThi GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudBool test = true; unsigned long const PUBLISH_INTERVAL_SEC = 1 * SECONDS; diff --git a/extras/test/src/test_publishOnChange.cpp b/extras/test/src/test_publishOnChange.cpp index 092c449f3..9568f13f3 100644 --- a/extras/test/src/test_publishOnChange.cpp +++ b/extras/test/src/test_publishOnChange.cpp @@ -9,7 +9,6 @@ #include #include -#include /************************************************************************************** TEST CODE @@ -20,9 +19,7 @@ SCENARIO("A Arduino cloud property is published on value change", "[ArduinoCloud GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 10; int const DELTA = 6; diff --git a/extras/test/src/test_publishOnChangeRateLimit.cpp b/extras/test/src/test_publishOnChangeRateLimit.cpp index 7cba892a6..ccb51148e 100644 --- a/extras/test/src/test_publishOnChangeRateLimit.cpp +++ b/extras/test/src/test_publishOnChangeRateLimit.cpp @@ -9,7 +9,6 @@ #include #include -#include /************************************************************************************** TEST CODE @@ -20,9 +19,7 @@ SCENARIO("A Arduino cloud property is published on value change but the update r GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; int const MIN_DELTA = 0; unsigned long const MIN_TIME_BETWEEN_UPDATES_ms = 500; /* No updates faster than 500 ms */ diff --git a/extras/test/src/test_readOnly.cpp b/extras/test/src/test_readOnly.cpp index a9963eb58..f29468cdd 100644 --- a/extras/test/src/test_readOnly.cpp +++ b/extras/test/src/test_readOnly.cpp @@ -9,7 +9,9 @@ #include #include -#include + +#include +#include /************************************************************************************** TEST CODE @@ -20,16 +22,14 @@ SCENARIO("A Arduino cloud property is marked 'read only'", "[ArduinoCloudThing:: GIVEN("CloudProtocol::V2") { PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::Read); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; int const payload_length = sizeof(payload) / sizeof(uint8_t); - thing.decode(payload, payload_length); + CBORDecoder::decode(property_container, payload, payload_length); REQUIRE(test == 0); } diff --git a/extras/test/src/test_writeOnly.cpp b/extras/test/src/test_writeOnly.cpp index 441c6a178..643f6d779 100644 --- a/extras/test/src/test_writeOnly.cpp +++ b/extras/test/src/test_writeOnly.cpp @@ -9,7 +9,9 @@ #include #include -#include + +#include +#include /************************************************************************************** TEST CODE @@ -19,9 +21,7 @@ SCENARIO("A Arduino cloud property is marked 'write only'", "[ArduinoCloudThing: /************************************************************************************/ PropertyContainer property_container; - ArduinoCloudThing thing; - thing.begin(&property_container); - + CloudInt test = 0; addPropertyToContainer(property_container, test, "test", Permission::Write); From 7548be5daaa1b6a7dbc8db64dd3c025b8d88b498 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 2 Jul 2020 08:06:01 +0200 Subject: [PATCH 6/6] Removing unncessary dynamic memory allocation during property decoding --- src/cbor/CBORDecoder.cpp | 93 +++++++++++++----------------- src/cbor/CBORDecoder.h | 21 ++++--- src/property/Property.cpp | 61 ++++++++++---------- src/property/Property.h | 6 +- src/property/PropertyContainer.cpp | 2 +- src/property/PropertyContainer.h | 2 +- 6 files changed, 83 insertions(+), 102 deletions(-) diff --git a/src/cbor/CBORDecoder.cpp b/src/cbor/CBORDecoder.cpp index f2f431905..b4eccd8c2 100644 --- a/src/cbor/CBORDecoder.cpp +++ b/src/cbor/CBORDecoder.cpp @@ -33,12 +33,11 @@ void CBORDecoder::decode(PropertyContainer & property_container, uint8_t const * const payload, size_t const length, bool isSyncMessage) { + CborValue array_iter, map_iter,value_iter; CborParser parser; - CborValue array_iter, map_iter,value_iter; - /* List of map data that will hold all the attributes of a property */ - std::list map_data_list; - /* Current property name during decoding: use to look for a new property in the senml value array */ - String current_property_name; + CborMapData map_data; + std::list map_data_list; /* List of map data that will hold all the attributes of a property */ + String current_property_name; /* Current property name during decoding: use to look for a new property in the senml value array */ unsigned long current_property_base_time{0}, current_property_time{0}; if (cbor_parser_init(payload, length, 0, &parser, &array_iter) != CborNoError) @@ -50,15 +49,13 @@ void CBORDecoder::decode(PropertyContainer & property_container, uint8_t const * if (cbor_value_enter_container(&array_iter, &map_iter) != CborNoError) return; - CborMapData * map_data = nullptr; - MapParserState current_state = MapParserState::EnterMap, next_state = MapParserState::Error; while (current_state != MapParserState::Complete) { switch (current_state) { - case MapParserState::EnterMap : next_state = handle_EnterMap(&map_iter, &value_iter, &map_data); break; + case MapParserState::EnterMap : next_state = handle_EnterMap(&map_iter, &value_iter); break; case MapParserState::MapKey : next_state = handle_MapKey(&value_iter); break; case MapParserState::UndefinedKey : next_state = handle_UndefinedKey(&value_iter); break; case MapParserState::BaseVersion : next_state = handle_BaseVersion(&value_iter, map_data); break; @@ -82,12 +79,11 @@ void CBORDecoder::decode(PropertyContainer & property_container, uint8_t const * PRIVATE MEMBER FUNCTIONS ******************************************************************************/ -CBORDecoder::MapParserState CBORDecoder::handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_EnterMap(CborValue * map_iter, CborValue * value_iter) { MapParserState next_state = MapParserState::Error; if (cbor_value_get_type(map_iter) == CborMapType) { if (cbor_value_enter_container(map_iter, value_iter) == CborNoError) { - *map_data = new CborMapData(); next_state = MapParserState::MapKey; } } @@ -144,13 +140,13 @@ CBORDecoder::MapParserState CBORDecoder::handle_UndefinedKey(CborValue * value_i return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_BaseVersion(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseVersion(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_integer(value_iter)) { int val = 0; if (cbor_value_get_int(value_iter, &val) == CborNoError) { - map_data->base_version.set(val); + map_data.base_version.set(val); if (cbor_value_advance(value_iter) == CborNoError) { next_state = MapParserState::MapKey; @@ -161,14 +157,14 @@ CBORDecoder::MapParserState CBORDecoder::handle_BaseVersion(CborValue * value_it return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_BaseName(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseName(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { char * val = 0; size_t val_size = 0; if (cbor_value_dup_text_string(value_iter, &val, &val_size, value_iter) == CborNoError) { - map_data->base_name.set(String(val)); + map_data.base_name.set(String(val)); free(val); next_state = MapParserState::MapKey; } @@ -177,12 +173,12 @@ CBORDecoder::MapParserState CBORDecoder::handle_BaseName(CborValue * value_iter, return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_BaseTime(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BaseTime(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; if (ifNumericConvertToDouble(value_iter, &val)) { - map_data->base_time.set(val); + map_data.base_time.set(val); if (cbor_value_advance(value_iter) == CborNoError) { next_state = MapParserState::MapKey; @@ -192,7 +188,7 @@ CBORDecoder::MapParserState CBORDecoder::handle_BaseTime(CborValue * value_iter, return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_Name(CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container) { +CBORDecoder::MapParserState CBORDecoder::handle_Name(CborValue * value_iter, CborMapData & map_data, PropertyContainer & property_container) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { @@ -202,25 +198,25 @@ CBORDecoder::MapParserState CBORDecoder::handle_Name(CborValue * value_iter, Cbo if (cbor_value_dup_text_string(value_iter, &val, &val_size, value_iter) == CborNoError) { String name = val; free(val); - map_data->name.set(name); + map_data.name.set(name); int colonPos = name.indexOf(":"); String attribute_name = ""; if (colonPos != -1) { attribute_name = name.substring(colonPos + 1); } - map_data->attribute_name.set(attribute_name); + map_data.attribute_name.set(attribute_name); next_state = MapParserState::MapKey; } } else if (cbor_value_is_integer(value_iter)) { // if the value in the cbor message is an integer, a light payload has been used and an integer identifier should be decode in order to retrieve the corresponding property and attribute name to be updated int val = 0; if (cbor_value_get_int(value_iter, &val) == CborNoError) { - map_data->light_payload.set(true); - map_data->name_identifier.set(val & 255); - map_data->attribute_identifier.set(val >> 8); - map_data->light_payload.set(true); + map_data.light_payload.set(true); + map_data.name_identifier.set(val & 255); + map_data.attribute_identifier.set(val >> 8); + map_data.light_payload.set(true); String name = getPropertyNameByIdentifier(property_container, val); - map_data->name.set(name); + map_data.name.set(name); if (cbor_value_advance(value_iter) == CborNoError) { @@ -234,12 +230,12 @@ CBORDecoder::MapParserState CBORDecoder::handle_Name(CborValue * value_iter, Cbo return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_Value(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_Value(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; if (ifNumericConvertToDouble(value_iter, &val)) { - map_data->val.set(val); + map_data.val.set(val); if (cbor_value_advance(value_iter) == CborNoError) { next_state = MapParserState::MapKey; @@ -249,14 +245,14 @@ CBORDecoder::MapParserState CBORDecoder::handle_Value(CborValue * value_iter, Cb return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_StringValue(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_StringValue(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; if (cbor_value_is_text_string(value_iter)) { char * val = 0; size_t val_size = 0; if (cbor_value_dup_text_string(value_iter, &val, &val_size, value_iter) == CborNoError) { - map_data->str_val.set(String(val)); + map_data.str_val.set(String(val)); free(val); next_state = MapParserState::MapKey; } @@ -265,12 +261,12 @@ CBORDecoder::MapParserState CBORDecoder::handle_StringValue(CborValue * value_it return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_BooleanValue(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_BooleanValue(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; bool val = false; if (cbor_value_get_boolean(value_iter, &val) == CborNoError) { - map_data->bool_val.set(val); + map_data.bool_val.set(val); if (cbor_value_advance(value_iter) == CborNoError) { next_state = MapParserState::MapKey; @@ -280,12 +276,12 @@ CBORDecoder::MapParserState CBORDecoder::handle_BooleanValue(CborValue * value_i return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_Time(CborValue * value_iter, CborMapData * map_data) { +CBORDecoder::MapParserState CBORDecoder::handle_Time(CborValue * value_iter, CborMapData & map_data) { MapParserState next_state = MapParserState::Error; double val = 0.0; if (ifNumericConvertToDouble(value_iter, &val)) { - map_data->time.set(val); + map_data.time.set(val); if (cbor_value_advance(value_iter) == CborNoError) { next_state = MapParserState::MapKey; @@ -295,31 +291,31 @@ CBORDecoder::MapParserState CBORDecoder::handle_Time(CborValue * value_iter, Cbo return next_state; } -CBORDecoder::MapParserState CBORDecoder::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list) { +CBORDecoder::MapParserState CBORDecoder::handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData & map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list) { MapParserState next_state = MapParserState::Error; - if (map_data->name.isSet()) { + if (map_data.name.isSet()) { String propertyName; - int colonPos = map_data->name.get().indexOf(":"); + int colonPos = map_data.name.get().indexOf(":"); if (colonPos != -1) { - propertyName = map_data->name.get().substring(0, colonPos); + propertyName = map_data.name.get().substring(0, colonPos); } else { - propertyName = map_data->name.get(); + propertyName = map_data.name.get(); } if (current_property_name != "" && propertyName != current_property_name) { /* Update the property containers depending on the parsed data */ updateProperty(property_container, current_property_name, current_property_base_time + current_property_time, is_sync_message, &map_data_list); /* Reset current property data */ - freeMapDataList(&map_data_list); + map_data_list.clear(); current_property_base_time = 0; current_property_time = 0; } /* Compute the cloud change event baseTime and Time */ - if (map_data->base_time.isSet()) { - current_property_base_time = (unsigned long)(map_data->base_time.get()); + if (map_data.base_time.isSet()) { + current_property_base_time = (unsigned long)(map_data.base_time.get()); } - if (map_data->time.isSet() && (map_data->time.get() > current_property_time)) { - current_property_time = (unsigned long)map_data->time.get(); + if (map_data.time.isSet() && (map_data.time.get() > current_property_time)) { + current_property_time = (unsigned long)map_data.time.get(); } map_data_list.push_back(map_data); current_property_name = propertyName; @@ -333,7 +329,7 @@ CBORDecoder::MapParserState CBORDecoder::handle_LeaveMap(CborValue * map_iter, C /* Update the property containers depending on the parsed data */ updateProperty(property_container, current_property_name, current_property_base_time + current_property_time, is_sync_message, &map_data_list); /* Reset last property data */ - freeMapDataList(&map_data_list); + map_data_list.clear(); next_state = MapParserState::Complete; } } @@ -341,17 +337,6 @@ CBORDecoder::MapParserState CBORDecoder::handle_LeaveMap(CborValue * map_iter, C return next_state; } -void CBORDecoder::freeMapDataList(std::list * map_data_list) -{ - std::for_each(map_data_list->begin(), - map_data_list->end(), - [](CborMapData * map_data) - { - delete map_data; - }); - map_data_list->clear(); -} - bool CBORDecoder::ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val) { if (cbor_value_is_integer(value_iter)) { diff --git a/src/cbor/CBORDecoder.h b/src/cbor/CBORDecoder.h index 796ca5eed..a0f9d7360 100644 --- a/src/cbor/CBORDecoder.h +++ b/src/cbor/CBORDecoder.h @@ -63,22 +63,21 @@ class CBORDecoder Error }; - static MapParserState handle_EnterMap(CborValue * map_iter, CborValue * value_iter, CborMapData **map_data); + static MapParserState handle_EnterMap(CborValue * map_iter, CborValue * value_iter); static MapParserState handle_MapKey(CborValue * value_iter); static MapParserState handle_UndefinedKey(CborValue * value_iter); - static MapParserState handle_BaseVersion(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_BaseName(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_BaseTime(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_Name(CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container); - static MapParserState handle_Value(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_StringValue(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_BooleanValue(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_Time(CborValue * value_iter, CborMapData * map_data); - static MapParserState handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData * map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list); + static MapParserState handle_BaseVersion(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_BaseName(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_BaseTime(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_Name(CborValue * value_iter, CborMapData & map_data, PropertyContainer & property_container); + static MapParserState handle_Value(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_StringValue(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_BooleanValue(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_Time(CborValue * value_iter, CborMapData & map_data); + static MapParserState handle_LeaveMap(CborValue * map_iter, CborValue * value_iter, CborMapData & map_data, PropertyContainer & property_container, String & current_property_name, unsigned long & current_property_base_time, unsigned long & current_property_time, bool const is_sync_message, std::list & map_data_list); static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val); static double convertCborHalfFloatToDouble(uint16_t const half_val); - static void freeMapDataList(std::list * map_data_list); }; diff --git a/src/property/Property.cpp b/src/property/Property.cpp index e1e14b700..9c4203c4d 100644 --- a/src/property/Property.cpp +++ b/src/property/Property.cpp @@ -216,21 +216,21 @@ void Property::appendAttributeName(String attributeName, std::function * map_data_list) { +void Property::setAttributesFromCloud(std::list * map_data_list) { _map_data_list = map_data_list; _attributeIdentifier = 0; setAttributesFromCloud(); } void Property::setAttributeReal(bool& value, String attributeName) { - setAttributeReal(attributeName, [&value](CborMapData * md) { + setAttributeReal(attributeName, [&value](CborMapData & md) { // Manage the case to have boolean values received as integers 0/1 - if (md->bool_val.isSet()) { - value = md->bool_val.get(); - } else if (md->val.isSet()) { - if (md->val.get() == 0) { + if (md.bool_val.isSet()) { + value = md.bool_val.get(); + } else if (md.val.isSet()) { + if (md.val.get() == 0) { value = false; - } else if (md->val.get() == 1) { + } else if (md.val.get() == 1) { value = true; } else { /* This should not happen. Leave the previous value */ @@ -240,24 +240,24 @@ void Property::setAttributeReal(bool& value, String attributeName) { } void Property::setAttributeReal(int& value, String attributeName) { - setAttributeReal(attributeName, [&value](CborMapData * md) { - value = md->val.get(); + setAttributeReal(attributeName, [&value](CborMapData & md) { + value = md.val.get(); }); } void Property::setAttributeReal(float& value, String attributeName) { - setAttributeReal(attributeName, [&value](CborMapData * md) { - value = md->val.get(); + setAttributeReal(attributeName, [&value](CborMapData & md) { + value = md.val.get(); }); } void Property::setAttributeReal(String& value, String attributeName) { - setAttributeReal(attributeName, [&value](CborMapData * md) { - value = md->str_val.get(); + setAttributeReal(attributeName, [&value](CborMapData & md) { + value = md.str_val.get(); }); } -void Property::setAttributeReal(String attributeName, std::functionsetValue) +void Property::setAttributeReal(String attributeName, std::functionsetValue) { if (attributeName != "") { _attributeIdentifier++; @@ -265,27 +265,24 @@ void Property::setAttributeReal(String attributeName, std::functionbegin(), _map_data_list->end(), - [this, attributeName, setValue](CborMapData * map) + [this, attributeName, setValue](CborMapData & map) { - if (map != nullptr) + if (map.light_payload.isSet() && map.light_payload.get()) { - if (map->light_payload.isSet() && map->light_payload.get()) - { - // if a light payload is detected, the attribute identifier is retrieved from the cbor map and the corresponding attribute is updated - int attid = map->attribute_identifier.get(); - if (attid == _attributeIdentifier) { - setValue(map); - return; - } + // if a light payload is detected, the attribute identifier is retrieved from the cbor map and the corresponding attribute is updated + int attid = map.attribute_identifier.get(); + if (attid == _attributeIdentifier) { + setValue(map); + return; } - else - { - // if a normal payload is detected, the name of the attribute to be updated is extracted directly from the cbor map - String an = map->attribute_name.get(); - if (an == attributeName) { - setValue(map); - return; - } + } + else + { + // if a normal payload is detected, the name of the attribute to be updated is extracted directly from the cbor map + String an = map.attribute_name.get(); + if (an == attributeName) { + setValue(map); + return; } } }); diff --git a/src/property/Property.h b/src/property/Property.h index e238dd7e8..8eb643668 100644 --- a/src/property/Property.h +++ b/src/property/Property.h @@ -174,12 +174,12 @@ class Property void appendAttributeReal(float value, String attributeName = "", CborEncoder *encoder = nullptr); void appendAttributeReal(String value, String attributeName = "", CborEncoder *encoder = nullptr); void appendAttributeName(String attributeName, std::functionf, CborEncoder *encoder); - void setAttributesFromCloud(std::list * map_data_list); + void setAttributesFromCloud(std::list * map_data_list); void setAttributeReal(bool& value, String attributeName = ""); void setAttributeReal(int& value, String attributeName = ""); void setAttributeReal(float& value, String attributeName = ""); void setAttributeReal(String& value, String attributeName = ""); - void setAttributeReal(String attributeName, std::functionsetValue); + void setAttributeReal(String attributeName, std::functionsetValue); String getAttributeName(String propertyName, char separator); virtual bool isDifferentFromCloud() = 0; @@ -214,7 +214,7 @@ class Property /* Variables used for reconnection sync*/ unsigned long _last_local_change_timestamp; unsigned long _last_cloud_change_timestamp; - std::list * _map_data_list; + std::list * _map_data_list; /* Store the identifier of the property in the array list */ int _identifier; int _attributeIdentifier; diff --git a/src/property/PropertyContainer.cpp b/src/property/PropertyContainer.cpp index c8ebb793c..b545378ad 100644 --- a/src/property/PropertyContainer.cpp +++ b/src/property/PropertyContainer.cpp @@ -126,7 +126,7 @@ void updateTimestampOnLocallyChangedProperties(PropertyContainer & prop_cont) }); } -void updateProperty(PropertyContainer & prop_cont, String propertyName, unsigned long cloudChangeEventTime, bool const is_sync_message, std::list * map_data_list) +void updateProperty(PropertyContainer & prop_cont, String propertyName, unsigned long cloudChangeEventTime, bool const is_sync_message, std::list * map_data_list) { Property * property = getProperty(prop_cont, propertyName); diff --git a/src/property/PropertyContainer.h b/src/property/PropertyContainer.h index 400d9ae82..abc9d7a79 100644 --- a/src/property/PropertyContainer.h +++ b/src/property/PropertyContainer.h @@ -81,7 +81,7 @@ Property * getProperty(PropertyContainer & prop_cont, int const identifier); int appendChangedProperties(PropertyContainer & prop_cont, CborEncoder * arrayEncoder, bool lightPayload); void updateTimestampOnLocallyChangedProperties(PropertyContainer & prop_cont); void requestUpdateForAllProperties(PropertyContainer & prop_cont); -void updateProperty(PropertyContainer & prop_cont, String propertyName, unsigned long cloudChangeEventTime, bool const is_sync_message, std::list * map_data_list); +void updateProperty(PropertyContainer & prop_cont, String propertyName, unsigned long cloudChangeEventTime, bool const is_sync_message, std::list * map_data_list); String getPropertyNameByIdentifier(PropertyContainer & prop_cont, int propertyIdentifier); #endif /* ARDUINO_PROPERTY_CONTAINER_H_ */ \ No newline at end of file