Azure IoT C SDK

Device Provisioning with the C SDK

Device Provisioning with the Azure IoT C SDK

This guide details how to use the Azure IoT C SDK to provision your devices securely and efficiently to Azure IoT Hub. Device provisioning is a critical step in the IoT solution lifecycle, ensuring that each device can be uniquely identified and authenticated with the cloud.

Prerequisites

Before you begin, ensure you have the following:

  • An Azure subscription.
  • An Azure IoT Hub instance created.
  • The Azure IoT Device Provisioning Service (DPS) configured and linked to your IoT Hub.
  • The Azure IoT C SDK downloaded and built for your target platform. Refer to the Getting Started guide for build instructions.
  • A device or development board capable of running C code.

Understanding Provisioning Services

The Azure IoT Device Provisioning Service (DPS) is a fully managed service that enables zero-touch, just-in-time provisioning to the right Azure IoT Hub without requiring human intervention. DPS supports several enrollment types:

  • Individual Enrollments: For provisioning individual devices.
  • Enrollment Groups: For provisioning groups of devices that share common attributes.

SDK Integration

The C SDK provides specific APIs to interact with DPS. These APIs allow your device to connect to the DPS endpoint, send a provisioning request, and receive device connection details for your IoT Hub. The core concepts involve:

  • Establishing a connection to the DPS endpoint.
  • Creating a provisioning client.
  • Registering the device with DPS using either individual or group enrollment.
  • Handling the registration response to obtain the IoT Hub connection string.

Individual Device Provisioning

For individual device provisioning, you'll typically use a device's unique identity (e.g., X.509 certificate or TPM endorsement key) to create an individual enrollment in DPS. The C SDK will use this identity to authenticate with DPS during the provisioning process.

The key function for this is often IoTHubDeviceClient_CreateFromEnvironment() or similar, which can be configured to use DPS.

Note: Ensure your device's identity (certificate or TPM key) matches the one registered in DPS for successful authentication.

Group Provisioning

Group provisioning simplifies the management of multiple devices. You create an enrollment group in DPS and associate it with a root certificate or an intermediate certificate. Devices within this group can then provision themselves using certificates signed by that root or intermediate CA.

The SDK handles the group enrollment by identifying which group the device belongs to based on its certificate chain.

Sample Code Snippet (Illustrative)

Here's a simplified C code example demonstrating the core logic for connecting to DPS and provisioning:


#include "azure_iot_provisioning_client.h"
#include "azure_iot_hub_client.h"
#include "azure_iot_identity_hsm.h" // For HSM specific identity

// DPS connection details
const char* dps_uri = "YOUR_DPS_ENDPOINT";
const char* scope_id = "YOUR_SCOPE_ID";

int main() {
    AZURE_IOT_PROVISIONING_CLIENT_HANDLE provisioning_client;
    AZURE_IOT_HUB_CLIENT_HANDLE hub_client;
    AZURE_IOT_PROVISIONING_REGISTER_DEVICE_RESPONSE register_response;
    AZURE_IOT_PROVISIONING_REGISTRATION_REQUEST registration_request;
    AZURE_IOT_PROVISIONING_REGISTRATION_TRANSPORT_type transport_type = AZURE_IOT_PROVISIONING_TRANSPORT_TYPE_MQTT_WS; // Or MQTT, AMQP

    // Initialize DPS client
    if (azure_iot_provisioning_client_init(dps_uri, scope_id, transport_type, &provisioning_client) != AZURE_IOT_SUCCESS) {
        // Handle error
        return -1;
    }

    // Create registration request (e.g., using TPM or X509)
    // Example for TPM:
    // AZURE_IOT_IDENTITY_HSM_HANDLE hsm_handle = azure_iot_identity_hsm_init(AZURE_IOT_IDENTITY_HSM_TYPE_TPM, ...);
    // azure_iot_provisioning_registration_request_set_identity(registration_request, hsm_handle, ...);

    // Example for X509:
    // AZURE_IOT_IDENTITY_X509_HANDLE x509_handle = azure_iot_identity_x509_init(...);
    // azure_iot_provisioning_registration_request_set_identity(registration_request, x509_handle, ...);

    // Send registration request
    if (azure_iot_provisioning_client_register_device(provisioning_client, registration_request, ®ister_response) != AZURE_IOT_SUCCESS) {
        // Handle error
        azure_iot_provisioning_client_deinit(provisioning_client);
        return -1;
    }

    // Process the registration response
    if (register_response.operation_status == AZURE_IOT_PROVISIONING_OPERATION_STATUS_ASSIGNED) {
        // Device assigned to an IoT Hub
        const char* iot_hub_hostname = register_response.iot_hub_hostname;
        const char* device_id = register_response.device_id;

        // Create IoT Hub client using the obtained details
        // Example: hub_client = IoTHubDeviceClient_CreateFromDPS(iot_hub_hostname, device_id, ...);

        // Connect to IoT Hub
        // IoTHubDeviceClient_Open(hub_client);
    } else {
        // Handle other statuses (e.g., `DEVICE_REJECTED`, `OPERATION_FAILED`)
    }

    // Cleanup
    azure_iot_provisioning_client_deinit(provisioning_client);
    // ... cleanup hub_client and identity handles
    return 0;
}
                

Troubleshooting Common Issues

Warning: Incorrectly configured credentials or network issues are common causes of provisioning failures. Always double-check your DPS endpoint, scope ID, and device identity setup.

  • Authentication Errors: Verify that the device's identity (e.g., X.509 certificate or TPM endorsement key) precisely matches the credentials registered in DPS.
  • Network Connectivity: Ensure your device can reach the DPS endpoint (`YOUR_DPS_ENDPOINT`) over the internet. Check firewalls and network configurations.
  • Scope ID Mismatch: Confirm that the scope_id used in your code is the correct one for your DPS instance.
  • SDK Configuration: Make sure the transport protocol (MQTT, AMQP, HTTPS) is correctly specified and supported by your network environment.