New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 806089 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Jan 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug

Blocking:
issue 518942



Sign in to add a comment

[bluetooth] Reading advertised Service Data is close to impossible on macOS for BLE Security Keys

Project Member Reported by jdoerrie@chromium.org, Jan 25 2018

Issue description

When advertising over BLE my U2F security key sends two packages in quick succession, one Connectable undirected advertising (ADV_IND) package followed by a Scan Response (SCAN_RSP) package. However, only the ADV_IND package includes meta data such as all Service UUIDs and Service Data, the SCAN_RSP package does not. Given that SCAN_RSP is sent almost immediately after ADV_IND (~1 ms delay), it clears out the cached service data of the corresponding device and a call to BluetoothDevice::GetServiceData() will almost always return an empty set.

I am not sure what the best solution is. Given that the included data in ADV_IND seems to be a strict superset of SCAN_RSP we could try to detect SCAN_RSP packages and simply ignore them in favor of ADV_IND. Another option would be to not clear out the Service Data, but simply merge the new data, overwriting already existing keys.

Please let me know if there is another option I am missing.

For reference, here are the packages as seen by Apple's PackageLogger utility:

ADV_IND:

[Jan 25 12:41:17.894]  [HCI EVENT]  LE Meta Event - LE Advertising Report - 0 - 08:7C:BE:BF:C1:19  -43 dBm
               LE Meta Event - LE Advertising Report - 0 - 08:7C:BE:BF:C1:19  -43 dBm
               Parameter Length: 40 (0x28)
               LE Advertising Report
               Num_Reports: 0X01
               Event_Type: Connectable undirected advertising (ADV_IND)
               Address_Type: Public Device Address
               Peer_Address: 08:7C:BE:BF:C1:19
               Length_Data: 0X1C
               Flags: 0x04
               Local Name (Incomplete): U2F FT
               16 bit UUIDs: 0xfffd 0x180a 0x180f 
               Service Data: -- 
               Manufacturer Specific Data: -- 
               Data: 02 01 04 07 08 55 32 46 20 46 54 07 03 FD FF 0A 18 0F 18 04 16 FD FF 40 03 FF 33 37 
               RSSI:  -43 dBm

SCAN_RSP:

[Jan 25 12:41:17.895]  [HCI EVENT]  LE Meta Event - LE Advertising Report - 0 - 08:7C:BE:BF:C1:19  -43 dBm
               LE Meta Event - LE Advertising Report - 0 - 08:7C:BE:BF:C1:19  -43 dBm
               Parameter Length: 20 (0x14)
               LE Advertising Report
               Num_Reports: 0X01
               Event_Type: Scan Response (SCAN_RSP)
               Address_Type: Public Device Address
               Peer_Address: 08:7C:BE:BF:C1:19
               Length_Data: 0X08
               16 bit UUIDs: 0x180a 
               Manufacturer Specific Data: -- 
               Data: 03 03 0A 18 03 FF 33 37 
               RSSI:  -43 dBm

Here is the dump of what BluetoothAdapterMac sees:

ADV_IND:

[71495:775:0125/124117.894925:VERBOSE3:bluetooth_adapter_mac.mm(581)] <BluetoothLowEnergyDeviceMac B9:04:02:C2:9E:B2/0x7f8defec6840, GATT disconnected, "YDRWFA">: Device updated with {
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = "U2F FT";
    kCBAdvDataManufacturerData = <3337>;
    kCBAdvDataServiceData =     {
        "Unknown (<fffd>)" = <40>;
    };
    kCBAdvDataServiceUUIDs =     (
        "Unknown (<fffd>)",
        "Device Information",
        Battery
    );
}

SCAN_RSP:

[71495:775:0125/124117.897633:VERBOSE3:bluetooth_adapter_mac.mm(581)] <BluetoothLowEnergyDeviceMac B9:04:02:C2:9E:B2/0x7f8defec6840, GATT disconnected, "YDRWFA">: Device updated with {
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataManufacturerData = <3337>;
    kCBAdvDataServiceUUIDs =     (
        "Device Information"
    );
}

 

Comment 1 by ortuno@chromium.org, Jan 26 2018

Cc: reillyg@chromium.org
Status: Available (was: Untriaged)
We've been meaning to refactor how we handle advertisements since forever. The current pattern was imposed on us by BlueZ and we never got a chance to revisit it.

Ideally we would introduce a new method in BluetoothAdapterObserver similar to didDiscoverPeripheral[1] of CoreBluetooth and onScanResult[2] of Android. The call would include all the advertisement information so clients wouldn't have to query it again.

If there is a way to distinguish between adv_ind and scan_rsp, then we could do what you suggest and merge the new data with previous data. This might result in us exposing wrong data in some edge cases though:

Device:
1. Sends adv_ind with Data1
2. Sends scan_rsp with Data2
3. Sends adv_ind with Data3
4. Sends scan_rsp with Data4

Chrome:
1. Receives adv_ind with Data1
2. Misses 2. and 3. from the device
3. Receives scan_rsp with Data4
4. Merges Data1 and Data4.


Your second suggestion is something we used to do but moved away from because clients couldn't know if a device stopped advertising a service.

Comment 2 by ortuno@chromium.org, Jan 26 2018

Also, is there no chance of changing the U2F advertising packet? It was my understanding that using scan response generates quite a bit of overhead.

Comment 3 by ortuno@chromium.org, Jan 26 2018

Blocking: 518942
Thanks ortuno@. Your comment actually made me realize that I could simply listen to DeviceChanged() to get the desired advertisement data. I still need to call GetServiceData() myself, but given that observers are notified immediately after an advertisement package is received I get what I need. A new DeviceAdvertisementChanged() method (or similar) might still be useful though.

Comment 5 by ortuno@chromium.org, Jan 29 2018

Status: WontFix (was: Available)
Great! Note that BlueZ does cache services and data.

Sign in to add a comment