Skip to content

Commit f5b729a

Browse files
committed
Allow propagation of CBOR library function return value to determine if a out-of-memory error occurs. If that's the case the CBOR encoding is completed until that property and the CBOR message is still sent with the next properties encoded on the next run of CBOREncoder::encode
1 parent 54f2d7d commit f5b729a

18 files changed

+100
-70
lines changed

src/cbor/CBOREncoder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ int CBOREncoder::encode(PropertyContainer & property_container, uint8_t * data,
4040
* time interval may be elapsed or property may be changed
4141
* and if that's the case encode the property into the CBOR.
4242
*/
43-
if (appendChangedProperties(property_container, &arrayEncoder, lightPayload) < 1)
43+
CborError err = appendChangedProperties(property_container, &arrayEncoder, lightPayload);
44+
if ((err != CborNoError) && (err != CborErrorOutOfMemory))
4445
return -1;
4546

4647
if (cbor_encoder_close_container(&encoder, &arrayEncoder) != CborNoError)

src/property/Property.cpp

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -142,78 +142,92 @@ void Property::execCallbackOnSync() {
142142
}
143143
}
144144

145-
void Property::append(CborEncoder *encoder, bool lightPayload) {
145+
CborError Property::append(CborEncoder *encoder, bool lightPayload) {
146146
_lightPayload = lightPayload;
147147
_attributeIdentifier = 0;
148-
appendAttributesToCloudReal(encoder);
148+
CHECK_CBOR(appendAttributesToCloudReal(encoder));
149149
fromLocalToCloud();
150150
_has_been_updated_once = true;
151151
_update_requested = false;
152152
_last_updated_millis = millis();
153+
return CborNoError;
153154
}
154155

155-
void Property::appendAttributeReal(bool value, String attributeName, CborEncoder *encoder) {
156-
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
157-
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::BooleanValue));
158-
cbor_encode_boolean(&mapEncoder, value);
156+
CborError Property::appendAttributeReal(bool value, String attributeName, CborEncoder *encoder) {
157+
return appendAttributeName(attributeName, [value](CborEncoder & mapEncoder)
158+
{
159+
CHECK_CBOR(cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::BooleanValue)));
160+
CHECK_CBOR(cbor_encode_boolean(&mapEncoder, value));
161+
return CborNoError;
159162
}, encoder);
160163
}
161164

162-
void Property::appendAttributeReal(int value, String attributeName, CborEncoder *encoder) {
163-
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
164-
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value));
165-
cbor_encode_int(&mapEncoder, value);
165+
CborError Property::appendAttributeReal(int value, String attributeName, CborEncoder *encoder) {
166+
return appendAttributeName(attributeName, [value](CborEncoder & mapEncoder)
167+
{
168+
CHECK_CBOR(cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value)));
169+
CHECK_CBOR(cbor_encode_int(&mapEncoder, value));
170+
return CborNoError;
166171
}, encoder);
167172
}
168173

169-
void Property::appendAttributeReal(float value, String attributeName, CborEncoder *encoder) {
170-
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
171-
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value));
172-
cbor_encode_float(&mapEncoder, value);
174+
CborError Property::appendAttributeReal(float value, String attributeName, CborEncoder *encoder) {
175+
return appendAttributeName(attributeName, [value](CborEncoder & mapEncoder)
176+
{
177+
CHECK_CBOR(cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value)));
178+
CHECK_CBOR(cbor_encode_float(&mapEncoder, value));
179+
return CborNoError;
173180
}, encoder);
174181
}
175182

176-
void Property::appendAttributeReal(String value, String attributeName, CborEncoder *encoder) {
177-
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
178-
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::StringValue));
179-
cbor_encode_text_stringz(&mapEncoder, value.c_str());
183+
CborError Property::appendAttributeReal(String value, String attributeName, CborEncoder *encoder) {
184+
return appendAttributeName(attributeName, [value](CborEncoder & mapEncoder)
185+
{
186+
CHECK_CBOR(cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::StringValue)));
187+
CHECK_CBOR(cbor_encode_text_stringz(&mapEncoder, value.c_str()));
188+
return CborNoError;
180189
}, encoder);
181190
}
182191

183-
void Property::appendAttributeName(String attributeName, std::function<void (CborEncoder& mapEncoder)>appendValue, CborEncoder *encoder) {
192+
CborError Property::appendAttributeName(String attributeName, std::function<CborError (CborEncoder& mapEncoder)>appendValue, CborEncoder *encoder) {
184193
if (attributeName != "") {
185194
// when the attribute name string is not empty, the attribute identifier is incremented in order to be encoded in the message if the _lightPayload flag is set
186195
_attributeIdentifier++;
187196
}
188197
CborEncoder mapEncoder;
189198
unsigned int num_map_properties = _encode_timestamp ? 3 : 2;
190-
cbor_encoder_create_map(encoder, &mapEncoder, num_map_properties);
191-
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Name));
199+
CHECK_CBOR(cbor_encoder_create_map(encoder, &mapEncoder, num_map_properties));
200+
CHECK_CBOR(cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Name)));
192201

193202
// if _lightPayload is true, the property and attribute identifiers will be encoded instead of the property name
194-
if (_lightPayload) {
203+
if (_lightPayload)
204+
{
195205
// the most significant byte of the identifier to be encoded represent the property identifier
196206
int completeIdentifier = _attributeIdentifier * 256;
197207
// the least significant byte of the identifier to be encoded represent the attribute identifier
198208
completeIdentifier += _identifier;
199-
cbor_encode_int(&mapEncoder, completeIdentifier);
200-
} else {
209+
CHECK_CBOR(cbor_encode_int(&mapEncoder, completeIdentifier));
210+
}
211+
else
212+
{
201213
String completeName = _name;
202214
if (attributeName != "") {
203215
completeName += ":" + attributeName;
204216
}
205-
cbor_encode_text_stringz(&mapEncoder, completeName.c_str());
217+
CHECK_CBOR(cbor_encode_text_stringz(&mapEncoder, completeName.c_str()));
206218
}
207219
/* Encode the value */
208-
appendValue(mapEncoder);
220+
CHECK_CBOR(appendValue(mapEncoder));
221+
209222
/* Encode the timestamp if that has been required. */
210223
if(_encode_timestamp)
211224
{
212-
cbor_encode_int (&mapEncoder, static_cast<int>(CborIntegerMapKey::Time));
213-
cbor_encode_uint(&mapEncoder, _timestamp);
225+
CHECK_CBOR(cbor_encode_int (&mapEncoder, static_cast<int>(CborIntegerMapKey::Time)));
226+
CHECK_CBOR(cbor_encode_uint(&mapEncoder, _timestamp));
214227
}
215228
/* Close the container */
216-
cbor_encoder_close_container(encoder, &mapEncoder);
229+
CHECK_CBOR(cbor_encoder_close_container(encoder, &mapEncoder));
230+
return CborNoError;
217231
}
218232

219233
void Property::setAttributesFromCloud(std::list<CborMapData> * map_data_list) {

src/property/Property.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@
3636

3737
#include "../cbor/lib/tinycbor/cbor-lib.h"
3838

39+
/******************************************************************************
40+
DEFINE
41+
******************************************************************************/
42+
43+
#define CHECK_CBOR(expr) \
44+
do { \
45+
CborError error = CborNoError; \
46+
error = (expr); \
47+
if (CborNoError != error) \
48+
return error; \
49+
} while(0);
50+
3951
#define appendAttributesToCloud() appendAttributesToCloudReal(CborEncoder *encoder)
4052
#define appendAttribute(x) appendAttributeReal(x, getAttributeName(#x, '.'), encoder)
4153
#define setAttribute(x) setAttributeReal(x, getAttributeName(#x, '.'))
@@ -168,12 +180,12 @@ class Property
168180
void setIdentifier(int identifier);
169181

170182
void updateLocalTimestamp();
171-
void append(CborEncoder * encoder, bool lightPayload);
172-
void appendAttributeReal(bool value, String attributeName = "", CborEncoder *encoder = nullptr);
173-
void appendAttributeReal(int value, String attributeName = "", CborEncoder *encoder = nullptr);
174-
void appendAttributeReal(float value, String attributeName = "", CborEncoder *encoder = nullptr);
175-
void appendAttributeReal(String value, String attributeName = "", CborEncoder *encoder = nullptr);
176-
void appendAttributeName(String attributeName, std::function<void (CborEncoder& mapEncoder)>f, CborEncoder *encoder);
183+
CborError append(CborEncoder * encoder, bool lightPayload);
184+
CborError appendAttributeReal(bool value, String attributeName = "", CborEncoder *encoder = nullptr);
185+
CborError appendAttributeReal(int value, String attributeName = "", CborEncoder *encoder = nullptr);
186+
CborError appendAttributeReal(float value, String attributeName = "", CborEncoder *encoder = nullptr);
187+
CborError appendAttributeReal(String value, String attributeName = "", CborEncoder *encoder = nullptr);
188+
CborError appendAttributeName(String attributeName, std::function<CborError (CborEncoder& mapEncoder)>f, CborEncoder *encoder);
177189
void setAttributesFromCloud(std::list<CborMapData> * map_data_list);
178190
void setAttributeReal(bool& value, String attributeName = "");
179191
void setAttributeReal(int& value, String attributeName = "");
@@ -185,7 +197,7 @@ class Property
185197
virtual bool isDifferentFromCloud() = 0;
186198
virtual void fromCloudToLocal() = 0;
187199
virtual void fromLocalToCloud() = 0;
188-
virtual void appendAttributesToCloudReal(CborEncoder *encoder) = 0;
200+
virtual CborError appendAttributesToCloudReal(CborEncoder *encoder) = 0;
189201
virtual void setAttributesFromCloud() = 0;
190202
virtual bool isPrimitive() {
191203
return false;

src/property/PropertyContainer.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,21 @@ Property * getProperty(PropertyContainer & prop_cont, int const identifier)
8383
return (*iter);
8484
}
8585

86-
int appendChangedProperties(PropertyContainer & prop_cont, CborEncoder * arrayEncoder, bool lightPayload)
86+
CborError appendChangedProperties(PropertyContainer & prop_cont, CborEncoder * arrayEncoder, bool lightPayload)
8787
{
88-
int appendedProperties = 0;
88+
CborError err = CborNoError;
8989
std::for_each(prop_cont.begin(),
9090
prop_cont.end(),
91-
[arrayEncoder, lightPayload, &appendedProperties](Property * p)
91+
[arrayEncoder, lightPayload, &err](Property * p)
9292
{
9393
if (p->shouldBeUpdated() && p->isReadableByCloud())
9494
{
95-
p->append(arrayEncoder, lightPayload);
96-
appendedProperties++;
95+
err = p->append(arrayEncoder, lightPayload);
96+
if(err != CborNoError)
97+
return;
9798
}
9899
});
99-
return appendedProperties;
100+
return err;
100101
}
101102

102103
void requestUpdateForAllProperties(PropertyContainer & prop_cont)

src/property/PropertyContainer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Property * getProperty(PropertyContainer & prop_cont, String const & name);
7878
Property * getProperty(PropertyContainer & prop_cont, int const identifier);
7979

8080

81-
int appendChangedProperties(PropertyContainer & prop_cont, CborEncoder * arrayEncoder, bool lightPayload);
81+
CborError appendChangedProperties(PropertyContainer & prop_cont, CborEncoder * arrayEncoder, bool lightPayload);
8282
void updateTimestampOnLocallyChangedProperties(PropertyContainer & prop_cont);
8383
void requestUpdateForAllProperties(PropertyContainer & prop_cont);
8484
void updateProperty(PropertyContainer & prop_cont, String propertyName, unsigned long cloudChangeEventTime, bool const is_sync_message, std::list<CborMapData> * map_data_list);

src/property/types/CloudBool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class CloudBool : public Property {
5252
virtual void fromLocalToCloud() {
5353
_cloud_value = _value;
5454
}
55-
virtual void appendAttributesToCloud() {
56-
appendAttribute(_value);
55+
virtual CborError appendAttributesToCloud() {
56+
return appendAttribute(_value);
5757
}
5858
virtual void setAttributesFromCloud() {
5959
setAttribute(_cloud_value);

src/property/types/CloudColor.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,11 @@ class CloudColor : public Property {
188188
virtual void fromLocalToCloud() {
189189
_cloud_value = _value;
190190
}
191-
virtual void appendAttributesToCloud() {
192-
appendAttribute(_value.hue);
193-
appendAttribute(_value.sat);
194-
appendAttribute(_value.bri);
191+
virtual CborError appendAttributesToCloud() {
192+
CHECK_CBOR(appendAttribute(_value.hue));
193+
CHECK_CBOR(appendAttribute(_value.sat));
194+
CHECK_CBOR(appendAttribute(_value.bri));
195+
return CborNoError;
195196
}
196197
virtual void setAttributesFromCloud() {
197198
setAttribute(_cloud_value.hue);

src/property/types/CloudFloat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ class CloudFloat : public Property {
5454
virtual void fromLocalToCloud() {
5555
_cloud_value = _value;
5656
}
57-
virtual void appendAttributesToCloud() {
58-
appendAttribute(_value);
57+
virtual CborError appendAttributesToCloud() {
58+
return appendAttribute(_value);
5959
}
6060
virtual void setAttributesFromCloud() {
6161
setAttribute(_cloud_value);

src/property/types/CloudInt.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class CloudInt : public Property {
5252
virtual void fromLocalToCloud() {
5353
_cloud_value = _value;
5454
}
55-
virtual void appendAttributesToCloud() {
56-
appendAttribute(_value);
55+
virtual CborError appendAttributesToCloud() {
56+
return appendAttribute(_value);
5757
}
5858
virtual void setAttributesFromCloud() {
5959
setAttribute(_cloud_value);

src/property/types/CloudLocation.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ class CloudLocation : public Property {
8989
virtual void fromLocalToCloud() {
9090
_cloud_value = _value;
9191
}
92-
virtual void appendAttributesToCloud() {
93-
appendAttribute(_value.lat);
94-
appendAttribute(_value.lon);
92+
virtual CborError appendAttributesToCloud() {
93+
CHECK_CBOR(appendAttribute(_value.lat));
94+
CHECK_CBOR(appendAttribute(_value.lon));
95+
return CborNoError;
9596
}
9697
virtual void setAttributesFromCloud() {
9798
setAttribute(_cloud_value.lat);

0 commit comments

Comments
 (0)