Skip to content

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.

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.