1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "ocpayloadcbor.h"
23 #include "oic_malloc.h"
25 #include "ocpayload.h"
27 #include "ocresourcehandler.h"
30 #define TAG PCF("OCPayloadConvert")
32 static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
34 static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
36 static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
38 static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size);
39 static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, uint8_t** outPayload,
41 static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
44 bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
47 bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
51 OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
53 OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
56 case PAYLOAD_TYPE_DISCOVERY:
57 return OCConvertDiscoveryPayload((OCDiscoveryPayload*)payload, outPayload, size);
58 case PAYLOAD_TYPE_DEVICE:
59 return OCConvertDevicePayload((OCDevicePayload*)payload, outPayload, size);
60 case PAYLOAD_TYPE_PLATFORM:
61 return OCConvertPlatformPayload((OCPlatformPayload*)payload, outPayload, size);
62 case PAYLOAD_TYPE_REPRESENTATION:
63 return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
64 case PAYLOAD_TYPE_PRESENCE:
65 return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
66 case PAYLOAD_TYPE_SECURITY:
67 return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
70 return OCRDPayloadToCbor((OCRDPayload*)payload, outPayload, size);
73 OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
74 return OC_STACK_NOTIMPL;
78 static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
81 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
82 *size = MAX_REQUEST_LENGTH;
86 return OC_STACK_NO_MEMORY;
92 cbor_encoder_init(&encoder, *outPayload, *size, 0);
94 CborEncoder rootArray;
95 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
96 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY);
100 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
102 if(payload->securityData)
104 err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION,
105 sizeof(OC_RSRVD_REPRESENTATION) - 1,
106 payload->securityData);
109 err = err || cbor_encoder_close_container(&rootArray, &map);
111 err = err || cbor_encoder_close_container(&encoder, &rootArray);
115 OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err);
116 OICFree(*outPayload);
117 return OC_STACK_ERROR;
120 *size = encoder.ptr - *outPayload;
121 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
125 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
126 OICFree(*outPayload);
127 return OC_STACK_ERROR;
130 *outPayload = tempPayload;
134 static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
137 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
138 *size = MAX_REQUEST_LENGTH;
142 return OC_STACK_NO_MEMORY;
145 CborEncoder encoder = {0};
147 size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload);
149 cbor_encoder_init(&encoder, *outPayload, *size, 0);
151 CborEncoder rootArray;
152 err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount);
153 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY);
155 for(size_t i = 0; i < resourceCount; ++i)
158 OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
162 OICFree(*outPayload);
163 return OC_STACK_INVALID_PARAM;
166 err = err || cbor_encoder_create_map(&rootArray, &map, 3);
168 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF,
169 sizeof(OC_RSRVD_HREF) - 1,
173 err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID,
174 sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1);
175 err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);
179 err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY,
180 sizeof(OC_RSRVD_PROPERTY) -1 );
181 err = err || cbor_encoder_create_map(&map, &propMap, 3);
186 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE,
187 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
188 err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength);
190 OCStringLL* rtPtr = resource->types;
193 err = err || cbor_encode_text_string(&rtArray, rtPtr->value,
194 strlen(rtPtr->value));
198 err = err || cbor_encoder_close_container(&propMap, &rtArray);
204 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE,
205 sizeof(OC_RSRVD_INTERFACE) - 1);
206 err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength);
207 OCStringLL* ifPtr = resource->interfaces;
211 err = err || cbor_encode_text_string(&ifArray, ifPtr->value,
212 strlen(ifPtr->value));
216 err = err || cbor_encoder_close_container(&propMap, &ifArray);
220 CborEncoder policyMap;
221 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY,
222 sizeof(OC_RSRVD_POLICY) - 1);
223 err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength);
226 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
227 sizeof(OC_RSRVD_BITMAP) - 1);
228 err = err || cbor_encode_uint(&policyMap, resource->bitmap);
232 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
233 sizeof(OC_RSRVD_SECURE) - 1);
234 err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
236 if(resource->port != 0)
238 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
239 sizeof(OC_RSRVD_HOSTING_PORT) - 1);
240 err = err || cbor_encode_uint(&policyMap, resource->port);
244 err = err || cbor_encoder_close_container(&propMap, &policyMap);
247 err = err || cbor_encoder_close_container(&map, &propMap);
250 err = err || cbor_encoder_close_container(&rootArray, &map);
253 err = err || cbor_encoder_close_container(&encoder, &rootArray);
257 OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err);
258 return OC_STACK_ERROR;
261 *size = encoder.ptr - *outPayload;
262 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
266 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
267 OICFree(*outPayload);
268 return OC_STACK_ERROR;
271 *outPayload = tempPayload;
275 static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
278 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
279 *size = MAX_REQUEST_LENGTH;
283 return OC_STACK_NO_MEMORY;
286 CborEncoder encoder = {0};
289 cbor_encoder_init(&encoder, *outPayload, *size, 0);
290 CborEncoder rootArray;
291 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
292 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE);
296 err = err || cbor_encoder_create_map(&rootArray, &map, 2);
299 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
305 err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
306 sizeof(OC_RSRVD_REPRESENTATION) - 1);
307 err = err || cbor_encoder_create_map(&map, &repMap, 4);
310 err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID,
311 sizeof(OC_RSRVD_DEVICE_ID) - 1);
312 err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE);
315 err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME,
316 sizeof(OC_RSRVD_DEVICE_NAME) - 1,
317 payload->deviceName);
319 // Device Spec Version
320 err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION,
321 sizeof(OC_RSRVD_SPEC_VERSION) - 1,
322 payload->specVersion);
324 // Device data Model Version
325 err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
326 sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1,
327 payload->dataModelVersion);
329 err = err || cbor_encoder_close_container(&map, &repMap);
333 err = err || cbor_encoder_close_container(&rootArray, &map);
337 err = err || cbor_encoder_close_container(&encoder, &rootArray);
341 OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err);
342 return OC_STACK_ERROR;
345 *size = encoder.ptr - *outPayload;
346 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
350 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
351 OICFree(*outPayload);
352 return OC_STACK_ERROR;
355 *outPayload = tempPayload;
359 static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
362 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
363 *size = MAX_REQUEST_LENGTH;
367 return OC_STACK_NO_MEMORY;
370 CborEncoder encoder = {0};
373 cbor_encoder_init(&encoder, *outPayload, *size, 0);
374 CborEncoder rootArray;
375 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
376 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM);
379 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
382 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
388 err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
389 sizeof(OC_RSRVD_REPRESENTATION) - 1);
390 err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
393 err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID,
394 sizeof(OC_RSRVD_PLATFORM_ID) - 1,
395 payload->info.platformID);
398 err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME,
399 sizeof(OC_RSRVD_MFG_NAME) - 1,
400 payload->info.manufacturerName);
403 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL,
404 sizeof(OC_RSRVD_MFG_URL) - 1,
405 payload->info.manufacturerUrl);
408 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM,
409 sizeof(OC_RSRVD_MODEL_NUM) - 1,
410 payload->info.modelNumber);
413 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE,
414 sizeof(OC_RSRVD_MFG_DATE) - 1,
415 payload->info.dateOfManufacture);
418 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION,
419 sizeof(OC_RSRVD_PLATFORM_VERSION) - 1,
420 payload->info.platformVersion);
423 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION,
424 sizeof(OC_RSRVD_OS_VERSION) - 1,
425 payload->info.operatingSystemVersion);
428 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION,
429 sizeof(OC_RSRVD_HARDWARE_VERSION) - 1,
430 payload->info.hardwareVersion);
433 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION,
434 sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1,
435 payload->info.firmwareVersion);
438 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL,
439 sizeof(OC_RSRVD_SUPPORT_URL) - 1,
440 payload->info.supportUrl);
443 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME,
444 sizeof(OC_RSRVD_SYSTEM_TIME) - 1,
445 payload->info.systemTime);
446 err = err || cbor_encoder_close_container(&map, &repMap);
450 err = err || cbor_encoder_close_container(&rootArray, &map);
454 err = err || cbor_encoder_close_container(&encoder, &rootArray);
458 OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err);
459 return OC_STACK_ERROR;
462 *size = encoder.ptr - *outPayload;
463 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
467 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
468 OICFree(*outPayload);
469 return OC_STACK_ERROR;
472 *outPayload = tempPayload;
477 static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload);
479 static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray)
484 err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength);
485 err = err || cbor_encode_uint(&array, valArray->type);
486 for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i)
488 err = err || cbor_encode_uint(&array, valArray->dimensions[i]);
491 size_t dimTotal = calcDimTotal(valArray->dimensions);
493 for(size_t i = 0; i < dimTotal; ++i)
495 switch(valArray->type)
497 case OCREP_PROP_NULL:
498 OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL"));
499 err = CborUnknownError;
502 err = err || cbor_encode_int(&array, valArray->iArray[i]);
504 case OCREP_PROP_DOUBLE:
505 err = err || cbor_encode_double(&array, valArray->dArray[i]);
507 case OCREP_PROP_BOOL:
508 err = err || cbor_encode_boolean(&array, valArray->bArray[i]);
510 case OCREP_PROP_STRING:
511 err = err || cbor_encode_text_string(&array, valArray->strArray[i],
512 strlen(valArray->strArray[i]));
514 case OCREP_PROP_OBJECT:
515 err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
517 case OCREP_PROP_ARRAY:
518 OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array"));
519 err = CborUnknownError;
524 err = err || cbor_encoder_close_container(parent, &array);
528 static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload)
532 err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength);
535 err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF,
536 sizeof(OC_RSRVD_HREF) - 1,
540 // resource types, interfaces
541 if(payload->types || payload->interfaces)
543 OC_LOG_V(INFO, TAG, "Payload has types or interfaces");
544 err = err || cbor_encode_text_string(&map,
546 sizeof(OC_RSRVD_PROPERTY) - 1);
548 err = err || cbor_encoder_create_map(&map, &propMap, 2);
550 CborEncoder curArray;
553 err = err || cbor_encode_text_string(&propMap,
554 OC_RSRVD_RESOURCE_TYPE,
555 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
556 err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
557 OCStringLL* val = payload->types;
560 err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
563 err = err || cbor_encoder_close_container(&propMap, &curArray);
565 if(payload->interfaces)
567 err = err || cbor_encode_text_string(&propMap,
569 sizeof(OC_RSRVD_INTERFACE) - 1);
570 err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
571 OCStringLL* val = payload->interfaces;
574 err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
577 err = err || cbor_encoder_close_container(&propMap, &curArray);
579 err = err || cbor_encoder_close_container(&map, &propMap);
585 err = err || cbor_encode_text_string(&map,
586 OC_RSRVD_REPRESENTATION,
587 sizeof(OC_RSRVD_REPRESENTATION) - 1);
588 err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
589 OCRepPayloadValue* value = payload->values;
592 err = err || cbor_encode_text_string(&repMap,
594 strlen(value->name));
597 case OCREP_PROP_NULL:
598 err = err || cbor_encode_null(&repMap);
601 err = err || cbor_encode_int(&repMap,
604 case OCREP_PROP_DOUBLE:
605 err = err || cbor_encode_double(&repMap,
608 case OCREP_PROP_BOOL:
609 err = err || cbor_encode_boolean(&repMap,
612 case OCREP_PROP_STRING:
613 err = err || cbor_encode_text_string(&repMap,
614 value->str, strlen(value->str));
616 case OCREP_PROP_OBJECT:
617 err = err || OCConvertSingleRepPayload(&repMap, value->obj);
619 case OCREP_PROP_ARRAY:
620 err = err || OCConvertArray(&repMap, &value->arr);
623 OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d",
630 err = err || cbor_encoder_close_container(&map, &repMap);
634 err = err || cbor_encoder_close_container(parent, &map);
639 static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size)
641 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
642 *size = MAX_REQUEST_LENGTH;
646 return OC_STACK_NO_MEMORY;
649 CborEncoder encoder = {0};
652 cbor_encoder_init(&encoder, *outPayload, *size, 0);
653 CborEncoder rootArray;
654 err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength);
655 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION);
657 while(payload != NULL && !err)
659 err = err || OCConvertSingleRepPayload(&rootArray, payload);
660 payload = payload->next;
664 err = err || cbor_encoder_close_container(&encoder, &rootArray);
668 OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err);
669 return OC_STACK_ERROR;
672 *size = encoder.ptr - *outPayload;
673 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
677 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
678 OICFree(*outPayload);
679 return OC_STACK_ERROR;
682 *outPayload = tempPayload;
687 static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload,
688 uint8_t** outPayload, size_t* size)
690 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
691 *size = MAX_REQUEST_LENGTH;
695 return OC_STACK_NO_MEMORY;
698 CborEncoder encoder = {0};
701 cbor_encoder_init(&encoder, *outPayload, *size, 0);
702 CborEncoder rootArray;
704 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
705 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE);
709 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
712 err = err || cbor_encode_text_string(&map,
714 sizeof(OC_RSRVD_NONCE) - 1);
715 err = err || cbor_encode_uint(&map, payload->sequenceNumber);
718 err = err || cbor_encode_text_string(&map,
720 sizeof(OC_RSRVD_TTL) - 1);
721 err = err || cbor_encode_uint(&map, payload->maxAge);
724 const char* triggerStr = convertTriggerEnumToString(payload->trigger);
725 err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1,
728 // Resource type name
729 if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
731 err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
732 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType);
736 err = err || cbor_encoder_close_container(&rootArray, &map);
737 err = err || cbor_encoder_close_container(&encoder, &rootArray);
741 OC_LOG_V(ERROR, TAG, "Convert Presence Payload failed with : %d", err);
742 return OC_STACK_ERROR;
745 *size = encoder.ptr - *outPayload;
746 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
750 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
751 OICFree(*outPayload);
752 return OC_STACK_ERROR;
755 *outPayload = tempPayload;
760 bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
763 return cbor_encode_text_string(map, key, keylen) ||
764 cbor_encode_text_string(map, value, strlen(value));
767 bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
770 return value ? AddTextStringToMap(map, key, keylen, value) : false;