在nrf官方例程上添加如下功能:
一、在连接时请求配对;
二、配对密码设置为静态密码;
三、配对成功后进行绑定,下次连接时不需要再输入密码
参考博客:
点击打开链接
*****************************************************************************************************************************************************************************************分割线********************************************************
****************************************************************************************************************************
术语:中心设备:手机app
外围设备:开发板
1、在连接时外围设备向中心设备发送配对请求:
ble_gap_sec_params_t sec_params_auth;
sd_ble_gap_authenticate(m_conn_handle, &sec_params_auth);//向中心设备发送配对请求
2、中心设备收到配对请求后,向外围设备发送安全参数参数请求,外围设备收到安全参数请求后开始回复中心设备:
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);
ble_gap_sec_params_t sec_params;
sec_params.bond = 0; //°ó¶¨±êÖ¾£¬ÔÝʱ²»ÐèÒª°ó¶¨
sec_params.mitm = 1;//ÖмäÈ˱£»¤
sec_params.io_caps = BLE_GAP_IO_CAPS_DISPLAY_ONLY;
sec_params.min_key_size = 7;
sec_params.max_key_size = 16;
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &sec_params, NULL);
APP_ERROR_CHECK(err_code);
break;
当中心设备收到安全参数后,开始进行配对流程。接下来,通过调试助手来显示配对密码
case BLE_GAP_EVT_PASSKEY_DISPLAY:
SEGGER_RTT_printf(0, "passkey: %s\n",p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
break;
效果如下:
至此,我们的整个配对过程已经结束,现在配对过程使用的是动态密码,接下来我们需要设置使用静态密码。
在gap_params_init中添加如下代码,将静态密码设置为123456,其中密码都是以字符串的方式存储
ble_opt_t passkey_opt;
uint8_t passkey[] = "123456";
passkey_opt.gap_opt.passkey.p_passkey = passkey;
err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &passkey_opt);
APP_ERROR_CHECK(err_code);
最终效果如下
接下来需要设置绑定状态,设置绑定状态后,已经配对的设备下次进行连接时就不需要再次进行配对,而是直接请求外部设备分发密钥,进行链路的加密,设置如下:
配对参数初始化:
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;
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));
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;
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;
}
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);
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_GAP_EVT_PASSKEY_DISPLAY://½øÐÐÅä¶Ôʱ£¬ÏÔʾPIN
SEGGER_RTT_printf(0, "passkey: %s\n",p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
break;
case BLE_GAP_EVT_SEC_INFO_REQUEST://°ó¶¨³É¹¦ºó£¬Ã¿´Î½øÐÐÁ¬½Ó¾Í²»ÐèÒªÔÚ½øÐÐÅä¶Ô£¬¶øÊÇÖ±½ÓÇëÇóÃÜÔ¿
sd_ble_gap_sec_info_reply(m_conn_handle, &(m_own_enc_key.enc_info), NULL, NULL);
sec_params_display();
SEGGER_RTT_printf(0, "BLE_GAP_EVT_SEC_INFO_REQUEST\n");
break;
case BLE_GAP_EVT_AUTH_STATUS:
if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
{
SEGGER_RTT_printf(0, "pair success\n");
sec_params_display();
}
else
{
SEGGER_RTT_printf(0, "pair error\n");
}
最后,说一下蓝牙配对绑定的过程
1、外围设备向中心设备发送配对请求
2、中心设备收到请求后向外围设备发送配对参数请求;
3、外围设备向中心设备发送配对参数,并根据自己的IO能力显示配对码;
4、配对切绑定成功后,中心设备再次连接外围设备时就不会进行配对,而是直接申请密钥