This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE advertising data flags field and discovery

For the BLE GAP advertising flags byte in the advertising data, we have the following options:

/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
 * @{ */
#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE         (0x01)   /**< LE Limited Discoverable Mode. */
#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE         (0x02)   /**< LE General Discoverable Mode. */
#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED         (0x04)   /**< BR/EDR not supported. */
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER         (0x08)   /**< Simultaneous LE and BR/EDR, Controller. */
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST               (0x10)   /**< Simultaneous LE and BR/EDR, Host. */
#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE   (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)   /**< LE Limited Discoverable Mode, BR/EDR not supported. */
#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE   (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)   /**< LE General Discoverable Mode, BR/EDR not supported. */
/**@} */

So this byte mixes two concepts:

  1. Discoverability (non-discoverable vs. limited vs. general)
  2. Bluetooth LE vs. Bluetooth Classic.

By setting this flag only:

BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED

we've specified that we're a BLE device and not a Bluetooth Classic device, but we've said nothing about discoverability. Does the central interpret that to mean that the peripheral is non-discoverable and it should not attempt to perform service discovery after connection?

Testing use the nRF Connect Android app and my own custom app, that's not the behaviour I'm seeing. Both will happily perform service discovery after connecting. I'm testing this with a BLE MAC address that hasn't been connected to or bonded with by the central before, so I don't think a cache in the BLE stack on the central is affecting what I'm seeing.

Secondly, what really is the difference between limited and general discoverability? I've read the spec on it and I still don't understand it (Vol 3, part C, section 4.1). (That section also suggests that if we set neither limited nor general here, the peripheral is non-discoverable.)

  • Does this go back to your thread from a few weeks ago you left unanswered after Hung Bui and I replied to it?

    That byte doesn't mix two concepts, it expresses two concepts in different bits of a single byte because data is precious.

    If you set no discoverability flags the peripheral is not supposed to be discoverable. If Android is broken enough to try discovering it then that's just Android. If (as in your previous thread) you're finding you get a connection attempt but no discovery, perhaps Android is only half broken and if it connects and discovers and the device responds, a lot of things are broken.

    Is there a reason you don't just set the discoverability flags which represent your actual discoverability status. If that doesn't work, that's bad.

    And the difference between general and limited discovery is that limited is like shouting loudly so you are seen first but can only be done for a short time.

  • Yes, it's related, but deserved a more general question. No, it's not just Android. iOS will also happily do service discovery even without the discoverability bit set in the flag byte. No, you're right, on closer inspection and a bit more testing, there's no reason for me not to just use BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE since that more correctly my intentions. But I'm asking because I want to understand the behaviour of the iOS and Android BLE stacks here, not just what the spec says.

  • I think these flags is meant as a help to the scanner to see which advertisements to prioritize. Basically all advertisements are visible to all scanners. But the scanners can assume that:

    • if the Limited discoverable mode is used the device will only advertise for a limited amount of time. e.g. the user has put the device in bondable mode or some other time limited mode.
    • If a scanner sees a "non discoverable" advertisement it can assume this device uses a whitelist or for some other reason is not connectable. So it can save power by not trying to connect.
    • But I'm afraid the behavior will depend on the implementation, as it's up to the developer to use these flags correctly. Unless you are implementing a sig define profile with given requirements for flags.

    Regardless I don't think there is anything wrong with Android or iOS when allowing you to connect to these devices. Hopefully the flags is forwarded to the application (looks like both Android and iOS forwards a string with the content of the ad packet), so the application can choose what to do.

    Not sure why you are talking about service discovery. That seems unrelated to me, and should be performed after connecting, at least when connecting to an unknown device.

Related