CborError sol_oic_decode_cbor_repr(struct sol_coap_packet *pkt, struct sol_vector *reprs) { CborParser parser; CborError err; CborValue root, array, repr; uint8_t *payload; uint16_t size; int payload_type; if (sol_coap_packet_get_payload(pkt, &payload, &size) < 0) return CborErrorUnknownLength; err = cbor_parser_init(payload, size, 0, &parser, &root); if (err != CborNoError) return err; if (!cbor_value_is_array(&root)) return CborErrorIllegalType; err |= cbor_value_enter_container(&root, &array); err |= cbor_value_get_int(&array, &payload_type); err |= cbor_value_advance_fixed(&array); if (err != CborNoError) return err; if (payload_type != SOL_OIC_PAYLOAD_REPRESENTATION) return CborErrorIllegalType; if (cbor_value_map_find_value(&array, SOL_OIC_KEY_REPRESENTATION, &repr) != CborNoError) return CborErrorIllegalType; /* We're done with this CborParser, no need to close the container. */ return sol_oic_decode_cbor_repr_map(&repr, reprs); }
static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue) { OCStackResult ret = OC_STACK_MALFORMED_RESPONSE; CborError err; char *securityData = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter"); VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid cbor"); CborValue strVal; err = cbor_value_enter_container(rootValue, &strVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container"); if (cbor_value_is_text_string(&strVal)) { size_t len = 0; err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data"); *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData); VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor"); ret = OC_STACK_OK; } exit: OICFree(securityData); return ret; }
static CborError advance_recursive(CborValue *it, int nestingLevel) { if (is_fixed_type(it->type)) return advance_internal(it); if (!cbor_value_is_container(it)) { size_t len = SIZE_MAX; return _cbor_value_copy_string(it, NULL, &len, it); } // map or array if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS) return CborErrorNestingTooDeep; CborError err; CborValue recursed; err = cbor_value_enter_container(it, &recursed); if (err) return err; while (!cbor_value_at_end(&recursed)) { err = advance_recursive(&recursed, nestingLevel + 1); if (err) return err; } return cbor_value_leave_container(it, &recursed); }
static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; char * securityData = NULL; CborValue map; size_t len; err = err || cbor_value_enter_container(rootValue, &map); err = err || cbor_value_dup_text_string(&map, &securityData, &len, NULL); err = err || cbor_value_leave_container(rootValue, &map); if(err) { OC_LOG(ERROR, TAG, "Cbor in error condition"); OICFree(securityData); return OC_STACK_MALFORMED_RESPONSE; } *outPayload = (OCPayload*)OCSecurityPayloadCreate(securityData); OICFree(securityData); return OC_STACK_OK; }
void readInputEventType(CborValue *it0, InputEventType *inputEventType) { cout<<"in IET - 1\n"; CborValue it1; CborValue *it = &it1; cbor_value_enter_container(it0, it); int i; cbor_value_get_int(it, &i); cbor_value_advance_fixed(it); inputEventType->selector = (EnumInputEventType)i; if (inputEventType->selector == 0) { }; if (inputEventType->selector == 1) { }; if (inputEventType->selector == 2) { }; if (inputEventType->selector == 3) { }; if (inputEventType->selector == 4) { }; if (inputEventType->selector == 5) { }; if (inputEventType->selector == 6) { }; if (inputEventType->selector == 7) { }; cbor_value_leave_container(it0, it); cout<<"in IET - 2\n"; }
static bool OCParseArrayFindDimensionsAndType(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType* type) { bool err = false; CborValue insideArray; *type = OCREP_PROP_NULL; dimensions[0] = dimensions[1] = dimensions[2] = 0; err = err || cbor_value_enter_container(parent, &insideArray); while (cbor_value_is_valid(&insideArray)) { OCRepPayloadPropType tempType = DecodeCborType(cbor_value_get_type(&insideArray)); if (tempType == OCREP_PROP_ARRAY) { size_t subdim[MAX_REP_ARRAY_DEPTH]; tempType = OCREP_PROP_NULL; err = err || OCParseArrayFindDimensionsAndType(&insideArray, subdim, &tempType); if (subdim[2] != 0) { OC_LOG(ERROR, TAG, "Parse array helper, sub-array too deep"); } dimensions[1] = dimensions[1] >= subdim[0] ? dimensions[1] : subdim[0]; dimensions[2] = dimensions[2] >= subdim[1] ? dimensions[2] : subdim[1]; if (*type != OCREP_PROP_NULL && tempType != OCREP_PROP_NULL && *type != tempType) { OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed (subtype)"); return true; } else if (*type == OCREP_PROP_NULL) { // We don't know the type of this array yet, so the assignment is OK *type = tempType; } } else if (*type == OCREP_PROP_NULL) { // We don't know the type of this array yet, so the assignment is OK *type = tempType; } // tempType is allowed to be NULL, since it might now know the answer yet else if (tempType != OCREP_PROP_NULL && *type != tempType) { // this is an invalid situation! OC_LOG(ERROR, TAG, "Array parse failed, mixed arrays not allowed"); return true; } ++dimensions[0]; cbor_value_advance(&insideArray); } return err; }
void readVec3(CborValue *it0, Vec3 *vec3) { CborValue it1; CborValue* it = &it1; cbor_value_enter_container(it0, it); cbor_value_get_float(it, &(vec3->x)); cbor_value_advance_fixed(it); cbor_value_get_float(it, &(vec3->y)); cbor_value_advance_fixed(it); cbor_value_get_float(it, &(vec3->z)); cbor_value_advance_fixed(it); cbor_value_leave_container(it0, it); }
static CborError FindStringLLInMap(const CborValue *linksMap, char *tag, OCStringLL **links) { size_t len; CborError cborFindResult; CborValue rtArray; cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray); if (CborNoError != cborFindResult) { return CborUnknownError; } CborValue rtVal; cborFindResult = cbor_value_enter_container(&rtArray, &rtVal); if (CborNoError != cborFindResult) { return CborUnknownError; } OCStringLL* llPtr = *links; while (cbor_value_is_text_string(&rtVal)) { if (llPtr == NULL) { llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); if (!llPtr) { return CborUnknownError; } *links = llPtr; } else if(llPtr) { while (llPtr->next) { llPtr = llPtr->next; } llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); if (!llPtr->next) { return CborUnknownError; } } cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL); if (CborNoError != cborFindResult) { return CborUnknownError; } cborFindResult = cbor_value_advance(&rtVal); if (CborNoError != cborFindResult) { return CborUnknownError; } } cborFindResult = cbor_value_leave_container(&rtArray, &rtVal); return cborFindResult; }
void readInputEventHandler(CborValue *it0, InputEventHandler *inputEventHandler) { CborValue it1; CborValue *it = &it1; cbor_value_enter_container(it0, it); int i; cbor_value_get_int(it, &i); cbor_value_advance_fixed(it); inputEventHandler->selector = (EnumInputEventHandler)i; if (inputEventHandler->selector == 0) { }; if (inputEventHandler->selector == 1) { /* TBD */ }; cbor_value_leave_container(it0, it); }
void readGeometry(CborValue *it0, Geometry *geometry) { CborValue it1; CborValue *it = &it1; cbor_value_enter_container(it0, it); int i; cbor_value_get_int(it, &i); cbor_value_advance_fixed(it); geometry->selector = (EnumGeometry)i; if (geometry->selector == 0) { readShape(it, &(geometry->data.ShapeGeometry.value0)); }; if (geometry->selector == 1) { { size_t l; cbor_value_calculate_string_length(it, &l); geometry->data.ResourceGeometry.value0.resize(l+1); cbor_value_copy_text_string(it, (char *)(geometry->data.ResourceGeometry.value0.c_str()), &l, NULL); cbor_value_advance(it);} }; cbor_value_leave_container(it0, it); }
uint16_t oc_parse_rep(const uint8_t *in_payload, uint16_t payload_size, oc_rep_t **out_rep) { CborParser parser; CborValue root_value, cur_value, map; CborError err = CborNoError; struct cbor_buf_reader br; cbor_buf_reader_init(&br, in_payload, payload_size); err |= cbor_parser_init(&br.r, 0, &parser, &root_value); if (cbor_value_is_map(&root_value)) { err |= cbor_value_enter_container(&root_value, &cur_value); *out_rep = 0; oc_rep_t **cur = out_rep; while (cbor_value_is_valid(&cur_value)) { oc_parse_rep_value(&cur_value, cur, &err); err |= cbor_value_advance(&cur_value); cur = &(*cur)->next; } } else if (cbor_value_is_array(&root_value)) { err |= cbor_value_enter_container(&root_value, &map); err |= cbor_value_enter_container(&map, &cur_value); *out_rep = 0; oc_rep_t **cur = out_rep; while (cbor_value_is_valid(&cur_value)) { *cur = _alloc_rep(); (*cur)->type = OBJECT; oc_parse_rep_value(&cur_value, &(*cur)->value_object, &err); err |= cbor_value_advance(&cur_value); (*cur)->next = 0; cur = &(*cur)->next; } } return (uint16_t)err; }
void readShape(CborValue *it0, Shape *shape) { CborValue it1; CborValue *it = &it1; cbor_value_enter_container(it0, it); int i; cbor_value_get_int(it, &i); cbor_value_advance_fixed(it); shape->selector = (EnumShape)i; if (shape->selector == 0) { }; if (shape->selector == 1) { }; if (shape->selector == 2) { }; if (shape->selector == 3) { }; if (shape->selector == 4) { }; if (shape->selector == 5) { }; cbor_value_leave_container(it0, it); }
static CborError FindStringLLInMap(const CborValue *linksMap, const char *tag, OCStringLL **links) { size_t len; CborValue rtArray; OCStringLL* llPtr = *links; CborError cborFindResult = cbor_value_map_find_value(linksMap, tag, &rtArray); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding tag"); CborValue rtVal; cborFindResult = cbor_value_enter_container(&rtArray, &rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering container"); while (cbor_value_is_text_string(&rtVal)) { if (llPtr == NULL) { llPtr = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL"); *links = llPtr; } else if (llPtr) { while (llPtr->next) { llPtr = llPtr->next; } llPtr->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); llPtr = llPtr->next; VERIFY_PARAM_NON_NULL(TAG, llPtr, "Failed allocating OCStringLL->next"); } cborFindResult = cbor_value_dup_text_string(&rtVal, &(llPtr->value), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed duplicating value"); cborFindResult = cbor_value_advance(&rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing OCStringLL"); } cborFindResult = cbor_value_leave_container(&rtArray, &rtVal); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed leaving container"); exit: return cborFindResult; }
static bool _cbor_array_to_vector(CborValue *array, struct sol_vector *vector) { CborError err; CborValue iter; for (err = cbor_value_enter_container(array, &iter); cbor_value_is_text_string(&iter) && err == CborNoError; err |= cbor_value_advance(&iter)) { struct sol_str_slice *slice = sol_vector_append(vector); if (!slice) { err = CborErrorOutOfMemory; break; } err |= cbor_value_dup_text_string(&iter, (char **)&slice->data, &slice->len, NULL); } return (err | cbor_value_leave_container(array, &iter)) == CborNoError; }
/** * Attempts to find the value in map \a map that corresponds to the text string * entry \a string. If the item is found, it is stored in \a result. If no item * is found matching the key, then \a result will contain an element of type * \ref CborInvalidType. * * \note This function may be expensive to execute. */ CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element) { assert(cbor_value_is_map(map)); size_t len = strlen(string); CborError err = cbor_value_enter_container(map, element); if (err) goto error; while (!cbor_value_at_end(element)) { // find the non-tag so we can compare err = cbor_value_skip_tag(element); if (err) goto error; if (cbor_value_is_text_string(element)) { bool equals; size_t dummyLen = len; err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen, &equals, element, iterate_memcmp); if (err) goto error; if (equals) return preparse_value(element); } else { // skip this key err = cbor_value_advance(element); if (err) goto error; } // skip this value err = cbor_value_skip_tag(element); if (err) goto error; err = cbor_value_advance(element); if (err) goto error; }
SOL_API enum sol_oic_map_loop_reason sol_oic_map_loop_init(const struct sol_oic_map_reader *map, struct sol_oic_map_reader *iterator, struct sol_oic_repr_field *repr) { SOL_NULL_CHECK(map, SOL_OIC_MAP_LOOP_ERROR); SOL_NULL_CHECK(iterator, SOL_OIC_MAP_LOOP_ERROR); SOL_NULL_CHECK(repr, SOL_OIC_MAP_LOOP_ERROR); #if __STDC_VERSION__ >= 201112L static_assert(sizeof(*iterator) == sizeof(CborValue), "struct sol_oic_map_reader size must be at least the same size of " "CborValue struct defined in cbor.h header2"); #endif if (!cbor_value_is_map((CborValue *)map)) return SOL_OIC_MAP_LOOP_ERROR; if (cbor_value_enter_container((CborValue *)map, (CborValue *)iterator) != CborNoError) return SOL_OIC_MAP_LOOP_ERROR; /* Initialize repr with harmless data so cleanup works. */ repr->type = SOL_OIC_REPR_TYPE_BOOLEAN; repr->key = NULL; return SOL_OIC_MAP_LOOP_OK; }
OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload) { CborValue *rdCBORPayload = (CborValue *)cborPayload; OCStackResult ret = OC_STACK_NO_MEMORY; CborError cborFindResult; OCRDPayload *rdPayload = OCRDPayloadCreate(); VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Failed allocating rdPayload"); ret = OC_STACK_MALFORMED_RESPONSE; if (cbor_value_is_array(rdCBORPayload)) { OCLinksPayload *linksPayload = NULL; OCTagsPayload *tagsPayload = NULL; while (cbor_value_is_container(rdCBORPayload)) { // enter tags map CborValue tags; cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering tags container."); cborFindResult= OCTagsCborToPayload(&tags, &tagsPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing tags payload."); OCTagsLog(DEBUG, tagsPayload); cborFindResult = OCLinksCborToPayload(&tags, &linksPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed parsing links payload."); OCLinksLog(DEBUG, linksPayload); // Move from tags payload to links array. cborFindResult = cbor_value_advance(rdCBORPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCborPayload."); } rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdPublish, "Failed allocating rdPayload->rdPublish"); } else if (cbor_value_is_map(rdCBORPayload)) { rdPayload->rdDiscovery = (OCRDDiscoveryPayload *)OICCalloc(1, sizeof(OCRDDiscoveryPayload)); VERIFY_PARAM_NON_NULL(TAG, rdPayload->rdDiscovery, "Failed allocating discoveryPayload"); cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME, &rdPayload->rdDiscovery->n.deviceName); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_NAME."); char *deviceId = NULL; cborFindResult = FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &deviceId); if (deviceId) { memcpy(rdPayload->rdDiscovery->di.id, deviceId, strlen(deviceId)); OICFree(deviceId); } VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_DEVICE_ID."); { uint64_t value = 0; cborFindResult = FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding OC_RSRVD_RD_DISCOVERY_SEL."); rdPayload->rdDiscovery->sel = value; } cborFindResult = cbor_value_advance(rdCBORPayload); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing rdCBORPayload."); } OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); *outPayload = (OCPayload *)rdPayload; return OC_STACK_OK; exit: OCRDPayloadDestroy(rdPayload); return ret; }
static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue *objMap) { if (!outPayload) { return false; } bool err = false; if (cbor_value_is_map(objMap)) { if (!*outPayload) { *outPayload = OCRepPayloadCreate(); if(!*outPayload) { return CborErrorOutOfMemory; } } OCRepPayload* curPayload = *outPayload; size_t len; CborValue repMap; err = err || cbor_value_enter_container(objMap, &repMap); while(!err && cbor_value_is_valid(&repMap)) { char* name; err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL); err = err || cbor_value_advance(&repMap); CborType type = cbor_value_get_type(&repMap); switch(type) { case CborNullType: err = !OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: { int64_t intval = 0; err = err || cbor_value_get_int64(&repMap, &intval); if (!err) { err = !OCRepPayloadSetPropInt(curPayload, name, intval); } } break; case CborDoubleType: { double doubleval = 0; err = err || cbor_value_get_double(&repMap, &doubleval); if (!err) { err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval); } } break; case CborBooleanType: { bool boolval = false; err = err || cbor_value_get_boolean(&repMap, &boolval); if (!err) { err = !OCRepPayloadSetPropBool(curPayload, name, boolval); } } break; case CborTextStringType: { char* strval = NULL; err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL); if (!err) { err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } } break; case CborByteStringType: { uint8_t* bytestrval = NULL; err = err || cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL); if (!err) { OCByteString tmp = {.bytes = bytestrval, .len = len}; err = !OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp); } } break; case CborMapType: { OCRepPayload *pl = NULL; err = err || OCParseSingleRepPayload(&pl, &repMap); if (!err) { err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } } break; case CborArrayType: err = err || OCParseArray(curPayload, name, &repMap); break; default: OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); err = true; } if (type != CborMapType && cbor_value_is_valid(&repMap)) { err = err || cbor_value_advance(&repMap); } OICFree(name); } err = err || cbor_value_leave_container(objMap, &repMap); if(err) { OCRepPayloadDestroy(*outPayload); *outPayload = NULL; } }
static bool OCParseArrayFillArray(const CborValue* parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void* targetArray) { bool err = false; CborValue insideArray; err = err || cbor_value_enter_container(parent, &insideArray); size_t i = 0; char* tempStr = NULL; size_t tempLen = 0; OCRepPayload* tempPl = NULL; size_t newdim[MAX_REP_ARRAY_DEPTH]; newdim[0] = dimensions[1]; newdim[1] = dimensions[2]; newdim[2] = 0; while (!err && i < dimensions[0] && cbor_value_is_valid(&insideArray)) { bool noAdvance = false; if (cbor_value_get_type(&insideArray) != CborNullType) { switch (type) { case OCREP_PROP_INT: if (dimensions[1] == 0) { err = err || cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((int64_t*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { err = err || cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((double*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_BOOL: if (dimensions[1] == 0) { err = err || cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i])); } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((bool*)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_STRING: if (dimensions[1] == 0) { err = err || cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL); ((char**)targetArray)[i] = tempStr; tempStr = NULL; } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((char**)targetArray)[arrayStep(dimensions, i)]) ); } break; case OCREP_PROP_OBJECT: if (dimensions[1] == 0) { err = err || OCParseSingleRepPayload(&tempPl, &insideArray); ((OCRepPayload**)targetArray)[i] = tempPl; tempPl = NULL; noAdvance = true; } else { err = err || OCParseArrayFillArray(&insideArray, newdim, type, &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)]) ); } break; default: OC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); err = true; break; } } ++i; if (!noAdvance && cbor_value_is_valid(&insideArray)) { err = err || cbor_value_advance(&insideArray); } } return err; }
static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* rootValue) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; OCResourcePayload* resource = NULL; uint16_t resourceCount = 0; CborValue resourceMap = {}; OCDiscoveryPayload* out = OCDiscoveryPayloadCreate(); if(!out) { return OC_STACK_NO_MEMORY; } // Root value is already inside the main root array CborValue rootMap = {}; // Enter the main root map err = err || cbor_value_enter_container(rootValue, &rootMap); // Look for DI CborValue curVal = {}; err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor find value failed."); goto malformed_cbor; } size_t len; err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL); // Look for Links which will have an array as the value err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor find value failed."); goto malformed_cbor; } // Enter the links array and start iterating through the array processing // each resource which shows up as a map. err = err || cbor_value_enter_container(&curVal, &resourceMap); while (cbor_value_is_map(&resourceMap)) { resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload)); if(!resource) { OC_LOG(ERROR, TAG, "Memory allocation failed"); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } // Uri CborValue uriVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding href type failed."); goto malformed_cbor; } err = cbor_value_dup_text_string(&uriVal, &(resource->uri), &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding href value failed."); goto malformed_cbor; } // ResourceTypes CborValue rtVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding rt type failed."); goto malformed_cbor; } if (cbor_value_is_text_string(&rtVal)) { char* input = NULL; char* savePtr; err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding rt value failed."); goto malformed_cbor; } if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddResourceType(resource, trimmed)) { OICFree(resource->uri); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Interface Types CborValue ifVal = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding if type failed."); goto malformed_cbor; } if (!err && cbor_value_is_text_string(&ifVal)) { char* input = NULL; char* savePtr; err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding if value failed."); goto malformed_cbor; } if (input) { char* curPtr = strtok_r(input, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] !='\0') { if (!OCResourcePayloadAddInterface(resource, trimmed)) { OICFree(resource->uri); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Policy CborValue policyMap = {}; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding policy type failed."); goto malformed_cbor; } // Bitmap CborValue val = {}; err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding bitmap type failed."); goto malformed_cbor; } uint64_t temp = 0; err = cbor_value_get_uint64(&val, &temp); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding bitmap value failed."); goto malformed_cbor; } resource->bitmap = (uint8_t)temp; // Secure Flag err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding secure type failed."); goto malformed_cbor; } if(cbor_value_is_valid(&val)) { err = cbor_value_get_boolean(&val, &(resource->secure)); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding secure value failed."); goto malformed_cbor; } // Port CborValue port; err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &port); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding port type failed."); goto malformed_cbor; } if(cbor_value_is_valid(&port)) { err = cbor_value_get_uint64(&port, &temp); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor finding port value failed."); goto malformed_cbor; } resource->port = (uint16_t)temp; } } err = cbor_value_advance(&resourceMap); if (CborNoError != err) { OC_LOG(ERROR, TAG, "Cbor advance value failed."); goto malformed_cbor; } ++resourceCount; OCDiscoveryPayloadAddNewResource(out, resource); } err = err || cbor_value_leave_container(rootValue, &resourceMap); *outPayload = (OCPayload*)out; return OC_STACK_OK; malformed_cbor: OICFree(resource->uri); OCFreeOCStringLL(resource->types); OCFreeOCStringLL(resource->interfaces); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; cbor_error: OCDiscoveryCollectionPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; }
/* Parse single property */ static void oc_parse_rep_value(CborValue *value, oc_rep_t **rep, CborError *err) { size_t k, len; CborValue map, array; *rep = _alloc_rep(); oc_rep_t *cur = *rep, **prev = 0; cur->next = 0; cur->value_object_array = 0; /* key */ *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->name, len); *err |= cbor_value_copy_text_string(value, (char *)oc_string(cur->name), &len, NULL); *err |= cbor_value_advance(value); /* value */ switch (value->type) { case CborIntegerType: *err |= cbor_value_get_int64(value, &cur->value_int); cur->type = INT; break; case CborBooleanType: *err |= cbor_value_get_boolean(value, &cur->value_boolean); cur->type = BOOL; break; case CborDoubleType: *err |= cbor_value_get_double(value, &cur->value_double); cur->type = DOUBLE; break; case CborByteStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_byte_string( value, oc_cast(cur->value_string, uint8_t), &len, NULL); cur->type = BYTE_STRING; break; case CborTextStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_text_string(value, oc_string(cur->value_string), &len, NULL); cur->type = STRING; break; case CborMapType: /* when value is a map/object */ { oc_rep_t **obj = &cur->value_object; // object points to list of properties *err |= cbor_value_enter_container(value, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); (*obj)->next = 0; obj = &(*obj)->next; *err |= cbor_value_advance(&map); } cur->type = OBJECT; } break; case CborArrayType: *err |= cbor_value_enter_container(value, &array); len = 0; cbor_value_get_array_length(value, &len); if (len == 0) { CborValue t = array; while (!cbor_value_at_end(&t)) { len++; cbor_value_advance(&t); } } k = 0; while (!cbor_value_at_end(&array)) { switch (array.type) { case CborIntegerType: if (k == 0) { oc_new_int_array(&cur->value_array, len); cur->type = INT | ARRAY; } *err |= cbor_value_get_int64(&array, oc_int_array(cur->value_array) + k); break; case CborDoubleType: if (k == 0) { oc_new_double_array(&cur->value_array, len); cur->type = DOUBLE | ARRAY; } *err |= cbor_value_get_double(&array, oc_double_array(cur->value_array) + k); break; case CborBooleanType: if (k == 0) { oc_new_bool_array(&cur->value_array, len); cur->type = BOOL | ARRAY; } *err |= cbor_value_get_boolean(&array, oc_bool_array(cur->value_array) + k); break; case CborByteStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = BYTE_STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_byte_string( &array, (uint8_t *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborTextStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_text_string( &array, (char *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborMapType: if (k == 0) { cur->type = OBJECT | ARRAY; cur->value_object_array = _alloc_rep(); prev = &cur->value_object_array; } else { (*prev)->next = _alloc_rep(); prev = &(*prev)->next; } (*prev)->type = OBJECT; (*prev)->next = 0; oc_rep_t **obj = &(*prev)->value_object; /* Process a series of properties that make up an object of the array */ *err |= cbor_value_enter_container(&array, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); obj = &(*obj)->next; *err |= cbor_value_advance(&map); } break; default: break; } k++; *err |= cbor_value_advance(&array); } break; default: break; } }
static int cbor_internal_read_object(CborValue *root_value, const struct cbor_attr_t *attrs, const struct cbor_array_t *parent, int offset) { const struct cbor_attr_t *cursor, *best_match; char attrbuf[MYNEWT_VAL(CBORATTR_MAX_SIZE) + 1]; void *lptr; CborValue cur_value; CborError err = 0; size_t len; CborType type = CborInvalidType; /* stuff fields with defaults in case they're omitted in the JSON input */ for (cursor = attrs; cursor->attribute != NULL; cursor++) { if (!cursor->nodefault) { lptr = cbor_target_address(cursor, parent, offset); if (lptr != NULL) { switch (cursor->type) { case CborAttrIntegerType: memcpy(lptr, &cursor->dflt.integer, sizeof(long long int)); break; case CborAttrUnsignedIntegerType: memcpy(lptr, &cursor->dflt.integer, sizeof(long long unsigned int)); break; case CborAttrBooleanType: memcpy(lptr, &cursor->dflt.boolean, sizeof(bool)); break; #if FLOAT_SUPPORT case CborAttrFloatType: memcpy(lptr, &cursor->dflt.fval, sizeof(float)); break; case CborAttrDoubleType: memcpy(lptr, &cursor->dflt.real, sizeof(double)); break; #endif default: break; } } } } if (cbor_value_is_map(root_value)) { err |= cbor_value_enter_container(root_value, &cur_value); } else { err |= CborErrorIllegalType; return err; } /* contains key value pairs */ while (cbor_value_is_valid(&cur_value) && !err) { /* get the attribute */ if (cbor_value_is_text_string(&cur_value)) { if (cbor_value_calculate_string_length(&cur_value, &len) == 0) { if (len > MYNEWT_VAL(CBORATTR_MAX_SIZE)) { err |= CborErrorDataTooLarge; break; } err |= cbor_value_copy_text_string(&cur_value, attrbuf, &len, NULL); } /* at least get the type of the next value so we can match the * attribute name and type for a perfect match */ err |= cbor_value_advance(&cur_value); if (cbor_value_is_valid(&cur_value)) { type = cbor_value_get_type(&cur_value); } else { err |= CborErrorIllegalType; break; } } else { attrbuf[0] = '\0'; type = cbor_value_get_type(&cur_value); } /* find this attribute in our list */ best_match = NULL; for (cursor = attrs; cursor->attribute != NULL; cursor++) { if (valid_attr_type(type, cursor->type)) { if (cursor->attribute == CBORATTR_ATTR_UNNAMED && attrbuf[0] == '\0') { best_match = cursor; } else if (strlen(cursor->attribute) == len && !memcmp(cursor->attribute, attrbuf, len)) { break; } } } if (!cursor->attribute && best_match) { cursor = best_match; } /* we found a match */ if (cursor->attribute != NULL) { lptr = cbor_target_address(cursor, parent, offset); switch (cursor->type) { case CborAttrNullType: /* nothing to do */ break; case CborAttrBooleanType: err |= cbor_value_get_boolean(&cur_value, lptr); break; case CborAttrIntegerType: err |= cbor_value_get_int64(&cur_value, lptr); break; case CborAttrUnsignedIntegerType: err |= cbor_value_get_uint64(&cur_value, lptr); break; #if FLOAT_SUPPORT case CborAttrFloatType: err |= cbor_value_get_float(&cur_value, lptr); break; case CborAttrDoubleType: err |= cbor_value_get_double(&cur_value, lptr); break; #endif case CborAttrByteStringType: { size_t len = cursor->len; err |= cbor_value_copy_byte_string(&cur_value, lptr, &len, NULL); *cursor->addr.bytestring.len = len; break; } case CborAttrTextStringType: { size_t len = cursor->len; err |= cbor_value_copy_text_string(&cur_value, lptr, &len, NULL); break; } case CborAttrArrayType: err |= cbor_read_array(&cur_value, &cursor->addr.array); continue; case CborAttrObjectType: err |= cbor_internal_read_object(&cur_value, cursor->addr.obj, NULL, 0); continue; default: err |= CborErrorIllegalType; } } cbor_value_advance(&cur_value); } if (!err) { /* that should be it for this container */ err |= cbor_value_leave_container(root_value, &cur_value); } return err; }
static CborError OCLinksCborToPayload(CborValue *links, OCLinksPayload **linksPayload) { OCLinksPayload *setLinks = NULL; CborValue linksMap; CborValue linksArray; CborError cborFindResult = CborErrorOutOfMemory; cborFindResult = cbor_value_map_find_value(links, OC_RSRVD_LINKS, &linksArray); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding links array"); cborFindResult = cbor_value_enter_container(&linksArray, &linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container"); while (cbor_value_is_map(&linksMap)) { setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload)); VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value"); // Policy CborValue policyMap; cborFindResult = cbor_value_map_find_value(&linksMap, OC_RSRVD_POLICY, &policyMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "to find policy tag"); // Bitmap cborFindResult = FindIntInMap(&policyMap, OC_RSRVD_BITMAP, (uint64_t *) &setLinks->p); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding bitmap value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->anchor); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value"); cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, (uint64_t *) &setLinks->ins); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value"); cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_TTL, &setLinks->ttl); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ttl"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->type); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value"); if (!*linksPayload) { *linksPayload = setLinks; } else { OCLinksPayload *temp = *linksPayload; while (temp->next) { temp = temp->next; } temp->next = setLinks; } cborFindResult = cbor_value_advance(&linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map"); } return cborFindResult; exit: OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return cborFindResult; }
int cbor_read_array(struct CborValue *value, const struct cbor_array_t *arr) { CborError err = 0; struct CborValue elem; int off, arrcount; size_t len; void *lptr; char *tp; err = cbor_value_enter_container(value, &elem); if (err) { return err; } arrcount = 0; tp = arr->arr.strings.store; for (off = 0; off < arr->maxlen; off++) { switch (arr->element_type) { case CborAttrBooleanType: lptr = &arr->arr.booleans.store[off]; err |= cbor_value_get_boolean(&elem, lptr); break; case CborAttrIntegerType: lptr = &arr->arr.integers.store[off]; err |= cbor_value_get_int64(&elem, lptr); break; case CborAttrUnsignedIntegerType: lptr = &arr->arr.uintegers.store[off]; err |= cbor_value_get_uint64(&elem, lptr); break; #if FLOAT_SUPPORT case CborAttrFloatType: case CborAttrDoubleType: lptr = &arr->arr.reals.store[off]; err |= cbor_value_get_double(&elem, lptr); break; #endif case CborAttrTextStringType: len = arr->arr.strings.storelen - (tp - arr->arr.strings.store); err |= cbor_value_copy_text_string(&elem, tp, &len, NULL); arr->arr.strings.ptrs[off] = tp; tp += len + 1; break; case CborAttrStructObjectType: err |= cbor_internal_read_object(&elem, arr->arr.objects.subtype, arr, off); break; default: err |= CborErrorIllegalType; break; } arrcount++; if (arr->element_type != CborAttrStructObjectType) { err |= cbor_value_advance(&elem); } if (!cbor_value_is_valid(&elem)) { break; } } if (arr->count) { *arr->count = arrcount; } while (!cbor_value_at_end(&elem)) { err |= CborErrorDataTooLarge; cbor_value_advance(&elem); } err |= cbor_value_leave_container(value, &elem); return err; }
static CborError OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload) { CborValue linksMap; OCLinksPayload *setLinks = NULL; CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed entering links map container"); while (cbor_value_is_map(&linksMap)) { setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload)); VERIFY_PARAM_NON_NULL(TAG, setLinks, "Failed allocating setLinks"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding href value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rel value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding title value"); cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding uri value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding rt value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding itf value"); cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding mt value"); { uint64_t value = 0; cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &value); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed finding ins value"); setLinks->ins = value; } if (!*linksPayload) { *linksPayload = setLinks; } else { OCLinksPayload *temp = *linksPayload; while (temp->next) { temp = temp->next; } temp->next = setLinks; } cborFindResult = cbor_value_advance(&linksMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed advancing links map"); } return cborFindResult; exit: OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return cborFindResult; }
CborError sol_oic_decode_cbor_repr_map(CborValue *map, struct sol_vector *reprs) { struct sol_oic_repr_field *repr; CborValue value; CborError err; size_t len; if (!cbor_value_is_map(map)) return CborInvalidType; err = cbor_value_enter_container(map, &value); for (; cbor_value_is_valid(&value) && err == CborNoError; err |= cbor_value_advance(&value)) { repr = sol_vector_append(reprs); if (!repr) return CborErrorOutOfMemory; err |= cbor_value_dup_text_string(&value, (char **)&repr->key, &len, NULL); err |= cbor_value_advance(&value); switch (cbor_value_get_type(&value)) { case CborIntegerType: err |= cbor_value_get_int64(&value, &repr->v_int); repr->type = SOL_OIC_REPR_TYPE_INT; break; case CborTextStringType: err |= cbor_value_dup_text_string(&value, (char **)&repr->v_slice.data, &repr->v_slice.len, NULL); if (err != CborNoError) goto harmless; repr->type = SOL_OIC_REPR_TYPE_TEXT_STRING; break; case CborByteStringType: err |= cbor_value_dup_byte_string(&value, (uint8_t **)&repr->v_slice.data, &repr->v_slice.len, NULL); if (err != CborNoError) goto harmless; repr->type = SOL_OIC_REPR_TYPE_BYTE_STRING; break; case CborDoubleType: err |= cbor_value_get_double(&value, &repr->v_double); repr->type = SOL_OIC_REPR_TYPE_DOUBLE; break; case CborFloatType: err |= cbor_value_get_float(&value, &repr->v_float); repr->type = SOL_OIC_REPR_TYPE_FLOAT; break; case CborHalfFloatType: err |= cbor_value_get_half_float(&value, &repr->v_voidptr); repr->type = SOL_OIC_REPR_TYPE_HALF_FLOAT; break; case CborBooleanType: err |= cbor_value_get_boolean(&value, &repr->v_boolean); repr->type = SOL_OIC_REPR_TYPE_BOOLEAN; break; default: SOL_ERR("While parsing representation map, got unexpected type %d", cbor_value_get_type(&value)); if (err == CborNoError) err = CborErrorUnknownType; harmless: /* Initialize repr with harmless data so cleanup works. */ repr->v_boolean = false; repr->type = SOL_OIC_REPR_TYPE_BOOLEAN; } } return err | cbor_value_leave_container(map, &value); }
OCStackResult OCRDCborToPayload(const CborValue *cborPayload, OCPayload **outPayload) { CborValue *rdCBORPayload = (CborValue *)cborPayload; CborError cborFindResult; OCRDPayload *rdPayload = OCRDPayloadCreate(); if (!rdPayload) { goto no_memory; } if (cbor_value_is_array(rdCBORPayload)) { OCLinksPayload *linksPayload = NULL; OCTagsPayload *tagsPayload = NULL; while (cbor_value_is_container(rdCBORPayload)) { // enter tags map CborValue tags; cborFindResult = cbor_value_enter_container(rdCBORPayload, &tags); if (cborFindResult != CborNoError) { goto cbor_error; } if (OC_STACK_OK != OCTagsCborToPayload(&tags, &tagsPayload)) { OCFreeTagsResource(tagsPayload); goto cbor_error; } OCTagsLog(DEBUG, tagsPayload); if (OC_STACK_OK != OCLinksCborToPayload(&tags, &linksPayload)) { OCFreeLinksResource(linksPayload); OCFreeTagsResource(tagsPayload); goto cbor_error; } OCLinksLog(DEBUG, linksPayload); // Move from tags payload to links array. if (CborNoError != cbor_value_advance(rdCBORPayload)) { OC_LOG(DEBUG, TAG, "Failed advancing from tags payload to links."); OCFreeLinksResource(linksPayload); OCFreeTagsResource(tagsPayload); goto cbor_error; } } rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload); if (!rdPayload->rdPublish) { goto cbor_error; } } else if (cbor_value_is_map(rdCBORPayload)) { char *name = NULL; if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_NAME, &name)) { goto cbor_error; } char *id = NULL; if (CborNoError != FindStringInMap(rdCBORPayload, OC_RSRVD_DEVICE_ID, &id)) { goto cbor_error; } uint64_t biasFactor = 0; if (CborNoError != FindIntInMap(rdCBORPayload, OC_RSRVD_RD_DISCOVERY_SEL, &biasFactor)) { goto cbor_error; } rdPayload->rdDiscovery = OCRDDiscoveryPayloadCreate(name, id, (uint8_t)biasFactor); if (!rdPayload->rdDiscovery) { goto no_memory; } OICFree(id); OICFree(name); cborFindResult = cbor_value_advance(rdCBORPayload); if (CborNoError != cborFindResult) { goto cbor_error; } } OC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload); *outPayload = (OCPayload *)rdPayload; return OC_STACK_OK; no_memory: OC_LOG(ERROR, TAG, "Failed allocating memory."); OCRDPayloadDestroy(rdPayload); return OC_STACK_NO_MEMORY; cbor_error: OCRDPayloadDestroy(rdPayload); return OC_STACK_ERROR; }
OCStackResult OCParsePayload(OCPayload** outPayload, OCPayloadType payloadType, const uint8_t* payload, size_t payloadSize) { CborParser parser; CborValue rootValue; bool err = false; OC_LOG_V(INFO, TAG, "CBOR Parsing size: %d", payloadSize, payload); if((err = cbor_parser_init(payload, payloadSize, 0, &parser, &rootValue)) != false) { OC_LOG_V(ERROR, TAG, "CBOR Parser init failed: %d", err); return OC_STACK_ERROR; } if(!cbor_value_is_array(&rootValue)) { OC_LOG_V(ERROR, TAG, "CBOR payload root object is not an array :%x", rootValue.type); return OC_STACK_MALFORMED_RESPONSE; } CborValue arrayValue; // enter the array err = err || cbor_value_enter_container(&rootValue, &arrayValue); if(err || arrayValue.type != CborMapType) { OC_LOG_V(ERROR, TAG, "CBOR payload parse failed :%d", err); return OC_STACK_MALFORMED_RESPONSE; } OCStackResult result = OC_STACK_ERROR; switch(payloadType) { case PAYLOAD_TYPE_DISCOVERY: result = OCParseDiscoveryPayload(outPayload, &arrayValue); break; case PAYLOAD_TYPE_DEVICE: result = OCParseDevicePayload(outPayload, &arrayValue); break; case PAYLOAD_TYPE_PLATFORM: result = OCParsePlatformPayload(outPayload, &arrayValue); break; case PAYLOAD_TYPE_REPRESENTATION: result = OCParseRepPayload(outPayload, &arrayValue); break; case PAYLOAD_TYPE_PRESENCE: result = OCParsePresencePayload(outPayload, &arrayValue); break; case PAYLOAD_TYPE_SECURITY: result = OCParseSecurityPayload(outPayload, &arrayValue); break; default: OC_LOG_V(ERROR, TAG, "ParsePayload Type default: %d", payloadType); result = OC_STACK_ERROR; break; } if(result == OC_STACK_OK) { err = err || cbor_value_leave_container(&rootValue, &arrayValue); if(err != CborNoError) { return OC_STACK_MALFORMED_RESPONSE; } } else { OC_LOG_V(INFO, TAG, "Finished parse payload, result is %d", result); } return result; }
OCStackResult OCLinksCborToPayload(CborValue *linksArray, OCLinksPayload **linksPayload) { CborValue linksMap; CborError cborFindResult = cbor_value_enter_container(linksArray, &linksMap); if (CborNoError != cborFindResult) { OC_LOG(ERROR, TAG, "Failed enter links map"); return OC_STACK_ERROR; } while (cbor_value_is_map(&linksMap)) { OCLinksPayload *setLinks = (OCLinksPayload *)OICCalloc(1, sizeof(OCLinksPayload)); if (!setLinks) { OC_LOG(ERROR, TAG, "Failed allocating memory."); OCFreeLinksResource(*linksPayload); return OC_STACK_NO_MEMORY; } cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_HREF, &setLinks->href); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_REL, &setLinks->rel); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_TITLE, &setLinks->title); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringInMap(&linksMap, OC_RSRVD_URI, &setLinks->uri); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_RESOURCE_TYPE, &setLinks->rt); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_INTERFACE, &setLinks->itf); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } cborFindResult = FindStringLLInMap(&linksMap, OC_RSRVD_MEDIA_TYPE, &setLinks->mt); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } uint64_t temp; cborFindResult = FindIntInMap(&linksMap, OC_RSRVD_INS, &temp); if (CborNoError != cborFindResult) { OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } setLinks->ins = (uint8_t) temp; if (!*linksPayload) { *linksPayload = setLinks; } else { OCLinksPayload *temp = *linksPayload; while (temp->next) { temp = temp->next; } temp->next = setLinks; } cborFindResult = cbor_value_advance(&linksMap); if (CborNoError != cborFindResult) { OC_LOG(ERROR, TAG, "Failed advancing links map"); OCFreeLinksResource(*linksPayload); OCFreeLinksResource(setLinks); return OC_STACK_ERROR; } } return OC_STACK_OK; }
static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent) { if (!outPayload) { return false; } *outPayload = OCRepPayloadCreate(); OCRepPayload* curPayload = *outPayload; bool err = false; if(!*outPayload) { return CborErrorOutOfMemory; } size_t len; CborValue curVal; err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal); if(cbor_value_is_valid(&curVal)) { err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len, NULL); } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal); if(cbor_value_is_valid(&curVal)) { CborValue insidePropValue = {0}; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allRt = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL); char* savePtr; if (allRt) { char* curPtr = strtok_r(allRt, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddResourceType(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allRt); } err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allIf = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL); char* savePtr; if (allIf) { char* curPtr = strtok_r(allIf, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddInterface(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allIf); } } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal); if(cbor_value_is_map(&curVal)) { CborValue repMap; err = err || cbor_value_enter_container(&curVal, &repMap); while(!err && cbor_value_is_valid(&repMap)) { char* name; err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL); err = err || cbor_value_advance(&repMap); int64_t intval = 0; bool boolval = false; char* strval = NULL; double doubleval = 0; OCRepPayload* pl; switch(cbor_value_get_type(&repMap)) { case CborNullType: err = !OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: err = err || cbor_value_get_int64(&repMap, &intval); if (!err) { err = !OCRepPayloadSetPropInt(curPayload, name, intval); } break; case CborDoubleType: err = err || cbor_value_get_double(&repMap, &doubleval); if (!err) { err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval); } break; case CborBooleanType: err = err || cbor_value_get_boolean(&repMap, &boolval); if (!err) { err = !OCRepPayloadSetPropBool(curPayload, name, boolval); } break; case CborTextStringType: err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL); if (!err) { err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } break; case CborMapType: err = err || OCParseSingleRepPayload(&pl, &repMap); if (!err) { err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } break; case CborArrayType: err = err || OCParseArray(curPayload, name, &repMap); break; default: OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); err = true; } err = err || cbor_value_advance(&repMap); OICFree(name); } err = err || cbor_value_leave_container(&curVal, &repMap); } if(err) { OCRepPayloadDestroy(*outPayload); *outPayload = NULL; } return err; }