static OCStackResult OCParseDevicePayload(OCPayload **outPayload, CborValue *rootValue) { OCStackResult ret = OC_STACK_INVALID_PARAM; CborError err = CborNoError; OCDevicePayload *out = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid param outPayload"); VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid param rootValue"); *outPayload = NULL; out = (OCDevicePayload *)OICCalloc(1, sizeof(OCDevicePayload)); VERIFY_PARAM_NON_NULL(TAG, out, "Failed allocating device payload") out->base.type = PAYLOAD_TYPE_DEVICE; ret = OC_STACK_MALFORMED_RESPONSE; if (cbor_value_is_map(rootValue)) { // Device ID size_t len = 0; CborValue curVal; err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_byte_string(&curVal, &out->sid, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find device id in device payload"); } // Device Name err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find device name in device payload"); } // Device Spec Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find spec version in device payload"); } // Data Model Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find data model version in device payload"); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "to advance device payload"); *outPayload = (OCPayload *)out; return OC_STACK_OK; } exit: OCDevicePayloadDestroy(out); return ret; }
SOL_API bool sol_oic_map_loop_next(struct sol_oic_repr_field *repr, struct sol_oic_map_reader *iterator, enum sol_oic_map_loop_reason *reason) { CborError err; SOL_NULL_CHECK_GOTO(repr, err); SOL_NULL_CHECK_GOTO(iterator, err); sol_oic_repr_field_clear(repr); if (cbor_value_at_end((CborValue *)iterator)) return false; if (!cbor_value_is_valid((CborValue *)iterator)) goto err; err = sol_oic_cbor_repr_map_get_next_field((CborValue *)iterator, repr); if (err != CborNoError) goto err; return true; err: if (reason) *reason = SOL_OIC_MAP_LOOP_ERROR; return false; }
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; }
static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue) { OCStackResult ret = OC_STACK_INVALID_PARAM; OCPresencePayload *payload = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); *outPayload = NULL; payload = (OCPresencePayload *)OICCalloc(1, sizeof(OCPresencePayload)); ret = OC_STACK_NO_MEMORY; VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating presence payload"); payload->base.type = PAYLOAD_TYPE_PRESENCE; ret = OC_STACK_MALFORMED_RESPONSE; if (cbor_value_is_map(rootValue)) { CborValue curVal; // Sequence Number CborError err = cbor_value_map_find_value(rootValue, OC_RSRVD_NONCE, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce tag"); err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->sequenceNumber); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding nonce value"); // Max Age err = cbor_value_map_find_value(rootValue, OC_RSRVD_TTL, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl tag"); err = cbor_value_get_uint64(&curVal, (uint64_t *)&payload->maxAge); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding ttl value"); // Trigger err = cbor_value_map_find_value(rootValue, OC_RSRVD_TRIGGER, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger tag"); err = cbor_value_get_simple_type(&curVal, (uint8_t *)&payload->trigger); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding trigger value"); // Resource type name err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal); if (cbor_value_is_valid(&curVal)) { size_t len = 0; err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding resource type value"); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing root value"); *outPayload = (OCPayload *)payload; return OC_STACK_OK; } exit: OIC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload"); OCPresencePayloadDestroy(payload); return ret; }
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; }
static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* arrayVal) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; char * securityData = NULL; if(cbor_value_is_map(arrayVal)) { CborValue curVal; err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_REPRESENTATION, &curVal); if(cbor_value_is_valid(&curVal)) { size_t len; err = err || cbor_value_dup_text_string(&curVal, &securityData, &len, NULL); } } else { OC_LOG(ERROR, TAG, "Cbor main value not a map"); return OC_STACK_MALFORMED_RESPONSE; } err = err || cbor_value_advance(arrayVal); 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; }
static OCStackResult OCParseDevicePayload(OCPayload** outPayload, CborValue* rootValue) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; if(cbor_value_is_map(rootValue)) { uint8_t* sid = NULL; char* dname = NULL; char* specVer = NULL; char* dmVer = NULL; CborValue repVal; // Device ID err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &repVal); size_t len; if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_byte_string(&repVal, &sid, &len, NULL); } // Device Name err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &dname, &len, NULL); } // Device Spec Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &specVer, &len, NULL); } // Data Model Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &repVal); if (cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &dmVer, &len, NULL); } err = err || cbor_value_advance(rootValue); if(err) { OICFree(sid); OICFree(dname); OICFree(specVer); OICFree(dmVer); OC_LOG_V(ERROR, TAG, "CBOR in error condition %d", err); return OC_STACK_MALFORMED_RESPONSE; } *outPayload = (OCPayload*)OCDevicePayloadCreate(sid, dname, specVer, dmVer); OICFree(sid); OICFree(dname); OICFree(specVer); OICFree(dmVer); if(!*outPayload) { return OC_STACK_NO_MEMORY; } return OC_STACK_OK; } else { OC_LOG(ERROR, TAG, "Root device node was not a map"); return OC_STACK_MALFORMED_RESPONSE; } }
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; }
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; }
static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* arrayVal) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; OCDiscoveryPayload* out = OCDiscoveryPayloadCreate(); if(!out) { return OC_STACK_NO_MEMORY; } size_t resourceCount = 0; while(!err && cbor_value_is_map(arrayVal)) { OCResourcePayload* resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload)); if(!resource) { OC_LOG(ERROR, TAG, "Memory allocation failed"); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } CborValue curVal; // Uri err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_HREF, &curVal); size_t len; err = err || cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL); // SID err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_SERVER_INSTANCE_ID, &curVal); err = err || cbor_value_dup_byte_string(&curVal, &(resource->sid), &len, NULL); // Prop Tag { err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_PROPERTY, &curVal); // ResourceTypes CborValue rtVal; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &rtVal); if (!err && cbor_value_is_text_string(&rtVal)) { char* input = NULL; char* savePtr; err = err || cbor_value_dup_text_string(&rtVal, &input, &len, NULL); 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); OICFree(resource->sid); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Interface Types CborValue ifVal; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &ifVal); if (!err && cbor_value_is_text_string(&ifVal)) { char* input = NULL; char* savePtr; err = err || cbor_value_dup_text_string(&ifVal, &input, &len, NULL); 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); OICFree(resource->sid); OCFreeOCStringLL(resource->types); OICFree(resource); OCDiscoveryPayloadDestroy(out); return OC_STACK_NO_MEMORY; } } curPtr = strtok_r(NULL, " ", &savePtr); } OICFree(input); } } // Policy { CborValue policyMap; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_POLICY, &policyMap); // Bitmap CborValue val; err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val); uint64_t temp = 0; err = err || cbor_value_get_uint64(&val, &temp); resource->bitmap = (uint8_t)temp; // Secure Flag err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val); if(cbor_value_is_valid(&val)) { err = err || cbor_value_get_boolean(&val, &(resource->secure)); // Port CborValue port; err = err || cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &port); if(cbor_value_is_valid(&port)) { err = err || cbor_value_get_uint64(&port, &temp); resource->port = (uint16_t)temp; } } } } err = err || cbor_value_advance(arrayVal); if(err) { OICFree(resource->uri); OICFree(resource->sid); OCFreeOCStringLL(resource->types); OCFreeOCStringLL(resource->interfaces); OICFree(resource); OCDiscoveryPayloadDestroy(out); OC_LOG_V(ERROR, TAG, "CBOR in error condition", err); return OC_STACK_MALFORMED_RESPONSE; } ++resourceCount; OCDiscoveryPayloadAddNewResource(out, resource); } if(err) { OCDiscoveryPayloadDestroy(out); return OC_STACK_MALFORMED_RESPONSE; } else { *outPayload = (OCPayload*)out; return OC_STACK_OK; } }
static OCStackResult OCParsePresencePayload(OCPayload** outPayload, CborValue* arrayVal) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; if(cbor_value_is_map(arrayVal)) { uint64_t seqNum = 0; uint64_t maxAge = 0; OCPresenceTrigger trigger = OC_PRESENCE_TRIGGER_CREATE; char* tempStr = NULL; size_t len = 0; CborValue curVal; // Sequence Number err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_NONCE, &curVal); err = err || cbor_value_get_uint64(&curVal, &seqNum); // Max Age err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TTL, &curVal); err = err || cbor_value_get_uint64(&curVal, &maxAge); // Trigger err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_TRIGGER, &curVal); err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL); trigger = convertTriggerStringToEnum(tempStr); OICFree(tempStr); tempStr = NULL; // Resource type name err = err || cbor_value_map_find_value(arrayVal, OC_RSRVD_RESOURCE_TYPE, &curVal); if(cbor_value_is_valid(&curVal)) { err = err || cbor_value_dup_text_string(&curVal, &tempStr, &len, NULL); } err = err || cbor_value_advance(arrayVal); if(!err) { *outPayload = (OCPayload*)OCPresencePayloadCreate(seqNum, maxAge, trigger, tempStr); } OICFree(tempStr); if(err) { OCPayloadDestroy(*outPayload); OC_LOG(ERROR, TAG, "CBOR error Parse Presence Payload"); return OC_STACK_MALFORMED_RESPONSE; } if(!*outPayload) { return OC_STACK_NO_MEMORY; } return OC_STACK_OK; } else { OC_LOG(ERROR, TAG, "Root presence node was not a map"); return OC_STACK_MALFORMED_RESPONSE; } }
static CborError OCParseArrayFillArray(const CborValue *parent, size_t dimensions[MAX_REP_ARRAY_DEPTH], OCRepPayloadPropType type, void *targetArray) { CborValue insideArray; size_t i = 0; char *tempStr = NULL; OCByteString ocByteStr = { .bytes = NULL, .len = 0}; 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; CborError err = cbor_value_enter_container(parent, &insideArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to enter container"); 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 = cbor_value_get_int64(&insideArray, &(((int64_t*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((int64_t*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((double*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_BOOL: if (dimensions[1] == 0) { err = cbor_value_get_boolean(&insideArray, &(((bool*)targetArray)[i])); } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((bool*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_STRING: if (dimensions[1] == 0) { err = cbor_value_dup_text_string(&insideArray, &tempStr, &tempLen, NULL); ((char**)targetArray)[i] = tempStr; tempStr = NULL; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((char**)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_BYTE_STRING: if (dimensions[1] == 0) { err = cbor_value_dup_byte_string(&insideArray, &(ocByteStr.bytes), &(ocByteStr.len), NULL); ((OCByteString*)targetArray)[i] = ocByteStr; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((OCByteString*)targetArray)[arrayStep(dimensions, i)])); } break; case OCREP_PROP_OBJECT: if (dimensions[1] == 0) { err = OCParseSingleRepPayload(&tempPl, &insideArray, false); ((OCRepPayload**)targetArray)[i] = tempPl; tempPl = NULL; noAdvance = true; } else { err = OCParseArrayFillArray(&insideArray, newdim, type, &(((OCRepPayload**)targetArray)[arrayStep(dimensions, i)])); } break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); err = CborErrorUnknownType; break; } VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting repPayload"); } ++i; if (!noAdvance && cbor_value_is_valid(&insideArray)) { err = cbor_value_advance(&insideArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advnce insideArray"); } } exit: return err; } static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container) { void *arr = NULL; OCRepPayloadPropType type; size_t dimensions[MAX_REP_ARRAY_DEPTH]; size_t dimTotal; size_t allocSize; bool res = true; CborError err = OCParseArrayFindDimensionsAndType(container, dimensions, &type); VERIFY_CBOR_SUCCESS(TAG, err, "Array details weren't clear"); if (type == OCREP_PROP_NULL) { res = OCRepPayloadSetNull(out, name); err = (CborError) !res; VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value"); err = cbor_value_advance(container); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing container"); return err; } dimTotal = calcDimTotal(dimensions); allocSize = getAllocSize(type); arr = OICCalloc(dimTotal, allocSize); VERIFY_PARAM_NON_NULL(TAG, arr, "Array Parse allocation failed"); res = OCParseArrayFillArray(container, dimensions, type, arr); VERIFY_CBOR_SUCCESS(TAG, err, "Failed parse array"); switch (type) { case OCREP_PROP_INT: res = OCRepPayloadSetIntArrayAsOwner(out, name, (int64_t *)arr, dimensions); break; case OCREP_PROP_DOUBLE: res = OCRepPayloadSetDoubleArrayAsOwner(out, name, (double *)arr, dimensions); break; case OCREP_PROP_BOOL: res = OCRepPayloadSetBoolArrayAsOwner(out, name, (bool *)arr, dimensions); break; case OCREP_PROP_STRING: res = OCRepPayloadSetStringArrayAsOwner(out, name, (char **)arr, dimensions); break; case OCREP_PROP_BYTE_STRING: res = OCRepPayloadSetByteStringArrayAsOwner(out, name, (OCByteString *)arr, dimensions); break; case OCREP_PROP_OBJECT: res = OCRepPayloadSetPropObjectArrayAsOwner(out, name, (OCRepPayload**)arr, dimensions); break; default: OIC_LOG(ERROR, TAG, "Invalid Array type in Parse Array"); break; } err = (CborError) !res; VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting array parameter"); return CborNoError; exit: if (type == OCREP_PROP_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((char**)arr)[i]); } } if (type == OCREP_PROP_BYTE_STRING) { for(size_t i = 0; i < dimTotal; ++i) { OICFree(((OCByteString*)arr)[i].bytes); } } if (type == OCREP_PROP_OBJECT) { for(size_t i = 0; i < dimTotal; ++i) { OCRepPayloadDestroy(((OCRepPayload**)arr)[i]); } } OICFree(arr); return err; }
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; }
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 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 OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root) { OCStackResult ret = OC_STACK_INVALID_PARAM; CborError err; OCRepPayload *temp = NULL; OCRepPayload *rootPayload = NULL; OCRepPayload *curPayload = NULL; CborValue rootMap = *root; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, root, "Invalid Parameter root"); *outPayload = NULL; if (cbor_value_is_array(root)) { err = cbor_value_enter_container(root, &rootMap); } while (cbor_value_is_valid(&rootMap)) { temp = OCRepPayloadCreate(); ret = OC_STACK_NO_MEMORY; VERIFY_PARAM_NON_NULL(TAG, temp, "Failed allocating memory"); CborValue curVal; ret = OC_STACK_MALFORMED_RESPONSE; if (cbor_value_is_map(&rootMap)) { err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal); if (cbor_value_is_valid(&curVal)) { size_t len = 0; err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find uri"); } } // Resource types if (cbor_value_is_map(&rootMap)) { if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal)) { err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->types); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find rt type tag/value"); } } // Interface Types if (cbor_value_is_map(&rootMap)) { if (CborNoError == cbor_value_map_find_value(&rootMap, OC_RSRVD_INTERFACE, &curVal)) { err = OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->interfaces); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find interfaces tag/value"); } } if (cbor_value_is_map(&rootMap)) { err = OCParseSingleRepPayload(&temp, &rootMap, true); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to parse single rep payload"); } if(rootPayload == NULL) { rootPayload = temp; curPayload = temp; } else { curPayload->next = temp; curPayload = curPayload->next; } if (cbor_value_is_array(&rootMap)) { err = cbor_value_advance(&rootMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to advance single rep payload"); } } *outPayload = (OCPayload *)rootPayload; return OC_STACK_OK; exit: OCRepPayloadDestroy(temp); OCRepPayloadDestroy(rootPayload); OIC_LOG(ERROR, TAG, "CBOR error in ParseRepPayload"); return ret; }
static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *objMap, bool isRoot) { CborError err = CborUnknownError; char *name = NULL; bool res; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, objMap, "Invalid Parameter objMap"); if (cbor_value_is_map(objMap)) { if (!*outPayload) { *outPayload = OCRepPayloadCreate(); if (!*outPayload) { return CborErrorOutOfMemory; } } OCRepPayload *curPayload = *outPayload; size_t len = 0; CborValue repMap; err = cbor_value_enter_container(objMap, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap"); while (!err && cbor_value_is_valid(&repMap)) { if (cbor_value_is_text_string(&repMap)) { err = cbor_value_dup_text_string(&repMap, &name, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding tag name in the map"); err = cbor_value_advance(&repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advancing rootMap"); if (name && isRoot && ((0 == strcmp(OC_RSRVD_HREF, name)) || (0 == strcmp(OC_RSRVD_RESOURCE_TYPE, name)) || (0 == strcmp(OC_RSRVD_INTERFACE, name)))) { err = cbor_value_advance(&repMap); OICFree(name); continue; } } CborType type = cbor_value_get_type(&repMap); switch (type) { case CborNullType: res = OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: { int64_t intval = 0; err = cbor_value_get_int64(&repMap, &intval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting int value"); res = OCRepPayloadSetPropInt(curPayload, name, intval); } break; case CborDoubleType: { double doubleval = 0; err = cbor_value_get_double(&repMap, &doubleval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting double value"); res = OCRepPayloadSetPropDouble(curPayload, name, doubleval); } break; case CborBooleanType: { bool boolval = false; err = cbor_value_get_boolean(&repMap, &boolval); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting boolean value"); res = OCRepPayloadSetPropBool(curPayload, name, boolval); } break; case CborTextStringType: { char *strval = NULL; err = cbor_value_dup_text_string(&repMap, &strval, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting string value"); res = OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } break; case CborByteStringType: { uint8_t* bytestrval = NULL; err = cbor_value_dup_byte_string(&repMap, &bytestrval, &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed getting byte string value"); OCByteString tmp = {.bytes = bytestrval, .len = len}; res = OCRepPayloadSetPropByteStringAsOwner(curPayload, name, &tmp); } break; case CborMapType: { OCRepPayload *pl = NULL; err = OCParseSingleRepPayload(&pl, &repMap, false); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting parse single rep"); res = OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } break; case CborArrayType: err = OCParseArray(curPayload, name, &repMap); break; default: OIC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); res = false; } if (type != CborArrayType) { err = (CborError) !res; } VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting value"); if (type != CborMapType && cbor_value_is_valid(&repMap)) { err = cbor_value_advance(&repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed advance repMap"); } OICFree(name); name = NULL; } if (cbor_value_is_container(objMap)) { err = cbor_value_leave_container(objMap, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to leave container"); } return err; } exit: OICFree(name); OCRepPayloadDestroy(*outPayload); *outPayload = NULL; return err; }
static OCStackResult OCParsePlatformPayload(OCPayload** outPayload, CborValue* rootValue) { if (!outPayload) { return OC_STACK_INVALID_PARAM; } bool err = false; if(cbor_value_is_map(rootValue)) { OCPlatformInfo info = {0}; CborValue repVal; size_t len; // Platform ID err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL); } // MFG Name err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL); } // MFG URL err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL); } // Model Num err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL); } // Date of Mfg err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL); } // Platform Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL); } // OS Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL); } // Hardware Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL); } // Firmware Version err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL); } // Support URL err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL); } // System Time err = err || cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal); if(cbor_value_is_valid(&repVal)) { err = err || cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL); } err = err || cbor_value_advance(rootValue); if(err) { OICFree(info.dateOfManufacture); OICFree(info.firmwareVersion); OICFree(info.hardwareVersion); OICFree(info.manufacturerName); OICFree(info.manufacturerUrl); OICFree(info.modelNumber); OICFree(info.operatingSystemVersion); OICFree(info.platformID); OICFree(info.platformVersion); OICFree(info.supportUrl); OICFree(info.systemTime); OC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload"); return OC_STACK_MALFORMED_RESPONSE; } *outPayload = (OCPayload*)OCPlatformPayloadCreateAsOwner(&info); if(!*outPayload) { return OC_STACK_NO_MEMORY; } return OC_STACK_OK; } else { OC_LOG(ERROR, TAG, "Root device node was not a map"); return OC_STACK_MALFORMED_RESPONSE; } }
static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *rootValue) { OCStackResult ret = OC_STACK_INVALID_PARAM; OCResourcePayload *resource = NULL; OCDiscoveryPayload *out = NULL; size_t len = 0; CborError err = CborNoError; *outPayload = NULL; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid Parameter rootValue"); // Root value is already inside the main root array CborValue rootMap; ret = OC_STACK_NO_MEMORY; out = OCDiscoveryPayloadCreate(); VERIFY_PARAM_NON_NULL(TAG, out, "Failed error initializing discovery payload"); // Enter the main root map ret = OC_STACK_MALFORMED_RESPONSE; err = cbor_value_enter_container(rootValue, &rootMap); VERIFY_CBOR_SUCCESS(TAG, err, "to enter root map container"); // Look for DI CborValue curVal; err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag"); { err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to copy device id value"); } // BaseURI - Not a mandatory field err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &(out->baseURI), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value"); } // Look for Links which will have an array as the value CborValue linkMap; err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &linkMap); VERIFY_CBOR_SUCCESS(TAG, err, "to find links tag"); // Enter the links array and start iterating through the array processing // each resource which shows up as a map. CborValue resourceMap; err = cbor_value_enter_container(&linkMap, &resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to enter link map"); while (cbor_value_is_map(&resourceMap)) { resource = (OCResourcePayload *)OICCalloc(1, sizeof(OCResourcePayload)); VERIFY_PARAM_NON_NULL(TAG, resource, "Failed allocating resource payload"); // Uri err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag"); err = cbor_value_dup_text_string(&curVal, &(resource->uri), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "to find href value"); // ResourceTypes err = OCParseStringLL(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &resource->types); VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag/value"); // Interface Types err = OCParseStringLL(&resourceMap, OC_RSRVD_INTERFACE, &resource->interfaces); VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag/value"); // Policy CborValue policyMap; err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap); VERIFY_CBOR_SUCCESS(TAG, err, "to find policy tag"); // Bitmap err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &curVal); VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap tag"); err = cbor_value_get_int(&curVal, (int *)&resource->bitmap); VERIFY_CBOR_SUCCESS(TAG, err, "to find bitmap value"); // Secure Flag err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_get_boolean(&curVal, &(resource->secure)); VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value"); } // Port err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal); if (cbor_value_is_valid(&curVal)) { err = cbor_value_get_int(&curVal, (int *)&resource->port); VERIFY_CBOR_SUCCESS(TAG, err, "to find port value"); } err = cbor_value_advance(&resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map"); OCDiscoveryPayloadAddNewResource(out, resource); } err = cbor_value_leave_container(rootValue, &resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map"); *outPayload = (OCPayload *)out; return OC_STACK_OK; exit: OCDiscoveryResourceDestroy(resource); OCDiscoveryPayloadDestroy(out); return ret; }
static OCStackResult OCParsePlatformPayload(OCPayload **outPayload, CborValue *rootValue) { OCStackResult ret = OC_STACK_INVALID_PARAM; CborError err = CborNoError; OCPlatformInfo info = {0}; VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload"); if (cbor_value_is_map(rootValue)) { CborValue repVal; size_t len = 0; ret = OC_STACK_MALFORMED_RESPONSE; // Platform ID err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformID in the platform payload"); } // MFG Name err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureName in the platform payload"); } // MFG URL err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find manufactureUrl in the platform payload"); } // Model Num err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find modelNumber in the platform payload"); } // Date of Mfg err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find dateOfManufacture in the platform payload"); } // Platform Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find platformVersion in the platform payload"); } // OS Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find OSVersion in the platform payload"); } // Hardware Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find HWVersion in the platform payload"); } // Firmware Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find firmwareVersion in the platform payload"); } // Support URL err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload"); } // System Time err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find systemTume in the platform payload"); } err = cbor_value_advance(rootValue); VERIFY_CBOR_SUCCESS(TAG, err, "Failed to find supportUrl in the platform payload"); *outPayload = (OCPayload *)OCPlatformPayloadCreateAsOwner(&info); return OC_STACK_OK; } exit: OCPlatformInfoDestroy(&info); OIC_LOG(ERROR, TAG, "CBOR error In ParsePlatformPayload"); 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; } }
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); }