Skip to content

Commit a17c1d2

Browse files
committed
pbio/drv/bluetooth: Check for HCI enabled.
On some platforms it may not be enabled, e.g. when the USB Bluetooth dongle is not plugged in.
1 parent 3e7a286 commit a17c1d2

6 files changed

Lines changed: 76 additions & 23 deletions

File tree

lib/pbio/drv/bluetooth/bluetooth.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect(pbdrv_bluetooth_periphe
158158

159159
pbdrv_bluetooth_peripheral_t *peri = &peripheral_singleton;
160160

161+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
162+
return PBIO_ERROR_INVALID_OP;
163+
}
164+
161165
// Can't connect if already connected or already busy.
162166
if (pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_PERIPHERAL) || peri->func) {
163167
return PBIO_ERROR_BUSY;
@@ -300,6 +304,10 @@ pbdrv_bluetooth_advertising_state_t pbdrv_bluetooth_advertising_state;
300304

301305
pbio_error_t pbdrv_bluetooth_start_advertising(bool start) {
302306

307+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
308+
return PBIO_ERROR_INVALID_OP;
309+
}
310+
303311
bool is_advertising = pbdrv_bluetooth_advertising_state == PBDRV_BLUETOOTH_ADVERTISING_STATE_ADVERTISING_PYBRICKS;
304312

305313
// Already in requested state. This makes it safe to call stop advertising
@@ -330,6 +338,10 @@ uint8_t pbdrv_bluetooth_broadcast_data_size;
330338

331339
pbio_error_t pbdrv_bluetooth_start_broadcasting(const uint8_t *data, size_t size) {
332340

341+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
342+
return PBIO_ERROR_INVALID_OP;
343+
}
344+
333345
if (advertising_or_scan_func) {
334346
return PBIO_ERROR_BUSY;
335347
}
@@ -374,6 +386,10 @@ pbdrv_bluetooth_start_observing_callback_t pbdrv_bluetooth_observe_callback;
374386

375387
pbio_error_t pbdrv_bluetooth_start_observing(pbdrv_bluetooth_start_observing_callback_t callback) {
376388

389+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
390+
return PBIO_ERROR_INVALID_OP;
391+
}
392+
377393
if (advertising_or_scan_func) {
378394
return PBIO_ERROR_BUSY;
379395
}
@@ -593,14 +609,19 @@ pbio_error_t pbdrv_bluetooth_close_user_tasks(pbio_os_state_t *state, pbio_os_ti
593609

594610
void pbdrv_bluetooth_deinit(void) {
595611

612+
// If Bluetooth is not even initialized, nothing to do.
613+
if (!pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
614+
return;
615+
}
616+
596617
// Under normal operation ::pbdrv_bluetooth_close_user_tasks completes
597618
// normally and there should be no user activity at this point. If there
598619
// is, a task got stuck, so exit forcefully.
599620
pbio_os_state_t unused;
600621
if (pbdrv_bluetooth_await_advertise_or_scan_command(&unused, NULL) != PBIO_SUCCESS ||
601622
pbdrv_bluetooth_await_peripheral_command(&unused, NULL) != PBIO_SUCCESS) {
602623

603-
// Hard reset without waitng on completion of any process.
624+
// Hard reset without waiting on completion of any process.
604625
pbdrv_bluetooth_controller_reset_hard();
605626
return;
606627
}

lib/pbio/drv/bluetooth/bluetooth_btstack.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,6 @@ static hci_con_handle_t uart_con_handle = HCI_CON_HANDLE_INVALID;
124124
static pup_handset_t handset;
125125
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
126126

127-
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
128-
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
129-
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && le_con_handle != HCI_CON_HANDLE_INVALID) {
130-
return true;
131-
}
132-
133-
if (connection == PBDRV_BLUETOOTH_CONNECTION_PYBRICKS && pybricks_con_handle != HCI_CON_HANDLE_INVALID) {
134-
return true;
135-
}
136-
137-
if (connection == PBDRV_BLUETOOTH_CONNECTION_UART && uart_con_handle != HCI_CON_HANDLE_INVALID) {
138-
return true;
139-
}
140-
141-
if (connection == PBDRV_BLUETOOTH_CONNECTION_PERIPHERAL && peripheral_singleton.con_handle != HCI_CON_HANDLE_INVALID) {
142-
return true;
143-
}
144-
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
145-
146-
return false;
147-
}
148-
149127
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
150128

151129
/**
@@ -202,6 +180,39 @@ static void propagate_event(uint8_t *packet) {
202180
event_packet = NULL;
203181
}
204182

183+
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
184+
185+
// Nothing connected if HCI is not running.
186+
if (bluetooth_thread_err != PBIO_ERROR_AGAIN) {
187+
return false;
188+
}
189+
190+
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
191+
192+
if (connection == PBDRV_BLUETOOTH_CONNECTION_HCI) {
193+
return true;
194+
}
195+
196+
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && le_con_handle != HCI_CON_HANDLE_INVALID) {
197+
return true;
198+
}
199+
200+
if (connection == PBDRV_BLUETOOTH_CONNECTION_PYBRICKS && pybricks_con_handle != HCI_CON_HANDLE_INVALID) {
201+
return true;
202+
}
203+
204+
if (connection == PBDRV_BLUETOOTH_CONNECTION_UART && uart_con_handle != HCI_CON_HANDLE_INVALID) {
205+
return true;
206+
}
207+
208+
if (connection == PBDRV_BLUETOOTH_CONNECTION_PERIPHERAL && peripheral_singleton.con_handle != HCI_CON_HANDLE_INVALID) {
209+
return true;
210+
}
211+
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
212+
213+
return false;
214+
}
215+
205216
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
206217
static void nordic_spp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
207218
switch (packet_type) {
@@ -993,6 +1004,10 @@ static pbio_error_t bluetooth_btstack_handle_power_control(pbio_os_state_t *stat
9931004

9941005
pbio_error_t pbdrv_bluetooth_controller_reset(pbio_os_state_t *state, pbio_os_timer_t *timer) {
9951006

1007+
if (pbdrv_bluetooth_is_connected(PBDRV_BLUETOOTH_CONNECTION_HCI)) {
1008+
return PBIO_ERROR_INVALID_OP;
1009+
}
1010+
9961011
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
9971012
static pbio_os_state_t sub;
9981013

lib/pbio/drv/bluetooth/bluetooth_simulation.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ pbio_error_t pbdrv_bluetooth_stop_advertising_func(pbio_os_state_t *state, void
3131
}
3232

3333
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
34+
35+
if (connection == PBDRV_BLUETOOTH_CONNECTION_HCI) {
36+
return true;
37+
}
38+
3439
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE) {
3540
return true;
3641
}

lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ pbio_error_t pbdrv_bluetooth_stop_advertising_func(pbio_os_state_t *state, void
290290

291291

292292
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
293+
294+
if (connection == PBDRV_BLUETOOTH_CONNECTION_HCI) {
295+
return true;
296+
}
297+
293298
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && conn_handle) {
294299
return true;
295300
}

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ pbio_error_t pbdrv_bluetooth_stop_advertising_func(pbio_os_state_t *state, void
321321
}
322322

323323
bool pbdrv_bluetooth_is_connected(pbdrv_bluetooth_connection_t connection) {
324+
325+
if (connection == PBDRV_BLUETOOTH_CONNECTION_HCI) {
326+
return true;
327+
}
328+
324329
if (connection == PBDRV_BLUETOOTH_CONNECTION_LE && conn_handle != NO_CONNECTION && !busy_disconnecting) {
325330
return true;
326331
}

lib/pbio/include/pbdrv/bluetooth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* BLE characteristic connection identifiers.
2323
*/
2424
typedef enum {
25+
/* Whether Bluetooth is present and enabled on this platform. */
26+
PBDRV_BLUETOOTH_CONNECTION_HCI,
2527
/* A low energy device connection. */
2628
PBDRV_BLUETOOTH_CONNECTION_LE,
2729
/** The Pybricks service. */

0 commit comments

Comments
 (0)