简体   繁体   English

如何使用Bluez发送蓝牙低功耗GATT通知?

[英]How to send Bluetooth Low Energy GATT Notification with Bluez?

I am extending plugin/gatt_example.c in Bluez sources to try the BLE Notification function without success. 我正在扩展Bluez源代码中的plugin / gatt_example.c来尝试BLE通知功能但没有成功。 I am using the included sample Battery Service in Bluez source. 我正在使用Bluez源中包含的样本电池服务。 It has 1 characteristic with READ and NOTIFY properties. 它具有READ和NOTIFY属性的1个特征。 I add dbus method to call attrib_db_update() to update the characteristic value from outside the bluetooth daemon. 我添加dbus方法来调用attrib_db_update()来更新蓝牙守护程序外部的特征值。

Now, I can connect which client (Nexus4 with Android 4.3 and iPhone (LightBlue free apps)) and start notification (setting descriptor CCC notify flags). 现在,我可以连接哪个客户端(Nexus4与Android 4.3和iPhone(LightBlue免费应用程序))并启动通知(设置描述符CCC通知标志)。 (note: ccc descriptor char has default auth permission, so from iPhone modifying CCC (start notify) will make bluez to return error: not authorize permission. Since I'm planning to deal with authorization later, I temporary change the default permission to none, and iPhone is able to set CCC notification flags). (注意:ccc描述符char具有默认的auth权限,因此从iPhone修改CCC(启动通知)将使bluez返回错误:不授权权限。由于我打算稍后处理授权,我暂时将默认权限更改为none ,iPhone可以设置CCC通知标志)。

The problem is even the client (both Android or iOS) has start notify, calling attrib_db_update() is not making bluez to send any notification to client (monitor with hcidump, no packet send to client). 问题是甚至客户端(Android或iOS)都有启动通知,调用attrib_db_update()不会使bluez向客户端发送任何通知(监视器使用hcidump,没有数据包发送到客户端)。

Question: Is there any step required beside attrib_db_update() to make bluez sending notification to client? 问题:attrib_db_update()旁边是否需要执行任何步骤才能使bluez向客户端发送通知? I appreciate any link to sample source. 我感谢任何与示例源的链接。 PS. PS。 I use bluez as peripheral + gatt server configuration (just as battery service in plugin/gatt_example.c) not vice-versa. 我使用bluez作为外设+ gatt服务器配置(就像插件/ gatt_example.c中的电池服务一样),反之亦然。

Thanks. 谢谢。

=== Update (I don't know how comment formatting work... so I add update here.) ===更新(我不知道注释格式化工作如何...所以我在这里添加更新。)
About profile/alert sample: 关于个人资料/警报样本:
Yes I already check on profile/alert prior asking the question. 是的我在询问问题之前已经查看了个人资料/警报。 Another problem is that I could not run those sample (That one reason I ask the question at the first place). 另一个问题是我无法运行这些样本(这是我首先提出问题的一个原因)。
profile/alert/server.c: attio_connected_cb() is a callback function, registered by filter_devices_notify() in server.c. profile / alert / server.c:attio_connected_cb()是一个回调函数,由server.c中的filter_devices_notify()注册。 It use btd_device_add_attio_callback() (from src/device.c). 它使用btd_device_add_attio_callback()(来自src / device.c)。 Further checking src/device.c, it look like that it check device->attrib if it exist to exec (insert to queue first then exec callback) the callback or just insert in queue until device connected?. 进一步检查src / device.c,看起来它检查device-> attrib是否存在exec(先插入队列然后执行回调)回调或只是插入队列直到设备连接?
Debugging it, it look like device->attrib is empty even if I already connected the device. 调试它,即使我已连接设备,它看起来像device-> attrib是空的。

For those interested to run/debug sample alert profile (Since there's no doc :( ). 对于那些有兴趣运行/调试样本警报配置文件的人(因为没有doc :()。
Comment out the following if (around line 564), we don't interested in those check... 如果(在第564行附近),请注释以下内容,我们对这些检查不感兴趣......

/*
        if (!g_str_equal(alert->srv, sender)) {
            DBG("Sender %s is not registered in category %s", sender,
                                    category);
            return btd_error_invalid_args(msg);
        }
    */

Run bluetoothd: ex. 运行bluetoothd:ex。 bluetoothd -n -d -p alert bluetoothd -n -d -p alert
Connect your device until startNotify 连接您的设备,直到startNotify

Register alert from other console: 从其他控制台注册警报:

dbus-send --system --dest=org.bluez --type=method_call "/org/bluez" "org.bluez.Alert1.RegisterAlert" string:"simple" objpath:"/org/bluez/AlertAgent1"

Create new alert: 创建新提醒:

dbus-send --system --dest=org.bluez --type=method_call "/org/bluez" "org.bluez.Alert1.NewAlert" string:"simple" uint16:"1" string:"test"

I got the following bluetoothd's log: 我得到了以下bluetoothd的日志:

bluetoothd[1928]: src/attrib-server.c:attrib_db_update() handle=0x001c
    bluetoothd[1928]: src/attrib-server.c:attrib_db_update() handle=0x0021
    bluetoothd[1928]: profiles/alert/server.c:register_alert() RegisterAlert("simple", "/org/bluez/AlertAgent1")
    bluetoothd[1928]: src/attrib-server.c:attrib_db_update() handle=0x001e
    bluetoothd[1928]: src/device.c:btd_device_add_attio_callback() 0x1b6e718 registered ATT connection callback
    bluetoothd[1928]: src/device.c:device_set_auto_connect() 10:68:3F:E1:4E:F2 auto connect: 1
    bluetoothd[1928]: src/adapter.c:adapter_connect_list_add() /org/bluez/hci0/dev_10_68_3F_E1_4E_F2 added to BlueZ 5.14's connect_list
    bluetoothd[1928]: src/adapter.c:trigger_passive_scanning()
    bluetoothd[1928]: src/device.c:btd_device_add_attio_callback() device->attrib = false
    bluetoothd[1928]: src/device.c:btd_device_add_attio_callback() cfunc = true
    bluetoothd[1928]: src/device.c:btd_device_add_attio_callback() no idle
    bluetoothd[1928]: profiles/alert/server.c:new_alert() NewAlert("simple", 1, "simple")
    bluetoothd[1928]: src/adapter.c:passive_scanning_complete() status 0x03
    bluetoothd[1928]: Wrong size of start scanning return parameters

Memo: adding some debug output in device.c. 备注:在device.c中添加一些调试输出。 It seem that device->attrib is empty. 似乎device-> attrib是空的。 And autoconnect (why gatt server/peripheral has to connect to central?) is failed for unknown reason. 并且autoconnect(为什么gatt服务器/外围设备必须连接到中央?)由于未知原因而失败。

Edit: I have succeeded running alert sample using the test-alert python script in the code. 编辑:我已成功使用代码中的test-alert python脚本运行警报示例。

I contacted the developer directly and asked. 我直接联系了开发人员并询问。 Turned out that there was a bug when running bluez as peripheral, so he created several patches on the mailing list. 结果发现将bluez作为外设运行时存在一个错误,因此他在邮件列表上创建了几个补丁。

http://marc.info/?l=linux-bluetooth&m=139092431515560&w=2 http://marc.info/?l=linux-bluetooth&m=139092431515560&w=2

After applying patch, run the server and try using test-alert : 应用补丁后,运行服务器并尝试使用test-alert:

  1. Connect and write to the right ccc handle for notification on client side 连接并写入正确的ccc句柄,以便在客户端进行通知
  2. On server side, run test-alert such as (-w is to keep the test-alert persistent, -r for registering email alert, -u for unread email, 30 is the number of unread email): 在服务器端,运行测试警报,例如(-w是保持测试警报持久性,-r用于注册电子邮件警报,-u用于未读电子邮件,30是未读电子邮件的数量):

    test-alert -w -r email -u email 30 test-alert -w -r email -u email 30

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

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