Example #1
0
static CborError OCParseStringLL(CborValue *map, char *type, OCStringLL **resource)
{
    CborValue val;
    CborError err = cbor_value_map_find_value(map, type, &val);
    VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL TAG");

    if (cbor_value_is_text_string(&val))
    {
        char *input = NULL;
        char *savePtr = NULL;
        size_t len = 0;

        err = cbor_value_dup_text_string(&val, &input, &len, NULL);
        VERIFY_CBOR_SUCCESS(TAG, err, "to find StringLL value");

        if (input)
        {
            char *curPtr = strtok_r(input, " ", &savePtr);
            while (curPtr)
            {
                char *trimmed = InPlaceStringTrim(curPtr);
                if (trimmed[0] !='\0')
                {
                    if (!OCResourcePayloadAddStringLL(resource, trimmed))
                    {
                        return CborErrorOutOfMemory;
                    }
                }
                curPtr = strtok_r(NULL, " ", &savePtr);
            }
            OICFree(input);
        }
    }
exit:
    return err;
}
static OCStackResult OCParseDiscoveryPayload(OCPayload** outPayload, CborValue* rootValue)
{
    if (!outPayload)
    {
        return OC_STACK_INVALID_PARAM;
    }

    bool err = false;
    OCResourcePayload* resource = NULL;
    uint16_t resourceCount = 0;
    CborValue resourceMap = {};

    OCDiscoveryPayload* out = OCDiscoveryPayloadCreate();
    if(!out)
    {
        return OC_STACK_NO_MEMORY;
    }

    // Root value is already inside the main root array
    CborValue rootMap = {};

    // Enter the main root map
    err = err || cbor_value_enter_container(rootValue, &rootMap);
    // Look for DI
    CborValue curVal = {};
    err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_ID, &curVal);
    if (CborNoError != err)
    {
        OC_LOG(ERROR, TAG, "Cbor find value failed.");
        goto malformed_cbor;
    }
    size_t len;
    err = cbor_value_dup_byte_string(&curVal, &(out->sid), &len, NULL);

    // Look for Links which will have an array as the value
    err = cbor_value_map_find_value(&rootMap, OC_RSRVD_LINKS, &curVal);
    if (CborNoError != err)
    {
        OC_LOG(ERROR, TAG, "Cbor find value failed.");
        goto malformed_cbor;
    }

    // Enter the links array and start iterating through the array processing
    // each resource which shows up as a map.
    err = err || cbor_value_enter_container(&curVal, &resourceMap);

    while (cbor_value_is_map(&resourceMap))
    {
        resource = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
        if(!resource)
        {
            OC_LOG(ERROR, TAG, "Memory allocation failed");
            OCDiscoveryPayloadDestroy(out);
            return OC_STACK_NO_MEMORY;
        }

        // Uri
        CborValue uriVal = {};
        err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_HREF, &uriVal);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding href type failed.");
            goto malformed_cbor;
        }
        err = cbor_value_dup_text_string(&uriVal, &(resource->uri), &len, NULL);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding href value failed.");
            goto malformed_cbor;
        }
        // ResourceTypes
        CborValue rtVal = {};
        err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_RESOURCE_TYPE, &rtVal);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding rt type failed.");
            goto malformed_cbor;
        }
        if (cbor_value_is_text_string(&rtVal))
        {
            char* input = NULL;
            char* savePtr;
            err = cbor_value_dup_text_string(&rtVal, &input, &len, NULL);
            if (CborNoError != err)
            {
                OC_LOG(ERROR, TAG, "Cbor finding rt value failed.");
                goto malformed_cbor;
            }
            if (input)
            {
                char* curPtr = strtok_r(input, " ", &savePtr);

                while (curPtr)
                {
                    char* trimmed = InPlaceStringTrim(curPtr);
                    if (trimmed[0] !='\0')
                    {
                        if (!OCResourcePayloadAddResourceType(resource, trimmed))
                        {
                            OICFree(resource->uri);
                            OCFreeOCStringLL(resource->types);
                            OICFree(resource);
                            OCDiscoveryPayloadDestroy(out);
                            return OC_STACK_NO_MEMORY;
                        }
                    }
                    curPtr = strtok_r(NULL, " ", &savePtr);
                }
                OICFree(input);
            }
        }

        // Interface Types
        CborValue ifVal = {};
        err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_INTERFACE, &ifVal);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding if type failed.");
            goto malformed_cbor;
        }
        if (!err && cbor_value_is_text_string(&ifVal))
        {
            char* input = NULL;
            char* savePtr;
            err = cbor_value_dup_text_string(&ifVal, &input, &len, NULL);
            if (CborNoError != err)
            {
                OC_LOG(ERROR, TAG, "Cbor finding if value failed.");
                goto malformed_cbor;
            }
            if (input)
            {
                char* curPtr = strtok_r(input, " ", &savePtr);

                while (curPtr)
                {
                    char* trimmed = InPlaceStringTrim(curPtr);
                    if (trimmed[0] !='\0')
                    {
                        if (!OCResourcePayloadAddInterface(resource, trimmed))
                        {
                            OICFree(resource->uri);
                            OCFreeOCStringLL(resource->types);
                            OICFree(resource);
                            OCDiscoveryPayloadDestroy(out);
                            return OC_STACK_NO_MEMORY;
                        }
                    }
                    curPtr = strtok_r(NULL, " ", &savePtr);
                }
                OICFree(input);
            }
        }

        // Policy
        CborValue policyMap = {};
        err = cbor_value_map_find_value(&resourceMap, OC_RSRVD_POLICY, &policyMap);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding policy type failed.");
            goto malformed_cbor;
        }
        // Bitmap
        CborValue val = {};
        err = cbor_value_map_find_value(&policyMap, OC_RSRVD_BITMAP, &val);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding bitmap type failed.");
            goto malformed_cbor;
        }
        uint64_t temp = 0;
        err = cbor_value_get_uint64(&val, &temp);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding bitmap value failed.");
            goto malformed_cbor;
        }
        resource->bitmap = (uint8_t)temp;
        // Secure Flag
        err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &val);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor finding secure type failed.");
            goto malformed_cbor;
        }
        if(cbor_value_is_valid(&val))
        {
            err = cbor_value_get_boolean(&val, &(resource->secure));
            if (CborNoError != err)
            {
                OC_LOG(ERROR, TAG, "Cbor finding secure value failed.");
                goto malformed_cbor;
            }
            // Port
            CborValue port;
            err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT,
                                            &port);
            if (CborNoError != err)
            {
                OC_LOG(ERROR, TAG, "Cbor finding port type failed.");
                goto malformed_cbor;
            }
            if(cbor_value_is_valid(&port))
            {
                err = cbor_value_get_uint64(&port, &temp);
                if (CborNoError != err)
                {
                    OC_LOG(ERROR, TAG, "Cbor finding port value failed.");
                    goto malformed_cbor;
                }
                resource->port = (uint16_t)temp;
            }
        }

        err = cbor_value_advance(&resourceMap);
        if (CborNoError != err)
        {
            OC_LOG(ERROR, TAG, "Cbor advance value failed.");
            goto malformed_cbor;
        }
        ++resourceCount;
        OCDiscoveryPayloadAddNewResource(out, resource);
    }

    err = err || cbor_value_leave_container(rootValue, &resourceMap);

    *outPayload = (OCPayload*)out;
    return OC_STACK_OK;

malformed_cbor:
    OICFree(resource->uri);
    OCFreeOCStringLL(resource->types);
    OCFreeOCStringLL(resource->interfaces);
    OICFree(resource);
    OCDiscoveryPayloadDestroy(out);
    return OC_STACK_MALFORMED_RESPONSE;

cbor_error:
    OCDiscoveryCollectionPayloadDestroy(out);
    return OC_STACK_MALFORMED_RESPONSE;
}
Example #3
0
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;
}
Example #4
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;
    }
}