小さなLine simple beaconを作る (nRF51822使用)

## 概要

- `17mm * 7mm * 2mm`くらいのサイズのモジュールでLine Simple beaconを実現できました。
- 使ったBLEモジュールは[BVMCN5103 (Braveridge社製)](http://www.products.braveridge.com/bvmcn5103-cfac-bk3/)です。
- [github](https://github.com/kopanitsa/simple-line-beacon-nrf51822)にソースおきました。

![IMG_2329.JPG](https://qiita-image-store.s3.amazonaws.com/0/42108/89ca162d-4209-a67c-f7dc-a6cead93bccc.jpeg)


## はじめに

2017年2月17日に、LINEがLine beaconの仕様を公開し、だれでもLine beaconを作ることができるようになりました。

- LINE Engineering Blogの記事
    - [ラズベリーパイでLINE Beaconが作成可能に！「LINE Simple Beacon」仕様を公開しました](https://engineering.linecorp.com/ja/blog/detail/117)
- LINE simple beaconの仕様書
    - [Github](https://github.com/line/line-simple-beacon/blob/master/README.ja.md)

LINE Engineer Blogの記事ではRaspberry PiやOSXでのbeaconの作成方法が紹介されています。しかし、これらのデバイスは少し大きいですよね。物理的にも大きいですし、消費電力も大きいですし、お値段も高価です。

そこで、もう少し小さなLine Beaconを作ることができないかと考えました。

## Line Simple Beaconとは

[公式ブログ](https://engineering.linecorp.com/ja/blog/detail/117)に詳しい記載があります。以下の流れでLINE simple beaconを使ってイベントを発生させることができます。

1. [開発者] LINE botと紐付いたLINE simple beaconを設置する。
2. [ユーザ] LINE botと友達になる。
3. [ユーザ] LINE simple beaconが設置されている場所に移動する。
4. [開発者] 3をトリガにして、LINE botがwebhookを投げる。
5. [開発者] webhookを受けて、メッセージを送ったりデータを取得したり...

## 小さなBLEモジュール

BLE搭載のモジュールは様々な物がありますが、今回はBraveridge社から発売されている[BVMCN5103](http://www.products.braveridge.com/bvmcn5103-cfac-bk3/)を使用しました。
このモジュールにはNordic Semiconductor社製の[nRF51822](https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF51822)というBLEチップが搭載されており、モジュールとして技適を取得しています。
開発にはNordic社のSDKを使用します。

ただ、このモジュールは基板に実装することを前提に開発されており、そのまま使用するには細かいはんだ付けが必要です。このモジュールを使いやすくした[ブレークアウトボード](http://www.products.braveridge.com/ble%E9%96%8B%E7%99%BA%E3%82%AD%E3%83%83%E3%83%88/bvmcn5103-bk-kit/)が発売されています。また、Braveridge社製以外の`nRF51822`搭載開発ボードでも開発が可能です。(今回ははんだづけをして、必要な線を直接引き出しました)

例:
[Brageridgeのブレークアウトボード](http://www.products.braveridge.com/ble%E9%96%8B%E7%99%BA%E3%82%AD%E3%83%83%E3%83%88/bvmcn5103-bk-kit/)
[Hoshidenのブレークアウトボード](https://www.switch-science.com/catalog/2803/)
[Nordicの評価ボード](http://www.digikey.com/product-detail/en/nordic-semiconductor-asa/NRF51-DK/1490-1038-ND/5022449)

## OSXでの開発方法

nRF51822をOSXで開発するために`Segger Embedded Studio`というIDEと、`Nordic社のマイコン用のSDK`を使用しました。開発環境を作る詳細は[Nordic社のブログ](https://devzone.nordicsemi.com/blogs/1032/segger-embedded-studio-a-cross-platform-ide-w-no-c/)に従います。(nRF51822前提のブログではないので、ところどころ読み替える必要があります。それは別途Qiitaに書きたいです、、、)

ひとまずLINE beaconをビルドしたいだけであれば、以下の手順でビルドできます。
1. [Segger Embedded Studio](https://www.segger.com/downloads/embeddedstudio)をダウンロードする。
2. [JLink開発環境](https://www.segger.com/downloads/jlink#)をインストールする。
3. [Nordic社のSDK(ver12.2)](https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF5-SDK#Downloads)をダウンロードする。
4. [github](https://github.com/kopanitsa/simple-line-beacon-nrf51822)からLine Simple Beaconのソースコードをダウンロードし、`<nRF5 SDK>/examples/ble_peripheral/ble_app_line_simple_beacon`に配置する。
5. `ble_app_line_simple_beacon/pca10028/s130/ses/ble_app_template_pca10028_s130.emProject`を開き、ビルド。

## モジュールへの書き込み方法

書き込みには[JLink Lite](https://www.segger.com/jlink-lite-arm.html)という書き込み用ボードが必要です。このあたりが面倒ですね。。
このあたりが参考になるかもしれません。
[BLEデバイスの開発環境を構築する（nRF51822 & MacOS編）](http://qiita.com/mkftr/items/6144fbb3f20e124731bf)

## BLEのadvertiseをLINE仕様に合わせる。

LINE simple beaconの仕様はこちらに記載されています。
https://github.com/line/line-simple-beacon/blob/master/README.ja.md

ポイントはこんな感じです。
1. アドバタイズのUUIDを`0xFE6F`にする。
2. アドバタイズに含めるServiceDataについて、Service UUIDを`0xFE6F`にする。
3. アドバタイズに含めるServiceDataのDataについて以下のようにする。

- 1byte目： `0x02` (LINE Simple Beacon FrameのFrame Type)
- 2byte目-7byte目: Line Botから発行されたLINE Simple Beacon FrameのHWID
- 8byte目： `0x7F` (Beaconの強さ。`0x7F`固定)
- 9byte目以降: Beaconにメッセージを含めることができる。現在は使われていない。

上記に従ってbyte列を定義し、

```
#define APP_ADV_DATA_LENGTH      0x0E /* m_beacon_info全体のbyte長 */
#define APP_LINE_FRAME_TYPE      0x02 /* 固定 */
#define APP_LINE_HWID            0xXX, 0xXX, 0xXX, 0xXX, 0xXX /* LINEbotから払い出される値 */
#define APP_LINE_TXPOWER         0x7F /* 固定 */
#define APP_LINE_MESSAGE         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde  /* メッセージ。ただし、現時点では特に処理されない */

static uint8_t m_beacon_info[APP_ADV_DATA_LENGTH] = 
{
    APP_LINE_FRAME_TYPE,
    APP_LINE_HWID,
    APP_LINE_TXPOWER,
    APP_LINE_MESSAGE
};
```

advertise dataの`service_uuid`として設定します。

```
static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advdata_t          advdata;

    memset(&advdata, 0, sizeof(advdata));

    ble_advdata_service_data_t service_data;
    service_data.data.p_data = (uint8_t *) m_beacon_info; /*　上で設定したbyte列を入れる */
    service_data.service_uuid = 0xFE6F; /* service UUIDを 0xFE6Fに設定する*/
    service_data.data.size   = APP_ADV_DATA_LENGTH;

    ...
}
```

## LINE beaconをwebhookにつなげる

LINE botにwebhookを設定した上で、スマホをLINE beaconの近くに置くとwebhookが発動します。
以下のようなjsonが飛んで来るので、適宜処理します。

```
[ { type: 'beacon',
replyToken: 'xxxxxxxxxxxxxxxxxxx',
source: { userId: 'Uxxxxxxxxxxxxxxxxxxxxxxxxxx', type: 'user' },
timestamp: xxxxxxxxx,
beacon: { hwid: 'XXXXXXXXXX', type: 'enter' } } ]
```

LINE botの設定方法はここが参考になると思いました。
http://qiita.com/n0bisuke/items/60523ea48109320ad4a5


## 今後

- まだ使われていませんが、LINE beaconのMessageプロパティが使えるようになると、beaconを通じて様々なデータをbotに送ることができるので色々おもしろいことができそうです。
- 書き込み機を使わなくても`mbed`仕様に従ってUSBで書き込めるデバイスもあるので、そっちのほうがお手軽に使えそうです。そちらも試してみてもいいかも。。
    - [mbed HRM1017をはじめよう](https://developer.mbed.org/teams/Switch-Science/wiki/mbed-HRM1017%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86)