Skip to content

Commit

Permalink
Give BLE scan more options.
Browse files Browse the repository at this point in the history
Most users shouldn't touch them, but for power users it's nice to have
them available.
  • Loading branch information
floitsch committed Nov 24, 2024
1 parent e59206a commit a315c16
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/ble/ble.toit
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ ble-create-central-manager_ adapter-resource:
ble-create-peripheral-manager_ adapter-resource bonding secure-connections:
#primitive.ble.create-peripheral-manager

ble-scan-start_ central-manager passive duration-us:
ble-scan-start_ central-manager passive/bool duration-us/int interval/int window/int limited/bool:
#primitive.ble.scan-start

ble-scan-next_ central-manager:
Expand Down
28 changes: 25 additions & 3 deletions lib/ble/remote.toit
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,33 @@ class Central extends Resource_:
Connections cannot be established while a scan is ongoing.
Stops the scan after the given $duration.
*/
scan [block] --duration/Duration?=null --active/bool=false:
The $interval is the time between the start of two consecutive scan windows. It is
given in units of 0.625 ms. If it is 0, the default value of the system is used.
The $window is the time the scanner is active during a scan window. It is given in
units of 0.625 ms. If it is 0, the default value of the system is used. The window
must be less than or equal to the interval.
If $limited-only is true, only limited discoverable devices are reported. Devices
declare during advertising whether they are limited (advertising for a limited
duration) or general (continuously broadcasting). This flag filters out general
devices.
*/
scan -> none
--interval/int=0
--window/int=0
--duration/Duration?=null
--limited-only/bool=false
--active/bool=false
[block]:
if interval != 0 and not 4 <= interval <= 16384:
throw "Invalid interval"
if window != 0 and not 4 <= window <= interval:
throw "Invalid window"
duration-us := duration ? (max 0 duration.in-us) : -1
resource-state_.clear-state COMPLETED-EVENT_
ble-scan-start_ resource_ (not active) duration-us
ble-scan-start_ resource_ (not active) duration-us interval window limited-only
is-macos := system.platform == system.PLATFORM_MACOS
try:
while true:
Expand Down
2 changes: 1 addition & 1 deletion src/primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ namespace toit {
PRIMITIVE(create_central_manager, 1) \
PRIMITIVE(close, 1) \
PRIMITIVE(release_resource, 1) \
PRIMITIVE(scan_start, 3) \
PRIMITIVE(scan_start, 6) \
PRIMITIVE(scan_next, 1) \
PRIMITIVE(scan_stop, 1) \
PRIMITIVE(connect, 3) \
Expand Down
6 changes: 4 additions & 2 deletions src/resources/ble_darwin.mm
Original file line number Diff line number Diff line change
Expand Up @@ -826,8 +826,10 @@ - (id)initWithResource:(toit::BleResource*)resource {
}

PRIMITIVE(scan_start) {
ARGS(BleCentralManagerResource, central_manager, bool, passive, int64, duration_us);

ARGS(BleCentralManagerResource, central_manager, bool, passive, int64, duration_us, int, interval, int, window, bool, limited);
USE(interval);
USE(window);
USE(limited);
Locker locker(central_manager->scan_mutex());
bool active = [central_manager->central_manager() isScanning];

Expand Down
8 changes: 4 additions & 4 deletions src/resources/ble_esp32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2417,7 +2417,7 @@ PRIMITIVE(close) {
}

PRIMITIVE(scan_start) {
ARGS(BleCentralManagerResource, central_manager, bool, passive, int64, duration_us)
ARGS(BleCentralManagerResource, central_manager, bool, passive, int64, duration_us, int, interval, int, window, bool, limited)

Locker locker(central_manager->group()->mutex());

Expand All @@ -2443,10 +2443,10 @@ PRIMITIVE(scan_start) {
disc_params.passive = passive ? 1 : 0;

/* Use defaults for the rest of the parameters. */
disc_params.itvl = 0;
disc_params.window = 0;
disc_params.itvl = interval;
disc_params.window = window;
disc_params.filter_policy = 0;
disc_params.limited = 0;
disc_params.limited = limited ? 1 : 0;

err = ble_gap_disc(BLE_ADDR_PUBLIC, duration_ms, &disc_params,
BleCentralManagerResource::on_discovery, central_manager->token());
Expand Down
28 changes: 23 additions & 5 deletions tests/hw/esp32/ble6-advertise-shared.toit
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,17 @@ main-peripheral:
next-semaphore.down
peripheral.stop-advertise

is-general-advertisement := false
advertise := : | blocks scan-response-blocks |
advertisement = AdvertisementData blocks
scan-response := scan-response-blocks
? AdvertisementData scan-response-blocks
: null
peripheral.start-advertise --allow-connections advertisement --scan-response=scan-response
peripheral.start-advertise
advertisement
--allow-connections
--scan-response=scan-response

next-semaphore.down
peripheral.stop-advertise

Expand All @@ -93,9 +98,11 @@ main-peripheral:
[ // The scan response.
DataBlock.services-128 [TEST-SERVICE],
]



advertise.call [
DataBlock.flags --general-discovery,
DataBlock.name "Test",
]
null

done = true

Expand Down Expand Up @@ -188,7 +195,7 @@ main-central:

advertisement/AdvertisementData? := null
scan-response/AdvertisementData? := null
while true: // Use loop to be able to break out of the block.
while true: // Use a loop to be able to break out of the block.
central.scan --duration=(Duration --s=3) --active: | device/RemoteScannedDevice |
if device.address == address:
if device.is-scan-response:
Expand All @@ -205,6 +212,17 @@ main-central:

characteristic.write #[central-test-counter++]

// Test limited scanning.
central.scan --duration=(Duration --s=1) --limited-only: | device/RemoteScannedDevice |
if device.address == address: unreachable
// But we should find the device with general scanning.
while true: // Use a loop to be able to break out of the block.
central.scan --duration=(Duration --s=3): | device/RemoteScannedDevice |
if device.address == address: break
unreachable

characteristic.write #[central-test-counter++]

remote-device.close
central.close
adapter.close
Expand Down

0 comments on commit a315c16

Please sign in to comment.