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

How can I bond with central device only one time?

Hi,

     This is my first time to use Nordic product and I have used nRF52832 based SDK 12.0 and SoftDevice132 v2.0 about 2 months. And the IDE used for devlopment is KEIL MDK.

In my project, I do paring operation configured with static passkey and enable bond. The problem is that after every time I reset nRF52832, my smart phone using andriod system will be asked to input static passkey again when want to connect the nRF52832.

And I used 5 days to search research usefully referrence document in Chinnese website,unfortunately I can not find any useful informations about the problem in China. So,finally I can not solve the problem by self.

I do not know the detailed operations about how to paire and bond with a BLE central device like a smart phone using andriod system only one time until now, even if nRF52832 will be reset we do not need to do bonding operations again.

So, I think I need your useful help to guide me the forever bond operations step by step, as more detailed as possible, when a project need security connectivity like paire operations.

Thanks & Cheers.

The following is my key code about the configure paire and bond operations in my project.


ble_gap_sec_params_t m_sec_params;
ble_gap_sec_keyset_t m_sec_keyset;

ble_gap_enc_key_t m_own_enc_key; //need to be stored in flash
ble_gap_enc_key_t m_peer_enc_key;

static void sec_params_init()
{
memset(&m_sec_params, 0, sizeof(ble_gap_sec_params_t));

//Initialize m_sec_params
m_sec_params.bond = 1;
m_sec_params.mitm = 1;
m_sec_params.io_caps = BLE_GAP_IO_CAPS_DISPLAY_ONLY;
m_sec_params.min_key_size = 7;
m_sec_params.max_key_size = 16;

m_sec_params.kdist_own.enc = 1;
m_sec_params.kdist_own.id = 0;
m_sec_params.kdist_own.sign = 0;

m_sec_params.kdist_peer.enc = 1;
m_sec_params.kdist_peer.id = 0;
m_sec_params.kdist_peer.sign = 0;

memset(&m_sec_keyset, 0, sizeof(ble_gap_sec_keyset_t));
//Initialize m_sec_keyset
m_sec_keyset.keys_own.p_enc_key = &m_own_enc_key;
m_sec_keyset.keys_own.p_id_key = NULL;
m_sec_keyset.keys_own.p_pk = NULL;
m_sec_keyset.keys_own.p_sign_key = NULL;

m_sec_keyset.keys_peer.p_enc_key = &m_peer_enc_key;
m_sec_keyset.keys_peer.p_id_key = NULL;
m_sec_keyset.keys_peer.p_pk = NULL;
m_sec_keyset.keys_peer.p_sign_key = NULL;
}

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;

switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:

err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

err_code = sd_ble_gap_authenticate(m_conn_handle,&m_sec_params);
APP_ERROR_CHECK(err_code);

break;

case BLE_GAP_EVT_DISCONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
break;

case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
// err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
// APP_ERROR_CHECK(err_code);
sec_params_init();
err_code = sd_ble_gap_sec_params_reply( m_conn_handle,
BLE_GAP_SEC_STATUS_SUCCESS,
&m_sec_params,
&m_sec_keyset);
APP_ERROR_CHECK(err_code);

break;

case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;

case BLE_GAP_EVT_AUTH_STATUS:
if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
{
printf("\r\npair success!!!\r\n");
}
else{
printf("\r\npair failed!!!\r\n");
sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}

case BLE_GAP_EVT_PASSKEY_DISPLAY:
printf("\r\npasskey: %s\r\n",p_ble_evt->evt.gap_evt.params.passkey_display.passkey);

case BLE_GAP_EVT_SEC_INFO_REQUEST:
sd_ble_gap_sec_info_reply(m_conn_handle, &(m_own_enc_key.enc_info), NULL, NULL);
printf("BLE_GAP_EVT_SEC_INFO_REQUEST\n");
break;

default:
// No implementation needed.
break;
}
}

static void gap_params_init(void)
{
uint32_t err_code;
ble_gap_conn_params_t gap_conn_params;
ble_gap_conn_sec_mode_t sec_mode;

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

err_code = sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *) DEVICE_NAME,
strlen(DEVICE_NAME));
APP_ERROR_CHECK(err_code);

memset(&gap_conn_params, 0, sizeof(gap_conn_params));

gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
gap_conn_params.slave_latency = SLAVE_LATENCY;
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;

err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
APP_ERROR_CHECK(err_code);


uint8_t passkey[] = "123456";
m_static_pin_option.gap_opt.passkey.p_passkey = passkey;

err_code=sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_static_pin_option);
APP_ERROR_CHECK(err_code);
}

int main(void)
{
uint32_t err_code;
bool erase_bonds;

// Initialize.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);


uart_init();

buttons_leds_init(&erase_bonds); //button 1(@pcb key2,pin14) is used as delete bonding information
ble_stack_init();

gap_params_init();

services_init();
advertising_init();
conn_params_init();

printf("\r\nUART Start!\r\n");
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);

// Enter main loop.
for (;;)
{
power_manage();
}
}

Parents
  • Hi Tianfei, 

    It's hard to tell what could be wrong here. But have you made sure you managed to bond on the first connection ?  If you test with nRFConnect do you see the status change to "Bonded" ?

    Do you have a particular reason of handling the bonding process on your own without using the peer manager library ? You can find the library used in most of our example in the SDK\example\ble_peripheral\ folder. I would suggest you to try the ble_app_proximity example. 

  • Dear Hung Bui,

            When testing and debuging the code, I used the nRFConnect  software in my smart phone. Everytime after I entered the satic key in my smartphone, the nRFConnect  shows bonded. And after disconnect with nRF52832, when I connect nRF52832 again, it will not need any pairing operations. 

            But every time I reset nRF52832, when my smart phone connect nRF52832, the phone also need to carry out pairing and bonding operations.

           The "ble_app_proximity " example I have refered in last week and I found it do not use static key when pairing. So this example can not solve my puzzled problem. 

    Thanks very much for your help.

    Best regards,

    Tianfei

  • Hi Tianfei, 

    If you want passkey you can try the ble_app_gls example. If you want static passkey you would need to modify that example. 

    It seemed that you didn't store bond information to flash. That's why when you restart the board you would need to do bonding again. Storing and managing bond information are handled by the peer manager library. We strongly suggest you to use the library.

    If you want to implement that on your own, you need to follow this message sequence chart.  You need to store and restore the ediv, LTK to flash. 

  • Dear Hung Bui,

             Actually I deeply realized there are some variables or parameters needed to be stored in flash when I modified my code, but I really do not konw which variables needed to be stored in flash and how to store them?I do not konw the detailed step to store them in order to achieve the goal of my project. 

           I think I need your company the related official guide documents and related examples which can teach me how to implement the function step by step.

    Thanks very much for your help.

    Best regards,

    Tianfei

Reply
  • Dear Hung Bui,

             Actually I deeply realized there are some variables or parameters needed to be stored in flash when I modified my code, but I really do not konw which variables needed to be stored in flash and how to store them?I do not konw the detailed step to store them in order to achieve the goal of my project. 

           I think I need your company the related official guide documents and related examples which can teach me how to implement the function step by step.

    Thanks very much for your help.

    Best regards,

    Tianfei

Children
  • Hi Tianfei, 

    You would need to follow the message sequence chart that I provided you. 

    I still don't understand why you dont use our library ? Have you tried examples we provided in the ble_peripheral example folder ?

  • Dear Hung Bui,

             Actually I have read and modified your company provided ble_peripheral examples like "ble_app_hrs" and "ble_hid_keyboard" , but I failed although I have tried many times to modify the examples in order to implement the functionality I wanted. 

            I think the reason I failed is that I do not understant all the steps which the static passkey and bonding functionality need at all.

           But in my opinion, I think the code of your examples is too complex and difficult to understand for a freshhand. Especially the wanted functionality your provided examples do not owning, the modified works will become difficult because we do not know the specific and detailed steps when lacking of the official guidance document. So it will result in the longer period for a company to develop a product when using nRF52832.

            All the provided ble_peripheral examples do not use static passkey meanwhile using bonding. Besides that I do not know how to use your library at all and all the steps when I want the nRF52832 own static passkey and bonding functionality?

           Best regards,

           Tianfei

  • Hi Tianfei, 

    Have you tried this example ? It has support for passkey bonding. 

    I understand that the learning curve to get started with Nordic would be steep. We tried our best to make it's easier for you but since there are more and more features need to be supported making the library getting more complex and would need some study before you can use it. 

    The best source for study I would say is by having a look at the message sequence chart, and reading the documentation of the functions provided in our library and of course the documentation on info center. 

  • Dear Hung Bui,

           In the past few days, I have been learning the infocenter's instructive documents which you provied for me. Because of my poor English, the learning progress is slow. I consider much more days will be hoped for me to understand the library's architecture before I can use it.

           Many thanks for your kind help. 

           Best regards,

           Tianfei

  • Dear Hung Bui,
             After reading your provided documents, I have resolved the problem which I posted at the first time by adding some codes as following, but without using the peer manager.


    #define MY_ENC_INFO_ADDR (0x70004)
    uint32_t * const p_dst=(uint32_t *)MY_ENC_INFO_ADDR;
    uint8_t  read_flash_flag=0;

    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t err_code;

        uint8_t i;
        uint8_t static temp[50];
        uint8_t static *p_temp=(uint8_t *)(&(m_own_enc_key.enc_info));

        memset(temp, 0, sizeof(temp));

       switch (p_ble_evt->header.evt_id)
       {
            case BLE_GAP_EVT_CONNECTED:
                     err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                     APP_ERROR_CHECK(err_code);
                    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                    err_code = sd_ble_gap_authenticate(m_conn_handle,&m_sec_params);
                    printf("\r\nexecute sd_ble_gap_authenticate()\r\n");
                    APP_ERROR_CHECK(err_code);
                    break;

            case BLE_GAP_EVT_DISCONNECTED:
                    err_code = bsp_indication_set(BSP_INDICATE_IDLE);
                    APP_ERROR_CHECK(err_code);
                    m_conn_handle = BLE_CONN_HANDLE_INVALID;
                    break;

            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                  sec_params_init();
                  err_code = sd_ble_gap_sec_params_reply( m_conn_handle,
                                                                                              BLE_GAP_SEC_STATUS_SUCCESS,
                                                                                              &m_sec_params,
                                                                                              &m_sec_keyset);
                  printf("\r\nexecute sd_ble_gap_sec_params_reply()\r\n");

                  APP_ERROR_CHECK(err_code);
                  break;

          case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                  // No system attributes have been stored.
                 err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                 APP_ERROR_CHECK(err_code);
                 break;
         case BLE_GAP_EVT_AUTH_STATUS:       

              if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status==BLE_GAP_SEC_STATUS_SUCCESS)           {
                    printf("\r\npair success@case BLE_GAP_EVT_AUTH_STATUS!!!\r\n");

                    if(0==read_flash_flag){
                          for(i=0;i<BLE_GAP_SEC_KEY_LEN;i++){
                                   printf("\r\n@case BLE_GAP_EVT_SEC_PARAMS_REQUEST,                            

                                   m_own_enc_key.enc_info.ltk[%d]=0x%X\r\n",i,m_own_enc_key.enc_info.ltk[i]);
                           }

                           p_temp=(uint8_t *)(&(m_own_enc_key.enc_info));
                           for(i=0;i<sizeof(ble_gap_enc_info_t);i++){
                                   temp[i]=*p_temp++;
                                   printf("\r\ntemp[%d]=%d \r\n",i,temp[i]);
                                   SEGGER_RTT_printf(0,"\r\ntemp[%d]=%d \r\n",i,temp[i]);
                            }
                           while((err_code=sd_flash_write(p_dst,(uint32_t *)temp,5))==NRF_ERROR_BUSY); 


                           printf("\r\nsd_flash_write(),return value is %d \r\n",err_code);
                            read_flash_flag=1;
                      }
            }
           else{
                  printf("\r\npair failed@case BLE_GAP_EVT_AUTH_STATUS!!!\r\n");
                  sd_ble_gap_disconnect(m_conn_handle,                

                                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            }

        case BLE_GAP_EVT_PASSKEY_DISPLAY:
                // printf("\r\npasskey: %s\r\n",p_ble_evt->evt.gap_evt.params.passkey_display.passkey);

        case BLE_GAP_EVT_SEC_INFO_REQUEST:
             printf("\r\n@case BLE_GAP_EVT_SEC_INFO_REQUEST\r\n");
             sd_ble_gap_sec_info_reply(m_conn_handle, &(m_own_enc_key.enc_info), NULL, NULL);

             for(i=0;i<BLE_GAP_SEC_KEY_LEN;i++){
                         printf("\r\n@case BLE_GAP_EVT_SEC_INFO_REQUEST,

                                    m_own_enc_key.enc_info.ltk[%d]=0x%X\r\n",i,m_own_enc_key.enc_info.ltk[i]);
             }
             break;
       default:
       // No implementation needed.
            break;
       }
    }

    int main(void)
    {
    uint32_t err_code;
    bool erase_bonds;
    uint8_t i;
    uint8_t *p_flash=(uint8_t *)MY_ENC_INFO_ADDR;

    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
    uart_init();
    buttons_leds_init(&erase_bonds);
    ble_stack_init();

    gap_params_init(); //including configuring static key.
    services_init();
    advertising_init();
    conn_params_init();

    printf("\r\nUART Start!\r\n");
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

    #ifdef RTT_DEBUG_EN
    SEGGER_RTT_Init();
    #endif

    if(*p_dst!=0xffffffff){
        m_own_enc_key.enc_info=*((ble_gap_enc_info_t *)MY_ENC_INFO_ADDR);

        for(i=0;i<BLE_GAP_SEC_KEY_LEN;i++){
              printf("\r\n@program initialize, m_own_enc_key.enc_info.ltk[%d]=0x%X\r\n",

                          i,m_own_enc_key.enc_info.ltk[i]);
        }
        read_flash_flag=1;
    }
    else{
        read_flash_flag=0;
    }

    for (;;)
    {
       nrf_delay_ms(7000);
       p_flash=(uint8_t *)MY_ENC_INFO_ADDR;


       for(i=0;i<sizeof(ble_gap_enc_info_t);i++){
             SEGGER_RTT_printf(0,"flash address 0x%X is 0x%X \r\n",MY_ENC_INFO_ADDR+i,*(p_flash));
             p_flash++;
       }
       SEGGER_RTT_printf(0,"**************The end**************\r\n\r\n\r\n");
       power_manage();
     }
    }

              But now I have found a new problem. When I use the function "sd_flash_write()", I find it can only write the same flash address one time,if you want to use the function to write the same address of flash again ,the operation will take no effect, eventhough I have changed the value which will be written to flash. But meanwhile the return value is NRF_SUCCESS, the result makes me very confused.

              I do not know what's the reason of me in using the function "sd_flash_write()" to execute storing some datas in flash. Wish you can give some useful guidance.

    Thanks very much for your help.
    Best regards,
    Tianfei

Related