AWS IoTの設定方法 with Spresense LTE


# 概要

世の中では、IoT（Internet of Things)の言葉が良く見られているが、サーバーの代表例であるAWSと通信デバイス機器（ここではSpresenseを利用）との接続を試してみた。Spresenseのlte_awsiotサンプルのユーザーガイドにもAWSの具体的な設定方法の記載もなく、AWSのドキュメントは初めて使うものには少し要点がわかりにくかったので、テスト接続できるまでの内容を整理してまとめてみた。

## 環境

#### 通信デバイス
- [Spresenseメインボード](https://www.switch-science.com/catalog/3900/)
- [SpresenseLTEボード](https://www.switch-science.com/catalog/5999/)　※IIJのTravel　SIMを利用

※補足：以下の記事も目にしたのでLTEボードのfirmwareを最新にしている。
　[SDK Ver2.3.0 Example lte_awsiotを長時間実行したら、エラーとリセットが発生する](https://ja.stackoverflow.com/questions/82861/sdk-ver2-3-0-example-lte-awsiot%e3%82%92%e9%95%b7%e6%99%82%e9%96%93%e5%ae%9f%e8%a1%8c%e3%81%97%e3%81%9f%e3%82%89-%e3%82%a8%e3%83%a9%e3%83%bc%e3%81%a8%e3%83%aa%e3%82%bb%e3%83%83%e3%83%88%e3%81%8c%e7%99%ba%e7%94%9f%e3%81%99%e3%82%8b)

#### ビルド環境
Linux（ubuntu16.04 LTS）※追記：18.04LTSでも動作確認実績あり
（もう少しWindowsでのビルド環境が使いやすくなったらいいのに･･･）

#### AWSサーバー
アカウント初めて作るところからだったので、その辺の情報も記載する。
無料期間は12ヵ月くらいと期限があり、その後は課金されるので使用状況次第で見直しを忘れないことは必要。期限が切れるころにメールがAWSから送られてくるとのこと。


## AWSサーバー設定

１. AWSアカウント(ルートアカウント)作成

”ルートユーザー”を選択して、”新しいAWSアカウントの作成”のボタンを押す。
※今回は、テスト接続用にルートユーザーで試したが、複数のデバイスのアクセスをまじめに考える場合は権限の制限を個々に選択できるのでIAMユーザーを作成した方が良いかと思っている。（そちらも試せたら別途・・）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/8a22f2bc-6027-4974-5dc2-ac023931fd9d.png" width="640">
アカウントの登録はAmazonの[”AWS アカウント作成の流れ”](https://aws.amazon.com/jp/register-flow/)は分かりやすいので、参照しながら設定すればできると思う。

２. AWSコンソールマネジメント
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/611cae68-6bff-1eec-b3e8-0ef30e1b1b25.png" width="640">
ログイン時の画面は、”AWSコンソールマネジメント”となる。
ここの図では、さらに利用するサーバのリージョンを東京に切り替えてある。
※補足：右上のアカウント欄は図を加工してある。

次に利用したいAWSIoTの設定画面に切り替える。
検索の欄で”IoT Core”を入力しても良いし、サービスの中から選択することもできる。

３. IoT Core

今回のサンプルコードで使用する設定はこのサービスになる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/a6ef7873-0c32-b1c1-cc98-06e7b62cf89a.png" width="640">
証明書の箇所をクリックする。

４. 証明書の作成

”1-click証明書(推奨)”の作成を選択する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/d4f71f69-a58f-43eb-d772-6187737cd0cc.png" width="640">
ダウンロード後に以下のファイルがAWSIOT用CONFIG設定で参照される。

 - ルート証明書
 - クライアント証明書
 - クライアント証明書の秘密鍵

※後述するが、クライアント証明書、秘密鍵のファイル名はそのままだと長くて失敗するので名前を変更する必要がある。

※補足：証明書はlte_awsiotのexampleのデフォルト設定では、"/mnt/sd0/CERTS"となっているので、SDカードに"CERTS"のフォルダを作成して、そこに証明書を配置する必要がある。

５. ポリシーのアタッチ

初めての場合は、ポリシーがないので作成する。
テスト用に作成するので、全許容の設定にする。

 - Action： iot*
 - Resource ARN: *
 - Effect: Allow

参考にしたサイト
 [AWS IoTを始めよう -MQTTの設定(AWS IoT編)- – ナレコムAWSレシピ ](https://recipe.kc-cloud.jp/archives/9612)

また、利用したい既存のポリシーがあれば選択するのでもよい、証明書にポリシーをアタッチさせるためポリシーを選択して完了ボタンを押す。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/5291a222-3ba6-e113-7a57-f604865d8e19.png" width="640">
※「ポリシーを次の・・・」の下には証明書のHashコードが表示されるが、ここでは黒塗り加工してある。

６. モノ（Thing）の作成

デバイスの管理や検索用に”モノ”を登録する。後に、デバイス側のサンプルビルド時の設定で識別子としてCONFIGファイルに記述する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/7310a0d5-0fd0-6c96-b381-7a5d1b4f91c3.png" width="640">
モノの設定において、今回のlte_awsiotコードのサンプル実行では名前を決める以外に特に設定は必要ない。対象となる証明書の”アクション”をプルダウンして現れる”モノをアタッチ”から証明書とモノの紐づけを行う。

証明書にモノがアタッチされると以下のように見られる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/cce372ed-fd29-d325-1728-fe8f56a57928.png" width="480">
参考サイト：
[AWS IoT のモノ、証明書、およびプライベートキーの作成 - AWS IoT Core (amazon.com)](https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-moisture-create-thing.html)

７. エンドポイント情報の確認

AWSサーバーへのアクセス時に必要になるエンドポイント情報を確認する。これはサンプルコードbuild前のCONFIGでのエンドポイント情報に設定される。
※赤線で囲まれた黒塗り加工した箇所に記載されている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/b8c6b12d-b0e5-1dca-1c40-f1cd22f60f7e.png" width="640">

## Spresense lte_awsiotサンプルの準備
１. コードの準備

以下のサイトページを参考に準備を行う。
[Spresense SDK LTE AWS-IoT サンプルアプリケーション チュートリアル ](https://developer.sony.com/develop/spresense/docs/sdk_tutorials_ja.html#_lte_aws_iot_%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

buildを行うフォルダ(AWS-SAMPLE)を用意して、GitHubからコードをローカル環境にダウンロードする。spresense.gitはsubmoduleを含むコードなので、submoduleの状態も"--recursive"フラグで一緒にcloneすることになる。

```
myubuntu:~/AWS-SAMPLE$git clone --recursive https://github.com/sonydevworld/spresense.git spresense
Cloning into 'spresense'...
remote: Enumerating objects: 29281, done.
remote: Counting objects: 100% (3752/3752), done.
・・・省略・・・
Checking connectivity... done.
Submodule path 'sdk/apps': checked out 'ef5576df0aaf696d7d52417bb04e398979e31362'
```

２. Configの設定

ビルド前に、利用するsimのAPNや、先にAWSサーバーの設定で得た必要な情報をCONFIGに記載する。
まずは、SIM情報の設定を行う。

 - SIM情報の設定
 
今回利用しているSIMはIIJのTRAVEL SIMなので、以下の情報に従ってAPN設定を行う。
[APN設定方法 | JAPAN TRAVEL SIM powered by IIJmio](https://t.iijmio.jp/apn/)

設定する箇所はExamples/AWSIOT以下の5か所のCONFIGになる。

```
　CONFIG_EXAMPLES_LTE_AWSIOT_APN_IPTYPE=0
　CONFIG_EXAMPLES_LTE_AWSIOT_APN_AUTHTYPE=2
　CONFIG_EXAMPLES_LTE_AWSIOT_APN_NAME="iijmio.jp"
　CONFIG_EXAMPLES_LTE_AWSIOT_APN_PASSWD="iij"
　CONFIG_EXAMPLES_LTE_AWSIOT_APN_USERNAME="mio@iij"
```
それぞれ、チュートリアルを基にすると以下の意味になる。

| コンフィグレーション名（略） | 説明 |設定値|
|---|---|---|
|APN_NAME| アクセスポイント名 |iijmio.jp|
|APN_IPTYPE|APNプロトコル。0: IPv4, 1: IPv6 2: IPv4/v6 から選択|0|
|APN_AUTHTYPE|認証タイプ。0: None 、1: PAP 、2: CHAP から選択|2|
|APN_PASSWD|パスワード(認証タイプがNone以外で有効)|iij|
|APN_USERNAME|ユーザ名(認証タイプがNone以外で有効)|mio@iij|

以下のコマンドのように、git cloneしたコードにディレクトリを変更してから、
lte_awsiotサンプルコード用CONFIGを編集するためにMenuを開き、設定値を入力する。

```
myubuntu:~/AWS-SAMPLE$cd spresense/sdk
myubuntu:~/AWS-SAMPLE/spresense/sdk$tools/config.py examples/lte_awsiot -m
```

対象は図の赤線のところ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/d1ddc26c-79da-6b15-d50f-0d1518495c99.png" width="640">

※補足：証明書の場所の指定は、コンフィギュレーションの"EXAMPLES_LTE_AWSIOT_CERT"に指定されるパスとなる。デフォルトは"/mnt/sd0/CERTS"となっているので、SDカードのCERTSフォルダ内が検索される。

次はAWSサーバー情報の設定を行う。

 - AWSIoT情報の設定

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/513fa442-2419-494a-154c-2e597a0a803f.png" width="640">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/ed66787a-d846-4035-79f9-740a37c23d02.png" width="640">

こちらも、チュートリアルを基にすると以下の意味になる。

|コンフィグレーション名|デフォルト値|説明|設定値|
|---|---|---|---|
|AWS_IOT_MQTT_HOST|なし|MQTTブローカー名|使用するAWS-IoT環境のエンドポイントを設定|
|AWS_IOT_MQTT_PORT|443|MQTTブローカーのポート番号。デフォルト値で接続可能|デフォルト値|
|AWS_IOT_MQTT_CLIENT_ID|"AWS-IoT-C-SDK"|MQTTのクライアントID|ここではAWSサーバーに登録したモノの名前を設定|
|AWS_IOT_MY_THING_NAME|"AWS-IoT-C-SDK"|モノの名前|ここではAWSサーバーに登録したモノの名前を設定|
|AWS_IOT_ROOT_CA_FILENAME|"rootCA.crt"|ルート証明書のファイル名|AWS-IoTサイトからダウンロードしたルート証明書ファイルを指定|
|AWS_IOT_CERTIFICATE_FILENAME|"cert.pem"|クライアント証明書のファイル名|AWS-IoTサイトからダウンロードしたクライアント証明書ファイルを利用（※1）|
|AWS_IOT_PRIVATE_KEY_FILENAME|"privkey.pem"|クライアント認証で用いる秘密鍵のファイル名|AWS-IoTサイトからダウンロードした秘密鍵ファイルを利用（※1）|

※1：AWSIoTからダウンロードした証明書の名前は長いためか、そのままではエラーが発生した。なので、ファイルの名前を短くする必要がある。ファイル名と参照名をきちんと合わせておくことを忘れずに。

最後にMenuの保存を忘れずにCONFIGの編集から抜ける。
 
３. コードのビルド

makeを実行してコードのビルドを行う。

```
myubuntu:~/AWS-SAMPLE/spresense/sdk$make 
```

４. バイナリコードのSPRESENSE基板へのinstall

出来上がったnuttx.spkをSPRESENSE基板にinstallする。
基板とUSBで接続しているポートが/dev/ttyUSB0の場合を例に、以下のコマンドのようにflashメモリに書き込む。

```
myubuntu:~/AWS-SAMPLE/spresense/sdk$tools/flash.sh -c /dev/ttyUSB0 nuttx.spk 
```

５. 実行

バイナリコードをinstallした基板との接続ポートをターミナルで開き、”lte_awsiot”のコマンドを実行する。”-x”オプションは回数を規定するようだ。ここでは、1回を指定する。

```
nsh> lte_awsiot -x 1
app_restart_cb called. reason:Modem restart by application.
app_radio_on_cb called. result: 0
app_localtime_report_cb called: localtime : "21/12/21 : 10:45:56"
set localtime completed: 2021/12/21,10:45:56
app_activate_pdn_cb called. result: 0
pdn.session_id : 1
pdn.active     : 1
pdn.apn_type   : 0x202
pdn.ipaddr[0].addr : 100.75.47.234
app_deactivate_pdn_cb called. result: 0
app_radio_off_cb called. result: 0
nsh>
```
特にエラーメッセージが出力されていなければ通信はできているはず。
次にAWSサーバー側から通信状況を確認してみる。

## AWSサーバーでのグラフ確認

サーバー側にて通信の状況はAWSIoTの”モニタリング”で確認ができる。
グラフでのデータやログの細かい見方は、まだよく分からないのでこれから調べてみたい。

表示例を示す。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2340894/c85ab339-76de-e158-5011-547f62f9ed48.png" width="640">
デフォルト時刻はUTC（ロンドン基準の時刻）になっているが、通信が行われた日時付近に通信の履歴に相当する点や線が見られる。

# 最後に

初めてAWSIoTをさわることもあり、いろいろ調べながら通信ができるところまでたどり着いたので、自分の備忘録的な意味合いで情報を記載した。まだ、AWSの扉を開いたに過ぎないから、これからいろいろ試してみたいと思う。