bleak
bleak copied to clipboard
Active scan data replaces passive data in the manufacturer_data dictionary.
- bleak version: 0.21.1
- Python version: 3.8.10
- Operating System: Linux Mint 20.3
- BlueZ version (
bluetoothctl -v
) in case of Linux: 5.53
Description
I have a BLE device that I'm developing that uses active scanning to provide additional data. Once in a while the bytes in the beginning of the array end up matching the manufacturer id of the advertising data and they replace it in the manufacturer_data dictionary.
I also scan this device using a microcontroller and the BLE Scanner app for Android, and both are able to read the entire data.
I'm running short on bytes so I can't afford losing two bytes to have a distinct dictionary key.
Is it possible to have the advertising data + active scan data before it is processed into a dictionary?
No, this is not possible with BlueZ. Since it doesn't conform to the Bluetooth specifications, it is not going to work universally.
Sorry, how's this non-conformant?
Without seeing the actual data, I can't say for sure, but manufacturer data should always have a valid manufacturer id as the first two bytes.
But the issue is triggered when the data sent during the active scan has the same bytes as the manufacturer id in data previously sent during the announcing.
This sounds like the expected behavior (from the point of view of BlueZ and Bleak). If manufacturer data changes, the old value is replaced.
Sorry, how's this non-conformant?
Technically it is (ignoring the fact that you shall register the Company ID used, if you intend to commercialize the device), but in a way you yourself described:
Once in a while the bytes in the beginning of the array end up matching the manufacturer id of the advertising data and they replace it in the manufacturer_data dictionary. I'm running short on bytes so I can't afford losing two bytes to have a distinct dictionary key.
The Bluetooth Core Specification v5.4, Vol 3, Part C:
11 ADVERTISING AND SCAN RESPONSE DATA FORMAT The format of Advertising, Periodic Advertising, and Scan Response data is shown in Figure 11.1. The data consists of a significant part and a nonsignificant part. The significant part contains a sequence of AD structures. Each AD structure shall have a Length field of one octet, which contains the Length value and shall not be zero, and a Data field of Length octets. The first octet of the Data field shall contain the AD type field. The content of the remaining Length - 1 octets in the Data field depends on the value of the AD type field and is called the AD data. The non-significant part shall only be present when necessary to fill a fixed-length field and shall contain all-zero octets. Only the significant part of the data should be sent over the air.
The Supplement to the Bluetooth Core Specification v11, Part A
1.4 MANUFACTURER SPECIFIC DATA The Manufacturer Specific data type is used for manufacturer specific data. The first two data octets shall contain a company identifier from Assigned Numbers. The interpretation of any other octets within the data shall be defined by the manufacturer specified by the company identifier.
Therefore, as dlech commented, if an AD structure FFxxxx...
is followed by another AD structure FFxxxx...
, either in the advertising or scan response data, the scanner shall "update" the manufacturer data for xxxx
with the latest value - effectively replacing the previous value.
Considering that you don't plan to be fully compliant anyway, what about packing your data under some other AD type (e.g. 0x16/0x20/0x21: Service Data - 16/32/128-bit UUID, 0x24: URI, 0x2C: BIGInfo, ...) or using extended advertising data?