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