1

Pre iPadOS 13.4 we needed to read/write to protected characteristic of a peripheral device in order to trigger pairing popup. Starting iPadOS 13.4 - the passcode popup seems to be triggered simply via a successful connection with the peripheral (CBCentralManager().connect(peripheral, options: nil)).

I need to further communicate with the peripheral in order to get the passcode before the pairing popup is displayed. Once the pairing popup is displayed - the peripheral stops responding to any further requests.

Is this a design change or a bug on 13.4? I cannot find anything on the web/apple's release notes for iPadOS 13.4.

If this is a design change - what is an elegant way of handling this?

The following code triggers pairing on didConnect peripheral: //Sample Code

var centralManager: CBCentralManager?
var peripheral: CBPeripheral?

override func viewDidLoad() {
    super.viewDidLoad()
    centralManager = CBCentralManager(delegate: self, queue: nil)
}

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .poweredOn:
        print("CentralManager state: Powered On")
        centralManager?.scanForPeripherals(withServices: [advertisingUUID], options: nil)
        print("Scanning for peripherals...")
    default:
        print("CentralManager state: Powered Off")
    }
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
       self.peripheral = peripheral
       self.peripheral?.delegate = self
       centralManager?.connect(peripheral, options: nil)
       centralManager?.stopScan()
}

func centralManager(_ central: CBCentralManager,
                           didConnect peripheral: CBPeripheral) {
    print("Peripheral Connected")
}

func centralManager(_ central: CBCentralManager,
                    didDisconnectPeripheral peripheral: CBPeripheral,
                    error: Error?){
    print("Peripheral Disconnected")
}
gammaB
  • 11
  • 2
  • What du you mean with "I need to further communicate with the peripheral in order to get the passcode before the pairing popup is displayed"? Per the Bluetooth standard, when passkey pairing is used, the remote device shall show the passkey on its display and the user shall then enter it on the other device. So your app should not do anything while the pairing is going on. If the device does not have input / output capabilities then "just works" pairing shall be used, meaning no passkey is used during the pairing. – Emil Apr 07 '20 at 20:57
  • The peripheral I am pairing to does not have input/ output capabilities so there are additional security related request responses in place to get a passcode. The issue is that in iPadOS 13.4 and 13.4.1 now, the pairing popup is triggered unexpectedly after BLE device is connected. – gammaB Apr 08 '20 at 02:10
  • What peripheral are you trying to pair? If it says it has i/o capabilities but still can't give the user a 6 digit decimal number, it clearly violates the Bluetooth Core spec (see Vol 3 Part H sections 2.3.2 and 2.3.5.1). Anyway, as far as I know, iOS will only initiate pairing either when it gets an error from the device that the characteristic needs security, or when the remote device sends an SMP Security Request (i.e. a request to initiate encryption). – Emil Apr 08 '20 at 11:46
  • Thank you for your comments. Like I mentioned in my previous comment - the peripheral I am using does not have i/o capabilities. That is not the real issue here. What I would like to know is why the pairing popup is triggered in iPadOS 13.4 by simply connecting to the peripheral - without ever trying to read/write protected characteristics. – gammaB Apr 08 '20 at 15:03
  • Does the remote device send an SMP Security Request? – Emil Apr 08 '20 at 15:53
  • It does not - the security request is initiated on my end. I never get to it though - before I can send any other request after connecting to the peripheral - the passcode popup is displayed on the screen. – gammaB Apr 08 '20 at 16:09
  • FYI - updated initial post with code sample – gammaB Apr 08 '20 at 17:40
  • Do you get the same behaviour if you use LightBlue or nRF Connect? Do you get the pairing dialog on Android? – Emil Apr 08 '20 at 21:34
  • I did get the same behavior using nRF Connect. The popup did not appear for iOS 13.3.1 but it did for 13.4 and 13.4.1. Did not test on android device as my application is iOS exclusive. – gammaB Apr 08 '20 at 21:47
  • Well you can still try connect to it using for example nRF Connect on Android. Are you 100% sure the remote device does not send an SMP Security Request? You should use hci logging feature in iOS to see what's really going on, or use a BLE sniffer. – Emil Apr 08 '20 at 22:31
  • I think we are starting to go on a tangent here. What I would like to know is - is it expected behavior for CoreBluetooth to display passcode popup right after didConnect or is it a bug in 13.4. – gammaB Apr 09 '20 at 15:23
  • No it's not expected behaviour. CoreBluetooth allows unencrypted BLE connections, so pairing is not required. Just verified on iOS 13.4 that no pairing dialog is shown when connecting to a non-paired BLE device. The only thing that can make a pairing dialog to automatically appear even if you don't execute any GATT operations, is if the remote device sends an SMP Security Request. So please take an HCI log or use a BLE sniffer to verify that the device sends an SMP Security Request. – Emil Apr 09 '20 at 15:49
  • Thank you for your input - it is greatly appreciated! Currently I do not have a way to verify if the SMP Security Request is being sent from the peripheral, but I will definitely explore that option. – gammaB Apr 10 '20 at 16:45
  • @gammaB Did you find anything>? I am facing same issue and not able to identify whey pairing popup is displaying. – PlusInfosys Nov 30 '21 at 11:02
  • @PlusInfosys - this was a specific issue with iOS 13.4.1. All other versions of iOS seems to work as expected – gammaB Dec 08 '21 at 15:42

0 Answers0