セキュアなIoTデバイス通信をやってみた(Azure IoT 接続編‐Azure IoT Hub MQTTS通信)

#はじめに#
2019年5月に[IoTLT](https://iotlt.connpass.com/)にてLTをさせていただきました。
その内容のフォローを記入しながら自分なりに整理していきたいと思います。

発表内容：
[スタートアップIoTデバイスのセキュリティを考える](https://www.slideshare.net/KentaroMitsuyasu1/iot-144602008)

#前回までのあらすじ#
[セキュアなIoTデバイス通信をやってみた(Azure IoT 接続編‐DPSプロビジョニング)](https://qiita.com/kmitsu76/items/0cf4bf0c6fd1af4ce26b)でAzure IoT Hubへの接続準備を行いました。

今回の記事に関連するソースコードは下記にて公開中。
[ECC608-AzureIoT-Connect](https://github.com/kmwebnet/ECC608-AzureIoT-Connect)

#Azure IoT Hubへの接続#
前回のDPS接続のコードは、多層のレイヤーになっており、ハンドルも多数で分かりづらく、シンプルに接続できるようにし、できるだけTLSレイヤーまでのリソースを削減したい。
そこで、[セキュアなIoTデバイス通信をやってみた(MbedTLS移植編-MQTTS)](https://qiita.com/kmitsu76/items/8573ee925ffd72b027e0)をカスタマイズして接続させる。
接続に必要な情報はすでに前回のDPSプロビジョニングでデバイス内に格納されている。

#ポーティングのポイント#
[MQTT プロトコルを使用した IoT Hub との通信](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-mqtt-support)が参考になる。
それによると、
> MQTT プロトコルの直接使用 (デバイスとして)
> デバイスでデバイス SDK を使用できない場合でも、MQTT プロトコルをポート 8883 で使用して、デバイスをパブリックのデバイス エンドポイントに接続できます。 CONNECT パケットの場合、デバイスでは次の値を使用する必要があります。
> ClientId フィールドには、deviceId を使用します。
>[Usename] フィールドには、{iothubhostname}/{device_id}/?api-version=2018-06-30 を使用します。{iothubhostname} は IoT Hub の完全な CName です。
> たとえば、IoT Hub の名前が contoso.azure-devices.net であり、デバイスの名前が MyDevice01 であるとすると、Username フィールドの内容は 次のようになります。
>contoso.azure-devices.net/MyDevice01/?api-version=2018-06-30

とのこと。デバイスからのパブリッシュは

> デバイスからクラウドへのメッセージの送信
>接続に成功したら、デバイスから IoT Hub に >devices/{device_id}/messages/events/ または >devices/{device_id}/messages/events/{property_bag} をトピック名として使用してメッセージを送信できます。 {property_bag} 要素を使用すると、デバイスは追加のプロパティ付きのメッセージを URL エンコード形式で送信できるようになります。

サブスクライブは
> クラウドからデバイスへのメッセージの受信
> IoT Hub からメッセージを受信するには、デバイスで、devices/{device_id}/messages/devicebound/# をトピック フィルターとして使用してサブスクライブする必要があります。 

と整理できる。これらを設定するため、main.c内で変数を設定。

```
char subtopic[100] = {};
char pubtopic[100] = {};
char usrname[100] = {};
char serialstr[20] = {};
char azureioturl[48] = {};
```

usrname はATECC608A からシリアル番号を抜き出し代入し、ClientIDとして使用。
azureioturlもATECC608Aのスロット8から読み込む。
残りはsprintfで生成することで作成した。

#Azure IoTとの通信結果#
下記の通りシリアルコンソールでパブリッシュしたところ。
Azure IoT Hubからデバイスへのメッセージをテストで送ると、デバイス側でも受信ができている。
<img width="780" alt="azureiothub.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/65c69d48-d6ab-6dd7-07af-66e33bb265de.png">

接続したBME280の温度、湿度、気圧データを視覚化してみた。
データの流れは
Azure IoT Hub → Stream Analytics → Power BI
となる。設定については下記を参考にさせていただいた。
[Power BI を使用して Azure IoT Hub からのリアルタイム センサー データを視覚化する](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-live-data-visualization-in-power-bi)
上記はWEB版のPower BIだがうまくいかず、Windowsデスクトップアプリ版のPower BI Desktop で行った。

<img width="960" alt="powerbidesktop1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/4175bf08-48cb-b58c-d90f-88f6eca10783.png">
まずPower BI データセットを選択。

<img width="960" alt="powerbidesktop2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/31be4eb2-e2d9-1e0e-d0bb-1fb0cef968d9.png">
Stream　Analyticsの設定が完了し、ジョブが走った状態でデータを受け始めると上記のようにデータセットが現れる。
そこからカラムのデータ型（temparature,Humidity,Pressureを数値型）をセットしてグラフ化した。

<img width="960" alt="powerbidesktop-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/6cd689c3-86d2-b24a-63a6-a923718ca104.png">

これで、セキュアエレメントを使ったAzure IoTへの接続ができた。