void OCPayloadDestroy(OCPayload* payload) { if(!payload) { return; } switch(payload->type) { case PAYLOAD_TYPE_REPRESENTATION: OCRepPayloadDestroy((OCRepPayload*)payload); break; case PAYLOAD_TYPE_DISCOVERY: OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload); break; case PAYLOAD_TYPE_DEVICE: OCDevicePayloadDestroy((OCDevicePayload*)payload); break; case PAYLOAD_TYPE_PLATFORM: OCPlatformPayloadDestroy((OCPlatformPayload*)payload); break; case PAYLOAD_TYPE_PRESENCE: OCPresencePayloadDestroy((OCPresencePayload*)payload); break; case PAYLOAD_TYPE_SECURITY: OCSecurityPayloadDestroy((OCSecurityPayload*)payload); break; default: OC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type); OICFree(payload); break; } }
static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* rootValue) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; OCResourcePayload* resource = NULL; uint16_t resourceCount = 0; CborValue resourceMap = {}; OCDiscoveryPayload* out = OCDiscoveryPayloadCreate(); if(!out) { return OC_STACK_NO_MEMORY; } // Root value is already inside the main root array CborValue rootMap = {}; // Enter the main root map err = err || cbor_value_enter_container(rootValue, &rootMap); // Look for DI CborValue curVal = {}; err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor find value failed."); goto malformed_cbor; } size_t len; err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL); // Look for Links which will have an array as the value err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor find value failed."); goto malformed_cbor; } // Enter the links array and start iterating through the array processing // each resource which shows up as a map. err = err || cbor_value_enter_container(&curVal, &resourceMap); while (cbor_value_is_map(&resourceMap)) { resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload)); if(!resource) { OC_LOG(ERROR, TAG, "Memory allocation failed"); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } // Uri CborValue uriVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding href type failed."); goto malformed_cbor; } err = cbor_value_dup_text_string(&uriVal, &(resource->uri), &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding href value failed."); goto malformed_cbor; } // ResourceTypes CborValue rtVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding rt type failed."); goto malformed_cbor; } if (cbor_value_is_text_string(&rtVal)) { char* input = NULL; char* savePtr; err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding rt value failed."); goto malformed_cbor; } if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddResourceType(resource, trimmed)) { OICFree(resource->uri); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Interface Types CborValue ifVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding if type failed."); goto malformed_cbor; } if (!err && cbor_value_is_text_string(&ifVal)) { char* input = NULL; char* savePtr; err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding if value failed."); goto malformed_cbor; } if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddInterface(resource, trimmed)) { OICFree(resource->uri); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Policy CborValue policyMap = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding policy type failed."); goto malformed_cbor; } // Bitmap CborValue val = {}; err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding bitmap type failed."); goto malformed_cbor; } uint64_t temp = 0; err = cbor_value_get_uint64(&val, &temp); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding bitmap value failed."); goto malformed_cbor; } resource->bitmap = (uint8_t)temp; // Secure Flag err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding secure type failed."); goto malformed_cbor; } if(cbor_value_is_valid(&val)) { err = cbor_value_get_boolean(&val, &(resource->secure)); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding secure value failed."); goto malformed_cbor; } // Port CborValue port; err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &port); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding port type failed."); goto malformed_cbor; } if(cbor_value_is_valid(&port)) { err = cbor_value_get_uint64(&port, &temp); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding port value failed."); goto malformed_cbor; } resource->port = (uint16_t)temp; } } err = cbor_value_advance(&resourceMap); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor advance value failed."); goto malformed_cbor; } ++resourceCount; OCDiscoveryPayloadAddNewResource(out, resource); } err = err || cbor_value_leave_container(rootValue, &resourceMap); *outPayload = (OCPayload*)out; return OC_STACK_OK; malformed_cbor: OICFree(resource->uri); OCFreeOCStringLL(resource->types); OCFreeOCStringLL(resource->interfaces); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; cbor_error: OCDiscoveryCollectionPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; }
static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; OCDiscoveryPayload* out = OCDiscoveryPayloadCreate(); if(!out) { return OC_STACK_NO_MEMORY; } size_t resourceCount = 0; while(!err && cbor_value_is_map(arrayVal)) { 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); // 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); // Prop Tag { err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal); // ResourceTypes CborValue rtVal; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtVal); if (!err && cbor_value_is_text_string(&rtVal)) { char* input = NULL; char* savePtr; err = err || cbor_value_dup_text_string(&rtVal, &input, &len, NULL); if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddResourceType(resource, trimmed)) { OICFree(resource->uri); OICFree(resource->sid); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Interface Types CborValue ifVal; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifVal); if (!err && cbor_value_is_text_string(&ifVal)) { char* input = NULL; char* savePtr; err = err || cbor_value_dup_text_string(&ifVal, &input, &len, NULL); if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddInterface(resource, trimmed)) { OICFree(resource->uri); OICFree(resource->sid); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Policy { 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)) { 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)) { err = err || cbor_value_get_uint64(&port, &temp); resource->port = (uint16_t)temp; } } } } err = err || cbor_value_advance(arrayVal); if(err) { 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; } ++resourceCount; OCDiscoveryPayloadAddNewResource(out, resource); } if(err) { OCDiscoveryPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; } else { *outPayload = (OCPayload*)out; return OC_STACK_OK; } }
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; }