0

I'm trying to send BLE Notification from android (GAP:central, GATT:server) to peer device (GAP: peripheral, GATT: client).

The problem is that on android 5.0 there is command: BluetoothGatt.requestMtu(int mtu).

But I do not know the way how to find out if peer device support requested MTU and what is actually negotiated MTU. The required function: BluetoothGattCallback.onMtuChanged(BluetoothGatt gatt, int mtu, int status) was added only in API level 22 (Android L 5.1).

My problem is that I do not know how many bytes in packet I can send.

I write a test code to send bigger packet than 20B and it seems android sends just first 20B of data and never tell me that it discarded rest of the data!!! That is terrible behavior. Either I'm missing something, or Android 5.0 is useless for bigger packets than 20 bytes :(

I wrote test code and logs prove that all is sent and returns 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

Even from call back I do not get any error:

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

but then I look with my BLE analyzer and I see that only first 20 B of notification data is send: enter image description here

So my question is either how to find out negotiated MTU or at least how to find out that not all data was sent? (Constrain is Android 5.0).

Perhaps it has no solution for Android 5.0 :( And I have to stick with 20B even when both device could support higher. Only work around would be to implement mechanism for returning MTU from peer device as was suggested here on stack overflow.

Vit Bernatik
  • 3,566
  • 2
  • 34
  • 40
  • Are you designing the peripheral? Are you designing the protocol? – Emil Oct 11 '17 at 18:16
  • I'm designing android app. I can potentially start a change in a services&characteristics in peer device. But I should know there is no android way. – Vit Bernatik Oct 11 '17 at 18:18
  • 1
    Yeah you have to do some other workaround. You can for example and a Write Without Response of 512 bytes from the peripheral. Then you simply detect in Android how many bytes you get. Or send the mtu on some characteristic from the peripheral. – Emil Oct 12 '17 at 08:07

1 Answers1

0

Your issue is not Android but Bluetooth / the app running on your central.

Increasing the useful data size from 20B is only possible with BLE v4.2 and newer. I suppose your radio is running with BLE v4.0 or v4.1 or there is an issue setting up your MTU.

Either way this should not affect reading data. The central device can read a characteristic with an offset. Assuming you have 60B, you would have 3 requests from the central:

  1. Read, offset=0
  2. Read, offset=20
  3. Read, offset=40

TL;DR: Your GATT central simply handles reads wrong.

paulgavrikov
  • 1,883
  • 3
  • 29
  • 51