iBeacon scan response formatting - ios

I would like to configure my Bluetooth Low Energy peripheral devices as iBeacons and send additional data without connecting. Scan response is the correct way to do this, but including my custom scan response is causing the iOS iBeacon callback not to trigger within my iOS app
This post clearly outlines how to format the advertising packet: http://e2e.ti.com/support/wireless_connectivity/f/538/p/293551/1023580.aspx#1023580
I know iBeacons made by Estimote do have scan responses, so it is possible, but I can't find any good documentation for iBeacons.
What are acceptable scan responses for iBeacons?

You can see an example of a scan request/response sequence here:
http://processors.wiki.ti.com/index.php/BLE_sniffer_guide
I doubt that making a custom scan response from your beacon is stopping detections. I think it is more likely that when you added the scan response you somehow altered your advertisement so that iOS no longer sees it.
Even if you get this working, I don't believe there is any way to make iOS be able to see the data from a scan response that came from an iBeacon. If you want this data for use by other platforms then this may be fine.

I was including the data type "manufacturer data" in the scan response. I had a different company code than the code given in Apples preamble for iBeacon advertising packets. Removing this data made iOS recognize my device as an iBeacon and receive the scan response packet

Related

iOS omits manufacturer data from advertisement in background mode

I work on iOS application which is using BLE for communication with our custom made BLE unit.
We want to send specific commands via BLE to the unit automatically.
When user is near unit and specific criteria are met, the app should connect to the unit, "login" the user, send command via BLE and disconnect right away.
These specific criteria are based on manufacturer data from advertisement (i.e. the unit is in "available to login" state when manufacturer data has last byte 0x01, when it's "NOT available to login", last byte is 0x00).
In foreground, this mechanism works flawlessly.
We want to do this even when app is in background or terminated (swipe up in dashboard on iPhone).
The mechanism we have implemented:
the unit has capability of acting as iBeacon
when unit is NOT available for login, the iBeacon is OFF
when it IS available for login, the iBeacon will turn ON and wakes up application, upon that the BLE scan will start in background mode
background mode setting is bluetooth-central
Problem here is that no matter what I tried, the advertisement:
sometimes it's not discovered at all (looks like it's timing issue?)
when it's discovered, it does NOT contain manufacturer data
Did anyone come across something similar?
Any help is appreciated and have a nice day!
An app simply cannot read raw BLE manufacturer advertisement data when in the background on iOS -- the operating system prohibits it.
Two exceptions to this rule:
iBeacon, which itself is implemented as a specific type of manufacturer advertisement. An app can detect iBeacons in the background on iOS, although only four bytes of readable data (encoded in the major and minor fields) are fully usable. If you can modify your device to send information this way, it will do what you want. However you must use CoreLocation APIs to detect iBeacon, as CoreBluetooth does not allow reading manufacturer data from iBeacon advertisements. If you do use CoreLocation, you cannot use the detections to establish a Bluetooth connection with CoreBluetooth as the two APIs are sandboxed.
Overflow Area advertisements. Backgrounded iOS apps can read these special types of manufacturer advertisements when in the background but only if the screen is turned on. (It is often possible to force the screen on at specific times by sending a local notification.) See my blog post here for more info: http://www.davidgyoungtech.com/2020/05/07/hacking-the-overflow-area
An alternative to detecting manufacturer advertisements is to use BLE Service advertisements with attached data. For this to work, you'd need to define a 16 bit or 128 bit GATT Service UUID and send out an advert with attached data bytes. Eddystone beacon formats work this way, and allow detection in the background on iOS. This is probably the best approach if you can alter the BLE hardware.

BLE different peripheral name on different devices

I am trying to connect BLE device using his hex number written on his peripheral name. but the peripheral name is different for some reason on different devices.
What could be the reason for that?
also i tried to find it inside advertisementData but without success.
thanks
Your device might have the shortened name in the advertisement data but have the longer one in the scan response.
If you're scanning while the app is in the foreground, you'll get the full scan response data, so it might not matter in your app. You just might have to ignore the first callback that doesn't have scan response data.

BLE advertising data not received from android device

Using CoreBluetooth I am trying to detect a BLE peripheral which is transmitting the advertisement and scan response packets.
Packet sniffer is able to find the advertisement as well as scan response data but iPhone only detects the scan response. So looks like iOS is rejecting the advertising data.
I am able to receive advertising data from other devices properly.
Any possible debug starting points ?
Note: The periferal device spec indicates that it does not set the 3 optional BLE packet bytes while transmitting the advertising data.
Advertising packets are used only to notify periodically any possible Central devices of the BLE device presence. The Advertising packet can contain information if the device can be connected to or not, and a few other data. Scan response should be the place where you should focus to pack important data.
On iOS you should rely on scan response to deliver the important identification data. On Android you have more flexibility, such as accessing both advertising packet and scan responses. Just to make sure you play along well with both platforms, keep the advertising simple so just the device is visible by any central, and store your data in scan response.

Sending only one iBeacon Packet

Is it possible to send only 1 iBeacon packet? I have tried using CBPeripheralManager,but since there are only 2 method to start and stop advertising, so I can't control how many packet is being broadcast.
What I want to try to do is use an iBeacon packet as a command, instead of just a broadcasting some ID. So I could send 1 iBeacon packet, and if the receiver got the message, it can send back Acknowledgement with another iBeacon packet. The intention is to avoid the pairing of bluetooth to send very simple data. The information will be linked to UUID, major, and minor of the packet.
Or are there better ways to do this than using iBeacon.
Yes, you can use iBeacon technology to send information back and forth between two iOS devices without pairing. If you have two devices, Device A and Device B, you set both of them up to range for beacons with a common ProximityUUID, say, E2C56DB5-DFFB-48D2-B060-D0F5A71096E0. And then you can exchange information in the two byte major and minor fields.
What you can't do is control the transmitter enough to send only a single iBeacon advertisement. The transmitter in iOS sends out 10 advertisement packets per second, so the best you could do is start the transmitter then stop it on a timer about 100ms later. (You probably shouldn't do this, because there is no guarantee that a single iBeacon advertising packet will be received successfully by the other device -- it may be lost due to a CRC error in the radio noise. You are probably better off letting the packet continue to transmit until you can confirm from a response from the other device that it was received.)
You can see an example of starting and stopping a transmitter on a timer in my answer here.
Of course, there may be easier and more robust ways of accomplishing what you want with built-in Bluetooth data exchange mechanisms. But that doesn't change the fact that what you propose is certainly possible.
No you can't since iBeacon is uni-direction device

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