Azure IoT Hub

The Azure IoT Hub library provides an API to connect to an Azure IoT Hub instance and interact with it. It connects to Azure IoT Hub using MQTT over TLS.

Optionally, the library supports Azure IoT Hub Device Provisioning Service (DPS). DPS can be enabled at compile time to make use of the device provisioning services for onboarding of devices to Azure IoT Hub. When the device provisioning is complete, the library automatically connects to the assigned Azure IoT Hub.

The library also has integrated support for a proprietary FOTA solution. For more information on Azure FOTA, see the documentation on Azure FOTA library and Azure IoT Hub sample.

The library uses Azure SDK for Embedded C for message processing and other operations. For more information on how Azure SDK for Embedded C is integrated in this library, see Azure SDK for Embedded C IoT client libraries.

Important

If the server sends a device-bound message when the device is unavailable for a period of time, for instance while in LTE Power Saving Mode, the server will most likely terminate the TCP connection. This will result in additional data traffic as the device has to reconnect to the server, which in turn requires a new TLS handshake and MQTT connection establishment.

Setup and configuration

To connect a device to Azure IoT Hub, complete the following steps:

  1. Setting up Azure IoT Hub

  2. Authenticate Azure CLI

  3. Create an IoT Hub

  4. Device Provisioning Service (optional)

  5. Generating certificates

  6. Register a device in Azure IoT Hub

  7. Provision root CA certificates

Setting up Azure IoT Hub

If you do not have an Azure account, you need to create one.

To get started with testing the Azure IoT Hub, make sure that the following prerequisites are met:

  • Install the Azure CLI.

  • To use the nrfcredstore tool, the dependencies in the nrf/scripts/requirements-extra.txt file must be installed.

Authenticate Azure CLI

Authenticate the Azure CLI tool to use your Azure account in the default browser with the following command:

az login

For other authentication options, see the Sign in with Azure CLI documentation.

Create an IoT Hub

  1. When creating an IoT Hub, you must create it in a resource group. You can create a resource group through Azure’s CLI using the following command:

    az group create --name <resource_name> --location westus
    

    If you want to use another region than westus, you can acquire a list of the available locations by running the following command:

    az account list-locations -o table
    
  2. To create an IoT Hub, use the following command, select the resource group you created, and create a unique name for your IoT Hub:

    az iot hub create --resource-group <resource_name> --name <hub_name> --sku F1 --partition-count 2
    

    Using F1 as an argument creates a free IoT Hub, which allows you to have only one instance. Hence, delete your existing free IoT Hub or change the SKU to S1.

For information on how to set up creating an Azure IoT Hub instance using the Azure portal, see Creating an Azure IoT Hub instance using the Azure portal.

Device Provisioning Service (optional)

Azure IoT Hub DPS is a helper service for IoT Hub that enables just-in-time provisioning to the right IoT hub without pre-registering each device manually.

The alternative is to register each device manually with the IoT Hub and hard-code the IoT Hub hostname in the device firmware.

When using DPS, make sure to select the DPS tabs in the following sections of this document.

To use DPS, you need to set up an Azure IoT Hub Device Provisioning Service (DPS) instance with the following commands:

  • To create the DPS instance:

    az iot dps create --name <dps_name> --resource-group <resource_name>
    
  • To link the IoT Hub to the DPS instance:

    az iot dps linked-hub create --dps-name <dps_name> --hub-name <hub_name> --resource-group <resource_name>
    

Generating certificates

The connection to the Azure IoT Hub with MQTT is secured using TLS. To create the device certificate, you need a Certificate Authority (CA) certificate and a private key that is used to sign all of your client certificates. The CA certificate is uploaded to Azure IoT Hub, so Azure can verify that the device certificate is signed by your CA. If you do not have a CA certificate, you can purchase one or make a self-signed test CA certificate for testing purposes.

To help generate test CA certificates and handle the device keys and certificates, you can use the nrf/scripts/cert_tool.py Python script. Either call the script relative from the current working directory or add it to the path.

Note

The cert_tool.py Python script has default values for all actions for the input and output file names. See the available arguments by running the --help argument to the script.

Generate test CA certificates

  • To generate the root CA certificate, use the following command:

    cert_tool.py root_ca
    

    This command generates a self-signed root CA certificate and private key and saves them to the files ca/root-ca-cert.pem and ca/root-ca-key.pem.

  • To generate the subordinate CA certificate, use the following command:

    cert_tool.py sub_ca
    

    This command generates a subordinate CA certificate (signed by the root CA) and private key and saves them to the files ca/sub-ca-cert.pem and ca/sub-ca-key.pem.

Proof of possession

To prove possession of the root CA key, you need to sign a verification code using the root CA certificate and upload the resulting certificate to Azure.

With individual enrollment, you need to upload and verify the root CA certificate with the IoT hub. When using DPS, you need to upload and verify the root CA certificate with the DPS instance.

To perform proof of possession of the root CA key, you can verify the root CA certificate using the following set of commands:

  • To upload root CA certificate:

    az iot hub certificate create --hub-name <hub_name> --name <cert_name> --path ca/root-ca-cert.pem
    
  • To ask Azure for a verification code (need two output values):

    az iot hub certificate generate-verification-code --hub-name <hub_name> --name <cert_name> --etag "<etag_from_prev_command>"
    

Note down the verification code and etag for later use.

  • To generate a new private key:

    cert_tool.py client_key
    
  • To Create a CSR with the verification code as common name:

    cert_tool.py csr --common-name <verification_code>
    
  • To Sign the CSR with the root CA:

    cert_tool.py sign_root
    
  • To Upload the verification certificate:

    az iot hub certificate verify --hub-name <hub_name> --name <cert_name> --etag "<etag_from_generate_verification_code>" --path certs/client-cert.pem
    

Generate and provision device certificates

The following are the ways to generate and register device certificates:

  • The device key and certificate are generated using the cert_tool.py script and provisioned to the device.

  • The device generates a key and a Certificate Signing Request (CSR). This method is more secure because the private key never leaves the device.

When the private key is generated inside the modem, it is never exposed to the outside world. This is more secure than generating a private key using a script. By default, the Common Name (CN) of the certificate is set to the device UUID, and the CN is read out by Azure to identify the device during the TLS handshake. This allows using the exact same firmware on many devices without hard-coding the device ID into the firmware because the device UUID can be read out at runtime. See the Azure IoT Hub sample for more information on how to read out the device UUID in the application.

Note

Generating a key pair on device requires an nRF91 Series device. If you are using an nRF9160 DK, modem version v1.3.x or later is required.

Important

Program the Cellular: AT Client sample to your device before following this guide.

Complete the following steps to generate a key pair and CSR on the modem, which is then signed using your CA and uploaded to Azure:

  1. Obtain a list of installed keys using the following command:

    nrfcredstore <serial port> list
    

    where <serial port> is the serial port of your device.

  2. Select a security tag that is not yet in use. This security tag must match the value set in the CONFIG_MQTT_HELPER_SEC_TAG Kconfig option.

  3. Generate a key pair and obtain a CSR using the following command:

    nrfcredstore <serial port> generate <sec tag> certs/client-csr.der
    

    where <serial port> is the serial port of your device and <sec tag> is the previously chosen unused security tag.

  4. Convert the CSR from DER format to PEM format using the following command:

    openssl req -inform DER -in certs/client-csr.der -outform PEM -out certs/client-csr.pem
    
  5. Sign the CSR using the subordinate CA certificate using the following command:

    cert_tool.py sign
    

    Note

    This process might vary depending on the CA you are using. See the documentation for your CA for more information on how to sign a CSR.

  6. Take note of the CN, as it will be required later.

    In case you got the certificate from a CA, you can extract the CN using the following command:

    openssl x509 -in certs/client-cert.pem -noout -subject
    
  7. Combine the device certificate and the subordinate CA certificate chain into a single file using the following command:

    cat certs/client-cert.pem ca/sub-ca-cert.pem > certs/client-cert-chain.pem
    

    This is necessary for Azure to verify the certificate chain.

  8. Provision the certificate to the modem using the following command:

    nrfcredstore <serial port> write <sec tag> CLIENT_CERT certs/client-cert-chain.pem
    

    where <serial port> is the serial port of your device and <sec tag> is the previously chosen unused security tag.

Register a device in Azure IoT Hub

Important

The device ID must match the CN of the certificate.

To register a new device in your IoT hub, use the following command:

az iot hub device-identity create -n <iothub_name> -d <device_id> --am x509_ca

Provision root CA certificates

The Azure IoT Hub library requires provisioning of the following certificates and a private key for a successful TLS connection:

  1. DigiCert Global Root G2 - The root CA certificate used to verify the server’s certificate chain while connecting.

  2. Baltimore CyberTrust Root Certificate - Azure’s legacy root CA certificate needed to verify the Azure server’s that have not migrated to DigiCert Global Root G2 yet.

  3. Device certificate - Generated by the procedures described in Generate and provision device certificates, used by Azure IoT Hub to authenticate the device.

  4. Private key of the device.

Important

Azure has started the process of migrating their DPS server certificates from Baltimore CyberTrust Root Certificate to DigiCert Global Root G2. Azure IoT Hub servers have finished this transition, and only DigiCert Global Root G2 is used now for those connections. Azure advises to have both Baltimore CyberTrust Root and DigiCert Global Root G2 certificates for all devices to avoid disruption of service during the transition. Refer to Azure IoT TLS: Critical changes for updated information and timeline. Due to this, it is recommended to provision the Baltimore CyberTrust Root Certificate to a secondary security tag set by the CONFIG_MQTT_HELPER_SECONDARY_SEC_TAG option. This ensures that the device can also connect after the transition.

To provision the certificates, use any of the following methods, depending on the DK you are using.

Important

Program the Cellular: AT Client sample to your device before following this guide and make sure you have nrfcredstore installed.

  1. Obtain a list of installed keys using the following command:

    nrfcredstore <serial port> list
    

    where <serial port> is the serial port of your device.

  2. Provision the server root CA certificates, which you downloaded previously, by running the following commands:

    nrfcredstore <serial port> write <sec tag> ROOT_CA_CERT DigiCertGlobalRootG2.crt.pem
    
    nrfcredstore <serial port> write <secondary sec tag> ROOT_CA_CERT BaltimoreCyberTrustRoot.crt.pem
    

The chosen security tag while provisioning the certificates must be the same as the security tag configured by the CONFIG_MQTT_HELPER_SEC_TAG option.

If more than one root server certificate is used, the second one can be provisioned to a different security tag and configured in the application using the CONFIG_MQTT_HELPER_SECONDARY_SEC_TAG Kconfig option. The modem checks both security tags if necessary when verifying the server’s certificate.

Configuring the library

You can configure the library to connect to Azure IoT Hub with or without using DPS. For both methods, you need to set the device ID, or registration ID, and the security tag used to store the certificates.

The following Kconfig options are common for both methods:

  1. Set the CONFIG_AZURE_IOT_HUB Kconfig option to y to enable the Azure IoT Hub library.

  2. Set the CONFIG_MQTT_HELPER_SEC_TAG Kconfig option to the security tag used while provisioning root CA certificates.

  3. Set the CONFIG_MQTT_HELPER_SECONDARY_SEC_TAG Kconfig option to the security tag of the extra root CA certificate until all Azure services have migrated to DigiCert Global Root G2.

To connect to Azure IoT Hub without using DPS, complete the following minimum required configuration:

  1. To retrieve your IoT Hub hostname, run the following command:

    az iot hub show --name <hub_name> --query "properties.hostName"
    
  2. Configure the CONFIG_AZURE_IOT_HUB_HOSTNAME Kconfig option to the returned address.

    You can also set the host name at runtime.

Device ID and Registration ID

The device ID is used to identify the device in the Azure IoT Hub. Registration ID is used to identify the device on the DPS server. The Azure IoT Hub sample uses the device ID as the registration ID when registering with the DPS server.

For testing on one device, you can manually configure the device ID with the CONFIG_AZURE_IOT_HUB_DEVICE_ID Kconfig option.

When running the same firmware on multiple devices, it is not practical to hard-code the registration ID. Instead, enable the use of a unique hardware identifier, such as the device UUID, as the registration ID. The hardware identifier of the device needs to match the CN in the certificate on the device.

Note

When using hardware identifiers in the Azure IoT Hub sample, set the CONFIG_AZURE_IOT_HUB_SAMPLE_DEVICE_ID_USE_HW_ID Kconfig option to y.

CONFIG_MODEM_JWT=y
CONFIG_HW_ID_LIBRARY_SOURCE_UUID=y

You can also set the device ID at runtime by populating the device_id member of the azure_iot_hub_config structure passed to the azure_iot_hub_connect() function when connecting. If the device_id.size buffer size is zero, the compile-time option CONFIG_AZURE_IOT_HUB_DEVICE_ID is used.

Application integration

This section describes how to initialize the library, use the DPS service, and connect to Azure IoT Hub.

Initializing the library

To initialize the library, call the azure_iot_hub_init() function. The initialization must be successful to make the other APIs in the library available for the application. An event handler is passed as the only argument to the azure_iot_hub_init() function. The library calls this function with data associated to the application, such as incoming data and other events. For an exhaustive list of event types and associated data, see azure_iot_hub_evt_type.

Using the Device Provisioning Service

You can use the Azure IoT Hub Device Provisioning Service to provision the device to an IoT Hub. When the registration process has completed successfully, the device receives its assigned hostname and device ID to use when connecting to Azure IoT Hub. The assigned host name and device ID are stored to the non-volatile memory on the device and are available also after a reset and power outage.

This code example shows how to configure and use DPS:

static void dps_handler(enum azure_iot_hub_dps_reg_status state)
{
   switch (state) {
   case AZURE_IOT_HUB_DPS_REG_STATUS_NOT_STARTED:
      LOG_INF("AZURE_IOT_HUB_DPS_REG_STATUS_NOT_STARTED");
      break;
   case AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNING:
      LOG_INF("AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNING");
      break;
   case AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNED:
      LOG_INF("AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNED");

      /* Act on assignment */
      k_sem_give(&dps_assigned_sem);
      break;
   case AZURE_IOT_HUB_DPS_REG_STATUS_FAILED:
      LOG_INF("ZURE_IOT_HUB_DPS_REG_STATUS_FAILED");

      /* Act on registration failure */
      k_sem_give(&dps_registration_failed_sem);
      break;
   default:
      LOG_WRN("Unhandled DPS registration status: %d", state);
      break;
   }
}

...

int err;
struct azure_iot_hub_buf assigned_hostname;
struct azure_iot_hub_buf assigned_device_id;
     struct azure_iot_hub_dps_config dps_cfg = {
             .handler = dps_handler,

   /* Can be left out to use CONFIG_AZURE_IOT_HUB_DPS_REG_ID instead. */
             .reg_id = {
                     .ptr = device_id_buf,
                     .size = device_id_len,
             },

   /* Can be left out to use CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE instead. */
   .id_scope = {
                     .ptr = id_scope_buf,
                     .size = id_scope_len,
             },
     };

     err = azure_iot_hub_dps_init(&dps_cfg);
/* Error handling */

err = azure_iot_hub_dps_start();
     if (err == 0) {
             LOG_INF("The DPS process has started");

   /* Wait for the registration process to complete. */
   err = k_sem_take(&dps_done_sem, K_SECONDS(SOME_TIMEOUT));
   /* Error handling */
     } else if (err == -EALREADY) {
             LOG_INF("Already assigned to an IoT hub, skipping DPS");
     } else {
   /* Error handling */
     }
     err = azure_iot_hub_dps_hostname_get(assigned_hostname);
/* Error handling */

     err = azure_iot_hub_dps_device_id_get(assigned_device_id);
/* Error handling */

/* Use the hostname and device ID to connect to IoT Hub. */

After the device has been successfully registered, the application can proceed to connect to the assigned IoT Hub using the obtained device ID.

When a device has been assigned to an IoT Hub and the information is stored to the non-volatile memory, the DPS APIs always return the stored information and do not trigger a new registration. To delete the stored assignment information, call the azure_iot_hub_dps_reset() function. Alternatively, you can call the functions azure_iot_hub_dps_hostname_delete() or azure_iot_hub_dps_device_id_delete() to delete specific information. After calling the azure_iot_hub_dps_reset() function, the library must be initialized again. After the initialization, a new registration with the DPS can be started by calling the azure_iot_hub_dps_start() function.

The DPS APIs are documented in the Azure IoT Hub DPS API section.

Connecting to Azure IoT Hub

After the initialization, calling the azure_iot_hub_connect() function connects the device to the configured IoT hub or DPS instance, depending on the configuration. The initial TLS handshake takes a few seconds to complete, depending on the network conditions and the TLS cipher suite used. During the TLS handshake, the azure_iot_hub_connect() function blocks. Consider this when deciding the context from which the API is called. Optionally, DPS registration can be run automatically as part of the call to the azure_iot_hub_connect() function.

Note

The azure_iot_hub_connect() function blocks when DPS registration is pending. Running DPS as part of the azure_iot_hub_connect() function also limits the DPS configuration options as follows:

Use the DPS APIs directly if you need more control over the DPS registration process.

When using the azure_iot_hub_connect() function, you can choose to provide the host name to the IoT Hub and device ID at runtime, or let the library use Kconfig options.

Here is an example for setting the host name and device ID at runtime:

struct azure_iot_hub_config cfg = {
   .hostname = {
      .ptr = hostname_buffer,
      .size = hostname_length,
   },
   .device_id = {
      .ptr = device_id_buffer,
      .size = device_id_length,
   },
   .use_dps = false,
};

err = azure_iot_hub_connect(&cfg);
/* Error handling */

You can pass NULL or a zeroed-out configuration to the azure_iot_hub_connect() function. The library uses the values for host name and device ID from the Kconfig options CONFIG_AZURE_IOT_HUB_HOSTNAME and CONFIG_AZURE_IOT_HUB_DEVICE_ID, respectively.

This code example uses a Kconfig value for the device ID (and by extension DPS registration ID) and runs DPS to acquire the assigned IoT Hub host name and assigned device ID.

struct azure_iot_hub_config cfg = {
   .use_dps = true,
};

err = azure_iot_hub_connect(&cfg);
/* Error handling */

After a successful connection, the library automatically subscribes to the following standard Azure IoT Hub MQTT topics (See Azure IoT Hub MQTT protocol support for details):

  • devices/<device ID>/messages/devicebound/# (cloud-to-device messages)

  • $iothub/twin/PATCH/properties/desired/# (desired properties update notifications)

  • $iothub/twin/res/# (operation responses)

  • $iothub/methods/POST/# (direct method requests)

Currently, the library does not support persistent MQTT sessions. Hence subscriptions are requested for each connection to the IoT hub.

For more information about the available APIs, see the Azure IoT Hub API section.

Configuration

To use the Azure IoT Hub library, you must enable the CONFIG_AZURE_IOT_HUB Kconfig option.

You can configure the following options when using this library:

MQTT helper library specific options:

DPS-specific configuration:

API documentation

Azure IoT Hub API

Header file: include/net/azure_iot_hub.h
Source files: subsys/net/lib/azure_iot_hub/src/azure_iot_hub.c
group azure_iot_hub

Library to connect a device to Azure IoT Hub.

Typedefs

typedef void (*azure_iot_hub_evt_handler_t)(struct azure_iot_hub_evt *evt)

Azure IoT Hub library event handler.

Param evt:

Pointer to event structure.

Enums

enum azure_iot_hub_evt_type

Azure IoT Hub notification events used to notify the user.

Values:

enumerator AZURE_IOT_HUB_EVT_CONNECTING

Connecting to Azure IoT Hub. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_CONNECTED

Connected to Azure IoT Hub. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_CONNECTION_FAILED

Connection attempt failed. The reported error code from the IoT Hub is available in the data.err member in the event structure. The error codes correspond to return codes in MQTT CONNACK messages.

enumerator AZURE_IOT_HUB_EVT_READY

Azure IoT Hub connection established and ready to receive data. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_DISCONNECTED

Disconnected from Azure IoT Hub. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_DATA_RECEIVED

Device-bound data received from Azure IoT Hub. The event contains the received data in the data.msg member, and the topic it was received on in the topic member, including message properties in topic.properties.

enumerator AZURE_IOT_HUB_EVT_PUBACK

Acknowledgment for data sent to Azure IoT Hub. The acknowledged message ID is in data.message_id.

enumerator AZURE_IOT_HUB_EVT_PINGRESP

Acknowledgment for ping request message sent to Azure IoT Hub. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_TWIN_RECEIVED

Device twin has been received. The event contains the received data in the data.msg member, and the topic it was received on in the topic member, including message properties in topic.properties.

enumerator AZURE_IOT_HUB_EVT_TWIN_DESIRED_RECEIVED

Device twin has received a desired property update. The event contains the received data in the data.msg member, and the topic it was received on in the topic member, including message properties in topic.properties.

enumerator AZURE_IOT_HUB_EVT_TWIN_RESULT_SUCCESS

Device twin update successful. The request ID and status are contained in the data.result member of the event structure. The received payload is in the data.msg member, and the topic it was received on is in the topic member.

enumerator AZURE_IOT_HUB_EVT_TWIN_RESULT_FAIL

Device twin update failed. The request ID and status are contained in the data.result member of the event structure.

enumerator AZURE_IOT_HUB_EVT_DIRECT_METHOD

Direct method invoked from the cloud side.

    The event contains the method data in the ``data.method`` member, and the topic it was
    received on in the ``topic`` member.

    @note After a direct method has been executed, @a azure_iot_hub_method_respond must be
      called to report back the result of the method invocation.

enumerator AZURE_IOT_HUB_EVT_FOTA_START

FOTA download starting. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_FOTA_DONE

FOTA update done, reboot required to apply update. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_FOTA_ERASE_PENDING

FOTA erase pending. On nRF9160-based devices this is typically caused by an active LTE connection preventing erase operation. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_FOTA_ERASE_DONE

FOTA erase done. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_FOTA_ERROR

FOTA failed. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_ERROR_MSG_SIZE

A received message is too large for the payload buffer and cannot be processed. The event has no associated data.

enumerator AZURE_IOT_HUB_EVT_ERROR

Internal library error. The event has no associated data.

enum azure_iot_hub_topic_type

Azure IoT Hub topic type, used to route messages to the correct destination.

Values:

enumerator AZURE_IOT_HUB_TOPIC_DEVICEBOUND

Data received on the devicebound topic.

enumerator AZURE_IOT_HUB_TOPIC_DIRECT_METHOD

Data received on the direct method topic.

enumerator AZURE_IOT_HUB_TOPIC_TWIN_DESIRED

Received “desired” properties from the device twin.

enumerator AZURE_IOT_HUB_TOPIC_TWIN_REQUEST_RESULT

Topic to receive twin request result messages. Both success and error messages are received on the same topic.

enumerator AZURE_IOT_HUB_TOPIC_DPS

Topic to receive Device Provisioning Service (DPS) messages.

enumerator AZURE_IOT_HUB_TOPIC_EVENT

Event topic used to send event data to Azure IoT Hub.

enumerator AZURE_IOT_HUB_TOPIC_TWIN_REPORTED

Send updates to the “reported” properties in the device twin.

enumerator AZURE_IOT_HUB_TOPIC_TWIN_REQUEST

Topic to request to receive the device twin.

enumerator AZURE_IOT_HUB_TOPIC_UNKNOWN

Indicates that the message was received on an unknown topic.

Functions

int azure_iot_hub_init(azure_iot_hub_evt_handler_t event_handler)

Initialize the module.

Note

This API must be called exactly once, and it must return successfully for subsequent calls to this library to succeed.

Parameters:
  • event_handler[in] Pointer to event handler function.

Return values:
  • 0 – If successful.

  • -EALREADY – if the library has already been initialized and is in a state where it can not be re-initialized.

  • -EINVAL – in invalid argument was provided.

int azure_iot_hub_connect(const struct azure_iot_hub_config *config)

Establish connection to Azure IoT Hub. The function blocks until a connection to the hub is established on the transport level. Subsequent calls to other library function should await AZURE_IOT_HUB_EVT_CONNECTED and AZURE_IOT_HUB_EVT_READY events.

Parameters:
  • config[in] Pointer to struct containing connection parameters. If NULL, values from Kconfig will be used instead.

Return values:
  • 0 – If successful.

  • -EALREADY – if the device is already connected to an IoT Hub.

  • -EINPROGRESS – if a connection attempt is already in progress.

  • -ENOENT – if the library is not in disconnected state.

  • -EINVAL – if the provided configuration is invalid.

  • -EMSGSIZE – if the provided device ID is larger than the internal buffer size.

  • -EFAULT – if there was an internal error in the library.

int azure_iot_hub_disconnect(void)

Disconnect from Azure IoT Hub. Calling this function initiates the disconnection procedure, and the event AZURE_IOT_HUB_EVT_DISCONNECTED is received when it is completed.

Return values:
  • 0 – If successful.

  • -ENOTCONN – if the device is not connected to an IoT Hub.

  • -ENXIO – if the MQTT library reported an error.

int azure_iot_hub_send(const struct azure_iot_hub_msg *const tx_data)

Send data to Azure IoT Hub.

Parameters:
  • tx_data[in] Pointer to struct containing data to be transmitted to Azure IoT Hub.

Return values:
  • 0 – If successful.

  • -EINVAL – if a NULL pointer was provided.

  • -ENOMSG – if the provided message topic was invalid.

  • -EMSGSIZE – an internal buffer is too small to hold the topic data. This can for instance happen if message properties are in use, as they are appended to the topic.

  • -ENOTCONN – if the device is not connected to an IoT Hub.

  • -ENOMEM – if the request ID buffer was insufficient to create the ID.

  • -EFAULT – if there was an internal error in the library.

int azure_iot_hub_method_respond(struct azure_iot_hub_result *result)

Send response to a direct method invoked from the cloud.

Parameters:
  • result[in] Structure containing result data from the direct method execution.

Return values:
  • 0 – If successful.

  • -EINVAL – if a NULL pointer was provided.

  • -ENOTCONN – if there was no IoT hub connection.

  • -EFAULT – if there was an error when creating the response message.

  • -ENXIO – if the MQTT library reported an error when publishing the response.

struct azure_iot_hub_buf
#include <azure_iot_hub.h>

Buffer to store data together with buffer size.

struct azure_iot_hub_property
#include <azure_iot_hub.h>

Property bag structure for key/value string pairs. Per Azure IoT Hub documentation, the key must be defined, while the value can be a string or empty.

Note

If the value is provided as a string, it is the equivalent to “key=value”. If the value is empty, it is the equivalent of “key=” or “key”.

Public Members

struct azure_iot_hub_buf key

Property key.

struct azure_iot_hub_buf value

Property value.

struct azure_iot_hub_topic_data
#include <azure_iot_hub.h>

Azure IoT Hub topic data.

Public Members

enum azure_iot_hub_topic_type type

Topic type.

struct azure_iot_hub_buf name

Topic name ptr and size.

struct azure_iot_hub_msg
#include <azure_iot_hub.h>

Azure IoT Hub transmission data.

Public Members

struct azure_iot_hub_topic_data topic

Topic data is sent/received on.

struct azure_iot_hub_buf payload

Pointer to the payload sent/received from Azure IoT Hub.

struct azure_iot_hub_buf request_id

Request ID that can be populated if it is relevant for the message type.

enum mqtt_qos qos

Quality of Service for the message.

uint16_t message_id

Message id used for the message, used to match acknowledgments.

uint8_t dup_flag

Duplicate flag. 1 indicates the message is a retransmission, Usually triggered by missing publication acknowledgment.

uint8_t retain_flag

Retain flag. 1 indicates to the IoT hub that the message should be stored persistently.

struct azure_iot_hub_method
#include <azure_iot_hub.h>

Azure IoT Hub direct method data.

Public Members

struct azure_iot_hub_buf name

Method name.

struct azure_iot_hub_buf request_id

Method request ID.

struct azure_iot_hub_buf payload

Method payload.

struct azure_iot_hub_result
#include <azure_iot_hub.h>

Azure IoT Hub result structure.

Used to signal result of direct method execution from device to cloud, and to receive result of device twin updates (twin updates sent from the device will receive a result message back from the cloud with success or failure).

Public Members

struct azure_iot_hub_buf request_id

Request ID to which the result belongs.

uint32_t status

Status code.

struct azure_iot_hub_buf payload

Result payload.

struct azure_iot_hub_evt
#include <azure_iot_hub.h>

Struct with data received from Azure IoT Hub.

Public Members

enum azure_iot_hub_evt_type type

Type of event.

struct azure_iot_hub_config
#include <azure_iot_hub.h>

Structure for Azure IoT Hub connection parameters.

Public Members

struct azure_iot_hub_buf hostname

Hostname to IoT Hub to connect to. If the buffer size is zero, the device ID provided by CONFIG_AZURE_IOT_HUB_HOSTNAME is used. If DPS is enabled and use_dps is set to true, the provided hostname is ignored.

struct azure_iot_hub_buf device_id

Device id for the Azure IoT Hub connection. If the buffer size is zero, the device ID provided by Kconfig is used.

bool use_dps

Use DPS to obtain hostname and device ID if true. Using DPS requires that CONFIG_AZURE_IOT_HUB_DPS is enabled and DPS configured accordingly. If a hostname and device ID have already been obtained previously, the stored values will be used. To re-run DPS, the DPS information must be reset first. Note that using this option will use the device ID as DPS registration ID and the ID cope from CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE . For more fine-grained control over DPS, use the azure_iot_hub_dps APIs directly instead.

Azure IoT Hub DPS API

Header file: include/net/azure_iot_hub_dps.h
Source files: subsys/net/lib/azure_iot_hub/src/azure_iot_hub_dps.c
group azure_iot_hub_dps

Library to connect a device to Azure IoT Hub Device Provisioning Service (DPS).

Typedefs

typedef void (*azure_iot_hub_dps_handler_t)(enum azure_iot_hub_dps_reg_status status)

The handler will be called when registration is done, be it successfully or if it fails.

Enums

enum azure_iot_hub_dps_reg_status

Device Provisioning Service registration status.

Values:

enumerator AZURE_IOT_HUB_DPS_REG_STATUS_NOT_STARTED

The DPS library has been initialized and the registration process can now be started.

enumerator AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNING
enumerator AZURE_IOT_HUB_DPS_REG_STATUS_ASSIGNED
enumerator AZURE_IOT_HUB_DPS_REG_STATUS_FAILED

Functions

int azure_iot_hub_dps_init(struct azure_iot_hub_dps_config *cfg)

Initialize Azure IoT hub Device Provisioning Service (DPS).

Note

The buffers provided in the configuration structure must remain unchanged until the DPS attempt has been completed. If the content of the buffers is changed while provisioning is ongoing, the behavior is undefined.

Parameters:
  • cfg[in] Pointer to DPS configuration structure.

Return values:
  • 0 – if successful.

  • -EINVAL – if configuration or event handler was NULL.

int azure_iot_hub_dps_start(void)
int azure_iot_hub_dps_hostname_get(struct azure_iot_hub_buf *buf)

Get the hostname of the currently assigned Azure IoT Hub as a terminated string.

Parameters:
  • buf[inout] Pointer to buffer where the hostname will be stored. The buffer will upon success be populated to point to the assigned IoT Hub and its size.

Return values:
  • 0 – if a valid hostname was found and populated to the provided buffer.

  • -EINVAL – if an invalid buffer pointer was provided.

  • -EMSGSIZE – if the provided buffer is too small.

  • -ENOENT – if no hostname has been registered using DPS.

int azure_iot_hub_dps_hostname_delete(void)

Delete the hostname of the currently assigned Azure IoT Hub.

Return values:
  • 0 – if a valid hostname was found and deleted, or of none existed.

  • -EFAULT – if there was in issue when erasing an already assigned IoT Hub from flash.

int azure_iot_hub_dps_device_id_get(struct azure_iot_hub_buf *buf)

Get the currently assigned device ID.

Parameters:
  • buf[inout] Pointer to buffer where the device ID will be stored. The buffer will upon success be populated to point to the assigned device ID and its size.

Return values:
  • 0 – if a valid device ID was found and populated to the provided buffer.

  • -EINVAL – if an invalid buffer pointer was provided.

  • -EMSGSIZE – if the provided buffer is too small.

  • -ENOENT – if no device ID has been registered using DPS.

int azure_iot_hub_dps_device_id_delete(void)

Delete the assigned device ID.

Return values:
  • 0 – if a valid device ID was found and deleted, or of none existed.

  • -EFAULT – if there was in issue when erasing an already assigned IoT Hub from flash.

int azure_iot_hub_dps_reset(void)

Reset DPS library. All stored information about assigned IoT Hub is deleted. After this call, the library is put into an uninitialized state and must be initialized again before the next provisioning attempt.

Return values:
  • 0 – if successful, otherwise a negative error code.

  • -EACCES – if a DPS request is already in progress.

  • -EFAULT – if there was in issue when erasing an already assigned IoT Hub from flash.

struct azure_iot_hub_dps_config
#include <azure_iot_hub_dps.h>

Device Provisioning Service configuration structure.

Public Members

azure_iot_hub_dps_handler_t handler

Handler to receive updates on registration status.

struct azure_iot_hub_buf id_scope

ID scope to use in the provisioning request. If the pointer is NULL or the length is zero, the compile-time option CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE is used.

struct azure_iot_hub_buf reg_id

Registration ID to use in the provisioning request. If the pointer is NULL or the length is zero, the compile-time option CONFIG_AZURE_IOT_HUB_REG_ID is used.