Bosch Live Data Interface on the Karoo 3: pairing works, reconnecting doesn’t (BLE private address). Can extensions get a stable address?
Bosch published the Live Data Interface (LDI) in May 2026: a Bluetooth LE interface that lets an accessory read the live data of a Smart System e-bike (control unit firmware v19 or later, CX Gen4, CX Gen5, SX). I have been building a Karoo 3 extension on it, BoschData, and I would like to share what I found, and ask Hammerhead one question.
What works from a normal extension
The Karoo 3 can act as the LDI accessory, with public Android APIs only:
- the extension advertises with the LDI Service Solicitation (`0xEB20`) and runs a small GATT server (Battery and Device Information, which is what the Bosch Flow app shows);
- the bike connects to it and the extension, as a GATT client, reads the LDI characteristic (`0xEB21`) once and then gets notifications, about one per second, with only the fields that changed (protobuf);
- from there: battery % as the bike shows it, rider power, speed, cadence, odometer and light, as data fields, as a sensor the Karoo records like a power meter, and as a FIT developer field.
Pairing is done once from Flow (Add component → Accessories), and the data shows up on the Karoo.

A trap worth knowing
The Karoo does not grant `BLUETOOTH_ADVERTISE` and `BLUETOOTH_CONNECT` by itself. Without them nothing happens, and from the outside it looks as if advertising were blocked on the Karoo. It is not: request the runtime permissions from your app (the normal Android dialog works on the Karoo 3, no adb needed) and advertising works.
The blocker: reconnecting
After the bike is switched off, it never comes back. With an HCI snoop log on the Karoo I could see why: the bike reconnects only to the exact resolvable private address the Karoo advertised at pairing time, and Android gives the advertiser a new address every time advertising restarts and about every 15 minutes. So a Karoo-only link lasts one session per pairing.
An app cannot avoid this: choosing the own address type of an advertising set (`AdvertisingSetParameters.Builder.setOwnAddressType`) is a system API, not available to extensions.
The question for Hammerhead
Could the Karoo offer extensions a way to advertise with a stable address, for example by allowing the public or a fixed static address for an advertising set, through the extension SDK or a permission? With that, every Bosch Smart System owner could get the bike's data on the Karoo with no extra hardware, and the same would help any other accessory protocol where the peripheral is expected to keep its address.
What I use meanwhile
A small board with a fixed address between the bike and the Karoo: an Adafruit Feather nRF52840 running the open-source https://github.com/bestie-org/BEStie firmware, with a small service of mine added that carries the live data, the board's status and its log. The board is the LDI accessory, the extension connects to the board. With it the bike reconnects by itself every time it is switched on, and the data is back on the Karoo about 10 seconds later.

The board in the Bosch Flow app, listed as an external display next to the bike's other components

An Adafruit Feather nRF52840 Express with a 500 mAh LiPo, running BEStie.
BoschData and my addition to the BEStie firmware are not released yet; they will be, as open source, after the ride tests. If you work on something similar, or know another way around the address rotation, I would be glad to compare notes.
---
My other Karoo extensions, free and open source, are on https://lagorai.bike/extensions.
All my code is on GitHub: github.com/anpaiss.
-
Update: BEStie in its printed case, bench test on the bike
The board is now in its printed case: a Feather nRF52840 running BEStie with the Karoo service, plus its LiPo. It's strapped to the bike with foam tape, lid facing out. Today's garage test, from the Karoo's log:
- Karoo ↔ board: connected for over an hour, from 17:30 to 18:38, with no drops and no reboots.
- Bike on at 18:04: the board linked to the bike in under a second, and the first data showed on the Karoo about 3 seconds later. Battery, rider power, speed, cadence, odometer and light all came through.
- 12 minutes of bike data: 752 messages from the bike, about one per second, none dropped.
- Light: switching the light off on the bike showed up on the Karoo right away.
- Bike auto-off at 18:16: the board reported it immediately, the Karoo fields switched to "bike off", and the board stayed connected to the Karoo.
- App reinstall: after I updated the extension, the board reconnected by itself within seconds, with the pairing kept.
- Board battery: 97–98 %. It isn't on a charger: standby drain so far is about 2 % in three days.
So far so good. Next: checking whether the bike sends the assist mode anywhere (the logging is in place), then a real ride to see how the link holds up on the trail.



Please sign in to leave a comment.
Comments
2 comments