I'm developing a stereo headset with Bluetooth using the classic profiles (HFP, A2DP, AVRCP) as one would expect Ina stereo headset. However, I want to deploy a remote control app for iOS, and use it simultaneously to the other classic links, but the dual-mode chipset I'm working with in my design does not behave as I'd expect;
The headset is setup as a peripheral, letting the iOS device act as central. As such, the peripheral advertise its BLE services (with my specific 128-bit UUIDs) and all is good. I can browse the peripheral from any central, but only when I'm not connected with classic profiles (e.g., while not streaming audio).
My device does not seem to be able to advertise BLE, while connected with HFP and/or A2DP! However, I have seen demos of the same chipset acting as BLE central, scanning and connecting to other BLE peripherals, while simultaneously streaming audio via A2DP. However, in that setup the device was acting as A2DP sink connected to an iPhone, while scanning/connecting via BLE to a third unit acting as BLE peripheral. Hence, not point-to-point with both Classic and Smart Bluetooth to the same device.
Is there a dual-mode constraint that one cannot act as peripheral while supporting/connecting to Bluetooth Classic profiles? And that only Central-mode is supported in that case?
FYI, I'm using CSR's 8670 chipset.
After some digging around, I've found that the it's not allowed (BT 4.0 spec violation) to continue to act as a LE peripheral and advertise once Classic links are established. And it makes sense, really, since because there's already ACL links from my phone to the headset (A2DP and HFP), there's no need to advertise to "discover" the peripheral from the phone -- it's already there, given that the headset has a valid GATT SDP-record stating which services/characteristics that are supported. This concept is referred to as "vanilla", using GATT-profile over the L2CAP-layer in Classic BT.
How can my iOS-app "detect" this already connected GATT/BLE-device? Traditionally, I'd setup the iOS device as BLE central, scan for peripheral matching my preferred UUID services, and then connect. But, in my scenario the gadget does not need to be discovered, nor can it for that matter since it's not advertising over LE since the BT-Classic links are connected.
Best How To :
Well, after digging down into specs and trying to understand things more clearly, I've found the answers I was looking for, even though I would have preferred to more optimistic answers... ;(
Nevertheless, let's get to it; the Bluetooth spec for 4.0 (BLE) says that;
Dual-mode gadgets cannot act as BLE peripheral and advertise its presence while still being connectable in "Classic" Bluetooth using BR/EDR.
Furthermore, CSR source-code examples for the CSR8670 dual-mode chipset I'm using all behave in the same say; BLE advertisements as peripheral are disabled when any classic BT-link is connected. Instead, the CSR source code promote that the device should act as the BLE central instead, allowing other BLE peripheral units to advertise and connect to it, all fully doable while streaming audio (acting as A2DP sink).
This does not suite my setup at all since;
- BLE centrals consume more power than BLE peripherals, and my device needs to conserve energy
- The dual-mode "combo"-problem of combining a BR/EDR-device with BLE peripheral functionality just moved to the phone instead, which will not work any better since we cannot expect Apple (or anyone else) to violate the BLE spec.
Instead, the recommended approach is let my stereo headset skip BLE entirely and use GATT over BR/EDR instead, also known as advertising via "vanilla", which makes sense really; I mean, I already have an ACL-link setup between two devices, why should I need to kick any sort of discovery mechanism?
Again, the Bluetooth SIG comes in handy;
GATT and ATT are not transport specific and can be used in both BR/EDR and LE. However, GATT and ATT are mandatory to implement in LE since it is used for discovering services
So, the SIG says "yes" to using BR/EDR as transport for GATT, but the question then instead becomes; how can I then get access to that connected BR/EDR device from within my iOS-app, where the typical scenario is to use CBCentral to scan, discover and connect to a CBPeripheral? The answer is simple; you cannot, since iOS 7.0 does not (yet?) support GATT for BR/EDR;
So, to sum things up; if you want to have a peer-to-peer setup between two dual-mode Bluetooth devices, using BOTH Bluetooth Classic profiles AND Bluetooth Smart services/characteristics, you should use GATT over BR/EDR, which is no-go for Apple-devices, but might be supported by Android (don't know, will port app to Android eventually though, but regardless it's not a big deal for Android since worst-case will imply a fallback to SPP and a simple byte-protocol to do the work that I need to get done).
That's that. Hope that I've helped someone ;) /Markus