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);
69 OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
70 return OC_STACK_NOTIMPL;
74 static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
77 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
78 *size = MAX_REQUEST_LENGTH;
82 return OC_STACK_NO_MEMORY;
88 cbor_encoder_init(&encoder, *outPayload, *size, 0);
90 CborEncoder rootArray;
91 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
92 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY);
96 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
98 if(payload->securityData)
100 err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION,
101 sizeof(OC_RSRVD_REPRESENTATION) - 1,
102 payload->securityData);
105 err = err || cbor_encoder_close_container(&rootArray, &map);
107 err = err || cbor_encoder_close_container(&encoder, &rootArray);
111 OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err);
112 OICFree(*outPayload);
113 return OC_STACK_ERROR;
116 *size = encoder.ptr - *outPayload;
117 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
121 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
122 OICFree(*outPayload);
123 return OC_STACK_ERROR;
126 *outPayload = tempPayload;
130 static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
133 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
134 *size = MAX_REQUEST_LENGTH;
138 return OC_STACK_NO_MEMORY;
141 CborEncoder encoder = {};
143 size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload);
145 cbor_encoder_init(&encoder, *outPayload, *size, 0);
147 CborEncoder rootArray;
148 err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount);
149 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY);
151 for(size_t i = 0; i < resourceCount; ++i)
154 OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
155 err = err || cbor_encoder_create_map(&rootArray, &map, 3);
157 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF,
158 sizeof(OC_RSRVD_HREF) - 1,
162 err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID,
163 sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1);
164 err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);
168 err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY,
169 sizeof(OC_RSRVD_PROPERTY) -1 );
170 err = err || cbor_encoder_create_map(&map, &propMap, 3);
175 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE,
176 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
177 err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength);
179 OCStringLL* rtPtr = resource->types;
182 err = err || cbor_encode_text_string(&rtArray, rtPtr->value,
183 strlen(rtPtr->value));
187 err = err || cbor_encoder_close_container(&propMap, &rtArray);
193 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE,
194 sizeof(OC_RSRVD_INTERFACE) - 1);
195 err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength);
196 OCStringLL* ifPtr = resource->interfaces;
200 err = err || cbor_encode_text_string(&ifArray, ifPtr->value,
201 strlen(ifPtr->value));
205 err = err || cbor_encoder_close_container(&propMap, &ifArray);
209 CborEncoder policyMap;
210 err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY,
211 sizeof(OC_RSRVD_POLICY) - 1);
212 err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength);
215 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
216 sizeof(OC_RSRVD_BITMAP) - 1);
217 err = err || cbor_encode_uint(&policyMap, resource->bitmap);
221 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
222 sizeof(OC_RSRVD_SECURE) - 1);
223 err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
225 if(resource->port != 0)
227 err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
228 sizeof(OC_RSRVD_HOSTING_PORT) - 1);
229 err = err || cbor_encode_uint(&policyMap, resource->port);
233 err = err || cbor_encoder_close_container(&propMap, &policyMap);
236 err = err || cbor_encoder_close_container(&map, &propMap);
239 err = err || cbor_encoder_close_container(&rootArray, &map);
242 err = err || cbor_encoder_close_container(&encoder, &rootArray);
246 OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err);
247 return OC_STACK_ERROR;
250 *size = encoder.ptr - *outPayload;
251 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
255 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
256 OICFree(*outPayload);
257 return OC_STACK_ERROR;
260 *outPayload = tempPayload;
264 static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
267 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
268 *size = MAX_REQUEST_LENGTH;
272 return OC_STACK_NO_MEMORY;
275 CborEncoder encoder = {};
278 cbor_encoder_init(&encoder, *outPayload, *size, 0);
279 CborEncoder rootArray;
280 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
281 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE);
285 err = err || cbor_encoder_create_map(&rootArray, &map, 2);
288 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
294 err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
295 sizeof(OC_RSRVD_REPRESENTATION) - 1);
296 err = err || cbor_encoder_create_map(&map, &repMap, 4);
299 err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID,
300 sizeof(OC_RSRVD_DEVICE_ID) - 1);
301 err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE);
304 err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME,
305 sizeof(OC_RSRVD_DEVICE_NAME) - 1,
306 payload->deviceName);
308 // Device Spec Version
309 err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION,
310 sizeof(OC_RSRVD_SPEC_VERSION) - 1,
311 payload->specVersion);
313 // Device data Model Version
314 err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
315 sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1,
316 payload->dataModelVersion);
318 err = err || cbor_encoder_close_container(&map, &repMap);
322 err = err || cbor_encoder_close_container(&rootArray, &map);
326 err = err || cbor_encoder_close_container(&encoder, &rootArray);
330 OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err);
331 return OC_STACK_ERROR;
334 *size = encoder.ptr - *outPayload;
335 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
339 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
340 OICFree(*outPayload);
341 return OC_STACK_ERROR;
344 *outPayload = tempPayload;
348 static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
351 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
352 *size = MAX_REQUEST_LENGTH;
356 return OC_STACK_NO_MEMORY;
359 CborEncoder encoder = {};
362 cbor_encoder_init(&encoder, *outPayload, *size, 0);
363 CborEncoder rootArray;
364 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
365 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM);
368 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
371 err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
377 err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
378 sizeof(OC_RSRVD_REPRESENTATION) - 1);
379 err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
382 err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID,
383 sizeof(OC_RSRVD_PLATFORM_ID) - 1,
384 payload->info.platformID);
387 err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME,
388 sizeof(OC_RSRVD_MFG_NAME) - 1,
389 payload->info.manufacturerName);
392 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL,
393 sizeof(OC_RSRVD_MFG_URL) - 1,
394 payload->info.manufacturerUrl);
397 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM,
398 sizeof(OC_RSRVD_MODEL_NUM) - 1,
399 payload->info.modelNumber);
402 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE,
403 sizeof(OC_RSRVD_MFG_DATE) - 1,
404 payload->info.dateOfManufacture);
407 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION,
408 sizeof(OC_RSRVD_PLATFORM_VERSION) - 1,
409 payload->info.platformVersion);
412 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION,
413 sizeof(OC_RSRVD_OS_VERSION) - 1,
414 payload->info.operatingSystemVersion);
417 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION,
418 sizeof(OC_RSRVD_HARDWARE_VERSION) - 1,
419 payload->info.hardwareVersion);
422 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION,
423 sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1,
424 payload->info.firmwareVersion);
427 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL,
428 sizeof(OC_RSRVD_SUPPORT_URL) - 1,
429 payload->info.supportUrl);
432 err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME,
433 sizeof(OC_RSRVD_SYSTEM_TIME) - 1,
434 payload->info.systemTime);
435 err = err || cbor_encoder_close_container(&map, &repMap);
439 err = err || cbor_encoder_close_container(&rootArray, &map);
443 err = err || cbor_encoder_close_container(&encoder, &rootArray);
447 OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err);
448 return OC_STACK_ERROR;
451 *size = encoder.ptr - *outPayload;
452 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
456 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
457 OICFree(*outPayload);
458 return OC_STACK_ERROR;
461 *outPayload = tempPayload;
466 static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload);
468 static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray)
473 err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength);
474 err = err || cbor_encode_uint(&array, valArray->type);
475 for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i)
477 err = err || cbor_encode_uint(&array, valArray->dimensions[i]);
480 size_t dimTotal = calcDimTotal(valArray->dimensions);
482 for(size_t i = 0; i < dimTotal; ++i)
484 switch(valArray->type)
486 case OCREP_PROP_NULL:
487 OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL"));
488 err = CborUnknownError;
491 err = err || cbor_encode_int(&array, valArray->iArray[i]);
493 case OCREP_PROP_DOUBLE:
494 err = err || cbor_encode_double(&array, valArray->dArray[i]);
496 case OCREP_PROP_BOOL:
497 err = err || cbor_encode_boolean(&array, valArray->bArray[i]);
499 case OCREP_PROP_STRING:
500 err = err || cbor_encode_text_string(&array, valArray->strArray[i],
501 strlen(valArray->strArray[i]));
503 case OCREP_PROP_OBJECT:
504 err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
506 case OCREP_PROP_ARRAY:
507 OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array"));
508 err = CborUnknownError;
513 err = err || cbor_encoder_close_container(parent, &array);
517 static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload)
521 err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength);
524 err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF,
525 sizeof(OC_RSRVD_HREF) - 1,
529 // resource types, interfaces
530 if(payload->types || payload->interfaces)
532 OC_LOG_V(INFO, TAG, "Payload has types or interfaces");
533 err = err || cbor_encode_text_string(&map,
535 sizeof(OC_RSRVD_PROPERTY) - 1);
537 err = err || cbor_encoder_create_map(&map, &propMap, 2);
539 CborEncoder curArray;
542 err = err || cbor_encode_text_string(&propMap,
543 OC_RSRVD_RESOURCE_TYPE,
544 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
545 err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
546 OCStringLL* val = payload->types;
549 err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
552 err = err || cbor_encoder_close_container(&propMap, &curArray);
554 if(payload->interfaces)
556 err = err || cbor_encode_text_string(&propMap,
558 sizeof(OC_RSRVD_INTERFACE) - 1);
559 err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength);
560 OCStringLL* val = payload->interfaces;
563 err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value));
566 err = err || cbor_encoder_close_container(&propMap, &curArray);
568 err = err || cbor_encoder_close_container(&map, &propMap);
574 err = err || cbor_encode_text_string(&map,
575 OC_RSRVD_REPRESENTATION,
576 sizeof(OC_RSRVD_REPRESENTATION) - 1);
577 err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
578 OCRepPayloadValue* value = payload->values;
581 err = err || cbor_encode_text_string(&repMap,
583 strlen(value->name));
586 case OCREP_PROP_NULL:
587 err = err || cbor_encode_null(&repMap);
590 err = err || cbor_encode_int(&repMap,
593 case OCREP_PROP_DOUBLE:
594 err = err || cbor_encode_double(&repMap,
597 case OCREP_PROP_BOOL:
598 err = err || cbor_encode_boolean(&repMap,
601 case OCREP_PROP_STRING:
602 err = err || cbor_encode_text_string(&repMap,
603 value->str, strlen(value->str));
605 case OCREP_PROP_OBJECT:
606 err = err || OCConvertSingleRepPayload(&repMap, value->obj);
608 case OCREP_PROP_ARRAY:
609 err = err || OCConvertArray(&repMap, &value->arr);
612 OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d",
619 err = err || cbor_encoder_close_container(&map, &repMap);
623 err = err || cbor_encoder_close_container(parent, &map);
628 static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size)
630 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
631 *size = MAX_REQUEST_LENGTH;
635 return OC_STACK_NO_MEMORY;
638 CborEncoder encoder = {};
641 cbor_encoder_init(&encoder, *outPayload, *size, 0);
642 CborEncoder rootArray;
643 err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength);
644 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION);
646 while(payload != NULL && !err)
648 err = err || OCConvertSingleRepPayload(&rootArray, payload);
649 payload = payload->next;
653 err = err || cbor_encoder_close_container(&encoder, &rootArray);
657 OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err);
658 return OC_STACK_ERROR;
661 *size = encoder.ptr - *outPayload;
662 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
666 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
667 OICFree(*outPayload);
668 return OC_STACK_ERROR;
671 *outPayload = tempPayload;
676 static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload,
677 uint8_t** outPayload, size_t* size)
679 *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
680 *size = MAX_REQUEST_LENGTH;
684 return OC_STACK_NO_MEMORY;
687 CborEncoder encoder = {};
690 cbor_encoder_init(&encoder, *outPayload, *size, 0);
691 CborEncoder rootArray;
693 err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
694 err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PRESENCE);
698 err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
701 err = err || cbor_encode_text_string(&map,
703 sizeof(OC_RSRVD_NONCE) - 1);
704 err = err || cbor_encode_uint(&map, payload->sequenceNumber);
707 err = err || cbor_encode_text_string(&map,
709 sizeof(OC_RSRVD_TTL) - 1);
710 err = err || cbor_encode_uint(&map, payload->maxAge);
713 const char* triggerStr = convertTriggerEnumToString(payload->trigger);
714 err = err || AddTextStringToMap(&map, OC_RSRVD_TRIGGER, sizeof(OC_RSRVD_TRIGGER) - 1,
717 // Resource type name
718 if(payload->trigger != OC_PRESENCE_TRIGGER_DELETE)
720 err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_RESOURCE_TYPE,
721 sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->resourceType);
725 err = err || cbor_encoder_close_container(&rootArray, &map);
726 err = err || cbor_encoder_close_container(&encoder, &rootArray);
730 OC_LOG_V(ERROR, TAG, "Convert Presence Payload failed with : %d", err);
731 return OC_STACK_ERROR;
734 *size = encoder.ptr - *outPayload;
735 uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
739 OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
740 OICFree(*outPayload);
741 return OC_STACK_ERROR;
744 *outPayload = tempPayload;
749 bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
752 return cbor_encode_text_string(map, key, keylen) ||
753 cbor_encode_text_string(map, value, strlen(value));
756 bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
759 return value ? AddTextStringToMap(map, key, keylen, value) : false;