summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2019-10-08 14:25:32 +1100
committerJim Mussared <jim.mussared@gmail.com>2019-10-11 13:51:07 +1100
commitb65cc387cd0819ab97a4a8f7ebbc1f6345f65379 (patch)
tree1b8970fb659f91444a1eb01cbd5d950390c5cac5
parent06ae818f9360e83284c64614144f1ad00998a739 (diff)
extmod/modbluetooth: Allow config of scan interval/window.
This adds two additional optional kwargs to `gap_scan()`: - `interval_us`: How long between scans. - `window_us`: How long to scan for during a scan. The default with NimBLE is a 11.25ms window with a 1.28s interval. Changing these parameters is important for detecting low-frequency advertisements (e.g. beacons). Note: these params are in microseconds, not milliseconds in order to allow the 625us granularity offered by the spec.
-rw-r--r--extmod/modbluetooth.c29
-rw-r--r--extmod/modbluetooth.h2
-rw-r--r--extmod/modbluetooth_nimble.c10
3 files changed, 22 insertions, 19 deletions
diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c
index f4996f7e8..0cfa3ac0d 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");
+ // 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]);
}
- duration_ms = mp_obj_get_int(args[1]);
}
-
- 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 9db3bed6c..8f34e3484 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 1e7211bfe..727894f86 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);