int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
{
    int64_t cborEncoderResult = CborErrorIO;
    int flags = 0;
    CborEncoder encoder;
    VERIFY_PARAM_NON_NULL(TAG, rdPayload, "Invalid input parameter rdPayload");
    VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid input parameter outPayload");
    VERIFY_PARAM_NON_NULL(TAG, size, "Invalid input parameter size");

    cbor_encoder_init(&encoder, outPayload, *size, flags);

    if (rdPayload->rdDiscovery)
    {
        CborEncoder map;
        cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create discovery map");

        cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME,
            rdPayload->rdDiscovery->n.deviceName);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_NAME in map");

        cborEncoderResult |= ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID,
            (char *)rdPayload->rdDiscovery->di.id);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add OC_RSRVD_DEVICE_ID in map");

        {
            uint64_t value = rdPayload->rdDiscovery->sel;
            cborEncoderResult |= ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL, &value);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add RD_DISCOVERY_SEL in map");
        }
        cborEncoderResult |= cbor_encoder_close_container(&encoder, &map);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map");
    }
    else if (rdPayload->rdPublish)
    {
        CborEncoder colArray;
        cborEncoderResult |= cbor_encoder_create_array(&encoder, &colArray, CborIndefiniteLength);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create collection array");

        OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
        while (rdPublish)
        {
            cborEncoderResult |= OCTagsPayloadToCbor(rdPublish->tags, &colArray);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding tags payload");
            cborEncoderResult |= OCLinksPayloadToCbor(rdPublish->setLinks, &colArray);
            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding setLinks payload");
            rdPublish = rdPublish->next;
        }
        cborEncoderResult |= cbor_encoder_close_container(&encoder, &colArray);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing collection array");
    }
    else
    {
        CborEncoder map;
        cborEncoderResult |= cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed entering discovery map");
        cborEncoderResult |= cbor_encoder_close_container(&encoder, &map);
        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing discovery map");
    }

    if (cborEncoderResult == CborErrorOutOfMemory)
    {
        *size += encoder.ptr - encoder.end;
    }
    else
    {
        *size = encoder.ptr - outPayload;
    }

    return cborEncoderResult;

exit:
    OICFree(outPayload);
    return cborEncoderResult;
}
예제 #2
0
int64_t OCRDPayloadToCbor(const OCRDPayload *rdPayload, uint8_t *outPayload, size_t *size)
{
    if (!outPayload || !size)
    {
        OC_LOG(ERROR, TAG, "Invalid parameters.");
        return OC_STACK_INVALID_PARAM;
    }

    CborEncoder encoder;
    int flags = 0;
    cbor_encoder_init(&encoder, outPayload, *size, flags);

    CborEncoder rootArray;
    CborError cborEncoderResult;
    cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, CBOR_ROOT_ARRAY_LENGTH);
    if (CborNoError != cborEncoderResult)
    {
        OC_LOG(ERROR, TAG, "Failed creating cbor array.");
        goto cbor_error;
    }

    if (rdPayload->rdDiscovery)
    {
        CborEncoder map;
        cborEncoderResult = cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed creating discovery map.");
            goto cbor_error;
        }
        if (CborNoError != ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_NAME,
                sizeof(OC_RSRVD_DEVICE_NAME) - 1, (char *)rdPayload->rdDiscovery->n.deviceName))
        {
            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_DEVICE_NAME.");
            goto cbor_error;
        }
        if (CborNoError != ConditionalAddTextStringToMap(&map, OC_RSRVD_DEVICE_ID,
                sizeof(OC_RSRVD_DEVICE_ID) - 1, (char *)rdPayload->rdDiscovery->di.id))
        {
            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_DEVICE_ID.");
            goto cbor_error;
        }
        uint64_t sel = (uint8_t) rdPayload->rdDiscovery->sel;
        if (CborNoError != ConditionalAddIntToMap(&map, OC_RSRVD_RD_DISCOVERY_SEL,
            sizeof(OC_RSRVD_RD_DISCOVERY_SEL) - 1, &sel))
        {
            OC_LOG(ERROR, TAG, "Failed setting OC_RSRVD_RD_DISCOVERY_SEL.");
            goto cbor_error;
        }
        cborEncoderResult = cbor_encoder_close_container(&rootArray, &map);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed closing discovery map.");
            goto cbor_error;
        }
    }
    else if (rdPayload->rdPublish)
    {
        CborEncoder colArray;
        cborEncoderResult = cbor_encoder_create_array(&rootArray, &colArray, CborIndefiniteLength);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed creating collection array.");
            goto cbor_error;
        }

        OCResourceCollectionPayload *rdPublish = rdPayload->rdPublish;
        while (rdPublish)
        {
            if (OC_STACK_OK != OCTagsPayloadToCbor(rdPublish->tags, &colArray))
            {
                OC_LOG(ERROR, TAG, "Failed creating tags payload.");
                goto cbor_error;
            }
            if (OC_STACK_OK != OCLinksPayloadToCbor(rdPublish->setLinks, &colArray))
            {
                OC_LOG(ERROR, TAG, "Failed creating links payload.");
                goto cbor_error;
            }
            rdPublish = rdPublish->next;
        }
        cborEncoderResult = cbor_encoder_close_container(&rootArray, &colArray);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed closing collection array.");
            goto cbor_error;
        }
    }
    cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
    if (CborNoError != cborEncoderResult)
    {
        OC_LOG(ERROR, TAG, "Failed closing root array container. ");
        goto cbor_error;
    }

    *size = encoder.ptr - outPayload;
    return OC_STACK_OK;

cbor_error:
    OICFree(outPayload);
    return OC_STACK_ERROR;
}
예제 #3
0
static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t* outPayload,
        size_t* size)
{
    CborEncoder encoder = {0};
    CborEncoder rootArray = {0};
    int64_t err = 0;

    cbor_encoder_init(&encoder, outPayload, *size, 0);

    if (payload->collectionResources)
    {
        CborError cborEncoderResult;
        cborEncoderResult = cbor_encoder_create_array(&encoder, &rootArray, DISCOVERY_CBOR_ARRAY_LEN);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed creating root array.");
            goto cbor_error;
        }

        CborEncoder colArray;
        cborEncoderResult = cbor_encoder_create_array(&rootArray, &colArray, CborIndefiniteLength);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed creating collection array.");
            goto cbor_error;
        }
        OCResourceCollectionPayload *colResources = payload->collectionResources;
        while (colResources)
        {
            if (OC_STACK_OK != OCTagsPayloadToCbor(colResources->tags, &colArray))
            {
                goto cbor_error;
            }
            if (OC_STACK_OK != OCLinksPayloadToCbor(colResources->setLinks, &colArray))
            {
                goto cbor_error;
            }
            colResources = colResources->next;
        }
        cborEncoderResult = cbor_encoder_close_container(&rootArray, &colArray);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed closing collection array.");
            goto cbor_error;
        }
        cborEncoderResult = cbor_encoder_close_container(&encoder, &rootArray);
        if (CborNoError != cborEncoderResult)
        {
            OC_LOG(ERROR, TAG, "Failed closing root array.");
            goto cbor_error;
        }
    }
    else if (payload->resources)
    {
        size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
        err = err | cbor_encoder_create_array(&encoder, &rootArray, resourceCount);

        for(size_t i = 0; i < resourceCount; ++i)
        {
            CborEncoder map;
            OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
            if(!resource)
            {
                OICFree(outPayload);
                return OC_STACK_INVALID_PARAM;
            }

            err = err | cbor_encoder_create_map(&rootArray, &map, DISCOVERY_CBOR_RES_MAP_LEN);

            // Device ID
            err = err | cbor_encode_text_string(&map, OC_RSRVD_DEVICE_ID,
                    sizeof(OC_RSRVD_DEVICE_ID) - 1);
            err = err | cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);

            {
                CborEncoder linkArray;
                err = err | cbor_encode_text_string(&map, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) -1);
                err = err | cbor_encoder_create_array(&map, &linkArray, CborIndefiniteLength);

                // Link Map
                {
                    CborEncoder linkMap;
                    err = err | cbor_encoder_create_map(&linkArray, &linkMap, DISCOVERY_CBOR_LINKS_MAP_LEN);

                    // Uri
                    err = err | AddTextStringToMap(&linkMap, OC_RSRVD_HREF,
                            sizeof(OC_RSRVD_HREF) - 1,
                            resource->uri);
                    // Resource Type
                    if (resource->types)
                    {
                        char* joinedTypes = OCStringLLJoin(resource->types);
                        if (joinedTypes)
                        {
                            err = err | cbor_encode_text_string(&linkMap, OC_RSRVD_RESOURCE_TYPE,
                                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
                            err = err | cbor_encode_text_string(&linkMap, joinedTypes,
                                    strlen(joinedTypes));
                            OICFree(joinedTypes);
                        }
                        else
                        {
                            return OC_STACK_NO_MEMORY;
                        }
                    }
                    // Interface Types
                    if (resource->interfaces)
                    {
                        char* joinedInterfaces = OCStringLLJoin(resource->interfaces);
                        if (joinedInterfaces)
                        {
                            err = err | cbor_encode_text_string(&linkMap, OC_RSRVD_INTERFACE,
                                    sizeof(OC_RSRVD_INTERFACE) - 1);
                            err = err | cbor_encode_text_string(&linkMap, joinedInterfaces,
                                    strlen(joinedInterfaces));
                            OICFree(joinedInterfaces);
                        }
                        else
                        {
                            return OC_STACK_NO_MEMORY;
                        }
                    }
                    // Policy
                    {
                        CborEncoder policyMap;
                        err = err | cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY,
                                sizeof(OC_RSRVD_POLICY) - 1);
                        err = err | cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength);

                        // Bitmap
                        err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
                                sizeof(OC_RSRVD_BITMAP) - 1);
                        err = err | cbor_encode_uint(&policyMap, resource->bitmap);

                        if(resource->secure)
                        {
                            err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
                                    sizeof(OC_RSRVD_SECURE) - 1);
                            err = err | cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);

                            if(resource->port != 0)
                            {
                                err = err | cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
                                        sizeof(OC_RSRVD_HOSTING_PORT) - 1);
                                err = err | cbor_encode_uint(&policyMap, resource->port);
                            }
                        }

                        err = err | cbor_encoder_close_container(&linkMap, &policyMap);
                    }
                    // Close
                    err = err | cbor_encoder_close_container(&linkArray, &linkMap);
                }
                err = err | cbor_encoder_close_container(&map, &linkArray);
            }
            err = err | cbor_encoder_close_container(&rootArray, &map);
        }
        // Close main array
        err = err | cbor_encoder_close_container(&encoder, &rootArray);
    }

    return checkError(err, &encoder, outPayload, size);
cbor_error:
    OICFree(outPayload);
    return OC_STACK_ERROR;
}