Demonstrates whitelisting within the context of a BLE peripheral. Whitelisting is the technique used to restrict which devices are allowed to connect to your device. If a remote device is not on the whitelist, then it is not allowed to connect.
Whitelisting with iOS devices will not work due to a limitation in the way the internal chipset in the BLE modules implements stack-level whitelisting functionality. See the "Additional Notes" section below for detail.
This example has the following features:
|Safe to Flash:||BLE112, DKBLE112, BLE113, DKBLE113|
|Unsafe to Flash:||BLED112 (no ability to return to DFU mode, GPIOs unavailable anyway)|
The whitelist on the module can only be modified while you are not already advertising, scanning, or connected. This example implements whitelist modifications correctly in this regard. Here are the basic steps:
You can stop advertising and set non-filtering policies at any time to allow connections from any device, even if the whitelist has entries added to it. This example project does this when you use the P0_0 button on the DKBLE11x devkit.
Lost bond data
Bonding data and the manually stored MAC address/type values are saved in the public store (PS) keys on the module itself. This information is retained across resets and power cycles, but it will be lost if you reflash the device with new firmware. This means that if you bond with another device, then make a change to the firmware and reflash it, the bonding information will be missing on only one side of the connection. This can cause unexpected behavior if you are not aware that it has happened. If you reflash the firmware or otherwise clear bonding info after bonding with an iOS device, you MUST go into the iOS device's Bluetooth Settings area and "forget" the bonded device before attempting to re-bond.
iOS and random/private addressing limitations
The CC254x chipset used in the BLE(D)11x devices has a hardware limitation which prevents a whitelisted private/random address from continuing to match after the remote device changes its address, EVEN IF THE DEVICES ARE BONDED. Whitelisting only matches the address and address type bit pattern transferred over the air, and does not make use of the IRK (identity-resolving key) which would allow the whitelisting filter to "follow" a changing private address.
This means that devices which employ the private addressing scheme with a rapid address update interval (most notably ANY iOS DEVICE) cannot be whitelisted using the built-in stack method demonstrated in this example. An alternative method would be to use bonding (as this example does), but write in similar application-level functionality which does not use the stack's whitelisting features but instead simply disconnects immediately (using "connection_disconnect") if a device connects without a valid bond handle. This is effectively what the stack's whitelisting functionality does, just a little bit less efficiently.
TO REITERATE: this example will not work with an iPhone/iPad for more than about 15 minutes. As soon as the iOS device updates its private address--which occurs on an interval as well as any time the Bluetooth subsystem is stopped/started, e.g. cycling flight mode--then whitelisting the original address will prevent the device from connecting again.
The "address_type" argument to the "system_whitelist_append" command is still useful for whitelisting if the remote device uses static addresses, i.e. an address which is random to the device but does not change often. More info on this is available in the Bluetooth 4.0 Core Spec Vol 3, Part C 10.8.