static IOTHUB_CLIENT_RESULT ProcessJsonFromTwin()

in src/adapters/pnp/PnpUtils.c [174:316]


static IOTHUB_CLIENT_RESULT ProcessJsonFromTwin(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char* payload, size_t size, PROPERTY_UPDATE_CALLBACK propertyCallback)
{
    JSON_Value* rootValue = NULL;
    JSON_Value* versionValue = NULL;
    JSON_Value* propertyValue = NULL;
    JSON_Value* childValue = NULL;
    JSON_Object* rootObject = NULL;
    JSON_Object* desiredObject = NULL;
    JSON_Object* childObject = NULL;
    size_t numChildren = 0;
    size_t numChildChildren = 0;
    int version = 0;
    char* jsonString = NULL;
    const char* componentName = NULL;
    const char* propertyName = NULL;
    IOTHUB_CLIENT_RESULT result = IOTHUB_CLIENT_OK;

    LogAssert(GetLog(), NULL != payload);

    jsonString = CopyPayloadToString(payload, size);
    if (NULL == jsonString)
    {
        OsConfigLogError(GetLog(), "ProcessJsonFromTwin: CopyPayloadToString failed");
        result = IOTHUB_CLIENT_ERROR;
    }

    if (IOTHUB_CLIENT_OK == result)
    {
        rootValue = json_parse_string(jsonString);
        if (NULL == rootValue)
        {
            OsConfigLogError(GetLog(), "ProcessJsonFromTwin: json_parse_string(root) failed");
            result = IOTHUB_CLIENT_ERROR;
        }
    }

    if (IOTHUB_CLIENT_OK == result)
    {
        rootObject = json_value_get_object(rootValue);
        if (NULL == rootObject)
        {
            OsConfigLogError(GetLog(), "ProcessJsonFromTwin: json_value_get_object(root) failed, cannot get desired object");
            result = IOTHUB_CLIENT_ERROR;
        }
    }

    if (IOTHUB_CLIENT_OK == result)
    {
        if (DEVICE_TWIN_UPDATE_COMPLETE == updateState)
        {
            OsConfigLogInfo(GetLog(), "ProcessJsonFromTwin: DEVICE_TWIN_UPDATE_COMPLETE");

            // For a complete update the JSON from IoT Hub contains both "desired" and "reported" (the full twin):
            desiredObject = json_object_get_object(rootObject, g_desiredObjectName);
        }
        else
        {
            OsConfigLogInfo(GetLog(), "ProcessJsonFromTwin: DEVICE_TWIN_UPDATE_PARTIAL");

            // For a partial update the JSON from IoT Hub skips the "desired" envelope, we need to read from root:
            desiredObject = rootObject;
        }

        if (NULL == desiredObject)
        {
            OsConfigLogError(GetLog(), "ProcessJsonFromTwin: no desired object");
            result = IOTHUB_CLIENT_ERROR;
        }
    }

    if (IOTHUB_CLIENT_OK == result)
    {
        versionValue = json_object_get_value(desiredObject, g_desiredVersion);
        if (NULL != versionValue)
        {
            if (JSONNumber == json_value_get_type(versionValue))
            {
                version = (int)json_value_get_number(versionValue);
            }
            else
            {
                OsConfigLogError(GetLog(), "ProcessJsonFromTwin: field %s type is not JSONNumber, cannot read the desired version", g_desiredVersion);
            }
        }
        else
        {
            OsConfigLogError(GetLog(), "ProcessJsonFromTwin: json_object_get_value(%s) failed, cannot read the desired version", g_desiredVersion);
        }

        numChildren = json_object_get_count(desiredObject);

        for (size_t i = 0; i < numChildren; i++)
        {
            componentName = json_object_get_name(desiredObject, i);
            childValue = json_object_get_value_at(desiredObject, i);

            if (0 == strcmp(componentName, g_desiredVersion))
            {
                // Ignore, nothing to do here
                continue;
            }

            if (JSONObject == json_type(childValue))
            {
                childObject = json_value_get_object(childValue);
                numChildChildren = json_object_get_count(childObject);

                for (size_t i = 0; i < numChildChildren; i++)
                {
                    propertyName = json_object_get_name(childObject, i);
                    propertyValue = json_object_get_value_at(childObject, i);

                    if ((NULL == propertyName) || (NULL == propertyValue))
                    {
                        OsConfigLogError(GetLog(), "ProcessJsonFromTwin: error retrieving property name and/or value from %s (child[%d])", componentName, (int)i);
                        continue;
                    }

                    if (0 == strcmp(propertyName, g_componentMarker))
                    {
                        // Ignore the marker
                        continue;
                    }

                    result = propertyCallback(componentName, propertyName, propertyValue, version);
                }
            }
        }
    }

    if (NULL != rootValue)
    {
        json_value_free(rootValue);
    }

    FREE_MEMORY(jsonString);

    UNUSED(propertyCallback);

    OsConfigLogInfo(GetLog(), "ProcessJsonFromTwin completed with %d", result);

    return result;
}