Ejemplo n.º 1
0
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;
}
static CborError FindIntInMap(const CborValue *map, const char *tags, uint64_t *value)
{
    CborValue curVal;
    CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
    if (CborNoError == cborFindResult && cbor_value_is_unsigned_integer(&curVal))
    {
        cborFindResult = cbor_value_get_uint64(&curVal, value);
    }
    return cborFindResult;
}
Ejemplo n.º 3
0
static CborError FindIntInMap(CborValue *map, char *tags, uint64_t *value)
{
    CborValue curVal;
    CborError cborFindResult = cbor_value_map_find_value(map, tags, &curVal);
    if (CborNoError == cborFindResult && cbor_value_is_unsigned_integer(&curVal))
    {
        cborFindResult = cbor_value_get_uint64(&curVal, value);
        if (CborNoError != cborFindResult)
        {
            OC_LOG_V(ERROR, TAG, "Failed finding value for tag %s .", tags);
            return cborFindResult;
        }
    }
    return CborNoError;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
    }
}
Ejemplo n.º 6
0
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;
    }
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}