Bluetooth scan does not discover devices visible to the iPhone in settings app (CoreBluetooth) - ios

UPDATE: please, keep in mind that since iOS 13, CoreBluetooth now supports both BLE and classic Bluetooth devices.
From Apple:
This year, we've merged the two layers together, and now, you have
transparent access to both BR/EDR and low energy without doing
anything. Now, what this means for you is without much changes in the
API, you can now work with both the classic devices and the low energy
devices.
[...]
This now will allow transparent use of GATT with the BR/EDR devices.
It's still running the exact same Bluetooth SIG protocol. There's no
changes to that, and so you can look at this specification online on
the Bluetooth SIG website. To your application and to the developer,
the CBPeripheral APIs are exactly the same. You can still do the same
service discovery and be notified of changes to characteristics.
Note: BR/EDR refers to the radio technology of the Bluetooth specification before the 4.0, used for LE devices. More info here.
I am trying to scan for some Bluetooth devices using CoreBluetooth but I am having trouble to discover them.
I am using Apple's sample code from this talk as reference.
This is how the Central Manager is initialized:
let cbManager = CBCentralManager(delegate: self, queue: nil)
This is how I'm scanning for peripherals:
cbManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
Since I don't know the serviceUUID to which I should connect initially, I am scanning with nil as the list of CBUUID.
When peripherals are discovered, then I get notified via the centralManager(_:didDiscover:advertisementData:rssi:) method of the CBCentralManagerDelegate and I hold on to those peripherals, which allows me to discover services on them via the peripheral(_:didDiscoverServices:) method of the CBPeripheralDelegate.
Having discovered a peripheral, and having discovered its services, I can connect directly to that peripheral next time with:
cbManager.scanForPeripherals(withServices: [myDiscoveredService], options: nil)
So far, so good.
However, I can't even seem to get started with devices which are not discovered. This is happening for a number of devices that do show up in the Bluetooth settings app.
How can I get exposed to those devices, which are clearly visible to the device but I can't get to discover from the code?
Would it help if I knew the serviceUUID to begin with? How can I get such serviceUUID by other means, possibly with additional tools?
Things I tried that did not work:
use the Bluetooth explorer from the new Xcode 11 additional tools to get information about the device: though I can get a fair amount of information about the target Bluetooth devices (via "Show Device Discovery", then "Get device info..."), I can't seem to find a suitable service UUID
use the Packet Logger for live capture of the iOS trace while scanning (from the same additional tools package): I see HCI Packets and HCI Events but I can't seem to figure out any valuable information from that traffic
I'm using iOS 13.2 and Xcode 11.2

CoreBluetooth now supports both BLE and classic Bluetooth devices.
This is a misunderstanding of the new features. As the quoted text notes, "This now will allow transparent use of GATT with the BR/EDR devices." (emphasis added)
GATT over BR/EDR is not a particularly common feature in Bluetooth devices, and has nothing to do with audio streaming devices. Other profiles such as A2DP, HID, and HFP, are still not supported by Core Bluetooth. These are likely the profiles supported by the devices you're working with.
For those of us who design Bluetooth products, this new feature is really quite powerful and exciting, but we need to update our firmware to support it. It's not something you get for free on the hardware side.

Related

swift how to develop an app performing an actual bluetooth pair

The actual bluetooth pair I am talking about is: let the app shows up in the searching list of Bluetooth of System Settings and other devices can pair to it (like we pair our device to Apple Air Pods).
But all articles I find online are talking about BLE/CoreBluetooth, I don't think these methods could make a device name shows up in the Bluetooth of System Settings.So how to develop an app performing an actual bluetooth pair? Any ideas?
The Bluetooth preferences screen only shows legacy Bluetooth peripherals. Devices advertising BLE services do not appear.
Apps on iOS do not have the ability to create and advertise legacy Bluetooth services.
If you create an app that acts as a BLE peripheral, using Core Bluetooth, and specify that encryption is required for a characteristic then you will trigger a pairing process when an app acting as a Bluetooth central on the other device connects and attempts to read/write that characteristic. Note that this requires cooperating apps on both devices.

Ios BT Connectivity & Raspberry Pi

I have a idea that requires connecting an ios device to a Raspberry Pi without the end user having to do anything special. The device will not be connected to an existing wifi network so BT or wifi hotspot seem to be my only options, BT preferred.
I'm aware that Apple does require some sort of BT hardware approval which I wont have I'll be using generic BT hardware. Once a connection is established I then want to be able to request data or call API's running on the Raspberry PI.
Does any of this sound achievable and are there any links that may help.
There are two flavours of Bluetooth: the so-called Bluetooth Classic, and the newer Bluetooth Low Energy (also called Smart Bluetooth or Bluetooth 4.0, though this is actually incorrect as BT 4.0 includes both Classic and Low Energy).
On iOS, Bluetooth Classic devices do indeed need to go through specific processes (MFi), or use an existing BT protocol supported by iOS to be used.
However, you can connect to any Bluetooth Low Energy (BLE) device, without any need for MFi, approval, or support by iOS. This is done though the Core Bluetooth framework.
As long as Bluetooth is enable in the iDevice, you can connect to a BLE device without any user interaction (though UX usually dictates doing so, so a user can actually select a specific device if there are many "matching" devices in range).

Can you pair a bluetooth LE device in an iOS app

Can you pair a bluetooth LE device in an iOS app, i.e. not via Settings. Trying to make it easier on the user to pair with a specific device.
If so how?
You don't pair Bluetooth LE devices through system settings. Generally you don't pair with Bluetooth Low Energy devices at all. The only time that pairing is required is when the device has an attribute that is marked as encryption required - attempting to read this attribute will trigger a pairing process, but before you can read you need to discover and connect to the device.
Discovery and connection is handled by the Core-Bluetooth framework.
The Core Bluetooth Programming Guide goes through the steps required to use a CBCentralManager to discover and connect to a BLE peripheral.
According to the BT SIG Security Manager documentation you can pair/Bond ble devices if they respond to the message that is.
You can also wait and do it as previously explained from the peripheral side. Some devices like HipKey does this automatically when connecting first time.
Look at BTSIG Security Manager specifications.
On Android this also works from BT settings menu IF the peripheral supports it.
Bonding and Authenticating are usually confused but om most platforms it means the same.
A good way to try this out is by buying the TI ble development kit. Its cheap. It comes with a USB dongle and SW which can be used to initiate pairing like from the settings menu.
To do it from iOS just connect and read a known encrypted characteristic.
Cases where you want to "pair" (remember a Bond) includes Pulse meters, hearing aid, keyboard and other private units.

Test Bluetooth on iOS

I'd really like to start testing my iOS apps Bluetooth capabilities, but have run into a few problems:
I have a device made with a RN-42 module, but it's not the Apple version and I don't have the Apple authentication module at the moment (I ordered it, but shipping from China can take a while). I know what the messages will look like, but can't send them to my iPhone!
I can use the module with my Macbook, but not in the iOS simulator! Apple has taken down all of the documentation related to getting the iOS < 7.0 to use a separate bluetooth dongle, and my efforts have left my 6.1 simulator endlessly spinning on the bluetooth screen.
I'm new to using Bluetooth, so this may be a dumb question...
Is there a way of getting a bluetooth client device (I have a Mac, another iPhone, and an Android tab) to act as a server module that can send (and receive) Bluetooth data to my iPhone?
Client/Server as per developer.bluetooth.org
Thanks!
Not 100% sure your meaning of "server module". But in CoreBluetooth, you can use CBPeripheralManager to broadcast data to other iOS or Mac apps.
https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBPeripheralManager_Class/Reference/CBPeripheralManager.html
If you're using standard Bluetooth (i.e. not Bluetooth LE or Bluetooth Smart or whatever you want to call it), you'll need to enroll in the MFI program or work with an MFI certified device (such as a Redpark cable) and use the External Accessories library provided by Apple. If you're using Bluetooth LE, you can use the Core Bluetooth library provided by Apple. If you fall into neither of those cases, sorry, you can't use Bluetooth on iOS.

iOS Bluetooth dual-mode; connect BLE (GATT) to an already connected BR/EDR (A2DP/HFP) stereo headset simultaneously

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.
UPDATE
New answer added. My apologies for not clarifying/cleaning-up my previous answer until now -- time flies!
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;
https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx
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;
https://www.bluetooth.org/tpg/showDeclaration.cfm?3A000A5A005C5344535D5414403B0C0D0E2405022413010E57503F202A5A72
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
You learn as long as you live, I suppose, and this question's answer is NOT that it's not supported which I claimed earlier (based on what I thought I knew).
The short and clean answer to dual-mode and headset development on CSR-chipsets is simply that it was a constraint in the CSR bluetooth stack on earlier SDKs.
The Bluetooth SIG has never not supported dual-mode acting as Peripheral while being connected via classic links to the same device. On the contrary, it clearly spec. how such interoperability should be carried out -- but that doesn't always mean that all BT-stack implementations out there are capable of such functionality.
Hence; Using the latest devtools and the latest Bluetooth firmwares/stacks from CSR has resolved all issues and dual-mode is now fully, and actually quite nicely I might add, supported on the CSR8670/75 chipsets.
I am also using the CSR8670 device.
It have it working. Both a BLE peripheral and audio.
You need to be using ADK 4.0.0 by CSR.
Bluetooth 4.1 and Bluetooth 4.0 are different. For what you said about Bluetooth 4.0 is correct, but your chip can do Bluetooth 4.1.
4.1 allows such connections.
I also added "Dual mode" flags to the advertising packet.
There are a few conditions, such as a connection Interval of at least 90 miliseconds highly recommended so you dont mess with the audio.
Good luck!

Resources