临时绑定

这里的绑定,不保存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;





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值