diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index f4996f7e88..0cfa3ac0d3 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -501,23 +501,26 @@ STATIC mp_obj_t bluetooth_ble_gap_connect(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_connect_obj, 3, 4, bluetooth_ble_gap_connect); STATIC mp_obj_t bluetooth_ble_gap_scan(size_t n_args, const mp_obj_t *args) { - if (n_args == 2 && args[1] == mp_const_none) { - int err = mp_bluetooth_gap_scan_stop(); - return bluetooth_handle_errno(err); - } else { - mp_int_t duration_ms = 0; - if (n_args == 2) { - if (!mp_obj_is_int(args[1])) { - mp_raise_ValueError("invalid duration"); - } - duration_ms = mp_obj_get_int(args[1]); + // Default is indefinite scan, with the NimBLE "background scan" interval and window. + mp_int_t duration_ms = 0; + mp_int_t interval_us = 1280000; + mp_int_t window_us = 11250; + if (n_args > 1) { + if (args[1] == mp_const_none) { + // scan(None) --> stop scan. + return bluetooth_handle_errno(mp_bluetooth_gap_scan_stop()); + } + duration_ms = mp_obj_get_int(args[1]); + if (n_args > 2) { + interval_us = mp_obj_get_int(args[2]); + if (n_args > 3) { + window_us = mp_obj_get_int(args[3]); + } } - - int err = mp_bluetooth_gap_scan_start(duration_ms); - return bluetooth_handle_errno(err); } + return bluetooth_handle_errno(mp_bluetooth_gap_scan_start(duration_ms, interval_us, window_us)); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_scan_obj, 1, 2, bluetooth_ble_gap_scan); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bluetooth_ble_gap_scan_obj, 1, 4, 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 9db3bed6cd..8f34e3484d 100644 --- a/extmod/modbluetooth.h +++ b/extmod/modbluetooth.h @@ -186,7 +186,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); +int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us); // Stop discovery (if currently active). int mp_bluetooth_gap_scan_stop(void); diff --git a/extmod/modbluetooth_nimble.c b/extmod/modbluetooth_nimble.c index 1e7211bfe8..727894f862 100644 --- a/extmod/modbluetooth_nimble.c +++ b/extmod/modbluetooth_nimble.c @@ -614,16 +614,16 @@ STATIC int gap_scan_cb(struct ble_gap_event *event, void *arg) { return 0; } -int mp_bluetooth_gap_scan_start(int32_t duration_ms) { +int mp_bluetooth_gap_scan_start(int32_t duration_ms, int32_t interval_us, int32_t window_us) { if (duration_ms == 0) { duration_ms = BLE_HS_FOREVER; } - STATIC const struct ble_gap_disc_params discover_params = { - .itvl = BLE_GAP_SCAN_SLOW_INTERVAL1, - .window = BLE_GAP_SCAN_SLOW_WINDOW1, + struct ble_gap_disc_params discover_params = { + .itvl = MAX(BLE_HCI_SCAN_ITVL_MIN, MIN(BLE_HCI_SCAN_ITVL_MAX, interval_us / BLE_HCI_SCAN_ITVL)), + .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 = 0, + .passive = 1, // TODO: Handle BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP in gap_scan_cb above. .filter_duplicates = 0, }; int err = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, duration_ms, &discover_params, gap_scan_cb, NULL);