OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
{
    // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation
    // strategy to work.  If you receive the following assertion error, please do a git-pull
    // from the extlibs/tinycbor/tinycbor directory
    #define CborNeedsUpdating  (CborErrorOutOfMemory < CborErrorDataTooLarge)
    OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0");
    #undef CborNeedsUpdating

    OCStackResult ret = OC_STACK_INVALID_PARAM;
    int64_t err;
    uint8_t *out = NULL;
    size_t curSize = INIT_SIZE;

    VERIFY_PARAM_NON_NULL(TAG, payload, "Input param, payload is NULL");
    VERIFY_PARAM_NON_NULL(TAG, outPayload, "OutPayload parameter is NULL");
    VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL");

    OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
    if (PAYLOAD_TYPE_SECURITY == payload->type)
    {
        size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize;
        if (securityPayloadSize > 0)
        {
            out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize);
            VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload");
        }
    }
    if (out == NULL)
    {
        out = (uint8_t *)OICCalloc(1, curSize);
        VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload");
    }
    err = OCConvertPayloadHelper(payload, out, &curSize);
    ret = OC_STACK_NO_MEMORY;

    if (err == CborErrorOutOfMemory)
    {
        // reallocate "out" and try again!
        uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
        VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
        out = out2;
        err = OCConvertPayloadHelper(payload, out, &curSize);
        while (err == CborErrorOutOfMemory)
        {
            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
            out = out2;
            err = OCConvertPayloadHelper(payload, out, &curSize);
        }
    }

    if (err == CborNoError)
    {
        if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type)
        {
            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
            out = out2;
        }

        *size = curSize;
        *outPayload = out;
        OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size);
        OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size);
        return OC_STACK_OK;
    }

    //TODO: Proper conversion from CborError to OCStackResult.
    ret = (OCStackResult)-err;

exit:
    OICFree(out);
    return ret;
}
Exemple #2
0
OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
{
    // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation
    // strategy to work.  If you receive the following assertion error, please do a git-pull
    // from the extlibs/tinycbor/tinycbor directory
    #define CborNeedsUpdating  (CborErrorOutOfMemory < CborErrorDataTooLarge)
    OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0");
    #undef CborNeedsUpdating
    if (!payload)
    {
        OC_LOG(ERROR, TAG, "Payload parameter NULL");
        return OC_STACK_INVALID_PARAM;
    }

    if (!outPayload || !size)
    {
        OC_LOG(ERROR, TAG, "Out parameter/s parameter NULL");
        return OC_STACK_INVALID_PARAM;
    }

    OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);

    size_t curSize = INIT_SIZE;
    uint8_t* out = (uint8_t*)OICCalloc(1, curSize);
    int64_t err = OCConvertPayloadHelper(payload, out, &curSize);

    if (err == CborErrorOutOfMemory)
    {
        // reallocate "out" and try again!
        uint8_t* out2 = (uint8_t*)OICRealloc(out, curSize);

        if (!out2)
        {
            OICFree(out);
            return OC_STACK_NO_MEMORY;
        }

        out = out2;
        err = OCConvertPayloadHelper(payload, out, &curSize);
    }

    if (err == 0)
    {
        if (curSize < INIT_SIZE)
        {
            uint8_t* out2 = (uint8_t*)OICRealloc(out, curSize);

            if (!out2)
            {
                OICFree(out);
                return OC_STACK_NO_MEMORY;
            }

            out = out2;
        }

        *size = curSize;
        *outPayload = out;
        return OC_STACK_OK;
    }
    else if (err < 0)
    {
        return (OCStackResult)-err;
    }
    else
    {
        return OC_STACK_ERROR;
    }
}