IOS Bluetooth LE : unable to connect using stored pairing data

I am stucked in my IOS dev and I need help. I am not an expert and it is perhaps a silly question.

What I am trying to do

  • Bonjour not advertising over BT
  • Background time issue for Bluetooth LE app for Iphone 4s
  • Connecting to a Bluetooth device from iOS, no MFi
  • PAN with Linux, iOS, Bluetooth, Bonjour, GameKit — Possible?
  • Can I broadcast multiple ibeacon signals from only one bluetooth? and how
  • Bluetooth HID Device & iOS textFields
  • I am trying to connect my app to a Bluetooth LE device which needs to be paired.

    Current behaviour

    There is no problem without pairing the device and my iPhone application. I am able to connect, reconnect and read/write characteristics without any problem.

    But, if the device need to be paired, I am only able to read/write characteristics the first time, right after the pairing popup confirmation. The next time, I discover and connect the app to my device, but I don’t have the rights to read/write characteristics data because (I guess) I am not using the pairing information.

    Finally…

    After spending few hours searching around the web with no luck here are my questions :

    • How can I connect my app to a Bluetooth LE device from my iPhone app using the pairing data stored in my phone? Am I missing something?

    • Is it possible that it is not an IOS problem because if pairing data are present in the phone for the connecting device, it is automatically used?

    Is there someone with experience with Bluetooth LE and IOS to help me?

    Update 2013-10-27

    I have discovered that you can’t read a protected characteristic by pairing authentication right after that the characteristic has been discovered if a pairing exists (no confirmation popup). No problem with non-protected characteristic! I don’t know exactly why is happening, but the behavior is that the IOS app never receive answers from the device.

    So if the first reading is done after, it doesn’t cause problem. Here is the code I am using to discover characteristics with the data reading in comment.

    - (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;
    {
        NSArray     *characteristics    = [service characteristics];
        CBCharacteristic *characteristic;
    
        if (peripheral != servicePeripheral) {
            NSLog(@"Wrong Peripheral.\n");
            return ;
        }
    
        if (service != batteryService) {
            NSLog(@"Wrong Service.\n");
            return ;
        }
    
        if (error != nil) {
            NSLog(@"Error %@\n", error);
            return ;
        }
    
        for (characteristic in characteristics) {
            NSLog(@"discovered characteristic %@", [characteristic UUID]);
    
            if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:kBatteryCharacteristicUUIDString]]) { // Bat
                NSLog(@"Discovered Bat Characteristic");
                batteryCharacteristic = [characteristic retain];
                //--> generate problem when pairing exists between IOS app and device
                //[peripheral readValueForCharacteristic:batteryCharacteristic];
            }
        }
    }
    

    Solutions Collect From Internet About “IOS Bluetooth LE : unable to connect using stored pairing data”

    You don’t have to do anything in your app for pairing management.

    If your app runs in LE Central mode, and the peripheral sends an Insufficient Authentication error code in response to a read / write request, iOS will automatically pair with your device and will retry the request.

    If you disconnect from the device, and later reconnect again, the peripheral needs to send the Insufficient Authentication error code again for the iPhone to restart encryption. Again, you don’t have to do anything special in your app here.

    If your app runs in LE Peripheral mode, things are a bit different. When you set up your GATT database, make sure to set correct flags for both the CBAttributePermissions and CBCharacteristicProperties. This will tell iOS that it should send the Insufficient Authentication error code itself, if it is not paired. It is then the responsibility of the central device to start the encryption process.

    In the Bluetooth Accessory Design Guidelines for Apple Products, further restrictions are described.

    • Your accessory needs the capability to resolve private Bluetooth addresses. The iPhone will change its public Bluetooth address every now and then, and only paired devices will have the correct key to resolve that public address and recognize the iPhone.

    • “Section 3.9 Pairing” is also interesting.

    • Note that if you pair without man-in-the-middle (MITM) protection, your peripheral can use the resulting key to resolve the private Bluetooth address of the iPhone. However, you won’t be able to encrypt the channel.

      Pairing with MITM protection on iOS involves entering a PIN code that is displayed by the remote device. Out-of-band (OOB) pairing where you send pairing data over an external channel is not supported by iOS as far as I know (at least there’s no public APIs to set OOB data).

      Long story short: if you have only a “Pair” / “Cancel” pairing, you cannot encrypt the LE channel but only recognize the iPhone in future connections. The nice thing is that you can still recognize the iPhone even if you unpair it on the iPhone side, and even after restoring the iPhone firmware ;-).

    Regarding LE encryption in general: it’s not secure anyways (see http://eprint.iacr.org/2013/309).