例如,如何使用 Bluez 发送长通知?
How do I send a long notification with Bluez, example?
我需要从我的 Linux 设备上的 Bluez 5.37 向移动设备 phone.
发送一个长的(比如说 10Kb)通知
我的实现是基于src/shared/gatt-server.c
.
我在 Bluez 中找不到这样的例子。 src/shared/gatt-server.c
、bt_gatt_server_send_notification()
严格将数据包修剪为 MTU-1,并丢弃其余部分。为此,我必须需要一个输出队列,例如 gatt-client.c
。 bt_gatt_client_read_long_value()
看起来像我需要的例子,但对于长的特征读取。
- 有没有办法发送与大多数蓝牙 4.0 Android phones 兼容的长通知?它requires a bit of collaboration on the phone side - sending a ATT_READ_BLOB_REQUESTS, AFAIS.
- 或者是否有一个通用的打包库可以处理 20 字节大小的数据包?
- 我能想到的另一种方法是创建另一个特征,使用 Notification messages 作为短消息,呃,"Hey, there's a long message, read it from that characteristic".
的通知
哪种方式更好?是否存在这三种方式中的任何一种的示例?
我为 Bluez 这样做:
PRLOG("Send Notify, %d bytes\n", send_len);
do {
if (RPService.valid) {
send_res = bt_gatt_server_send_notification (pCharac->server->gatt, pCharac->handle,
pTx, mMIN(send_len, mBLE_TRANSFER_SIZE));
} else {
break;
}
if (send_res) {
pTx += mBLE_TRANSFER_SIZE;
send_len -= mBLE_TRANSFER_SIZE;
} else {
PRLOG(" Notify write failed...wait\n");
usleep(mTX_WAIT);
}
} while (send_len > 0);
我无权公开代码,但这是我所做工作的基本思路。我使用 tools/bgatt-server.c 作为外围设备的基础。
发送长消息:
- 保存正在发送的
notification_buffer
和 server
字段中的 notification_position
;
- 在
gatt-server.c
中实现 bt_gatt_server_send_notification_with_callback()
函数。它应该与 bt_gatt_server_send_notification()
相同,但有额外的 void *user_data
和 bt_gatt_server_destroy_func_t destroy
参数,并将它们传递给 bt_att_send()
。当 bluez 输出 queue 变为空闲时,这将启用 queue destroy
回调的下一次调用。
- 实现一个
bt_gatt_server_destroy_func_t
计算下一个要从服务器的 notification_buffer
和 notification_position
字段发送的块,用 bt_gatt_server_send_notification_with_callback()
发送它们并传递 server
作为 user_data
和本身作为 destroy
回调。
要在接收端重组消息:
- 我用自己的packetizer/depacketizer拆分了长消息。
- 我使用 header:1 个字节 - 数据包的
messageId
和 2 个字节的 packetId - 这样,最多可以有 17*65536 字节长度的消息。另外,这也为将来 re-request 一个数据包的可靠交付留下了机会。
我需要从我的 Linux 设备上的 Bluez 5.37 向移动设备 phone.
发送一个长的(比如说 10Kb)通知我的实现是基于src/shared/gatt-server.c
.
我在 Bluez 中找不到这样的例子。 src/shared/gatt-server.c
、bt_gatt_server_send_notification()
严格将数据包修剪为 MTU-1,并丢弃其余部分。为此,我必须需要一个输出队列,例如 gatt-client.c
。 bt_gatt_client_read_long_value()
看起来像我需要的例子,但对于长的特征读取。
- 有没有办法发送与大多数蓝牙 4.0 Android phones 兼容的长通知?它requires a bit of collaboration on the phone side - sending a ATT_READ_BLOB_REQUESTS, AFAIS.
- 或者是否有一个通用的打包库可以处理 20 字节大小的数据包?
- 我能想到的另一种方法是创建另一个特征,使用 Notification messages 作为短消息,呃,"Hey, there's a long message, read it from that characteristic". 的通知
哪种方式更好?是否存在这三种方式中的任何一种的示例?
我为 Bluez 这样做:
PRLOG("Send Notify, %d bytes\n", send_len);
do {
if (RPService.valid) {
send_res = bt_gatt_server_send_notification (pCharac->server->gatt, pCharac->handle,
pTx, mMIN(send_len, mBLE_TRANSFER_SIZE));
} else {
break;
}
if (send_res) {
pTx += mBLE_TRANSFER_SIZE;
send_len -= mBLE_TRANSFER_SIZE;
} else {
PRLOG(" Notify write failed...wait\n");
usleep(mTX_WAIT);
}
} while (send_len > 0);
我无权公开代码,但这是我所做工作的基本思路。我使用 tools/bgatt-server.c 作为外围设备的基础。
发送长消息:
- 保存正在发送的
notification_buffer
和server
字段中的notification_position
; - 在
gatt-server.c
中实现bt_gatt_server_send_notification_with_callback()
函数。它应该与bt_gatt_server_send_notification()
相同,但有额外的void *user_data
和bt_gatt_server_destroy_func_t destroy
参数,并将它们传递给bt_att_send()
。当 bluez 输出 queue 变为空闲时,这将启用 queuedestroy
回调的下一次调用。 - 实现一个
bt_gatt_server_destroy_func_t
计算下一个要从服务器的notification_buffer
和notification_position
字段发送的块,用bt_gatt_server_send_notification_with_callback()
发送它们并传递server
作为user_data
和本身作为destroy
回调。
要在接收端重组消息:
- 我用自己的packetizer/depacketizer拆分了长消息。
- 我使用 header:1 个字节 - 数据包的
messageId
和 2 个字节的 packetId - 这样,最多可以有 17*65536 字节长度的消息。另外,这也为将来 re-request 一个数据包的可靠交付留下了机会。