简体   繁体   English

如何在 Ubuntu 20.04 上使用 BlueZ 5 和 5.4 内核发送打包的广告数据包

[英]How to send a packed advertising packet with BlueZ 5 and the 5.4 kernel on Ubuntu 20.04

In prior kernels and releases of Ubuntu, it was possible to use the hci socket interface to send an arbitrary set of 31 bytes as an advertising beacon, but in ubuntu 20.04 the hci bluetooth tools were deprecated, as were some elements of the socket API they were using.在之前的 Ubuntu 内核和版本中,可以使用 hci 套接字接口发送任意一组 31 字节作为广告信标,但在 ubuntu 20.04 中,不推荐使用 hci 蓝牙工具,因为它们的套接字 API 的某些元素正在使用。

The goal is to have some N number of devices broadcast 31 bytes of sensor data to each other at a rate of 5 Hz, and have all N read the packets from the other devices.目标是让一些 N 个设备以 5 Hz 的速率相互广播 31 字节的传感器数据,并让所有 N 个设备读取来自其他设备的数据包。

With the hci socket API being deprecated, the replacements are the DBus BlueZ API and the Management BlueZ API.随着 hci 套接字 API 被弃用,替代品是 DBus BlueZ API 和管理 BlueZ API。 The DBus API is limited and seems to only allow a max of 25 bytes. DBus API 是有限的,似乎只允许最多 25 个字节。 The Management API seems more capable, and it seems to work on Ubuntu 18.04/4.15 kernel (though even there the scan seemed to only pick up the advertisements sporadically when switching between scan and advertise every 100ms while with the hci api it was rock solid), but on Ubuntu 20.04/5.4 kernel, various issues crop up.管理 API 似乎更强大,它似乎可以在 Ubuntu 18.04/4.15 内核上运行(尽管即使在那里,扫描似乎也只是在每 100 毫秒在扫描和广告之间切换时偶尔接收广告,而使用 hci api 时它坚如磐石) ,但在 Ubuntu 20.04/5.4 内核上,会出现各种问题。

  • Using the hci socket API seems like it could still be possible, but even running something like hcitool lescan results in btmon saying Command Disallowed .使用 hci 套接字 API 似乎仍然是可能的,但即使运行hcitool lescan类的东西hcitool lescan导致btmonCommand Disallowed I believe this might be due to LE Extended Advertising being enabled, but I have not figured out how to disable it yet.我相信这可能是由于启用了 LE 扩展广告,但我还没有想出如何禁用它。

  • Using the DBus API (or bluetoothctl ) is still limited and doesn't allow the full use of the 31 bytes (or even 30 bytes + length)使用 DBus API(或bluetoothctl )仍然受到限制,并且不允许充分利用 31 个字节(甚至 30 个字节 + 长度)

  • Using the Management API leads to a Advertising Timeout shortly after setting the advertising data, which I think might be from LE Extended Advertising being enabled.在设置广告数据后不久,使用管理 API 会导致Advertising Timeout ,我认为这可能是由于启用了 LE 扩展广告。 This problem persists even if I explicitly set the timeout in the packet.即使我在数据包中明确设置了超时,这个问题仍然存在。

For example, running例如,运行

btmgmt add-adv -c -d 1E000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D 1

to send an advertising packet at a fixed MAC with the advertising data being length:31 payload: 0-30 results in a btmon output of:在固定 MAC 发送广告数据包,广告数据为 length:31 payload:0-30 导致btmon输出:

  < HCI Command:... (0x08|0x0036) plen 25  #631 [hci0] 5676.358401
        Handle: 0x01
        Properties: 0x0013
          Connectable
          Scannable
          Use legacy advertising PDUs: ADV_IND
        Min advertising interval: 1280.000 msec (0x0800)
        Max advertising interval: 1280.000 msec (0x0800)
        Channel map: 37, 38, 39 (0x07)
        Own address type: Public (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:00:00:00:00:00 (OUI 00-00-00)
        Filter policy: Allow Scan Request from Any, Allow Connect Request from Any (0x00)
        TX power: 127 dbm (0x7f)
        Primary PHY: LE 1M (0x01)
        Secondary max skip: 0x00
        Secondary PHY: LE 1M (0x01)
        SID: 0x00
        Scan request notifications: Disabled (0x00)
> HCI Event: Command Co.. (0x0e) plen 5  #632 [hci0] 5676.359321
      LE Set Extended Advertising Parameters (0x08|0x0036) ncmd 1
        Status: Success (0x00)
        TX power (selected): 7 dbm (0x07)
< HCI Command: L.. (0x08|0x0039) plen 6  #633 [hci0] 5676.359410
        Extended advertising: Enabled (0x01)
        Number of sets: 1 (0x01)
        Entry 0
          Handle: 0x01
          Duration: 2000 ms (0xc8)
          Max ext adv events: 0
> HCI Event: Command Co.. (0x0e) plen 4  #634 [hci0] 5676.361330
      LE Set Extended Advertising Enable (0x08|0x0039) ncmd 2
        Status: Success (0x00)
@ MGMT Event: Com.. (0x0001) plen 4  {0x0003} [hci0] 5676.361372
      Add Advertising (0x003e) plen 1
        Status: Success (0x00)
        Instance: 1
> HCI Event: LE Meta Ev.. (0x3e) plen 6  #635 [hci0] 5676.362333
      LE Advertising Set Terminated (0x12)
        Status: Advertising Timeout (0x3c)
        Handle: 1
        Connection handle: 65535
        Number of completed extended advertising events: 0

Is there a good way to recreate the functionality that was available using the hci socket, or a way to disable extended advertising so that the hci socket works again?是否有一种很好的方法来重新创建使用 hci 套接字可用的功能,或者一种禁用扩展广告以便 hci 套接字再次工作的方法?

This image from Jos Ryke might help explain what is going on. Jos Ryke 的这张图片可能有助于解释发生了什么。 Of those 31 bytes, 3 were always used for setting the advertising flags.在这 31 个字节中,3 个总是用于设置广告标志。

BT 4.0 广告包

Looking at the source code for btmgmt those flags are now set with the -g , and -l command line switches.查看 btmgmt 的源代码,现在使用-g-l命令行开关设置了这些标志。 Use general discoverable mode to advertise indefinitely.使用通用可发现模式无限期地做广告。

static void add_adv_usage(void)
{
    bt_shell_usage();
    print("Options:\n"
        "\t -u, --uuid <uuid>         Service UUID\n"
        "\t -d, --adv-data <data>     Advertising Data bytes\n"
        "\t -s, --scan-rsp <data>     Scan Response Data bytes\n"
        "\t -t, --timeout <timeout>   Timeout in seconds\n"
        "\t -D, --duration <duration> Duration in seconds\n"
        "\t -P, --phy <phy>           Phy type, Specify 1M/2M/CODED\n"
        "\t -c, --connectable         \"connectable\" flag\n"
        "\t -g, --general-discov      \"general-discoverable\" flag\n"
        "\t -l, --limited-discov      \"limited-discoverable\" flag\n"
        "\t -n, --scan-rsp-local-name \"local-name\" flag\n"
        "\t -a, --scan-rsp-appearance \"appearance\" flag\n"
        "\t -m, --managed-flags       \"managed-flags\" flag\n"
        "\t -p, --tx-power            \"tx-power\" flag\n"
        "e.g.:\n"
        "\tadd-adv -u 180d -u 180f -d 080954657374204C45 1");
}

The other 28 bytes must start with a byte declaring the length and a byte declaring what data type the rest of the bytes in the declared length are describing.其他 28 个字节必须以声明长度的字节和声明长度的其余字节所描述的数据类型的字节开头。 It is those 28 bytes that is being set with the -d option of btmgmt .正是使用btmgmt-d选项设置的那 28 个字节。

If 28 bytes are not enough, then common workarounds people use is to split the data over multiple adverts or use scan response packet.如果 28 个字节不够,那么人们常用的解决方法是将数据拆分到多个广告上或使用扫描响应数据包。

There is more detail on the Advertising Data Format in the Core Specification where it defines an Advertising Packet as: 核心规范中有关于广告数据格式的更多详细信息,其中将Advertising Packet定义为:

A packet containing an advertising PDU.包含广告 PDU 的数据包。 See [Vol 6] Part B, Section 2.3.1参见 [Vol 6] Part B, Section 2.3.1

More data is section:更多数据是部分:

BLUETOOTH CORE SPECIFICATION Version 5.2 |蓝牙核心规范版本 5.2 | Vol 3, Part C |第 3 卷,C 部分 | 11 ADVERTISING AND SCAN RESPONSE DATA FORMAT 11 广告和扫描响应数据格式

It has an example for ADV_NONCONN_IND packet type:它有一个 ADV_NONCONN_IND 数据包类型的例子:

PDU Type: 2
ChSel: RFU
TxAdd: 1 (random)
RxAdd: RFU
AdvA: 0xC1A2A3A4A5A6 (a static device address)
AdvData: (3 octets) 0x01 0x02 0x03

Which starts with the flags data type.其中以 flags 数据类型开头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM