{"id":50987048,"url":"https://github.com/partymola/bike-radar-docs","last_synced_at":"2026-06-19T20:31:23.472Z","repository":{"id":352753539,"uuid":"1213964079","full_name":"partymola/bike-radar-docs","owner":"partymola","description":"BLE protocol notes for a rear-facing cycling radar (6a4e3200 service)","archived":false,"fork":false,"pushed_at":"2026-05-06T23:50:25.000Z","size":157,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-07T01:25:25.803Z","etag":null,"topics":["ble","bluetooth-low-energy","cycling","protocol"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/partymola.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-18T00:39:11.000Z","updated_at":"2026-05-06T23:50:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/partymola/bike-radar-docs","commit_stats":null,"previous_names":["partymola/bike-radar-docs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/partymola/bike-radar-docs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/partymola%2Fbike-radar-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/partymola%2Fbike-radar-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/partymola%2Fbike-radar-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/partymola%2Fbike-radar-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/partymola","download_url":"https://codeload.github.com/partymola/bike-radar-docs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/partymola%2Fbike-radar-docs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34547787,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ble","bluetooth-low-energy","cycling","protocol"],"created_at":"2026-06-19T20:31:22.661Z","updated_at":"2026-06-19T20:31:23.466Z","avatar_url":"https://github.com/partymola.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bike-radar-docs\n\nProtocol notes and reference decoders for the `6a4e3200`-family BLE GATT services used by some cycling-radar accessories, written for interoperability with third-party clients.\n\nThis 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.\n\n## What's covered\n\n- 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).\n- The legacy V1 stream on characteristic `6a4e3203` (heartbeats, threat packets, sector amplitude packets).\n- The V2 measurement stream on characteristic `6a4e3204` (per-target structs with lateral offset, length, width, lateral and longitudinal speed).\n- The pre-handshake sequence that unlocks V2 on the RearVue 820.\n- The LESC (LE Secure Connections) pairing quirk that breaks programmatic `createBond()` on Android 16 / Pixel 10 Pro XL, and the workaround.\n\nSee [PROTOCOL.md](PROTOCOL.md) for the full byte-level spec.\n\n## What's in the repo\n\n```\n.\n|-- PROTOCOL.md             # authoritative protocol doc\n|-- python/\n|   |-- decode_3203.py      # V1 stream decoder (stdlib-only CLI)\n|   |-- decode_3204.py      # V2 stream decoder (stdlib-only CLI)\n|   `-- tests/              # pytest suite for both decoders\n|-- kotlin/\n|   |-- Model.kt            # Vehicle / RadarState / VehicleSize / DataSource types\n|   |-- RadarV1Decoder.kt   # V1 stateful decoder, pure JVM (no Android imports)\n|   |-- RadarV2Decoder.kt   # V2 stateful decoder, pure JVM (no Android imports)\n|   `-- test/               # JUnit4 tests for both decoders\n`-- samples/\n    `-- README.md           # notes on capture log format + how to gather your own\n```\n\nThe 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.\n\n## Status\n\n\n- V1 (`3203`) decoding: confirmed across thousands of packets from real commutes.\n- 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.\n- Pairing: verified on Android 16 / Pixel 10 Pro XL via both the manufacturer's official Android app and Settings -\u003e Connected devices. Other Android versions and other phones untested.\n\n## Prior art and credit\n\n- 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.\n- github.com/Wunderfitz/harbour-tacho (C++, SailfishOS) is a long-running V1 client; the V1 layout here was cross-checked against its source.\n- 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).\n- 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.\n\n## Licence\n\nGPLv3 or later. See [LICENSE](LICENSE).\n\n## Contributions welcome\n\n- More captures from other models in this radar family (e.g. RTL515, RTL516, Vue 870) so the GATT-variant table can be filled in.\n- Independent confirmation of the V2 unlock sequence on non-Pixel Android devices or on iOS.\n- Corrections or gaps in PROTOCOL.md.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpartymola%2Fbike-radar-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpartymola%2Fbike-radar-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpartymola%2Fbike-radar-docs/lists"}