Search code examples
iosbluetoothcore-bluetoothcbcentralmanager

iOS Core Bluetooth - Can't discover the real device from scan


I am trying to discover a bluetooth device and connect to it through the use of CBCentralManager. The device is a headset. It can be discovered through bluetooth scan on the phone. The device name is "A1-25". When I connect "A1-25" directly from phone bluetooth settings, I can play songs with it, it's working fine.

enter image description here

However, when I started scanning peripherals using CBCentralManager. I can't see a peripheral named "A1-25". But rather, I saw a peripheral named "EQ_Test_llyan". But before, when I scan nearby devices from the bluetooth settings, "EQ_Test_llyan" did not come out.

2017-12-13 16:35:07.233021+0800 Test[1405:500801] started scanning
2017-12-13 16:35:17.469375+0800 Test[1405:500801] discovered peripheral with name EQ_Test_llyan advertisementData:{
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = "EQ_Test_llyan";
    kCBAdvDataManufacturerData = <b0024551 5f544553 54>;
}
2017-12-13 16:35:17.470672+0800 Test[1405:500801] connecting with device!!!!!!!
2017-12-13 16:35:17.654884+0800 Test[1405:500801] connected to peripheral name:EQ_Test_llyan id:7326E741-BF68-D9E8-D7A6-5F27227685A7
2017-12-13 16:35:17.656526+0800 Test[1405:500801] discovering services for peripheral name:EQ_Test_llyan
2017-12-13 16:35:18.193311+0800 Test[1405:500801] discovered services:(
) for peripheral name:EQ_Test_llyan

The peripheral "EQ_Test_llyan" has no services (see above log), so I can't communicate with it. Now, when I went back to the bluetooth devices in the phone settings I am now connected to "EQ_Test_llyan", but not to "A1-25". Now, I try to play the music, the sound does not come out from the headset.

enter image description here

When I turned off the headset, I will be disconnected from "EQ_Test_llyan" and "A1-25" will be gone. Therefore I conclude that "EQ_Test_llyan" and "A1-25" comes from the same device.

Take note that I can connect to both at the same time. I will just connect to "EQ_Test_llyan" programmatically, then it will appear on the settings. Then I manually connect to "A1-25" from the phone settings. It will be like what it shows on the picture below. When I play the music, I can still hear sound coming out from headset. So, it's working fine as long as I am connected to "A1-25", but not to "EQ_Test_llyan" alone.

enter image description here

So my questions are:

  1. Is CBPeripheral referring to the actual device? Because if it is, why can't I scan "A1-25" but I can scan "EQ_Test_llyan"?
  2. Take note that when the phone is connected to "A1-25", it has an "i" beside it, this means that the connection can be terminated. But when the phone is connected to "EQ_Test_llyan", there's no "i" beside it. So, it can't be disconnected unless you turned off the device. So, what's the difference between the two? Is "AI-25" the real device, while "EQ_Test_llyan" is just a connection? I don't understand.

Solution

  • You can not discover "A1-25" from the CBCentralManager because it is a headset as you've mentioned. Headset uses Headset Profile (HSP), which is known as "Bluetooth Classic" profile, while Core Bluetooth is suitable only for Bluetooth Low Energy (BLE, Bluetooth 4.0) General Attribute Profile (GATT). If you examine the CoreBluetooth API, you'll discover it's all about services and characteristics. It has no abstractions for sound-related profiles.

    On the other hand, GATT is very general and abstract profile, and can be used by a device of any kind, each time for some very specific data — speed, temperature, heart rate, some device configuration, and virtually any other values. So you can pair to GATT devices only from an app that aware of that exact device. You just have nothing to do with such generic service from your phone settings screen.