From: Erich Keane Date: Fri, 7 Aug 2015 17:18:51 +0000 (-0700) Subject: Enable arbitrary package sizes for OCPayloadConvert X-Git-Tag: 1.2.0+RC1~1212 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7923ad1300da449981d8fd5f9a11ab4bd8cb8d2a;p=platform%2Fupstream%2Fiotivity.git Enable arbitrary package sizes for OCPayloadConvert Previously OCPayloadConvert would only allocate sizes up to 1024 due to how it was designed. This patch will enable unlimited size, since it will now recover from a CborErrorOutOfMemory and resize the buffer, then try again. This requires tinycbor commit 47a78569c0 (currently HEAD of master in the github tinycbor library), so you'll likely need to do a git-pull in the extlibs/tinycbor/tinycbor directory. This commit also adds a static_assert like functionality for C, and tests for the condition where tinycbor needs updating. Change-Id: I6f81d374ca2b68ebaf2f6a8239be58898b247309 Signed-off-by: Erich Keane Reviewed-on: https://gerrit.iotivity.org/gerrit/2141 Tested-by: jenkins-iotivity --- diff --git a/resource/c_common/platform_features.h b/resource/c_common/platform_features.h index 2fdaded..8f39e19 100644 --- a/resource/c_common/platform_features.h +++ b/resource/c_common/platform_features.h @@ -34,4 +34,11 @@ #define SUPPORTS_DEFAULT_CTOR #endif +#if (__STDC_VERSION__ >= 201112L) + #include + #define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg) +#else + #define OC_STATIC_ASSERT(condition, msg) ((void)sizeof(char[2*!!(condition) - 1])) +#endif + #endif diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index d72c136..7c8db38 100644 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -19,6 +19,7 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "ocpayloadcbor.h" +#include "platform_features.h" #include #include "oic_malloc.h" #include "logger.h" @@ -28,29 +29,104 @@ #include "cbor.h" #define TAG PCF("OCPayloadConvert") +// Arbitrarily chosen size that seems to contain the majority of packages +#define INIT_SIZE (255) -static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload, +// Functions all return either a CborError, or a negative version of the OC_STACK return values +static int64_t OCConvertPayloadHelper(OCPayload* payload, uint8_t* outPayload, size_t* size); +static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t* outPayload, size_t* size); -static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload, +static int64_t OCConvertDevicePayload(OCDevicePayload* payload, uint8_t* outPayload, size_t* size); -static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload, +static int64_t OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t* outPayload, size_t* size); -static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size); -static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, uint8_t** outPayload, +static int64_t OCConvertRepPayload(OCRepPayload* payload, uint8_t* outPayload, size_t* size); +static int64_t OCConvertPresencePayload(OCPresencePayload* payload, uint8_t* outPayload, size_t* size); -static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload, +static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload, size_t* size); +static int64_t OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload); +static int64_t OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray); -bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, +static int64_t AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, const char* value); -bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, +static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, const char* value); +#define STRINGIFY(s) XSTRINGIFY(s) +#define XSTRINGIFY(s) #s OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size) { + // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation + // strategy to work. If you receive the following assertion error, please do a git-pull + // from the extlibs/tinycbor/tinycbor directory + #define CborNeedsUpdating (CborErrorOutOfMemory < CborErrorDataTooLarge) + OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0"); + #undef CborNeedsUpdating + if (!payload) + { + OC_LOG(ERROR, TAG, PCF("Payload parameter NULL")); + return OC_STACK_INVALID_PARAM; + } + + if (!outPayload || !size) + { + OC_LOG(ERROR, TAG, PCF("Out parameter/s parameter NULL")); + return OC_STACK_INVALID_PARAM; + } + OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type); + + size_t curSize = INIT_SIZE; + uint8_t* out = (uint8_t*)OICCalloc(1, curSize); + int64_t err = OCConvertPayloadHelper(payload, out, &curSize); + + if (err == CborErrorOutOfMemory) + { + // reallocate "out" and try again! + uint8_t* out2 = (uint8_t*)OICRealloc(out, curSize); + + if (!out2) + { + OICFree(out); + return OC_STACK_NO_MEMORY; + } + + out = out2; + err = OCConvertPayloadHelper(payload, out, &curSize); + } + + if (err == 0) + { + if (curSize < INIT_SIZE) + { + uint8_t* out2 = (uint8_t*)OICRealloc(out, curSize); + + if (!out2) + { + OICFree(out); + return OC_STACK_NO_MEMORY; + } + } + + *size = curSize; + *outPayload = out; + return OC_STACK_OK; + } + else if (err < 0) + { + return (OCStackResult)-err; + } + else + { + return OC_STACK_ERROR; + } +} + +static int64_t OCConvertPayloadHelper(OCPayload* payload, uint8_t* outPayload, size_t* size) +{ switch(payload->type) { case PAYLOAD_TYPE_DISCOVERY: @@ -71,82 +147,66 @@ OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* } } -static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload, - size_t* size) +static int64_t checkError(int64_t err, CborEncoder* encoder, uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) + if (err == CborErrorOutOfMemory) { - return OC_STACK_NO_MEMORY; + *size += encoder->ptr - encoder->end; + return err; } - + else if (err != 0) + { + OC_LOG_V(ERROR, TAG, "Convert Payload failed", err); + return err; + } + else + { + *size = encoder->ptr - outPayload; + return 0; + } +} +static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload, + size_t* size) +{ CborEncoder encoder; - bool err = false; + int64_t err = 0; - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, 2); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY); + err = err | cbor_encoder_create_array(&encoder, &rootArray, 2); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY); CborEncoder map; - err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); if(payload->securityData) { - err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION, + err = err | AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1, payload->securityData); } - err = err || cbor_encoder_close_container(&rootArray, &map); - - err = err || cbor_encoder_close_container(&encoder, &rootArray); - - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err); - OICFree(*outPayload); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); + err = err | cbor_encoder_close_container(&rootArray, &map); - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } + err = err | cbor_encoder_close_container(&encoder, &rootArray); + return checkError(err, &encoder, outPayload, size); - *outPayload = tempPayload; - return OC_STACK_OK; } -static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload, +static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) - { - return OC_STACK_NO_MEMORY; - } - CborEncoder encoder = {0}; - bool err = false; + int64_t err = 0; size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload); - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY); + err = err | cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY); for(size_t i = 0; i < resourceCount; ++i) { @@ -155,333 +215,262 @@ static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint if(!resource) { - OICFree(*outPayload); return OC_STACK_INVALID_PARAM; } - err = err || cbor_encoder_create_map(&rootArray, &map, 3); + err = err | cbor_encoder_create_map(&rootArray, &map, 3); // Uri - err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, + err = err | AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, resource->uri); // Server ID - err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID, + err = err | cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID, sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1); - err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE); + err = err | cbor_encode_byte_string(&map, resource->sid, UUID_SIZE); // Prop Tag { CborEncoder propMap; - err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY, + err = err | cbor_encode_text_string(&map, OC_RSRVD_PROPERTY, sizeof(OC_RSRVD_PROPERTY) -1 ); - err = err || cbor_encoder_create_map(&map, &propMap, 3); + err = err | cbor_encoder_create_map(&map, &propMap, 3); // Resource Type { CborEncoder rtArray; - err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE, + err = err | cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1); - err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength); + err = err | cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength); OCStringLL* rtPtr = resource->types; while(rtPtr) { - err = err || cbor_encode_text_string(&rtArray, rtPtr->value, + err = err | cbor_encode_text_string(&rtArray, rtPtr->value, strlen(rtPtr->value)); rtPtr = rtPtr->next; } - err = err || cbor_encoder_close_container(&propMap, &rtArray); + err = err | cbor_encoder_close_container(&propMap, &rtArray); } // Interface Types { CborEncoder ifArray; - err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE, + err = err | cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1); - err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength); + err = err | cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength); OCStringLL* ifPtr = resource->interfaces; while(ifPtr) { - err = err || cbor_encode_text_string(&ifArray, ifPtr->value, + err = err | cbor_encode_text_string(&ifArray, ifPtr->value, strlen(ifPtr->value)); ifPtr= ifPtr->next; } - err = err || cbor_encoder_close_container(&propMap, &ifArray); + err = err | cbor_encoder_close_container(&propMap, &ifArray); } // Policy { CborEncoder policyMap; - err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY, + err = err | cbor_encode_text_string(&propMap, OC_RSRVD_POLICY, sizeof(OC_RSRVD_POLICY) - 1); - err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength); // Bitmap - err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, + err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, sizeof(OC_RSRVD_BITMAP) - 1); - err = err || cbor_encode_uint(&policyMap, resource->bitmap); + err = err | cbor_encode_uint(&policyMap, resource->bitmap); if(resource->secure) { - err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, + err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, sizeof(OC_RSRVD_SECURE) - 1); - err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE); + err = err | cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE); if(resource->port != 0) { - err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, + err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, sizeof(OC_RSRVD_HOSTING_PORT) - 1); - err = err || cbor_encode_uint(&policyMap, resource->port); + err = err | cbor_encode_uint(&policyMap, resource->port); } } - err = err || cbor_encoder_close_container(&propMap, &policyMap); + err = err | cbor_encoder_close_container(&propMap, &policyMap); } // Close - err = err || cbor_encoder_close_container(&map, &propMap); + err = err | cbor_encoder_close_container(&map, &propMap); } // Close Item - err = err || cbor_encoder_close_container(&rootArray, &map); + err = err | cbor_encoder_close_container(&rootArray, &map); } // Close main array - err = err || cbor_encoder_close_container(&encoder, &rootArray); + err = err | cbor_encoder_close_container(&encoder, &rootArray); - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); - - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } - - *outPayload = tempPayload; - return OC_STACK_OK; + return checkError(err, &encoder, outPayload, size); } -static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload, +static int64_t OCConvertDevicePayload(OCDevicePayload* payload, uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) - { - return OC_STACK_NO_MEMORY; - } - CborEncoder encoder = {0}; - bool err = false; + int64_t err = 0; - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, 2); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE); + err = err | cbor_encoder_create_array(&encoder, &rootArray, 2); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE); { CborEncoder map; - err = err || cbor_encoder_create_map(&rootArray, &map, 2); + err = err | cbor_encoder_create_map(&rootArray, &map, 2); // uri - err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, + err = err | AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, payload->uri); // Rep Map { CborEncoder repMap; - err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, + err = err | cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1); - err = err || cbor_encoder_create_map(&map, &repMap, 4); + err = err | cbor_encoder_create_map(&map, &repMap, 4); // Device ID - err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID, + err = err | cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1); - err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE); + err = err | cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE); // Device Name - err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME, + err = err | AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME, sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->deviceName); // Device Spec Version - err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION, + err = err | AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION, sizeof(OC_RSRVD_SPEC_VERSION) - 1, payload->specVersion); // Device data Model Version - err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION, + err = err | AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION, sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1, payload->dataModelVersion); - err = err || cbor_encoder_close_container(&map, &repMap); + err = err | cbor_encoder_close_container(&map, &repMap); } // Close Map - err = err || cbor_encoder_close_container(&rootArray, &map); + err = err | cbor_encoder_close_container(&rootArray, &map); } // Close main array - err = err || cbor_encoder_close_container(&encoder, &rootArray); - - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); - - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } + err = err | cbor_encoder_close_container(&encoder, &rootArray); - *outPayload = tempPayload; - return OC_STACK_OK; + return checkError(err, &encoder, outPayload, size); } -static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload, +static int64_t OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) - { - return OC_STACK_NO_MEMORY; - } - CborEncoder encoder = {0}; - bool err = false; + int64_t err = 0; - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, 2); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM); + err = err | cbor_encoder_create_array(&encoder, &rootArray, 2); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM); { CborEncoder map; - err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); // uri - err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, + err = err | AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, payload->uri); // Rep Map { CborEncoder repMap; - err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, + err = err | cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1); - err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); // Platform ID - err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID, + err = err | AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID, sizeof(OC_RSRVD_PLATFORM_ID) - 1, payload->info.platformID); // MFG Name - err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME, + err = err | AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME, sizeof(OC_RSRVD_MFG_NAME) - 1, payload->info.manufacturerName); // MFG Url - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL, sizeof(OC_RSRVD_MFG_URL) - 1, payload->info.manufacturerUrl); // Model Num - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM, sizeof(OC_RSRVD_MODEL_NUM) - 1, payload->info.modelNumber); // Date of Mfg - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE, sizeof(OC_RSRVD_MFG_DATE) - 1, payload->info.dateOfManufacture); // Platform Version - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION, sizeof(OC_RSRVD_PLATFORM_VERSION) - 1, payload->info.platformVersion); // OS Version - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION, sizeof(OC_RSRVD_OS_VERSION) - 1, payload->info.operatingSystemVersion); // Hardware Version - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION, sizeof(OC_RSRVD_HARDWARE_VERSION) - 1, payload->info.hardwareVersion); // Firmware Version - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION, sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1, payload->info.firmwareVersion); // Support URL - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL, sizeof(OC_RSRVD_SUPPORT_URL) - 1, payload->info.supportUrl); // System Time - err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME, + err = err | ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME, sizeof(OC_RSRVD_SYSTEM_TIME) - 1, payload->info.systemTime); - err = err || cbor_encoder_close_container(&map, &repMap); + err = err | cbor_encoder_close_container(&map, &repMap); } // Close Map - err = err || cbor_encoder_close_container(&rootArray, &map); + err = err | cbor_encoder_close_container(&rootArray, &map); } // Close main array - err = err || cbor_encoder_close_container(&encoder, &rootArray); - - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); - - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } - - *outPayload = tempPayload; + err = err | cbor_encoder_close_container(&encoder, &rootArray); - return OC_STACK_OK; + return checkError(err, &encoder, outPayload, size); } -static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload); - -static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray) +static int64_t OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray) { CborEncoder array; - bool err = false; + int64_t err = 0; - err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength); - err = err || cbor_encode_uint(&array, valArray->type); + err = err | cbor_encoder_create_array(parent, &array, CborIndefiniteLength); + err = err | cbor_encode_uint(&array, valArray->type); for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i) { - err = err || cbor_encode_uint(&array, valArray->dimensions[i]); + err = err | cbor_encode_uint(&array, valArray->dimensions[i]); } size_t dimTotal = calcDimTotal(valArray->dimensions); @@ -495,16 +484,16 @@ static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* va err = CborUnknownError; break; case OCREP_PROP_INT: - err = err || cbor_encode_int(&array, valArray->iArray[i]); + err = err | cbor_encode_int(&array, valArray->iArray[i]); break; case OCREP_PROP_DOUBLE: - err = err || cbor_encode_double(&array, valArray->dArray[i]); + err = err | cbor_encode_double(&array, valArray->dArray[i]); break; case OCREP_PROP_BOOL: - err = err || cbor_encode_boolean(&array, valArray->bArray[i]); + err = err | cbor_encode_boolean(&array, valArray->bArray[i]); break; case OCREP_PROP_STRING: - err = err || cbor_encode_text_string(&array, valArray->strArray[i], + err = err | cbor_encode_text_string(&array, valArray->strArray[i], strlen(valArray->strArray[i])); break; case OCREP_PROP_OBJECT: @@ -517,18 +506,18 @@ static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* va } } - err = err || cbor_encoder_close_container(parent, &array); + err = err | cbor_encoder_close_container(parent, &array); return err; } -static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload) +static int64_t OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload) { - bool err = false; + int64_t err = 0; CborEncoder map; - err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength); + err = err | cbor_encoder_create_map(parent, &map, CborIndefiniteLength); // Uri - err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF, + err = err | ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, payload->uri); @@ -537,83 +526,83 @@ static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* p if(payload->types || payload->interfaces) { OC_LOG_V(INFO, TAG, "Payload has types or interfaces"); - err = err || cbor_encode_text_string(&map, + err = err | cbor_encode_text_string(&map, OC_RSRVD_PROPERTY, sizeof(OC_RSRVD_PROPERTY) - 1); CborEncoder propMap; - err = err || cbor_encoder_create_map(&map, &propMap, 2); + err = err | cbor_encoder_create_map(&map, &propMap, 2); CborEncoder curArray; if(payload->types) { - err = err || cbor_encode_text_string(&propMap, + err = err | cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1); - err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); + err = err | cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); OCStringLL* val = payload->types; while(val) { - err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value)); + err = err | cbor_encode_text_string(&curArray, val->value, strlen(val->value)); val = val->next; } - err = err || cbor_encoder_close_container(&propMap, &curArray); + err = err | cbor_encoder_close_container(&propMap, &curArray); } if(payload->interfaces) { - err = err || cbor_encode_text_string(&propMap, + err = err | cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1); - err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); + err = err | cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); OCStringLL* val = payload->interfaces; while(val) { - err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value)); + err = err | cbor_encode_text_string(&curArray, val->value, strlen(val->value)); val = val->next; } - err = err || cbor_encoder_close_container(&propMap, &curArray); + err = err | cbor_encoder_close_container(&propMap, &curArray); } - err = err || cbor_encoder_close_container(&map, &propMap); + err = err | cbor_encoder_close_container(&map, &propMap); } // Rep Map { CborEncoder repMap; - err = err || cbor_encode_text_string(&map, + err = err | cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1); - err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); OCRepPayloadValue* value = payload->values; while(value) { - err = err || cbor_encode_text_string(&repMap, + err = err | cbor_encode_text_string(&repMap, value->name, strlen(value->name)); switch(value->type) { case OCREP_PROP_NULL: - err = err || cbor_encode_null(&repMap); + err = err | cbor_encode_null(&repMap); break; case OCREP_PROP_INT: - err = err || cbor_encode_int(&repMap, + err = err | cbor_encode_int(&repMap, value->i); break; case OCREP_PROP_DOUBLE: - err = err || cbor_encode_double(&repMap, + err = err | cbor_encode_double(&repMap, value->d); break; case OCREP_PROP_BOOL: - err = err || cbor_encode_boolean(&repMap, + err = err | cbor_encode_boolean(&repMap, value->b); break; case OCREP_PROP_STRING: - err = err || cbor_encode_text_string(&repMap, + err = err | cbor_encode_text_string(&repMap, value->str, strlen(value->str)); break; case OCREP_PROP_OBJECT: - err = err || OCConvertSingleRepPayload(&repMap, value->obj); + err = err | OCConvertSingleRepPayload(&repMap, value->obj); break; case OCREP_PROP_ARRAY: - err = err || OCConvertArray(&repMap, &value->arr); + err = err | OCConvertArray(&repMap, &value->arr); break; default: OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d", @@ -623,145 +612,93 @@ static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* p value = value->next; } - err = err || cbor_encoder_close_container(&map, &repMap); + err = err | cbor_encoder_close_container(&map, &repMap); } // Close Map - err = err || cbor_encoder_close_container(parent, &map); + err = err | cbor_encoder_close_container(parent, &map); return err; } -static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size) +static int64_t OCConvertRepPayload(OCRepPayload* payload, uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) - { - return OC_STACK_NO_MEMORY; - } - CborEncoder encoder = {0}; - bool err = false; + int64_t err = 0; - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION); + err = err | cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION); - while(payload != NULL && !err) + while(payload != NULL && (err == 0 || err == CborErrorOutOfMemory)) { - err = err || OCConvertSingleRepPayload(&rootArray, payload); + err = err | OCConvertSingleRepPayload(&rootArray, payload); payload = payload->next; } // Close main array - err = err || cbor_encoder_close_container(&encoder, &rootArray); - - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); - - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } - - *outPayload = tempPayload; + err = err | cbor_encoder_close_container(&encoder, &rootArray); - return OC_STACK_OK; + return checkError(err, &encoder, outPayload, size); } -static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, - uint8_t** outPayload, size_t* size) +static int64_t OCConvertPresencePayload(OCPresencePayload* payload, + uint8_t* outPayload, size_t* size) { - *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); - *size = MAX_REQUEST_LENGTH; - - if(!*outPayload) - { - return OC_STACK_NO_MEMORY; - } - CborEncoder encoder = {0}; - bool err = false; + int64_t err = 0; - cbor_encoder_init(&encoder, *outPayload, *size, 0); + cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; - err = err || cbor_encoder_create_array(&encoder, &rootArray, 2); - err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE); + err = err | cbor_encoder_create_array(&encoder, &rootArray, 2); + err = err | cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE); CborEncoder map; - err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); + err = err | cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength); // Sequence Number - err = err || cbor_encode_text_string(&map, + err = err | cbor_encode_text_string(&map, OC_RSRVD_NONCE, sizeof(OC_RSRVD_NONCE) - 1); - err = err || cbor_encode_uint(&map, payload->sequenceNumber); + err = err | cbor_encode_uint(&map, payload->sequenceNumber); // Max Age - err = err || cbor_encode_text_string(&map, + err = err | cbor_encode_text_string(&map, OC_RSRVD_TTL, sizeof(OC_RSRVD_TTL) - 1); - err = err || cbor_encode_uint(&map, payload->maxAge); + err = err | cbor_encode_uint(&map, payload->maxAge); // Trigger const char* triggerStr = convertTriggerEnumToString(payload->trigger); - err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1, + err = err | AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1, triggerStr); // Resource type name if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE) { - err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE, + err = err | ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType); } // Close Map - err = err || cbor_encoder_close_container(&rootArray, &map); - err = err || cbor_encoder_close_container(&encoder, &rootArray); - - if(err) - { - OC_LOG_V(ERROR, TAG, "Convert Presence Payload failed with : %d", err); - return OC_STACK_ERROR; - } - - *size = encoder.ptr - *outPayload; - uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); - - if(!tempPayload) - { - OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); - OICFree(*outPayload); - return OC_STACK_ERROR; - } - - *outPayload = tempPayload; + err = err | cbor_encoder_close_container(&rootArray, &map); + err = err | cbor_encoder_close_container(&encoder, &rootArray); - return OC_STACK_OK; + return checkError(err, &encoder, outPayload, size); } -bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, +static int64_t AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, const char* value) { - return cbor_encode_text_string(map, key, keylen) || + return cbor_encode_text_string(map, key, keylen) | cbor_encode_text_string(map, value, strlen(value)); } -bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, +static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen, const char* value) { - return value ? AddTextStringToMap(map, key, keylen, value) : false; + return value ? AddTextStringToMap(map, key, keylen, value) : 0 - OC_STACK_INVALID_PARAM; }