CODEFIRST_RESULT CodeFirst_SendAsyncReported()

in serializer/src/codefirst.c [1313:1458]


CODEFIRST_RESULT CodeFirst_SendAsyncReported(unsigned char** destination, size_t* destinationSize, size_t numReportedProperties, ...)
{
    CODEFIRST_RESULT result;
    if ((destination == NULL) || (destinationSize == NULL) || numReportedProperties == 0)
    {
        LogError("invalid argument unsigned char** destination=%p, size_t* destinationSize=%p, size_t numReportedProperties=%lu", destination, destinationSize, (unsigned long)numReportedProperties);
        result = CODEFIRST_INVALID_ARG;
    }
    else
    {
        (void)CodeFirst_Init_impl(NULL, false);/*lazy init*/

        DEVICE_HEADER_DATA* deviceHeader = NULL;
        size_t i;
        REPORTED_PROPERTIES_TRANSACTION_HANDLE transaction = NULL;
        va_list ap;
        result = CODEFIRST_ACTION_EXECUTION_ERROR; /*this initialization squelches a false warning about result not being initialized*/

        va_start(ap, numReportedProperties);

        for (i = 0; i < numReportedProperties; i++)
        {
            void* value = (void*)va_arg(ap, void*);
            if (value == NULL)
            {
                LogError("argument number %lu passed through variable arguments is NULL", (unsigned long)i);
                result = CODEFIRST_INVALID_ARG;
                break;
            }
            else
            {
                DEVICE_HEADER_DATA* currentValueDeviceHeader = FindDevice(value);
                if (currentValueDeviceHeader == NULL)
                {
                    result = CODEFIRST_INVALID_ARG;
                    LOG_CODEFIRST_ERROR;
                    break;
                }
                else if ((deviceHeader != NULL) &&
                    (currentValueDeviceHeader != deviceHeader))
                {
                    result = CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR;
                    LOG_CODEFIRST_ERROR;
                    break;
                }
                else if ((deviceHeader == NULL) &&
                    ((transaction = Device_CreateTransaction_ReportedProperties(currentValueDeviceHeader->DeviceHandle)) == NULL))
                {
                    result = CODEFIRST_DEVICE_PUBLISH_FAILED;
                    LOG_CODEFIRST_ERROR;
                    break;
                }
                else
                {
                    deviceHeader = currentValueDeviceHeader;
                    if (value == ((unsigned char*)deviceHeader->data))
                    {
                        result = SendAllDeviceReportedProperties(deviceHeader, transaction);
                        if (result != CODEFIRST_OK)
                        {
                            LOG_CODEFIRST_ERROR;
                            break;
                        }
                    }
                    else
                    {
                        const REFLECTED_SOMETHING* propertyReflectedData;
                        const char* modelName;

                        STRING_HANDLE valuePath;
                        if ((valuePath = STRING_new()) == NULL)
                        {
                            result = CODEFIRST_ERROR;
                            LOG_CODEFIRST_ERROR;
                            break;
                        }
                        else
                        {
                            modelName = Schema_GetModelName(deviceHeader->ModelHandle);

                            if ((propertyReflectedData = FindReportedProperty(deviceHeader, value, modelName, 0, valuePath)) == NULL)
                            {
                                result = CODEFIRST_INVALID_ARG;
                                LOG_CODEFIRST_ERROR;
                                STRING_delete(valuePath);
                                break;
                            }
                            else
                            {
                                AGENT_DATA_TYPE agentDataType;
                                if (propertyReflectedData->what.reportedProperty.Create_AGENT_DATA_TYPE_from_Ptr(value, &agentDataType) != AGENT_DATA_TYPES_OK)
                                {
                                    result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
                                    LOG_CODEFIRST_ERROR;
                                    STRING_delete(valuePath);
                                    break;
                                }
                                else
                                {
                                    if (Device_PublishTransacted_ReportedProperty(transaction, STRING_c_str(valuePath), &agentDataType) != DEVICE_OK)
                                    {
                                        Destroy_AGENT_DATA_TYPE(&agentDataType);
                                        result = CODEFIRST_DEVICE_PUBLISH_FAILED;
                                        LOG_CODEFIRST_ERROR;
                                        STRING_delete(valuePath);
                                        break;
                                    }
                                    else
                                    {
                                        STRING_delete(valuePath);
                                    }
                                    Destroy_AGENT_DATA_TYPE(&agentDataType);
                                }
                            }
                        }
                    }
                }
            }
        }

        if (i < numReportedProperties)
        {
            if (transaction != NULL)
            {
                Device_DestroyTransaction_ReportedProperties(transaction);
            }
        }
        else
        {
            if (Device_CommitTransaction_ReportedProperties(transaction, destination, destinationSize) != DEVICE_OK)
            {
                result = CODEFIRST_DEVICE_PUBLISH_FAILED;
                LOG_CODEFIRST_ERROR;
            }
            else
            {
                result = CODEFIRST_OK;
            }

            Device_DestroyTransaction_ReportedProperties(transaction);
        }

        va_end(ap);
    }
    return result;
}