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

Double pairing request with android

I am testing several phones with a specific App that I connect to my nRF52832. Some phones pair nicely but others do not pair as expected. They display two pairing requests.

- I have checked that my BLE device only sends one pairing request which is the case
- I tried increasing the PM_HANDLER_SEC_DELAY_MS and also setting it to zero but in both cases we would still get two pairing requests

- I allow repairing of already bonded peers

- As described here: https://devzone.nordicsemi.com/f/nordic-q-a/76912/double-pairing-prompt-in-android this behavior might be due to having several services and being peripheral. In my setting the nRF acts as central and connects to the phone which is in peripheral role. Then the phone exposes services as server which the nRF discovers as client. The nRF also exposes services. 

What could be the reason we get two pairing requests with some android phones?

When I log the connection trace I get the following messages:

Parents
  • Hi 

    Do you have access to a Bluetooth sniffer in order to sniff the communication occurring over the air?
    Then it is much easier to figure out what is happening in the background. 

    Even without an expensive high end sniffer (Ellisys, FrontLine etc) it is possible to use a Nordic devkit as a cheap Bluetooth sniffer, as explained here

    In the mean time I will check with our Android developers if this is a known issue. 

    Best regards
    Torbjørn

  • Thank you for your response.

    I do use the nRF Dongle with wireshark as a sniffer tool. The problem is that because I am using LESC the sniffer cannot follow the encrypted connection. I read that both devices would need to be in "Secure Connections debug mode" (https://infocenter.nordicsemi.com/index.jsp?topic=%2Fug_sniffer_ble%2FUG%2Fsniffer_ble%2Fsniffing_actions.html)

    However, I cannot put the android device into secure connections debug mode as far as I know? Maybe I will need to use the android debugging capabilities?

  • Hi 

    Is there any chance you could disable LESC while testing and just use legacy pairing instead?

    Normally LESC will only be enabled if both sides of the link state that they support it, and on the Nordic side it is up to the application to decide if LESC should be supported. 

    Best regards
    Torbjørn

  • That's a great idea!

    I did it and received the wireshark traces that you can see in the appended link.

    I see the following:

    1. my device sends a "Pairing Request (0x01)"   --> first pairing dialogue on smartphone pops up

    2. wait 10s then press the pair button on smartphone ---> I receive "Pairing Response" and send 4 times "Pairing Confirm" ----> at this moment the second pairing dialogue pops up on the phone.

    3. wait 10s then press the second pair button --> get the "Rcv Pairing Confirm", send the "Pairing Random", get the "Rcv Pairing Random"  --> then bonding is done

    So apparently after sending 4 times "Pairing Confirm" we get the second pairing indication on the phone. but it is not clear if its due to this or due to another event in the pairing state machine.

    wireshark trace of the Redmi ewo:

    https://drive.google.com/file/d/1omdrNM8MlJ6l_DgfnMGKoqzZs6Q-4TLd/view?usp=sharing

    I also added the trace from android studio (just the messages from a phone that works and one that doesn't)

    https://drive.google.com/file/d/1nGj32Nk88dclEgrVoJe9N9R9UY_i8PRI/view?usp=sharing

     

  • Hi 

    Thanks a lot for the trace. 

    It seems all the encryption operations are taking a lot of time for some reason.  

    The delay between the Pairing request and response makes sense, since you need to press the button in the app, but after that I would expect things to speed up. 

    Also, the connection settings are quite slow (100ms connection interval, and 4 slave latency), which is why the phone has to retransmit the pairing confirmation for half a second before the peripheral wakes up again. 

    Is there any way you could try to use more aggressive connection parameters after connection, to speed up encryption and service discovery?
    It is quite common to start out with ~50ms connection interval and 0 slave latency for the first minute or so, to speed up the initial connection process. Once you are bonded this is no longer needed, since you don't need to redo service discovery. 

    Best regards
    Torbjørn

  • - The encryption operations are taking so long because I wait 10s before pressing "pair" on the phone at every pair request to see what triggers the second pair request.

    - I also tested with parameters of 30ms interval and 0 slave latency but this does not make a difference. But I will try to go down as low as 7.5ms with the interval to see if it makes a difference.

    After a test with the nRF Connect Desktop BLE Application where I also received two pairing requests with "just works" LESC bonding I now think this is standard behaviour for "Just Works" pairing on some android phones. What I also observed is that when using for example passkey entry or passkey comparison pairing method the phone also gets two pairing requests. One without any passkeys and the second one with the key comparison/entry dialogue. 

    I think when I do not need to compare keys or similar I still get a dialogue, just without anything.

    But I don't know how to find a workaround from my side to prevent this

  • Hi 

    I found an old case which seems to discuss the same issue, but it doesn't seem like a solution was found unfortunately. 

    Most of the Android expertise is also on holiday, just to complicate it further ;)

    Tomorrow I will do some testing with the phones I have available here, trying to figure out what the difference is between phones that show this issue and those that don't. Hopefully that can give some more clues. 

    Best regards
    Torbjørn

Reply
  • Hi 

    I found an old case which seems to discuss the same issue, but it doesn't seem like a solution was found unfortunately. 

    Most of the Android expertise is also on holiday, just to complicate it further ;)

    Tomorrow I will do some testing with the phones I have available here, trying to figure out what the difference is between phones that show this issue and those that don't. Hopefully that can give some more clues. 

    Best regards
    Torbjørn

Children
  • Ok thank you.

    You can try with the nRF Desktop App Bluetoot Low Energy Application. There just connect to a Samsung (also double request) or Pixel phone. Then bond and specify "no keyboard, no display" to use "just works" (parameters as specified here). The phone should show two pairing requests.

  • Hi

    Have you been able to reproduce the issue based on one of the standard SDK examples?

    As an example, should I be able to use the ble_app_hrs_c example on the nRF5 side, and set up the peripheral on the phone in the nRF Connect app?

    I tried this without being able to reproduce the issue, but at the moment I am testing on my own Huawei P20 Pro, which might behave differently compared to the Samsung and the Pixel you have tested with. 

    Best regards
    Torbjørn

  • Hi,

    I have tested the ble_app_hrs_c with the Samsung Galaxy A51 and the Redmi 8 which had the double pairing request problem with my nRF device.

    -> They both show the same behaviour with a double pairing request in the nRF Connect App. 

    Can we therefore conclude that its a problem in the BLE stack of these phones?

  • Hi

    I am pretty sure this is an issue on the Android side, yes. 

    I guess the question now is whether or not a workaround exists. Some times it is possible to avoid issues like this by changing something in the sequence of events after establishing a connection, which the central device might be able to influence. 

    Best regards
    Torbjørn

  • what I do is to bond immediately when a new device that I connected to is found with the function below. do you see an issue with that?

    ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing)
    {
        VERIFY_MODULE_INITIALIZED();
    
        ret_code_t err_code;
    
        err_code = sm_link_secure(conn_handle, force_repairing);
    
        if (err_code == NRF_ERROR_INVALID_STATE)
        {
            err_code = NRF_ERROR_BUSY;
        }
    
        return err_code;
    }

Related