iBeacon温度センサーを作るまで その1


ビーコンのMajor値を場所、Minor値を温度の値としてアドバタイズして、
それを受信する温度管理アプリを作るまでのメモ。

## 参考
Bluetooth仕様 [Bluetooth Specifications](https://developer.bluetooth.org/gatt/Pages/default.aspx)

開発環境セットアップ方法 [【改訂版】BLE112 / 113 の開発環境を Mac に構築する](http://d.hatena.ne.jp/shu223/20140421/1398117215)

参考にさせて頂くiBeacon送信ソース [slackhappy/ble112/beacon](https://github.com/slackhappy/ble112/tree/master/beacon)

BGScript関連 [BLEデバイス製作とIPHONEからのコントロールの基本](http://www.laksmido.com/bledemo/iPhoneBLE112.pdf)

## 調査

Bluetoothの設定はBGScriptで開発できる。以下4ファイルを作成してout.hexを生成する。

* gatt.xml
* hardware.xml
* beacon.bgs
* project.xml

```project.xml

<project>
    <gatt in="gatt.xml" />
    <hardware in="hardware.xml" />    
    <script in="beacon.bgs" />
    <image out="out.hex" />    
</project>

```

ビーコン送信のgattとbgsが何やっているか調べてみた。

```gatt.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!—- 標準サービスUUID 0x1800 = 汎用アクセスプロファイルGAP -—>
    <service uuid="1800">
      <description>Generic Access Profile</description>

      <!—- 標準キャラクタリスティックタイプUUID 0x2A00 = デバイス名称 -—>
      <characteristic uuid="2a00">
        <properties read="true" const="true" />
        <value>iBeacon Demo</value>
      </characteristic>

      <!—- 標準キャラクタリスティックタイプUUID 0x2a01 = 外観 -—>
      <characteristic uuid="2a01">
        <properties read="true" const="true" />
        <value type="hex">4142</value>
      </characteristic>
    </service>

    <!—- 標準サービスUUID 0x180A = デバイス情報(すべてオプション。無くてもよい？) -—>
    <service uuid="180A">
      <description>Device Information</description>
      
      <!—- 標準キャラクタリスティックタイプUUID 0x2a29 = メーカー名 -—>
      <characteristic uuid="2a29">
        <properties read="true" const="true" />
        <value>Bluegiga</value>
      </characteristic>
      
      <!—- 標準キャラクタリスティックタイプUUID 0x2a28 = ソフトウェアリビジョン -—>
      <characteristic uuid="2a28">
        <properties read="true" const="true" />
        <value>1.0</value>
      </characteristic>
      
      <!—- 標準キャラクタリスティックタイプUUID 0x2a26 = ファームウェアリビジョン -—>
      <characteristic uuid="2a26">
        <properties read="true" const="true" />
        <value>25</value>
      </characteristic>
　　　 
      <!—- 標準キャラクタリスティックタイプUUID 0x2a24 = モデル番号 -—>
      <characteristic uuid="2a24">
        <properties read="true" const="true" />
        <value>BLE112</value>
      </characteristic>
    </service>

    <!—- ユーザー独自定義タイプのUUIDは128ビット -—>
    <!—- 7548d6e0-3476-11e3-aa6e-0800200c9a66は何でもよい？ -—>
    <service uuid="7548d6e0-3476-11e3-aa6e-0800200c9a66" advertise="true">
      <description>iBeacon Service</description>
      
      <!—- id属性を付けるとbgsファイルから参照できる(idはキャラクタリスティックのみ付けられる) -—>
      <characteristic uuid="7548d6e1-3476-11e3-aa6e-0800200c9a66" id="xgatt_beacon_uuid">
        <description>UUID</description>
        <properties read="true" write="true" />
        
        <!—- UUID値 -—>
        <value length="16" type="hex">E2C56DB5DFFB48D2B060D0F5A71096E0</value>
      </characteristic>
      <characteristic uuid="7548d6e2-3476-11e3-aa6e-0800200c9a66" id="xgatt_beacon_major">
        <description>Major</description>
        <properties read="true" write="true" />
        
        <!—- Major値 -—>
        <value length="2" type="hex">0001</value>
      </characteristic>
      <characteristic uuid="7548d6e3-3476-11e3-aa6e-0800200c9a66" id="xgatt_beacon_minor">
        
        <!—- Minor値 -—>
        <description>Minor</description>
        <properties read="true" write="true" />
        <value length="2" type="hex">0002</value>
      </characteristic>
      <characteristic uuid="7548d6e4-3476-11e3-aa6e-0800200c9a66" id="xgatt_beacon_tx">
        
        <!—- 送信電波出力 -—>
        <description>Tx Power</description>
        <properties read="true" write="true" />
        <value length="1" type="hex">BC</value>
      </characteristic>
      <characteristic uuid="7548d6e5-3476-11e3-aa6e-0800200c9a66" id="xgatt_beacon_adv">
        
        <!—- ペイロードデータ。bgs内で作成するのでvalueは空 -—>
        <description>Advertising Payload</description>
        <properties read="true"/>
        <value length="30" type="hex"></value>
      </characteristic>
    </service>
</configuration>
```

```beacon.bgs

# 変数は32bit-integer。必ず定義が必要
dim load_result
dim load_len
dim uuid_value(16)
dim major_value(2)
dim minor_value(2)
dim tx_value(1)
dim ps_beacon_uuid
dim ps_beacon_major
dim ps_beacon_minor
dim ps_beacon_tx
dim adv_data(30) # custom adv data

# Boot event listener
event system_boot(major, minor, patch, build, ll_version, protocol_version, hw)
  
  # ‘$’を付けると16進数
  ps_beacon_uuid = $8000 

  # PS Storeから読み込み。GATT event listernerの方が先に呼ばれる（のだろう）
  # PS Storeにはユーザーデータを保存することができて、8000から807Fのキーが利用可能。それぞれ32Bytes保存可能。
  call flash_ps_load(ps_beacon_uuid)(load_result, load_len, uuid_value(0:16))

  # xgatt_beacon_uuidの値をuuid_valueに出力
  call attributes_write(xgatt_beacon_uuid, 0, load_len, uuid_value(0:16))
  
  ps_beacon_major = $8001
  call flash_ps_load(ps_beacon_major)(load_result, load_len, major_value(0:2))
  call attributes_write(xgatt_beacon_major, 0, load_len, major_value(0:2))
  ps_beacon_minor = $8002
  call flash_ps_load(ps_beacon_minor)(load_result, load_len, minor_value(0:2))
  call attributes_write(xgatt_beacon_minor, 0, load_len, minor_value(0:2))
  ps_beacon_tx = $8003
  call flash_ps_load(ps_beacon_tx)(load_result, load_len, tx_value(0:1))
  call attributes_write(xgatt_beacon_tx, 0, load_len, tx_value(0:1))

  # iBeacon用のパケットを生成
  adv_data( 0:1) = $02 # ad field length = 2 bytes
  adv_data( 1:1) = gap_ad_type_flags   # ad field type = 0x01 (Flags)
  adv_data( 2:1) = $06 # 3.C.18.1: 00000110b  generaldisc, no BR/EDR

  adv_data( 3:1) = $1a # ad field length = 26 bytes
  adv_data( 4:1) = $ff # 3.C.18.11 manufacturer-specific data
  adv_data( 5:1) = $4c # Apple, Inc.
  adv_data( 6:1) = $00 # Apple, Inc.
  adv_data( 7:1) = $02 # iBeacon header, part 1
  adv_data( 8:1) = $15 # iBeacon header, part 2 (maybe length?)
  adv_data(9:16) = uuid_value(0:16)
  adv_data(25:2) = major_value(0:2)
  adv_data(27:2) = minor_value(0:2)
  adv_data(29:1) = tx_value(0:1) # 2's complement of calibrated Tx Power

  # set advertising payload so it can be seen in the GATT
  call attributes_write(xgatt_beacon_adv, 0, 30, adv_data(0:30))

  # set the iBeacon data
  call gap_set_adv_data(0, 30, adv_data(0:30))
  call gap_set_mode(gap_user_data, gap_undirected_connectable)
end

# GATT event listener
event attributes_value(connection, reason, handle, offset, value_len, value)
  if handle = xgatt_beacon_uuid then
    call flash_ps_save(ps_beacon_uuid, 16, value(0:16))
    adv_data(9:16) = value(0:16)
  end if
  if handle = xgatt_beacon_major then
    call flash_ps_save(ps_beacon_major, 2, value(0:2))
    adv_data(25:2) = value(0:2)
  end if
  if handle = xgatt_beacon_minor then
    call flash_ps_save(ps_beacon_minor, 2, value(0:2))
    adv_data(27:2) = value(0:2)
  end if
  if handle = xgatt_beacon_tx then
    call flash_ps_save(ps_beacon_tx, 1, value(0:1))
    adv_data(29:1) = value(0:1) # 2's complement of calibrated Tx Power
  end if
  # update the advertising payload
  call attributes_write(xgatt_beacon_adv, 0, 30, adv_data(0:30))
  call gap_set_adv_data(0, 30, adv_data(0:30))
end

event connection_disconnected(handle, result)
  call gap_set_mode(gap_user_data, gap_undirected_connectable)
end
```

## わかったこと

```
adv_data(27:2) = minor_value(0:2)
```

の部分に温度を入れれば良さそう。

次は温度を取得するサンプルを調べてみる。