SMP Pairing Request doesn't set SC Bit

I'm using an iPhone XR to connect to my Linux 4.9 / Bluez 5.50 peripheral and want to use Bluetooth 4.2's Secure Connection pairing.

On my device, there are a couple of characteristics the require authentication, the agent for pairing is set up as "DisplayYesNo". After discovering the services and characteristics on the iPhone, I read a characteristic for the first time. As expected, a Bluetooth Pairing dialog pops up, but instead of asking me to compare numbers, I have to enter a passkey (that I show on the peripheral's display).

With `btmon` on the Linux side, I can see that after the "Insufficient Authentication" response from Linux, the iPhone sends a SMP Pairing Request, but doesn't set the SC bit. Everything works consistently, but I would have expected the iPhone to initiate pairing with SC enabled.


There is a rather brittle way to run the pairing with SC enabled: After the connection is established, Bluez' "battery" plugin runs on the Linux side, discovers the "Battery Service (0x180f)" on the iPhone and tries to read "the third of four" characteristics. The iPhone responds with an Insufficient Authentication error by itself, Linux sends an SMP Security Request with the SC bit set and then the iPhone issues a SMP Pairing Request with the SC bit set resulting in numeric comparison on both ends and public key exchange etc.

I can now "force" this second behavior by putting an arbitrary delay (3 seconds...) into the iOS app right after the successful connection before starting service and characteristic discovery and reading characteristics. That way the SC pairing due to the battery plugin likely has already started before I try to read from the authenticated characteristic within the app.


*shudder* What can I do to improve that?