https://toitlang.org/ logo
Ble AdvertisementData shows only one instance of A...
# help
z
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:
Copy code
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"
Copy code
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] https://cdn.discordapp.com/attachments/1339094810455445565/1339094811076067429/image.png?ex=67ad78ba&is=67ac273a&hm=ed43a7c012bcab922c412c28109a761621fd7b04ee4ea378b8c1e895dc58d19d&
from
Copy code
ble-scan-next_ central-manager:
  #primitive.ble.scan-next
Copy code
(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
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
maybe it's while doing an
--active
scan on MacOS specifically? I would expect to be getting some true values of
--.is-scan-response
Copy code
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"
Copy code
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
f
Which example is this? Where does the code come from?
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:
Copy code
[central_manager->central_manager() scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"180D"]] 
                                                          options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}];
Do you think you could test that?
z
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?
ok, got it compiling and changed these
options
but the ble scan is still showing no responses where
Copy code
// 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 https://cdn.discordapp.com/attachments/1339094810455445565/1339243377362731050/image.png?ex=67ae0317&is=67acb197&hm=a540b2bb75a95c0d58e685bcf38ff72aba0302ac75bca3692a81bb1a0880acd1&
more 🦆 debugging: I have added in these log statements: at L507: this will log what the Mac gets for the structured advertising data. https://cdn.discordapp.com/attachments/1339094810455445565/1339249833566933092/image.png?ex=67ae091a&is=67acb79a&hm=88773e571754a16545f7434000eea0f2592d439733d6bb3242720ac62fc18fe9&
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.
Copy code
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;
}
Copy code
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
f
Thanks for testing. I will try to find some time to look at the Darwin sources.
@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
z
Nice!
f
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.