guild icon
Toit
#Ble AdvertisementData shows only one instance of Advertisement Data type
Thread channel in help
z3ugma
z3ugma 02/12/2025 04:44 AM
Here is the advertisement message of a device from nRFConnect. There are multiple instances of advertisement data type 0xFF manufacturer-specific data. Toit on MacOS BLE shows only the first instance of the advertisement data:

central := adapter.central device := find_by_name central DEV_NAME print device.data.raw identifier := device.identifier remote_device := central.connect identifier print "Address: $remote_device.identifier"

find_by_name central/ble.Central name/string: central.scan --duration=SCAN_DURATION: | device/ble.RemoteScannedDevice | if device.identifier and device.data.name == name: return device throw "no ring device found"
#[0xff, 0xff, 0x00, 0x00, 0x2b, 0x51, 0xb0, 0x23, 0x3a, 0xd1]
z3ugma
z3ugma 02/12/2025 04:45 AM
from
ble-scan-next_ central-manager: #primitive.ble.scan-next
z3ugma
z3ugma 02/12/2025 04:53 AM
(venv) ?1 circul % jag run -d host ble_scan.toit Class 'DataBlock' does not have any method 'hash-code'. 0: HashedInsertionOrderedCollection_.hash-code_ <sdk>/core/collections.toit:2188:16 1: HashedInsertionOrderedCollection_.find_ <sdk>/core/collections.toit:2303:13 2: Set.add <sdk>/core/collections.toit:2565:17 3: Set.add-all.<block> <sdk>/core/collections.toit:2577:20 4: SmallArray_.do_ <sdk>/core/collections.toit:954:3 5: List_.do <sdk>/core/collections.toit:1983:19 6: Set.add-all <sdk>/core/collections.toit:2577:16 7: main.<block> ble_scan.toit:18:12 8: Central.scan.<block> <sdk>/ble/remote.toit:135:9 9: Central.scan <sdk>/ble/remote.toit:74:3 10: main ble_scan.toit:16:11 Error: exit status 1 (venv) ?1 circul %

^^that example actually now throws an error
z3ugma
z3ugma 02/12/2025 05:14 AM
I think what I've come to is that my find-by-name function only returns the very first thing it comes across which may only include the AD packet and not the scan response packet which contains the further info
z3ugma
z3ugma 02/12/2025 05:36 AM
maybe it's while doing an --active scan on MacOS specifically? I would expect to be getting some true values of --.is-scan-response
z3ugma
z3ugma 02/12/2025 05:37 AM
main: adapter := ble.Adapter central := adapter.central // An active scan may need the responses to be merged. central.scan --duration=(Duration --s=5) --active: | device/ble.RemoteScannedDevice | print "$device.is-scan-response $device.rssi"


jag run -d host ble_scan.toit false -47 false -82 false -48 false -78 false -54 false -76 false -77 false -83 false -91 false -87 false -75 false -61 false -73 false -95 false -88 false -90 false -102 false -98 false -95
z3ugmaOPz3ugma
``` (venv) ?1 circul % jag run -d host blescan.toit Class 'DataBlock' does not have any method 'hash-code'. 0: HashedInsertionOrderedCollection.hash-code_ <sdk>/core/collection...
floitsch
floitsch 02/12/2025 11:12 AM
Which example is this? Where does the code come from?
z3ugmaOPz3ugma
``` main: adapter := ble.Adapter central := adapter.central // An active scan may need the responses to be merged. central.scan --duration=(Duration --s=5) --active: | dev...
floitsch
floitsch 02/12/2025 11:25 AM
The macos BLE driver is best-effort only, since I don't own a mac, and the code wasn't written by us.
It might be that we need to change the "allow duplicate keys": https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerscanoptionallowduplicateskey

https://github.com/toitlang/toit/blob/d8e86dc24d69fe2d24b8040f842485f3df2e2ae2/src/resources/ble_darwin.mm#L839

According to chatgpt it should be changed to:
[central_manager->central_manager() scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"180D"]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}];

Do you think you could test that?
A Boolean value that specifies whether the scan should run without duplicate filtering.
Program your microcontrollers in a fast and robust high-level language. - toitlang/toit
z3ugma
z3ugma 02/12/2025 02:03 PM
z3ugma
z3ugma 02/12/2025 02:04 PM
and yes, I can test the suggested change to ble_darwin.mm

That will require compiling the src, right? It's not interpreted / I can't just edit my current Jag install on the fly?
z3ugma
z3ugma 02/12/2025 02:35 PM
ok, got it compiling and changed these options but the ble scan is still showing no responses where
// An active scan may need the responses to be merged. central.scan --duration=(Duration --s=5) --active: | device/ble.RemoteScannedDevice | print "$device.is-scan-response $device.rssi"

is-scan-response is true
z3ugma
z3ugma 02/12/2025 03:00 PM
more :🦆: debugging:

I have added in these log statements: at L507: this will log what the Mac gets for the structured advertising data.
z3ugma
z3ugma 02/12/2025 03:02 PM
2 subsequent lines of scanned data, note the kCBAdvDataManufacturerData. In the first scan there are 37 bytes of mnfr data. in the second scan, there are 10. same peripheral ID and same identifier.

2025-02-12 08:59:07.338 toit.run[24749:1947303] Peripheral: <CBPeripheral: 0x104c05250, identifier = 6EF5B2E2-87AF-477E-D116-B27C6F7EF37E, name = MR, mtu = 0, state = disconnected> 2025-02-12 08:59:07.338 toit.run[24749:1947303] RSSI: -84 2025-02-12 08:59:07.338 toit.run[24749:1947303] Advertisement Data: { kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = MR; kCBAdvDataManufacturerData = {length = 37, bytes = 0x00002b51 b0233ad1 01010100 00000000 ... 000067ac b73b0000 }; kCBAdvDataRxPrimaryPHY = 129; kCBAdvDataRxSecondaryPHY = 0; kCBAdvDataServiceUUIDs = ( FAB1 ); kCBAdvDataTimestamp = "761065147.33799"; } 2025-02-12 08:59:07.339 toit.run[24749:1947303] Peripheral: <CBPeripheral: 0x104c05250, identifier = 6EF5B2E2-87AF-477E-D116-B27C6F7EF37E, name = MR, mtu = 0, state = disconnected> 2025-02-12 08:59:07.339 toit.run[24749:1947303] RSSI: -83 2025-02-12 08:59:07.693 toit.run[24749:1947303] Advertisement Data: { kCBAdvDataIsConnectable = 1; kCBAdvDataManufacturerData = {length = 10, bytes = 0x4c001006351e1ab800cd}; kCBAdvDataRxPrimaryPHY = 1; kCBAdvDataRxSecondaryPHY = 0; kCBAdvDataTimestamp = "761065147.693242"; kCBAdvDataTxPowerLevel = 12; }
z3ugma
z3ugma 02/12/2025 03:09 PM
2025-02-12 09:05:12.713 toit.run[30024:1967859] Advertisement Mnfr Data: {length = 8, bytes = 0x00002b51b0233ad1} 2025-02-12 09:05:12.713 toit.run[30024:1967859] Peripheral: <CBPeripheral: 0x13e706860, identifier = 6EF5B2E2-87AF-477E-D116-B27C6F7EF37E, name = MR, mtu = 0, state = disconnected> 2025-02-12 09:05:12.713 toit.run[30024:1967859] RSSI: -84 false -84 2025-02-12 09:05:12.713 toit.run[30024:1967859] Advertisement Mnfr Data: {length = 37, bytes = 0x00002b51 b0233ad1 01010100 00000000 ... 000067ac b8a90000 } 2025-02-12 09:05:12.713 toit.run[30024:1967859] Peripheral: <CBPeripheral: 0x13e706860, identifier = 6EF5B2E2-87AF-477E-D116-B27C6F7EF37E, name = MR, mtu = 0, state = disconnected> 2025-02-12 09:05:12.713 toit.run[30024:1967859] RSSI: -82 2025-02-12 09:05:12.720 toit.run[30024:1967859] Advertisement Mnfr Data: {length = 6, bytes = 0x4c0012020000} 2025-02-12 09:05:12.720 toit.run[30024:1967859] Peripheral: <CBPeripheral: 0x13e611c90, identifier = 6D78A7EF-B545-7E99-B985-DED0AA52BC29, name = (null), mtu = 0, state = disconnected> 2025-02-12 09:05:12.720 toit.run[30024:1967859] RSSI: -37

^so here we see the NSLog statements followed by the Toit stdout. it appears that only the first packet is passed up to Toit. the second packet doesn't have a false -82 for example
(edited)
floitsch
floitsch 02/12/2025 03:11 PM
Thanks for testing. I will try to find some time to look at the Darwin sources.
floitsch
floitsch 03/05/2025 09:41 AM
@z3ugma It took some time, but I finally had a look. I think I found the reason for the behavior.
https://github.com/toitlang/toit/pull/2723
z3ugma
z3ugma 03/07/2025 01:51 PM
Nice!
floitsch
floitsch 03/07/2025 02:00 PM
Kasper tried to test on his Mac, but he already got the complete advertisement before the patch. So something in his setup is different. If you could try too that would be nice.
19 messages in total