Android 5.0 BluetoothGattServer.notifyCharacteristicChanged如何查找MTU?

时间:2017-10-11 16:54:22

标签: android bluetooth-lowenergy

我试图从Android(GAP:中央,GATT:服务器)向对等设备(GAP:外围设备,GATT:客户端)发送BLE通知。

问题是在android 5.0上有命令:BluetoothGatt.requestMtu(int mtu)

但我不知道如何确定对等设备支持是否请求MTU以及实际协商的MTU是什么。 所需功能: BluetoothGattCallback.onMtuChanged(BluetoothGatt gatt, int mtu, int status) 仅在API级别22(Android L 5.1)中添加。

我的问题是我不知道我可以发送的数据包中有多少字节。

我写了一个测试代码来发送比20B更大的数据包,似乎android只发送了第一个20B的数据,并且从未告诉我它丢弃了其余的数据!这是一种可怕的行为。要么我错过了某些东西,要么Android 5.0对于大于20字节的数据包没用:(

我编写的测试代码和日志证明所有内容都已发送并返回true:

BluetoothGattCharacteristic mCharacVal;
BluetoothGattServer mGattServer;
...
//log: I/vbeOryNotify: bleNotify snd:msg body; id:27; len:60 :I should have known those alien maggots booby-trapped this s
ret = mCharacVal.setValue(toSnd);
Log.i("vbeOry","bleNotify: setValue "+AppCommon.ByteArrayToHexStr(toSnd)+" ret:"+ret);
//log: I/vbeOry: bleNotify: setValue 03 1B 00 00 00 3C 49 20 73 68 6F 75 6C 64 20 68 61 76 65 20 6B 6E 6F 77 6E 20 74 68 6F 73 65 20 61 6C 69 65 6E 20 6D 61 67 67 6F 74 73 20 62 6F 6F 62 79 2D 74 72 61 70 70 65 64 20 74 68 69 73 20 73      
//log: ret:true
byte[] dataRdBck = mCharacVal.getValue();
Log.i("vbeOry","bleNotify: getValue "+AppCommon.ByteArrayToHexStr(dataRdBck));
//log: I/vbeOry: bleNotify: getValue 03 1B 00 00 00 3C 49 20 73 68 6F 75 6C 64 20 68 61 76 65 20 6B 6E 6F 77 6E 20 74 68 6F 73 65 20 61 6C 69 65 6E 20 6D 61 67 67 6F 74 73 20 62 6F 6F 62 79 2D 74 72 61 70 70 65 64 20 74 68 69 73 20 73 
ret = mGattServer.notifyCharacteristicChanged(device, mCharacVal, false);
Log.i("vbeOry","bleNotify: notifyCharacteristicChanged "+AppCommon.ByteArrayToHexStr(toSnd)+" ret:"+ret);
//log: I/vbeOry: bleNotify: notifyCharacteristicChanged 03 1B 00 00 00 3C 49 20 73 68 6F 75 6C 64 20 68 61 76 65 20 6B 6E 6F 77 6E 20 74 68 6F 73 65 20 61 6C 69 65 6E 20 6D 61 67 67 6F 74 73 20 62 6F 6F 62 79 2D 74 72 61 70 70 65 64 20 74 68 69 73 20 73  
//log: ret:true

即使回电话,我也不会收到任何错误:

private BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
    public void onNotificationSent(BluetoothDevice device, int status){
        Log.i("vbeGattServ", "onNotificationSent status: "+status);
        //log: I/vbeGattServ: onNotificationSent status: 0

然后我看看我的BLE分析仪,我发现只发送了前20 B的通知数据: enter image description here

所以我的问题是如何找出协商的MTU或至少如何找出并非所有数据都被发送? (Constrain是Android 5.0)。

也许它没有针对Android 5.0的解决方案:(即使两个设备都支持更高,我也必须坚持使用20B。只有解决方法是实现从对等设备返回MTU的机制,如建议here on stack overflow

1 个答案:

答案 0 :(得分:0)

您的问题不是Android,而是蓝牙/应用在您的中心运行。

只有使用BLE v4.2及更高版本才能将有用数据大小从20B增加。我想您的收音机正在使用BLE v4.0或v4.1运行,或者设置MTU时出现问题。

无论哪种方式,这都不应影响阅读数据。中央设备可以读取具有偏移的特征。假设您有60B,那么您将收到来自中央的3个请求:

  1. 读取,偏移= 0
  2. 读取,偏移= 20
  3. 读取,偏移= 40
  4. TL; DR:你的GATT中心只是处理读错了。