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

Clean way to deal with a central not bonding (pseudo denial of service)

iOS's auto connect introduces a number of unpleasant corner cases that can be difficult to deal with.

One annoying error path is if you delete the bond data on the peripheral but not on the iOS device. When iOS auto-reconnects, it will not do any IOs that would cause the switch to encrypted mode and detect that the bond is broken/lost. So it just sits there doing nothing. For something like ANCS it is the peripheral that initiates the service (by writing to a CCCD). In my current implementation, I do not do anything ANCS related until the encrypted session is established.

Is there a way for a peripheral to force a central to switch to encrypted mode? Or is there a clean way to terminate the connection if the central does not switch to encrypted mode. Just doing the obvious and disconnecting after a timeout if not encrypted just causes iOS to reconnect again, which eventually puts the peripheral on auto-connect black list.

  • You cannot force the central. You can send a security request with sd_ble_gap_authenticate(), but iOS doesn't respond to that.

    When the peripheral has lost the bond that you will end up in variant 2 in this MSC. So after you reply with sd_ble_gap_sec_info_reply(NULL) you could do a disconnect. It seems that to do this requires you to modify the Device Manager library a bit.

    I guess it doesn't solve your problem, but it is an alternative to a timeout.

Related