Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluetooth LE advertising fails when started and stopped cyclically

I've tried out Bluetooth LE advertising i.e. using an Android phone as a BLE "peripheral" device. Starting and stopping a constant advertising once works fine but if I'd like to actually transmit some varying data I would need to start, stop and restart the advertising in a cycle and always change the advertising package.

I'm using these methods of course:
BluetoothLeAdvertiser.startAdvertising()
BluetoothLeAdvertiser.stopAdvertising()

At least on a Motorola Moto G 4G 2nd gen. (XT1072) with Android 5.0.2 the cycle only runs for a while and then something goes wrong in the Bluetooth stack and a new advertising can no longer be started. When running the cycle quickly this happens quickly and if running slowly it takes more time so it could be related to some buffer filling up.

My question is: Does this also happen on other devices than Motorola?

(And any other related comments are of course welcome.)

Theoretically it could be dependent on some manufacturer specific HAL implementation etc. so I'd like to know if I should just get another device to be able to work on this as any fix from Google/Motorola would take some time of course.

This test app. can be used to try this out:

https://bitbucket.org/MarkusKauppinen/bleadvertisertest

If everything goes fine it'll happily keep advertising for ever and if this problem reproduces, it will show a dialog within a couple of minutes or so. If your device doesn't support Bluetooth LE advertising or BLE at all it will just crash. (It's just a quick-and-dirty test app.)

Another easy way to reproduce this is to run the "bluetoothadvertiser" app from https://github.com/devunwired/accessory-samples and just keep quickly tapping on the "Update advertisement" button on the UI for a while.

Additional details:

The Bluetooth LE peripheral mode support (needed for advertising) was added in Lollipop and is not available in 4.x. Only certain devices have the peripheral mode support. Compatibility is covered at least in:

https://altbeacon.github.io/android-beacon-library/beacon-transmitter-devices.html Chipsets/Devices supporting Android 5 BLE peripheral mode chipsets supporting BLE peripheral role on Android 5

For example these devices should have the support: Motorola Moto E 4G (2015), Motorola Moto G 4G (2nd gen.), Sony Xperia M4 Aqua, ZTE Blade S6, Motorola Moto X (2014), Samsung Galaxy S6, Google Nexus 6, Google Nexus 9, HTC One M9, Samsung Galaxy S6 Edge.

As for the "dirty details" I can always see a "GKI_Exception" in LogCat before this happens:

GKI_exception(): 65524 getbuf: out of buffers

Soon after the first "GKI_Exception" the advertisement fails with AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR. The line...

E/BtGatt.btif? ### ASSERT : external/bluetooth/bluedroid/main/../btif/src/btif_gatt_client.c line 803 Context transfer failed! (3) ###

...is probably relevant but I'm not familiar with BlueDroid. The said assert is here:

https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.0.2_r1/btif/src/btif_gatt_client.c#803

Some possibly related problems:
https://code.google.com/p/android/issues/detail?id=65455 <-- I added some comments and log files to this one.
https://code.google.com/p/android-developer-preview/issues/detail?id=1753
Scanning large number of BLE Tags
Bluetooth Crash on Samsung S4

like image 577
Markus Kauppinen Avatar asked Sep 18 '15 16:09

Markus Kauppinen


1 Answers

I tested your app on a Moto G 2nd Gen and run into the same problem.

I tried it on a Nexus 9 tablet running Android 6.0, there I could not reproduce the error and it seems to work. Also on a nexus player with Android 5.1.1 it seems to run without problems. So either it is really an issue of the Moto G or - what I think is more likely - a bug of Android 5.0.2 that was solved in later versions.

like image 147
Chris Avatar answered Oct 19 '22 20:10

Chris