3

Questions first...

1) How does Android (pre API23) detect device type of Bluetooth devices? Apparently setting the BLE ADV flag BREDR_NOT_SUPPORTED in the dual-mode Bluetooth headset I’m trying to connect to does the trick, but at the cost of interfering with classic link setup / pairings in more modern APIs. So that’s not really an option...

2) If nothing can be done FW-wise (which would be the best really) in my Bluetooth headset, could you suggest any ideas of HOW I could perhaps override the BluetoothAdapter’s logic for device detection so that I always return device type DUAL. I mean, I don’t need a proper detection in the app since I already use GATT service UUID filtering during LE scanning to find the device in the first place, so I already know that it’s a “compliant device” as long as I can get Android on pre API23 mobiles to behave accordingly...

... and then perhaps some background/context ;)

I’m making apps for iOS and Android that interact with a Bluetooth headset that I also write the FW for. Hence, I have source code control on the behavior on both the headset as well as the apps.

The headset is based on the CSR8670 chipset from Qualcomm, and acts as a dual-mode Bluetooth “smart ready” spec 4.2 gadget which the typical classic profiles (A2DP/AVRCP/HFP) plus my own custom GATT service as a BLE peripheral running a tunneled propriety serial protocol to interface my app(s) on the phone-side.

Everything works like a charm on iOS.

But...

On Android, I’ve seen a gradual change since the launch of API23 and Marshmallow as BLE ADV data and the ADV flags in particular has begun to be used by Android to control classic Bluetooth link establishment/pairing.

For instance, a few years ago when API21 was the latest thing I had to explicitly set the BREDR_NOT_SUPPORTED flag AND use reflection to enforce transport = BLE to eventually succeed with my connectGatt(..) request.

But, since API23 this is not needed, nor does it honestly make any sense to have there since the headset IS a dual-mode device with BREDR-support...

Instead, the recommendation is to use the LE_BR_EDR_CONTROLLER and LE_BR_EDR_HOST BLE ADV flags to let Android know that this is indeed a fully capable dual-mode device...

And it works. Just fine. As long as you DO NOT try to run your companion app on the Android API21 phone again which now suddenly fails to detect that my headset IS a dual-mode device. Despite my reflection approaches to force a proper connect with proper transport, Android running API21 on my Samsung S5 “active” test phone simply will not establish a GATT connection to my headset, and I strongly think that it’s correlated with the fact that device type is detected as DEVICE_TYPE_CLASSIC.

Markus Millfjord
  • 707
  • 1
  • 6
  • 26
  • couldn't you provide different connection services for API 21 and 23? – Jakub Licznerski Jan 18 '18 at 21:59
  • Yeah, I already do that. So — my problem is not related to API21 vs API23 or the like. The problem is just that API21 for whatever reason detect my headset as a classic type, and NOT as a dual-mode type. Which in turn causes connectGatt to fail. And he question is; how/if I can change and affect this detection mechanism (since I think it correlates with the outcome one of my connectGatt request that indeed fails on API21). And yes. The connectGatt request I do is done differently on API21 vs. 23 as I use reflection on API21 to enforce BLE as transport. – Markus Millfjord Jan 18 '18 at 22:02
  • That's pretty interesting as the device type info is sent from device as an element of each package. Maybe the problem is that the device you are connecting to the headset doesn't support BLE along with GATT as `connectGatt` on API <23 is officially not supoprted? – Jakub Licznerski Jan 18 '18 at 22:15
  • What do you mean by “sent in each packet”? There’s no device type data in the BLE ADV data I generate as LE peripheral, only ADV flags, and some other stuff... And the headset IS detected as a dual-mode device on API23 android phones... as for GATT over BLE not being supported on pre API23, I have to disagree. BLE support as Central, allowing scanning and connection to a peripheral was officially introduced in API18, extended with bonding in 19, and reworked in terms of scanning in 21. – Markus Millfjord Jan 19 '18 at 03:33
  • I really think no one has taken care of the code correctly in the old Android versions. I have for example many times seen where an Android device tries to connect to a LE device (using connectGatt without reflection) and by looking at the HCI log it thinks it's a Classic device even though all times it has advertised it has advertised BR/EDR Not supported. If you really want to know and debug what's happening you could try read the Android source code. I'm not sure anyone at Stack Overflow knows exactly how it works in detail. Also try experiment some more and see if some configuration works. – Emil Jan 19 '18 at 09:42

0 Answers0