From a80a146858b3c9a7fbae4030a524666ab19f7a47 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 14 Aug 2020 11:49:41 +1000 Subject: [PATCH] extmod/bluetooth: Support active scanning in BLE.gap_scan(). This adds an additional optional parameter to gap_scan() to select active scanning, where scan responses are returned as well as normal scan results. This parameter is False by default which retains the existing behaviour. --- docs/library/ubluetooth.rst | 4 +++- extmod/btstack/modbluetooth_btstack.c | 5 ++--- extmod/modbluetooth.c | 8 ++++++-- extmod/modbluetooth.h | 2 +- extmod/nimble/modbluetooth_nimble.c | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/library/ubluetooth.rst b/docs/library/ubluetooth.rst index e103932efd..0cac16f5f4 100644 --- a/docs/library/ubluetooth.rst +++ b/docs/library/ubluetooth.rst @@ -204,7 +204,7 @@ Broadcaster Role (Advertiser) Observer Role (Scanner) ----------------------- -.. method:: BLE.gap_scan(duration_ms, [interval_us], [window_us]) +.. method:: BLE.gap_scan(duration_ms, [interval_us], [window_us], [active]) Run a scan operation lasting for the specified duration (in **milli**\ seconds). @@ -228,6 +228,8 @@ Observer Role (Scanner) * 0x03 - ADV_NONCONN_IND - non-connectable undirected advertising * 0x04 - SCAN_RSP - scan response + ``active`` can be set ``True`` if you want to receive scan responses in the results. + When scanning is stopped (either due to the duration finishing or when explicitly stopped), the ``_IRQ_SCAN_DONE`` event will be raised. diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c index 89e396dfd0..8f0c82974c 100644 --- a/extmod/btstack/modbluetooth_btstack.c +++ b/extmod/btstack/modbluetooth_btstack.c @@ -894,7 +894,7 @@ STATIC void scan_duration_timeout_handler(btstack_timer_source_t *ds) { mp_bluetooth_gap_scan_stop(); } -int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us) { +int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us, bool active_scan) { DEBUG_EVENT_printf("mp_bluetooth_gap_scan_start\n"); if (duration_ms > 0) { @@ -903,8 +903,7 @@ int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_ btstack_run_loop_add_timer(&scan_duration_timeout); } - // 0 = passive scan (we don't handle scan response). - gap_set_scan_parameters(0, interval_us / 625, window_us / 625); + gap_set_scan_parameters(active_scan ? 1 : 0, interval_us / 625, window_us / 625); gap_start_scan(); return 0; diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 730c288ee7..82efe49385 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -609,6 +609,7 @@ STATIC mp_obj_t bluetooth_ble_gap_scan(size_t n_args, const mp_obj_t *args) { mp_int_t duration_ms = 0; mp_int_t interval_us = 1280000; mp_int_t window_us = 11250; + bool active_scan = false; if (n_args > 1) { if (args[1] == mp_const_none) { // scan(None) --> stop scan. @@ -619,12 +620,15 @@ STATIC mp_obj_t bluetooth_ble_gap_scan(size_t n_args, const mp_obj_t *args) { interval_us = mp_obj_get_int(args[2]); if (n_args > 3) { window_us = mp_obj_get_int(args[3]); + if (n_args > 4) { + active_scan = mp_obj_is_true(args[4]); + } } } } - return bluetooth_handle_errno(mp_bluetooth_gap_scan_start(duration_ms, interval_us, window_us)); + return bluetooth_handle_errno(mp_bluetooth_gap_scan_start(duration_ms, interval_us, window_us, active_scan)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_scan_obj, 1, 4, bluetooth_ble_gap_scan); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_scan_obj, 1, 5, bluetooth_ble_gap_scan); #endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE STATIC mp_obj_t bluetooth_ble_gap_disconnect(mp_obj_t self_in, mp_obj_t conn_handle_in) { diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h index cdb86e5e63..2c07683124 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -215,7 +215,7 @@ int mp_bluetooth_gap_disconnect(uint16_t conn_handle); #if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE // Start a discovery (scan). Set duration to zero to run continuously. -int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us); +int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us, bool active_scan); // Stop discovery (if currently active). int mp_bluetooth_gap_scan_stop(void); diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c index 843989b2b8..e51f2747ec 100644 --- a/extmod/nimble/modbluetooth_nimble.c +++ b/extmod/nimble/modbluetooth_nimble.c @@ -661,7 +661,7 @@ STATIC int gap_scan_cb(struct ble_gap_event *event, void *arg) { return 0; } -int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us) { +int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us, bool active_scan) { if (!mp_bluetooth_is_active()) { return ERRNO_BLUETOOTH_NOT_ACTIVE; } @@ -673,7 +673,7 @@ int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_ .window = MAX(BLE_HCI_SCAN_WINDOW_MIN, MIN(BLE_HCI_SCAN_WINDOW_MAX, window_us / BLE_HCI_SCAN_ITVL)), .filter_policy = BLE_HCI_CONN_FILT_NO_WL, .limited = 0, - .passive = 1, // TODO: Handle BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP in gap_scan_cb above. + .passive = active_scan ? 0 : 1, .filter_duplicates = 0, }; int err = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, duration_ms, &discover_params, gap_scan_cb, NULL);