//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include "ocpayloadcbor.h"
+// Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1-2001 base
+// specification (excluding the XSI extension).
+// For POSIX.1-2001 base specification,
+// Refer http://pubs.opengroup.org/onlinepubs/009695399/
+// Required for strok_r
+#define _POSIX_C_SOURCE 200112L
+#include <string.h>
#include <stdlib.h>
-#include "logger.h"
+#include "oic_string.h"
#include "oic_malloc.h"
-#include "ocstackinternal.h"
#include "ocpayload.h"
-#include "cbor.h"
+#include "ocpayloadcbor.h"
+#include "ocstackinternal.h"
+#include "payload_logging.h"
+#include "rdpayload.h"
-#define TAG "OCPayloadParse"
+#define TAG "OIC_RI_PAYLOADPARSE"
-static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal);
-static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal);
-static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal);
-static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent);
-static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal);
-static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal);
-static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal);
+static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
+static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *arrayVal);
+static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *arrayVal);
+static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
+static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
+static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
+static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
-OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType,
- const uint8_t* payload, size_t payloadSize)
+OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
+ const uint8_t *payload, size_t payloadSize)
{
- CborParser parser;
- CborValue rootValue;
- bool err = false;
+ OCStackResult result = OC_STACK_MALFORMED_RESPONSE;
+ CborError err;
- OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload);
- if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false)
- {
- OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err);
- return OC_STACK_ERROR;
- }
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
+ VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
- if(!cbor_value_is_array(&rootValue))
- {
- OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type);
- return OC_STACK_MALFORMED_RESPONSE;
- }
+ OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize);
- CborValue arrayValue;
- // enter the array
- err = err || cbor_value_enter_container(&rootValue, &arrayValue);
+ CborParser parser;
+ CborValue rootValue;
- if(err || arrayValue.type != CborMapType)
- {
- OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err);
- return OC_STACK_MALFORMED_RESPONSE;
- }
+ err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value")
- OCStackResult result = OC_STACK_ERROR;
switch(payloadType)
{
case PAYLOAD_TYPE_DISCOVERY:
- result = OCParseDiscoveryPayload(outPayload, &arrayValue);
+ result = OCParseDiscoveryPayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_DEVICE:
- result = OCParseDevicePayload(outPayload, &arrayValue);
+ result = OCParseDevicePayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_PLATFORM:
- result = OCParsePlatformPayload(outPayload, &arrayValue);
+ result = OCParsePlatformPayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_REPRESENTATION:
- result = OCParseRepPayload(outPayload, &arrayValue);
+ result = OCParseRepPayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_PRESENCE:
- result = OCParsePresencePayload(outPayload, &arrayValue);
+ result = OCParsePresencePayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_SECURITY:
- result = OCParseSecurityPayload(outPayload, &arrayValue);
+ result = OCParseSecurityPayload(outPayload, payload, payloadSize);
+ break;
+ case PAYLOAD_TYPE_RD:
+ result = OCRDCborToPayload(&rootValue, outPayload);
break;
default:
- OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
- result = OC_STACK_ERROR;
+ OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType);
+ result = OC_STACK_INVALID_PARAM;
break;
}
- if(result == OC_STACK_OK)
- {
- err = err || cbor_value_leave_container(&rootValue, &arrayValue);
- if(err != CborNoError)
- {
- return OC_STACK_MALFORMED_RESPONSE;
- }
- }
- else
- {
- OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
- }
+ OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result);
+exit:
return result;
}
void OCFreeOCStringLL(OCStringLL* ll);
-static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal)
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
+ size_t size)
{
- bool err = false;
- char * securityData = NULL;
-
- if(cbor_value_is_map(arrayVal))
+ if (size > 0)
{
- CborValue curVal;
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
-
- if(cbor_value_is_valid(&curVal))
- {
- size_t len;
- err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL);
- }
+ *outPayload = (OCPayload *)OCSecurityPayloadCBORCreate(payload, size);
}
else
{
- OC_LOG(ERROR, TAG, "Cbor main value not a map");
- return OC_STACK_MALFORMED_RESPONSE;
+ *outPayload = NULL;
}
+ return OC_STACK_OK;
+}
- err = err || cbor_value_advance(arrayVal);
-
- if(err)
+static char* InPlaceStringTrim(char* str)
+{
+ while (str[0] == ' ')
{
- OC_LOG(ERROR, TAG, "Cbor in error condition");
- OICFree(securityData);
- return OC_STACK_MALFORMED_RESPONSE;
+ ++str;
}
- *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData);
- OICFree(securityData);
+ size_t lastchar = strlen(str);
- return OC_STACK_OK;
+ while (str[lastchar] == ' ')
+ {
+ str[lastchar] = '\0';
+ --lastchar;
+ }
+ return str;
}
-static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal)
+static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
{
- bool err = false;
-
- OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
-
- if(!out)
- {
- return OC_STACK_NO_MEMORY;
- }
+ CborValue val;
+ CborError err = cbor_value_map_find_value(map, type, &val);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");
- size_t resourceCount = 0;
- while(!err &&
- cbor_value_is_map(arrayVal))
+ if (cbor_value_is_text_string(&val))
{
- OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
- if(!resource)
- {
- OC_LOG(ERROR, TAG, "Memory allocation failed");
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
- CborValue curVal;
-
- // Uri
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
- size_t len;
- err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+ char *input = NULL;
+ char *savePtr = NULL;
+ size_t len = 0;
- // SID
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal);
- err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL);
+ err = cbor_value_dup_text_string(&val, &input, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");
- // Prop Tag
+ if (input)
{
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal);
- // ResourceTypes
- CborValue rtArray;
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtArray);
-
- CborValue rtVal;
- err = err || cbor_value_enter_container(&rtArray, &rtVal);
-
- OCStringLL* llPtr = NULL;
- while(!err && cbor_value_is_text_string(&rtVal))
- {
- if(resource->types == NULL)
- {
- resource->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
- llPtr = resource->types;
- if(!llPtr)
- {
- OC_LOG(ERROR, TAG, "Memory allocation failed");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
- }
- else if(llPtr)
- {
- llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
- llPtr = llPtr->next;
- if(!llPtr)
- {
- OC_LOG(ERROR, TAG, "Memory allocation failed");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, "Unknown state in resource type copying");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
-
- err = err || cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
- err = err || cbor_value_advance(&rtVal);
- }
-
- err = err || cbor_value_leave_container(&rtArray, &rtVal);
- //
- // Interface Types
- CborValue ifArray;
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifArray);
- CborValue ifVal;
- err = err || cbor_value_enter_container(&ifArray, &ifVal);
-
- llPtr = NULL;
- while(!err && cbor_value_is_text_string(&ifVal))
- {
- if(resource->interfaces == NULL)
- {
- resource->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
- llPtr = resource->interfaces;
- if(!llPtr)
- {
- OC_LOG(ERROR, TAG, "Memory allocation failed");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
- }
- else if (llPtr)
- {
- llPtr->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
- llPtr = llPtr->next;
- if(!llPtr)
- {
- OC_LOG(ERROR, TAG, "Memory allocation failed");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OCFreeOCStringLL(resource->interfaces);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, "Unknown state in resource interfaces copying");
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_NO_MEMORY;
- }
-
- err = err || cbor_value_dup_text_string(&ifVal, &(llPtr->value), &len, NULL);
- err = err || cbor_value_advance(&ifVal);
- }
- err = err || cbor_value_leave_container(&ifArray, &ifVal);
-
- // Policy
+ char *curPtr = strtok_r(input, " ", &savePtr);
+ while (curPtr)
{
- CborValue policyMap;
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap);
-
- // Bitmap
- CborValue val;
- err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
- uint64_t temp = 0;
- err = err || cbor_value_get_uint64(&val, &temp);
- resource->bitmap = (uint8_t)temp;
- // Secure Flag
- err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
- if(cbor_value_is_valid(&val))
+ char *trimmed = InPlaceStringTrim(curPtr);
+ if (trimmed[0] !='\0')
{
- err = err || cbor_value_get_boolean(&val, &(resource->secure));
- // Port
- CborValue port;
- err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
- &port);
- if(cbor_value_is_valid(&port))
+ if (!OCResourcePayloadAddStringLL(resource, trimmed))
{
- err = err || cbor_value_get_uint64(&port, &temp);
- resource->port = (uint16_t)temp;
+ return CborErrorOutOfMemory;
}
}
+ curPtr = strtok_r(NULL, " ", &savePtr);
}
+ OICFree(input);
}
+ }
+exit:
+ return err;
+}
- err = err || cbor_value_advance(arrayVal);
- if(err)
+static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue)
+{
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ OCResourcePayload *resource = NULL;
+ OCDiscoveryPayload *out = NULL;
+ size_t len = 0;
+ CborError err = CborNoError;
+ *outPayload = NULL;
+
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
+ VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue");
+
+ // Root value is already inside the main root array
+ CborValue rootMap;
+ ret = OC_STACK_NO_MEMORY;
+ out = OCDiscoveryPayloadCreate();
+ VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload");
+
+ // Enter the main root map
+ ret = OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_enter_container(rootValue, &rootMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container");
+
+ // Look for DI
+ CborValue curVal;
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
+ if (cbor_value_is_valid(&curVal))
+ {
+ if (cbor_value_is_byte_string(&curVal))
{
- OICFree(resource->uri);
- OICFree(resource->sid);
- OCFreeOCStringLL(resource->types);
- OCFreeOCStringLL(resource->interfaces);
- OICFree(resource);
- OCDiscoveryPayloadDestroy(out);
- OC_LOG_V(ERROR, TAG, "CBOR in error condition", err);
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&(out->sid), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
+ }
+ else if (cbor_value_is_text_string(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &(out->sid), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value");
}
- ++resourceCount;
- OCDiscoveryPayloadAddNewResource(out, resource);
}
- if(err)
+ // BaseURI - Not a mandatory field
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- OCDiscoveryPayloadDestroy(out);
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
}
- else
- {
- *outPayload = (OCPayload*)out;
- return OC_STACK_OK;
- }
-}
-static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* arrayVal)
-{
- bool err = false;
+ // Look for Links which will have an array as the value
+ CborValue linkMap;
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag");
- if(cbor_value_is_map(arrayVal))
+ // Enter the links array and start iterating through the array processing
+ // each resource which shows up as a map.
+ CborValue resourceMap;
+ err = cbor_value_enter_container(&linkMap, &resourceMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map");
+
+ while (cbor_value_is_map(&resourceMap))
{
- char* uri = NULL;
- uint8_t* sid = NULL;
- char* dname = NULL;
- char* specVer = NULL;
- char* dmVer = NULL;
- CborValue curVal;
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
- size_t len;
- err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
+ resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload));
+ VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload");
- // Representation
+ // Uri
+ err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
+ err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find href value");
+
+ // ResourceTypes
+ err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value");
+
+ // Interface Types
+ err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces);
+ if (CborNoError != err)
{
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
-
- CborValue repVal;
- // Device ID
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_ID, &repVal);
- err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL);
- // Device Name
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DEVICE_NAME, &repVal);
- err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL);
- // Device Spec Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SPEC_VERSION, &repVal);
- err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL);
- // Data Model Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_DATA_MODEL_VERSION, &repVal);
- err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL);
-
+ if (!OCResourcePayloadAddStringLL(&resource->interfaces, OC_RSRVD_INTERFACE_LL))
+ {
+ err = CborErrorOutOfMemory;
+ }
}
- err = err || cbor_value_advance(arrayVal);
+ // Policy
+ CborValue policyMap;
+ err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag");
+
+ // Bitmap
+ err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag");
+ err = cbor_value_get_int(&curVal, (int *)&resource->bitmap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value");
- if(err)
+ // Secure Flag
+ err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- OICFree(uri);
- OICFree(sid);
- OICFree(dname);
- OICFree(specVer);
- OICFree(dmVer);
- OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err);
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_get_boolean(&curVal, &(resource->secure));
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
}
- *outPayload = (OCPayload*)OCDevicePayloadCreate(uri, sid, dname, specVer, dmVer);
-
- OICFree(uri);
- OICFree(sid);
- OICFree(dname);
- OICFree(specVer);
- OICFree(dmVer);
- if(!*outPayload)
+ // Port
+ err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- return OC_STACK_NO_MEMORY;
+ err = cbor_value_get_int(&curVal, (int *)&resource->port);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find port value");
}
- return OC_STACK_OK;
- }
- else
- {
- OC_LOG(ERROR, TAG, "Root device node was not a map");
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_advance(&resourceMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
+
+ OCDiscoveryPayloadAddNewResource(out, resource);
}
+ err = cbor_value_leave_container(rootValue, &resourceMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map");
+
+ *outPayload = (OCPayload *)out;
+ return OC_STACK_OK;
+
+exit:
+ OCDiscoveryResourceDestroy(resource);
+ OCDiscoveryPayloadDestroy(out);
+ return ret;
}
-static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* arrayVal)
+static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue)
{
- bool err = false;
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ CborError err = CborNoError;
+ OCDevicePayload *out = NULL;
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload");
+ VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue");
+
+ *outPayload = NULL;
+
+ out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload));
+ VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload")
+ out->base.type = PAYLOAD_TYPE_DEVICE;
+ ret = OC_STACK_MALFORMED_RESPONSE;
- if(cbor_value_is_map(arrayVal))
+ if (cbor_value_is_map(rootValue))
{
- char* uri = NULL;
- OCPlatformInfo info = {0};
CborValue curVal;
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal);
- size_t len;
- err = err || cbor_value_dup_text_string(&curVal, &uri, &len, NULL);
-
- // Representation
+ // Resource Type
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal);
-
- CborValue repVal;
- // Platform ID
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_ID, &repVal);
- err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
-
- // MFG Name
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_NAME, &repVal);
- err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
-
- // MFG URL
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_URL, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
- }
-
- // Model Num
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MODEL_NUM, &repVal);
- if(cbor_value_is_valid(&repVal))
+ err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
+ }
+ // Device ID
+ size_t len = 0;
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ if (cbor_value_is_byte_string(&curVal))
{
- err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
+ err = cbor_value_dup_byte_string(&curVal, (uint8_t **)&out->sid, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
}
-
- // Date of Mfg
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_MFG_DATE, &repVal);
- if(cbor_value_is_valid(&repVal))
+ else if (cbor_value_is_text_string(&curVal))
{
- err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len,
- NULL);
+ err = cbor_value_dup_text_string(&curVal, &out->sid, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload");
}
+ }
+ // Device Name
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload");
+ }
+ // Device Spec Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload");
+ }
+ // Data Model Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload");
+ }
+ err = cbor_value_advance(rootValue);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload");
- // Platform Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_PLATFORM_VERSION, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len,
- NULL);
- }
+ *outPayload = (OCPayload *)out;
+ return OC_STACK_OK;
+ }
- // OS Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_OS_VERSION, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion),
- &len, NULL);
- }
+exit:
+ OCDevicePayloadDestroy(out);
+ return ret;
+}
- // Hardware Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_HARDWARE_VERSION, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len,
- NULL);
- }
+static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue)
+{
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ CborError err = CborNoError;
+ OCPlatformInfo info = {0};
+ char* rt = NULL;
+ OCStringLL* interfaces = NULL;
+ OCPlatformPayload* out = NULL;
- // Firmware Version
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_FIRMWARE_VERSION, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len,
- NULL);
- }
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
- // Support URL
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SUPPORT_URL, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
- }
+ if (cbor_value_is_map(rootValue))
+ {
+ CborValue repVal;
+ size_t len = 0;
+ ret = OC_STACK_MALFORMED_RESPONSE;
- // System Time
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_SYSTEM_TIME, &repVal);
- if(cbor_value_is_valid(&repVal))
- {
- err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
- }
+ // Platform ID
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload");
}
-
- err = err || cbor_value_advance(arrayVal);
-
- if(err)
+ // MFG Name
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload");
+ }
+ // MFG URL
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
+ if (cbor_value_is_valid(&repVal))
{
- OICFree(info.dateOfManufacture);
- OICFree(info.firmwareVersion);
- OICFree(info.hardwareVersion);
- OICFree(info.manufacturerName);
- OICFree(info.manufacturerUrl);
- OICFree(info.modelNumber);
- OICFree(info.operatingSystemVersion);
- OICFree(info.platformID);
- OICFree(info.platformVersion);
- OICFree(info.supportUrl);
- OICFree(info.systemTime);
- OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload");
+ }
+ // Model Num
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload");
+ }
+ // Date of Mfg
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload");
+ }
+ // Platform Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload");
+ }
+ // OS Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
+ if (cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload");
+ }
+ // Hardware Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload");
+ }
+ // Firmware Version
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload");
+ }
+ // Support URL
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
+ }
+ // System Time
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload");
}
- *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(uri, &info);
+ // Resource type
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
+ if(cbor_value_is_valid(&repVal))
+ {
+ err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find resource type in the platform payload");
+ }
- if(!*outPayload)
+ // Interface Types
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
+ if(cbor_value_is_valid(&repVal))
{
- return OC_STACK_NO_MEMORY;
+ err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
}
- return OC_STACK_OK;
- }
- else
- {
- OC_LOG(ERROR, TAG, "Root device node was not a map");
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_advance(rootValue);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload");
+
+ out = (OCPlatformPayload *)OCPlatformPayloadCreateAsOwner(&info);
+ out->rt = rt;
+ out->interfaces = interfaces;
+ *outPayload = (OCPayload *)out;
+ return OC_STACK_OK;
}
+
+exit:
+ OCPlatformInfoDestroy(&info);
+ OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload");
+ return ret;
}
static OCRepPayloadPropType DecodeCborType(CborType type)
{
switch (type)
{
- case CborNullType:
- return OCREP_PROP_NULL;
- case CborIntegerType:
- return OCREP_PROP_INT;
- case CborDoubleType:
- return OCREP_PROP_DOUBLE;
- case CborBooleanType:
- return OCREP_PROP_BOOL;
- case CborTextStringType:
- return OCREP_PROP_STRING;
- case CborMapType:
- return OCREP_PROP_OBJECT;
- case CborArrayType:
- return OCREP_PROP_ARRAY;
- default:
- return OCREP_PROP_NULL;
+ case CborNullType:
+ return OCREP_PROP_NULL;
+ case CborIntegerType:
+ return OCREP_PROP_INT;
+ case CborDoubleType:
+ case CborFloatType:
+ return OCREP_PROP_DOUBLE;
+ case CborBooleanType:
+ return OCREP_PROP_BOOL;
+ case CborTextStringType:
+ return OCREP_PROP_STRING;
+ case CborByteStringType:
+ return OCREP_PROP_BYTE_STRING;
+ case CborMapType:
+ return OCREP_PROP_OBJECT;
+ case CborArrayType:
+ return OCREP_PROP_ARRAY;
+ default:
+ return OCREP_PROP_NULL;
}
}
-static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
- OCRepPayloadPropType* type)
+static CborError OCParseArrayFindDimensionsAndType(const CborValue *parent,
+ size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType *type)
{
- bool err = false;
CborValue insideArray;
*type = OCREP_PROP_NULL;
dimensions[0] = dimensions[1] = dimensions[2] = 0;
- err = err || cbor_value_enter_container(parent, &insideArray);
+ CborError err = cbor_value_enter_container(parent, &insideArray);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
while (cbor_value_is_valid(&insideArray))
{
{
size_t subdim[MAX_REP_ARRAY_DEPTH];
tempType = OCREP_PROP_NULL;
- err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
+ err = OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse array");
if (subdim[2] != 0)
{
- OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
+ OIC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep");
}
dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0];
dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1];
- if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL
- && *type != tempType)
+ if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType)
{
- OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
- return true;
+ OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)");
+ return CborUnknownError;
}
else if (*type == OCREP_PROP_NULL)
{
else if (tempType != OCREP_PROP_NULL && *type != tempType)
{
// this is an invalid situation!
- OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
- return true;
+ OIC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed");
+ return CborUnknownError;
}
++dimensions[0];
- cbor_value_advance(&insideArray);
+ err = cbor_value_advance(&insideArray);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance array");
}
+exit:
return err;
}
return sizeof (bool);
case OCREP_PROP_STRING:
return sizeof (char*);
+ case OCREP_PROP_BYTE_STRING:
+ return sizeof (OCByteString);
case OCREP_PROP_OBJECT:
return sizeof (OCRepPayload*);
default:
elementNum;
}
-static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH],
- OCRepPayloadPropType type, void* targetArray)
+static CborError OCParseArrayFillArray(const CborValue *parent,
+ size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray)
{
- bool err = false;
CborValue insideArray;
- err = err || cbor_value_enter_container(parent, &insideArray);
-
size_t i = 0;
- char* tempStr = NULL;
+ char *tempStr = NULL;
+ OCByteString ocByteStr = { .bytes = NULL, .len = 0};
size_t tempLen = 0;
- OCRepPayload* tempPl = NULL;
+ OCRepPayload *tempPl = NULL;
size_t newdim[MAX_REP_ARRAY_DEPTH];
newdim[0] = dimensions[1];
newdim[1] = dimensions[2];
newdim[2] = 0;
+ CborError err = cbor_value_enter_container(parent, &insideArray);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container");
+
while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray))
{
+ bool noAdvance = false;
if (cbor_value_get_type(&insideArray) != CborNullType)
{
switch (type)
case OCREP_PROP_INT:
if (dimensions[1] == 0)
{
- err = err || cbor_value_get_int64(&insideArray,
- &(((int64_t*)targetArray)[i]));
+ err = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i]));
}
else
{
- err = err || OCParseArrayFillArray(&insideArray, newdim,
- type,
- &(((int64_t*)targetArray)[arrayStep(dimensions, i)])
- );
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((int64_t*)targetArray)[arrayStep(dimensions, i)]));
}
break;
case OCREP_PROP_DOUBLE:
if (dimensions[1] == 0)
{
- err = err || cbor_value_get_double(&insideArray,
- &(((double*)targetArray)[i]));
+ double *d = &(((double*)targetArray)[i]);
+ if (cbor_value_get_type(&insideArray) == CborDoubleType)
+ {
+ err = cbor_value_get_double(&insideArray, d);
+ }
+ else
+ {
+ /* must be float */
+ float f;
+ err = cbor_value_get_float(&insideArray, &f);
+ if (!err)
+ *d = f;
+ }
}
else
{
- err = err || OCParseArrayFillArray(&insideArray, newdim,
- type,
- &(((double*)targetArray)[arrayStep(dimensions, i)])
- );
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((double*)targetArray)[arrayStep(dimensions, i)]));
}
break;
case OCREP_PROP_BOOL:
if (dimensions[1] == 0)
{
- err = err || cbor_value_get_boolean(&insideArray,
- &(((bool*)targetArray)[i]));
+ err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i]));
}
else
{
- err = err || OCParseArrayFillArray(&insideArray, newdim,
- type,
- &(((bool*)targetArray)[arrayStep(dimensions, i)])
- );
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((bool*)targetArray)[arrayStep(dimensions, i)]));
}
break;
case OCREP_PROP_STRING:
if (dimensions[1] == 0)
{
- err = err || cbor_value_dup_text_string(&insideArray,
- &tempStr, &tempLen, NULL);
+ err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL);
((char**)targetArray)[i] = tempStr;
tempStr = NULL;
}
else
{
- err = err || OCParseArrayFillArray(&insideArray, newdim,
- type,
- &(((char**)targetArray)[arrayStep(dimensions, i)])
- );
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((char**)targetArray)[arrayStep(dimensions, i)]));
+ }
+ break;
+ case OCREP_PROP_BYTE_STRING:
+ if (dimensions[1] == 0)
+ {
+ err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes),
+ &(ocByteStr.len), NULL);
+ ((OCByteString*)targetArray)[i] = ocByteStr;
+ }
+ else
+ {
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((OCByteString*)targetArray)[arrayStep(dimensions, i)]));
}
break;
case OCREP_PROP_OBJECT:
if (dimensions[1] == 0)
{
- err = err || OCParseSingleRepPayload(&tempPl, &insideArray);
+ err = OCParseSingleRepPayload(&tempPl, &insideArray, false);
((OCRepPayload**)targetArray)[i] = tempPl;
tempPl = NULL;
+ noAdvance = true;
}
else
{
- err = err || OCParseArrayFillArray(&insideArray, newdim,
- type,
- &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])
- );
+ err = OCParseArrayFillArray(&insideArray, newdim, type,
+ &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]));
}
break;
default:
- OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
- err = true;
+ OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
+ err = CborErrorUnknownType;
break;
}
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload");
}
++i;
- err = err || cbor_value_advance(&insideArray);
+ if (!noAdvance && cbor_value_is_valid(&insideArray))
+ {
+ err = cbor_value_advance(&insideArray);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray");
+ }
}
+exit:
return err;
}
-static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* container)
+static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
{
+ void *arr = NULL;
OCRepPayloadPropType type;
size_t dimensions[MAX_REP_ARRAY_DEPTH];
- bool err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
-
- if (err)
- {
- OC_LOG(ERROR, TAG, "Array details weren't clear");
- return err;
- }
+ size_t dimTotal = 0;
+ size_t allocSize = 0;
+ bool res = true;
+ CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear");
if (type == OCREP_PROP_NULL)
{
- err = err || OCRepPayloadSetNull(out, name);
- err = err || cbor_value_advance(container);
+ res = OCRepPayloadSetNull(out, name);
+ err = (CborError) !res;
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
+ err = cbor_value_advance(container);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container");
return err;
}
- size_t dimTotal = calcDimTotal(dimensions);
- size_t allocSize = getAllocSize(type);
- void* arr = OICCalloc(dimTotal, allocSize);
+ dimTotal = calcDimTotal(dimensions);
+ allocSize = getAllocSize(type);
+ arr = OICCalloc(dimTotal, allocSize);
+ VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed");
- if (!arr)
- {
- OC_LOG(ERROR, TAG, "Array Parse allocation failed");
- return true;
- }
-
- err = err || OCParseArrayFillArray(container, dimensions, type, arr);
+ res = OCParseArrayFillArray(container, dimensions, type, arr);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array");
switch (type)
{
case OCREP_PROP_INT:
- if (err || !OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t*)arr, dimensions))
- {
- OICFree(arr);
- err = true;
- }
+ res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions);
break;
case OCREP_PROP_DOUBLE:
- if (err || !OCRepPayloadSetDoubleArrayAsOwner(out, name, (double*)arr, dimensions))
- {
- OICFree(arr);
- err = true;
- }
+ res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions);
break;
case OCREP_PROP_BOOL:
- if (err || !OCRepPayloadSetBoolArrayAsOwner(out, name, (bool*)arr, dimensions))
- {
- OICFree(arr);
- err = true;
- }
+ res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions);
break;
case OCREP_PROP_STRING:
- if (err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
- {
- for(size_t i = 0; i < dimTotal; ++i)
- {
- OICFree(((char**)arr)[i]);
- }
- OICFree(arr);
- err = true;
- }
+ res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions);
+ break;
+ case OCREP_PROP_BYTE_STRING:
+ res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions);
break;
case OCREP_PROP_OBJECT:
- if (err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions))
- {
- for(size_t i = 0; i < dimTotal; ++i)
- {
- OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
- }
- OICFree(arr);
- err = true;
- }
+ res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions);
break;
default:
- OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
- err = true;
+ OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array");
break;
}
-
- return err;
-}
-
-static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent)
-{
- *outPayload = OCRepPayloadCreate();
- OCRepPayload* curPayload = *outPayload;
- bool err = false;
- if(!*outPayload)
+ err = (CborError) !res;
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter");
+ return CborNoError;
+exit:
+ if (type == OCREP_PROP_STRING)
{
- return CborErrorOutOfMemory;
+ for(size_t i = 0; i < dimTotal; ++i)
+ {
+ OICFree(((char**)arr)[i]);
+ }
}
-
- size_t len;
- CborValue curVal;
- err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal);
- if(cbor_value_is_valid(&curVal))
+ if (type == OCREP_PROP_BYTE_STRING)
{
- err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len,
- NULL);
+ for(size_t i = 0; i < dimTotal; ++i)
+ {
+ OICFree(((OCByteString*)arr)[i].bytes);
+ }
}
-
- err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal);
- if(cbor_value_is_valid(&curVal))
+ if (type == OCREP_PROP_OBJECT)
{
- CborValue insidePropArray = {0};
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE,
- &insidePropArray);
-
- if(cbor_value_is_array(&insidePropArray))
+ for(size_t i = 0; i < dimTotal; ++i)
{
- CborValue rtArray;
- err = err || cbor_value_enter_container(&insidePropArray, &rtArray);
-
- while(!err && cbor_value_is_valid(&rtArray))
- {
- char* curRt;
- err = err || cbor_value_dup_text_string(&rtArray, &curRt, &len, NULL);
- err = err || cbor_value_advance(&rtArray);
- OCRepPayloadAddResourceTypeAsOwner(curPayload, curRt);
- }
-
- err = err || cbor_value_leave_container(&insidePropArray, &rtArray);
+ OCRepPayloadDestroy(((OCRepPayload**)arr)[i]);
}
+ }
+ OICFree(arr);
+ return err;
+}
- err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropArray);
+static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot)
+{
+ CborError err = CborUnknownError;
+ char *name = NULL;
+ bool res = false;
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
+ VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap");
- if(cbor_value_is_array(&insidePropArray))
+ if (cbor_value_is_map(objMap))
+ {
+ if (!*outPayload)
{
- CborValue ifArray;
- err = err || cbor_value_enter_container(&insidePropArray, &ifArray);
-
- while(!err && cbor_value_is_valid(&ifArray))
+ *outPayload = OCRepPayloadCreate();
+ if (!*outPayload)
{
- char* curIf;
- err = err || cbor_value_dup_text_string(&ifArray, &curIf, &len, NULL);
- err = err || cbor_value_advance(&ifArray);
- OCRepPayloadAddInterfaceAsOwner(curPayload, curIf);
+ return CborErrorOutOfMemory;
}
-
- err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
}
- }
- err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
- if(cbor_value_is_map(&curVal))
- {
+ OCRepPayload *curPayload = *outPayload;
+
+ size_t len = 0;
CborValue repMap;
- err = err || cbor_value_enter_container(&curVal, &repMap);
+ err = cbor_value_enter_container(objMap, &repMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
- while(!err && cbor_value_is_valid(&repMap))
+ while (!err && cbor_value_is_valid(&repMap))
{
- char* name;
- err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL);
-
- err = err || cbor_value_advance(&repMap);
-
- int64_t intval = 0;
- bool boolval = false;
- char* strval = NULL;
- double doubleval = 0;
- OCRepPayload* pl;
-
- switch(cbor_value_get_type(&repMap))
+ if (cbor_value_is_text_string(&repMap))
+ {
+ err = cbor_value_dup_text_string(&repMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map");
+ err = cbor_value_advance(&repMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap");
+ if (name &&
+ isRoot &&
+ ((0 == strcmp(OC_RSRVD_HREF, name)) ||
+ (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) ||
+ (0 == strcmp(OC_RSRVD_INTERFACE, name))))
+ {
+ err = cbor_value_advance(&repMap);
+ OICFree(name);
+ continue;
+ }
+ }
+ CborType type = cbor_value_get_type(&repMap);
+ switch (type)
{
case CborNullType:
- err = !OCRepPayloadSetNull(curPayload, name);
+ res = OCRepPayloadSetNull(curPayload, name);
break;
case CborIntegerType:
- err = err || cbor_value_get_int64(&repMap, &intval);
- if (!err)
{
- err = !OCRepPayloadSetPropInt(curPayload, name, intval);
+ int64_t intval = 0;
+ err = cbor_value_get_int64(&repMap, &intval);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value");
+ res = OCRepPayloadSetPropInt(curPayload, name, intval);
}
break;
case CborDoubleType:
- err = err || cbor_value_get_double(&repMap, &doubleval);
- if (!err)
{
- err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval);
+ double doubleval = 0;
+ err = cbor_value_get_double(&repMap, &doubleval);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value");
+ res = OCRepPayloadSetPropDouble(curPayload, name, doubleval);
}
break;
case CborBooleanType:
- err = err || cbor_value_get_boolean(&repMap, &boolval);
- if (!err)
{
- err = !OCRepPayloadSetPropBool(curPayload, name, boolval);
+ bool boolval = false;
+ err = cbor_value_get_boolean(&repMap, &boolval);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value");
+ res = OCRepPayloadSetPropBool(curPayload, name, boolval);
}
break;
case CborTextStringType:
- err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
- if (!err)
{
- err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
+ char *strval = NULL;
+ err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value");
+ res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval);
+ }
+ break;
+ case CborByteStringType:
+ {
+ uint8_t* bytestrval = NULL;
+ err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value");
+ OCByteString tmp = {.bytes = bytestrval, .len = len};
+ res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp);
}
break;
case CborMapType:
- err = err || OCParseSingleRepPayload(&pl, &repMap);
- if (!err)
{
- err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
+ OCRepPayload *pl = NULL;
+ err = OCParseSingleRepPayload(&pl, &repMap, false);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep");
+ res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl);
}
break;
case CborArrayType:
- err = err || OCParseArray(curPayload, name, &repMap);
+ err = OCParseArray(curPayload, name, &repMap);
break;
default:
- OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
- err = true;
+ OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type);
+ res = false;
+ }
+ if (type != CborArrayType)
+ {
+ err = (CborError) !res;
}
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value");
- err = err || cbor_value_advance(&repMap);
+ if (type != CborMapType && cbor_value_is_valid(&repMap))
+ {
+ err = cbor_value_advance(&repMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap");
+ }
OICFree(name);
+ name = NULL;
}
- err = err || cbor_value_leave_container(&curVal, &repMap);
- }
-
- if(err)
- {
- OCRepPayloadDestroy(*outPayload);
- *outPayload = NULL;
+ if (cbor_value_is_container(objMap))
+ {
+ err = cbor_value_leave_container(objMap, &repMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container");
+ }
+ return err;
}
+exit:
+ OICFree(name);
+ OCRepPayloadDestroy(*outPayload);
+ *outPayload = NULL;
return err;
}
-static OCStackResult OCParseRepPayload(OCPayload** outPayload, CborValue* arrayVal)
-{
- bool err = false;
- OCRepPayload* rootPayload = NULL;
- OCRepPayload* curPayload = NULL;
- OCRepPayload* temp = NULL;
- while(!err && cbor_value_is_map(arrayVal))
+static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
+{
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ CborError err;
+ OCRepPayload *temp = NULL;
+ OCRepPayload *rootPayload = NULL;
+ OCRepPayload *curPayload = NULL;
+ CborValue rootMap = *root;
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
+ VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root");
+
+ *outPayload = NULL;
+ if (cbor_value_is_array(root))
{
- err = err || OCParseSingleRepPayload(&temp, arrayVal);
+ err = cbor_value_enter_container(root, &rootMap);
+ }
+ while (cbor_value_is_valid(&rootMap))
+ {
+ temp = OCRepPayloadCreate();
+ ret = OC_STACK_NO_MEMORY;
+ VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory");
+
+ CborValue curVal;
+ ret = OC_STACK_MALFORMED_RESPONSE;
+ if (cbor_value_is_map(&rootMap))
+ {
+ err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
+ if (cbor_value_is_valid(&curVal))
+ {
+ size_t len = 0;
+ err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri");
+ }
+ }
+ // Resource types
+ if (cbor_value_is_map(&rootMap))
+ {
+ if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal))
+ {
+ err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value");
+ }
+ }
+
+ // Interface Types
+ if (cbor_value_is_map(&rootMap))
+ {
+ if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal))
+ {
+ err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value");
+ }
+ }
+
+ if (cbor_value_is_map(&rootMap))
+ {
+ err = OCParseSingleRepPayload(&temp, &rootMap, true);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload");
+ }
if(rootPayload == NULL)
{
rootPayload = temp;
curPayload = curPayload->next;
}
-
- err = err || cbor_value_advance(arrayVal);
- if(err)
+ if (cbor_value_is_array(&rootMap))
{
- OCRepPayloadDestroy(rootPayload);
- OC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
- return OC_STACK_MALFORMED_RESPONSE;
+ err = cbor_value_advance(&rootMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload");
}
}
-
- *outPayload = (OCPayload*)rootPayload;
-
+ *outPayload = (OCPayload *)rootPayload;
return OC_STACK_OK;
+
+exit:
+ OCRepPayloadDestroy(temp);
+ OCRepPayloadDestroy(rootPayload);
+ OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload");
+ return ret;
}
-static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal)
+static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
{
- bool err = false;
- if(cbor_value_is_map(arrayVal))
- {
- uint64_t seqNum = 0;
- uint64_t maxAge = 0;
- OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE;
- char* tempStr = NULL;
- size_t len = 0;
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ OCPresencePayload *payload = NULL;
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
+
+ *outPayload = NULL;
+ payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload));
+ ret = OC_STACK_NO_MEMORY;
+ VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload");
+ payload->base.type = PAYLOAD_TYPE_PRESENCE;
+ ret = OC_STACK_MALFORMED_RESPONSE;
+
+ if (cbor_value_is_map(rootValue))
+ {
CborValue curVal;
+
// Sequence Number
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal);
- err = err || cbor_value_get_uint64(&curVal, &seqNum);
+ CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag");
+ err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value");
// Max Age
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal);
- err = err || cbor_value_get_uint64(&curVal, &maxAge);
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag");
+ err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value");
// Trigger
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal);
- err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
- trigger = convertTriggerStringToEnum(tempStr);
- OICFree(tempStr);
- tempStr = NULL;
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag");
+ err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value");
// Resource type name
- err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
- if(cbor_value_is_valid(&curVal))
- {
- err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL);
- }
-
- err = err || cbor_value_advance(arrayVal);
-
- if(!err)
+ err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ if (cbor_value_is_valid(&curVal))
{
- *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr);
+ size_t len = 0;
+ err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value");
}
- OICFree(tempStr);
- if(err)
- {
- OCPayloadDestroy(*outPayload);
- OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
- return OC_STACK_MALFORMED_RESPONSE;
- }
-
- if(!*outPayload)
- {
- return OC_STACK_NO_MEMORY;
- }
+ err = cbor_value_advance(rootValue);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value");
+ *outPayload = (OCPayload *)payload;
return OC_STACK_OK;
}
- else
- {
- OC_LOG(ERROR, TAG, "Root presence node was not a map");
- return OC_STACK_MALFORMED_RESPONSE;
- }
+exit:
+ OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload");
+ OCPresencePayloadDestroy(payload);
+ return ret;
}