IOTHUB_DEVICE_HANDLE IoTHubTransport_AMQP_Common_Register()

in iothub_client/src/iothubtransport_amqp_common.c [2034:2162]


IOTHUB_DEVICE_HANDLE IoTHubTransport_AMQP_Common_Register(TRANSPORT_LL_HANDLE handle, const IOTHUB_DEVICE_CONFIG* device, PDLIST_ENTRY waitingToSend)
{
    IOTHUB_DEVICE_HANDLE result;

    if ((handle == NULL) || (device == NULL) || (waitingToSend == NULL))
    {
        LogError("invalid parameter TRANSPORT_LL_HANDLE handle=%p, const IOTHUB_DEVICE_CONFIG* device=%p, PDLIST_ENTRY waiting_to_send=%p",
            handle, device, waitingToSend);
        result = NULL;
    }
    else if (device->deviceId == NULL)
    {
        LogError("Transport failed to register device (device_id provided is NULL)");
        result = NULL;
    }
    else
    {
        LIST_ITEM_HANDLE list_item;
        AMQP_TRANSPORT_INSTANCE* transport_instance = (AMQP_TRANSPORT_INSTANCE*)handle;

        if (is_device_registered_ex(transport_instance->registered_devices, device->deviceId, &list_item))
        {
            LogError("IoTHubTransport_AMQP_Common_Register failed (device '%s' already registered on this transport instance)", MU_P_OR_NULL(device->deviceId));
            result = NULL;
        }
        else if (!is_device_credential_acceptable(device, transport_instance->preferred_authentication_mode))
        {
            LogError("Transport failed to register device '%s' (device credential was not accepted)", MU_P_OR_NULL(device->deviceId));
            result = NULL;
        }
        else
        {
            AMQP_TRANSPORT_DEVICE_INSTANCE* amqp_device_instance;

            if ((amqp_device_instance = (AMQP_TRANSPORT_DEVICE_INSTANCE*)malloc(sizeof(AMQP_TRANSPORT_DEVICE_INSTANCE))) == NULL)
            {
                LogError("Transport failed to register device '%s' (failed to create the device state instance; malloc failed)", MU_P_OR_NULL(device->deviceId));
                result = NULL;
            }
            else
            {
                memset(amqp_device_instance, 0, sizeof(AMQP_TRANSPORT_DEVICE_INSTANCE));

                amqp_device_instance->transport_instance = transport_instance;
                amqp_device_instance->waiting_to_send = waitingToSend;
                amqp_device_instance->device_state = DEVICE_STATE_STOPPED;
                amqp_device_instance->max_state_change_timeout_secs = DEFAULT_DEVICE_STATE_CHANGE_TIMEOUT_SECS;
                amqp_device_instance->subscribe_methods_needed = false;
                amqp_device_instance->subscribed_for_methods = false;
                amqp_device_instance->is_quota_exceeded = false;  
                amqp_device_instance->transport_ctx = transport_instance->transport_ctx;
                amqp_device_instance->transport_callbacks = transport_instance->transport_callbacks;

                if ((amqp_device_instance->device_id = STRING_construct(device->deviceId)) == NULL)
                {
                    LogError("Transport failed to register device '%s' (failed to copy the deviceId)", MU_P_OR_NULL(device->deviceId));
                    result = NULL;
                }
                else
                {
                    AMQP_DEVICE_CONFIG device_config;
                    (void)memset(&device_config, 0, sizeof(AMQP_DEVICE_CONFIG));
                    device_config.iothub_host_fqdn = (char*)STRING_c_str(transport_instance->iothub_host_fqdn);
                    device_config.authorization_module = device->authorization_module;

                    device_config.authentication_mode = get_authentication_mode(device);
                    device_config.on_state_changed_callback = on_device_state_changed_callback;
                    device_config.on_state_changed_context = amqp_device_instance;
                    device_config.prod_info_cb = transport_instance->transport_callbacks.prod_info_cb;
                    device_config.prod_info_ctx = transport_instance->transport_ctx;

                    if ((amqp_device_instance->device_handle = amqp_device_create(&device_config)) == NULL)
                    {
                        LogError("Transport failed to register device '%s' (failed to create the DEVICE_HANDLE instance)", MU_P_OR_NULL(device->deviceId));
                        result = NULL;
                    }
                    else
                    {
                        bool is_first_device_being_registered = (singlylinkedlist_get_head_item(transport_instance->registered_devices) == NULL);

                        amqp_device_instance->methods_handle = iothubtransportamqp_methods_create(STRING_c_str(transport_instance->iothub_host_fqdn), device->deviceId, device->moduleId);
                        if (amqp_device_instance->methods_handle == NULL)
                        {
                            LogError("Transport failed to register device '%s' (Cannot create the methods module)", MU_P_OR_NULL(device->deviceId));
                            result = NULL;
                        }
                        else
                        {
                            if (replicate_device_options_to(amqp_device_instance, device_config.authentication_mode) != RESULT_OK)
                            {
                                LogError("Transport failed to register device '%s' (failed to replicate options)", MU_P_OR_NULL(device->deviceId));
                                result = NULL;
                            }
                            else if (singlylinkedlist_add(transport_instance->registered_devices, amqp_device_instance) == NULL)
                            {
                                LogError("Transport failed to register device '%s' (singlylinkedlist_add failed)", MU_P_OR_NULL(device->deviceId));
                                result = NULL;
                            }
                            else
                            {
                                if (transport_instance->preferred_authentication_mode == AMQP_TRANSPORT_AUTHENTICATION_MODE_NOT_SET &&
                                    is_first_device_being_registered)
                                {
                                    if (device_config.authentication_mode == DEVICE_AUTH_MODE_CBS)
                                    {
                                        transport_instance->preferred_authentication_mode = AMQP_TRANSPORT_AUTHENTICATION_MODE_CBS;
                                    }
                                    else
                                    {
                                        transport_instance->preferred_authentication_mode = AMQP_TRANSPORT_AUTHENTICATION_MODE_X509;
                                    }
                                }

                                result = (IOTHUB_DEVICE_HANDLE)amqp_device_instance;
                            }
                        }
                    }
                }

                if (result == NULL)
                {
                    internal_destroy_amqp_device_instance(amqp_device_instance);
                }
            }
        }
    }

    return result;
}