7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PowerUp3.0のBLEをHackして自作Appから操作してみた

Last updated at Posted at 2017-05-04

What is PowerUp3.0 ?

紙飛行機に装着して,ケータイから操作可能なラジコン化するキット.
プロペラの回転数と垂直尾翼の角度をコントロールして紙飛行機を自在に操縦できるようになる.

↓ 実物はこんなもの,プロペラのついたちっさいUnitを実物の紙飛行機に装着します.
2017-04-21_010546.JPG

↓ 公式はこちら
https://www.poweruptoys.com/products/powerup-v3

何をしたか?

Android/iOSから操作するためのAppは公式から公開されているが,
ケータイとPowerUp3.0とはBluetoothを使って通信する,とのことだったので,
通信ProtocolをHackすれば自作Appからも操作可能になるはず.
Bluetooth/BLEの勉強も兼ねて,PowerUp3.0を自作Appから操作するまでをまとめてみた.

Step1 : 通信Protocolの特定

Bluetooth通信,と一言でいわれても,ケータイとPowerUp3.0間でどういう通信をしているか,が全く不明なので,解析のとっかかりをつかむためにも,公式App動作中のBluetooth通信をPacket Dumpしてみる.

Androidの開発者設定にHCI Snoop Log有効化のOptionがあるらしく,これを使えば簡単にPacket Logが取れるらしい.

↓ こちらのページが分かりやすかったのでこれを参考に公式AppでPowerUp3.0を操作中のLogを取ってみる.
http://fromnorth.blogspot.jp/2015/02/bluetooth-hci.html

AndroidのADBを有効化 + HCI Snoop Log有効化
↓
PowerUp3.0 公式Appを起動して操作
↓
HCI Snoop Log無効化
(この時点でHCI Logファイルが書き出される)
↓
$adb shell pull /sdcard/btsnoop_hci.log .
でLogファイルを回収(Productによってファイルパスが変わるらしい)

取ったLogをWiresharkで見ると,↓ のようなPacketが大量に取れている.
プロペラ回転数のみを変更していたため,このPacketはプロペラ回転数制御Packetと思われる.
ble_log.png

Bluetooth HCI ACL Packet
HCI (Host Controller Interface)のPacket.
Frameの種類が4種類(HCI Command/Event, ACL Data, SCO Data)あり,そのうちの1つ(ACL)らしい.
非同期通信用のL2CAP Packet用に使われるとのこと.
http://www.wdic.org/w/WDIC/HCI%20(Bluetooth)

Bluetooth L2CAP Protocol
ACLの説明どおり,L2CAP Protocolが使われている.
CID(Channel ID) = 0x0004 → Attribute Protocol
はBluetooth 4.0(= BLE)以降サポートされているものの模様.
http://www.wdic.org/w/WDIC/L2CAP

Bluetooth Attribute Protocol
Opcode: Write Command
によって,
Service UUID = 86c3810ef17140d9a11726b300768cd6
Characteristic UUID = 86c3810e001040d9a11726b300768cd6
に対して,
Value=0a
の書込をしている模様.

Step2 : Android BT/BLE APIでPowerUp3.0のBLE情報をDumpする

使われているProtocolがBLEのAttribute Protocolなことがわかったので,AndroidのPublic APIでPowerUp3.0デバイスのBLEを情報をDumpしてみる.

Bluetooth GATT(Generic Attributes)
https://www.bluetooth.com/ja-jp/specifications/generic-attributes-overview

公式仕様によると,BLEデバイスは↓のような構造で情報を持っている.

GATT                         // BLEデバイスは1つのGATT(GATT Server)をもつ
    - Service                // GATTは復数(1つ以上)のServiceをもつ
        - Characteristic     // 1つのServiceは復数(1つ以上)のCharacteristicをもつ
            - Value          // 1つのCharacteristicは1つのValueをもつ
            - Descriptor     // 1つのCharacteristicは復数(1つ以上)のDescriptorをもつ
            - Descriptor
        - Characteristic
            - Value
            - Descriptor
    - Service
        - Service            // 1つのServiceが復数(1つ以上)のServiceを含むことがある
    - Service

これをAndroidのBluetooth APIを使ってすべてDumpすればいい.

Android Developer - Bluetooth Low Energy
https://developer.android.com/guide/topics/connectivity/bluetooth-le.html
↓のBluetoothGattからService取得→Characteristic/DescriptionのReadリクエスト,でOK.
https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html

GATTがもつ全Service/CharacteristicをDumpすると↓のような感じになるはず.

Service/Characteristic=UUID
service = 00001800-0000-1000-8000-00805f9b34fb
chara   = 00002a00-0000-1000-8000-00805f9b34fb
chara   = 00002a01-0000-1000-8000-00805f9b34fb
chara   = 00002a02-0000-1000-8000-00805f9b34fb
chara   = 00002a03-0000-1000-8000-00805f9b34fb
chara   = 00002a04-0000-1000-8000-00805f9b34fb

service = 00001801-0000-1000-8000-00805f9b34fb
chara   = 00002a05-0000-1000-8000-00805f9b34fb

service = 0000180a-0000-1000-8000-00805f9b34fb
chara   = 00002a23-0000-1000-8000-00805f9b34fb
chara   = 00002a24-0000-1000-8000-00805f9b34fb
chara   = 00002a25-0000-1000-8000-00805f9b34fb
chara   = 00002a26-0000-1000-8000-00805f9b34fb
chara   = 00002a27-0000-1000-8000-00805f9b34fb
chara   = 00002a29-0000-1000-8000-00805f9b34fb

service = 0000180f-0000-1000-8000-00805f9b34fb
chara   = 00002a19-0000-1000-8000-00805f9b34fb

service = 86c3810e-f171-40d9-a117-26b300768cd6
chara   = 86c3810e-0010-40d9-a117-26b300768cd6
chara   = 86c3810e-0020-40d9-a117-26b300768cd6
chara   = 86c3810e-0021-40d9-a117-26b300768cd6
chara   = 86c3810e-0040-40d9-a117-26b300768cd6

service = f000ffc0-0451-4000-b000-000000000000
chara   = f000ffc1-0451-4000-b000-000000000000
chara   = f000ffc2-0451-4000-b000-000000000000

PowerUp3.0のFirmwareのVersionによってはズレているものもあるかも.

Step3 : 各Characteristicの内容を調べる

[UUID=0000xxxx-0000-1000-8000-00805F9B34FB]
のパターンになっているUUIDが多いが,これはBluetooth Service Discovery Protocolで定められているBase UUIDというもので,特定の機能のために標準で予約されている.
https://www.bluetooth.com/specifications/assigned-numbers/service-discovery

GATT Services
https://www.bluetooth.com/specifications/gatt/services
GATT Characteristics
https://www.bluetooth.com/specifications/gatt/characteristics

[UUID=0451-4000-b000-000000000000]
のパターンが何者なのか不明だったが,TI社製ChipのOAD Service(Over the Air Download)に使うUUIDらしい.
https://e2e.ti.com/support/wireless_connectivity/bluetooth_low_energy/f/538/t/380928

公式App起動時にPowerUp3.0のFirmware Updateが走るときがあり,これに使っているのかな.

各Service/Characteristicをまとめると↓のような感じ

Service/Characteristic=UUID
service = 00001800-0000-1000-8000-00805f9b34fb → 0x1800 Generic Access
chara   = 00002a00-0000-1000-8000-00805f9b34fb → 0x2A00 Device Name
chara   = 00002a01-0000-1000-8000-00805f9b34fb → 0x2A01 Appearance
chara   = 00002a02-0000-1000-8000-00805f9b34fb → 0x2A02 Peripheral Privacy Flag
chara   = 00002a03-0000-1000-8000-00805f9b34fb → 0x2A03 Reconnection Address
chara   = 00002a04-0000-1000-8000-00805f9b34fb → 0x2A04 Peripheral Preferred Connection Parameters

service = 00001801-0000-1000-8000-00805f9b34fb → 0x1801 Generic Attribute
chara   = 00002a05-0000-1000-8000-00805f9b34fb → 0x2A05 Service Changed

service = 0000180a-0000-1000-8000-00805f9b34fb → 0x180A Device Information
chara   = 00002a23-0000-1000-8000-00805f9b34fb → 0x2A23 System ID 
chara   = 00002a24-0000-1000-8000-00805f9b34fb → 0x2A24 Model Number String
chara   = 00002a25-0000-1000-8000-00805f9b34fb → 0x2A25 Serial Number String
chara   = 00002a26-0000-1000-8000-00805f9b34fb → 0x2A26 Firmware Revision String
chara   = 00002a27-0000-1000-8000-00805f9b34fb → 0x2A27 Hardware Revision String
chara   = 00002a29-0000-1000-8000-00805f9b34fb → 0x2A29 Manufacturer Name String

service = 0000180f-0000-1000-8000-00805f9b34fb → 0x180F Battery Service
chara   = 00002a19-0000-1000-8000-00805f9b34fb → 0x2A19 Battery Level

service = 86c3810e-f171-40d9-a117-26b300768cd6 → PowerUp3.0独自のUUID
chara   = 86c3810e-0010-40d9-a117-26b300768cd6
chara   = 86c3810e-0020-40d9-a117-26b300768cd6
chara   = 86c3810e-0021-40d9-a117-26b300768cd6
chara   = 86c3810e-0040-40d9-a117-26b300768cd6

service = f000ffc0-0451-4000-b000-000000000000 → TI ChipのOAD機能
chara   = f000ffc1-0451-4000-b000-000000000000
chara   = f000ffc2-0451-4000-b000-000000000000

となり,消去法的に
[UUID=86c3810e-xxxx-40d9-a117-26b300768cd6]
がPowerUp3.0の制御用Service/Characteristicになっている模様.

Step4 : PowerUp3.0制御用Characteristic UUIDを調べる

[UUID=86c3810e-xxxx-40d9-a117-26b300768cd6]
の xxxx を 0010,0020,0021,0040,の4パターンそれぞれに適当に値を書き込んでみて,
PowerUp3.0の実機の挙動がどうなるか,を見ればどのUUIDがプロペラ回転数か尾翼角度かが分かる.

プロペラ回転数
[UUID=86c3810e-0010-40d9-a117-26b300768cd6]
1 byte 範囲で制御

垂直尾翼角度
[UUID=86c3810e-0021-40d9-a117-26b300768cd6]
Signed Integerで,
0 = Center
+/- = Right/Left

各CharacteristicのDescriptorを読み出せばHintが書かれているかもしれない.
PowerUp3.0の場合は,

86c3810e-0010-40d9-a117-26b300768cd6 → Engine Speed
86c3810e-0020-40d9-a117-26b300768cd6 → Rudder Angle
86c3810e-0021-40d9-a117-26b300768cd6 → Rudder 2 Angle
86c3810e-0040-40d9-a117-26b300768cd6 → Temperature

というDescriptorが入っている.
(Rudder AngleじゃなくRudder 2 Angleが制御用に使われているのはなぜだろう..)

これで後は適当にAndroid AppでSlider UIとか作ればPowerUp3.0を自作Appから制御できる.

まとめ

WireSharkのBluetooth Packet DumpとAndroidのBT/BLE APIを使って
PowerUp3.0のデータ構造を解析,公式App以外の自作AppからPowerUp3.0のデバイス制御ができた.

///---

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?