iOS BLE peripheral / advertisement data in backgro

2019-03-15 21:18发布

问题:

I'm developing a system which has a BLE device (TI CC2540) as Central and an iOS app on iPhone4S as Peripheral. Everything works fine except 1 function I need: white-list (filtering) advertising devices from central side.

As far as I know, iOS devices use Random Resolvable MAC address, so we cannot apply white-list based on MAC address.

So my current method is: put an ID on "Local name" field on advertisement data of iOS app (iOS device acts as peripheral), Central device will scan and filter based on retrieved advertisement data. This works unless app is in background.

When my app is put in background, advertisement data is truncated and my "local name" does not appear over-the-air. From header file of corebluetooth, I see there is only "overflow area" data can be in advertisement data when app is in background, but only iOS device can read this area.

So can anybody here light me how to add custom data into advertisement packet even in background mode, or any other solution to have this filtering function.

Any comment will help me very much.

回答1:

I know this is an older post, but for anybody curious, there is no reliable way to accomplish this because the CBAdvertisementDataLocalNameKey not transmitted while the app is in the background.

Also, the OS ignores the CBCentralManagerScanOptionAllowDuplicatesKey, so you will get exactly one didDiscoverPeripheral callback for each new device discovered.

If you are curious as to why, remember that at the hardware level there is only one bluetooth radio that is shared by all the apps using BLE, and the advertisement packet is shared among all the apps that advertising.

The overflow area holds all the service UUID's that your device advertises. I would imagine that this field is small and the system likely has to send out several packets cycling through the UUID's to advertise them all, if you have many.

Also, here is one more reason why the advertisement packet is a non-optimal place to put required app information. Say you have an app that relies on advertisement data for service UUID A. Then, that app becomes backgrounded and the user opens up another app that uses advertisement data for service UUID B.

Because the device is now advertising services for UUID A and UUID B, any receiving device will get a callback on any central looking for an A or B. However, the CBAdvertisementDataLocalNameKey will only contain the data for B, since it is in the foreground on the transmitting device, which means your device is only expecting data for A could be processing the wrong data.

If you want to get a clearer at what the advertisement data is actually transmitting, there is an excellent iOS app on the App Store called LightBlue will show you this data, and allow you to connect to a device and look at all it's services, characteristics and descriptors.



回答2:

I'm struggling with the same problem. For my project i need to read at least the CBAdvertisementDataLocalNameKey of an iPhone in background from a Raspberry Pi. I'm still not able to get any info from the overflow area.

However i've found an interesting thing that could solve our problem. There are some Android application for BLE scan that are able to read the LocalName while the nearby iOS device is in background. An example is this one. This is the screenshot of the cited app showing the correct CBAdvertisementDataLocalNameKey while the nearby iPhone is in background.

During the android scanning experiment, the raspberry isn't able to read anything except the Manufacturer Data block. A possible solution is to use a bluetooth packet sniffer to understand which is the correct scan request to obtain the scan response message containing the overflow area. This unfortunately requires specific hardware like the Ubertooth One.