INKBIRD IBS-TH2 Plus の動作解析で、
公式アプリが history data 拾ってて、
gatttool や hcitool で entry point までは確認できてるんだけど、
具体的にどういうデータ送れば、history data を拾えるのかが全く分からない。
で、Bluetooth 通信の sniffing をするしかないのでは?
みたいに思って、bluetooh sniffing とか bluetooh packet capture とかで検索してみると
で、今日、Pixel10a の発売予定で購入時に次回注文時に利用可能なポイント5000円付与みたいなメールが入ってて、
10a のスペックってどういう状況?って思って、検索して、
「開発者向けオプション」の項目に
え!?まさか!?
と思って「Android Bluetooth スヌープ ログ」とかで検索してみると以下のページを見つけた。
展開して
ってことで、少なくとも Android 上で動くアプリに関しては、追加コストゼロで Bluttooth の通信を好き勝手に観測できる!
素晴らしい!!!
なお、ログに記録されるのが ※1 のタイミングなのか ※2 タイミングなのかは要確認だが、
下記の結果を見る限りだと、多分 ※2 を取ってるんじゃないかと思われる。
「wireshark log コマンドラインツール」で検索してみたところ、
Ubuntu にも tshark のパッケージとして収録されているので、とりあえず
例えばこんな感じ
オプション -Y で与える display filter は
log を取った期間の確認は、head, tail の "Arrival Time:" を見れば良いので、以下のようにすれば良い。
と言うことで、大雑把に解析した結果は以下のようになった。
サンプル数 17859 (これはアプリ上の表示と一致)に対して、
0x0023 から notify で降って来るデータが int16le * 10 [sample/capture] * 358 [capture] = 3580 [sample] なんだけど、notify が 358 回ってのがどこから来ているのかが謎。
公式アプリが history data 拾ってて、
gatttool や hcitool で entry point までは確認できてるんだけど、
具体的にどういうデータ送れば、history data を拾えるのかが全く分からない。
で、Bluetooth 通信の sniffing をするしかないのでは?
みたいに思って、bluetooh sniffing とか bluetooh packet capture とかで検索してみると
- Zenn / @knot / 2024-08-20: Bluefruit LE Sniffer + WiresharkでBluetoothパケットを見るための準備
- びえびえ's Personal webpage / 2021-10-13: BLE Snifferを使ってデバッグしてみる
- Switch Science / nRF51822搭載 Bluefruit LE Sniffer
で、今日、Pixel10a の発売予定で購入時に次回注文時に利用可能なポイント5000円付与みたいなメールが入ってて、
10a のスペックってどういう状況?って思って、検索して、
- WIRED / 2026-02-21: グーグルの「Pixel 10a」は、見た目も中身もかなり“見覚えあり”
「開発者向けオプション」の項目に
- Bluetooth HCI スヌープログを有効化
え!?まさか!?
と思って「Android Bluetooth スヌープ ログ」とかで検索してみると以下のページを見つけた。
- Qiita / @KentaHarada / 2020-05-04: Updated: 2023-06-28: 【Android】Bluetooth HCIスヌープログの取り方
- Bluetooth HCI スヌープログを有効化 : 無効 → 有効
- Bluetooth : ON → OFF → ON
- ※1
- バグレポート : 「対話レポート」 or 「完全レポート」で「レポート」
- ドロワー内に「バグレポート #X の生成中」が通知
- ※2
- 通知が「バグレポート #1 の記録完了」になったらタップして共有(保存は転送)
展開して
- ./FS/data/misc/bluetooth/logs/btsnoop_hci.log
ってことで、少なくとも Android 上で動くアプリに関しては、追加コストゼロで Bluttooth の通信を好き勝手に観測できる!
素晴らしい!!!
なお、ログに記録されるのが ※1 のタイミングなのか ※2 タイミングなのかは要確認だが、
下記の結果を見る限りだと、多分 ※2 を取ってるんじゃないかと思われる。
「wireshark log コマンドラインツール」で検索してみたところ、
- momuki / 2025-04-07: TShark徹底解説:コマンドラインでのパケットキャプチャと解析ガイド
Ubuntu にも tshark のパッケージとして収録されているので、とりあえず
apt install tsharkして
MAC=**:**:**:**:**:** tshark -r $LOGFILE -Y "bthci_acl.src.bd_addr == $MAC or bthci_acl.dst.bd_addr == $MAC" -PVxみたいにすると、目的の Bluetooth Device のみの log を抽出できる。
例えばこんな感じ
$ tshark -r $LOGFILE -Y "bthci_acl.src.bd_addr == $MAC or bthci_acl.dst.bd_addr == $MAC" -PVx
933 20.335982 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 16 Sent Read By Type Request, Appearance, Handles: 0x0001..0xffff
Frame 933: 16 bytes on wire (128 bits), 16 bytes captured (128 bits)
Encapsulation type: Bluetooth H4 with linux header (99)
Arrival Time: Apr 6, 2026 14:28:34.243920000 JST
UTC Arrival Time: Apr 6, 2026 05:28:34.243920000 UTC
Epoch Arrival Time: 1775453314.243920000
[Time shift for this packet: 0.000000000 seconds]
[Time delta from previous captured frame: 0.003374000 seconds]
[Time delta from previous displayed frame: 0.000000000 seconds]
[Time since reference or first frame: 20.335982000 seconds]
Frame Number: 933
Frame Length: 16 bytes (128 bits)
Capture Length: 16 bytes (128 bits)
[Frame is marked: False]
[Frame is ignored: False]
Point-to-Point Direction: Sent (0)
[Protocols in frame: bluetooth:hci_h4:bthci_acl:btl2cap:btatt]
Bluetooth
Bluetooth HCI H4
[Direction: Sent (0x00)]
HCI Packet Type: ACL Data (0x02)
Bluetooth HCI ACL Packet
.... 0000 0000 0011 = Connection Handle: 0x003
..00 .... .... .... = PB Flag: First Non-automatically Flushable Packet (0)
00.. .... .... .... = BC Flag: Point-To-Point (0)
Data Total Length: 11
Data
[Connect in frame: 911]
[Source BD_ADDR: Google_**:**:** (5c:33:7b:d7:8f:6b)]
[Source Device Name: Pixel 7a]
[Source Role: Unknown (0)]
[Destination BD_ADDR: **:**:**:**:**:** (**:**:**:**:**:**)]
[Destination Device Name: sps]
[Destination Role: Unknown (0)]
[Current Mode: Unknown (-1)]
Bluetooth L2CAP Protocol
Length: 7
CID: Attribute Protocol (0x0004)
Bluetooth Attribute Protocol
Opcode: Read By Type Request (0x08)
0... .... = Authentication Signature: False
.0.. .... = Command: False
..00 1000 = Method: Read By Type Request (0x08)
Starting Handle: 0x0001
Ending Handle: 0xffff
UUID: Appearance (0x2a01)
0000 02 03 00 0b 00 07 00 04 00 08 01 00 ff ff 01 2a ...............*
...
オプション -Y で与える display filter は
[Protocols in frame: bluetooth:hci_h4:bthci_acl:btl2cap:btatt]
のところの protocols に従って、その下に表示されてる項目と値を参考にしつつ、- Wireshark / Display Filter Reference
log を取った期間の確認は、head, tail の "Arrival Time:" を見れば良いので、以下のようにすれば良い。
$ tshark -r btsnoop_hci.log -PVx | grep -E "^ *Arrival Time:" | awk 'NR==1;{last=$0}END{print last}'
Arrival Time: Apr 6, 2026 14:28:13.907938000 JST
Arrival Time: Apr 6, 2026 14:31:18.598784000 JST
と言うことで、大雑把に解析した結果は以下のようになった。
====
1032 22.254156 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 14 Sent Write Request, Handle: 0x0024 (Unknown: Matter Profile ID: Client Characteristic Configuration)
Characteristic Configuration Client: 0x0001, Notification
0000 02 03 00 09 00 05 00 04 00 12 24 00 01 00 ..........$...
history data の notify 準備を指示?
多分 0x002a に 0x01 書き込み notify 開始?
====
1035 22.758842 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 12 Sent Read Request, Handle: 0x0014 (Unknown: Unknown)
1037 22.838897 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 30 Rcvd Read Response, Handle: 0x0014 (Unknown: Unknown)
Value: 0000000000000078000000322d37ae4f00000000
0000 02 03 20 19 00 15 00 04 00 0b 00 00 00 00 00 00 .. .............
0010 00 78 00 00 00 32 2d 37 ae 4f 00 00 00 00 .x...2-7.O....
cfg data の取得
多分、記録間隔 2分 (= 120s = 0x0078)
を取得している?
====
1038 23.356538 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 02
0000 02 03 00 08 00 04 00 04 00 12 2a 00 02 ..........*..
0x002a へ 0x02 書き込み
多分、サンプル数と何かの値を取得
----
1041 23.649169 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: c34500002db50000000000000000000000000000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 c3 45 00 00 .. .......#..E..
0010 2d b5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -...............
> [0x45c3, 0xb52d] # [サンプル数, ???]
=> [17859, 46381]
> [0x45c3, 0x2d, 0xb5]
=> [17859, 45, 181] # [サンプル数, ???, ???]
多分サンプル数取得
====
1042 24.163703 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 01
0000 02 03 00 08 00 04 00 04 00 12 2a 00 01 ..........*..
多分、history data の notify 開始を指示?
----
1045 24.249567 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 2a09a10ba40adf09cb0935092d09ca08ca088108
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 2a 09 a1 0b .. .......#.*...
0010 a4 0a df 09 cb 09 35 09 2d 09 ca 08 ca 08 81 08 ......5.-.......
1046 24.343864 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 81083c084e0817081608ea07fd07c507ce07b807
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 81 08 3c 08 .. .......#...<.
0010 4e 08 17 08 16 08 ea 07 fd 07 c5 07 ce 07 b8 07 N...............
...
1425 49.271450 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 4b09620978099909a909ad09ae09b909c3090000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 4b 09 62 09 .. .......#.K.b.
0010 78 09 99 09 a9 09 ad 09 ae 09 b9 09 c3 09 00 00 x...............
$ tshark -r btsnoop_hci.log -PVx -Y "frame.number >= 1045 and frame.number <= 1425"|grep -E '^ [0-9]+ .*ATT 32 Rcvd' | wc
358 7160 55490
int16le * 10 [samples/capture] * 358 [capture] = 3580 [samples]
計算が合わない、、、
====
1426 49.783958 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 07
0000 02 03 00 08 00 04 00 04 00 12 2a 00 07 ..........*..
----
1430 49.869512 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 82e2000000000000000000000000000000000000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 82 e2 00 00 .. .......#.....
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0xe282
=> 57986
> [0x82, 0xe2]
=> [130, 226]
====
1477 50.410097 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 04
0000 02 03 00 08 00 04 00 04 00 12 2a 00 04 ..........*..
----
1480 50.498103 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: c34500002db50000000000000000000000000000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 c3 45 00 00 .. .......#..E..
0010 2d b5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -...............
> [0x45c3, 0xb52d] # [サンプル数, ???]
=> [17859, 46381]
> [0x45c3, 0x2d, 0xb5]
=> [17859, 45, 181] # [サンプル数, ???, ???]
多分サンプル数取得
====
1481 51.007938 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 03
0000 02 03 00 08 00 04 00 04 00 12 2a 00 03 ..........*..
----
1486 51.098983 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: cf0b7b0a010b410b450b950b8f0bd90bd60b270c
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 cf 0b 7b 0a .. .......#...{.
0010 01 0b 41 0b 45 0b 95 0b 8f 0b d9 0b d6 0b 27 0c ..A.E.........'.
...
1983 76.122083 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 871363132b131213fb12d912c812af12b3120000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 87 13 63 13 .. .......#...c.
0010 2b 13 12 13 fb 12 d9 12 c8 12 af 12 b3 12 00 00 +...............
$ tshark -r btsnoop_hci.log -PVx -Y "frame.number >=1486 and frame.number <= 1983"|grep -E '^ [0-9]+ .*ATT 32 Rcvd' | wc
358 7160 55490
int16le * 10 [samples/capture] * 358 [capture] = 3580 [samples]
====
1984 76.645559 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002a (Unknown: Mopria Alliance BLE)
Value: 08
0000 02 03 00 08 00 04 00 04 00 12 2a 00 08 ..........*..
----
1987 76.811558 **:**:**:**:**:** (sps) → Google_**:**:** (Pixel 7a) ATT 32 Rcvd Handle Value Notification, Handle: 0x0023 (Unknown: Matter Profile ID)
Value: 22a0000000000000000000000000000000000000
0000 02 03 20 1b 00 17 00 04 00 1b 23 00 22 a0 00 00 .. .......#."...
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
====
1989 77.385458 Google_**:**:** (Pixel 7a) → **:**:**:**:**:** (sps) ATT 13 Sent Write Request, Handle: 0x002d (Unknown: FIDO2 secure client-to-authenticator transport)
Value: 06
0000 02 03 00 08 00 04 00 04 00 12 2d 00 06 ..........-..
サンプル数 17859 (これはアプリ上の表示と一致)に対して、
0x0023 から notify で降って来るデータが int16le * 10 [sample/capture] * 358 [capture] = 3580 [sample] なんだけど、notify が 358 回ってのがどこから来ているのかが謎。
タグ

コメントをかく