static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue) { OCStackResult ret = OC_STACK_MALFORMED_RESPONSE; CborError err; char *securityData = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter"); VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid cbor"); CborValue strVal; err = cbor_value_enter_container(rootValue, &strVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container"); if (cbor_value_is_text_string(&strVal)) { size_t len = 0; err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data"); *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData); VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor"); ret = OC_STACK_OK; } exit: OICFree(securityData); return ret; }
static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue) { 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(rootValue)) { // Device ID size_t len = 0; CborValue curVal; err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_byte_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"); *outPayload = (OCPayload *)out; return OC_STACK_OK; } exit: OCDevicePayloadDestroy(out); return ret; }
static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue) { 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 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 = 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 = 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 = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal); if (cbor_value_is_valid(&curVal)) { 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"); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value"); *outPayload = (OCPayload *)payload; return OC_STACK_OK; } exit: OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload"); OCPresencePayloadDestroy(payload); return ret; }
OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType, const uint8_t *payload, size_t payloadSize) { OCStackResult result = OC_STACK_MALFORMED_RESPONSE; CborError err; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed"); VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value"); OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize); CborParser parser; CborValue rootValue; err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "Failed initializing init value") switch(payloadType) { case PAYLOAD_TYPE_DISCOVERY: result = OCParseDiscoveryPayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_DEVICE: result = OCParseDevicePayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_PLATFORM: result = OCParsePlatformPayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_REPRESENTATION: result = OCParseRepPayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_PRESENCE: result = OCParsePresencePayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_SECURITY: result = OCParseSecurityPayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_RD: result = OCRDCborToPayload(&rootValue, outPayload); break; default: OIC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType); result = OC_STACK_INVALID_PARAM; break; } OIC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result); exit: return result; }
OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links) { OCResourceCollectionPayload *pl = NULL; VERIFY_PARAM_NON_NULL(TAG, tags, "Invalid param tags"); VERIFY_PARAM_NON_NULL(TAG, links, "Invalid param links"); pl = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload)); VERIFY_PARAM_NON_NULL(TAG, pl, "Failed allocating memory for the OCResourceCollectionPayload"); pl->tags = tags; pl->setLinks = links; exit: return pl; }
static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source) { if (!source || !dest) { return; } switch(source->type) { case OCREP_PROP_STRING: dest->str = OICStrdup(source->str); break; case OCREP_PROP_BYTE_STRING: dest->ocByteStr.bytes = (uint8_t*)OICMalloc(source->ocByteStr.len * sizeof(uint8_t)); VERIFY_PARAM_NON_NULL(TAG, dest->ocByteStr.bytes, "Failed allocating memory"); dest->ocByteStr.len = source->ocByteStr.len; memcpy(dest->ocByteStr.bytes, source->ocByteStr.bytes, dest->ocByteStr.len); break; case OCREP_PROP_OBJECT: dest->obj = OCRepPayloadClone(source->obj); break; case OCREP_PROP_ARRAY: OCCopyPropertyValueArray(dest, source); break; default: // Nothing to do for the trivially copyable types. break; } exit: return; }
static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload) { CborError cborFindResult = CborErrorOutOfMemory; OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload)); VERIFY_PARAM_NON_NULL(TAG, tags, "Failed allocating tags"); cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName"); { char *deviceId = NULL; cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &deviceId); if (deviceId) { memcpy(tags->di.id, deviceId, strlen(deviceId)); OICFree(deviceId); } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceId"); } cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_DEVICE_TTL, &tags->ttl); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl"); *tagsPayload = tags; return cborFindResult; exit: OCFreeTagsResource(tags); return cborFindResult; }
OCRDPayload *OCRDPayloadCreate() { OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload)); VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload"); rdPayload->base.type = PAYLOAD_TYPE_RD; exit: return rdPayload; }
static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links) { size_t len; CborValue rtArray; OCStringLL* llPtr = *links; CborError cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding tag"); CborValue rtVal; cborFindResult = cbor_value_enter_container(&rtArray, &rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering container"); while (cbor_value_is_text_string(&rtVal)) { if (llPtr == NULL) { llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL"); *links = llPtr; } else if (llPtr) { while (llPtr->next) { llPtr = llPtr->next; } llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); llPtr = llPtr->next; VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL->next"); } cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed duplicating value"); cborFindResult = cbor_value_advance(&rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing OCStringLL"); } cborFindResult = cbor_value_leave_container(&rtArray, &rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed leaving container"); exit: return cborFindResult; }
static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload) { CborError cborFindResult = CborErrorOutOfMemory; OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload)); VERIFY_PARAM_NON_NULL(TAG, tags, "Failed allocating tags"); if (cbor_value_is_map(tagsMap)) { cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName"); cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DREL, &tags->drel); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding drel"); cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_RTS, &tags->rts); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rts"); cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_BASE_URI, &tags->baseURI); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding baseURI"); char *deviceId = NULL; cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &deviceId); if (deviceId) { memcpy(tags->di.id, deviceId, strlen(deviceId)); OICFree(deviceId); } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceId"); { uint64_t value = 0; cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_HOSTING_PORT, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding port"); tags->port = value; value = 0; cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_BITMAP, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap"); tags->bitmap = value; value = 0; cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_INS, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins"); tags->ins = value; value = 0; cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_TTL, &value); tags->ttl = value; } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl"); cborFindResult = cbor_value_advance(tagsMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing bitmap"); } *tagsPayload = tags; return cborFindResult; exit: OCFreeTagsResource(tags); return cborFindResult; }
OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *deviceName, const char *id, int biasFactor) { OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload)); VERIFY_PARAM_NON_NULL(TAG, discoveryPayload, "Failed allocating memory for discovery payload"); if (deviceName) { discoveryPayload->n.deviceName = OICStrdup(deviceName); VERIFY_PARAM_NON_NULL(TAG, discoveryPayload->n.deviceName, "Failed allocating memory for discovery device name"); } if (id) { OICStrcpy((char*)discoveryPayload->di.id, MAX_IDENTITY_SIZE, id); } discoveryPayload->sel = biasFactor; return discoveryPayload; exit: OICFree(discoveryPayload); discoveryPayload = NULL; return discoveryPayload; }
static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source) { if (!dest || !source) { return; } size_t dimTotal = calcDimTotal(source->arr.dimensions); switch(source->arr.type) { case OCREP_PROP_INT: dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory"); memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t)); break; case OCREP_PROP_DOUBLE: dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory"); memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double)); break; case OCREP_PROP_BOOL: dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory"); memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool)); break; case OCREP_PROP_STRING: dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]); } break; case OCREP_PROP_OBJECT: dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]); } break; case OCREP_PROP_ARRAY: dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*)); VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]); } break; default: OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type"); break; } exit: return; }
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"); { err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value"); } // BaseURI - Not a mandatory field err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value"); } // 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"); // 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)) { resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload)); VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload"); // 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); VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag/value"); // 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"); // Secure Flag err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_get_boolean(&curVal, &(resource->secure)); VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value"); } // Port err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_get_int(&curVal, (int *)&resource->port); VERIFY_CBOR_SUCCESS(TAG, err, "to find port value"); } 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; }
int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size) { int64_t cborEncoderResult = CborErrorIO; int flags = 0; CborEncoder encoder; VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Invalid input parameter rdPayload"); VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid input parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, size, "Invalid input parameter size"); cbor_encoder_init(&encoder, outPayload, *size, flags); if (rdPayload->rdDiscovery) { CborEncoder map; cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create discovery map"); cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME, rdPayload->rdDiscovery->n.deviceName); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in map"); cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID, (char *)rdPayload->rdDiscovery->di.id); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in map"); { uint64_t value = rdPayload->rdDiscovery->sel; cborEncoderResult |= ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL, &value); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add RD_DISCOVERY_SEL in map"); } cborEncoderResult |= cbor_encoder_close_container(&encoder, &map); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map"); } else if (rdPayload->rdPublish) { CborEncoder colArray; cborEncoderResult |= cbor_encoder_create_array(&encoder, &colArray, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection array"); OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish; while (rdPublish) { cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &colArray); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload"); cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &colArray); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload"); rdPublish = rdPublish->next; } cborEncoderResult |= cbor_encoder_close_container(&encoder, &colArray); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection array"); } else { CborEncoder map; cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed entering discovery map"); cborEncoderResult |= cbor_encoder_close_container(&encoder, &map); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map"); } if (cborEncoderResult == CborErrorOutOfMemory) { *size += encoder.ptr - encoder.end; } else { *size = encoder.ptr - outPayload; } return cborEncoderResult; exit: OICFree(outPayload); return cborEncoderResult; }
static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload) { CborValue linksMap; OCLinksPayload *setLinks = NULL; CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container"); while (cbor_value_is_map(&linksMap)) { setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload)); VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value"); { uint64_t value = 0; cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value"); setLinks->ins = value; } if (!*linksPayload) { *linksPayload = setLinks; } else { OCLinksPayload *temp = *linksPayload; while (temp->next) { temp = temp->next; } temp->next = setLinks; } cborFindResult = cbor_value_advance(&linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map"); } return cborFindResult; exit: OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return cborFindResult; }
OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload) { CborValue *rdCBORPayload = (CborValue *)cborPayload; OCStackResult ret = OC_STACK_NO_MEMORY; CborError cborFindResult; OCRDPayload *rdPayload = OCRDPayloadCreate(); VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload"); ret = OC_STACK_MALFORMED_RESPONSE; if (cbor_value_is_array(rdCBORPayload)) { OCLinksPayload *linksPayload = NULL; OCTagsPayload *tagsPayload = NULL; while (cbor_value_is_container(rdCBORPayload)) { // enter tags map CborValue tags; cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering tags container."); cborFindResult= OCTagsCborToPayload(&tags, &tagsPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload."); OCTagsLog(DEBUG, tagsPayload); cborFindResult = OCLinksCborToPayload(&tags, &linksPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload."); OCLinksLog(DEBUG, linksPayload); // Move from tags payload to links array. cborFindResult = cbor_value_advance(rdCBORPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload."); } rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdPublish, "Failed allocating rdPayload->rdPublish"); } else if (cbor_value_is_map(rdCBORPayload)) { rdPayload->rdDiscovery = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload)); VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdDiscovery, "Failed allocating discoveryPayload"); cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME, &rdPayload->rdDiscovery->n.deviceName); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_NAME."); char *deviceId = NULL; cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &deviceId); if (deviceId) { memcpy(rdPayload->rdDiscovery->di.id, deviceId, strlen(deviceId)); OICFree(deviceId); } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_ID."); { uint64_t value = 0; cborFindResult = FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL."); rdPayload->rdDiscovery->sel = value; } cborFindResult = cbor_value_advance(rdCBORPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCBORPayload."); } OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); *outPayload = (OCPayload *)rdPayload; return OC_STACK_OK; exit: OCRDPayloadDestroy(rdPayload); return ret; }
static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue) { OCStackResult ret = OC_STACK_INVALID_PARAM; CborError err = CborNoError; OCPlatformInfo info = {0}; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); if (cbor_value_is_map(rootValue)) { CborValue repVal; size_t len = 0; ret = OC_STACK_MALFORMED_RESPONSE; // 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"); } // 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)) { 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"); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload"); *outPayload = (OCPayload *)OCPlatformPayloadCreateAsOwner(&info); return OC_STACK_OK; } exit: OCPlatformInfoDestroy(&info); OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload"); return ret; }
static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload, size_t *size) { CborEncoder encoder; int64_t err = CborNoError; cbor_encoder_init(&encoder, outPayload, *size, 0); if (payload->resources) { /* The format for the payload is "modelled" as JSON. [ // rootArray { // rootMap "di" : UUID, // device ID "rt": "oic.wk.res" "n":"MyDevice" "if":"oic.if.ll oic.if.baseline" "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1", links :[ // linksArray contains maps of resources { href, rt, if, policy // Resource 1 }, { href, rt, if, policy // Resource 2 }, . . . ] } ] */ // Open the main root array CborEncoder rootArray; size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload); err |= cbor_encoder_create_array(&encoder, &rootArray, 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array"); // Open the root map in the root array CborEncoder rootMap; err |= cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery map"); // Insert Name err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_NAME, sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->name); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting name"); // Insert Device ID into the root map err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1, payload->sid); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id"); // Insert Resource Type err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->type); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT"); // Insert interfaces if (payload->interface) { err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->interface); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag/value"); } // Insert baseURI if present err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI, sizeof(OC_RSRVD_BASE_URI) - 1, payload->baseURI); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting baseURI"); // Insert Links into the root map. CborEncoder linkArray; err |= cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array tag"); err |= cbor_encoder_create_array(&rootMap, &linkArray, resourceCount); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array"); for(size_t i = 0; i < resourceCount; ++i) { CborEncoder linkMap; OCResourcePayload *resource = OCDiscoveryPayloadGetResource(payload, i); VERIFY_PARAM_NON_NULL(TAG, resource, "Failed retrieving resource"); // resource map inside the links array. err |= cbor_encoder_create_map(&linkArray, &linkMap, LINKS_MAP_LEN); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating links map"); // Below are insertions of the resource properties into the map. // Uri err |= AddTextStringToMap(&linkMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, resource->uri); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding uri to links map"); // Resource Type if (resource->types) { err |= OCStringLLJoin(&linkMap, OC_RSRVD_RESOURCE_TYPE, resource->types); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resourceType tag/value to links map"); } // Interface Types if (resource->interfaces) { err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interfaces tag/value to links map"); } // Policy CborEncoder policyMap; err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY, sizeof(OC_RSRVD_POLICY) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy tag to links map"); err |= cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy map to links map"); // Bitmap err |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, sizeof(OC_RSRVD_BITMAP) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap tag to policy map"); err |= cbor_encode_uint(&policyMap, resource->bitmap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map"); if (resource->secure) { err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE, sizeof(OC_RSRVD_SECURE) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map"); err |= cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map"); } if ((resource->secure && resource->port != 0) || payload->baseURI) { err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT, sizeof(OC_RSRVD_HOSTING_PORT) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port tag"); err |= cbor_encode_uint(&policyMap, resource->port); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value"); } #ifdef TCP_ADAPTER err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT, sizeof(OC_RSRVD_TCP_PORT) - 1); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag"); err |= cbor_encode_uint(&policyMap, resource->tcpPort); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value"); #endif err |= cbor_encoder_close_container(&linkMap, &policyMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map"); // Finsihed encoding a resource, close the map. err |= cbor_encoder_close_container(&linkArray, &linkMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link map"); } // Close links array inside the root map. err |= cbor_encoder_close_container(&rootMap, &linkArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing link array"); // close root map inside the root array. err |= cbor_encoder_close_container(&rootArray, &rootMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map"); // Close the final root array. err |= cbor_encoder_close_container(&encoder, &rootArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array"); } exit: return checkError(err, &encoder, outPayload, size); }
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 = 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 = temp; } else { curPayload->next = temp; curPayload = curPayload->next; } if (cbor_value_is_array(&rootMap)) { err = cbor_value_advance(&rootMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload"); } } *outPayload = (OCPayload *)rootPayload; return OC_STACK_OK; exit: OCRepPayloadDestroy(temp); OCRepPayloadDestroy(rootPayload); OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload"); return ret; }
static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot) { CborError err = CborUnknownError; char *name = NULL; bool res; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap"); if (cbor_value_is_map(objMap)) { if (!*outPayload) { *outPayload = OCRepPayloadCreate(); if (!*outPayload) { return CborErrorOutOfMemory; } } OCRepPayload *curPayload = *outPayload; size_t len = 0; CborValue repMap; err = cbor_value_enter_container(objMap, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap"); while (!err && cbor_value_is_valid(&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: res = OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: { 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: { 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: { 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: { 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: { 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 = OCParseArray(curPayload, name, &repMap); break; default: 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"); 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; } 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 CborError OCParseArrayFillArray(const CborValue *parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray) { CborValue insideArray; size_t i = 0; char *tempStr = NULL; OCByteString ocByteStr = { .bytes = NULL, .len = 0}; size_t tempLen = 0; 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 = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((int64_t*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((double*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_BOOL: if (dimensions[1] == 0) { err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((bool*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_STRING: if (dimensions[1] == 0) { err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL); ((char**)targetArray)[i] = tempStr; tempStr = NULL; } else { 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 = OCParseSingleRepPayload(&tempPl, &insideArray, false); ((OCRepPayload**)targetArray)[i] = tempPl; tempPl = NULL; noAdvance = true; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])); } break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); err = CborErrorUnknownType; break; } VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload"); } ++i; if (!noAdvance && cbor_value_is_valid(&insideArray)) { err = cbor_value_advance(&insideArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray"); } } exit: return err; } static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container) { void *arr = NULL; OCRepPayloadPropType type; size_t dimensions[MAX_REP_ARRAY_DEPTH]; size_t dimTotal; size_t allocSize; bool res = true; CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type); VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear"); if (type == OCREP_PROP_NULL) { 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; } dimTotal = calcDimTotal(dimensions); allocSize = getAllocSize(type); arr = OICCalloc(dimTotal, allocSize); VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed"); res = OCParseArrayFillArray(container, dimensions, type, arr); VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array"); switch (type) { case OCREP_PROP_INT: res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions); break; case OCREP_PROP_DOUBLE: res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions); break; case OCREP_PROP_BOOL: res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions); break; case OCREP_PROP_STRING: 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: res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions); break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); break; } err = (CborError) !res; VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter"); return CborNoError; exit: if (type == OCREP_PROP_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((char**)arr)[i]); } } if (type == OCREP_PROP_BYTE_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((OCByteString*)arr)[i].bytes); } } if (type == OCREP_PROP_OBJECT) { for(size_t i = 0; i < dimTotal; ++i) { OCRepPayloadDestroy(((OCRepPayload**)arr)[i]); } } OICFree(arr); return err; }
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 OCStackResult ret = OC_STACK_INVALID_PARAM; int64_t err; uint8_t *out = NULL; size_t curSize = INIT_SIZE; VERIFY_PARAM_NON_NULL(TAG, payload, "Input param, payload is NULL"); VERIFY_PARAM_NON_NULL(TAG, outPayload, "OutPayload parameter is NULL"); VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL"); OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type); if (PAYLOAD_TYPE_SECURITY == payload->type) { size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize; if (securityPayloadSize > 0) { out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize); VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload"); } } if (out == NULL) { out = (uint8_t *)OICCalloc(1, curSize); VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload"); } err = OCConvertPayloadHelper(payload, out, &curSize); ret = OC_STACK_NO_MEMORY; if (err == CborErrorOutOfMemory) { // reallocate "out" and try again! uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize); VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size"); out = out2; err = OCConvertPayloadHelper(payload, out, &curSize); while (err == CborErrorOutOfMemory) { uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize); VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size"); out = out2; err = OCConvertPayloadHelper(payload, out, &curSize); } } if (err == CborNoError) { if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type) { uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize); VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size"); out = out2; } *size = curSize; *outPayload = out; OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size); OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size); return OC_STACK_OK; } //TODO: Proper conversion from CborError to OCStackResult. ret = (OCStackResult)-err; exit: OICFree(out); return ret; }
static CborError OCLinksCborToPayload(CborValue *links, OCLinksPayload **linksPayload) { OCLinksPayload *setLinks = NULL; CborValue linksMap; CborValue linksArray; CborError cborFindResult = CborErrorOutOfMemory; cborFindResult = cbor_value_map_find_value(links, OC_RSRVD_LINKS, &linksArray); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding links array"); cborFindResult = cbor_value_enter_container(&linksArray, &linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container"); while (cbor_value_is_map(&linksMap)) { setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload)); VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value"); // Policy CborValue policyMap; cborFindResult = cbor_value_map_find_value(&linksMap, OC_RSRVD_POLICY, &policyMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "to find policy tag"); // Bitmap cborFindResult = FindIntInMap(&policyMap, OC_RSRVD_BITMAP, (uint64_t *) &setLinks->p); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->anchor); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value"); cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &setLinks->ins); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value"); cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_TTL, &setLinks->ttl); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->type); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value"); if (!*linksPayload) { *linksPayload = setLinks; } else { OCLinksPayload *temp = *linksPayload; while (temp->next) { temp = temp->next; } temp->next = setLinks; } cborFindResult = cbor_value_advance(&linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map"); } return cborFindResult; exit: OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return cborFindResult; }