Skip to content

Commit 328fa4c

Browse files
committed
pbio/drv/bluetooth: Cache matching advertisements.
When re-using an existing connection, this lets us make sure all filters match as if making a new connection.
1 parent b8467a7 commit 328fa4c

5 files changed

Lines changed: 40 additions & 8 deletions

File tree

lib/pbio/drv/bluetooth/bluetooth.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,14 @@ pbio_error_t pbdrv_bluetooth_peripheral_get_connected(pbdrv_bluetooth_peripheral
188188
continue;
189189
}
190190

191-
// Callbacks must be the same.
191+
// Callbacks must be the same, and still match with the given user.
192+
// This ensures that we fail as intended when the same classes are used
193+
// but the user has configured different filters such as the name.
192194
if (peri->config.match_adv != config->match_adv ||
193195
peri->config.match_adv_rsp != config->match_adv_rsp ||
194-
peri->config.notification_handler != config->notification_handler) {
196+
peri->config.notification_handler != config->notification_handler ||
197+
!peri->config.match_adv(user, peri->config.match_adv_data, peri->config.match_adv_data_len) ||
198+
!peri->config.match_adv_rsp(user, peri->config.match_adv_rsp_data, peri->config.match_adv_rsp_data_len)) {
195199
continue;
196200
}
197201

lib/pbio/drv/bluetooth/bluetooth_btstack.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,10 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
726726

727727
DEBUG_PRINT("Advertisement matched, waiting for scan response\n");
728728

729+
// Copy data to allow virtual re-connect in a new user program.
730+
peri->config.match_adv_data_len = gap_event_advertising_report_get_data_length(event_packet);
731+
memcpy(peri->config.match_adv_data, gap_event_advertising_report_get_data(event_packet), peri->config.match_adv_data_len);
732+
729733
// Wait for advertising response unless timed out or cancelled.
730734
PBIO_OS_AWAIT_UNTIL(state, scan_timed_out || peri->cancel ||
731735
(hci_event_is_type(event_packet, GAP_EVENT_ADVERTISING_REPORT) && ({
@@ -748,12 +752,7 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
748752
// that event data for processing.
749753
const uint8_t *data = gap_event_advertising_report_get_data(event_packet);
750754
uint8_t data_len = gap_event_advertising_report_get_data_length(event_packet);
751-
if (peri->config.match_adv_rsp(peri->user, data, data_len)) {
752-
// Copy name for later use.
753-
if (data[1] == BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME) {
754-
memcpy(peri->name, &data[2], sizeof(peri->name));
755-
}
756-
} else {
755+
if (!peri->config.match_adv_rsp(peri->user, data, data_len)) {
757756
// We got a valid scan response from the device that matched our
758757
// advertising filter, but it did not match the response filter (e.g.
759758
// requested name did not match), so scan again.
@@ -763,6 +762,14 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
763762

764763
DEBUG_PRINT("Scan response matched, initiate connection to %s.\n", bd_addr_to_str(peri->bdaddr));
765764

765+
// Copy name for later use.
766+
if (data[1] == BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME) {
767+
memcpy(peri->name, &data[2], sizeof(peri->name));
768+
}
769+
// Copy response data to allow virtual re-connect in a new user program.
770+
peri->config.match_adv_rsp_data_len = data_len;
771+
memcpy(peri->config.match_adv_rsp_data, data, data_len);
772+
766773
// We can stop scanning now.
767774
gap_stop_scan();
768775

lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
381381
// save the Bluetooth address for later
382382
peri->bdaddr_type = subevt->bdaddr_type;
383383
memcpy(peri->bdaddr, subevt->bdaddr, sizeof(peri->bdaddr));
384+
// Copy data to allow virtual re-connect in a new user program.
385+
peri->config.match_adv_data_len = subevt->data_length;
386+
memcpy(peri->config.match_adv_data, subevt->data_RSSI, subevt->data_length);
384387
break;
385388
}
386389

@@ -411,6 +414,9 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
411414

412415
// All checks passed, so copy the device name for later use.
413416
memcpy(peri->name, &subevt->data_RSSI[2], sizeof(peri->name));
417+
// Copy data to allow virtual re-connect in a new user program.
418+
peri->config.match_adv_rsp_data_len = subevt->data_length;
419+
memcpy(peri->config.match_adv_rsp_data, subevt->data_RSSI, subevt->data_length);
414420
break;
415421
}
416422

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,10 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
458458
// Save the Bluetooth address for later comparison against response.
459459
peri->bdaddr_type = read_buf[10];
460460
memcpy(peri->bdaddr, &read_buf[11], sizeof(peri->bdaddr));
461+
462+
// Copy data to allow virtual re-connect in a new user program.
463+
peri->config.match_adv_data_len = read_buf[18];
464+
memcpy(peri->config.match_adv_data, &read_buf[19], read_buf[18]);
461465
break;
462466
}
463467

@@ -498,6 +502,9 @@ pbio_error_t pbdrv_bluetooth_peripheral_scan_and_connect_func(pbio_os_state_t *s
498502

499503
// All checks passed, so copy the device name for later use.
500504
memcpy(peri->name, &read_buf[21], sizeof(peri->name));
505+
// Copy data to allow virtual re-connect in a new user program.
506+
peri->config.match_adv_rsp_data_len = read_buf[18];
507+
memcpy(peri->config.match_adv_rsp_data, &read_buf[19], read_buf[18]);
501508
break;
502509
}
503510

lib/pbio/include/pbdrv/bluetooth.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ typedef struct {
123123
pbdrv_bluetooth_peripheral_options_t options;
124124
/** Timeout before aborting scan and connect. Use 0 for no timeout. */
125125
uint32_t timeout;
126+
/** Last matching advertisement data for this peripheral. */
127+
uint8_t match_adv_data[PBDRV_BLUETOOTH_MAX_ADV_SIZE];
128+
/** Last matching advertisement data length for this peripheral. */
129+
uint8_t match_adv_data_len;
130+
/** Last matching advertisement response data for this peripheral. */
131+
uint8_t match_adv_rsp_data[PBDRV_BLUETOOTH_MAX_ADV_SIZE];
132+
/** Last matching advertisement response data length for this peripheral. */
133+
uint8_t match_adv_rsp_data_len;
126134
} pbdrv_bluetooth_peripheral_connect_config_t;
127135

128136
/** Platform-specific state needed to operate the peripheral. */

0 commit comments

Comments
 (0)