1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #include "rdpayload.h"
22 #include "oic_malloc.h"
23 #include "oic_string.h"
26 #include "ocpayload.h"
27 #include "payload_logging.h"
29 #define TAG "OIC_RI_RDPAYLOAD"
31 #define CBOR_ROOT_ARRAY_LENGTH 1
33 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap);
34 static int64_t OCLinksPayloadToCbor(OCLinksPayload *links, CborEncoder *setMap);
35 static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, const char *value);
36 static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const uint64_t *value);
37 static int64_t AddStringLLToMap(CborEncoder *map, const char *tag, const OCStringLL *value);
38 static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload);
39 static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload);
40 static CborError FindStringInMap(const CborValue *map, const char *tags, char **value);
41 static CborError FindIntInMap(const CborValue *map, const char *tags, uint64_t *value);
42 static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links);
43 static OCStackResult CreateStringLL(uint8_t numElements, OCResourceHandle handle,
44 const char* (*getValue)(OCResourceHandle handle, uint8_t i),
45 OCStringLL **stringLL);
47 int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
49 int64_t cborEncoderResult = CborNoError;
52 VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Invalid input parameter rdPayload");
53 VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid input parameter outPayload");
54 VERIFY_PARAM_NON_NULL(TAG, size, "Invalid input parameter size");
56 cbor_encoder_init(&encoder, outPayload, *size, flags);
58 if (rdPayload->rdDiscovery)
61 cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
62 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create discovery map");
64 cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME,
65 rdPayload->rdDiscovery->n.deviceName);
66 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in map");
68 cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID,
69 (char *)rdPayload->rdDiscovery->di.id);
70 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in map");
73 uint64_t value = rdPayload->rdDiscovery->sel;
74 cborEncoderResult |= ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL, &value);
75 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add RD_DISCOVERY_SEL in map");
77 cborEncoderResult |= cbor_encoder_close_container(&encoder, &map);
78 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map");
80 else if (rdPayload->rdPublish)
83 cborEncoderResult |= cbor_encoder_create_map(&encoder, &collMap, CborIndefiniteLength);
84 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection map");
86 OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
87 cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &collMap);
88 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload");
89 cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &collMap);
90 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload");
92 cborEncoderResult |= cbor_encoder_close_container(&encoder, &collMap);
93 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection map");
98 cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
99 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed entering discovery map");
100 cborEncoderResult |= cbor_encoder_close_container(&encoder, &map);
101 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map");
104 if (cborEncoderResult == CborErrorOutOfMemory)
106 *size += encoder.ptr - encoder.end;
110 *size = encoder.ptr - outPayload;
113 return cborEncoderResult;
117 return cborEncoderResult;
120 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap)
122 int64_t cborEncoderResult = CborNoError;
124 cborEncoderResult |= ConditionalAddTextStringToMap(setMap, OC_RSRVD_DEVICE_NAME,
126 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in tags map");
128 cborEncoderResult |= ConditionalAddTextStringToMap(setMap, OC_RSRVD_DEVICE_ID,
129 (char *)tags->di.id);
130 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in tags map");
132 cborEncoderResult |= ConditionalAddIntToMap(setMap, OC_RSRVD_DEVICE_TTL, &tags->ttl);
133 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in tags map");
135 return cborEncoderResult;
138 static int64_t OCLinksPayloadToCbor(OCLinksPayload *links, CborEncoder *setMap)
140 CborEncoder linksArray;
141 int64_t cborEncoderResult = CborNoError;
143 cborEncoderResult |= cbor_encode_text_string(setMap, OC_RSRVD_LINKS,
144 sizeof(OC_RSRVD_LINKS) - 1);
146 cborEncoderResult |= cbor_encoder_create_array(setMap, &linksArray, CborIndefiniteLength);
147 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create Links array");
151 CborEncoder linksMap;
152 cborEncoderResult |= cbor_encoder_create_map(&linksArray, &linksMap, CborIndefiniteLength);
153 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create links map");
155 cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_HREF, links->href);
156 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HREF in links map");
158 cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_REL, links->rel);
159 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_REL in links map");
161 cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, links->rt);
162 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RT in links map");
164 cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_INTERFACE, links->itf);
165 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_ITF in links map");
168 CborEncoder policyMap;
169 cborEncoderResult |= cbor_encode_text_string(&linksMap, OC_RSRVD_POLICY,
170 sizeof(OC_RSRVD_POLICY) - 1);
171 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding policy tag to links map");
172 cborEncoderResult |= cbor_encoder_create_map(&linksMap, &policyMap, CborIndefiniteLength);
173 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding policy map to links map");
176 cborEncoderResult |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
177 sizeof(OC_RSRVD_BITMAP) - 1);
178 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding bitmap tag to policy map");
179 cborEncoderResult |= cbor_encode_uint(&policyMap, links->p);
180 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding bitmap value to policy map");
182 cborEncoderResult |= cbor_encoder_close_container(&linksMap, &policyMap);
183 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing policy map");
185 cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_TITLE, links->title);
186 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TITLE in links map");
188 cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_URI, links->anchor);
189 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_URI in links map");
191 cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &links->ins);
192 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in links map");
194 cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_TTL, &links->ttl);
195 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in links map");
197 cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_MEDIA_TYPE, links->type);
198 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_MT in links map");
200 // Finsihed encoding a resource, close the map.
201 cborEncoderResult |= cbor_encoder_close_container(&linksArray, &linksMap);
202 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing links map");
206 cborEncoderResult |= cbor_encoder_close_container(setMap, &linksArray);
207 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing links array");
210 return cborEncoderResult;
213 OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
215 CborValue *rdCBORPayload = (CborValue *)cborPayload;
216 OCStackResult ret = OC_STACK_NO_MEMORY;
217 CborError cborFindResult;
219 OCRDPayload *rdPayload = OCRDPayloadCreate();
220 VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload");
222 ret = OC_STACK_MALFORMED_RESPONSE;
224 if (cbor_value_is_map(rdCBORPayload))
226 // rdCBORPayload is already inside the main root map.
227 OCTagsPayload *tagsPayload = NULL;
228 OCLinksPayload *linksPayload = NULL;
230 cborFindResult = OCTagsCborToPayload(rdCBORPayload, &tagsPayload);
231 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload.");
233 cborFindResult = OCLinksCborToPayload(rdCBORPayload, &linksPayload);
234 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload.");
236 // Move from tags payload to links array.
237 cborFindResult = cbor_value_advance(rdCBORPayload);
238 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload.");
240 rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
241 VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdPublish, "Failed allocating rdPayload->rdPublish");
243 // TODO: This logic needs to be modified to check the payload type exactly..
244 else if (cbor_value_is_map(rdCBORPayload))
246 rdPayload->rdDiscovery = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
247 VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdDiscovery, "Failed allocating discoveryPayload");
249 cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME,
250 &rdPayload->rdDiscovery->n.deviceName);
251 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_NAME.");
252 char *deviceId = NULL;
253 cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &deviceId);
256 memcpy(rdPayload->rdDiscovery->di.id, deviceId, strlen(deviceId));
259 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_ID.");
263 cborFindResult = FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &value);
264 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL.");
265 rdPayload->rdDiscovery->sel = value;
268 cborFindResult = cbor_value_advance(rdCBORPayload);
269 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCBORPayload.");
271 OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
272 *outPayload = (OCPayload *)rdPayload;
276 OCRDPayloadDestroy(rdPayload);
280 static CborError FindStringInMap(const CborValue *map, const char *tags, char **value)
283 CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
284 if (CborNoError == cborFindResult && cbor_value_is_text_string(&curVal))
287 cborFindResult = cbor_value_dup_text_string(&curVal, value, &len, NULL);
289 return cborFindResult;
292 static CborError FindIntInMap(const CborValue *map, const char *tags, uint64_t *value)
295 CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
296 if (CborNoError == cborFindResult && cbor_value_is_unsigned_integer(&curVal))
298 cborFindResult = cbor_value_get_uint64(&curVal, value);
300 return cborFindResult;
303 static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links)
307 OCStringLL* llPtr = *links;
308 CborError cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray);
309 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding tag");
312 cborFindResult = cbor_value_enter_container(&rtArray, &rtVal);
313 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering container");
315 while (cbor_value_is_text_string(&rtVal))
319 llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
320 VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL");
329 llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
331 VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL->next");
333 cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
334 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed duplicating value");
335 cborFindResult = cbor_value_advance(&rtVal);
336 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing OCStringLL");
339 cborFindResult = cbor_value_leave_container(&rtArray, &rtVal);
340 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed leaving container");
343 return cborFindResult;
346 static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload)
348 CborError cborFindResult = CborErrorOutOfMemory;
349 OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
350 VERIFY_PARAM_NON_NULL(TAG, tags, "Failed allocating tags");
352 cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName);
353 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName");
356 char *deviceId = NULL;
357 cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &deviceId);
360 memcpy(tags->di.id, deviceId, strlen(deviceId));
363 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceId");
366 cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_DEVICE_TTL, &tags->ttl);
367 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
370 return cborFindResult;
373 OCFreeTagsResource(tags);
374 return cborFindResult;
377 static CborError OCLinksCborToPayload(CborValue *links, OCLinksPayload **linksPayload)
379 OCLinksPayload *setLinks = NULL;
381 CborValue linksArray;
382 CborError cborFindResult = CborErrorOutOfMemory;
384 cborFindResult = cbor_value_map_find_value(links, OC_RSRVD_LINKS, &linksArray);
385 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding links array");
387 cborFindResult = cbor_value_enter_container(&linksArray, &linksMap);
388 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container");
390 while (cbor_value_is_map(&linksMap))
392 setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
393 VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks");
395 cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href);
396 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value");
398 cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel);
399 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value");
401 cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt);
402 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value");
404 cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf);
405 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value");
409 cborFindResult = cbor_value_map_find_value(&linksMap, OC_RSRVD_POLICY, &policyMap);
410 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "to find policy tag");
413 cborFindResult = FindIntInMap(&policyMap, OC_RSRVD_BITMAP, (uint64_t *) &setLinks->p);
414 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap value");
416 cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title);
417 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value");
419 cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->anchor);
420 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value");
422 cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &setLinks->ins);
423 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value");
425 cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_TTL, &setLinks->ttl);
426 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
428 cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->type);
429 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value");
433 *linksPayload = setLinks;
437 OCLinksPayload *temp = *linksPayload;
442 temp->next = setLinks;
444 cborFindResult = cbor_value_advance(&linksMap);
445 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map");
448 return cborFindResult;
451 OCFreeLinksResource(*linksPayload);
452 OCFreeLinksResource(setLinks);
453 return cborFindResult;
456 static int64_t AddTextStringToMap(CborEncoder* map, const char* key, const char* value)
458 int64_t err = cbor_encode_text_string(map, key, strlen(key));
459 VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting key value");
460 err |= cbor_encode_text_string(map, value, strlen(value));
465 static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, const char* value)
467 return value ? AddTextStringToMap(map, key, value) : CborNoError;
470 static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const uint64_t *value)
472 int64_t err = CborNoError;
475 err |= cbor_encode_text_string(map, tags, strlen(tags));
476 VERIFY_CBOR_SUCCESS(TAG, err, "failed setting value");
477 err |= cbor_encode_uint(map, *value);
483 static int64_t AddStringLLToMap(CborEncoder *map, const char *tag, const OCStringLL *strType)
486 int64_t cborEncoderResult = CborNoError;
488 cborEncoderResult |= cbor_encode_text_string(map, tag, strlen(tag));
489 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed encoding string tag name");
490 cborEncoderResult |= cbor_encoder_create_array(map, &array, CborIndefiniteLength);
491 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed creating stringLL array");
494 cborEncoderResult |= cbor_encode_text_string(&array, strType->value, strlen(strType->value));
495 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed encoding string value");
496 strType = strType->next;
498 cborEncoderResult |= cbor_encoder_close_container(map, &array);
499 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing string array");
501 return cborEncoderResult;
504 OCRDPayload *OCRDPayloadCreate()
506 OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
507 VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload");
508 rdPayload->base.type = PAYLOAD_TYPE_RD;
515 OCRDPayload *OCRDPublishPayloadCreate(OCResourceHandle resourceHandles[], uint8_t nHandles,
518 OCTagsPayload *tagsPayload = NULL;
519 OCLinksPayload *linksPayload = NULL;
520 OCStringLL *rt = NULL;
521 OCStringLL *itf = NULL;
522 OCStringLL *mt = NULL;
523 OCResourceProperty p = OC_RES_PROP_NONE;
526 OCRDPayload *rdPayload = OCRDPayloadCreate();
532 const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
533 tagsPayload = OCCopyTagsResources(NULL, id, ttl);
539 for (uint8_t j = 0; j < nHandles; j++)
541 OCResourceHandle handle = resourceHandles[j];
548 const char *uri = OCGetResourceUri(handle);
549 uint8_t numElement = 0;
550 if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
552 OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceTypeName, &rt);
553 if (OC_STACK_OK != res || !rt)
559 if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
561 OCStackResult res = CreateStringLL(numElement, handle, OCGetResourceInterfaceName,
563 if (OC_STACK_OK != res || !itf)
569 p = OCGetResourceProperties(handle);
570 p = (OCResourceProperty) ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE));
572 OCStackResult res = OCGetResourceIns(handle, &ins);
573 if (OC_STACK_OK != res)
578 mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
583 mt->value = OICStrdup(DEFAULT_MESSAGE_TYPE);
591 linksPayload = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL,
592 NULL, ins, ttl, mt);;
600 OCLinksPayload *temp = linksPayload;
605 temp->next = OCCopyLinksResources(uri, NULL, rt, itf, p, NULL,
612 OCFreeOCStringLL(rt);
613 OCFreeOCStringLL(itf);
614 OCFreeOCStringLL(mt);
618 rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
619 if (!rdPayload->rdPublish)
629 OCFreeOCStringLL(rt);
633 OCFreeOCStringLL(itf);
637 OCFreeOCStringLL(mt);
641 OCFreeTagsResource(tagsPayload);
645 OCFreeLinksResource(linksPayload);
647 OCRDPayloadDestroy(rdPayload);
651 OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *deviceName, const char *id, int biasFactor)
653 OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
654 VERIFY_PARAM_NON_NULL(TAG, discoveryPayload, "Failed allocating memory for discovery payload");
658 discoveryPayload->n.deviceName = OICStrdup(deviceName);
659 VERIFY_PARAM_NON_NULL(TAG, discoveryPayload->n.deviceName,
660 "Failed allocating memory for discovery device name");
664 OICStrcpy((char*)discoveryPayload->di.id, MAX_IDENTITY_SIZE, id);
667 discoveryPayload->sel = biasFactor;
668 return discoveryPayload;
670 OICFree(discoveryPayload);
671 discoveryPayload = NULL;
672 return discoveryPayload;
675 void OCRDPayloadDestroy(OCRDPayload *payload)
682 if (payload->rdDiscovery)
684 if (payload->rdDiscovery->n.deviceName)
686 OICFree(payload->rdDiscovery->n.deviceName);
688 OICFree(payload->rdDiscovery);
691 if (payload->rdPublish)
693 OCResourceCollectionPayload *col = payload->rdPublish;
697 OCFreeLinksResource(col->setLinks);
702 OCFreeTagsResource(col->tags);
710 OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *id, uint64_t ttl)
712 OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
719 tags->n.deviceName = OICStrdup(deviceName);
720 if (!tags->n.deviceName)
722 goto memory_allocation_failed;
727 OICStrcpy((char*)tags->di.id, MAX_IDENTITY_SIZE, (char *)id);
732 memory_allocation_failed:
733 OIC_LOG(ERROR, TAG, "Memory allocation failed.");
734 OCFreeTagsResource(tags);
738 OCLinksPayload* OCCopyLinksResources(const char *href, const char *rel, OCStringLL *rt,
739 OCStringLL *itf, uint8_t p, const char *title,
740 const char *anchor, uint8_t ins, uint64_t ttl,
743 OCLinksPayload *links = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
746 OIC_LOG(ERROR, TAG, "Failed allocating memory.");
751 links->href = OICStrdup(href);
754 goto memory_allocation_failed;
759 links->rel = OICStrdup(rel);
762 goto memory_allocation_failed;
767 links->rt = CloneOCStringLL(rt);
770 goto memory_allocation_failed;
775 links->itf = CloneOCStringLL(itf);
778 goto memory_allocation_failed;
784 links->title = OICStrdup(title);
787 goto memory_allocation_failed;
792 links->anchor = OICStrdup(anchor);
795 goto memory_allocation_failed;
802 links->type = CloneOCStringLL(mt);
805 goto memory_allocation_failed;
811 memory_allocation_failed:
812 OIC_LOG(ERROR, TAG, "Memory allocation failed.");
813 OCFreeLinksResource(links);
817 OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links)
819 OCResourceCollectionPayload *pl = NULL;
820 VERIFY_PARAM_NON_NULL(TAG, tags, "Invalid param tags");
821 VERIFY_PARAM_NON_NULL(TAG, links, "Invalid param links");
823 pl = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
824 VERIFY_PARAM_NON_NULL(TAG, pl, "Failed allocating memory for the OCResourceCollectionPayload");
827 pl->setLinks = links;
833 void OCFreeLinksResource(OCLinksPayload *links)
839 OICFree(links->href);
841 OCFreeOCStringLL(links->rt);
842 OCFreeOCStringLL(links->itf);
843 OICFree(links->title);
844 OICFree(links->anchor);
845 OCFreeOCStringLL(links->type);
846 OCFreeLinksResource(links->next);
850 void OCFreeTagsResource(OCTagsPayload *payload)
856 OICFree(payload->n.deviceName);;
860 void OCFreeCollectionResource(OCResourceCollectionPayload *payload)
868 OCFreeTagsResource(payload->tags);
870 if (payload->setLinks)
872 OCFreeLinksResource(payload->setLinks);
877 static OCStackResult CreateStringLL(uint8_t numElements, OCResourceHandle handle,
878 const char* (*getValue)(OCResourceHandle handle, uint8_t i),
879 OCStringLL **stringLL)
881 for (uint8_t i = 0; i < numElements; ++i)
883 const char *value = getValue(handle, i);
884 OIC_LOG_V(ERROR, TAG, "value: %s", value);
887 *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
890 OIC_LOG(ERROR, TAG, "Failed allocating memory.");
891 return OC_STACK_NO_MEMORY;
893 (*stringLL)->value = OICStrdup(value);
894 if (!(*stringLL)->value)
896 OIC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
897 return OC_STACK_NO_MEMORY;
902 OCStringLL *cur = *stringLL;
907 cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
910 OIC_LOG(ERROR, TAG, "Failed allocating memory.");
911 return OC_STACK_NO_MEMORY;
913 cur->next->value = OICStrdup(value);
914 if (!cur->next->value)
916 OIC_LOG(ERROR, TAG, "Failed copying to OCStringLL.");
917 return OC_STACK_NO_MEMORY;