本帖最后由 leijixiaomile 于 2017-6-12 14:53 编辑
MTU定义: Maximum Transmission Unit.
MTU size的作用: 其决定了 attribute在一个connection interval发送的最大长度:MTU size - 3 bytes. 也就是说如果profile的特征值characteristic定义了的Notify属性,那么通过调用一次API:CyBle_GattsNotification能够发送的最大长度为MTU size - 3 bytes. indicate/write/write without response 等属性也是如此。
主从双方如何决定MTU size: 根据BLE 4.2 spec的描述: MTU is not a negotiated value, it is an informational parameter that each device can specify independently. It indicates to the remote device that the local device can receive, in this channel, an MTU larger than the minimum required. 我的理解是,主从双方在连接握手后,会告知对方自己的MTU size大小,主从双方会根据对方跟自己的MTU size选取较小的MTU size作为参考值,并在设计应用程序时考虑收发包的最大长度。
BLE 如何交互MTU size: 如下图所示,主机发送exchange MTU request, 把主机的MTUsize发给从机,从机收到request后发送Response,把从机的MTU size发给主机。主从根据双方的MTU size取最小的MTU size作为MTU size值。
Cypress BLE处理MTU size的过程:
1.cypress做从机时,收到主机端的exchange MTU request指令时,产生事件:CYBLE_EVT_GATTS_XCNHG_MTU_REQ, CYBLE 产生该事件时会在协议栈底层调用如下代码:
case CYBLE_EVT_GATTS_XCNHG_MTU_REQ:
{
uint16 cyBle_mtuSize;
if(CYBLE_GATT_MTU > ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu)
{
cyBle_mtuSize = ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu;
}
else
{
cyBle_mtuSize = CYBLE_GATT_MTU;
}
(void)CyBle_GattsExchangeMtuRsp(((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->connHandle, cyBle_mtuSize);
}
break;
上述代码逻辑:根据主机的MTU size 值跟自身设定的attribute MTU size值:CYBLE_GATT_MTU做比较,取较小MTU size值回复主机, 取这个最小值。
根据此逻辑,Cy BLE做从机时,需要在应用层的事件下做如下处理,取出MTU size值:
case CYBLE_EVT_GATTS_XCNHG_MTU_REQ:
negotiatedMtu = (((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu < CYBLE_GATT_MTU) ?
((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu : CYBLE_GATT_MTU;
2. Cyrpess BLE 做主机时,根据我的理解: 需要在连接事件后调用 API: CyBle_GattcExchangeMtuReq(),发起MTU size exchange MTU request,从机收到reqeust 并回复后,主机端产生:CYBLE_EVT_GATTC_XCHNG_MTU_RSP事件,在该事件下,取出MTUsize 值:
negotiatedMtu = ((CYBLE_GATT_XCHG_MTU_PARAM_T*)eventParam)->mtu;
手机默认的MTU size: 根据个人测试(cysmart连接从机),IOS7.1/9.3.3/9.3.4/9.3.5其默认值为0x9e,IOS10.2.1为0xB9。 Android 5.1.1 Mi Note pro为 0x200, 以前测试Android 4.3 Coopad 为0x17。 Android 5.0以后的版本可以在APP 开发中设置MTU size, 推断在Android 5.0以后的版本都支持0x200的MTU size,有待查证。
MTU size跟数据传输速率及OTA速度相关,需要高速率传输时,请设置最大的MTUsize: 512。
本文如有纰漏,还请各位大神不吝斧正。
个人新建cypress PSoC 交流群: 497718076, 欢迎大家加群讨论。
|