使用Linux和Bluez 5.0进行多个BLE连接

6
我目前正在使用BlueZ 5.0和Linux尝试连接多个BLE设备。我有一个主机BLE适配器,并且已经修改了gatttool以连接并执行此功能。如果我运行修改后的gatttool实例,我可以成功连接并接收来自BLE设备的通知数据。如果我运行另一个修改后的gatttool实例并连接到另一个BLE设备,则该应用程序开始从两个BLE设备接收通知数据,最初的应用程序不再接收任何数据。我认为这是由于套接字设置引起的,其中两个应用程序都在将其套接字配置为相同的地址和PSM(最新实例接收数据,而其他实例则被饿死)。有没有一种方法防止这种情况?理想情况下,我希望一个应用程序能够连接多个设备。我假设应用程序只能拥有一个套接字,因为多个套接字将具有与上面的多个实例相同的问题。我的BLE设备是一个作为心率监测仪的TI CC2540钥匙扣。

这不是你想要的吗?如果你想让一个应用程序连接多个设备,那么你可以通过一个单一的套接字来实现。我相信每个消息都会带有设备的蓝牙地址,所以你可以将其与正确的设备关联起来。 - Tim Tisdall
我现在明白了应该使用一个socket。ACL连接句柄应该用于分离数据。我在通过BlueZ访问此句柄时遇到了困难。socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)创建了socket。connect(sock, (struct sockaddr *) &addr, sizeof(addr))连接了socket。使用ioctl(socket, HCIGETCONNINFO, cr)访问句柄返回errno 2(没有文件)。目标地址是正确的。我上面创建的socket返回值为5,而socket = hci_open_dev(dev_id)的返回值为6。有更好的方法来获取这个句柄吗? - user2321427
1
ioctl(socket, HCIGETCONNINFO, cr) 方法适用于蓝牙经典设备,但不适用于BLE设备。我需要一种方法来访问BLE设备的ACL数据句柄以进行数据配对。在BlueZ中是否可能实现这一点? - user2321427
我有类似的问题。请解释一下你实验的结果? - abhiarora
2个回答

2

我使用Python和C的组合来让我的代码正常运行,所以我的“代码”可能看起来很奇怪,因为它可能是从任何一种语言中来的。此外,我使用了Bluez 4,因为5不支持我正在使用的内核。如果有问题,请告诉我,我可以澄清。

似乎有几种方法可以做到这一点,但我最终选择了为不同的任务打开单独的套接字。你可以打开一个单一的套接字,然后设置套接字选项以取消过滤,这样你应该能够在一个地方得到所有的数据包。然而,那是我的最初做法,我发现我的连接会在几秒钟内死掉。

要扫描连接,我打开了一个socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI),然后在设备0上执行了bind。(有一个叫做hci_get_route的函数来获取可用设备号)然后您可以调用hci_le_set_scan_parameters来设置选项,setsockopt(SOL_HCI, HCI_FILTER, filter)只获取LE扫描事件,然后调用hci_le_set_scan_enable来启动扫描。

每个设备连接都是使用socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)创建的,然后通过在套接字上调用connect并将特定设备地址放入struct sockaddr_l2中来告诉它连接到特定设备。在该套接字上,您应该只能从该设备获取数据包。(一个注意点...我发现我的适配器在进行活动扫描时不允许连接...我必须在连接之前暂时关闭它,然后再打开它。否则,我将从errno中得到一个BUSY错误)

虽然这么说了,但我认为你应该使用DBUS来完成Bluez 5中的所有操作。不幸的是,对于我正在做的事情,这不是一个真正的选项。我提到的函数在共享库中,这个共享库显然在5中没有默认安装(您必须使用configure明确要求安装)。他们停止默认安装共享库,因为他们想鼓励人们使用DBUS。


我希望最初不使用DBUS来解决这个问题。我需要检索与传入套接字数据相关联的句柄,以便将数据与正确的连接关联起来。ioctl(socket,HCIGETCONNINFO,cr)调用对于BLE设备无效。您是否有一种方法可以访问与连接和传入数据相关联的句柄信息? - user2321427
我不确定我理解了...你没有初始化连接吗?那么在这种情况下,您不已经有句柄并知道连接到了什么吗? - Tim Tisdall
1
当我执行connect(socket, (struct sockaddr *)&addr, sizeof(addr))时,返回值为0,表示套接字连接已建立。如果同时运行hcidump,则可以看到句柄1025分配给该连接。该连接的进一步数据交换使用该句柄。我正在尝试访问该句柄。 - user2321427
句柄和套接字/文件描述符是一样的吗?你可以尝试查看sockaddr结构体。我想我让Python来完成那部分工作。 - Tim Tisdall
等待一下,fd 应该在 socket 变量中。 - Tim Tisdall

1
我们已经将hcitool和gatttool的代码结合起来。该代码可用于2个设备(扫描、hci_le_create_conn和gatt_connect)。我相信使用设备数量没有限制。
1 Start cmd_lescan (from hcitool.c)
2.For each device scanned - 
      cmd_lecc (from hcitool.c)
      gatt_connect (from gatttool.c)

这样,一个进程就可以管理多个BLE设备。我们不必关闭扫描,只需忽略非广告信息即可:
        if (meta->subevent != 0x02)
                continue; 

感谢并期待评论。

你能解释一下为什么要使用cmd_lecc和GATT_connect来与同一个设备建立两个连接吗? - abhiarora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接