1、最大传输单元(Maximum Transmission Unit, MTU)
MTU是指在一个协议数据单元中(Protocol Data Unit, PDU) 有效的最大传输Byte。
2、蓝牙MTU默认23个Byte
core spec中ATT的默认MTU为23个Byte,ATT的Opcode占1个Byte、ATT的Handle2个Byte、GATT占20个Byte。
23Byte(ATT)=1Byte(Opcode)+2Byte(Handler)+20Byte(BATT)。
3、蓝牙最大MTU
不同的蓝牙版本最大MTU不同,例如:蓝牙4.2的最大MTU=247Byte(不一定正确,也有说是257Byte、也有说是241Byte),蓝牙5.0的最大MTU=512,有效的最大MTU还需要减去协议Byte、Opcode和Handler。蓝牙4.2的有效的最大MTU是244Byte(不一定正确),有兴趣的可以看看Bluetooth SIG官网https://bluetoothworldevent.com/welcome。
蓝牙4.2:1Byte(Opcode)+2Byte(Handler)+244Byte(BATT)=247Byte(不一定正确);
蓝牙5.0:没查到
4、自定义MTU
不是说蓝牙协议中MTU定义了多少,移动设备就能用多少,不用的移动设备的蓝牙支持的最大有效的MTU不同,例如:有些移动可能仅仅支持默认的MTU=23Byte,也可能仅仅MTU=185(例如苹果)。
在实际开发过程中,需要根据实际需求去选择相应的移动设备,然后根据实际的需要去修改MTU,自定义的MTU不能大于最大的MTU值。此外,自定义的MTU不是随意设置的,自定义的MTU值不同蓝牙的性能可能不同,例如:自定义的MTU=185的蓝牙性能,可能会比自定义的MTU=153的性能好。最好根据实际情况多测几个数据。
5、Android中自定义MTU
在Android中修改MTU很简单只需要调用BluetoothGatt#requestMtu(int MTU)方法即可。requestMtu(intMTU)必须在发现蓝牙服务并建立蓝牙服务连接之后才能调用,否则MTU会默认为20Byte。如果调用成功会自定回调BluetoothGattCallback类中的onMtuChanged(BluetoothGatt gatt, int mtu, int status)方法。
// 重写MTU
private boolean requestMtu() {
if (bleGatt != null && Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {
// 25 *6 +3 =153
return bleGatt.requestMtu(this.bleMtu);
}
return false;
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
Log.d("onMtuChanged"," onMtuChanged");
if (BluetoothGatt.GATT_SUCCESS == status) {
Log.d("BleService", "onMtuChanged success MTU = " + mtu);
}else {
Log.d("BleService", "onMtuChanged fail ");
}
}
注:本文如果有误的地方请原谅。