BLEを理解するため、まずはMicroPythonのubluetoothのscanを実行してみた。
スキャンした相手はKorgのKeyboard(BLE接続できる microKey Air)
BLEをスキャンするためのコードは以下。長くなるのでコールバック関数は省略しています。*1
import ubluetooth ble = ubluetooth.BLE() ble.irq(irq) ble.active(True) ble.gap_scan(2000, 30000, 30000)
GATTC_READ (0, b'\xb8\xd7\xaf3t\xXX', True, -93, b'\x02\x01\x06\x11\x07\x00\xc7\xc4N\xe3lQ\xa73K\xe8\xedZ\x0e\xb8\x03')
デバイスが見つかったというコールバックではなく、GATT Clientが
読み込んだというコールバック(gattc_read() has completed)。なぜ?? scanなのに??
戻り値の2つ目の値はMACアドレスのようで、
B8-D7-AF-33-74-XX
となり、これは村田製作所らしい。BLEのパーツとして村田製作所のを使っている??
戻り値の5つ目は、長さ21なのだが、、何の値なのか分からず。
コールバック上はgattc_read() has completedと判断しているが、実は_IRQ_SCAN_RESULTなのでは??と解釈。スキャンできたらマニュアルでは以下の値が返ることになっているが、、(addr_type, addr, adv_type, rssi, adv_data)
adv_type が Trueって何なのか??
長さ21の値は、adv_dataだろうと推測。
advertising data...
[02, 01, 06, 11, 07, 00, c7, c4, 4e, e3, 6c, 51, a7, 33, 4b, e8, ed, 5a, 0e, 0b8, 03]
[Length][Ad Type][Ad Data]の並びらしいので、
[02,01,06] は、Len:2 , type:01(Flags) , flag_06:(LE General Discoverable Mode + BE/EDR Not Support)
[11,07,00....03]は、Len:17,type:07(128bit UUID), UUID:00c7c44ee36c51a7334be8ed5a0eb803
値はよく分からんが、フォーマット上はつじつまが合う
スマフォ上でBLEスキャナを使って、同じようにKorgのキーボードをスキャンした。
すると、、上記の128bit UUIDはやはりアドバタイズ時のUUIDであることが分かった。しかし、、バイトの並びが逆だった。エンディアンの違いとでも言おうか。。先は長い。。
スキャンして見つけられたので、次はconnectだ。
>>> ble.gap_connect(0,b'\xb8\xd7\xaf3t\x80',1000) GAP procedure initiated: connect; peer_addr_type=0 peer_addr=b8:d7:af:33:74:80 scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=16 max_ce_len=768 own_addr_type=0
event : 64 (0x40) (0, 0, b'\xb8\xd7\xaf3t\x80')
サンプルソースによると、以下のペアで返却されるようなので、最初の値はconn_handleだろうと。
conn_handle, addr_type, addr, = data
GATTClientのdiscover_servicesメソッドを使ってサービスを走査してみた。
conn_handle = 0 ble.gattc_discover_services(conn_handle) GATT procedure initiated: discover all services
コールバックで以下が返却された。サービスの詳細はまだ調べられていないけど、スマフォのBLEスキャナーで表示されたサービス一覧と大体一致している。
>>> 256 0x100 (0, 1, 9, UUID16(0x1800)) 256 0x100 (0, 12, 15, UUID16(0x1801)) 256 0x100 (0, 16, 20, UUID16(0x180a)) 256 0x100 (0, 21, 24, UUID128('d0611e78-bbb4-4591-a5f8-487910ae4366')) 256 0x100 (0, 25, 28, UUID128('03b80e5a-ede8-4b33-a751-6ce34ec4c700'))
スマフォのBLEスキャナで調べていくと、以下のサービスが鍵盤入力のようであった。
(0, 25, 28, UUID128('03b80e5a-ede8-4b33-a751-6ce34ec4c700'))
■追記
少ししらべると、BLE MIDIという仕様があって、仕様書も公開されている。
仕様書の中にUUIDが定義されていて、
以下のUUIDは、MIDI Serviceを表すBLE MIDIで規定されたコードであった
[03b80e5a-ede8-4b33-a751-6ce34ec4c700]
bluepyで始めるBluetooth Low Energy(BLE)プログラミング | 株式会社アイ・プライド
bluepyで始めるBluetooth Low Energy(BLE)プログラミング | 株式会社アイ・プライド
さらにBLEライブラリで掘った結果、得られたサービスとキャラクタリスティック
(0, 1, 9, UUID16(0x1800)) (0, 2, 3, 2, UUID16(0x2a00)) b'microKEY2-25 Air\x00\x00\x00\x00\x00\x00') (0, 4, 5, 2, UUID16(0x2a01)) b'\x80\x00') (0, 6, 7, 10, UUID16(0x2a02)) 00 (0, 8, 9, 2, UUID16(0x2a04)) b'\x06\x00\t\x00\x00\x00\xc8\x00') (0, 12, 15, UUID16(0x1801)) (0, 13, 14, 34, UUID16(0x2a05)) b'\x01\x00\xff\xff') (0, 16, 20, UUID16(0x180a)) (0, 17, 18, 2, UUID16(0x2a29)) b'Korg Inc.') (0, 19, 20, 2, UUID16(0x2a24)) b'microKEY Air') (0, 21, 24, UUID128('d0611e78-bbb4-4591-a5f8-487910ae4366')) (0, 22, 23, 24, UUID128('8667556c-9a37-4c91-84ed-54ee27d90049')) (0, 25, 28, UUID128('03b80e5a-ede8-4b33-a751-6ce34ec4c700')) (0, 26, 27, 22, UUID128('7772e5db-3868-4112-a1a9-f2669d106bf3'))
*1:マニュアルとほぼ同じような関数を使っています https://docs.micropython.org/en/latest/library/ubluetooth.html#event-handling