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 "rd_payload.h"
22 #include "oic_malloc.h"
23 #include "oic_string.h"
28 #define TAG PCF("OCRDPayload")
30 #define CBOR_ROOT_ARRAY_LENGTH 1
31 #define CBOR_LINK_ARRAY_LENGTH 3
33 static void linksPayloadDestroy(OCRDLinksPayload *linkPayload)
35 OCRDLinksPayload *links = linkPayload;
42 OCRDLinksPayload *tmp = links;
48 OCStackResult OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
50 if (!outPayload || !size)
52 OC_LOG_V(ERROR, TAG, "Invalid parameters.");
53 return OC_STACK_ERROR;
58 cbor_encoder_init(&encoder, outPayload, *size, flags);
60 CborEncoder rootArray;
61 CborError cborEncoderResult;
62 cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
63 if (CborNoError != cborEncoderResult)
65 OC_LOG_V(ERROR, TAG, "Failed creating cbor array.");
70 cborEncoderResult = cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
71 if (CborNoError != cborEncoderResult)
73 OC_LOG_V(ERROR, TAG, "Failed creating cbor map.");
77 cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_CONTENT_TYPE,
78 sizeof(OC_RSRVD_CONTENT_TYPE) - 1);
79 if (CborNoError != cborEncoderResult)
81 OC_LOG_V(ERROR, TAG, "Failed setting content type.");
85 cborEncoderResult = cbor_encode_uint(&map, rdPayload->payloadType);
86 if (CborNoError != cborEncoderResult)
88 OC_LOG_V(ERROR, TAG, "Failed setting rdPayload->payloadType.");
92 if (rdPayload->payloadType == RD_PAYLOAD_TYPE_DISCOVERY)
94 if (rdPayload->rdDiscovery && rdPayload->rdDiscovery->sel)
96 cborEncoderResult = cbor_encode_text_string(&map,
97 OC_RSRVD_RD_DISCOVERY_SEL, sizeof(OC_RSRVD_RD_DISCOVERY_SEL) -1);
98 if (CborNoError != cborEncoderResult)
100 OC_LOG_V(ERROR, TAG, "Failed setting discovery sel type.");
103 cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdDiscovery->sel);
104 if (CborNoError != cborEncoderResult)
106 OC_LOG_V(ERROR, TAG, "Failed setting discovery sel value.");
112 OC_LOG_V(ERROR, TAG, "Missing sel parameter in the discovery payload.");
116 else if (rdPayload->payloadType == RD_PAYLOAD_TYPE_PUBLISH)
118 cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_TTL, sizeof(OC_RSRVD_TTL) - 1);
119 if (CborNoError != cborEncoderResult)
121 OC_LOG_V(ERROR, TAG, "Failed setting publish ttl type.");
125 cborEncoderResult = cbor_encode_uint(&map, rdPayload->rdPublish->ttl);
126 if (CborNoError != cborEncoderResult)
128 OC_LOG_V(ERROR, TAG, "Failed setting publish ttl value.");
132 CborEncoder linksArray;
133 cborEncoderResult = cbor_encode_text_string(&map, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1);
134 if (CborNoError != cborEncoderResult)
136 OC_LOG_V(ERROR, TAG, "Failed setting publish links type.");
140 cborEncoderResult = cbor_encoder_create_array(&map, &linksArray, CborIndefiniteLength);
141 if (CborNoError != cborEncoderResult)
143 OC_LOG_V(ERROR, TAG, "Failed setting publish links array.");
148 OCRDLinksPayload *rtPtr = rdPayload->rdPublish->links;
151 CborEncoder linksMap;
152 cborEncoderResult = cbor_encoder_create_map(&linksArray, &linksMap, CBOR_LINK_ARRAY_LENGTH);
153 if (CborNoError != cborEncoderResult)
155 OC_LOG_V(ERROR, TAG, "Failed setting publish map.");
159 cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_HREF,
160 sizeof(OC_RSRVD_HREF) - 1);
161 if (CborNoError != cborEncoderResult)
163 OC_LOG_V(ERROR, TAG, "Failed setting publish href type.");
167 cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->href,
168 strlen(rtPtr->href));
169 if (CborNoError != cborEncoderResult)
171 OC_LOG_V(ERROR, TAG, "Failed setting publish href value.");
175 cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_INTERFACE,
176 sizeof(OC_RSRVD_INTERFACE) - 1);
177 if (CborNoError != cborEncoderResult)
179 OC_LOG_V(ERROR, TAG, "Failed setting publish itf type.");
183 cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->itf,
185 if (CborNoError != cborEncoderResult)
187 OC_LOG_V(ERROR, TAG, "Failed setting publish itf value.");
191 cborEncoderResult = cbor_encode_text_string(&linksMap, OC_RSRVD_RESOURCE_TYPE,
192 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
193 if (CborNoError != cborEncoderResult)
195 OC_LOG_V(ERROR, TAG, "Failed setting publish rt type.");
199 cborEncoderResult = cbor_encode_text_string(&linksMap, rtPtr->rt,
201 if (CborNoError != cborEncoderResult)
203 OC_LOG_V(ERROR, TAG, "Failed setting publish rt value.");
207 cborEncoderResult = cbor_encoder_close_container(&linksArray, &linksMap);
208 if (CborNoError != cborEncoderResult)
210 OC_LOG_V(ERROR, TAG, "Failed closing linksMap publish map.");
217 cborEncoderResult = cbor_encoder_close_container(&map, &linksArray);
218 if (CborNoError != cborEncoderResult)
220 OC_LOG_V(ERROR, TAG, "Failed closing linksArray container.");
225 cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
226 if (CborNoError != cborEncoderResult)
228 OC_LOG_V(ERROR, TAG, "Failed closing map container.");
232 cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
233 if (CborNoError != cborEncoderResult)
235 OC_LOG_V(ERROR, TAG, "Failed closing encoder container.");
239 *size = encoder.ptr - outPayload;
244 return OC_STACK_ERROR;
247 OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload)
249 CborValue *rdCBORPayload = (CborValue *)cborPayload;
250 OCRDPayload *rdPayload = NULL;
252 if (!cbor_value_is_map(rdCBORPayload))
254 OC_LOG_V(ERROR, TAG, "RD CBOR Payload is not in map format.");
255 return OC_STACK_ERROR;
260 CborError cborFindResult;
261 cborFindResult = cbor_value_map_find_value(rdCBORPayload,
262 OC_RSRVD_CONTENT_TYPE, &curVal);
263 if (CborNoError != cborFindResult)
265 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE type in the payload.");
269 int payloadType = 0 ;
270 if (cbor_value_is_valid(&curVal))
272 cborFindResult = cbor_value_get_int(&curVal, &payloadType);
273 if (CborNoError != cborFindResult)
275 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_CONTENT_TYPE value in the payload.");
280 rdPayload = OCRDPayloadCreate(payloadType);
286 if (RD_PAYLOAD_TYPE_DISCOVERY == payloadType)
288 cborFindResult = cbor_value_map_find_value(rdCBORPayload,
289 OC_RSRVD_RD_DISCOVERY_SEL, &curVal);
290 if (CborNoError != cborFindResult)
292 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL type in the payload.");
297 if (cbor_value_is_valid(&curVal))
299 cborFindResult = cbor_value_get_int(&curVal, &biasFactor);
300 if (CborNoError != cborFindResult)
302 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL value in the payload.");
307 rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(biasFactor);
308 if (!rdPayload->rdDiscovery)
313 else if (RD_PAYLOAD_TYPE_PUBLISH == payloadType)
316 cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_TTL, &curVal);
317 if (CborNoError != cborFindResult)
319 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL type in the payload.");
323 cborFindResult = cbor_value_get_int(&curVal, &ttl);
324 if (CborNoError != cborFindResult)
326 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_TTL value in the payload.");
332 cborFindResult = cbor_value_map_find_value(rdCBORPayload, OC_RSRVD_LINKS, &linkArray);
333 if (CborNoError != cborFindResult)
335 OC_LOG_V(ERROR, TAG, "Failed finding OC_RSRVD_LINKS type in the payload.");
340 cborFindResult = cbor_value_enter_container(&linkArray, &linkVal);
341 if (CborNoError != cborFindResult)
343 OC_LOG_V(ERROR, TAG, "Failed entering linkArray container in the payload.");
347 OCRDLinksPayload *links = NULL;
348 while(cbor_value_is_map(&linkVal))
355 cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_HREF, &curVal);
356 if (CborNoError != cborFindResult)
358 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF type in the payload.");
362 cborFindResult = cbor_value_dup_text_string(&curVal, &href, &len, NULL);
363 if (CborNoError != cborFindResult)
365 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_HREF value in the payload.");
369 cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_INTERFACE, &curVal);
370 if (CborNoError != cborFindResult)
372 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE type in the payload.");
376 cborFindResult = cbor_value_dup_text_string(&curVal, &itf, &len, NULL);
377 if (CborNoError != cborFindResult)
379 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_INTERFACE value in the payload.");
383 cborFindResult = cbor_value_map_find_value(&linkVal, OC_RSRVD_RESOURCE_TYPE, &curVal);
384 if (CborNoError != cborFindResult)
386 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE type in the payload.");
390 cborFindResult = cbor_value_dup_text_string(&curVal, &rt, &len, NULL);
391 if (CborNoError != cborFindResult)
393 OC_LOG_V(ERROR, TAG, "Failed finding link value OC_RSRVD_RESOURCE_TYPE value in the payload.");
397 OCRDLinksPayloadCreate(href, rt, itf, &links);
403 cborFindResult = cbor_value_advance(&linkVal);
404 if (CborNoError != cborFindResult)
406 OC_LOG_V(ERROR, TAG, "Failed advancing the linkVal payload.");
410 cborFindResult = cbor_value_advance(&linkArray);
411 if (CborNoError != cborFindResult)
413 OC_LOG_V(ERROR, TAG, "Failed advancing the linkArray payload.");
416 rdPayload->rdPublish = OCRDPublishPayloadCreate(ttl, links);
417 if (!rdPayload->rdPublish)
423 OCRDPayloadLog(DEBUG, TAG, rdPayload);
424 cborFindResult = cbor_value_advance(rdCBORPayload);
425 if (CborNoError != cborFindResult)
427 OC_LOG_V(ERROR, TAG, "Failed advancing the payload.");
430 *outPayload = (OCPayload *)rdPayload;
434 OC_LOG_V(ERROR, TAG, "Failed allocating memory.");
435 OCRDPayloadDestroy(rdPayload);
436 return OC_STACK_NO_MEMORY;
439 OCRDPayloadDestroy(rdPayload);
440 return OC_STACK_ERROR;
443 OCRDPayload *OCRDPayloadCreate(OCRDPayloadType payloadType)
445 OCRDPayload *rdPayload = (OCRDPayload *)OICCalloc(1, sizeof(OCRDPayload));
452 rdPayload->base.type = PAYLOAD_TYPE_RD;
453 rdPayload->payloadType = payloadType;
458 void OCRDLinksPayloadCreate(const char *uri, const char *rt, const char *itf,
459 OCRDLinksPayload **linksPayload)
461 OCRDLinksPayload *payload = OICCalloc(1, sizeof(OCRDLinksPayload));
467 payload->href = OICStrdup(uri);
473 payload->rt = OICStrdup(rt);
479 payload->itf = OICStrdup(itf);
485 payload->next = NULL;
487 if (*linksPayload == NULL)
489 *linksPayload = payload;
493 OCRDLinksPayload *temp = *linksPayload;
498 temp->next = payload;
503 OC_LOG_V(ERROR, TAG, "Memory allocation failed.");
504 linksPayloadDestroy(payload);
507 OCRDDiscoveryPayload *OCRDDiscoveryPayloadCreate(int biasFactor)
509 OCRDDiscoveryPayload *discoveryPayload = OICCalloc(1, sizeof(OCRDDiscoveryPayload));
511 if (!discoveryPayload)
515 discoveryPayload->sel = biasFactor;
517 return discoveryPayload;
521 OCRDPublishPayload* OCRDPublishPayloadCreate(int ttl,
522 OCRDLinksPayload *linksPayload)
524 OCRDPublishPayload *rdPublish = OICCalloc(1, sizeof(OCRDPublishPayload));
530 //TODO: Find way of device device id.
531 // rdPayload->rdPublish->id = (uint8_t *)OICCalloc(1, UUID_SIZE);
532 // memcpy(rdPayload->rdPublish->id, , UUID_SIZE);
533 //TODO: Find way of device device name.
534 // rdPayload->rdPublish->n = (char*)OICCalloc(1, strlen(name));
535 // memcpy(rdPayload->rdPublish->n, , strlen(name));
536 rdPublish->ttl = ttl; // TODO Expose API to allow user to set this value.
537 rdPublish->links = linksPayload;
542 void OCRDPayloadDestroy(OCRDPayload *payload)
549 if (payload->rdDiscovery)
551 OICFree(payload->rdDiscovery);
554 if (payload->rdPublish)
556 if (payload->rdPublish->links)
558 linksPayloadDestroy(payload->rdPublish->links);
561 if (payload->rdPublish->deviceName.deviceName)
563 OICFree(payload->rdPublish->deviceName.deviceName);
566 OICFree(payload->rdPublish);
572 void OCRDPayloadLog(LogLevel level, const char *tag, const OCRDPayload *payload)
579 OC_LOG_V(level, tag, "BaseType : %d", payload->base.type);
580 OC_LOG_V(level, tag, "RD Payload Type : %d", payload->payloadType);
582 if (payload->rdDiscovery)
584 OC_LOG_V(level, tag, "RD Payload Discovery BIAS : %d", payload->rdDiscovery->sel);
586 OCRDPublishPayloadLog(level, tag, payload->rdPublish);
589 void OCRDPublishPayloadLog(LogLevel level, const char *tag, const OCRDPublishPayload *rdPublish)
593 if (rdPublish->deviceName.deviceName)
595 OC_LOG_V(level, tag, "RD Payload Pulish Name : %s", rdPublish->deviceName.deviceName);
598 if (rdPublish->deviceId.id)
600 OC_LOG_V(level, tag, "RD Payload Publish ID : %s", rdPublish->deviceId.id);
603 OC_LOG_V(level, tag, "RD Payload Publish TTL : %d", rdPublish->ttl);
605 if (rdPublish->links)
607 for (OCRDLinksPayload *temp = rdPublish->links; temp; temp = temp->next)
609 OC_LOG_V(level, tag, "RD Payload Publish Link HREF : %s", temp->href);
610 OC_LOG_V(level, tag, "RD Payload Publish Link RT : %s", temp->rt);
611 OC_LOG_V(level, tag, "RD Payload Publish Link ITF : %s", temp->itf);