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

iOS and pairing

I'm trying to perform communication between my device and iOS and I ran into some problems. For tests I'm using iPod touch 5 with nRF Toolbox and LightBlue apps and nRF51822-EK with modified ble_app_hrs example from SDK6 and S110v7. I changed it so that device will always will advertise when not connected with timeout = 0 and all it's characteristics will be available only after pairing (BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM instead BLE_GAP_CONN_SEC_MODE_SET_OPEN) also I added UART test info output. I attached this example project in the end.

  1. When I'm connecting to the device with LightBlue or nRF Toolbox the pairing request from iOS will pop-up and when I press "Cancel" an error will occur in device.

    I got this UART output:

    0010
    0013
    error
    00000081
    ..\main.c
    0507
    

    So first device will get BLE_GAP_EVT_CONNECTED (0x10) event, then BLE_GAP_EVT_SEC_PARAMS_REQUEST (0x13) and when I press "Cancel" in pairing request it's asserting in device_manager_evt_handler with MUTEX_INIT_FAILED (0x81).

    How can I properly handle pairing cancel?

  2. When I'm connecting to the device with LightBlue or nRF Toolbox, pair with it and then press back to main screen with "Peripherals Nearby" in LightBlue or "Disconnect" in nRF Toolbox HRM the device remains connected and I can see notifications still being send (I see BLE_EVT_TX_COMPLETE events in UART output) and in iOS Settings -> Bluetooth I can see Nordic_HRM being Connected. And I can't connect anymore with apps to the device because as soon as I reset the device I can see it advertising in LightBlue and nRF Toolbox but iOS immediately automatically connect to the device and I can't connect to the device with LightBlue or nRF Toolbox.

    So is there a way to pair with device and reconnect to it in iOS app? Is it just LightBlue/nRF Toolbox imperfection in handling already connected devices or some iOS problem?

ble_app_hrs.rar

UPD1:

I google for some info regarding this issues and found this:

  1. Regarding "Cancel" issue.

    It seems that I can check which button was clicked and if it was "Cancel" then send cancelPeripheralConnection. Will this still lead to assert on device side?

  2. Regarding inability to disconnect.

    It seems that if app send cancelPeripheralConnection then iOS can still maintain connection. What to do in this case if I need to forcefully disconnect device from iOS?

UPD2:

Again about inability to disconnect.

I read this:

In both cases, cancel any subscriptions you may have and then disconnect from the peripheral. You can cancel any subscription to a characteristic’s value by calling the setNotifyValue:forCharacteristic: method, setting the first parameter to NO. You can cancel a connection to a peripheral device by calling the cancelPeripheralConnection: method of the CBCentralManager class

Does that mean that if I disable notifications before disconnecting then device will disconnect from iOS too?

I checked nRF Toolbox code and in HRSViewController.m there is no disabling notifications before disconnect. So if I disable all notifications before disconnect iOS will disconnect from device?

UPD3:

Yes, it seems like it'll work:

- (void) disconnect {
    // it seems necessary to explicitly unsubscribe before disconnecting
    // if we don't do this, the server still thinks it's connected
    // and subsequent connection attempts fail.
    if (self.characteristic) {
        [self.peripheral setNotifyValue:NO forCharacteristic:self.characteristic];
    }
    if (self.peripheral) {
        [self.manager cancelPeripheralConnection:self.peripheral];
    }
}
Related