1. 问题引言:

  想在gatt client上(一般是手机上)传输长一点的数据给gatt server(一般是一个Bluetooth smart设备,即只有BLE功能的设备),但通过

writeCharacteristic(BluetoothGattCharacteristic)  

  来写的时候,发现最多只能写入20个byte的数据。

  这篇文章会回答下面几个问题:

1)为什么会是20

2)如何突破20

3)如何更优雅的来实现?

  2. 为什么为限制成20个字节?

  core spec里面定义了ATT的默认MTU为23个bytes, 除去ATT的opcode一个字节以及ATT的handle 2个字节之后,剩下的20个字节便是留给GATT的了。

  考虑到有些Bluetooth smart设备功能弱小,不敢太奢侈的使用内存空间,因此core spec规定每一个设备都必须支持MTU为23

  在两个设备连接初期,大家都像新交的朋友一样,不知对方底细,因此严格的按照套路来走,即最多一次发20个字节,是最保险的。

  由于ATT的最大长度为512byte因此一般认为MTU的最大长度为512个byte就够了,再大也没什么意义,你不可能发一个超过512的ATT的数据。所以ATT的MTU的最大长度可视为512个bytes。

  3. 如何突破20

  很简单嘛,改变传输的ATT的MTU就行了,大家经过友好的协商,得到双方都想要的结果,是最好的。在Android上(API 21),改变ATT MTU的接口为:

public boolean requestMtu (int mtu)    

Added in API level 21 

Request an MTU size used for a given connection.

When performing a write request operation (write without response), the data sent is truncated to the MTU size. This function may be used to request a larger MTU size to be able to send more data at once.

A onMtuChanged(BluetoothGatt, int, int) callback will indicate whether this operation was successful.

Requires BLUETOOTH permission.

Returns

true, if the new MTU value has been requested successfully

  大声的说出来你想要一下子传多少,调用上面的接口就可以了,然后在下面的函数中看最终结果(当然了,如果你的peripheral申请改变MTU并且成功的话,那这个回调也会被调用):

public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
    super.onMtuChanged(gatt, mtu, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        this.supportedMTU = mtu;//local var to record MTU size
    }
}  

之后你就可以快乐的发送supported  MTU-3的长度的数据了。

  4. 如何优雅的来实现?

  万一对方设备不同意你的请求怎么办?

  对于app来说,一般是知道自己要最大发送多少数据的,例如一次要发100个bytes,那么就首先试试申请一下103,失败的话,则申请一下53,即二分法,剩下的只能自己分段拆着发了。

  一般来讲,app的开发者和对端设备的开发者都是同一伙儿人,这是好事,他们可以根据自己设备的硬件情况,来商量MTU应该是多少。

最新文章

  1. 用excel做分组散点图
  2. Ubuntu 16 安装odoo10 实录
  3. Linux 下解压大全
  4. 【转】常用的shell脚本
  5. php多态设计
  6. css3背景色渐变
  7. php ajax提交数据 在本地可以执行,而在服务器不能执行
  8. Android Studio开发环境的配置
  9. 深入理解Redux
  10. Java_并发工具包 java.util.concurrent 用户指南(转)
  11. qt 利用 HTML 生成PDF文档,不能显示jpg图片
  12. 大众点评selfxss结合两个csrf变废为宝(已修复,故公开,不涉及真实参数)
  13. python中 __init__.py的例程
  14. 多线程处理N维度topk问题demo--[c++]
  15. HTTPS到底是个什么鬼?
  16. scrapy 参考教程及安装
  17. 浅析Java源码之HashMap外传-红黑树Treenode(已鸽)
  18. Web.config的Release版本和Debug版本不一样的奥秘
  19. 第二阶段每日站立会议Third Day
  20. 【HTTP请求】、详解

热门文章

  1. 2016.6.23 PHP实现新闻发布系统主体部分
  2. SU suspike命令学习
  3. DOM--1 遵循最佳实践
  4. POJ1511 Invitation Cards(多源单汇最短路)
  5. BZOJ3784 : 树上的路径
  6. MyBatis insert返回主键(sqlserver2008)
  7. ibatis插入数据返回ID的方法
  8. Highcharts 本地导出图片 Java
  9. cookiecutter-flask生成的框架里边自带了一个CRUDMixin类
  10. 在树莓派上使用ss和iptables实现fq功能