Using Core Bluetooth Classic sample - ios

I tried to test the sample code in apple developer's site https://developer.apple.com/documentation/corebluetooth/using_core_bluetooth_classic for gatt over classic with gatt_streamer_server from bluekitchen (https://github.com/bluekitchen/btstack/blob/master/example/gatt_streamer_server.c) - I enabled gatt over classic.
The callback of centralManager is not called. I reach to the "Starting cbManager" and then nothing happens. I registered with the peripheral UUID.
Can anybody help?
Thanks

Related

CoreBluetooth not discovering hear-trate monitor if other app is connected first

I want my users to be able to track their heart-rate with my app. So I use CBCentralManager for that. Everything works fine if no other app is connected to the heart-rate sensor yet. The problem I have is if I start f.e. Strava or Endomondo first. Then I just can't find any devices any more. The other way round everything works fine, so I guess I am missing an options somewhere?
What I currently do:
I instantiate my CBCentralManager like so
centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
which will cause the delegate method for connection to be triggered
func centralManagerDidUpdateState(_ central: CBCentralManager) {
let heartRateServiceUUID = CBUUID(string: "180D")
let services = [heartRateServiceUUID]
switch central.state {
case .poweredOn:
centralManager.scanForPeripherals(withServices: services, options: nil)
and from there on no peripheral are found.
But again, when I force quit other apps like Endomondo or Strava and then start my app, everything works fine.
Ok, I just found the solution to my main problem myself. So anybody who might have the same issue:
Once you are connected to a device remember it's UUID
When you want to reconnect to it you don't need to scan, just use centralManager.retrievePeripherals(withIdentifiers: [the id's of the devices you know])
This will give you back a list of CBPeripherals and you simple connect to them like you would have after searching for them.
The only thing that I still don't know:
Even when i uninstall Endomondo, start my app first, they still can discover my heartrate monitor... And I suppose even if they remember the UUID it will be in UserDefaults i suppose, so they can't reconnect using centralManager.retrievePeripherals(...). So I still like to know what I'd need to change in order for that to work...
See Best Practices For Interacting With A Remote Peripheral Device for full details on how to connect to devices you already know about.
The main issue you're encountering is that most BLE devices stop advertising once they have a connection. Since they aren't advertising, you can't see them in a scan. In this particular case, the BLE device is connected to the iPhone you're running on, but that doesn't change anything. It's still not advertising.
To deal with this, you want to ask the iPhone for connected devices that have the service you want, using retrieveConnectedPeripherals(withServices:). This is a very fast, synchronous call, and you generally should do it before calling scan​For​Peripherals(with​Services:​options:​).
There are several other steps that you generally should do. The precise order and logic depends a little on your situation, but the linked flowchart above walks you through one approach. Basically it will look something like this:
Call retrieve​Peripherals(with​Identifiers:​) to find a peripheral you already know the identifier for. Note that this just tells you the system knows about the peripheral; it doesn't mean it's currently nearby. Calling connect on it may never succeed.
Call retrieveConnectedPeripherals(withServices:) to find a peripheral that is already connected to this iPhone and advertises your service. You still need to call connect on it for your process, but it should succeed.
If all the rest fails, then call scan​For​Peripherals(with​Services:​options:​).
Update:
It appears that BLE4.0 chipset did only support one connection so when a centralmanager connected to a BLE4.0 device it stopped advertising and established a connected layer.
With BLE4.1 chipset it added support for multi-role connection. It is possible that the heart-rate sensor use newer BLE technique that support more than one connection.
https://e2e.ti.com/blogs_/b/connecting_wirelessly/archive/2016/11/30/bluetooth-low-energy-multi-role-demystified
It is still unclear why your app wont connect if the other apps are connected. Can you post all your code?
My old answer:
"Core bluetooth and Bluetooth Low Energy can only handle one connection for each peripheral which means that if your app(CBCentralManager) establish a connection with a peripheral(UUID) it establish a message layer between the central and peripheral so other apps cant interfere the connection to that peripheral unless you disconnect the first app. This is how Bluetooth Low Energy works."
Apple Guides and Samples:
https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html#//apple_ref/doc/uid/TP40013257-CH1-SW1
Apple Core Bluetooth API:
https://developer.apple.com/reference/corebluetooth

Unable to discover bluetooth peripheral or service from iOS device

I am attempting to scan for a bluetooth device using the CoreBluetooth framework. The device is a prototype provided by a client.
I believe my implementation of the CBCentralManagerDelegate is correct, but I am never receiving the centralManager: didDiscoverPeripheral: advertisementData: RSSI: callback. Even if I register for nil service UUIDs, which should fire discovery callbacks for all devices, nothing happens.
I would consider whether the bluetooth device might be defective, except here's the wrinkle... when I fire up the Bluetooth debugging application LightBlue on my iPad, the prototype device is listed, along with some services. In fact, as soon as I use that app's 'clone' feature to reproduce the service from the iPad directly, my delegate callback fires.
I can post some sample code but it really is boiler plate stuff (I believe). Bluetooth experts: are there any obvious causes for the behavior I am experiencing?
Some points to check: make sure you have set the delegate of your CCBCentralManager correctly. If your device is bonded to iOS device I suppose didDiscoverPeripheralshould not be fired, but in this case LightBlue app would not show any service at "Scanning for peripherals..." screen.
Good luck

BLE Shield used for ANCS iPhone

I have a http://redbearlab.com/bleshield/.
I successfully tested the Chat example and i have sent a message from iPhone to Arduino.
Now i want to test the ANCS functionality. From what i heard, the iPhone must be the Peripheral and BLE Shield must connect to ANCS service and then it will receive notifications.
Is it possible to discover and connect to bluetooth devices using BLE Shield? How?
Thank you!
Is it possible to discover and connect to bluetooth devices using BLE Shield?
yes it is possible! I'm currently writing an article and I'm also about to publish a library that handles ANCS notifications. It's way more complicated than only running the Chat example, though.
How?
To access the ANCS, here are the key things to do:
open nRFGoStudio
add the ANCS services into the pipe definition
force bonding to access the services
and generate the new services.h
in your code
when bonding is done shutdown and restart the BLE radio
wait until the ANCS pipes are opened
when they all are opened, subscribe to the ANCS Notification Source
to get more details, and a working library, please have a look at the following article I wrote:
http://i.got.nothing.to/code/on/avr-for-ble-and-ios
and the library:
https://github.com/guyzmo/avr_nrf_ancs_library
HTH

iOS CoreBluetooth reconnecting device with UUID

I have a Bluetooth 4.0 (BLE) device using the CC2541 chipset which I am interfacing with via the iOS Core Bluetooth Framework.
I can successfully make a connection to the device using Core Bluetooth when the device is in a discoverable/advertising mode and transfer data to and from the device without any problem.
I maintain a collection of device UUIDs that I have connected with and I am now attempting to connect to one of these devices again using:
CBCentralManager
- (void)retrievePeripherals:(NSArray *)peripheralUUIDs
Calling this function appears to work and I receive a callback to my implementation of the the following function:
CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals
The device I'm attempting to connect with is the one and only peripheral listed in the peripherals array that is passed to this function.
When I then attempt to connect to this device using my connect function (shown below) the connection will not initiate and I get no callbacks at all on either the CBCentralManagerDelegate or the CBPeripheralDelegate.
- (void) connectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"Connecting to peripheral with UUID : %s\r\n",[self UUIDToString:peripheral.UUID]);
activePeripheral = peripheral;
activePeripheral.delegate = self;
[CM connectPeripheral:activePeripheral options:nil];
}
I can make the connection go through successfully, as described above, if I first place the device into discoverable/advertising mode, but this is not a workable solution. The device must allow reconnection without it being placed into discoverable mode.
I did note the answer given to this question CoreBluetooth: What is the lifetime of unique UUIDs suggests I need to pair/bond the BLE device with the iOS device but that this may be dependent on the BLE chipset, the device I'm using is the CC2541. Any advice on how to go about pairing with the device would be most useful, or indeed whether this is a necessary step. I have attempted to watch WWDC 2012: Advanced Core Bluetooth which might give me some assistance, but since Apple were hacked on Thursday I'm not able to access my acccount to watch the video.
Please let me know if any more details are required. The Bluetooth device is stable, but it is being developed internally. If changes may be required to the firmware to assist with the pairing process, I can pass this information along to the electronics team.
Why dont you try this?
It specifies first you need to send a request to a GATT characteristic that requires GATT_AUTHEN_READ permission. Then your CC2541 will respond with INVALID AUTHENTICATION. This will trigger Apple's internal Bonding mechanism and ask for a key. You can enter the passkey and then if the device and CC2541 are successfully paired, it will read the characteristic value and enter your callback.
NOTE: I'm not an iOS developer, but I have worked with CC2541. If you are using the default simplePEripheral example, then a characteristic in simpleProfile characteristic5 requires authentication to read. Take a look at profiles/SimpleProfile/simpleGATTprofile.c

How to use core bluetooth framework get data?

I am working on an iOS core Bluetooth application, i can connect the bluetooth device use iphone4S , but i dont know how to communication with the device. i want to read information form the device.
i also see this sources code https://github.com/sergiomtzlosa/CoreBluetooth-Demo/
and this article How to read information from core bluetooth device
but i dont understand how to transfer data.
can some one help me? thank you
To use CoreBluetooth, first your device must support Bluetooth Low Energy in Bluetooth 4.0. You can't connect to the device through iOS's UI for LE, you will have to develop your own UI for it because your application need to connect to only the devices with the services that you are interested in.
After that, you can subscribe to notification of the device when a characteristic value is updated, and then read the value using CoreBluetooth API. If the device has a characteristic that can be written to, then your application can write to the characteristic using CoreBluetooth API.
That's the general idea, hope that answers your question.
Edit: check out these samples:
Heart Rate Monitor
Temperature Sensor
A very similiar question has been asked and answered.
Read through the framework and find methods and callbacks with very descriptive names like:
- (void) centralManagerDidUpdateState:central
- (void) centralManager:central didDiscoverPeripheral
- (void) peripheral:peripheral didDiscoverServices:error

Resources