MQTT over BLE!Amazon FreeRTOSがBLEをサポートしたので試してみた #reinvent

AWS re:Invent 2018でAmazon FreeRTOSのBLEサポートが発表されました。ESP32開発ボードを使用して、MQTT over BLEのサンプルコードを試してみました。
2018.12.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

大阪IoT部の浜田です! 先日のre:Invent2018でAmazon FreeRTOSのBLEサポートが発表されましたね!

[速報] Amazon FreeRTOSでBLE(Bluetooth Low Energy)がサポートされました! #reinvent

まだベータ版ということですが、発表と合わせて投稿された公式ブログの記事を参考にサンプルコードなどを試してみました。

Amazon FreeRTOSでBluetooth Low Energyが利用可能、Espressif ESP32で利用する例 | Amazon Web Services ブログ

今回試すサンプルコードはAndroidアプリがMQTTプロトコルのプロキシとして動作します。ESP32上で動作するFreeRTOSプログラム-Androidアプリ間はBLE経由で通信し、Androidアプリ-AWS間は一般的なWi-Fiなどのネットワーク経由で通信を行います。

AWS、FreeRTOSプログラム、MQTTプロキシアプリの準備を順に進めて、最後に動作確認を行います。

  1. AWS IoTの設定
  2. AWS Cognitoの設定
  3. AWS IAMの設定
  4. FreeRTOSプログラムの準備(ESP32-DevKitC使用)
  5. MQTTプロキシアプリの準備(Android端末使用)
  6. 動作確認

必要なもの

  • PC
    • この記事ではMacを使用
  • ESP32開発ボード
    • この記事ではESP32-DevKitCのv2を使用
  • Android端末
    • Android 8.0, APIレベル26以降
    • この記事ではHUAWEI P20 lite(型式ANE-LX2J)を使用
  • AWSアカウント
  • USBケーブル
    • PCとESP32開発ボードの接続用
    • PCとAndroid端末の接続用

AWS IoTの設定

AWS IoTの設定を行います。

1. ポリシーの作成

AWS IoT Coreのコンソールへ移動します。

左側のナビゲーションペインから、「安全性>ポリシー」を選択します。

使用しているアカウントでまだポリシーが作成されていない場合は次のようなページが表示されます。「ポリシーの作成」を選択します。

※すでに何らかのポリシーが作成されている場合は次のようなページが表示されるので、「作成」を選択します。

作成するポリシーの名前を入力します。今回はesp32_mqtt_proxy_iot_policyという名前にします。

JSONを直接指定してステートメントを追加したいので、「アドバンストモード」を選択します。

下記のJSONを編集して使用します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
    }
  ]
}

以下のプレースホルダーをそれぞれ置換します。

  • <aws-region>: 使用しているリージョン
  • <aws-account-id>: アカウントID

例えば、使用しているリージョンがus-east-1、アカウントIDがxxxxxxxxxxxxの場合は次のように置換します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:xxxxxxxxxxxx:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:us-east-1:xxxxxxxxxxxx:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:us-east-1:xxxxxxxxxxxx:*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": "arn:aws:iot:us-east-1:xxxxxxxxxxxx:*"
    }
  ]
}

編集後のJSONを入力して、「作成」を選択します。

ここまでで、ポリシーの作成に関する作業は完了です。作成されたポリシーが一覧に表示されます。

2. モノの作成

引き続き、AWS IoT Coreのコンソールで作業します。

左側のナビゲーションペインから、「管理>モノ」を選択します。

使用しているアカウントでまだモノが登録されていない場合は次のようなページが表示されます。「モノの登録」を選択します。

※すでに何らかのモノが登録されている場合は次のようなページが表示されるので、「作成」を選択します。

「AWS Iot モノを作成する」というページが表示されます。「単一のモノを作成する」を選択します。

モノの名前を入力します。今回はesp32-bleという名前にします。

「次へ」を選択します。

「モノに証明書を追加」というページが表示されます。「証明書なしでモノを作成」を選択します。(※プロキシとして動作するAndroidアプリやiOSアプリがAWS Cognitoから認証を受ける構成にするので、あとで証明書を追加することもありません)

ここまでで、モノの作成に関する作業は完了です。作成されたモノが一覧に表示されます。

AWS Cognitoの設定

AWS Cognitoの設定を行います。

1. ユーザープールの作成

AWS Cognitoのコンソールへ移動して、ユーザープールの管理ページを表示します。「ユーザープールの管理」を選択します。

「ユーザープールを作成する」を選択します。

作成するユーザープールの名前を入力します。今回はesp32_mqtt_proxy_user_poolという名前にします。

「デフォルトを確認する」を選択します。

「アプリクライアントの追加…」を選択します。

「このユーザープールへのアクセス権限があるアプリクライアントはどれですか?」というページが表示されます。「アプリクライアントの追加」を選択します。

アプリクライアント名を入力します。今回はmqtt_app_clientという名前にします。

「クライアントシークレットを生成」のチェックボックスがONになっていることを確認してから、「アプリクライアントの作成」を選択します。

追加する予定のアプリクライアントが確認のために表示されます。「プールの詳細に戻る」を選択します。

アプリクライアントが設定されていることを確認してから、「プールの作成」を選択します。

ユーザープールが作成中であることを示す表示が行われるので少し待機します。

「ユーザープールは正常に作成されました。」と表示されます。

次の手順でAWS Cognitoに新しいIDプールを作成しますが、そのときに必要になるIDなどをメモしておきます。

まず、「ユーザープールID」をメモします。

次に、ナビゲーションペインから「アプリクライアント」を選択します。

「アプリクライアントID」をメモします。

ここまでで、ユーザープールの作成に関する作業は完了です。

2. IDプールの作成

AWS Cognitoのコンソールへ移動して、IDプールの管理ページを表示します。「IDプールの管理」を選択します。

※すでになんらかのIDプールが作成されている場合は、一覧ページが表示されます。「新しいIDプールの作成」を選択してください。

作成するIDプールの名前を入力します。今回はmqtt_proxy_identity_poolという名前にします。

「認証プロバイダー」を選択して、折りたたまれている表示を開きます。

「Cognito」のタブを選択し、さきほどユーザープールの作成時にメモしておいた、ユーザープールIDとアプリクライアントIDを入力します。

「プールの作成」を選択します

「許可」を選択します。認証されたIDと認証されていないIDに対する新しいIAMロールが作成されます(※この記事では自動で設定される名前を使用します。同名のIAMロールがすでに存在する場合はエラーメッセージが表示されるので、「詳細を表示」から任意のロール名を入力して進めます)。

次の手順で、認証されたIDに対するIAMロールにポリシーを追加するので、作成されたIAMロールの名前をメモしておきます。

IDプールの一覧ページを表示して、さきほど作成したIDプールを選択します。

「IDプールの編集」を選択します。

「認証されたロール」に割り当てられているロール名をメモします。

ここまでで、IDプールの作成に関する作業は完了です。

AWS IAMの設定

AWS Cognitoによって認証されたIDに割り当てられているIAMロールにポリシーを追加することで、認証情報とAWS IoTポリシーを紐付けます。

1. ポリシーの追加

AWS IAMコンソールで、さきほどメモしたロールを検索して選択します。

「インラインポリシーの追加」を選択します。

「JSON」のタブを選択します。

表示された入力欄に下記のJSONをそのまま入力します。

{
   "Version": "2012-10-17",
   "Statement": [
   {
      "Effect": "Allow",
      "Action": [
         "iot:AttachPolicy",
         "iot:AttachPrincipalPolicy",
         "iot:Connect",
         "iot:Publish",
         "iot:Subscribe"
      ],
      "Resource": "*"
   }]
}

「Review Policy」を選択します。

作成するポリシーの名前を入力して、「Create policy」を選択します。今回は「mqttProxyCognitoPolicy」という名前にします。

IAMロールに対して、ポリシーが追加されたことが確認できます。

ここまでで、AWSの設定は完了です。

FreeRTOSプログラムの準備(ESP32-DevKitC使用)

ESP32開発ボードに対してFreeRTOSプログラムの書き込みを行います。

1. USBシリアル通信ドライバーのインストール

※macOS Mojave 10.14.2を使用する手順を記載します。それ以外の環境については下記の参考手順を確認にしてください。

PC上でビルドしたFreeRTOSプログラムは、USBシリアル通信経由でESP32開発ボードに書き込む必要があります。まずは、ESP32-DevKitC向けのドライバーをインストールします(厳密にはESP32-DevKitに組み込まれているUSBシリアル変換ICのドライバー)。

下記のページに移動します。

https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

各プラットフォーム向けのドライバーの一覧の中から、「Download for Macintosh OSX(v5)」を見つけて、「Download VCP」を選択してダウンロードします。

ダウンロードしたzipファイルを解凍して、「SiLabsUSBDriverDisk.dmg」を実行します。

「Agree」を選択します。

「Silicon Labs VCP Driver.pkg」を実行します。

「続ける」を選択します。

使用許諾を確認の上、「続ける」を選択します。

「同意する」を選択します。

「インストール」を選択します。

「"セキュリティ"環境設定を開く」を選択します。

「一般」タブの内容を表示し、開発元の「Silicon Laboratories Inc」のソフトウェアがブロックされたことを確認の上、「許可」を選択します。

インストーラーのウィンドウでドライバーのインストールが開始されるので少し待ちます。

インストールが完了しました。「閉じる」を選択してインストーラーを終了します。

これで、Mac PCにESP32-DevKitCを接続すると、USBシリアル通信のデバイスとして認識され、シリアルポートとして/dev/直下にデバイスファイルが作成されます。

2. シリアルポートの確認

ESP32-DevKitCを接続します。

デバイスファイルが存在するか確認します。

$ ls /dev/tty.S*
/dev/tty.SLAB_USBtoUART

この/dev/tty.SLAB_USBtoUARTをシリアルポートとして設定することで、ESP32-DevKitCとシリアル通信できます(あとで設定します)。シリアル通信はプログラムの書き込みや、ESP32-DevKitCで動作中のプログラムとの双方向の通信で使用できます。

※異なるOSのPCを使用した場合や、PCにESP32-DevKitCを複数接続した場合、異なる開発ボードを使用した場合はデバイスファイルの名称が異なります。のちほど、FreeRTOSのプログラムをESP32-DevKitCを書き込むときにこのデバイスファイルを指定するので、メモしておいてください。

3. ツールチェインのセットアップ

※macOS Mojave 10.14.2を使用する手順を記載します。それ以外の環境については下記の参考手順を確認にしてください。

FreeRTOSプログラムをESP32向けにビルドできるように、ESP32の開発元Espressif社提供のツールチェインをインストールします。

ツールチェインがPythonのpyserialモジュールに依存しているため、pipで入れておきます。

$ sudo easy_install pip
$ sudo pip install pyserial

Espressif社のサイトからツールチェインをダウンロードして、~/esp以下に展開しておきます。

$ mkdir -p ~/esp
$ cd ~/esp
$ curl -O https://dl.espressif.com/dl/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz
$ tar -xzf xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz
$ ls
xtensa-esp32-elf
xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz

ツールチェインが~/esp/xtensa-esp32-elfに展開されました。

FreeRTOSのビルド時にツールチェインに含まれている実行ファイルが参照できるようにパスを通しておきます。

$ export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin

4. Amazon FreeRTOSのベータ版のダウンロード

この記事に記載されているログなどは`feature/ble-beta`ブランチの2018年12月18日時点のコミット(aws/amazon-freertos@95ed74a)を使用した場合の出力です。

Amazon FreeRTOSのソースコードをダウンロードします。

今回試すMQTT over BLEのサンプルコードはfeature/ble-betaブランチに含まれているので、そのブランチを指定してgitでcloneします。

$ cd ~/esp
$ git clone -b feature/ble-beta --single-branch https://github.com/aws/amazon-freertos

5. シリアルポートの設定

FreeRTOSのソースコードをビルドする前に、ビルドしたプログラムを書き込めるようにシリアルポートを設定します。

まず、ESP32-DevKitCの作業用のディレクトリに移動します(makeコマンドで作業します)。

$ cd ~/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make

次に、make menuconfigというコマンドを実行します。

$ make menuconfig

コマンドを実行したターミナル上で次のようなメニューが表示されます。

このメニューの項目の選択はキーボードの上下左右キーで行います。

Enterキーを押すと、選択状態の下部のコマンドが実行されます。

  • Select: 上下キーで選択中の項目の実行(サブメニューへの移動や設定変更)
  • Exit: 終了(またはサブメニューからもどる)
  • Help: 操作方法の表示
  • Save: 変更した設定の保存
  • Load: 設定の読み込み

例えば、次の表示の場合はSelectが選択されているので、Enterキーを押すとSDK tool configurationのサブメニューに移動します。

基本的な操作方法を把握したところで、シリアルポートの設定変更を行います。

上下キーを使用して、Serial flasher configを選択状態にしてEnterキーを押します。

(/dev/tty.SLAB_USBtoUART) Default serial portが選択状態になっていることを確認の上、Enterキーを押します。

ここでシリアルポートとして、さきほど確認したデバイスファイルの絶対パスを入力するのですが、先にBackspaceキーを数回押して、入力済みの内容をすべて消します。

/dev/tty.SLAB_USBtoUARTを入力して、Enterキーを押します。

※Windowsを使用している場合や、ESP32-DevKitC以外の開発ボードを使用している場合は確認時にメモしておいたシリアルポートを入力してください。

Serial flasher configのメニューが表示され、Default serial portが入力したシリアルポートに変わっていることを確認します。

設定を保存するので、左右キーを使用してSaveを選択状態にして、Enterキーを押します。

Enterキーを押します。

Enterキーを押します。

左右キーでExitを選択状態にして、Enterキーを押します。

左右キーでExitを選択状態にして、Enterキーを押します。

make menuconfigが終了し、ターミナルに次のような内容が出力されているはずです。

... (省略)

*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.

GENCONFIG

6. デバイス名の確認

FreeRTOSのサンプルコードの内容の確認や、変更を行っていきます。

まずは、BLE通信のアドバタイズパケットに含めて送信されるデバイス名を確認します。

~/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/common/config_files/aws_ble_config.hbleconfigDEVICE_NAMEという定数でデバイス名が定義されているのでlessコマンドや任意のテキストエディタで確認します。

$ less ~/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/common/config_files/aws_ble_config.h
/* Device name for this peripheral device. */
#define bleconfigDEVICE_NAME                     "ESP32"

定数bleconfigDEVICE_NAMEの値ESP32をメモしておきます。動作確認するときに、アドバタイズパケットを受信したAndroidアプリの画面にこのデバイス名が表示されます。

"Device name for this peripheral device."と記述されているとおり、今回試すサンプルコードでは、AndroidアプリがBLE通信におけるセントラル、ESP32-DevKitC上で動作するFreeRTOSプログラムがペリフェラルです。

7. AWSのクレデンシャルを設定

FreeRTOSのサンプルコードにAWS IoTの情報を記述する必要があるので、確認のためにAWS IoTコンソールに移動します。

「設定」を選択します。

「エンドポイント」の内容をメモします。

次に、「管理>モノ」を選択し、作成済みのIoTモノの名前をメモします。

メモした情報をソースコードに記述するのでAWS IoTコンソールから離れましょう。

~/esp/amazon-freertos/demos/common/include/aws_clientcredential.hというファイルを任意のテキストエディタで編集します。

$ vi ~/esp/amazon-freertos/demos/common/include/aws_clientcredential.h

まず、次のような記述を見つけます(記述されている内容で検索してください)。

// ...

/*
 * MQTT Broker endpoint.
 */
static const char clientcredentialMQTT_BROKER_ENDPOINT[] = "Paste AWS IoT Broker endpoint here.";


/* Use of a "define" and not a "static const" here to be able to
* use pre-compile concatenation on the string. */
#define clientcredentialIOT_THING_NAME "Paste AWS IoT Thing name here."

// ...

上記の記述のPaste AWS IoT Broker endpoint here.Paste AWS IoT Thing name here.を、それぞれメモしておいたエンドポイントとIoTモノの名前に変更します。

例えば、エンドポイントがxxxxxxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com、IoTモノの名前がesp32-bleの場合は次のように変更します。

// ...

/*
 * MQTT Broker endpoint.
 */
static const char clientcredentialMQTT_BROKER_ENDPOINT[] = "xxxxxxxxxxxxxxxxxx.iot.us-east-1.amazonaws.com";


/* Use of a "define" and not a "static const" here to be able to
* use pre-compile concatenation on the string. */
#define clientcredentialIOT_THING_NAME "esp32-ble"

// ...

編集を終えたら、忘れずに保存しましょう。

8. ソースコードのビルド

FreeRTOSプログラムをビルドします。

ツールチェインの実行ファイルのパスを通す設定を行っていない場合は、改めて設定しておきます(.bashrcに設定するなどしている場合は不要です)。

$ export PATH=$PATH:$HOME/esp/xtensa-esp32-elf/bin

ESP32-DevKitCの作業用のディレクトリに移動します(さきほどシリアルポートを設定したときと同じディレクトリです)。

$ cd ~/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make

makeコマンドを実行してプログラムをビルドします。2分〜5分ほどかかるので終了するまで待ちます。

$ make
... (5分から10分ほどコンパイルが走る)
esptool.py v2.6-beta1
To flash all build output, run 'make flash' or:
python /Users/hamada.hideki/esp/amazon-freertos/lib/third_party/mcu_vendor/espressif/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/tty.SLAB_USBtoUART --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /Users/hamada.hideki/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make/build/bootloader/bootloader.bin 0x20000 /Users/hamada.hideki/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make/build/aws_demos.bin 0x8000 /Users/hamada.hideki/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make/build/partitions_example.bin

上記のTo flash all build output, run 'make flash' or ...のように、次のステップを示すメッセージが表示されればビルドに成功しています。

9. プログラムの書き込み

PCにESP32-DevKitCを接続して、改めてシリアルポートのデバイスファイルが認識されていることを確認します。

ls /dev/tty.S*
/dev/tty.SLAB_USBtoUART

前述のmakeコマンドの出力の最後で示されているとおり、make flashコマンドを使用して、ESP32-DevKitCにビルドしたプログラムを書き込みます。

$ make flash
Flashing binaries to serial port /dev/tty.SLAB_USBtoUART (app at offset 0x20000 )...
esptool.py v2.6-beta1
Serial port /dev/tty.SLAB_USBtoUART
Connecting........___
... (省略)

Leaving...
Hard resetting via RTS pin...

10. プログラムの実行とモニター

書き込んだプログラムは、ESP32-DevKitCの電源投入時やリセットボタンの押下時に開始されます。

また、make monitorコマンドを実行することでプログラムが最初から開始され、プログラムのシリアル出力がターミナル上に表示されます。

$ make monitor
MONITOR
--- WARNING: Serial ports accessed as /dev/tty.* will hang gdb if launched.
--- Using /dev/cu.SLAB_USBtoUART instead...
--- idf_monitor on /dev/cu.SLAB_USBtoUART 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
... (省略)
0 0 [main] [INFO ][MQTT][0] MQTT library successfully initialized.
1 0 [main] Write code signing certificate...
2 0 [main] Key provisioning done...
... (省略)
3 49 [Btc_task] [INFO ][DEMO][49] Successfully set the scan Response data

4 50 [Btc_task] [INFO ][DEMO][50] Started advertisement. Listening for a BLE Connection.

make monitorを終了するときはCtrl+]キーを押してください。

最後の"Started advertisement"という出力はBLE通信におけるアドバタイズパケットの送信が開始されていることを示しています。 このアドバタイズパケットによって、Androidアプリや、iOSアプリがこのデバイスの存在を気づくことができます。

ここまででFreeRTOSプログラムの準備は完了です。

MQTTプロキシアプリの準備(Android端末使用)

Android端末で動作するMQTTプロキシアプリの準備を行います。

0. Androidアプリの開発環境の準備

以下のドキュメントを参考にすでに存在するAndroidプロジェクトを実行できる環境を用意してください。

サンプルアプリに必要なSDKとビルドツールがインストールされているか確認します。

「SDK Platform」タブで「Android 8.0 (Oreo)」のSDKがインストールされているか確認します(インストールされていなければインストールしてください)。

次に、「SDK Tools」タブで右下の「Show Package Details」をONにして、「Android SDK Build-Tools」の折りたたみを開きます。

「Android SDK Build-Tools」の28.0.2がインストールされているか確認します(インストールされていなければインストールしてください)。

1. サンプルアプリのソースコードをダウンロード

この記事に記載されているログなどは`beta`ブランチの2018年12月21日時点のコミットaws/amazon-freertos-ble-android-sdk@dab3dadを使用した場合の出力です。

FreeRTOSプログラムとAWS IoT間でプロキシとして動作するAndroidアプリのソースコードをダウンロードします。

今回試すMQTT over BLEのサンプルコードはbetaブランチに含まれているので、そのブランチを指定してgitでcloneします。

$ cd ~/esp
$ git clone -b beta --single-branch https://github.com/aws/amazon-freertos-ble-android-sdk

2. サンプルアプリのAndroidプロジェクトを開く

Android Studioを起動して、「Open an existing Android Studio project」を選択します。

さきほどcloneした~/esp/amazon-freertos-ble-android-sdkディレクトリを指定します。

初めてプロジェクトを開いた場合、自動でGradle syncという処理が走ります。終了するまで待ちます。

途中で以下のようなダイアログが表示される場合がありますが、「Don't remind me again for this project」を選択します。

「Sync」タブに「synced successfully」という表示が行われたらGradle syncに成功しています。ここで失敗する場合、SDKの不足など、開発環境の調査が必要です。

4. AWS Cognito IDプールの情報を確認

これから、サンプルアプリのファイルにAWSの情報などを記述していきます。Android Studioから離れて、AWSに移動しましょう。

まずはIDプールの情報を確認します。AWS Cognitoコンソールに移動して、「「IDプールの管理」を選択します。

作成済みのIDプールを選択します。

「サンプルコード」を選択します。

プラットフォームで「Android」を選択し、「IDプールのID」と「リージョン」をメモします。

5. AWS Cognito ユーザープールの情報を確認

ユーザープールの情報を確認します。AWS Cognitoコンソールに移動して、「ユーザープールの管理」を選択します。

作成済みのユーザープールを選択します。

「プールID」をメモします。さきほどのIDプールのIDとは異なるので、区別して管理しましょう。

「アプリクライアント」を選択します。

「詳細を表示」を選択します。

「アプリクライアントID」と「アプリクライアントのシークレット」をメモします。

6. AWS IoTの情報を確認

AWS IoTの情報を確認します。AWS IoTコンソールに移動して、「安全性」を選択します。

「ポリシー」を選択して、作成済みのポリシーを選択します。

ポリシー名をメモします。また、ポリシーARNに含まれているリージョンをメモします(以下のスクリーンショットだとus-east-1)。

7. awsconfiguration.jsonの編集

AWSから離れて、Android Studioの操作にもどりましょう。

まずは、awsconfiguration.jsonに、AWS CognitoのIDプールとユーザープールの情報を記述します。

~/esp/amazon-freertos-ble-android-sdk/app/src/main/res/raw/awsconfiguration.jsonの内容を表示すると次のような内容になっています。

{
  "UserAgent": "MobileHub/1.0",
  "Version": "1.0",
  "CredentialsProvider": {
    "CognitoIdentity": {
      "Default": {
        "PoolId": "Federated Identities -> Edit identity pool -> Identity pool ID. (eg. us-west-2:fc4d19b1-873f-44d8-bdcf-3a8e7aabf3ea)",
        "Region": "Your Region. (eg. us-east-1)"
      }
    }
  },
  "IdentityManager": {
    "Default": {}
  },
  "CognitoUserPool": {
    "Default": {
      "PoolId": "UserPool -> General settings -> Pool Id. (eg. us-east-1_example)",
      "AppClientId": "UserPool -> General settings -> App clients -> Show Details. (eg. 3tcegaot7efa8abgn1fxnebq5)",
      "AppClientSecret": "UserPool -> General settings -> App clients -> Show Details. (eg. dse11rx91vs1t9600uacc0ssw1byju8em3k60271n748s26ts9l)",
      "Region": "Your Region. (eg. us-east-1)"
    }
  }
}
JSONの要素
CredentialsProvider.CognitoIdentity.Default.PoolId IDプールのID
CredentialsProvider.CognitoIdentity.Default.Region IDプールのリージョン
CognitoUserPool.Default.PoolId ユーザープールのID
CognitoUserPool.Default.AppClientId ユーザープールのアプリクライアントID
CognitoUserPool.Default.AppClientSecret ユーザープールのアプリクライアントのシークレット
CognitoUserPool.Default.Region ユーザープールのリージョン

それぞれ、メモした内容で置き換えてください。

{
  "UserAgent": "MobileHub/1.0",
  "Version": "1.0",
  "CredentialsProvider": {
    "CognitoIdentity": {
      "Default": {
        "PoolId": "IDプールのID",
        "Region": "IDプールのリージョン"
      }
    }
  },
  "IdentityManager": {
    "Default": {}
  },
  "CognitoUserPool": {
    "Default": {
      "PoolId": "ユーザープールのID",
      "AppClientId": "ユーザープールのアプリクライアントID",
      "AppClientSecret": "ユーザープールのアプリクライアントのシークレット",
      "Region": "ユーザープールのリージョン"
    }
  }
}

4. DemoConstants.javaの編集

Android Studioを使用してDemoConstants.javaに、AWS CognitoのIDプールとAWS IoTのポリシーの情報を記述します。

~/esp/amazon-freertos-ble-android-sdk/app/src/main/java/com/amazon/aws/freertosandroid/DemoConstants.javaの内容を表示すると次のような内容になっています。

public class DemoConstants {
    /*
     * Replace with your AWS IoT policy name.
     */
    final static String AWS_IOT_POLICY_NAME = "Your AWS IoT policy name";
    /*
     * Replace with your AWS IoT region, eg: us-west-2.
     */
    final static String AWS_IOT_REGION = "us-west-2";
    /*
     * Replace with your Amazon Cognito Identity pool ID. Make sure this matches the pool id in
     * awsconfiguration.json file.
     */
    final static String COGNITO_POOL_ID = "us-west-2:xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    /*
     * Replace with your Amazon Cognito region, eg: Regions.US_WEST_2.
     */
    final static Regions COGNITO_REGION = Regions.US_WEST_2;
    /*
     * Replace with the desired MTU value to set between the BLE device and the Android device.
     * Note: this is only required if you want to set MTU that is different than the original MTU
     * value on the BLE device. However, even after you set the MTU, the actual MTU value may be
     * smaller than what you set, because it is limited by the maximum MTU the devices can support.
     * Please refer to API documentation for AmazonFreeRTOSManager.class#setMtu.
     */
    static final int MTU = 512;
}
定数名
AWS_IOT_POLICY_NAME AWS IoTのポリシー名
AWS_IOT_REGION AWS IoTのリージョン
COGNITO_POOL_ID AWS CognitoのIDプールのID
COGNITO_REGION AWS Cognitoのリージョンを示す列挙値(例: us-east-1の場合はRegions.US_EAST_1)

それぞれ、メモした内容に置き換えてください。

public class DemoConstants {
    /*
     * Replace with your AWS IoT policy name.
     */
    final static String AWS_IOT_POLICY_NAME = "AWS IoTのポリシー名";
    /*
     * Replace with your AWS IoT region, eg: us-west-2.
     */
    final static String AWS_IOT_REGION = "AWS IoTのリージョン";
    /*
     * Replace with your Amazon Cognito Identity pool ID. Make sure this matches the pool id in
     * awsconfiguration.json file.
     */
    final static String COGNITO_POOL_ID = "AWS CognitoのIDプールのID";
    /*
     * Replace with your Amazon Cognito region, eg: Regions.US_WEST_2.
     */
    final static Regions COGNITO_REGION = Regions.US_EAST_1;
    /*
     * Replace with the desired MTU value to set between the BLE device and the Android device.
     * Note: this is only required if you want to set MTU that is different than the original MTU
     * value on the BLE device. However, even after you set the MTU, the actual MTU value may be
     * smaller than what you set, because it is limited by the maximum MTU the devices can support.
     * Please refer to API documentation for AmazonFreeRTOSManager.class#setMtu.
     */
    static final int MTU = 512;
}

6. アプリのインストール

Android端末を接続して、Android Studioからデバッグ実行してみましょう。

以下のような画面が表示されます。

動作確認

準備はすべて完了しました。動作確認します。

1. アカウントの作成

AWS Cognitoに作成済みのユーザープールにアカウントを作成します。 Androidアプリの最初の画面の「Create New Account」を選択します。

「Username」、「Password」、「Email address」だけ入力して、「Sign Up」を選択します(※パスワードは大文字、小文字、数字、記号を含めてください)。

入力したメールアドレス宛に6桁のコードがAmazon Cognitoから送信されているので入力して、「Confirm」を選択します。

アカウント作成が成功したというメッセージのダイアログが表示、「OK」を選択するとすぐにログインされ、プロキシ処理の実行用画面が表示されます(表示されない場合は自分でログインすると表示できます)。

AWS Cognitoのユーザープールの管理画面で、作成されたアカウントを確認できます。パスワードを忘れた場合などは、ここからパスワードリセットのメールを送信したり、アカウントの削除が行なえます。

2. AWS IoTコンソールでメッセージを待ち受ける

これから、Androidアプリをプロキシとして動作させ、FreeRTOSから/freertos/demos/echoというトピックにメッセージを送信します。メッセージがトピックに届いていることを確認したいので、あらかじめ、AWS IoTコンソールでそのトピックをサブスクライブして待つことにします。

AWS IoTコンソールに移動して、「テスト」を選択します。 「トピックのサブスクリプション」にfreertos/demos/echoを入力して、「トピックへのサブスクライブ」を選択します。

このページをそのままにして、AndroidアプリとFreeRTOSプログラムの操作に移りましょう。

3. デバイスの検出

まだベータ版のサンプルコードなので、エラーなどがログにのみ出力されます。適宜、確認しながら進めてください。

まず、ターミナルに移動して、make monitorコマンドを実行して、動作確認中にFreeRTOSプログラムの出力を確認できるようにします(※ESP32-DevKitCとPCの接続を切っていた場合は改めて接続してください)。

$ cd ~/esp/amazon-freertos/demos/espressif/esp32_devkitc_esp_wrover_kit/make
$ make monitor
...
3 52 [Btc_task] [INFO ][DEMO][52] Successfully set the scan Response data
4 53 [Btc_task] [INFO ][DEMO][53] Started advertisement. Listening for a BLE Connection.

Started advertisement. Listening for a BLE Connection.という内容を最後に、出力が止まることを確認してください。

ターミナルはそのままにして、Androidアプリの以下の画面の操作に移ります。

「SCAN FOR BLE DEVICES」を選択して、数秒待つと、アドバタイズパケットを送信しているデバイスが表示されます。

このときAndriod StudioのLogcatでは、FreeRTOSプログラムが送信しているアドバタイズパケットを、Androidアプリが受信したことを示す出力が確認できます。

2018-12-24 14:23:28.814 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Found ble device: 30:AE:A4:01:46:56 RSSI: -66
2018-12-24 14:23:28.824 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Found ble device: 30:AE:A4:01:46:56 RSSI: -66
2018-12-24 14:23:29.357 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Found ble device: 30:AE:A4:01:46:56 RSSI: -54

4. デバイスに接続

デバイス名の横のトグルスイッチを選択します。AndroidアプリとFreeRTOSプログラムの接続が確立した場合、トグルスイッチがONの状態で維持されます(※切断されているにもかかわらずONになったままの場合もあるので、その場合は手動でOFFにしましょう)。

このとき、ターミナルではFreeRTOSが接続が確立したことを示す出力を行います。

5 26132 [Btc_task] [INFO ][DEMO][26132] BLE Connected to remote device, connId = 0

Android StudioのLogcatでは次の内容が確認できます。

2018-12-24 14:32:42.439 10252-10252/com.amazon.aws.freertosandroid I/DeviceScanFragment: connect switch isChecked: ON
2018-12-24 14:32:42.442 10252-10252/com.amazon.aws.freertosandroid D/BluetoothGatt: connect() - device: 30:AE:A4:01:46:56, auto: false
2018-12-24 14:32:42.442 10252-10252/com.amazon.aws.freertosandroid D/BluetoothGatt: registerApp()
2018-12-24 14:32:42.442 10252-10252/com.amazon.aws.freertosandroid D/BluetoothGatt: registerApp() - UUID=a0cbc70f-a659-4744-a8e6-33cc5fd2437d
2018-12-24 14:32:42.451 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
2018-12-24 14:32:42.452 10252-10252/com.amazon.aws.freertosandroid V/AudioManager: playSoundEffect   effectType: 0
2018-12-24 14:32:42.743 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=30:AE:A4:01:46:56
2018-12-24 14:32:42.744 10252-10279/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: BLE connection state changed: 0; new state: BLE_CONNECTED
2018-12-24 14:32:42.744 10252-10279/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Connected to GATT server.
2018-12-24 14:32:42.744 10252-10279/com.amazon.aws.freertosandroid I/DeviceScanFragment: BLE connection status changed to: BLE_CONNECTED
2018-12-24 14:32:42.745 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: discoverServices() - device: 30:AE:A4:01:46:56
2018-12-24 14:32:42.805 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: onSearchComplete() = Device=30:AE:A4:01:46:56 Status=0
2018-12-24 14:32:42.806 10252-10279/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Discovered Ble gatt services successfully.
2018-12-24 14:32:42.806 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: GattService: 00001801-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.807 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 00002a05-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.807 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: GattService: 00001800-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.807 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 00002a00-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.807 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 00002a01-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 00002aa6-0000-1000-8000-00805f9b34fb
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: GattService: 8a7f1168-48af-4efb-83b5-e679f932ff00
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 8a7f1168-48af-4efb-83b5-e679f932ff01
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 8a7f1168-48af-4efb-83b5-e679f932ff02
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: 8a7f1168-48af-4efb-83b5-e679f932ff03
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: GattService: a9d7166a-d72e-40a9-a002-48044cc3ff00
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: a9d7166a-d72e-40a9-a002-48044cc3ff01
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: a9d7166a-d72e-40a9-a002-48044cc3ff02
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: a9d7166a-d72e-40a9-a002-48044cc3ff03
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: a9d7166a-d72e-40a9-a002-48044cc3ff04
2018-12-24 14:32:42.808 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:  |-characteristics: a9d7166a-d72e-40a9-a002-48044cc3ff05
2018-12-24 14:32:42.810 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 0
2018-12-24 14:32:42.811 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: setCharacteristicNotification() - uuid: a9d7166a-d72e-40a9-a002-48044cc3ff02 enable: true
2018-12-24 14:32:42.813 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 1 Ble commands in the queue.
2018-12-24 14:32:42.813 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 2 Ble commands in the queue.
2018-12-24 14:32:42.814 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 3 Ble commands in the queue.
2018-12-24 14:32:42.814 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 4 Ble commands in the queue.
2018-12-24 14:32:42.814 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 5 Ble commands in the queue.
2018-12-24 14:32:42.814 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Getting current MTU.
2018-12-24 14:32:42.814 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Ble operation is in progress. There are 6 Ble commands in the queue.
2018-12-24 14:32:43.132 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: onDescriptorWrite for characteristic: MQTT_TX; Status: Success
2018-12-24 14:32:43.133 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 5
2018-12-24 14:32:43.135 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: setCharacteristicNotification() - uuid: a9d7166a-d72e-40a9-a002-48044cc3ff04 enable: true
2018-12-24 14:32:43.227 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: onDescriptorWrite for characteristic: MQTT_TXLARGE; Status: Success
2018-12-24 14:32:43.228 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 4
2018-12-24 14:32:43.229 10252-10279/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: There's no such service found with uuid: 3113a187-4b9f-4f9a-aa83-c614e11bff00
2018-12-24 14:32:46.232 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: Ble command has timeout since it has not received response from device after 3000ms
2018-12-24 14:32:46.233 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 3
2018-12-24 14:32:46.234 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: There's no such service found with uuid: 3113a187-4b9f-4f9a-aa83-c614e11bff00
2018-12-24 14:32:49.238 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: Ble command has timeout since it has not received response from device after 3000ms
2018-12-24 14:32:49.239 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 2
2018-12-24 14:32:49.240 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: There's no such service found with uuid: 3113a187-4b9f-4f9a-aa83-c614e11bff00
2018-12-24 14:32:52.244 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: Ble command has timeout since it has not received response from device after 3000ms
2018-12-24 14:32:52.244 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_DESCRIPTOR queue size: 1
2018-12-24 14:32:52.246 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: There's no such service found with uuid: 3113a187-4b9f-4f9a-aa83-c614e11bff00
2018-12-24 14:32:55.249 10252-10312/com.amazon.aws.freertosandroid W/AmazonFreeRTOSManager: Ble command has timeout since it has not received response from device after 3000ms
2018-12-24 14:32:55.250 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: READ_CHARACTERISTIC queue size: 0
2018-12-24 14:32:55.252 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: <-<-<- Reading from characteristic: DEVICE_MTU
2018-12-24 14:32:55.327 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> onCharacteristicRead status: Success
2018-12-24 14:32:55.328 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager:     with data: {"mtu":0}
2018-12-24 14:32:55.380 10252-10279/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Current MTU is set to: 0
2018-12-24 14:32:55.381 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: There's no ble command in the queue.

5. MTU値の変更

「More...」、「Set MTU」を選択します。

MTU値はBLE通信におけるパケットの最大サイズです。Androidアプリの内部ではBluetoothGatt#requestMtu(int)というAPIが実行されます。

512という値を要求し、Android StudioのLogcatでは実際に設定されたMTU値が出力されます。

2018-12-24 14:36:19.022 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Setting mtu to: 512
2018-12-24 14:36:19.022 10252-10252/com.amazon.aws.freertosandroid D/BluetoothGatt: configureMTU() - device: 30:AE:A4:01:46:56 mtu: 512
2018-12-24 14:36:19.058 10252-10252/com.amazon.aws.freertosandroid V/InputMethodManager: Reporting focus gain, without startInput
2018-12-24 14:36:19.127 10252-10279/com.amazon.aws.freertosandroid D/BluetoothGatt: onConfigureMTU() - Device=30:AE:A4:01:46:56 mtu=180 status=0
2018-12-24 14:36:19.127 10252-10279/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: onMTUChanged : 180 status: Success
2018-12-24 14:36:19.128 10252-10279/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: There's no ble command in the queue.

6. MQTTプロキシの実行

「More...」、「MQTT Proxy」を選択します。

「Mqtt Proxy」のトグルスイッチを選択します。

Androidアプリがプロキシとしての動作を開始し、FreeRTOSプログラムがパブリッシュしたメッセージがAWS IoTコンソールで確認できます。

認証情報などに問題がなければ、トグルスイッチがONの状態で維持されます。 FreeRTOSプログラムがパブリッシュを開始して、ターミナルでは次のような出力が確認できます。

6 11363 [pthread] [INFO ][MQTT][11363] Establishing new MQTT connection.
7 11363 [pthread] [INFO ][MQTT][11363] Waiting for operation CONNECT to complete.
8 11533 [pthread] [INFO ][MQTT][11533] MQTT operation CONNECT complete with result SUCCESS.
9 11533 [pthread] [INFO ][MQTT][11533] New MQTT connection 0x3ffd453c established.
10 11534 [pthread] [INFO ][MQTT][11534] MQTT SUBSCRIBE operation queued.
11 11534 [pthread] [INFO ][MQTT][11534] Waiting for operation SUBSCRIBE to complete.
12 11664 [pthread] [INFO ][MQTT][11663] MQTT operation SUBSCRIBE complete with result SUCCESS.
13 11664 [pthread] [INFO ][DEMO][11664] Sent: HelloWorld 1
14 11764 [pthread] [INFO ][DEMO][11764] Sent: HelloWorld 2
15 11864 [pthread] [INFO ][DEMO][11864] Sent: HelloWorld 3

Android StudioのLogcatでは、FreeRTOSがパブリッシュした内容をプロキシとしてAWS IoTにパブリッシュしていることが、Sending mqtt message to IoT on topic: freertos/demos/echo message: HelloWorld 1という出力で示されています。

2018-12-24 14:42:38.316 10252-10252/com.amazon.aws.freertosandroid I/MqttProxyFragment: mqtt proxy switch isChecked: ON
2018-12-24 14:42:38.316 10252-10252/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Enabling MQTT Proxy
2018-12-24 14:42:38.319 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_CHARACTERISTIC queue size: 0
2018-12-24 14:42:38.320 10252-10252/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: <-<-<- Writing to characteristic: MQTT_CONTROL  with data: {"proxyState":1}
2018-12-24 14:42:38.322 10252-10252/com.amazon.aws.freertosandroid V/AudioManager: playSoundEffect   effectType: 0
2018-12-24 14:42:38.478 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: onCharacteristicWrite for: MQTT_CONTROL; status: Success
2018-12-24 14:42:38.478 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: There's no ble command in the queue.
2018-12-24 14:42:42.930 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> Characteristic changed for: MQTT_TX with data: {"type":1,"clientID":"esp32-ble","brokerEndpoint":"xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com","brokerPort":8883,"userName":"","cleanSession":true}
2018-12-24 14:42:42.940 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Handling Mqtt Message type : 1
2018-12-24 14:42:42.951 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Connecting to IoT: xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com
2018-12-24 14:42:43.140 10252-10740/com.amazon.aws.freertosandroid I/AWSIotMqttManager: metrics collection is enabled, username: ?SDK=Android&Version=2.7.7
2018-12-24 14:42:43.141 10252-10740/com.amazon.aws.freertosandroid I/AWSIotMqttManager: resetting reconnect attempt and retry time
2018-12-24 14:42:43.141 10252-10740/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: mqtt connection status changed to: Connecting
2018-12-24 14:42:43.610 10252-10746/com.amazon.aws.freertosandroid I/AWSIotMqttManager: onSuccess: mqtt connection is successful.
2018-12-24 14:42:43.611 10252-10746/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: mqtt connection status changed to: Connected
2018-12-24 14:42:43.614 10252-10746/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_CHARACTERISTIC queue size: 0
2018-12-24 14:42:43.615 10252-10746/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: <-<-<- Writing to characteristic: MQTT_RX  with data: {"status":2,"type":2}
2018-12-24 14:42:43.677 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: onCharacteristicWrite for: MQTT_RX; status: Success
2018-12-24 14:42:43.677 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: There's no ble command in the queue.
2018-12-24 14:42:43.777 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> Characteristic changed for: MQTT_TX with data: {"type":8,"topics":["ZnJlZXJ0b3MvZGVtb3MvZWNobw=="],"qoSs":[0],"msgID":1}
2018-12-24 14:42:43.782 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Handling Mqtt Message type : 8
2018-12-24 14:42:43.794 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Subscribe message:
        type: 8
        msgId: 1
        topic: ZnJlZXJ0b3MvZGVtb3MvZWNobw==, qos: 0
2018-12-24 14:42:43.794 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Subscribing to IoT on topic : freertos/demos/echo
2018-12-24 14:42:44.802 10252-10312/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Sending SUB ACK back to device.
2018-12-24 14:42:44.814 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Processing BLE command: WRITE_CHARACTERISTIC queue size: 0
2018-12-24 14:42:44.816 10252-10312/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: <-<-<- Writing to characteristic: MQTT_RX  with data: {"msgID":1,"status":0,"type":9}
2018-12-24 14:42:44.929 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: onCharacteristicWrite for: MQTT_RX; status: Success
2018-12-24 14:42:44.929 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: There's no ble command in the queue.
2018-12-24 14:42:45.030 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> Characteristic changed for: MQTT_TX with data: {"type":3,"topic":"ZnJlZXJ0b3MvZGVtb3MvZWNobw==","qoS":0,"msgID":0,"payloadVal":"SGVsbG9Xb3JsZCAx"}
2018-12-24 14:42:45.038 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Handling Mqtt Message type : 3
2018-12-24 14:42:45.057 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Sending mqtt message to IoT on topic: freertos/demos/echo message: HelloWorld 1
2018-12-24 14:42:45.063 10252-10746/com.amazon.aws.freertosandroid I/AWSIotMqttManager: delivery is complete
2018-12-24 14:42:45.064 10252-10746/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Publish msg delivery status: Success
2018-12-24 14:42:46.078 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> Characteristic changed for: MQTT_TX with data: {"type":3,"topic":"ZnJlZXJ0b3MvZGVtb3MvZWNobw==","qoS":0,"msgID":0,"payloadVal":"SGVsbG9Xb3JsZCAy"}
2018-12-24 14:42:46.087 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Handling Mqtt Message type : 3
2018-12-24 14:42:46.096 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Sending mqtt message to IoT on topic: freertos/demos/echo message: HelloWorld 2
2018-12-24 14:42:46.101 10252-10746/com.amazon.aws.freertosandroid I/AWSIotMqttManager: delivery is complete
2018-12-24 14:42:46.101 10252-10746/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: Publish msg delivery status: Success
2018-12-24 14:42:47.028 10252-10295/com.amazon.aws.freertosandroid D/AmazonFreeRTOSManager: ->->-> Characteristic changed for: MQTT_TX with data: {"type":3,"topic":"ZnJlZXJ0b3MvZGVtb3MvZWNobw==","qoS":0,"msgID":0,"payloadVal":"SGVsbG9Xb3JsZCAz"}
2018-12-24 14:42:47.037 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Handling Mqtt Message type : 3
2018-12-24 14:42:47.049 10252-10295/com.amazon.aws.freertosandroid I/AmazonFreeRTOSManager: Sending mqtt message to IoT on topic: freertos/demos/echo message: HelloWorld 3
2018-12-24 14:42:47.057 10252-10746/com.amazon.aws.freertosandroid I/AWSIotMqttManager: delivery is complete

さきほどトピックをサブスクライブしたままにしていたAWS IoTコンソールに移動してみましょう。freertos/demos/echoトピックにメッセージが届いていることが確認できます。

AWS IoTコンソールを表示しているブラウザと、make monitorを実行しているターミナルを並べて表示するとわかりやすいです。

今回試したサンプルコードは、FreeRTOSプログラムが120回のパブリッシュを終えると、Androidアプリを介したAWS IoTとのコネクションを切断し、プログラムを終了します。

133 23664 [pthread] [INFO ][MQTT][23664] MQTT UNSUBSCRIBE operation queued.
134 23664 [pthread] [INFO ][MQTT][23664] Waiting for operation UNSUBSCRIBE to complete.
135 23678 [pthread] [INFO ][MQTT][23678] MQTT operation UNSUBSCRIBE complete with result SUCCESS.
136 23678 [pthread] [INFO ][MQTT][23678] Disconnecting MQTT connection 0x3ffd453c.
137 23679 [pthread] [INFO ][MQTT][23679] Waiting for operation DISCONNECT to complete.
138 23680 [pthread] [INFO ][MQTT][23680] MQTT operation DISCONNECT complete with result SUCCESS.
139 23680 [pthread] [INFO ][MQTT][23680] MQTT connection 0x3ffd453c disconnected.

さいごに

MQTT over Bluetooth Low Energyの通信を確認できました。

まだFreeRTOSによるトピックのサブスクライブの動作が確認できていないので、もう少し遊んでみたいと思います!

参考