Segway-Ninebot BLE Protocol¶
Open documentation of the Bluetooth Low Energy communication protocol used by Segway-Ninebot vehicles, reverse-engineered for interoperability and owner control.
What is this?¶
This project documents the proprietary BLE protocol that Segway-Ninebot vehicles use to communicate with the official mobile app. The protocol was reverse-engineered through analysis of the com.ninebot.segway Android application (React Native + Hermes) and its native cryptographic library libnbcrypto.so.
The goal is to enable vehicle owners and developers to:
- Build alternative apps and tools for their own vehicles
- Integrate vehicle data into home automation, dashboards, and fleet management
- Understand the security model of their vehicle's connectivity
- Exercise their right to repair and maintain their own property
What's documented¶
| Section | Contents |
|---|---|
| BLE Transport | Service UUIDs, characteristics, connection flow, MTU handling |
| Frame Formats | Wire format for all protocol generations (Protocol 1, 2, Encryption2, WiFi) |
| Encryption | AES-128-based encryption, key derivation, nonce construction, MAC |
| Authentication | 3-phase handshake (PRE_COMM, SET_PWD, AUTH) |
| Command Reference | Register-based read/write commands for speed, battery, lights, security |
| Firmware Update | IAP (In-Application Programming) protocol |
| Board Addressing | Module IDs, device families, protocol selection |
| Python BLE Client | Reference client implementation (untested with real hardware) |
Protocol overview¶
The current production protocol (Encryption2) uses:
- Header:
0x5A 0xA5(same sync bytes as Protocol 2) - Encryption: AES-128 in a custom CTR-like mode with CBC-MAC authentication
- Key exchange: 3-phase handshake deriving session keys from device name and random challenge
- Replay protection: Monotonically increasing counter per session
- Transport: BLE GATT with custom Ninebot service UUID (
6e400001-*-006e-696e65626f74)
App Vehicle
| |
|-- PRE_COMM (get challenge) ---->|
|<---- auth_param + serial -------|
| |
|-- SET_PWD (session password) -->|
|<---- accepted ------------------|
| |
|-- AUTH (prove identity) ------->|
|<---- authenticated -------------|
| |
|== Encrypted commands ==========>|
|<== Encrypted responses =========|
Supported devices¶
The protocol applies to the entire Segway-Ninebot product range. Configuration data has been documented for 66 device models across 8 categories:
| Category | Count | Examples |
|---|---|---|
| Kick scooters | 30 | Max, F2, P-series, GT-series |
| Mopeds/motorcycles | 6 | E125S, E150S, E250S, E300SE |
| Self-balancing | 10 | S2, S-Max, S-Pro |
| GoKarts | 6 | GoKart Pro, GoKart Bundle |
| Unicycles | 3 | One S2 |
| E-bikes | 4 | |
| Speakers | 3 | Segway portable speakers |
| Power stations | 2 | Cube series |
Quick start¶
# Clone the repository
git clone https://codeberg.org/NootNooot/segway-ninebot-ble.git
# Install the Python BLE client
cd segway-ninebot-ble/ble-client
pip install bleak pycryptodome
# Scan for nearby devices
python segway_ble_client.py scan
# Connect and read speed limit
python segway_ble_client.py -a AA:BB:CC:DD:EE:FF read-speed
See the Python BLE Client page for full usage instructions.
Legal basis¶
This research is conducted under Article 6 of the EU Software Directive (2009/24/EC), which permits decompilation to achieve interoperability with independently created software. All documentation describes communication protocols and interfaces. No proprietary source code, firmware, or cryptographic keys are redistributed.
See About for the full legal discussion.
Contribution
This is a community documentation project. If you have additional findings, corrections, or support for other device models, contributions are welcome.