How to add Flags inside Advertising Data?
Thank you @ukBaz for your great work!
In my project I'm trying to send special BT-Advertising-Telegrams to control MouldKing Hubs.
My platform is a Raspberry 4.
I managed to send the required telegrams using the deprecated HCITool:
hcitool -i hci0 cmd 08 0008 3E 02 01 02 1b ff f0 ff 6D B6 43 CF 7E 8F 47 11 88 66 59 38 D1 7A AA 26 49 5E 13 14 15 16 17 18
hcitool -i hci0 cmd 0x08 0x0006 A0 00 A0 00 03 00 00 00 00 00 00 00 00 07 00
hcitool -i hci0 cmd 0x08 0x000a 01
This calls generate the following output - catched by wireshark Inside the "Advertising Data" are two bytes of "Flags", followed by the "Manufacturer Specific" data
Frame 2: 63 bytes on wire (504 bits), 63 bytes captured (504 bits) on interface COM3-4.2, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
Access Address: 0x8e89bed6
Packet Header: 0x2502 (PDU Type: ADV_NONCONN_IND, TxAdd: Public)
Advertising Address: RaspberryPiT_c2:62:00 (dc:a6:32:c2:62:00)
Advertising Data
Flags
Length: 2
Type: Flags (0x01)
000. .... = Reserved: 0x0
...0 .... = Simultaneous LE and BR/EDR to Same Device Capable (Host): false (0x0)
.... 0... = Simultaneous LE and BR/EDR to Same Device Capable (Controller): false (0x0)
.... .0.. = BR/EDR Not Supported: false (0x0)
.... ..1. = LE General Discoverable Mode: true (0x1)
.... ...0 = LE Limited Discoverable Mode: false (0x0)
Manufacturer Specific
Length: 27
Type: Manufacturer Specific (0xff)
Company ID: Unknown (0xfff0)
Data: 6db643cf7e8f471188665938d17aaa26495e131415161718
[Expert Info (Note/Undecoded): Undecoded]
CRC: 0x0a9130
I'm trying to reproduce the same BT-telegrams by modifying your example "manufacturer_data_beacon.py":
from bluezero import broadcaster
def main():
alt = broadcaster.Beacon()
alt.add_manufacturer_data(
'fff0', # Manufacturer ID
b'\x6D\xB6\x43\xCF\x7E\x8F\x47\x11\x88\x66\x59\38\xD1\x7A\xAA\26\x5E\13\x14\x15\x16\x17\x18')
alt.start_beacon()
if __name__ == '__main__':
main()
Wireshark's output looks like this - very close to my requirements:
Frame 11872: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface COM3-4.2, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
Access Address: 0x8e89bed6
Packet Header: 0x2200 (PDU Type: ADV_IND, ChSel: #1, TxAdd: Public)
Advertising Address: RaspberryPiT_c2:62:00 (dc:a6:32:c2:62:00)
Advertising Data
Manufacturer Specific
Length: 27
Type: Manufacturer Specific (0xff)
Company ID: Unknown (0xfff0)
Data: 6db643cf7e8f47118866590338d17aaa165e0b1415161718
[Expert Info (Note/Undecoded): Undecoded]
CRC: 0xb3521a
Only the Flags are missing.
Could you please help me to add the missing Flags ? :)
I'm not sure I have a good answer for you on this as it is about what BlueZ supports.
Depending what version of BlueZ you have on your RPi, there is the possibility to add more detail to advertisements using the data property but this is hidden behind the experimental flag and so Bluezero doesn't support it. More information at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt?h=5.65#n64
To access features hidden behind the experimental flag you have to restart bluetoothd with the --experimental command line flag.
If you wanted a command line option that was not deprecated then doing it with bluetoothctl or btmgmt should be possible.
For example:
$ sudo btmgmt add-adv -d 1bfff0ff6DB643CF7E8F471188665938D17AAA26495E131415161718 --general-discov 1
Instance added: 1
seems to be very close to what you are looking for.
To remove the advertisement you use:
$ sudo rm-adv 1
Hi @ukBaz :) Thank you very much for your very quick response! :) I knew you're the right man to ask that stuff! ;)
I still tried to extend some examples for BlueZ for my needs - like adding the Discoverable property (wich adds Flags to the advertisement but behind the manufacturer specific data) and the usage of the Data property. ...but sadly without success.
Now I know why: I did not set the bluetoothd to experimental mode Aaaarggghh :( I'll give it a try with experimental mode set...
And I will add an advertiser-class using the btmgmt tool, thanks for your hint.
Another idea is - to prevent using commandline tools - to do the same as hciool or btmgmt internally do in python. What do you think - is that possible, does it make sense?
You might want to take a look at: https://github.com/ukBaz/python-btsocket
I did some experiments to use the Bluez mgmt API. https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/mgmt-api.txt
Thanks a lot - now I have a very good starting point...
Hi @ukBaz :)
First I tried your suggestion with btmgmt tool
$ sudo btmgmt add-adv -d 1bfff0ff6DB643CF7E8F471188665938D17AAA26495E131415161718 --general-discov 1
Instance added: 1
and it works like a charm! ;)
I added and removed three instances of different advertisements with success.
Now I have the next problem: The rotation speed of the three advertised instances is to slow - it's about 2 seconds per advertisement (changing output from btmon). So my MouldKing hubs go into timeout. I guess, they need to receive an advertisement telegram every second minimum.
I think I have to set the add_ext_adv_params_options "min-internal" and "max-interval".
I looked everywhere how to set these parameters with btmgmt tool. Without success. Could you please help me to climb this little hill...? ;)
looked everywhere how to set these parameters with btmgmt tool. Without success. Could you please help me to climb this little hill...? ;)
I think you are looking for the --duration <duration> and --timeout <timeout> options. Please note that the units are in seconds so I have never tried to go below 1 second.
The full help for the add-adv command can be read with the following:
$ btmgmt add-adv -h
Usage: add-adv [options] <instance_id>
Options:
-u, --uuid <uuid> Service UUID
-d, --adv-data <data> Advertising Data bytes
-s, --scan-rsp <data> Scan Response Data bytes
-t, --timeout <timeout> Timeout in seconds
-D, --duration <duration> Duration in seconds
-P, --phy <phy> Phy type, Specify 1M/2M/CODED
-c, --connectable "connectable" flag
-g, --general-discov "general-discoverable" flag
-l, --limited-discov "limited-discoverable" flag
-n, --scan-rsp-local-name "local-name" flag
-a, --scan-rsp-appearance "appearance" flag
-m, --managed-flags "managed-flags" flag
-p, --tx-power "tx-power" flag
e.g.:
add-adv -u 180d -u 180f -d 080954657374204C45 1
@ukBaz, dear Barry, it's very kind of you to help me with your quick responses. Thank you :)
$ btmgmt add-adv -h
Usage: add-adv [options] <instance_id>
OK, this will help me in the future! ;)
And I'll try out the timeout und duration options.
At the moment my code switches between the different advertisement in a loop by calling the btmgmt tool about 4 times the second...