Two failures on the tablet, one of them mine from an hour ago. The real one first. A trainer that drops mid-ride could not get back: its supervisor reconnects on its own (FR-1.10) and those attempts never pass through `DeviceRegistry::connect`, so nothing suspended the device list for them. On Android a GATT link that is discovering services while a scan is running is killed by the platform, and the log has it exactly — a reconnect at 13:07:18 dying with `Disconnected while discovering services`, inside a list-scan session opened at 13:07:02. My first fix was to suspend the list whenever the trainer was mid-connect. That was drawn around the wrong thing. `Connecting` covers the 15 s *search*, `Reconnecting` covers the backoff between attempts, and against an asleep trainer those alternate for the whole of RECONNECT_ATTEMPTS — so the list scan went off the air for minutes and every other device starved with it. A pod that dropped could never be seen again, which is what "the pods disconnect after 40 seconds" was. The window that matters is narrower than either: connect, then discover services. `scan::gatt_setup` marks it — an RAII guard taken by the trainer, pod and heart rate paths the moment their search returns a peripheral — and the device list yields only for that. Measured on the tablet: 1.2 s of yielding for a heart rate connect, then straight back to one session per 21 s. Also: the "+ pod seen; the − pod speaks for the pair" line is logged once per run of refusals rather than once per sighting. The device list republishes several times a second and every pass re-reported a visible pod — 274 identical lines in five minutes, burying the connect failures the log was being read for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
52 lines
1.3 KiB
JSON
52 lines
1.3 KiB
JSON
{
|
|
"$schema": "https://schema.tauri.app/config/2",
|
|
"productName": "BikeControl",
|
|
"version": "0.2.3",
|
|
"identifier": "paris.tourolle.bikecontrol",
|
|
"build": {
|
|
"frontendDist": "../ui/dist",
|
|
"devUrl": "http://localhost:1420",
|
|
"beforeDevCommand": {
|
|
"cwd": "../ui",
|
|
"script": "npm run dev"
|
|
},
|
|
"beforeBuildCommand": {
|
|
"cwd": "../ui",
|
|
"script": "npm run build"
|
|
}
|
|
},
|
|
"app": {
|
|
"windows": [
|
|
{
|
|
"title": "BikeControl",
|
|
"width": 1440,
|
|
"height": 900,
|
|
"minWidth": 960,
|
|
"minHeight": 640,
|
|
"resizable": true,
|
|
"fullscreen": false,
|
|
"backgroundColor": "#07090d"
|
|
}
|
|
],
|
|
"security": {
|
|
"csp": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src ipc: http://ipc.localhost"
|
|
}
|
|
},
|
|
"bundle": {
|
|
"active": true,
|
|
"targets": "all",
|
|
"icon": [
|
|
"icons/32x32.png",
|
|
"icons/128x128.png",
|
|
"icons/128x128@2x.png",
|
|
"icons/icon.png"
|
|
],
|
|
"category": "Utility",
|
|
"android": {
|
|
"versionCode": 1203
|
|
},
|
|
"shortDescription": "Indoor cycling trainer control",
|
|
"longDescription": "Control a smart trainer over BLE, ride gradient profiles and synthetic waveforms, and record the result."
|
|
}
|
|
}
|