https://github.com/partymola/bike-radar-docs
BLE protocol notes for a rear-facing cycling radar (6a4e3200 service)
https://github.com/partymola/bike-radar-docs
ble bluetooth-low-energy cycling protocol
Last synced: 2 days ago
JSON representation
BLE protocol notes for a rear-facing cycling radar (6a4e3200 service)
- Host: GitHub
- URL: https://github.com/partymola/bike-radar-docs
- Owner: partymola
- License: gpl-3.0
- Created: 2026-04-18T00:39:11.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-06T23:50:25.000Z (about 2 months ago)
- Last Synced: 2026-05-07T01:25:25.803Z (about 2 months ago)
- Topics: ble, bluetooth-low-energy, cycling, protocol
- Language: Python
- Homepage:
- Size: 153 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# bike-radar-docs
Protocol notes and reference decoders for the `6a4e3200`-family BLE GATT services used by some cycling-radar accessories, written for interoperability with third-party clients.
This repo is a knowledge drop, not a finished product. It documents what the wire looks like and gives minimal, standalone decoders that anyone can run against a captured log. A more complete Android client exists and will be released here in stages.
## What's covered
- The `6a4e3200` radar service on currently-shipping rear-radar accessories in this device family (confirmed on a RearVue 820; other related devices probably share it but are untested here).
- The legacy V1 stream on characteristic `6a4e3203` (heartbeats, threat packets, sector amplitude packets).
- The V2 measurement stream on characteristic `6a4e3204` (per-target structs with lateral offset, length, width, lateral and longitudinal speed).
- The pre-handshake sequence that unlocks V2 on the RearVue 820.
- The LESC (LE Secure Connections) pairing quirk that breaks programmatic `createBond()` on Android 16 / Pixel 10 Pro XL, and the workaround.
See [PROTOCOL.md](PROTOCOL.md) for the full byte-level spec.
## What's in the repo
```
.
|-- PROTOCOL.md # authoritative protocol doc
|-- python/
| |-- decode_3203.py # V1 stream decoder (stdlib-only CLI)
| |-- decode_3204.py # V2 stream decoder (stdlib-only CLI)
| `-- tests/ # pytest suite for both decoders
|-- kotlin/
| |-- Model.kt # Vehicle / RadarState / VehicleSize / DataSource types
| |-- RadarV1Decoder.kt # V1 stateful decoder, pure JVM (no Android imports)
| |-- RadarV2Decoder.kt # V2 stateful decoder, pure JVM (no Android imports)
| `-- test/ # JUnit4 tests for both decoders
`-- samples/
`-- README.md # notes on capture log format + how to gather your own
```
The Kotlin sources are lifted verbatim from a working Android app and depend only on standard library types. They compile against plain Kotlin/JVM; the JUnit tests run without Android instrumentation.
## Status
- V1 (`3203`) decoding: confirmed across thousands of packets from real commutes.
- V2 (`3204`) decoding: byte format confirmed against live captures; our own handshake replays it successfully. Real-road target decoding is tested against synthetic frames; end-to-end road validation is pending.
- Pairing: verified on Android 16 / Pixel 10 Pro XL via both the manufacturer's official Android app and Settings -> Connected devices. Other Android versions and other phones untested.
## Prior art and credit
- github.com/rale/radarble is the only public writeup of the V2 `6a4e3204` target struct I have found. No code from that repo was copied; the byte layout here was cross-checked against live captures.
- github.com/Wunderfitz/harbour-tacho (C++, SailfishOS) is a long-running V1 client; the V1 layout here was cross-checked against its source.
- github.com/kartoone/mybiketraffic (Monkey C) is a Garmin Connect IQ data-field and the closest public reference to V1 packet behaviour from inside the ConnectIQ radar API. The "V1 third byte = approach speed in m/s (multiply by 3.6 for km/h)" reading cited from it and from other public notes does not match real-road 820 captures, where that byte only ever takes values 0 or 1 (see [PROTOCOL.md](PROTOCOL.md) §V1 threat packet).
- kartoone has an ongoing developer-forum thread covering the same territory; anyone with follow-up data or corrections is encouraged to participate there as well as opening an issue here.
## Licence
GPLv3 or later. See [LICENSE](LICENSE).
## Contributions welcome
- More captures from other models in this radar family (e.g. RTL515, RTL516, Vue 870) so the GATT-variant table can be filled in.
- Independent confirmation of the V2 unlock sequence on non-Pixel Android devices or on iOS.
- Corrections or gaps in PROTOCOL.md.