This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Azure Iot hub: client_connect can fail and leave internal state set incorrectly, resulting in all subsequent calls to azure_iot_hub_connect failing.

azure_iot_hub_connect does the following check:

int azure_iot_hub_connect(void)
{
	if (connection_state != STATE_INIT) {
		LOG_ERR("Azure IoT Hub is not initialized");
		return -EACCES;
	}

	return connect_client(&conn_config);
}

connect_client looks like this:

static int connect_client(struct azure_iot_hub_config *cfg)
{
	int err;
	bool use_dps =
		IS_ENABLED(CONFIG_AZURE_IOT_HUB_DPS) &&
		(dps_get_reg_state() != DPS_STATE_REGISTERED);
	struct azure_iot_hub_evt evt = {
		.type = AZURE_IOT_HUB_EVT_CONNECTING,
	};

#if IS_ENABLED(CONFIG_AZURE_IOT_HUB_DPS)
	if (use_dps) {
		evt.type = AZURE_IOT_HUB_EVT_DPS_CONNECTING;

		err = dps_start();
		if (err == -EALREADY) {
			use_dps = false;
			LOG_INF("The device is already registered to IoT hub");
		} else if (err == -EFAULT) {
			LOG_ERR("Failed to start DPS");
			return err;
		}
	}
#endif /* IS_ENABLED(CONFIG_AZURE_IOT_HUB_DPS) */

	err = client_broker_init(&client, use_dps);
	if (err) {
		LOG_ERR("client_broker_init, error: %d", err);
		return err;
	}

	connection_state = STATE_CONNECTING;

	/* Notify _CONNECTING event, either to IoT hub or DPS */
	azure_iot_hub_notify_event(&evt);

	err = mqtt_connect(&client);
	if (err) {
		LOG_ERR("mqtt_connect, error: %d", err);
		return err;
	}

	/* Set the current socket and start reading from it in polling thread */
	conn_config.socket = client.transport.tls.sock;

	k_sem_give(&connection_poll_sem);

	return 0;
}

If the embedded return at line 40 of connect_client occurs (as I've seen it do) then subsequent calls to azure_iot_hub_connect will fail.

I've fixed this by setting connection_state = STATE_INIT  just before the return at line 40, but I wonder if this is the most correct way to do this?

Regards,

Josh

Parents Reply Children
No Data
Related