How to match EAAccessory and CBPeripheral with MFi device? - ios

I have MFi device which uses BLE for control and Classic Bluetooth for audio streaming.
In the App, i use coreBluetooth framework to scan BLE and EAAccessory framework to scan Classic Bluetooth.
I don't want the BLE of target device to be connected if its Classic Bluetooth is not yet connected. So i need to know which EAAccessory is corresponding to target CBPeripheral.
I am familiar with coreBluetooth, there is UUID string to identify the CBPeripheral. But it looks not exist in EAAccessory.
I have an idea but not sure: maybe firmware side can config EAAccessory's serial number and CBPeripheral's manufacture data in advertisement data with the same
serial number, so that App side can check if they are the same.
Dose anyone knows the general way to implement this in App side and firmware side?

I really do not think there is s relationship between the 2. BT and BTLE are managed by different chip at peripheral side and phone side.
Usually in BT you use the MAC address to identify the peripheral on BTLE side the MAC address is not used anymore since iOS at the first connection give its own identifier to the peripheral.
What you can do is probably at firmware side, by exposing a service with a characteristic that somehow relate the 2.
UPDATE AFTER COMMENT
I see, as far as I know there a best practice doesn't exist.The worst part is that you have to handle connections differently, mostly due to how connection are made on iOS side. While on the BLE you can choose a not encrypted connection that would not require paring or bonding, on BT side I guess that bonding is required.
Probably the most simple flow would be, user bond the BT device. Once you are in the app and detect the connected BT device, use a scan method for detect BLE companion device by filtering for a specific service id that your device exposes, once you do that you can also filter discoveries using BLE name without still making a connection.
Adv packet are restricted in size (29 usable byte) but you can also use the scan response (31 byte), that exposes some additional properties such as manufacturer data that will be exposed in a dictionary (kCBAdvDataManufacturerData).
Once you know that is the correct device you can start a connection, that does not require pair or bond but is NOT encrypted (Pair and Bond will require the user to accept the connection inside your app).

Related

Pairing two BLE Devices with the same UUID (with CoreBluetooth)

I have two BLE devices with the same UUID. Is there any way to connect to both of them so that they are both connected at the same time?
Right now I'm not able to even see both devices simultaneously using a bluetooth explorer, so I assume for the system they appear as just one device. Is it still somehow possible?
I assume that with UUID you mean the MAC-Address (Bluetooth address) of the device. UUIDs are typically used for services and characteristics.
All connection procedures work with the Bluetooth address as the main parameter. So two devices with the same address will be treated as the same device. (In fact, it is a common requirement that MAC-Addresses of Bluetooth devices should be unique, exactly for this reason.)
So it is not possible to connect to two devices with the same address at the same time. (*)
You can find more information about how connection is done in the Bluetooth Core Spec, Vol. 3, Part C, chapter 9.3.5 - 9.3.8.
(*) This is meant in the common way of having a connection to two different devices. Since incoming messages are not distinguishable on Link Layer level between the two devices with identical address (your control will always think there is only one device with the given address out there), you could mess around with this fact, especially in non-encrypted connections (since encryption is negotiated on a device-to-device basis, another device could not join in an encrypted connection, even if it has the same Bluetooth address). But it is definitely not recommended to do so.
If two devices are having the same UUID , then I think they would be consider as a single device. What I would suggest , send a trigger notification to the UUID and check which device will respond first . Secondly , try to send notification to devices put them far apart . The nearer to your smartphone/bluetooth explorer , will get notify first . Bluetooth works on the distance basis, the device which is near to the source will get the notification than the other one.I tried the same with Beacons but end up like you.

What is the nature of BLE characteristic notify property?

I need to provide communication via Bluetooth Low Energy 4.0 between iOS-device from one side and certain peripheral device, which has bluetooth-module onboard.
Peripheral device was assembled with DORJI DBM01 bluetooth LE 4.0 module which allow to communicate with it using one characteristic with READ property (UUID = 0xFFF4) and one characteristic with WRITE property (UUID = 0xFFF1). Technical manual of DORJI DBM01 is here: http://dorji.com/docs/data/DBM01.pdf
I succeeded in establishing bluetooth LE connection between iOS-device (using Core Bluetooth Framework) and described above peripheral device, but characteristic with READ property doesn't have a property of notify (CBCharacteristicPropertyNotify in Core Bluetooth Framework). So I have to use some kind of infinite loop to scan and read new information from characteristic with READ property (by calling method of CBPeripheral instance - readValueForCharacteristic:) instead of subscribing to a characteristing value (by calling method setNotifyValue:forCharacteristic:).
Is it possible to add notify property to read characteristic of peripheral device (for instance, by engineer who built peripheral device or adding some low-level code which run on peripheral device) or notify property is an integral part of BLE-module (DORJI DBM01) and it can't be added without using another BLE-module?
The DBM01 is based on a Texas Instruments CC2540, like many other BLE-to-serial modules, which do implement notifications, so technically, it is definitely possible to do it.
However, this requires the firmware of the DBM01 to support it, and you'll of course have the issue of upgrading said firmware in existing modules. Unless there are undocumented features on the module, I doubt there would be a way to change the behaviour of the module without touching the firmware.
Another option could be (but that really depends on your scenario) to switch the central and peripheral roles, so that the iOS app would be notified when the BLE module writes data. As I understand it, this needs to be done in hardware (the level on a specific pin needs to be changed).

Ios Peripheral Device in BACKGROUND

We need in our project to detect the proximity of an iPhone that is running a custom APP that is using Bluetooth LE.
The detector (Scanner, Central...) will be implemented using a BLE Integrated Circuit (from Texas or Nordic). I mean that the scanner is not another IOS device... running Core Bluetooth as a Central..
For the detector to guess the proximity, the idea is very simple, just advertise a service with an UUID proprietary.
While in foreground all works OK, and the UUID and a Local name are advertised (The UUID in the main advertise packet, and the Local Name in the SCAN Response packet....), and our scanner is able to decide if this iOS device is running our App.
The problem arises when going to background .....
The iOS stops broadcasting UUID and Local Name. (As the documentation of Core Bluetooth Explains... I Know...)
At this moment (Background), IOS begin to broadcast a SPECIAL MANUFACTURER DATA in the main advertise packet, and nothing in the SCAN Response packet)
The data packet we see using a Bluetooth Sniffer is :
0x14 (length of packet not including this byte).
0xFF (Manufacturer specific data AD Type).
And then :
0x4C, 0x00 (this data is the manufacturer identifier, if the packet is compliant with BLE 4.0 specification).
0x01, 0x00,0x00, 0x00, 0x00,0x00,0x80, and ten 0x00 more....
I know Apple says that while in background ONLY ANOTHER IOS DEVICE SEARCHING FOR A SPECIFIC SERVICE CAN DISCOVER IT. (Really I do not know how they can achieve that, unless they connect to the peripheral and retrieve the services, or if the peripheral knows about other IOS device is scanning because of it´s Address in the SCAN REQUEST and then changes the advertisement data in background).
The main questions are :
Is there any documentation or knowledge of what this manufacturer data means....Perhaps it would be possible to the scanner to know based on this info that this is an iOS device advertising in background and then connect to look if the custom service is there. (Not a quick and clean solution...but I do not see any other workaround....)
Does anybody worked with this scenario...and found a clean solution .....
I have heard from people that forces the application not to go to background.
This limitation, will stop a lot of possible projects.

How to send data to an iphone which is turned into a iBeacon?

how is it possible to send data to an iPhone which acts as an iBeacon?
I am looking for an process as the following:
Search nearby iBeacons
Connect to some iBeacon
Exchange data between the devices
Does anybody know how to put the different bluetooth functions together to make
this possible?
thx in advance
Standard iBeacons are transmit-only devices that can be seen by mobile devices, but don't actually "connect" to them or exchange data.
But you can still do what you are asking if you have an app on all devices as well as a web service to do the data transfer. This would allow devices A and B to detect each other when they are nearby and exchange data. Here's how:
Your app on devices A and B alternates between acting as an iBeacon (advertising its presence with an application-specific identifier and a phone-specific identifier) and ranging for iBeacon signals including the application-specific identifier.
During its ranging cycle, your app on device A will detect an iBeacon transmission from device B, which includes both your application identifier and the device identifier of B.
App A then makes a "write" call to the web service with a source of "A" and a destination of "B", along with any data you want to transfer, like "Device A says hello to device B."
The app would also periodically make a "read" call to the web service. In this example, device B would read any information destined for B, and the web service would return a record that device A had send it a message with the data "Device A says hello to device B."
Because the same process is also running on both phones, this communication can happen both ways.
iBeacon is a proximity technology and isn't designed for data interchange. However, since the Bluetooth stack is going to be active on your iPhone acting as the beacon (so it can advertise its proximity UUID), you can use Core Bluetooth to connect to the beacon and exchange data between the devices.
Does it specifically need to use iBeacon technology? The reason I ask is that from reading your description of the process, you could achieve the same thing using iOS 7's Multipeer Connectivity. It's able to abstract out all the technical complexities of connecting 2 iOS devices together regardless of the interface, be it WiFi or Bluetooth. I've managed to build something similar using MCNearbyServiceBrowser, MCNearbyServiceAdvertiser, and MCSession classes.

Transmitting data with CoreBluetooth

I'm developing an iOS app with an accompanying Bluetooth LE peripheral. The one step I don't seem to be able to solve is how to actually transmit the data from my app to the peripheral or vice versa.
What I've built so far is a test app that can connect to my sample Bluetooth peripheral, and read all of its services/characteristics/descriptors. It can toggle notifications for a given characteristic, and write to given characteristics. It is just this last step of "transmit n bytes to the peripheral, and receive m bytes from the peripheral" that I can't seem to figure out.
Looking at the External Accessory Framework (what I would use if Apple would actually give me MFi approval for this project), they give you input and output streams on a given session to communicate with the accessory, but no such object exists for CoreBluetooth.
Is this simply an oversight on Apple's part on the functionality of CoreBluetooth? Or do I simply need to develop my own Bluetooth service profile to handle the inflow/outflow of data to and from the peripheral?
LE is fundamentally designed to work with these GATT based profiles, which are suited for monitoring sensors, not for data streams. While LE does allow for additional L2CAP streams to be opened for custom protocols, Apple's CoreBluetooth doesn't provide access to do so.
You can build a custom profile with private services and characteristics and have it work kind of like SSP; that's the way I'm using my BLE module to get data from some sensors to my app. The module I bought (Microchip's RN-4020) already has a custom profile made specifically for this known as MLDP (Microchip Low-energy Data Profile).
The way I get the data in my iOS app is by subscribing to the private characteristic, thus being notified when the values are updated. So far it has been working great, and the data rate can go up to 20 kbps according to Microchip (I haven't tested its limits, since I don't need much speed). Here's a link to Microchip's product page: http://www.microchip.com/wwwproducts/Devices.aspx?product=RN4020
Good luck!
You can use the bluetooth.org 'Immediate Alert Service' uuid=1802 with characteristic uuid=2A06 with property=write_no_response to send one byte values to your peripheral device from your iPhone. The peripheral device must be programmed to act on the data that is sent. For example, you might use a button on an iPhone app to send a hex address that causes one or more port pins to turn on or off on the peripheral. While this is not using the Alert Service as it was intended, it does provide an easy way to test out data transfer to a peripheral device. The same process could be used to send sequential data bytes similar to a serial data stream. I have not yet tried sending more complex data streams. The write_no_response does not provide any feedback to the app as to whether the data was received by the peripheral.
The IOS TemperatureSensor.xproj is an example of code for reading temperature data from a peripheral. The OSX HealthThermometerClient.xproj has the code needed to decode the somewhat complex thermometer data structure. The IOS TI-BLE-Demo.xproj TIBLECBKeyfob.m has code for reading and writing characteristic values, such as, reading temperature or battery levels from a peripheral device.

Resources