static int64_t OCConvertArrayItem(CborEncoder* array, const OCRepPayloadValueArray* valArray, size_t index) { int64_t err = 0; switch (valArray->type) { case OCREP_PROP_NULL: OC_LOG(ERROR, TAG, "ConvertArray Invalid NULL"); err = CborUnknownError; break; case OCREP_PROP_INT: err = err | cbor_encode_int(array, valArray->iArray[index]); break; case OCREP_PROP_DOUBLE: err = err | cbor_encode_double(array, valArray->dArray[index]); break; case OCREP_PROP_BOOL: err = err | cbor_encode_boolean(array, valArray->bArray[index]); break; case OCREP_PROP_STRING: if (!valArray->strArray[index]) { err = err | cbor_encode_null(array); } else { err = err | cbor_encode_text_string(array, valArray->strArray[index], strlen(valArray->strArray[index])); } break; case OCREP_PROP_BYTE_STRING: if (!valArray->strArray[index]) { err = err | cbor_encode_null(array); } else { err = err | cbor_encode_byte_string(array, valArray->ocByteStrArray[index].bytes, valArray->ocByteStrArray[index].len); } break; case OCREP_PROP_OBJECT: if (!valArray->objArray[index]) { err = err | cbor_encode_null(array); } else { err = OCConvertSingleRepPayload(array, valArray->objArray[index]); } break; case OCREP_PROP_ARRAY: OC_LOG(ERROR, TAG, "ConvertArray Invalid child array"); err = CborUnknownError; break; } return err; }
static int64_t OCConvertRepMap(CborEncoder *map, const OCRepPayload *payload) { int64_t err = CborNoError; CborEncoder repMap; err |= cbor_encoder_create_map(map, &repMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating rep map"); err |= OCConvertSingleRepPayload(&repMap, payload); VERIFY_CBOR_SUCCESS(TAG, err, "Failed converting single rep payload"); err |= cbor_encoder_close_container(map, &repMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing rep map"); exit: return err; }
static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray) { CborEncoder array; bool err = false; err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength); err = err || cbor_encode_uint(&array, valArray->type); for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i) { err = err || cbor_encode_uint(&array, valArray->dimensions[i]); } size_t dimTotal = calcDimTotal(valArray->dimensions); for(size_t i = 0; i < dimTotal; ++i) { switch(valArray->type) { case OCREP_PROP_NULL: OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL")); err = CborUnknownError; break; case OCREP_PROP_INT: err = err || cbor_encode_int(&array, valArray->iArray[i]); break; case OCREP_PROP_DOUBLE: err = err || cbor_encode_double(&array, valArray->dArray[i]); break; case OCREP_PROP_BOOL: err = err || cbor_encode_boolean(&array, valArray->bArray[i]); break; case OCREP_PROP_STRING: err = err || cbor_encode_text_string(&array, valArray->strArray[i], strlen(valArray->strArray[i])); break; case OCREP_PROP_OBJECT: err = OCConvertSingleRepPayload(&array, valArray->objArray[i]); break; case OCREP_PROP_ARRAY: OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array")); err = CborUnknownError; break; } } err = err || cbor_encoder_close_container(parent, &array); return err; }
static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size) { *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH); *size = MAX_REQUEST_LENGTH; if(!*outPayload) { return OC_STACK_NO_MEMORY; } CborEncoder encoder = {}; bool err = false; cbor_encoder_init(&encoder, *outPayload, *size, 0); CborEncoder rootArray; err = err || cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength); err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_REPRESENTATION); while(payload != NULL && !err) { err = err || OCConvertSingleRepPayload(&rootArray, payload); payload = payload->next; } // Close main array err = err || cbor_encoder_close_container(&encoder, &rootArray); if(err) { OC_LOG_V(ERROR, TAG, "Convert Rep Payload failed with : %d", err); return OC_STACK_ERROR; } *size = encoder.ptr - *outPayload; uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size); if(!tempPayload) { OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!")); OICFree(*outPayload); return OC_STACK_ERROR; } *outPayload = tempPayload; return OC_STACK_OK; }
static int64_t OCConvertRepPayload(OCRepPayload* payload, uint8_t* outPayload, size_t* size) { CborEncoder encoder = {0}; int64_t err = 0; cbor_encoder_init(&encoder, outPayload, *size, 0); CborEncoder rootArray; err = err | cbor_encoder_create_array(&encoder, &rootArray, CborIndefiniteLength); while(payload != NULL && (err == 0 || err == CborErrorOutOfMemory)) { err = err | OCConvertSingleRepPayload(&rootArray, payload); payload = payload->next; } // Close main array err = err | cbor_encoder_close_container(&encoder, &rootArray); return checkError(err, &encoder, outPayload, size); }
static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, size_t *size) { CborEncoder encoder; int64_t err = CborNoError; cbor_encoder_init(&encoder, outPayload, *size, 0); size_t arrayCount = 0; for (OCRepPayload *temp = payload; temp; temp = temp->next) { arrayCount++; } CborEncoder rootArray; if (arrayCount > 1) { err |= cbor_encoder_create_array(&encoder, &rootArray, arrayCount); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep root map"); } while (payload != NULL && (err == CborNoError)) { CborEncoder rootMap; err |= cbor_encoder_create_map(((arrayCount == 1)? &encoder: &rootArray), &rootMap, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating root map"); // Only in case of collection href is included. if (arrayCount > 1 && payload->uri && strlen(payload->uri) > 0) { OIC_LOG(INFO, TAG, "Payload has uri"); err |= cbor_encode_text_string(&rootMap, OC_RSRVD_HREF, strlen(OC_RSRVD_HREF)); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep href tag"); err |= cbor_encode_text_string(&rootMap, payload->uri, strlen(payload->uri)); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep href value"); } if (payload->types) { OIC_LOG(INFO, TAG, "Payload has types"); err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->types); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type."); } if (payload->interfaces) { OIC_LOG(INFO, TAG, "Payload has interfaces"); err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->interfaces); VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface type."); } err |= OCConvertSingleRepPayload(&rootMap, payload); VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting rep payload"); // Close main array err |= cbor_encoder_close_container(((arrayCount == 1) ? &encoder: &rootArray), &rootMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map"); payload = payload->next; } if (arrayCount > 1) { err |= cbor_encoder_close_container(&encoder, &rootArray); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array"); } exit: return checkError(err, &encoder, outPayload, size); }
static int64_t OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload) { int64_t err = 0; CborEncoder map; err = err | cbor_encoder_create_map(parent, &map, CborIndefiniteLength); // Uri err = err | ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, payload->uri); // Prop Map // resource types, interfaces if(payload->types || payload->interfaces) { OC_LOG(INFO, TAG, "Payload has types or interfaces"); err = err | cbor_encode_text_string(&map, OC_RSRVD_PROPERTY, sizeof(OC_RSRVD_PROPERTY) - 1); CborEncoder propMap; err = err | cbor_encoder_create_map(&map, &propMap, CborIndefiniteLength); if (payload->types) { char* joinedTypes = OCStringLLJoin(payload->types); if (joinedTypes) { err = err | cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1); err = err | cbor_encode_text_string(&propMap, joinedTypes, strlen(joinedTypes)); OICFree(joinedTypes); } else { return OC_STACK_NO_MEMORY; } } if (payload->interfaces) { char* joinedInterfaces = OCStringLLJoin(payload->interfaces); if (joinedInterfaces) { err = err | cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1); err = err | cbor_encode_text_string(&propMap, joinedInterfaces, strlen(joinedInterfaces)); OICFree(joinedInterfaces); } else { return OC_STACK_NO_MEMORY; } } err = err | cbor_encoder_close_container(&map, &propMap); } // Rep Map { CborEncoder repMap; err = err | cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1); err = err | cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); OCRepPayloadValue* value = payload->values; while(value) { err = err | cbor_encode_text_string(&repMap, value->name, strlen(value->name)); switch(value->type) { case OCREP_PROP_NULL: err = err | cbor_encode_null(&repMap); break; case OCREP_PROP_INT: err = err | cbor_encode_int(&repMap, value->i); break; case OCREP_PROP_DOUBLE: err = err | cbor_encode_double(&repMap, value->d); break; case OCREP_PROP_BOOL: err = err | cbor_encode_boolean(&repMap, value->b); break; case OCREP_PROP_STRING: err = err | cbor_encode_text_string(&repMap, value->str, strlen(value->str)); break; case OCREP_PROP_BYTE_STRING: err = err | cbor_encode_byte_string(&repMap, value->ocByteStr.bytes, value->ocByteStr.len); break; case OCREP_PROP_OBJECT: err = err | OCConvertSingleRepPayload(&repMap, value->obj); break; case OCREP_PROP_ARRAY: err = err | OCConvertArray(&repMap, &value->arr); break; default: OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d", value->type); break; } value = value->next; } err = err | cbor_encoder_close_container(&map, &repMap); } // Close Map err = err | cbor_encoder_close_container(parent, &map); return err; }
static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload) { bool err = false; CborEncoder map; err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength); // Uri err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1, payload->uri); // Prop Map // resource types, interfaces if(payload->types || payload->interfaces) { OC_LOG_V(INFO, TAG, "Payload has types or interfaces"); err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY, sizeof(OC_RSRVD_PROPERTY) - 1); CborEncoder propMap; err = err || cbor_encoder_create_map(&map, &propMap, 2); CborEncoder curArray; if(payload->types) { err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_RESOURCE_TYPE) - 1); err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); OCStringLL* val = payload->types; while(val) { err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value)); val = val->next; } err = err || cbor_encoder_close_container(&propMap, &curArray); } if(payload->interfaces) { err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1); err = err || cbor_encoder_create_array(&propMap, &curArray, CborIndefiniteLength); OCStringLL* val = payload->interfaces; while(val) { err = err || cbor_encode_text_string(&curArray, val->value, strlen(val->value)); val = val->next; } err = err || cbor_encoder_close_container(&propMap, &curArray); } err = err || cbor_encoder_close_container(&map, &propMap); } // Rep Map { CborEncoder repMap; err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION, sizeof(OC_RSRVD_REPRESENTATION) - 1); err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength); OCRepPayloadValue* value = payload->values; while(value) { err = err || cbor_encode_text_string(&repMap, value->name, strlen(value->name)); switch(value->type) { case OCREP_PROP_NULL: err = err || cbor_encode_null(&repMap); break; case OCREP_PROP_INT: err = err || cbor_encode_int(&repMap, value->i); break; case OCREP_PROP_DOUBLE: err = err || cbor_encode_double(&repMap, value->d); break; case OCREP_PROP_BOOL: err = err || cbor_encode_boolean(&repMap, value->b); break; case OCREP_PROP_STRING: err = err || cbor_encode_text_string(&repMap, value->str, strlen(value->str)); break; case OCREP_PROP_OBJECT: err = err || OCConvertSingleRepPayload(&repMap, value->obj); break; case OCREP_PROP_ARRAY: err = err || OCConvertArray(&repMap, &value->arr); break; default: OC_LOG_V(ERROR, TAG, "Invalid Prop type: %d", value->type); break; } value = value->next; } err = err || cbor_encoder_close_container(&map, &repMap); } // Close Map err = err || cbor_encoder_close_container(parent, &map); return err; }