From 0698c7cc6d55f3d74615fdd02de146fbec352a27 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 18:03:47 +0000 Subject: [PATCH 1/2] Document required BLE GATT services and characteristics. Add a BLE GATT reference section to the README listing the Tap and NUS services this SDK requires, plus optional feature characteristics, aligned with the other official Tap SDKs and internal BLE API docs (#42). Co-authored-by: Liron Ilouz --- Readme.md | 37 +++++++++++++++++++++++++++++++++++++ tapsdk/tap.py | 7 +++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 0d50e1f..2f69ed6 100644 --- a/Readme.md +++ b/Readme.md @@ -57,6 +57,43 @@ If no Tap is already connected at the OS level, `run()` will scan and wait for a Also make sure that you have updated your Tap device to the latest version. +### BLE GATT reference + +Tap devices expose a GATT server. This SDK discovers Tap by the proprietary Tap service UUID and then uses the Nordic UART Service (NUS) for mode commands. UUIDs below match the other official Tap SDKs (iOS / Android / Windows / Web) and the internal [Tap BLE API Documentation](https://tapwithus.atlassian.net/wiki/spaces/FIR/pages/426803201/Tap+BLE+API+Documentation). + +#### Required for this SDK + +These services/characteristics are required for a usable connection (device discovery, mode control, and tap events). The Windows SDK treats Tap Data + NUS RX as the minimum pair that identifies a Tap; this Python SDK additionally needs the Tap service UUID for scan/filter. + +| Role | UUID | Properties | Purpose | +| --- | --- | --- | --- | +| **Tap service** | `c3ff0001-1d8b-40fd-a56f-c7bd5d0f3370` | (service) | Advertised UUID used to find / filter Tap devices | +| Tap data | `c3ff0005-1d8b-40fd-a56f-c7bd5d0f3370` | Notify | Finger tap codes (`register_tap_events`) | +| **NUS service** | `6e400001-b5a3-f393-e0a9-e50e24dcca9e` | (service) | Nordic UART Service used for mode / input-type commands | +| NUS RX (mode) | `6e400002-b5a3-f393-e0a9-e50e24dcca9e` | Write | Write input-mode and input-type magic packets (`set_input_mode`, `set_input_type`); must be refreshed about every 10s while in controller/raw modes | + +#### Optional (feature-dependent) + +Notification setup is best-effort: missing characteristics are logged and skipped so older firmware still connects. + +| Characteristic | UUID | Properties | Purpose | +| --- | --- | --- | --- | +| Mouse data | `c3ff0006-1d8b-40fd-a56f-c7bd5d0f3370` | Notify | Optical / surface mouse motion (`register_mouse_events`) | +| UI / haptic | `c3ff0009-1d8b-40fd-a56f-c7bd5d0f3370` | Write | Vibration sequences (`send_vibration_sequence`) | +| Air gesture | `c3ff000a-1d8b-40fd-a56f-c7bd5d0f3370` | Notify / Write | Air gestures and mouse-mode state (`register_air_gesture_*`); TapXR | +| NUS TX (raw) | `6e400003-b5a3-f393-e0a9-e50e24dcca9e` | Notify | Raw sensor stream in raw mode (`register_raw_data_events`); requires Developer mode in TapManager | + +#### Standard services (present on device; not used by this SDK) + +| Service | UUID | Notes | +| --- | --- | --- | +| Device Information | `0000180a-0000-1000-8000-00805f9b34fb` | Firmware / hardware revision strings (other SDKs read `2a26` / `2a27`) | +| Battery Service | `0000180f-0000-1000-8000-00805f9b34fb` | Battery Level `2a19` | + +Other Tap-service characteristics exist on some firmware/SDK combinations (for example device name `c3ff0003-…` and data-request `c3ff000b-…` in the Android SDK) but are unused here. + +Constants live in [`tapsdk/tap.py`](tapsdk/tap.py). + ### Features This SDK implements two basic interfaces with a Tap device. diff --git a/tapsdk/tap.py b/tapsdk/tap.py index 255d6c6..0f04d48 100644 --- a/tapsdk/tap.py +++ b/tapsdk/tap.py @@ -11,14 +11,17 @@ logger = logging.getLogger(__name__) +# BLE GATT UUIDs used by Tap Strap / TapXR. +# Required for this SDK: Tap service (scan/filter), Tap data (notify), NUS service, +# and NUS RX (write input mode). See README "BLE GATT reference". tap_service = 'c3ff0001-1d8b-40fd-a56f-c7bd5d0f3370' nus_service = '6e400001-b5a3-f393-e0a9-e50e24dcca9e' tap_data_characteristic = 'c3ff0005-1d8b-40fd-a56f-c7bd5d0f3370' mouse_data_characteristic = 'c3ff0006-1d8b-40fd-a56f-c7bd5d0f3370' ui_cmd_characteristic = 'c3ff0009-1d8b-40fd-a56f-c7bd5d0f3370' air_gesture_data_characteristic = 'c3ff000a-1d8b-40fd-a56f-c7bd5d0f3370' -tap_mode_characteristic = '6e400002-b5a3-f393-e0a9-e50e24dcca9e' # nus rx -raw_sensors_characteristic = '6e400003-b5a3-f393-e0a9-e50e24dcca9e' # nus tx +tap_mode_characteristic = '6e400002-b5a3-f393-e0a9-e50e24dcca9e' # NUS RX (write) +raw_sensors_characteristic = '6e400003-b5a3-f393-e0a9-e50e24dcca9e' # NUS TX (notify) if platform.system() == "Darwin": From 3a71dd948243511e669fcbad17afac0f879a1633 Mon Sep 17 00:00:00 2001 From: Liron Date: Tue, 21 Jul 2026 23:19:20 +0300 Subject: [PATCH 2/2] Verify BLE GATT docs against firmware TAP_XR_develop. Re-check UUIDs and properties from ble-mcu-hw-v3-sdk-14.0, expand the README with the full firmware service/characteristic map, and note that the Tap UUID is advertised in the scan response (#42). Co-authored-by: Cursor --- Readme.md | 68 ++++++++++++++++++++++++++++++++++----------------- tapsdk/tap.py | 7 +++--- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/Readme.md b/Readme.md index 2f69ed6..73454fe 100644 --- a/Readme.md +++ b/Readme.md @@ -59,40 +59,62 @@ Also make sure that you have updated your Tap device to the latest version. ### BLE GATT reference -Tap devices expose a GATT server. This SDK discovers Tap by the proprietary Tap service UUID and then uses the Nordic UART Service (NUS) for mode commands. UUIDs below match the other official Tap SDKs (iOS / Android / Windows / Web) and the internal [Tap BLE API Documentation](https://tapwithus.atlassian.net/wiki/spaces/FIR/pages/426803201/Tap+BLE+API+Documentation). +Verified against firmware `tap_rd/ble-mcu-hw-v3-sdk-14.0` branch **`TAP_XR_develop`** (`ble_tap_service.c`, `services_init`, Nordic `ble_nus`). Also matches the other official Tap SDKs and [Tap BLE API Documentation](https://tapwithus.atlassian.net/wiki/spaces/FIR/pages/426803201/Tap+BLE+API+Documentation). -#### Required for this SDK +Tap base UUID: `c3ff0000-1d8b-40fd-a56f-c7bd5d0f3370` (16-bit offsets below). NUS is the standard Nordic UART base `6e400000-b5a3-f393-e0a9-e50e24dcca9e`. -These services/characteristics are required for a usable connection (device discovery, mode control, and tap events). The Windows SDK treats Tap Data + NUS RX as the minimum pair that identifies a Tap; this Python SDK additionally needs the Tap service UUID for scan/filter. +**Advertising:** primary adv carries HID (`0x1812`); Tap service UUID is in the **scan response**. Active scan (or OS-paired reconnect) is needed to see `c3ff0001-…` in advertised service lists. -| Role | UUID | Properties | Purpose | -| --- | --- | --- | --- | -| **Tap service** | `c3ff0001-1d8b-40fd-a56f-c7bd5d0f3370` | (service) | Advertised UUID used to find / filter Tap devices | -| Tap data | `c3ff0005-1d8b-40fd-a56f-c7bd5d0f3370` | Notify | Finger tap codes (`register_tap_events`) | -| **NUS service** | `6e400001-b5a3-f393-e0a9-e50e24dcca9e` | (service) | Nordic UART Service used for mode / input-type commands | -| NUS RX (mode) | `6e400002-b5a3-f393-e0a9-e50e24dcca9e` | Write | Write input-mode and input-type magic packets (`set_input_mode`, `set_input_type`); must be refreshed about every 10s while in controller/raw modes | +#### Services the firmware always registers + +From `services_init()` / device mediator on `TAP_XR_develop`: -#### Optional (feature-dependent) +| Service | UUID | Role | +| --- | --- | --- | +| HID | `00001812-0000-1000-8000-00805f9b34fb` | Keyboard / mouse HID over GATT | +| Battery | `0000180f-0000-1000-8000-00805f9b34fb` | Battery Level | +| Device Information | `0000180a-0000-1000-8000-00805f9b34fb` | FW / HW / serial strings | +| Buttonless DFU | Nordic DFU | FOTA bootloader trigger | +| **Tap** | `c3ff0001-1d8b-40fd-a56f-c7bd5d0f3370` | Proprietary events / commands | +| **NUS** | `6e400001-b5a3-f393-e0a9-e50e24dcca9e` | Mode / raw-sensor channel | -Notification setup is best-effort: missing characteristics are logged and skipped so older firmware still connects. +#### Required by this Python SDK -| Characteristic | UUID | Properties | Purpose | +Minimum used for discovery, mode control, and tap events (Windows SDK similarly requires Tap Data + NUS RX): + +| Role | UUID | FW properties | Purpose | | --- | --- | --- | --- | -| Mouse data | `c3ff0006-1d8b-40fd-a56f-c7bd5d0f3370` | Notify | Optical / surface mouse motion (`register_mouse_events`) | -| UI / haptic | `c3ff0009-1d8b-40fd-a56f-c7bd5d0f3370` | Write | Vibration sequences (`send_vibration_sequence`) | -| Air gesture | `c3ff000a-1d8b-40fd-a56f-c7bd5d0f3370` | Notify / Write | Air gestures and mouse-mode state (`register_air_gesture_*`); TapXR | -| NUS TX (raw) | `6e400003-b5a3-f393-e0a9-e50e24dcca9e` | Notify | Raw sensor stream in raw mode (`register_raw_data_events`); requires Developer mode in TapManager | +| Tap service | `c3ff0001-…` | (service; scan response) | Find / filter Tap | +| Tap data | `c3ff0005-…` | Notify | Tap codes (`register_tap_events`) | +| NUS service | `6e400001-…` | (service) | Mode channel | +| NUS RX | `6e400002-…` | Write | Input mode / type (`set_input_mode`, `set_input_type`); refresh ~every 10s in controller/raw | -#### Standard services (present on device; not used by this SDK) +#### Used optionally by this SDK -| Service | UUID | Notes | -| --- | --- | --- | -| Device Information | `0000180a-0000-1000-8000-00805f9b34fb` | Firmware / hardware revision strings (other SDKs read `2a26` / `2a27`) | -| Battery Service | `0000180f-0000-1000-8000-00805f9b34fb` | Battery Level `2a19` | +Notify setup is best-effort if a characteristic is missing on older devices. -Other Tap-service characteristics exist on some firmware/SDK combinations (for example device name `c3ff0003-…` and data-request `c3ff000b-…` in the Android SDK) but are unused here. +| Characteristic | UUID | FW properties | Purpose | +| --- | --- | --- | --- | +| Mouse data | `c3ff0006-…` | Notify, Write, WriteWithoutResponse | Surface mouse (`register_mouse_events`) | +| UI / haptic | `c3ff0009-…` | Write, WriteWithoutResponse | Vibration (`send_vibration_sequence`) | +| Air gesture | `c3ff000a-…` | Notify, WriteWithoutResponse, Read | Air gestures / mouse-mode state (`register_air_gesture_*`) | +| NUS TX | `6e400003-…` | Notify | Raw sensors (`register_raw_data_events`; Developer mode) | + +#### Other Tap-service characteristics (on device; unused here) -Constants live in [`tapsdk/tap.py`](tapsdk/tap.py). +Registered in `ble_tap_init()` on `TAP_XR_develop`: + +| Char | UUID | FW properties | Notes | +| --- | --- | --- | --- | +| Settings | `c3ff0002-…` | Read, Write | Device settings | +| Name | `c3ff0003-…` | Read, Write | BLE name (Android SDK) | +| Mapping RX | `c3ff0007-…` | Write, WriteWithoutResponse | Custom map upload | +| Mapping TX | `c3ff0008-…` | Notify | Custom map download | +| Data request | `c3ff000b-…` | Notify, WriteWithoutResponse, Read | State queries (Android SDK) | +| Kneron model ver | `c3ff000c-…` | Notify, Read | TapXR NPU model | +| Kneron FW ver | `c3ff000d-…` | Notify, Read | TapXR NPU firmware | + +Constants: [`tapsdk/tap.py`](tapsdk/tap.py). ### Features diff --git a/tapsdk/tap.py b/tapsdk/tap.py index 0f04d48..bbe0afd 100644 --- a/tapsdk/tap.py +++ b/tapsdk/tap.py @@ -11,9 +11,10 @@ logger = logging.getLogger(__name__) -# BLE GATT UUIDs used by Tap Strap / TapXR. -# Required for this SDK: Tap service (scan/filter), Tap data (notify), NUS service, -# and NUS RX (write input mode). See README "BLE GATT reference". +# BLE GATT UUIDs — verified against tap_rd/ble-mcu-hw-v3-sdk-14.0 @ TAP_XR_develop +# (ble_tap_service.c / Nordic ble_nus). Required for this SDK: Tap service (scan +# response filter), Tap data (notify), NUS service, NUS RX (write input mode). +# See README "BLE GATT reference". tap_service = 'c3ff0001-1d8b-40fd-a56f-c7bd5d0f3370' nus_service = '6e400001-b5a3-f393-e0a9-e50e24dcca9e' tap_data_characteristic = 'c3ff0005-1d8b-40fd-a56f-c7bd5d0f3370'