Skip to content

Commit 3d8fa4f

Browse files
committed
drv/bluetooth: handle remote + observing
If observing has already started when connecting to another Bluetooth device, we need to pause observing (which is passive scanning) so that we can do active scanning to find the device we want to connect to. Then we need to restore passive scanning for observing once active scanning is complete. This is done on CC2540 and BTStack. On BlueNRG, the chip can't handle observing while being connected to another device so we just raise an error instead.
1 parent 661b490 commit 3d8fa4f

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

lib/pbio/drv/bluetooth/bluetooth_btstack.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,11 @@ void pbdrv_bluetooth_set_notification_handler(pbdrv_bluetooth_receive_handler_t
625625
notification_handler = handler;
626626
}
627627

628+
static void start_observing(void) {
629+
gap_set_scan_params(0, 0x30, 0x30, 0);
630+
gap_start_scan();
631+
}
632+
628633
static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
629634
pbdrv_bluetooth_scan_and_connect_context_t *context = task->context;
630635

@@ -661,7 +666,7 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
661666
memcpy(context->name, handset.name, sizeof(context->name));
662667

663668
task->status = PBIO_SUCCESS;
664-
PT_EXIT(pt);
669+
goto out;
665670

666671
cancel:
667672
if (handset.con_state == CON_STATE_WAIT_ADV_IND || handset.con_state == CON_STATE_WAIT_SCAN_RSP) {
@@ -673,6 +678,13 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
673678
}
674679
handset.con_state = CON_STATE_NONE;
675680
task->status = PBIO_ERROR_CANCELED;
681+
682+
out:
683+
// restore observing state
684+
if (is_observing) {
685+
start_observing();
686+
}
687+
676688
PT_END(pt);
677689
}
678690

@@ -760,8 +772,7 @@ void pbdrv_bluetooth_start_observing(pbio_task_t *task, pbdrv_bluetooth_start_ob
760772
observe_callback = callback;
761773

762774
if (!is_observing) {
763-
gap_set_scan_params(0, 0x30, 0x30, 0);
764-
gap_start_scan();
775+
start_observing();
765776
is_observing = true;
766777
}
767778

lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
416416

417417
PT_BEGIN(pt);
418418

419+
// observing while connected to another device is not going to work
420+
if (is_observing) {
421+
task->status = PBIO_ERROR_INVALID_OP;
422+
PT_EXIT(pt);
423+
}
424+
419425
// start scanning
420426
PT_WAIT_WHILE(pt, write_xfer_size);
421427
aci_gap_start_general_conn_establish_proc_begin(ACTIVE_SCAN, 0x0030, 0x0030, STATIC_RANDOM_ADDR, 0);

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,17 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
474474

475475
PT_BEGIN(pt);
476476

477+
// temporarily stop observing so we can active scan
478+
if (is_observing) {
479+
PT_WAIT_WHILE(pt, write_xfer_size);
480+
GAP_DeviceDiscoveryCancel();
481+
PT_WAIT_UNTIL(pt, hci_command_status);
482+
483+
if (read_buf[8] == bleSUCCESS) {
484+
PT_WAIT_UNTIL(pt, device_discovery_done);
485+
}
486+
}
487+
477488
// start scanning
478489

479490
PT_WAIT_WHILE(pt, write_xfer_size);
@@ -484,7 +495,7 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
484495

485496
if (context->status != bleSUCCESS) {
486497
task->status = ble_error_to_pbio_error(context->status);
487-
PT_EXIT(pt);
498+
goto out;
488499
}
489500

490501
device_discovery_done = false;
@@ -664,7 +675,7 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
664675

665676
task->status = PBIO_SUCCESS;
666677

667-
PT_EXIT(pt);
678+
goto out;
668679

669680
disconnect:
670681
PT_WAIT_WHILE(pt, write_xfer_size);
@@ -673,7 +684,7 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
673684

674685
// task->status must be set before goto disconnect!
675686

676-
PT_EXIT(pt);
687+
goto out;
677688

678689
cancel_connect:
679690
PT_WAIT_WHILE(pt, write_xfer_size);
@@ -691,6 +702,22 @@ static PT_THREAD(scan_and_connect_task(struct pt *pt, pbio_task_t *task)) {
691702

692703
end_cancel:
693704
task->status = PBIO_ERROR_CANCELED;
705+
706+
out:
707+
// start passive scanning again if observing
708+
if (is_observing) {
709+
PT_WAIT_WHILE(pt, write_xfer_size);
710+
GAP_DeviceDiscoveryRequest(GAP_DEVICE_DISCOVERY_MODE_NONDISCOVERABLE, 0, GAP_FILTER_POLICY_SCAN_ANY_CONNECT_ANY);
711+
PT_WAIT_UNTIL(pt, hci_command_status);
712+
713+
if (read_buf[8] != bleSUCCESS) {
714+
task->status = ble_error_to_pbio_error(read_buf[8]);
715+
PT_EXIT(pt);
716+
}
717+
718+
device_discovery_done = false;
719+
}
720+
694721
PT_END(pt);
695722
}
696723

0 commit comments

Comments
 (0)