|
| 1 | +# Event Notes: Pixel Buds Pro 2 (`libmaestro` / `libgfps`) — Group W, GATT handle↔UUID mapping (`CAP-034`) |
| 2 | + |
| 3 | +**Status:** ⬜ Not yet captured. Skeleton prepared for `CAP-014-FINDINGS.md` §8's recommended next |
| 4 | +step: a session combining (1) a confirmed-unlimited HCI snoop snaplen and (2) a genuine GATT |
| 5 | +cache-miss for the *entire* database (not just the GATT service, `CAP-014-FINDINGS.md` §4). |
| 6 | + |
| 7 | +**Method for this session — a hybrid not yet tried, per the maintainer's own device availability:** |
| 8 | +Group W's Option (b) (a phone that has never connected to this Buds unit) was originally intended |
| 9 | +for the Pixel 9a, but the maintainer confirmed this specific Pixel 9a *has* connected to this Buds |
| 10 | +unit before — so Option (b)'s own precondition doesn't hold as-is. This session instead combines |
| 11 | +Option (a)'s cache-clearing action (`pm clear com.android.bluetooth`) **applied to the Pixel 9a** |
| 12 | +(GrapheneOS) rather than the Pixel 7a used throughout the rest of this project, using nRF Connect |
| 13 | +as the GATT client (the same third-party-client approach that got `CAP-017` a genuine, if |
| 14 | +truncated, discovery walk). Fill in each `[ ]`/`___` below as the session happens — do not |
| 15 | +pre-fill any log-derived value (frame numbers, exact timestamps) before the capture exists. |
| 16 | + |
| 17 | +## Log Metadata |
| 18 | + |
| 19 | +| Field | Value | |
| 20 | +|------------------|-----------------------------------------------------| |
| 21 | +| Capture ID | `CAP-034` | |
| 22 | +| Group(s) | W (`GATT-001` — GATT handle↔UUID mapping, cache-busted via `pm clear com.android.bluetooth` on a phone not otherwise used in this project's captures) | |
| 23 | +| Date | `___` (fill in) | |
| 24 | +| Firmware version | `___` (confirm on-screen if possible — no official Pixel Buds app is used this session, see below, so this may have to stay ⚪ ASSUMPTION `release_5.203` carried over from the most recent capture) | |
| 25 | +| Test device | Pixel 9a, GrapheneOS `___` (Android/GrapheneOS version — check Settings → About phone). **Client app: nRF Connect for Mobile (Nordic Semiconductor)** — official Pixel Buds Companion App **not installed** this session (see Preparation below) | |
| 26 | +| Video file | `CAP-034-recording.mp4` — `___`s, `___`–`___` local time | |
| 27 | +| Log file | `CAP-034-btsnoop_hci.log` — `___`s, `___` packets, `___`–`___` local time | |
| 28 | +| Buds MAC (partial, per `AGENTS.md` §7/§9) | `04:00:6e:cf:6e:07` (expected — same physical Buds/case used throughout this project; confirm on capture) | |
| 29 | + |
| 30 | +**Capture-integrity pre-flight (do this immediately after extraction, before any analysis — per |
| 31 | +`CAP-014-FINDINGS.md` §0's method and `CAPTURE_BLUETOOTH_HCI_SNOOP.md` §6's snaplen gotcha):** |
| 32 | + |
| 33 | +``` |
| 34 | +$ capinfos CAP-034-btsnoop_hci.log |
| 35 | +# check: "Packet size limit" should read "(not set)" / "inferred: 262144" or similar — NOT a small value |
| 36 | +
|
| 37 | +$ tshark -r CAP-034-btsnoop_hci.log -T fields -e frame.number -e frame.cap_len -e frame.len \ |
| 38 | + | awk '$2!=$3 {c++} END{print "mismatches:", c+0}' |
| 39 | +# expect: mismatches: 0 |
| 40 | +``` |
| 41 | + |
| 42 | +If this fails (truncated), stop before spending analysis time — re-extract via §3 step 3's raw |
| 43 | +`FS/data/log/bt/btsnoop_hci.log` / `FS/data/misc/bluetooth/logs/btsnoop_hci.log` path instead of |
| 44 | +the `btsnooz.py` fallback (the fallback is what produced `CAP-017`'s truncation). |
| 45 | + |
| 46 | +## Preparation checklist (before recording) |
| 47 | + |
| 48 | +- [x] Pixel Buds Companion App: **not installed** on the Pixel 9a for this session — not needed |
| 49 | + (GATT-001 only needs a generic GATT client; matches this project's own established Pixel 9a |
| 50 | + baseline, `CAPTURE_BLUETOOTH_HCI_SNOOP.md` §1's device table: "no Pixel Buds app"). |
| 51 | +- [x] Confirmed: this Pixel 9a **has** connected to this Buds unit before (per this session's own |
| 52 | + preparation) — a real cache risk, not a hypothetical one. Run, in this order: |
| 53 | + 1. `adb shell pm clear com.android.bluetooth` (clears **all** Bluetooth pairings on the |
| 54 | + 9a, not just the Buds' — confirm this is acceptable; re-pairing any other device on |
| 55 | + this phone afterward is expected). |
| 56 | + 2. Clear nRF Connect's own app cache/data too — `adb shell pm clear <nrf connect package>` |
| 57 | + (check the actual installed package name) or Settings → Apps → nRF Connect → Storage → |
| 58 | + Clear storage/cache. `CAP-004-FINDINGS.md` §6 already found nRF Connect's on-screen |
| 59 | + service list can be served from the app's *own* cache even when `com.android.bluetooth` |
| 60 | + itself has none — clearing only one of the two risks a false "it worked" read from the |
| 61 | + UI that the HCI log won't back up. |
| 62 | + - *(A full Settings → System → Reset options → "Reset Wi-Fi, mobile & Bluetooth" would also |
| 63 | + work, but is more than this needs — it additionally wipes Wi-Fi networks and every other |
| 64 | + paired Bluetooth device on the phone. `pm clear com.android.bluetooth` alone is the |
| 65 | + targeted equivalent; use the full reset only if `pm clear` turns out not to be available/ |
| 66 | + sufficient.)* |
| 67 | +- [x] Bluetooth HCI snoop logging enabled (Developer options), then **reboot** the Pixel 9a |
| 68 | + (recommended default per `CAPTURE_BLUETOOTH_HCI_SNOOP.md` §2 step 5 — more reliable than a |
| 69 | + plain toggle). |
| 70 | +- [x] USB debugging enabled, `adb devices` shows the 9a as `device` (not `unauthorized`/`offline`). |
| 71 | +- [x] A way to note wall-clock timestamps of your own actions during the session (§1.3). |
| 72 | +- [x] Confirm the Buds are currently **not** bonded to the 9a on screen (Settings → Connected |
| 73 | + devices) before starting — if they still show up bonded, the `pm clear` above didn't take; |
| 74 | + re-check before proceeding. |
| 75 | + |
| 76 | +## Procedure (per `CAPTURE_BLUETOOTH_HCI_SNOOP.md` Group W + §4.2's Pixel-9a session shape) |
| 77 | + |
| 78 | +1. Start video recording (wall-clock overlay visible) and HCI snoop logging. |
| 79 | +2. Open the Buds case, press the pairing button. **[`PAIR-001`]** |
| 80 | +3. In nRF Connect's **Scanner** tab, find and tap **CONNECT** on the Buds. Note the exact time. |
| 81 | + **[`GATT-001`]** |
| 82 | +4. Let discovery run — do not interact for a few seconds after connecting, so the initial |
| 83 | + MTU-exchange + discovery burst is cleanly isolated (mirrors `CAP-017`'s 18:31:39.58–41.94 |
| 84 | + window). **[`GATT-001`]** |
| 85 | +5. Once nRF Connect's **CLIENT** tab populates, scroll through the **full** service list |
| 86 | + on screen (top to bottom) so every service/characteristic name is video-visible, in case the |
| 87 | + wire log needs a video cross-check the way `CAP-017`'s truncated log did. |
| 88 | +6. **Drill down into "Unknown Service" (`109b862f-…`)** specifically — tap each of its |
| 89 | + characteristics, use "Read" where available, to trigger characteristic-level (not just |
| 90 | + service-level) declaration traffic. This is the specific action `CAP-014`/`CAP-017` never |
| 91 | + completed. **[`GATT-001`]** |
| 92 | +7. Do **not** open or read "Accessory Non-Owner Service" — out of scope per `DECISIONS.md` |
| 93 | + ADR-008 (`PROJECT.md` non-goals). Skip it entirely if it appears in the list. |
| 94 | +8. System SSP pairing dialog should appear at some point (classic BR/EDR bonding) — confirm it. |
| 95 | + Note the exact time. **[`PAIR-001`]** |
| 96 | +9. Idle ~30–60s once fully connected/paired, without touching anything, to capture any |
| 97 | + spontaneous status traffic. **[`BATT-003`]** |
| 98 | +10. Optional, if time allows: disconnect and reconnect once, as an isolated pair of actions. |
| 99 | + **[`PAIR-003`]** |
| 100 | +11. Stop video recording and HCI snoop logging. Keep the session short — don't let it run long |
| 101 | + enough to risk on-device log rotation (§2's note). |
| 102 | +12. Extract via `adb bugreport` (§3) — check for the raw `btsnoop_hci.log` path first, before |
| 103 | + falling back to `btsnooz.py`. |
| 104 | + |
| 105 | +## Event Timeline |
| 106 | + |
| 107 | +*(Fill in after reviewing the video frame-by-frame against its wall-clock overlay, cross-checked |
| 108 | +against `CAP-034-btsnoop_hci.log` via `tshark` — per `AGENTS.md` §13. Add a row per distinct |
| 109 | +action/event; don't compress the discovery burst into one row without at least noting its start/end |
| 110 | +frame numbers, the way `CAP-017-EVENT-NOTES.md` did.)* |
| 111 | + |
| 112 | +| Time (local) | Action / Event | Initiator | Test-ID | Evidence in `CAP-034-btsnoop_hci.log` | |
| 113 | +|---|---|---|---|---| |
| 114 | +| `06:46:31` | Start video recording | — | — | — | |
| 115 | +| pre-`06:46:31` | `pm clear` / reboot already done pre-session — first frame of this session's log | — | — | frame `___` | |
| 116 | +| `06:47:06` | Open case, buds in pairing mode (visible on scanner) | User (Hardware) | `PAIR-001` | — | |
| 117 | +| `06:47:41.966` | Tap CONNECT in nRF Connect scanner | User (App) | `GATT-001` | frame `___` | |
| 118 | +| `06:47:42.147` - `06:47:45.490` | MTU exchange + discovery burst (Read By Type / Read By Group Type / Find Information) | App (Auto) | `GATT-001` | frames `___`–`___` | |
| 119 | +| `06:47:45` - `06:48:13` | CLIENT tab populated — full service list visible on screen (scrolling down) | User (App) | `GATT-001` | — | |
| 120 | +| `06:48:13.798` - `06:50:00` | Read individual characteristics (starts with Client Supported Features `2b29`, Fast pair Model ID `fe2c1233...`, etc.) | User (App) | `GATT-001` | frames `___` | |
| 121 | +| `06:51:05.069` | System SSP pairing dialog appears ("Koppelen met Pixel Buds Pro 2 van Ted?") | App/OS (Auto) | `PAIR-001` | frame `___` | |
| 122 | +| `06:51:08.000` | Confirmed SSP pairing dialog (tapped "Koppelen") | User (App) | `PAIR-001` | frame `___` | |
| 123 | +| `06:51:10.332` | Device successfully bonded | App/OS (Auto) | `PAIR-001` | frame `___` | |
| 124 | +| `06:51:13.568` | Disconnect (automatic ACL_DISCONNECT following bond completion) | OS (Auto) | `PAIR-003` | frame `___` | |
| 125 | +| `06:51:22.142` | Tap CONNECT again (Reconnect from nRF Connect UI) | User (App) | `PAIR-003` | frame `___` | |
| 126 | +| `06:51:23.765` | Service discovery on reconnect (should hit cache) | App (Auto) | `GATT-001` | frame `___` | |
| 127 | +| `06:51:37.000` - `06:51:40.000` | Drill into "Unknown Service" (`109b862f...`), tap Read on characteristics | User (App) | `GATT-001` | frames `___` | |
| 128 | +| `06:51:40` - `06:52:45` | Idle observation window | — | `BATT-003` | — | |
| 129 | +| `06:52:45` | End video recording | — | — | — | |
| 130 | + |
| 131 | +## Decode / Analysis |
| 132 | + |
| 133 | +*(Fill in after capture — isolate the Buds' own `chandle` first per `AGENTS.md` §13's CLI-hygiene |
| 134 | +rule and `CAP-014-FINDINGS.md` §4a's own worked example, in case another device's LE connection is |
| 135 | +in the same log. Then walk the `0x0c0X`/`0x0f2X` handle cluster the same way `CAP-014-FINDINGS.md` |
| 136 | +§4c did — command + raw hex per finding, per `PROJECT_RULES.md` §1 rule 4a.)* |
| 137 | + |
| 138 | +## Open Questions |
| 139 | + |
| 140 | +- 🔴 *(carry forward any that remain unresolved after this session)* |
| 141 | + |
| 142 | +--- |
| 143 | +https://github.com/tedsluis/opencontrolpixelbudspro2/blob/main/captures/CAP-034-Group_W/CAP-034-EVENT-NOTES.md - https://tedsluis.github.io/opencontrolpixelbudspro2/captures/CAP-034-Group_W/CAP-034-EVENT-NOTES |
0 commit comments