BLE Just Works on nrf52832 and NRF Connect

Hi, I am working on something that requires me to use Just Works on nrf52832 custom board. Here is the work sccenario. under normal conditions, my module has a bonding PIN and the user is supposed to enter the PIN on his application to get data. My NRF module is a peripheral and i have enabled following in the prj.conf.


CONFIG_BT_NUS_SECURITY_ENABLED

CONFIG_BT_FIXED_PASSKEY

I have registered the necessary callbacks too.

What I now need to implement is a functionality which allows user to bond without a PIN temporarily after a button press. I assume BLE Just Works is what I need for this purpose. But I am open to any other suggestions or new perspectives to get this done.Thanks in advance.

Parents
  • Hi Midhunjac, 

    To be able to change the capability of the device to not have passkey (no display and keyboard) what you need to do is to 

    bt_conn_auth_cb_register() with NULL input to remove the callback. Then you recall the bt_conn_auth_cb_register() without the display or confirm or entry callback. 

    However we need to look at how you define your characteristics as well. Because in the characteristic definitions you also define the minimum level of security to access the characteristics. If you set it to requires MITM, having Just work bonding would not be enough to allow accessing the characteristics. 
    If it's the case you may want to reinitalize the characteristic with new parameter. 
  • I tried your suggestion but it didnt work. When I tried out what you suggested, the bonding failed. These are the logs.

    <inf>: Connected 68:4A:E9:DC:F3:BC (public)
    <wrn>: Security failed: 68:4A:E9:DC:F3:BC (public) level 1 err 4
    <inf> migration1: Pairing failed conn: 68:4A:E9:DC:F3:BC (public), reason 4
    <inf>: Disconnected: 68:4A:E9:DC:F3:BC (public) (reason 19)
    <inf>:Disconnected 68:4A:E9:DC:F3:BC (public) :
    I am sure it must be a mistake on my side. Can you please take a look at this ? Isn't this how you suggested that I do ? Just to make sure that we are not misunderstanding each other, I am using NCSv2.1.0 and for testing purposes, I have switched to the basic peripheral UART example. So the characteristics of that particular service applies now. What I am testing is if I can bond with the peripheral without a passkey. I am not trying to access any particular characteristic. I just want to bond with the peripheral straight away.

    /*some code*/
    err = bt_conn_auth_cb_register(NULL);
    err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    /* some code */
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    		.cancel = auth_cancel,
    
    };

    Tried adding the bt_conn_auth_cb_register() with the passkey display and passkey entry and passkey confirm callbacks set to NULL. That didnt work out too.

  • Hi Midhunjac, 

    Pairing failed reason 4 means: 

        /** The requested security level could not be reached. */
        BT_SECURITY_ERR_AUTH_REQUIREMENT,

    Could you give some more information on how you tested ? 

    - Which central device did you use ? 

    - How did you do the test, have you tried to remove the previous bond  ? I suspect that it may have something to do with that. You may need to call bt_unpair() or can simply do a chip erase and then reflash for testing. 

    - Please try to capture a sniffer trace of the bonding process.  We would need to see exactly what exchanged between the peers. 

  • Hi,

    my central device is my phone running the nrf connect android application. In the scanner page of the application, instead of clicking on the 'Connect' button, I click on the kebab icon on the connect button and it shows me an option to bond. I use that to check the bonding.
    Additionally, i just tried with the nrf52 dongle and the NRF Connect for desktop to bond. But when i try to bond with the device, this is what I get on the desktop app.

    Before I test, I erase and reflash the chip.
    Is my method of testing wrong? If so, how should I test ?

    16:23:22.682
    Connecting to device
    16:23:22.742
    Connected to device CD:DB:D6:42:56:FE: interval: 7.5ms, timeout: 4000ms, latency: 0
    16:23:22.826
    Phy updated for device CD:DB:D6:42:56:FE, tx: 2 Mb/s, rx: 2 Mb/s
    16:23:23.028
    Attribute value read, handle: 0x0B, value (0x): 4E-6F-72-64-69-63-5F-55-41-52-54-5F-53-65-72-76-69-63-65
    16:23:27.794
    Connection parameters updated for device CD:DB:D6:42:56:FE: interval 30ms, timeout 420ms, latency: 0
    16:23:40.674
    Authentication failed with status BLE_GAP_SEC_STATUS_UNSPECIFIED
  • Hi Midhunjac, 

    Please try capturing a sniffer trace of the process. 

    I attached here a quick example that I modified from the peripheral_uart sample, SDK v2.1.2. 

    If you press button 3 it will erase all bond. If you press button 4 it will switch the pairing response from supporting MITM to not supporting MITM ( no display , no keyboard, just work). If you want to have display capability again you would need to modify the code to have another button to enable that or just reset the board. 

    peripheral_uart_changebond.zip

  • Hi, i am working on the sniffer API. But I just wanted to let you know that the source code you provided did not work as expected. I tried in the v2.1.0 SDK as well as the 2.1.2. It behaved the same in both cases. When I press button 4, in you code, the device connects and then suddenly disconnects on its own.

    Is there any explanation for this behavior ?

    Also, can you please confirm if the code that you provided worked in the SDKv2.1.2. Are there any changes in this general area in the SDK V2.1.1 and above ?

Reply
  • Hi, i am working on the sniffer API. But I just wanted to let you know that the source code you provided did not work as expected. I tried in the v2.1.0 SDK as well as the 2.1.2. It behaved the same in both cases. When I press button 4, in you code, the device connects and then suddenly disconnects on its own.

    Is there any explanation for this behavior ?

    Also, can you please confirm if the code that you provided worked in the SDKv2.1.2. Are there any changes in this general area in the SDK V2.1.1 and above ?

Children
  • Hi Midhunjac, 
    I'm not sure if you need to do anything with the sniffer API. To run the sniffer you just need to copy it to wireshark folder and use Wireshark to capture. You don't need to work with the API directly. 
    Please make sure you erase bonding on the phone's side before testing. 

  • Hi, just wanted to provide an update here. I was working on this and I almost got what I wanted. By making the following changes, I could pair the DK with the nrf connect android application without problems

    /*<in prj.conf>*/
    CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y
    
    /*<in main.c>*/
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.passkey_display=NULL,
    	.passkey_confirm=NULL,
    	.cancel = auth_cancel,
    	.pairing_confirm=NULL,
    };

    And for the fixed passkey use case, the following changes were made

    /*in prj.conf*/
    CONFIG_BT_FIXED_PASSKEY=y
    CONFIG_BT_SMP=y
    
    
    /*<in main.c>*/
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.passkey_display = auth_passkey_display,
    	.passkey_confirm=NULL,
    	.cancel = auth_cancel,
    	.pairing_confirm=NULL,
    };
    unsigned int passkey = 123456;
    bt_passkey_set(passkey);

    The changes seem to do what I want (ALMOST. there are some issue described below) but I am not sure if these are the right methods. especially to get the Just Works working. Please advise me on that.

    As part of debugging, I went through the smp.c (C:\ncs\v2.1.0\zephyr\subsys\bluetooth\host\smp.c) and that is where I found the CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE configuration option inside the function update_keys_check( ).However, there are some issues here regarding the keys->flags in this function.

    1) When I reflash the device and load the program with the first set of attached changes, I get it all working fine with these logs. Please note that the keys->flags is 0 here.

    *** Booting Zephyr OS build v3.1.99-ncs1  ***
    ## starting mainStarting Nordic UART service example
    Bluetooth initializedConnected 66:53:DE:E0:64:51 (random)
    keys->flags is 0 and smp->flags is 536879924
    Pairing completed: 68:4A:E9:DC:F3:BC (public), bonded: 1
    

    2) next i reflash the device and load program with second set of attached changes and it works as I expected. Note that the keys->flags is 16.

    *** Booting Zephyr OS build v3.1.99-ncs1  ***
    ## starting mainStarting Nordic UART service example
    Bluetooth initializedConnected 66:53:DE:E0:64:51 (random)
    keys->flags is 16 and smp->flags is 536879932
    Pairing completed: 68:4A:E9:DC:F3:BC (public), bonded: 1
    

    3) If i reflash and load program with the first set of attached changes, it does NOT work as I expected it to (without passkey. it fails on its own). Note that the keys-> flags is now 17.

    ## starting mainStarting Nordic UART service example
    Bluetooth initializedConnected 68:4A:E9:DC:F3:BC (public)
    keys->flags is 17 and smp->flags is 536879924
    Pairing failed conn: 68:4A:E9:DC:F3:BC (public), reason 4Disconnected: 68:4A:E9:DC:F3:BC (public) (reason 19)

    What I do not understand is that test case 1 and 3 are the same yet has different values for the keys->flags and I believe this is the reason why I cannot get it correctly working in the third case. Since in the function update_keys_check(), these flags are checked against some conditions.

    I reflash using the Visual studio NRF extension. I erae bonding information in the application too.I believe erasing is part of the visual studio NRF extension and so, I expect the keys->flags to be set to 0 and then updated when a new connection comes to play. But I believe, the values are somehow overwritten. I am not sure if I am in the right direction here.

    NCS version : 2.1.0

    i am sorry for such long message. Can you please take a look at this for me ? Any help would be appreciated. Thanks in advance.

  • Hi Midhunjac, 

    To sum up what you described:

    - You have two binary images. One image supports Just work and the other image supports fixed passkey. 

    - When you flash the Fixed passkey to replace the Just work (step 2) it worked fine, you can make new bonding

    - When you flash the Just work back to replace the Fixed passkey it didn't work. 

    Please be aware that CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y only allow replacement of unauthorized (Just Work) bonding. So you can't replace bonding automatically if the bonding was done with Passkey. 

    You would need to clear the bond either by erasing the chip or by the application itself. To make sure you have erased the chip, please use nrfjprog (or nRF Connect for desktop) and erase the chip. In VS Code you need to click the one with 2 arrows on the right hand side not the icon next to the "Flash" text.


    Could you explain what you are trying to achieve ? I thought you want to have a button to allow new bond without passkey. This means one single image can handle Just Work and Passkey depends on the state of the button? 
    Do  you still have an issue with my example ? 

  • Hi, you are right about my final goal. I want a button press event to allow both Just Work and passkey states. But it does not work. The example that you provided also did not yield any success. The button press events are registered but it does not allow the Just Work method. The two separate images were just part of debugging, to get a better clarity.

    But the summary you derived is not quite right. I will make myself clear.

    • First I flash the Just Works image. It works fine. (No passkey,just bonded fine) (log 1)
    • Next i flashed the Fixed passkey image. It works fine too.(Prompted to enter passkey. If passkey is right, bonded) (log 2)
    • Finally, flash the Just Works image again. This time it does not work as it worked in the first iteration.(log 3)

    As for the extension in VS code, I had been using the icon next to "flash". Maybe that explains my observation in the above three iterations. I will give the icon you mentioned a try and see if the situation changes.

    Please be aware that CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y only allow replacement of unauthorized (Just Work) bonding. So you can't replace bonding automatically if the bonding was done with Passkey. 

    Can you please elaborate on this ? Or can you point me to a document which explains what this is and its application? This seems to do what I want but somehow it feels like this is not the right way to implement Just Works.

    Also, what is the correct way to get Just Works working ?My characteristics do not require any encryption at all yet Just Works does not seem to work. Thank you for the help.

  • Hi again, 

    You can read about the CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE here. For any KConfig configuration you can search there.

    Basically when you enable this option, it allow a device that you already bonded can make another bond. Just like what you did in Step 2 and 3. 
    However this option only allow overwriting when the previous bond is UNAUTHORIZED (Just work) At step 3 , the previous bond as Passkey so it not allowed to overwrite the bond without erasing it first. 

    Please try to test my example again and list how you tested it and what you observed. 
    My suggestion is: 

    - First use nRF Connect to connect and bond, you should see a passkey appear and you need to press button 1 on the board to confirm the pass key (numeric comparison)

    - Disconnect

    - Press button 3 to erase bond

    - Press button 4 to change mode

    - Use nRF Connect to connect, then bond. You will see a pop up asking to pair, but no passkey, you don't have to press anything on the DK , only on the phone. This is Just work pairing. 

    If you still have issue please try to capture the sniffer trace. You don't need to install the Sniffer API, just need to follow what in the documentation. 

Related