5

I have a question about android 4.4 Bluetooth Low Energy.

I have a BLE dongle with UART Rx pin. I can send bytes data from Rx-pin to BLE dongle, and BLE dongle will send the data to bluetooth host device by indication.

So I have a Rx characteristic value it's property is indication. I send about 80 bytes data to Rx characteristic, but i only get 20 bytes by once callback function onCharacteristicChanged.

But I use iPad mini to indicate this characteristic value, it receives 4 packets one of 20 bytes data and it seems right.

How can I do to receive 80 bytes data like iOS in Android callback function ?

ThomasW
  • 16,981
  • 4
  • 79
  • 106
user3530962
  • 51
  • 1
  • 3

3 Answers3

7

Try negotiating a bigger GATT MTU. The default is 23 bytes. The (G)ATT protocol takes up 3 bytes for the header per Notification / Indication. So 20 - 3 = 20 bytes left by default.

On iOS 8, the maximum MTU that iOS will allow is 158 bytes. I'm not sure about what Android allows.

Martijn Thé
  • 4,674
  • 3
  • 29
  • 42
  • I think you are suggesting using [this](https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestMtu(int)) API. Note that it is from API level 21. – ThomasW May 28 '15 at 05:24
  • I've been able to request a value of 512 with an iOS device. – ThomasW May 29 '15 at 02:55
  • 1
    It seems that even though 512 bytes is negotiated, I'm only receiving 155 bytes. – ThomasW Jun 02 '15 at 11:05
  • Yeah, you'd use that indeed. – Martijn Thé Jun 05 '15 at 07:54
  • 1
    I doubt that 512 bytes MTU is negotiated. What might be happening is that iOS is chunking the payload in separate messages (each containing max. 155 bytes of payload data) using the Read/Write Long operation that will transparently happen under the hood. For Notifications and Write w/o Response, there such chunking does not exist. – Martijn Thé Jun 05 '15 at 07:56
3

I had exactly the same problem - 20 bytes it is a limitation applied to both indications and notifications. It is defined in the Spec, however I am yet to find it.

If your characteristic is not using either indications or notifications then this constraint doesn't apply and all your data will be sent in chunks of MTU-5 see section section 3.4.6.1 of the BT4.0 spec.

eklektek
  • 1,083
  • 1
  • 16
  • 31
2

The data is sent in chunks of 20 bytes each. So if you want to receive all 80 bytes, then divide the data in 20 byte chunks and send it in a loop. Refer to Android: Sending data >20 bytes by BLE for clarification.

Remember to add Thread.sleep(200) in the loop so that the characteristic is not overwritten.

Community
  • 1
  • 1
Ankit Aggarwal
  • 2,367
  • 24
  • 30
  • before writing charateristics or callback method ? – Jeff Bootsholz Nov 07 '14 at 07:05
  • 3
    total crap: 200ms is a random value depends on the Hardware. Mine does take over 350ms. So build a stack writeCharacteristic, wait until writeCharacteristicWrite, poll stack and send next value – paulgavrikov Dec 20 '14 at 04:54
  • Additionnally there is an onCharateristicWrite() event that could be used for trigger the next send, right ? – Graveen Jan 31 '15 at 19:32
  • At least, this is how i experience it. The event is set _after_ the datas are sent. – Graveen Jan 31 '15 at 21:45