/** * This internal method handles RD publish request. * Responds with the RD success message. */ static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest *ehRequest) { OCEntityHandlerResult ehResult = OC_EH_OK; if (!ehRequest) { OIC_LOG(DEBUG, TAG, "Invalid request pointer"); return OC_EH_ERROR; } OIC_LOG_V(DEBUG, TAG, "Received OC_REST_PUT from client with query: %s.", ehRequest->query); OCRDPayload *payload = (OCRDPayload *)ehRequest->payload; if (payload && payload->rdPublish) { OCRDStorePublishedResources(payload->rdPublish, &ehRequest->devAddr); } OCRDPayload *rdPayload = OCRDPayloadCreate(); if (!rdPayload) { OIC_LOG(ERROR, TAG, "Failed allocating memory."); return OC_STACK_NO_MEMORY; } OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); if (sendResponse(ehRequest, rdPayload) != OC_STACK_OK) { OIC_LOG(ERROR, TAG, "Sending response failed."); ehResult = OC_EH_ERROR; } return ehResult; }
/** * This internal method handles RD discovery request. * Responds with the RD discovery payload message. */ static OCEntityHandlerResult handleGetRequest(const OCEntityHandlerRequest *ehRequest) { if (!ehRequest) { OIC_LOG(DEBUG, TAG, "Invalid request pointer."); return OC_EH_ERROR; } OCEntityHandlerResult ehResult = OC_EH_OK; OIC_LOG_V(DEBUG, TAG, "Received OC_REST_GET from client with query: %s.", ehRequest->query); OCRDPayload *rdPayload = OCRDPayloadCreate(); if (!rdPayload) { return OC_STACK_NO_MEMORY; } rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(NULL, OCGetServerInstanceIDString(), OC_RD_DISC_SEL); if (!rdPayload->rdDiscovery) { OCRDPayloadDestroy(rdPayload); return OC_STACK_NO_MEMORY; } OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); if (sendResponse(ehRequest, rdPayload) != OC_STACK_OK) { OIC_LOG(ERROR, TAG, "Sending response failed."); ehResult = OC_EH_ERROR; } return ehResult; }
OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload) { CborValue *rdCBORPayload = (CborValue *)cborPayload; CborError cborFindResult; OCRDPayload *rdPayload = OCRDPayloadCreate(); if (!rdPayload) { goto no_memory; } 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); if (cborFindResult != CborNoError) { goto cbor_error; } if (OC_STACK_OK != OCTagsCborToPayload(&tags, &tagsPayload)) { OCFreeTagsResource(tagsPayload); goto cbor_error; } OCTagsLog(DEBUG, tagsPayload); if (OC_STACK_OK != OCLinksCborToPayload(&tags, &linksPayload)) { OCFreeLinksResource(linksPayload); OCFreeTagsResource(tagsPayload); goto cbor_error; } OCLinksLog(DEBUG, linksPayload); // Move from tags payload to links array. if (CborNoError != cbor_value_advance(rdCBORPayload)) { OC_LOG(DEBUG, TAG, "Failed advancing from tags payload to links."); OCFreeLinksResource(linksPayload); OCFreeTagsResource(tagsPayload); goto cbor_error; } } rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); if (!rdPayload->rdPublish) { goto cbor_error; } } else if (cbor_value_is_map(rdCBORPayload)) { char *name = NULL; if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME, &name)) { goto cbor_error; } char *id = NULL; if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &id)) { goto cbor_error; } uint64_t biasFactor = 0; if (CborNoError != FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &biasFactor)) { goto cbor_error; } rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(name, id, (uint8_t)biasFactor); if (!rdPayload->rdDiscovery) { goto no_memory; } OICFree(id); OICFree(name); cborFindResult = cbor_value_advance(rdCBORPayload); if (CborNoError != cborFindResult) { goto cbor_error; } } OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); *outPayload = (OCPayload *)rdPayload; return OC_STACK_OK; no_memory: OC_LOG(ERROR, TAG, "Failed allocating memory."); OCRDPayloadDestroy(rdPayload); return OC_STACK_NO_MEMORY; cbor_error: OCRDPayloadDestroy(rdPayload); return OC_STACK_ERROR; }
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; }
OCRDPayload *OCRDPublishPayloadCreate(OCResourceHandle resourceHandles[], uint8_t nHandles, uint64_t ttl) { OCTagsPayload *tagsPayload = NULL; OCLinksPayload *linksPayload = NULL; OCStringLL *rt = NULL; OCStringLL *itf = NULL; OCStringLL *mt = NULL; OCResourceProperty p = OC_RES_PROP_NONE; uint8_t ins = 0; OCRDPayload *rdPayload = OCRDPayloadCreate(); if (!rdPayload) { return NULL; } const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString(); tagsPayload = OCCopyTagsResources(NULL, id, ttl); if (!tagsPayload) { goto exit; } for (uint8_t j = 0; j < nHandles; j++) { OCResourceHandle handle = resourceHandles[j]; if (handle) { rt = NULL; itf = NULL; mt = NULL; ins = 0; const char *uri = OCGetResourceUri(handle); uint8_t numElement = 0; if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement)) { OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceTypeName, &rt); if (OC_STACK_OK != res || !rt) { goto exit; } } if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement)) { OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceInterfaceName, &itf); if (OC_STACK_OK != res || !itf) { goto exit; } } p = OCGetResourceProperties(handle); p = (OCResourceProperty) ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE)); OCStackResult res = OCGetResourceIns(handle, &ins); if (OC_STACK_OK != res) { goto exit; } mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); if (!mt) { goto exit; } mt->value = OICStrdup(DEFAULT_MESSAGE_TYPE); if (!mt->value) { goto exit; } if (!linksPayload) { linksPayload = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL, NULL, ins, ttl, mt);; if (!linksPayload) { goto exit; } } else { OCLinksPayload *temp = linksPayload; while (temp->next) { temp = temp->next; } temp->next = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL, NULL, ins, ttl, mt); if (!temp->next) { goto exit; } } OCFreeOCStringLL(rt); OCFreeOCStringLL(itf); OCFreeOCStringLL(mt); } } rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); if (!rdPayload->rdPublish) { goto exit; } return rdPayload; exit: if (rt) { OCFreeOCStringLL(rt); } if (itf) { OCFreeOCStringLL(itf); } if (mt) { OCFreeOCStringLL(mt); } if (tagsPayload) { OCFreeTagsResource(tagsPayload); } if (linksPayload) { OCFreeLinksResource(linksPayload); } OCRDPayloadDestroy(rdPayload); return NULL; }