Imported Upstream version 1.1.1
[platform/upstream/iotivity.git] / resource / csdk / stack / src / rdpayload.c
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #include "rdpayload.h"
21
22 #include "oic_malloc.h"
23 #include "oic_string.h"
24 #include "octypes.h"
25 #include "ocstack.h"
26 #include "ocpayload.h"
27 #include "payload_logging.h"
28
29 #define TAG "OIC_RI_RDPAYLOAD"
30
31 #define CBOR_ROOT_ARRAY_LENGTH 1
32
33 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap);
34 static int64_t OCLinksPayloadToCbor(OCLinksPayload *rtPtr, 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
44 int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
45 {
46     int64_t cborEncoderResult = CborErrorIO;
47     int flags = 0;
48     CborEncoder encoder;
49     VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Invalid input parameter rdPayload");
50     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid input parameter outPayload");
51     VERIFY_PARAM_NON_NULL(TAG, size, "Invalid input parameter size");
52
53     cbor_encoder_init(&encoder, outPayload, *size, flags);
54
55     if (rdPayload->rdDiscovery)
56     {
57         CborEncoder map;
58         cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
59         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create discovery map");
60
61         cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME,
62             rdPayload->rdDiscovery->n.deviceName);
63         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in map");
64
65         cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID,
66             (char *)rdPayload->rdDiscovery->di.id);
67         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in map");
68
69         {
70             uint64_t value = rdPayload->rdDiscovery->sel;
71             cborEncoderResult |= ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL, &value);
72             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add RD_DISCOVERY_SEL in map");
73         }
74         cborEncoderResult |= cbor_encoder_close_container(&encoder, &map);
75         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map");
76     }
77     else if (rdPayload->rdPublish)
78     {
79         CborEncoder colArray;
80         cborEncoderResult |= cbor_encoder_create_array(&encoder, &colArray, CborIndefiniteLength);
81         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection array");
82
83         OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
84         while (rdPublish)
85         {
86             cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &colArray);
87             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload");
88             cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &colArray);
89             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload");
90             rdPublish = rdPublish->next;
91         }
92         cborEncoderResult |= cbor_encoder_close_container(&encoder, &colArray);
93         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection array");
94     }
95     else
96     {
97         CborEncoder 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");
102     }
103
104     if (cborEncoderResult == CborErrorOutOfMemory)
105     {
106         *size += encoder.ptr - encoder.end;
107     }
108     else
109     {
110         *size = encoder.ptr - outPayload;
111     }
112
113     return cborEncoderResult;
114
115 exit:
116     OICFree(outPayload);
117     return cborEncoderResult;
118 }
119
120 static int64_t OCTagsPayloadToCbor(OCTagsPayload *tags, CborEncoder *setMap)
121 {
122     CborEncoder tagsMap;
123     int64_t cborEncoderResult = CborNoError;
124     cborEncoderResult |= cbor_encoder_create_map(setMap, &tagsMap, CborIndefiniteLength);
125     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create tags map");
126
127     cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_NAME, tags->n.deviceName);
128     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in tags map");
129
130     cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DEVICE_ID,
131             (char *)tags->di.id);
132     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in tags map");
133
134     cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_RTS, tags->rts);
135     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RTS in tags map");
136
137     cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_DREL, tags->drel);
138     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DREL in tags map");
139
140     cborEncoderResult |= ConditionalAddTextStringToMap(&tagsMap, OC_RSRVD_BASE_URI, tags->baseURI);
141     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_BASE_URI in tags map");
142
143     {
144         uint64_t value = tags->bitmap;
145         cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_BITMAP, &value);
146         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_BITMAP in tags map");
147
148         value = tags->port;
149         cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_HOSTING_PORT, &value);
150         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HOSTING_PORT in tags map");
151
152         value = tags->ins;
153         cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_INS, &value);
154         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in tags map");
155
156         value = tags->ttl;
157         cborEncoderResult |= ConditionalAddIntToMap(&tagsMap, OC_RSRVD_TTL, &value);
158         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TTL in tags map");
159     }
160
161     cborEncoderResult |= cbor_encoder_close_container(setMap, &tagsMap);
162     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close container");
163
164 exit:
165     return cborEncoderResult;
166 }
167
168 static int64_t OCLinksPayloadToCbor(OCLinksPayload *rtPtr, CborEncoder *setMap)
169 {
170     CborEncoder linksArray;
171     int64_t cborEncoderResult = CborNoError;
172
173     cborEncoderResult |= cbor_encoder_create_array(setMap, &linksArray, CborIndefiniteLength);
174     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create Links array");
175
176     while (rtPtr)
177     {
178         CborEncoder linksMap;
179         cborEncoderResult |= cbor_encoder_create_map(&linksArray, &linksMap, CborIndefiniteLength);
180         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create Links map");
181
182         cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_HREF, rtPtr->href);
183         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_HREF in Links map");
184
185         cborEncoderResult|= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_REL, rtPtr->rel);
186         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_REL in Links map");
187
188         cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_TITLE, rtPtr->title);
189         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_TITLE in Links map");
190
191         cborEncoderResult |= ConditionalAddTextStringToMap(&linksMap, OC_RSRVD_URI, rtPtr->uri);
192         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_URI in Links map");
193
194         cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, rtPtr->rt);
195         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_RT in Links map");
196
197         cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_INTERFACE, rtPtr->itf);
198         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_ITF in Links map");
199
200         cborEncoderResult |= AddStringLLToMap(&linksMap, OC_RSRVD_MEDIA_TYPE, rtPtr->mt);
201         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_MT in Links map");
202
203         {
204             uint64_t value = rtPtr->ins;
205             cborEncoderResult |= ConditionalAddIntToMap(&linksMap, OC_RSRVD_INS, &value);
206             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_INS in Links map");
207         }
208
209         cborEncoderResult |= cbor_encoder_close_container(&linksArray, &linksMap);
210         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing Links map");
211
212         rtPtr = rtPtr->next;
213     }
214     cborEncoderResult |= cbor_encoder_close_container(setMap, &linksArray);
215     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing links array");
216
217 exit:
218     return cborEncoderResult;
219 }
220
221 OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
222 {
223     CborValue *rdCBORPayload = (CborValue *)cborPayload;
224     OCStackResult ret = OC_STACK_NO_MEMORY;
225     CborError cborFindResult;
226
227     OCRDPayload *rdPayload = OCRDPayloadCreate();
228     VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload");
229
230     ret = OC_STACK_MALFORMED_RESPONSE;
231
232     if (cbor_value_is_array(rdCBORPayload))
233     {
234         OCLinksPayload *linksPayload = NULL;
235         OCTagsPayload *tagsPayload = NULL;
236
237         while (cbor_value_is_container(rdCBORPayload))
238         {
239             // enter tags map
240             CborValue tags;
241             cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags);
242             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering tags container.");
243
244             cborFindResult= OCTagsCborToPayload(&tags, &tagsPayload);
245             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload.");
246             OCTagsLog(DEBUG, tagsPayload);
247
248             cborFindResult = OCLinksCborToPayload(&tags, &linksPayload);
249             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload.");
250             OCLinksLog(DEBUG, linksPayload);
251
252             // Move from tags payload to links array.
253             cborFindResult = cbor_value_advance(rdCBORPayload);
254             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload.");
255         }
256         rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
257         VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdPublish, "Failed allocating rdPayload->rdPublish");
258     }
259     else if (cbor_value_is_map(rdCBORPayload))
260     {
261         rdPayload->rdDiscovery = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
262         VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdDiscovery, "Failed allocating discoveryPayload");
263
264         cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME,
265                 &rdPayload->rdDiscovery->n.deviceName);
266         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_NAME.");
267         char *deviceId = NULL;
268         cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &deviceId);
269         if (deviceId)
270         {
271             memcpy(rdPayload->rdDiscovery->di.id, deviceId, strlen(deviceId));
272             OICFree(deviceId);
273         }
274         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_ID.");
275
276         {
277             uint64_t value = 0;
278             cborFindResult = FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &value);
279             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL.");
280             rdPayload->rdDiscovery->sel = value;
281         }
282
283         cborFindResult =  cbor_value_advance(rdCBORPayload);
284         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCBORPayload.");
285     }
286     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
287     *outPayload = (OCPayload *)rdPayload;
288     return OC_STACK_OK;
289
290 exit:
291     OCRDPayloadDestroy(rdPayload);
292     return ret;
293 }
294
295 static CborError FindStringInMap(const CborValue *map, const char *tags, char **value)
296 {
297     CborValue curVal;
298     CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
299     if (CborNoError == cborFindResult && cbor_value_is_text_string(&curVal))
300     {
301         size_t len = 0;
302         cborFindResult = cbor_value_dup_text_string(&curVal, value, &len, NULL);
303     }
304     return cborFindResult;
305 }
306
307 static CborError FindIntInMap(const CborValue *map, const char *tags, uint64_t *value)
308 {
309     CborValue curVal;
310     CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
311     if (CborNoError == cborFindResult && cbor_value_is_unsigned_integer(&curVal))
312     {
313         cborFindResult = cbor_value_get_uint64(&curVal, value);
314     }
315     return cborFindResult;
316 }
317
318 static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links)
319 {
320     size_t len;
321     CborValue rtArray;
322     OCStringLL* llPtr = *links;
323     CborError cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray);
324     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding tag");
325
326     CborValue rtVal;
327     cborFindResult = cbor_value_enter_container(&rtArray, &rtVal);
328     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering container");
329
330     while (cbor_value_is_text_string(&rtVal))
331     {
332         if (llPtr == NULL)
333         {
334             llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
335             VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL");
336             *links = llPtr;
337         }
338         else if(llPtr)
339         {
340             while (llPtr->next)
341             {
342                 llPtr = llPtr->next;
343             }
344             llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
345             VERIFY_PARAM_NON_NULL(TAG, llPtr->next, "Failed allocating OCStringLL->next");
346         }
347         cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL);
348         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed duplicating value");
349         cborFindResult = cbor_value_advance(&rtVal);
350         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing OCStringLL");
351     }
352
353     cborFindResult = cbor_value_leave_container(&rtArray, &rtVal);
354     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed leaving container");
355
356 exit:
357     return cborFindResult;
358 }
359
360 static CborError OCTagsCborToPayload(CborValue *tagsMap, OCTagsPayload **tagsPayload)
361 {
362     CborError cborFindResult = CborErrorOutOfMemory;
363     OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
364     VERIFY_PARAM_NON_NULL(TAG, tags, "Failed allocating tags");
365
366     if (cbor_value_is_map(tagsMap))
367     {
368         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_NAME, &tags->n.deviceName);
369         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceName");
370         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DREL, &tags->drel);
371         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding drel");
372         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_RTS, &tags->rts);
373         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rts");
374         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_BASE_URI, &tags->baseURI);
375         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding baseURI");
376         char *deviceId = NULL;
377         cborFindResult = FindStringInMap(tagsMap, OC_RSRVD_DEVICE_ID, &deviceId);
378         if (deviceId)
379         {
380             memcpy(tags->di.id, deviceId, strlen(deviceId));
381             OICFree(deviceId);
382         }
383         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding deviceId");
384         {
385             uint64_t value = 0;
386             cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_HOSTING_PORT, &value);
387             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding port");
388             tags->port = value;
389             value = 0;
390             cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_BITMAP, &value);
391             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap");
392             tags->bitmap = value;
393             value = 0;
394             cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_INS, &value);
395             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins");
396             tags->ins = value;
397             value = 0;
398             cborFindResult = FindIntInMap(tagsMap, OC_RSRVD_TTL, &value);
399             tags->ttl = value;
400         }
401         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl");
402         cborFindResult = cbor_value_advance(tagsMap);
403         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing bitmap");
404     }
405     *tagsPayload = tags;
406     return cborFindResult;
407
408 exit:
409     OCFreeTagsResource(tags);
410     return cborFindResult;
411 }
412
413 static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload)
414 {
415     CborValue linksMap;
416     OCLinksPayload *setLinks = NULL;
417     CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap);
418     VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container");
419
420     while (cbor_value_is_map(&linksMap))
421     {
422         setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
423         VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks");
424
425         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href);
426         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value");
427
428         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel);
429         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value");
430
431         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title);
432         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value");
433
434         cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri);
435         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value");
436
437         cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt);
438         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value");
439
440         cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf);
441         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value");
442
443         cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt);
444         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value");
445
446         {
447             uint64_t value = 0;
448             cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &value);
449             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value");
450             setLinks->ins = value;
451         }
452
453         if (!*linksPayload)
454         {
455             *linksPayload = setLinks;
456         }
457         else
458         {
459             OCLinksPayload *temp = *linksPayload;
460             while (temp->next)
461             {
462                 temp = temp->next;
463             }
464             temp->next = setLinks;
465         }
466         cborFindResult = cbor_value_advance(&linksMap);
467         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map");
468     }
469
470     return cborFindResult;
471
472 exit:
473     OCFreeLinksResource(*linksPayload);
474     OCFreeLinksResource(setLinks);
475     return cborFindResult;
476 }
477
478 static int64_t AddTextStringToMap(CborEncoder* map, const char* key, const char* value)
479 {
480     int64_t err = cbor_encode_text_string(map, key, strlen(key));
481     VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting key value");
482     err |= cbor_encode_text_string(map, value, strlen(value));
483 exit:
484     return err;
485 }
486
487 static int64_t ConditionalAddTextStringToMap(CborEncoder* map, const char* key, const char* value)
488 {
489     return value ? AddTextStringToMap(map, key, value) : CborNoError;
490 }
491
492 static int64_t ConditionalAddIntToMap(CborEncoder *map, const char *tags, const uint64_t *value)
493 {
494     int64_t err = CborNoError;
495     if (*value)
496     {
497         err |= cbor_encode_text_string(map, tags, strlen(tags));
498         VERIFY_CBOR_SUCCESS(TAG, err, "failed setting value");
499         err |= cbor_encode_uint(map, *value);
500     }
501 exit:
502     return err;
503 }
504
505 static int64_t AddStringLLToMap(CborEncoder *map, const char *tag, const OCStringLL *strType)
506 {
507     CborEncoder array;
508     int64_t cborEncoderResult = CborNoError;
509     cborEncoderResult |= cbor_encode_text_string(map, tag, strlen(tag));
510     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed encoding string tag name");
511     cborEncoderResult |= cbor_encoder_create_array(map, &array, CborIndefiniteLength);
512     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed creating stringLL array");
513     while (strType)
514     {
515         cborEncoderResult |= cbor_encode_text_string(&array, strType->value, strlen(strType->value));
516         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed encoding string value");
517         strType = strType->next;
518     }
519     cborEncoderResult |= cbor_encoder_close_container(map, &array);
520     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing string array");
521 exit:
522     return cborEncoderResult;
523 }
524
525 OCRDPayload *OCRDPayloadCreate()
526 {
527     OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
528     VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload");
529     rdPayload->base.type = PAYLOAD_TYPE_RD;
530
531 exit:
532     return rdPayload;
533 }
534
535 OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(const char *deviceName, const char *id, int biasFactor)
536 {
537     OCRDDiscoveryPayload *discoveryPayload = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload));
538     VERIFY_PARAM_NON_NULL(TAG, discoveryPayload, "Failed allocating memory for discovery payload");
539
540     if (deviceName)
541     {
542         discoveryPayload->n.deviceName = OICStrdup(deviceName);
543         VERIFY_PARAM_NON_NULL(TAG, discoveryPayload->n.deviceName,
544                 "Failed allocating memory for discovery device name");
545     }
546     if (id)
547     {
548         OICStrcpy((char*)discoveryPayload->di.id, MAX_IDENTITY_SIZE, id);
549     }
550
551     discoveryPayload->sel = biasFactor;
552     return discoveryPayload;
553 exit:
554     OICFree(discoveryPayload);
555     discoveryPayload = NULL;
556     return discoveryPayload;
557 }
558
559 void OCRDPayloadDestroy(OCRDPayload *payload)
560 {
561     if (!payload)
562     {
563         return;
564     }
565
566     if (payload->rdDiscovery)
567     {
568         if (payload->rdDiscovery->n.deviceName)
569         {
570             OICFree(payload->rdDiscovery->n.deviceName);
571         }
572         OICFree(payload->rdDiscovery);
573     }
574
575     if (payload->rdPublish)
576     {
577         for (OCResourceCollectionPayload *col = payload->rdPublish; col; )
578         {
579             if (col->setLinks)
580             {
581                 OCFreeLinksResource(col->setLinks);
582             }
583
584             if (col->tags)
585             {
586                 OCFreeTagsResource(col->tags);
587             }
588             OCResourceCollectionPayload *temp = col->next;
589             OICFree(col);
590             col = temp;
591         }
592     }
593
594     OICFree(payload);
595 }
596
597 OCTagsPayload* OCCopyTagsResources(const char *deviceName, const unsigned char *id, const char *baseURI,
598         uint8_t bitmap, uint16_t port, uint8_t ins, const char *rts,const  char *drel, uint32_t ttl)
599 {
600     OCTagsPayload *tags = (OCTagsPayload *)OICCalloc(1, sizeof(OCTagsPayload));
601     if (!tags)
602     {
603         return NULL;
604     }
605         if (deviceName)
606     {
607         tags->n.deviceName = OICStrdup(deviceName);
608         if (!tags->n.deviceName)
609         {
610             goto memory_allocation_failed;
611         }
612     }
613     if (id)
614     {
615         OICStrcpy((char*)tags->di.id, MAX_IDENTITY_SIZE, (char *)id);
616         if (!tags->di.id)
617         {
618             goto memory_allocation_failed;
619         }
620     }
621     if (baseURI)
622     {
623         tags->baseURI = OICStrdup(baseURI);
624         if (!tags->baseURI)
625         {
626             goto memory_allocation_failed;
627         }
628     }
629     tags->bitmap = bitmap;
630     tags->port = port;
631     tags->ins = ins;
632     if (rts)
633     {
634         tags->rts = OICStrdup(rts);
635         if (!tags->rts)
636         {
637             goto memory_allocation_failed;
638         }
639     }
640     if (drel)
641     {
642         tags->drel = OICStrdup(drel);
643         if (!tags->drel)
644         {
645             goto memory_allocation_failed;
646         }
647     }
648     tags->ttl = ttl;
649     return tags;
650
651 memory_allocation_failed:
652     OIC_LOG(ERROR, TAG, "Memory allocation failed.");
653     OCFreeTagsResource(tags);
654     return NULL;
655 }
656
657 OCLinksPayload* OCCopyLinksResources(const char *href, OCStringLL *rt, OCStringLL *itf,
658         const char *rel, bool obs, const char *title, const char *uri, uint8_t ins, OCStringLL *mt)
659 {
660     OCLinksPayload *links = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload));
661     if (!links)
662     {
663         OIC_LOG(ERROR, TAG, "Failed allocating memory.");
664         return NULL;
665     }
666     if (href)
667     {
668         links->href = OICStrdup(href);
669         if (!links->href)
670         {
671             goto memory_allocation_failed;
672         }
673     }
674     if (rt)
675     {
676         links->rt = CloneOCStringLL(rt);
677         if (!links->rt)
678         {
679             goto memory_allocation_failed;
680         }
681     }
682     if (itf)
683     {
684         links->itf = CloneOCStringLL(itf);
685         if (!links->itf)
686         {
687             goto memory_allocation_failed;
688         }
689     }
690     if (rel)
691     {
692         links->rel = OICStrdup(rel);
693         if (!links->rel)
694         {
695             goto memory_allocation_failed;
696         }
697     }
698     links->obs = obs;
699     if (title)
700     {
701         links->title = OICStrdup(title);
702         if (!links->title)
703         {
704             goto memory_allocation_failed;
705         }
706     }
707     if (uri)
708     {
709         links->uri = OICStrdup(uri);
710         if (!links->uri)
711         {
712             goto memory_allocation_failed;
713         }
714     }
715     links->ins = ins;
716     if (mt)
717     {
718         links->mt = CloneOCStringLL(mt);
719         if (!links->mt)
720         {
721             goto memory_allocation_failed;
722         }
723     }
724     links->next = NULL;
725     return links;
726
727 memory_allocation_failed:
728     OIC_LOG(ERROR, TAG, "Memory allocation failed.");
729     OCFreeLinksResource(links);
730     return NULL;
731 }
732
733 OCResourceCollectionPayload* OCCopyCollectionResource(OCTagsPayload *tags, OCLinksPayload *links)
734 {
735     OCResourceCollectionPayload *pl =  NULL;
736     VERIFY_PARAM_NON_NULL(TAG, tags, "Invalid param tags");
737     VERIFY_PARAM_NON_NULL(TAG, links, "Invalid param links");
738
739     pl = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
740     VERIFY_PARAM_NON_NULL(TAG, pl, "Failed allocating memory for the OCResourceCollectionPayload");
741
742     pl->tags = tags;
743     pl->setLinks = links;
744
745 exit:
746     return pl;
747 }
748
749 void OCFreeLinksResource(OCLinksPayload *payload)
750 {
751     if (!payload)
752     {
753         return;
754     }
755     OICFree(payload->href);
756     OCFreeOCStringLL(payload->rt);
757     OCFreeOCStringLL(payload->itf);
758     OICFree(payload->rel);
759     OICFree(payload->title);
760     OICFree(payload->uri);
761     OCFreeOCStringLL(payload->mt);
762     OCFreeLinksResource(payload->next);
763     OICFree(payload);
764 }
765
766 void OCFreeTagsResource(OCTagsPayload *payload)
767 {
768     if (!payload)
769     {
770         return;
771     }
772     OICFree(payload->n.deviceName);
773     OICFree(payload->baseURI);
774     OICFree(payload->rts);
775     OICFree(payload->drel);
776     OICFree(payload);
777 }
778
779 void OCFreeCollectionResource(OCResourceCollectionPayload *payload)
780 {
781     if (!payload)
782     {
783         return;
784     }
785     if (payload->tags)
786     {
787         OCFreeTagsResource(payload->tags);
788     }
789     if (payload->setLinks)
790     {
791         OCFreeLinksResource(payload->setLinks);
792     }
793     OCFreeCollectionResource(payload->next);
794     OICFree(payload);
795 }
796
797 void OCTagsLog(const LogLevel level, const OCTagsPayload *tags)
798 {
799     if (tags)
800     {
801         if (tags->n.deviceName)
802         {
803             OIC_LOG_V(level, TAG, " Device Name : %s ",tags->n.deviceName);
804         }
805         if (tags->baseURI)
806         {
807             OIC_LOG_V(level, TAG, " Base URI : %s ",tags->baseURI);
808         }
809         OIC_LOG_V(level, TAG, " Device ID : %s ",tags->di.id);
810         OIC_LOG_V(level, TAG, " Bitmap : %d ",tags->bitmap);
811         OIC_LOG_V(level, TAG, " Port : %d ",tags->port);
812         OIC_LOG_V(level, TAG, " Ins : %d ",tags->ins);
813         OIC_LOG_V(level, TAG, " Ttl : %d ",tags->ttl);
814
815         if (tags->rts)
816         {
817             OIC_LOG_V(level, TAG, " RTS : %s ",tags->rts);
818         }
819         if (tags->drel)
820         {
821             OIC_LOG_V(level, TAG, " DREL : %s ",tags->drel);
822         }
823     }
824     else
825     {
826         (void) level;
827     }
828 }
829
830 void OCLinksLog(const LogLevel level, const OCLinksPayload *links)
831 {
832     while (links)
833     {
834         if (links->href)
835         {
836             OIC_LOG_V(level, TAG, " href: %s ",links->href);
837         }
838         OIC_LOG(level, TAG, " RT: ");
839         OCStringLL *rt = links->rt;
840         while (rt)
841         {
842             if (rt->value)
843             {
844                 OIC_LOG_V(level, TAG, "   %s", rt->value);
845             }
846             rt = rt->next;
847         }
848         OIC_LOG(level, TAG, " IF: ");
849         OCStringLL *itf = links->itf;
850         while (itf)
851         {
852             if (itf->value)
853             {
854                 OIC_LOG_V(level, TAG, "   %s", itf->value);
855             }
856             itf = itf->next;
857         }
858         OIC_LOG(level, TAG, " MT: ");
859         OCStringLL *mt = links->mt;
860         while (mt)
861         {
862             if (mt->value)
863             {
864                 OIC_LOG_V(level, TAG, "   %s", mt->value);
865             }
866             mt = mt->next;
867         }
868         OIC_LOG_V(level, TAG, " INS: %d", links->ins);
869         OIC_LOG_V(level, TAG, " OBS: %d", links->obs);
870         if (links->rel)
871         {
872             OIC_LOG_V(level, TAG, " REL: %s", links->rel);
873         }
874         if (links->title)
875         {
876             OIC_LOG_V(level, TAG, " TITLE: %s", links->title);
877         }
878         if (links->uri)
879         {
880             OIC_LOG_V(level, TAG, " URI: %s", links->uri);
881         }
882         links = links->next;
883     }
884     if (!links)
885     {
886         (void) level;
887     }
888 }