| 194 | _ble_server = ble_provisioning.build_server( |
| 195 | base_dir, |
| 196 | get_config=lambda: shared_data.config, |
| 197 | get_ap_state=_ble_ap_state, |
| 198 | set_ap=_ble_set_ap, |
| 199 | logger=logger, |
| 200 | ) |
| 201 | if _ble_server is None: |
| 202 | return False |
| 203 | server = _ble_server |
| 204 | # start() blocks until BlueZ registers or the wait times out. Do that |
| 205 | # OUTSIDE the lock: GET /api/ble/provisioning takes the same lock, so |
| 206 | # holding it here made the status the UI polls hang for the full wait — |
| 207 | # exactly while the user is watching for it to come up. |
| 208 | return server.start() |
| 209 | except Exception as e: # pragma: no cover - hardware/D-Bus dependent |
| 210 | logger.error(f"BLE provisioning failed to start: {e}") |
| 211 | return False |