It's no secret that Bluetooth has been a problem child for Android, plagued with poor audio quality and connectivity issues. I've already covered a handful of common problems in a previous post, but another issue has been emerging in the last few months that threatens to virtually kill all Bluetooth operation on a device in the right conditions. The culprit is a nasty little oversight in the Bluetooth Low-Energy code added with Android 4.3 Jelly Bean. Once a device has been within range of enough BLE devices, the entire Bluetooth service will begin crashing.
There is only one truly obvious symptom, but it's incredibly unhelpful for diagnosing the issue. When the bug exposes itself, it's in the form of a single dialog box with the message, "Unfortunately, Bluetooth share has stopped." After tapping the 'OK' button, the service will automatically restart in the background, and the cycle often repeats shortly afterward. Turning off Bluetooth will prevent the dialog from appearing, but once Bluetooth is re-enabled, the cycle is likely to begin again.
The problem is located in a piece of the Bluetooth Low-Energy code. When a new MAC address (a unique number for identifying a piece of hardware on a network) is detected, it is first stored in memory and later written to a file called bt_config.xml when the Bluetooth service shuts down naturally. This logging operation is going on anytime the radio is scanning for devices. That may not sound like a common occurrence, but scans occur frequently as long as Bluetooth is enabled.
Once the log reaches 1,990 entries, any new MAC address will cause an overflow and immediately crash the Bluetooth service. Since the log is reloaded into memory each time the service restarts, the problem doesn't really go away on its own. Keep in mind, devices that have already been detected and exist within the log will not cause a crash; rather, it's just when a previously unknown address appears. In other words, the Bluetooth service might start crashing as you're walking around a mall or even driving by a jogger with a fitness band, but it's unlikely to act up when you're at home, even if you've got a handful of BLE gadgets laying around.
Nearly 2,000 addresses should sound like a lot, and aside from frequent travelers, many people wouldn't even come close enough to that many active BLE devices in the lifetime of a phone or tablet. However, a new type of gadget will virtually guarantee this number is hit within hours of going into a public setting: Proximity Beacons. The most notable of these are based on a technology developed by Apple, called iBeacon. These small, fairly low-cost transmitters can be placed around stores and events to push data and location information to devices. Proximity beacons are already appearing in some sporting and concert venues, and they are likely to become commonplace in popular retail outlets like Macy's and Walmart.
Where the problem becomes eminently worse is a "security feature" employed by some beacons. To prevent spoofing, products like the Gimbal by Qualcomm are designed to rapidly roll through auto-generated MAC addresses. The Gimbal broadcasts a new MAC every 0.8 seconds and can roll through the necessary 1990 addresses in less than 30 minutes. This video taken at Dodger Stadium demonstrates a deployed Gimbal setting off the bug.
Affected Versions And Devices
The bug was introduced when Android 4.3 Jelly Bean added support for BLE to the Bluedroid Bluetooth stack. Since this issue has gone largely unnoticed until recently, it managed to survive well into the life of Android 4.4. Virtually every device running stock firmware on Android 4.3 - 4.4.2 should be affected by this issue, assuming the manufacturer hasn't substantially modified the Bluetooth stack on their own. It's possible that some recent firmware updates may have silently patched this issue already, but it has been identified in the latest updates to the HTC One (m7 and m8), Samsung Galaxy S 5, and a few others.
Workarounds and Fixes
If the Bluetooth service on your device has started crashing, there are a few methods for solving the problem, and even one that may prevent it from returning. Unfortunately, there's one catch that prevents this from being easily and permanently fixed on most devices: the log file bt_config.xml is restricted to system-level access. That means it can only be directly read or modified by the Bluetooth service, the OS, or apps with root access.
- I'll start with the best option in the group, an app called Bluetooth Crash Resolver. It was developed by Radius Networks, one of the companies that manufactures proximity beacons. bt_config.xml can't be modified directly without root, but the Bluetooth service can be tricked into clearing out entries by forcing a "discovery" to run. The app can watch for and fix the log after a crash occurs and it will attempt to prevent further issues through regular paring down of the list. The developers acknowledge that it's not a perfect solution and it may cost some battery life, but it's the easiest and as close to a permanent fix that exists without rooting. Unfortunately, there are reports that it doesn't work with every device firmware, so some users will have to resort to alternative solutions. This app is also open source. Note to developers using BLE: there are instructions for ways your own apps can help to reduce the problem.
- The other non-root solution, if you can call it that, is a factory reset. I only mention this because there aren't any other alternatives. This will fix the issue until the log refills, and then you're right back to square one. Consider this a last resort.
- If your device is rooted, you can manually edit bt_config.xml to remove excess entries. It's located at /data/misc/bluedroid. Doing this may require re-pairing with your existing BLE devices, unless those are kept in the list. This method is also a very temporary fix since the log will eventually refill on its own. I've yet to see an app that automates this process, but such a thing will probably turn up fairly soon.
While I don't consider 3rd-party ROMs to inherently be a "fix," it's worth noting that this bug was patched in CyanogenMod 10.2 all the way back on September 27th - four days before the launch of KitKat. Umm, did anybody remember to submit this patch upstream to Google? Nonetheless, any custom ROM based on CM source from after that date should be free of this issue.
A bug report has already been posted to the AOSP Issue Tracker with details for reproduction. Google hasn't directly responded to that bug post, but we've reached out to Qualcomm, and received a comment that confirms Google is aware of the issue and fixing it with a future release.
Please know that while the overall Gimbal context aware platform supports iOS and Android, Gimbal proximity beacons today only support iOS. We are aware of an issue within Android and have been working with Google to address in their next software release. We look forward to Gimbal proximity beacons being supported by Android in the near future. -- Qualcomm
With the rise of Bluetooth Low-Energy devices, we're bound to see a few bugs bubbling up from the depths. This particular issue will likely pose problems for the next year or two on devices that have been abandoned with Android 4.3 - 4.4.2. As for devices that will continue to receive updates, we can probably expect many OEMs to simply skip 4.4.3 (if it is released) in favor of the next major release due to come out at Google I/O 2014.