臨時綁定

這裏的綁定,不保存flash,掉電會丟失。  掉電保存用到device_manager。


綁定過程是否存在 取決於配對信息交換中是否設置了Bond標誌。


大部分的工作協議棧都做好了,上層要處理的就是設置一些 參數以及處理幾個事件。


步驟一:設置配對綁定參數

ble_gap_sec_params_t  g_pair_params;
void init_sec(void)
{
 g_pair_params.bond = 1;
 g_pair_params.io_caps = 0;
 g_pair_params.oob = 0;
 g_pair_params.mitm = 1;
 g_pair_params.min_key_size = 7;
 g_pair_params.max_key_size = 16;

 g_pair_params.kdist_own.enc = 1;
 g_pair_params.kdist_own.id = 0;
 g_pair_params.kdist_own.sign = 0;
 g_pair_params.kdist_peer.enc = 1;
 g_pair_params.kdist_peer.id = 0;
 g_pair_params.kdist_peer.sign = 0;
}

PS:

1、Bond 設置爲1表示需要綁定,則配對會存在綁定過程即LTK等祕鑰的分發。具體分發哪些祕鑰也是可以控制,這裏只說LTK,,所以下面的設置中只設置了相互分發長期祕鑰LTK,其他不需要設置。

2、之所以相互分發LTK是因爲,如果手機本次作爲主機連接了設備,設備作爲從機,配對綁定後斷開連接,當再次連接時如果手機依然是作爲主機去連設備,那麼加密時就需要  從機分發給手機的LTK。但是有的應用可能主從角色並不是固定的,下次可能 是設備作爲主機去連手機那麼 加密時 就需要上次綁定時 手機發給設備的LTK。 上面的情況我們設置了相互分發LTK,其實一般都是手機一直作爲主機去連設備,這種情況我們只需要g_pair_params.kdist_peer.enc = 1;就可以了。


步驟二:創建變量來存儲分發的祕鑰

配對會存在分發祕鑰過程,那麼協議棧交換的祕鑰存儲在哪裏?在綁定完成後返回給上層呢。返回的祕鑰就是存在 sd_ble_gap_sec_params_repl 的第四個參數keyset中,所以我們需要自己創建變量來存儲分發的祕鑰,因爲這隻用了LTK,所以其他兩個指針設置爲NULL就行了。

ble_gap_enc_key_t my_enc_key;

ble_gap_enc_key_t my_enc_key_center;

ble_gap_sec_keyset_t keyset;

void init_keyset(void){

       keyset.keys_peer.p_enc_key = &my_enc_key_center;

       keyset.keys_peer.p_id_key = NULL;

       keyset.keys_peer.p_sign_key = NULL;

       keyset.keys_own.p_enc_key = &my_enc_key;

       keyset.keys_own.p_id_key = NULL;

       keyset.keys_own.p_sign_key = NULL;           

}


步驟三:連接時觸發配對請求

case BLE_GAP_EVT_CONNECTED:

m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
egBTLinkState = LINK_CONN;
err_code =  sd_ble_gap_authenticate(m_conn_handle,&m_sec_params); 
APP_ERROR_CHECK(err_code);
break;


步驟四:收到主機配對請求,把自己的配對安全參數迴應給主機

case BLE_GAP_EVT_SEC_PARAMS_REQUEST:

     printf("receive pair req\r\n");

init_sec();
init_keyset();
err_code =  sd_ble_gap_authenticate(m_conn_handle,&g_pair_params); 
        APP_ERROR_CHECK(err_code);

break;


步驟五:打印passkey到串口,用戶輸入該配對碼

case BLE_GAP_EVT_PASSKEY_DISPLAY:

printf("show passkey: ");
for ( int i = 0; i < 6; i++)
printf("%c",p_ble_evt->evt.gap_evt.params. passkey_display.passkey[i]);

break;


這之後基本都是協議棧內部進行了,當綁定完成後上層會收到協議棧的BLE_GAP_EVT_AUTH_STATUS事件表示完成了祕鑰的分發。


步驟六:打印首次連接的祕鑰信息,和如果配對不成功直接斷開處理

case BLE_GAP_EVT_AUTH_STATUS:
printf("1LTK:");
for(int i = 0; i < my_enc_key.enc_info.ltk_len; i++)
{
printf("%x",my_enc_key.enc_info.ltk[i]);
        }
printf("\r\n");
printf("1AUTH:%d  ",my_enc_key.enc_info.auth);
        printf("1LTK_length:%d  ",my_enc_key.enc_info.ltk_len);
        printf("1EDIV:%x  ",my_enc_key.master_id.ediv);
        printf("1rand:");
        for(int i = 0; i < 8; i++)
{
         printf("%x",my_enc_key.master_id.rand[i]);
        }
        printf("\r\n");


if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
{
printf("pair success\r\n");
}
else
{
sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}
break;

到這裏配對綁定過程就結束了,前面說過綁定的目的是爲了下次鏈接需要安全鏈路時不再進行繁瑣的配對過程,所以一般手機和一個設備綁定過後,當下次再連接時都會直接用以前綁定時的LTK來發起加密請求。


我們在收到這個信息後打印了加密請求的一些信息,打印了我們回覆的LTK和請求的EDIV,RAND看是不是和上面綁定過程時分配的一樣。

case BLE_GAP_EVT_SEC_INFO_REQUEST:           
printf("LTK :");
for(int i = 0; i < my_enc_key.enc_info.ltk_len; i++)
{
printf("%x",my_enc_key.enc_info.ltk[i]);
}
printf("\r\nEDIV :%x  RANDOM:",p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv);
for(int i = 0; i< 8; i++)
{
printf("%x",p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.rand[i]);
}
printf("\r\n");
err_code=sd_ble_gap_sec_info_reply(m_conn_handle,  &(my_enc_key.enc_info), NULL, NULL);
APP_ERROR_CHECK(err_code);
break;





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章