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应该是多少。

蓝牙BLE MTU规则与约定的更多相关文章

  1. 低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端

    低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端 Android对外模模式(peripheral)的支持 从Android5.0开始才支持 关键术语和概念 以下是关键BLE术语和 ...

  2. 深入浅出低功耗蓝牙(BLE)协议栈

    深入浅出低功耗蓝牙(BLE)协议栈 BLE协议栈为什么要分层?怎么理解蓝牙"连接"?如果蓝牙协议只有ATT没有GATT会发生什么? 协议栈框架 一般而言,我们把某个协议的实现代码称 ...

  3. 蓝牙ble数据转语音实现Android AudioRecord方法推荐

    蓝牙ble数据转语音实现Android AudioRecord方法推荐 教程  欢迎走进zozo的学习之旅. 概述 蓝牙BLE又称bluetooth smart,主打的是低功耗和快速链接,所以在支持的 ...

  4. Android-低功耗蓝牙(BLE)-客户端(主机/中心设备)和服务端(从机/外围设备)

    一.Android 低功耗蓝牙(BLE)的API简介 从Android 4.3(API 18)才支持低功耗蓝牙(Bluetooth Low Energy, BLE)的核心功能, BLE蓝牙协议是GAT ...

  5. 蓝牙BLE: ATT协议层中属性(Attribute)

    ATT(Attribute Protocol)属性层是GATT和GAP的基础,它定义了BLE协议栈上层的数据结构和组织方式. 属性(Attribute)概念是ATT层的核心,ATT层定义了属性的内容, ...

  6. 蓝牙 BLE 协议学习: 001-BLE协议栈整体架构

    背景 在深入BLE协议帧之前,我们先看一下BLE协议栈整体架构. 转载自:<深入浅出低功耗蓝牙(BLE)协议栈> 架构 如上图所述,要实现一个BLE应用,首先需要一个支持BLE射频的芯片, ...

  7. 蓝牙BLE传输性能及延迟分析

    BLE传输性能主要受以下几个因素影响:操作类型,Connection Interval,每个Connection Event内发送的帧数.每一帧数据的长度.具体参见如下链接: https://devz ...

  8. 蓝牙BLE实用教程

    蓝牙BLE实用教程 Bluetooth BLE 欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 设置 里的修改模板来改变新建文章的内容. 1.蓝牙BLE常见问答 Q: Smart Re ...

  9. 微信蓝牙BLE接入调试指引 硬件篇

    1 平台框架简介 微信蓝牙BLE由三个模块组成,分别是蓝牙设备.微信和第三方服务器,如下图: 蓝牙设备与微信之间的通信是通过蓝牙GATT协议进行. 微信与第三方服器之间的通信是通过网络http 接口进 ...

随机推荐

  1. android 项目中规范使用SharedPreferences

    一.SharedPreferences是什么来的? SharedPreferences是Android四种数据存储技术中的一种(SharedPreferences.SQLite.Content Pro ...

  2. 将long型转换为多少MB的方法

    Formatter.formatFileSize( this, processInfo.getMemsize()) public class DensityUtil { /** * 根据手机的分辨率从 ...

  3. css构造文本

    1. 1. 文本缩进text-indent:值:值为数字,最常用的数值单位是px(像素),也可以直接是百分比!text-indent:100px;text-indent:10%;2. 文本对齐text ...

  4. 关于用了SSH连接之后,但是Chrome中访问stackoverflow超慢的原因

    FQ条件如下: SSH + Chrome + ProxySwitchySharp 其中ProxySwitchySharp已经设置了通配符: 但是打开 www.stackoverflow.com还是奇慢 ...

  5. ISODATA算法

    ISODATA算法是在k-均值算法的基础上,增加对聚类结果的'合并'和'分裂'两个操作,并 设定算法运行控制参数的一种聚类算法. 全称:Iterative Selforganizing Data An ...

  6. cocos2d CCDictionary

    CCDictionary* dict=CCDictionary::create(); CCString* str1=CCString::create("); CCString* str2=C ...

  7. 理解cookie的path和domain属性

    今天在做验证码时发现一个问题:A.B窗口都打开同一个页面,A先生成一个验证码,B再生成验证码,这时A所生成的验证码被B覆盖掉了.原因是使用了同名的cookie来存储验证码.一时找不到解决方法就参考了W ...

  8. jquery easyui datagrid 分页详解

    由于项目原因,用了jquery easyui 感觉界面不错,皮肤样式少点,可是官网最近打不开了,资料比较少,给的demo没有想要的效果,今天在用datagrid 做分页显示的时候,折腾了半天,网上的资 ...

  9. 关于EnumerateObjectsUsingBlock和for-in之间的较量

      遍历一个数组看谁快 参赛选手 ForLoop, For - in, enumerateObjectsUsingBlock这个三个方法: NSMutableArray *test = [NSMuta ...

  10. 以下是关于Controller的一些Hint

    在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数据的交互.CI中所有的应用控制器都应该是CI_Controller的子类(除非你扩展了CI的核心,那么你的Contr ...