简体   繁体   English

如何向Bluez发送长通知,例如?

[英]How do I send a long notification with Bluez, example?

I need to send a long (let's say 10Kb) notification from Bluez 5.37 on my Linux device to a mobile phone. 我需要在我的Linux设备上将Bluez 5.37的长(例如10Kb)通知发送到手机。

My implementation is based on src/shared/gatt-server.c . 我的实现基于src/shared/gatt-server.c

I cannot find an example of this in Bluez. 我在Bluez找不到这个例子。 src/shared/gatt-server.c , bt_gatt_server_send_notification() is strictly trimming the packet to MTU-1 and discards the rest. src/shared/gatt-server.c bt_gatt_server_send_notification() src/shared/gatt-server.cbt_gatt_server_send_notification()严格将数据包修改为MTU-1并丢弃其余数据包。 I must need an output queue for this, like in gatt-client.c . 我必须要有一个输出队列,就像在gatt-client.c bt_gatt_client_read_long_value() looks like an example of what I need, but for long characteristic reads. bt_gatt_client_read_long_value()看起来像我需要的一个例子,但是对于长特征读取。

  1. Is there a way to send a long notification compatible with majority of Bluetooth 4.0 Android phones? 有没有办法发送与大多数蓝牙4.0 Android手机兼容的长通知? It requires a bit of collaboration on the phone side - sending a ATT_READ_BLOB_REQUESTS , AFAIS. 需要在电话方面进行一些协作 - 发送ATT_READ_BLOB_REQUESTS ,AFAIS。
  2. Or is there a generic packetization library that will work over 20-byte-sized packets? 或者是否有一个通用的打包库,可以处理20字节大小的数据包?
  3. Another way I can think of is to create another characteristic, use Notification messages for short messages and, er, notifications that "Hey, there's a long message, read it from that characteristic". 我能想到的另一种方法是创建另一个特性,使用短消息的通知消息,呃,通知“嘿,有一条很长的消息,从那个特征中读取它”。

Which way is better? 哪种方式更好? Does an example of any of the three ways exist? 是否存在三种方式中的任何一种的例子?

I'm not entitled to disclose the code, but here's the basic idea of what I did. 我无权透露代码,但这是我所做的基本想法。 I use a tools/bgatt-server.c as an base for my peripheral. 我使用tools / bgatt-server.c作为我的外围设备的基础。

To send a long message: 要发送长消息:

  • Save the notification_buffer being sent and the notification_position in the server 's fields; 保存notification_buffer发送和notification_positionserver的领域;
  • Implement a bt_gatt_server_send_notification_with_callback() function in gatt-server.c . bt_gatt_server_send_notification_with_callback() gatt-server.c实现bt_gatt_server_send_notification_with_callback()函数。 It should do the same as bt_gatt_server_send_notification() but have extra void *user_data and bt_gatt_server_destroy_func_t destroy arguments, and pass them to bt_att_send() . 它应该与bt_gatt_server_send_notification()一样,但是有额外的void *user_databt_gatt_server_destroy_func_t destroy参数,并将它们传递给bt_att_send() This will enqueue the next invocation of destroy callback when the bluez output queue becomes free. 当bluez输出队列变为空闲时,这将使下一次对destroy回调的调用排入队列。
  • Implement a bt_gatt_server_destroy_func_t that calculates the next chunk to be sent from server's notification_buffer and notification_position fields, send them with bt_gatt_server_send_notification_with_callback() and passes server as user_data and itself as the destroy callback. 实现bt_gatt_server_destroy_func_t ,计算从服务器的notification_buffernotification_position字段发送的下一个块,使用bt_gatt_server_send_notification_with_callback()发送它们,并将server作为user_data和自身作为destroy回调传递。

To reassemble the message on receiving end: 要在接收端重新组合消息:

  • I split the long message with my own packetizer/depacketizer. 我用自己的打包器/拆包器拆分了长消息。
  • I use a header: 1 byte - packet's messageId and 2 bytes for packetId - this way, one can have messages up to 17*65536 bytes length. 我使用一个标题:1个字节 - 数据包的messageId和2个字节的packetId - 这样,一个可以有长达17 * 65536字节的消息。 Plus, this leaves the opportunity to re-request a packet for reliable delivery in the future. 此外,这使得有机会在将来重新请求数据包以便可靠地传送。

I do this for Bluez: 我为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);

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

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