I needed to make a Bluetooth LE device that required a more secure pairing with the companion iOS app than just "Click Pair to connect…".
This can easily be implemented in BTLE using a bonded, encrypted connection with man-in-the-middle protection enabled. But the device needs either a display to show the code which should be entered on the iOS device, or a keypad to enter the code shown on the iOS device. If the device has neither, then only the "Just works" method can be used. And this will not prompt for a passkey/PIN code.
"But can't I just hardcode a PIN code in the firmware," I asked Google. And Google said, "No, fixed-passkey authentication is not supported in Bluetooth LE."
But it turns out that there is a solution: pretend the BTLE device has a display and specify a hardcoded passkey in the config.xml file. That way, instead of generating a random key to display to the user, the hardcoded passkey will be generated instead.
Script file
In your .bgs file, do this:
# Boot event listener event system_boot( major, minor, patch, build, ll_version, protocol_version, hw ) call gap_set_mode( gap_general_discoverable, gap_undirected_connectable ) # Bondable mode call sm_set_bondable_mode( 1 ) # Requre MITM protection (keylength=7, capabilities = DisplayOnly) call sm_set_parameters( 1, 7, 0 ) end # Connection established event connection_status( connection, flags, address, address_type, conn_interval, timeout, latency, bonding ) # Require encypted, bonded connection call sm_encrypt_start( connection, 1 ) end
That enables bonding and specifies that MITM is required and that the device has a display only, which means the system will generate a passkey and let the device show it (this should be done in the sm_passkey_display
event handler).
When a connection is made, encryption is started and this will prompt for a passkey on the iOS device.
Configuration file
In your config.xml file, add this:
<config> <passkey value="111111"/> </config>
And be sure to specify <config in="config.xml" />
in your project file.
When connecting, the iOS (or other) will now prompt for a passkey, which is hardcoded to "111111". This is technically not in keeping with the BT4 specification, but in my case it does what I need it to do.
I would expect the iOS device to be configured as a device with display and button input. In this case wouldn't the iOS device simply show your hardcoded passkey and a yes/no confirmation dialog since your other device is supposed to be displaying it on a screen anyways? The only way I see this working is if the iOS device is configured as keyboard entry only.