BLE : Advertising of UUID from background iOS app

2019-04-01 23:07发布

问题:

As the iOS documentation states, when an iOS application that utilizes BLE as a peripheral moves to background mode, the local name is not advertised and all service UUIDs are placed in the overflow area. The documentation states that they can only be discovered by an iOS device.

My overall question is how exactly this happens on a lower level. Using a non-iOS bluetooth packet sniffer, I examined the advertisement data structure from my iOS peripheral app when it was in foreground and in background modes. The advertisement data structure in foreground mode looks to be what was expected, similar to other advertisement data from non-iOS devices, such as those I have coming from an Android device.

When the iOS app is background mode, this structure changes and the service UUID is not apparent. I do not see anything suggesting an “overflow” area.

How does a iOS central device discover a peripheral device that is in background mode if the UUID is not a part of the advertising data packet?

回答1:

There is a so-called overflow area according to Apple documentation. More information can be found in this archive page about Core Bluetooth concepts.

I've sniffed the packets over the air. You can read the details on github. What iOS does is broadcasting custom packages with particular bits representing UUIDs. For example UUID 3333 is represented by a bit going up in the BLE package.

04 3E 24 02 01 00 01 8C 91 A0 AD 8F 40 18 02 01 1A 14 FF 4C 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 D3

You see here 02 somewhere surrounded by zeros (preceding D3 the 8-bit RSSI value).

Every UUID is one-hot encoded to a bit in this range. This will lead to collisions. You will notice that if you send 1001 by one iPhone and scan for 3333 by another iPhone you will receive the advertisements as if UUID 3333 is sent.

Note, there is a lot of nonsense written about this. It's just a regular undirected BLE packet. It's not a scan response. When running this on the background I've reliable gotten BLE packets every 0.2 seconds.

Time is on the x-axis (over a couple of days). The interval between messages is plotted on the y-axis. You see that at times the intervals are a multiple of 0.2 seconds. However, you also see that this is shared across the three iPhones (one broadcasting 1000, one broadcasting FFFF, and one broadcasting 3333 in the background). This means that this is an artifact from the laptop receiving the messages. The iPhones are probably even more robust than this. Over the entire weekend the battery drop is like 25%, which has very likely to do with other things than the BLE broadcasting.