Changelog¶
All notable changes to this documentation project.
2026-04-18¶
Clarified (provenance)¶
- How the ident reaches both sides — New "Provenance" section on the Credential QR page explains: the 16-byte vehicle-action ident is a factory-programmed per-device secret burned into scooter flash at manufacturing, mirrored in Segway's cloud keyed by serial number. The app fetches it once via
POST /vehicle/vehicle/vehicle-basic-infowith{uid, wnumber}and caches it for offline use. There is no BLE command that sets the ident on the scooter — the scooter already has it — which is why scoot-side verification works offline and why wrong-ident frames fail silently. Documents why the value is not derivable from public inputs (serial, ECU PN, BLE device name).
Added¶
- Python BLE Client chapter — Nav was promoted from "Implementation" to a top-level "Python BLE Client" section.
client.mdrewritten with: current CLI surface (including--identandopen-acc/close-acc/open-trunksubcommands), worked-example walkthrough, per-MAC session-file schema, Gen2/Gen3 constant tables, and "extending the client" recipe. Cross-linked tocredentials-qr.md. - Vehicle-action builders in the reference client —
nb_protocol.pynow exposesbuild_open_acc/build_close_acc/build_open_trunkwith a 16-byte ident payload;build_frameand all convenience builders take agen="gen2"|"gen3"argument (default Gen2 for the E-series moped target). Fixed a latent bug where the old client hardcoded Gen3 sync bytes (0x5A 0xB5) despite claiming E125S (Gen2) compatibility. - Credential QR setup page — Documents the
segway://credentials?sn=…&pwd=…&ident=…URI format used to transfer session password and vehicle-action ident between installations. Ships atools/make_creds_qr.pyCLI with--password,--ident,--sn,--ascii, and--outflags. - Cross-link from Authentication — Added a closing "Authorization beyond the handshake" section so readers who finished the 3-phase handshake know why writes may still silently fail without
$ident.
Clarified¶
$identis a 16-byte secret, not the ECU PN — Rewrote the Vehicle actions section of the command reference. Documented: (1) wire format is 16 raw bytes derived from a 32-char hex string, (2) mismatched payloads are silently dropped by the firmware (MAC still verifies, no error response — the worst possible failure mode for an app developer to diagnose), (3) storage location is iOS UserDefaults{serialNumber}_ident/ Android SharedPreferences, (4) the value is cloud-issued at first pairing and cached locally for offline use.- Not related to "airlock" — Explicit disclaimer that the
nb_airlock_*UserDefaults keys belong to the separate proximity-unlock feature (iBeacon). They coincidentally hold the same byte value in the reference app but are not the source of truth forcmd=0x64payloads.
2026-04-05¶
Added¶
fw_dataconstant documentation — Documented the 16-bytefw_dataconstant (97 CF B8 02...) fromlibnbcrypto.sothat is substituted for null key2 in Gen2 non-SN mode. Explains why Gen2 and Gen3 produce different ciphertext for the same plaintext.- iOS bonded device behaviour — New transport section covering stale CCCD state, notification draining, echo detection, and retry recovery. Practical workarounds for each issue.
- Vehicle action commands with
$ident— Rewrote security commands section. Documents Gen2 vs Gen3 target board differences (VCU 0x09 vs BLE 0x04), action registers (open ACC, close ACC, open trunk), and the$identauthorization token payload. - Stored password recovery — Step-by-step guide to extracting stored BLE passwords from iOS backups (
{SN}_decryptkey in UserDefaults plist), includingsqlite3andplutilcommands. - System device discovery — Documented iOS-specific
systemDevices()API for finding bonded peripherals that don't appear in scans.
Fixed¶
- Index page — Updated Python BLE client description from "untested with real hardware" to "verified against Segway E125S".
2026-04-04 (evening)¶
Verified¶
- Live hardware test — BLE client tested successfully against a real Segway E125S. Handshake (PRE_COMM + stored-password AUTH), register reads, and session persistence all confirmed working.
Fixed¶
- MTU fragmentation — App must split outgoing frames exceeding
MTU - 3bytes (20 bytes at default MTU 23). AUTH frames (27 bytes) were silently truncated without fragmentation, causing the device to never respond. Added explicit documentation and implementation. - Authentication
0x5A 0xB5references — Fixed remaining5A B5references in handshake examples (should be5A A5for BLE). - Speed limit data values — Corrected speed limit write examples (values are in 0.1 km/h units: 250=25 km/h, not 0x19=25).
- Odometer units — Documented as 0.001 km (1 metre precision), not raw km.
Added¶
- Board availability by power state — Table showing which boards respond when vehicle is off (DIS, BLE, VCU: always on; MCU, BMS, ECU: asleep). Commands to sleeping boards time out silently.
- Reconnect counter documentation — First AUTH frame in reconnect mode uses counter=2, same as normal flow.
--passwordCLI flag — Supply stored password from iOS backup to skip SET_PWD phase during reconnection.- Register value units — Range (0.1 km), speeds (0.1 km/h), odometer (0.001 km) now explicitly documented.
2026-04-04¶
Fixed¶
- Critical: BLE header correction — All BLE protocols (Protocol 2, Encryption2, Encryption3) use
0x5A 0xA5. The0x5A 0xB5header is exclusively used by WiFi v2 transport (WifiEncryptionProtocol2). Previous documentation incorrectly stated Encryption2 uses0x5AB5. Confirmed by decompilation ofBleEncryption2Protocol.java(FRAME_BEGIN = -91, i.e.0xA5) andWifiEncryptionProtocol2.java(FRAME_BEGIN = -75, i.e.0xB5).
Added¶
- Per-device protocol map — All 71 devices now show their BLE protocol class (Proto1, Proto2, Enc2) on the Board Addressing page, derived from
backup_config.nbscan configuration. - Protocol column in device tables — The Device Command Reference tables now include a Protocol column, auto-generated from
generate_device_pages.py. - Protocol class hierarchy — Full class hierarchy documented (BleProtocol1 → BleProtocol2 → BleEncryption2Protocol → BleEncryption3Protocol2), including WiFi variants.
- Encryption3 / V3Auth — Added documentation for the newest protocol variant (
BleEncryption3Protocol2), which uses a different handshake flow. - Protocol version selection logic — Documented
DynamicDevice.createBleProtocol()selection rules and BLE advertisement manufacturer data (0x4E42/0x4E43). - Gear profile commands — MCU board registers for reading/writing gear profiles (top speed, acceleration, TCS, nitro, energy recovery, speed safety lock).
- Vehicle action commands —
power-on,power-off,open-seatCLI commands with--identflag for E-series mopeds (cmd 0x64, target VCU 0x09). - Sound preset control — DIS register 0x75 (rWarn) bit 8 for sound effect toggling, volume control, alarm settings.
- Gen2/Gen3 protocol support — BLE client now supports both Gen2 (E-series mopeds) and Gen3 (newer kick scooters) protocol variants via
--genflag. - Changelog — This page.
Changed¶
- WiFi v2 documentation clarified — WiFi v2 section now explicitly states it is the only protocol using
0xB5. - Device count updated — 71 devices documented (was 66), including newer models from updated scan config.
2026-03-28¶
Added¶
- Initial release — Full protocol documentation published.
- 66 device command tables — Auto-generated from decrypted device configuration packages.
- Python BLE client — Reference implementation of Encryption2 protocol.
- Encryption algorithm — Complete AES-128 CTR + CBC-MAC documentation with Python reference code.
- Authentication handshake — 3-phase PRE_COMM / SET_PWD / AUTH sequence.
- BLE transport — Service UUIDs, characteristics, MTU handling.
- Board addressing — Module IDs and routing for all device families.
- Command reference — Register-based read/write commands for speed, battery, lights, security.
- Firmware update protocol — IAP (In-Application Programming) documentation.