Azure IoT Hubにメッセージ送信する最小コード


Azure Sphere SDKには、Azure IoT Hubに接続するアプリケーション、Azure IoT Hub Sample for MT3620 RDBのプロジェクトテンプレートが含まれており、Azure SphereからAzure IoT Hubに接続するアプリケーションを簡単に作ることができます。

ただ、生成されたコードはデバイスツインやダイレクトメソッドなどテンコ盛りで、コールバックを使っていることから、分かりやすいコードとは言えません。
そこで、きちんとした作りではありませんが、理解しやすいコードを紹介します。

プロジェクトを作成

Blank Application for MT3620 RDB (Azure Sphere)のプロジェクトを新規作成します。

ライブラリを追加

libazureiot.soの読み込みを追加します。
具体的には、プロジェクトのプロパティにある、Linker - InputのAdditional Dependenciesに-lazureiotを追加してください。

ヘッダファイルをインクルード

IoTHubDeviceClient_LL_Xxxx関数の呼び出しに必要なヘッダファイル、iothub_device_client_ll.hiothubtransportmqtt.hをインクルードします。

#include <azureiot/iothubtransportmqtt.h>
#include <azureiot/iothub_device_client_ll.h>

あと、簡易なエラーチェックとしてassert()を使うので、assert.hもインクルードしてください。

#include <assert.h>

接続文字列

接続文字列をCONNECTION_STRINGという名前で定義します。

#define CONNECTION_STRING   "具体的な接続文字列"

接続の許可

接続先のホスト名を、app_manifest.jsonのAllowedConnectionsに追加します。

...
    "AllowedConnections": [ "名前.azure-devices.net" ],
...

証明書

ルートCA証明書をazureIoTCertificatesXという名前で定義します。

static const char azureIoTCertificatesX[] =
/* Baltimore */
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n"
"RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n"
"VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\n"
"DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\n"
"ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\n"
"VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\n"
"mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\n"
"IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\n"
"mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\n"
"XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\n"
"dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\n"
"jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\n"
"BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\n"
"DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n"
"9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\n"
"jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\n"
"Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\n"
"ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n"
"R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n"
"-----END CERTIFICATE-----\r\n";

メッセージ送信するコード(断片)

クライアントハンドルの作成

IoTHubDeviceClient_LL_CreateFromConnectionString()で、接続文字列からクライアントハンドルを作成します。

    IOTHUB_DEVICE_CLIENT_LL_HANDLE clientHandle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
    assert(clientHandle != NULL);

証明書を設定

IoTHubDeviceClient_LL_SetOption()で、クライアントハンドルに証明書を設定します。

    IOTHUB_CLIENT_RESULT result;
    result = IoTHubDeviceClient_LL_SetOption(clientHandle, "TrustedCerts", azureIoTCertificatesX);
    assert(result == IOTHUB_CLIENT_OK);

メッセージを送信

IoTHubDeviceClient_LL_SendEventAsync()で、クライアントハンドルに送信するメッセージを追加します。

実際には、このタイミングでは送信しません。
後のIoTHubDeviceClient_LL_DoWork()でAzure IoT Hubに接続して送信します。

    IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromString("Hello world.");
    assert(messageHandle != NULL);
    result = IoTHubDeviceClient_LL_SendEventAsync(clientHandle, messageHandle, NULL, 0);
    assert(result == IOTHUB_CLIENT_OK);
    IoTHubMessage_Destroy(messageHandle);

実行

IoTHubDeviceClient_LL_DoWork()で、クライアントに関する処理を実行します。

    while (!terminationRequired)
    {
        IoTHubDeviceClient_LL_DoWork(clientHandle);
    }

クライアントハンドルの破棄

IoTHubDeviceClient_LL_Destroy()で、クライアントハンドルを破棄(終了)します。

    IoTHubDeviceClient_LL_Destroy(clientHandle);

メッセージ送信するコード(全部)

int main(int argc, char *argv[])
{
    Log_Debug("Application starting.\n");

    // Register a SIGTERM handler for termination requests
    struct sigaction action;
    memset(&action, 0, sizeof(struct sigaction));
    action.sa_handler = TerminationHandler;
    sigaction(SIGTERM, &action, NULL);

    IOTHUB_DEVICE_CLIENT_LL_HANDLE clientHandle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
    assert(clientHandle != NULL);

    IOTHUB_CLIENT_RESULT result;
    result = IoTHubDeviceClient_LL_SetOption(clientHandle, "TrustedCerts", azureIoTCertificatesX);
    assert(result == IOTHUB_CLIENT_OK);

    IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromString("Hello world.");
    assert(messageHandle != NULL);
    result = IoTHubDeviceClient_LL_SendEventAsync(clientHandle, messageHandle, NULL, 0);
    assert(result == IOTHUB_CLIENT_OK);
    IoTHubMessage_Destroy(messageHandle);

    while (!terminationRequired)
    {
        IoTHubDeviceClient_LL_DoWork(clientHandle);
    }

    IoTHubDeviceClient_LL_Destroy(clientHandle);

    Log_Debug("Application exiting.\n");
    return 0;
}

補足

  • Azure Sphere SDKに含まれているAzure IoT Hub関連APIはAzure IoT Device C SDKのサブセット。
  • iothub_device_client_ll.hを使う。同等APIのiothub_client_ll.hは使えない。(というか、無い。)