nrf51822 --- 配对绑定输入密码(pair)

1.目的

    防止别的设备连上自己的蓝牙设备,可以使用配对

2.分析

   在实际应用中,经常用到配对,使指定设备连接

3.平台:

协议栈版本:SDK10.0.0

编译软件:keil 5.12

硬件平台:nrf51822最小系统

例子:E:\SDK10.0\examples\ble_peripheral\ble_app_hrs\pca10028\s110\arm4   //心率

4.步骤

 

int main(void)
{
    uint32_t err_code;
    bool erase_bonds;
    
    // Initialize.
    app_trace_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
    ble_stack_init();
    device_manager_init(erase_bonds);
    gap_params_init();
    advertising_init();
    services_init();
    sensor_simulator_init();
    conn_params_init();

	  //下面是添加设置配对密码
	  uint8_t *passcode="123456";
          ble_opt_t 	static_option;
	  static_option.gap_opt.passkey.p_passkey = passcode;
	  err_code =  sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &static_option);
	  APP_ERROR_CHECK(err_code);
	
    // Start execution.
    application_timers_start();
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

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

配对设置

#define SEC_PARAM_BOND                   1                                          /**< Perform bonding. */
#define SEC_PARAM_MITM                   1                                          /**< Man In The Middle protection not required. */
#define SEC_PARAM_IO_CAPABILITIES        BLE_GAP_IO_CAPS_DISPLAY_ONLY                       /**< No I/O capabilities. */
#define SEC_PARAM_OOB                    0                                          /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE           7                                          /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE           16                                         /**< Maximum encryption key size. */


<pre name="code" class="cpp">static void device_manager_init(bool erase_bonds)
{
    uint32_t               err_code;
    dm_init_param_t        init_param = {.clear_persistent_data = erase_bonds};
    dm_application_param_t register_param;

    // Initialize persistent storage module.
    err_code = pstorage_init();
    APP_ERROR_CHECK(err_code);

    err_code = dm_init(&init_param);
    APP_ERROR_CHECK(err_code);

    memset(&register_param.sec_param, 0, sizeof(ble_gap_sec_params_t));

    register_param.sec_param.bond         = SEC_PARAM_BOND;
    register_param.sec_param.mitm         = SEC_PARAM_MITM;
    register_param.sec_param.io_caps      = SEC_PARAM_IO_CAPABILITIES;
    register_param.sec_param.oob          = SEC_PARAM_OOB;
    register_param.sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
    register_param.sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
    register_param.evt_handler            = device_manager_evt_handler;
    register_param.service_type           = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;

    err_code = dm_register(&m_app_handle, &register_param);
    APP_ERROR_CHECK(err_code);
}


 


定义了一个配对请求事件。

static  dm_handle_t                      m_peer_handle;                                       /**< Identifes the peer that is currently connected. */
APP_TIMER_DEF(m_sec_req_timer_id);  
#define SECURITY_REQUEST_DELAY          APP_TIMER_TICKS(100, APP_TIMER_PRESCALER)  /**< Delay after connection until Security Request is sent, if necessary (ticks). */


static void timers_init(void)
{
    uint32_t err_code;

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

    // Create timers.
    err_code = app_timer_create(&m_battery_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                battery_level_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);
  err_code = app_timer_create(&m_heart_rate_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                heart_rate_meas_timeout_handler);
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_create(&m_rr_interval_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                rr_interval_timeout_handler);
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_create(&m_sensor_contact_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                sensor_contact_detected_timeout_handler);
    APP_ERROR_CHECK(err_code);
	//建立配对事件	
	 err_code = app_timer_create(&m_sec_req_timer_id,
                               APP_TIMER_MODE_SINGLE_SHOT,
                               sec_req_timeout_handler);
}

定义了多少个事件

#define APP_TIMER_OP_QUEUE_SIZE          5                                          /**< Size of timer operation queues. */

下面是配对事件回调函数

蓝牙连上设备产生DM_EVT_CONNECTION事件,然后启动配对事件app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL);

跳出输入密码对话框产生DM_EVT_SECURITY_SETUP事件,输入密码完然后按确定产生DM_EVT_SECURITY_SETUP_COMPLETE事件,如果密码正确产生DM_EVT_LINK_SECURED事件,密码错误产生DM_EVT_DEVICE_CONTEXT_DELETED事件,同时也会产生BLE_GAP_EVT_AUTH_STATUS里面状态会显示不成功,这个时候要看是否在连接着,如果连接着 并且密码错误,则断开。。

    

static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle,
                                           dm_event_t const  * p_event,
                                           ret_code_t        event_result)
{
    APP_ERROR_CHECK(event_result);
	 switch(p_event->event_id)
    {
        case DM_EVT_CONNECTION:
                m_peer_handle = (*p_handle);
                app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL);	
			break;
				case DM_EVT_DISCONNECTION:
					// dm_device_delete_all(&m_peer_handle);
					 break;
				case DM_EVT_SECURITY_SETUP :
					 break;
				case DM_EVT_SECURITY_SETUP_COMPLETE :
					  
					  break;
				case DM_EVT_DEVICE_CONTEXT_DELETED:
					// if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
					// {
					//   sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);		
					// }		         
					 break;
				case DM_EVT_LINK_SECURED:
					 break;
				default :
				 break;
		}
#ifdef BLE_DFU_APP_SUPPORT
    if (p_event->event_id == DM_EVT_LINK_SECURED)
    {
        app_context_load(p_handle);
    }
#endif // BLE_DFU_APP_SUPPORT

    return NRF_SUCCESS;
}

假如在应用中每次要求每次连接都产生输入密码,则需要dm_device_delete_all(&m_app_handle);这个每次在断开的时候,删除配对的信息,这样每次就会产生配对信息。。 但是,每次删除都会产生:DM_EVT_DEVICE_CONTEXT_DELETED事件。。。


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;
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
                                     //新添加代码
				    dm_device_delete_all(&m_app_handle);
            break;
         case BLE_GAP_EVT_AUTH_STATUS:                                                                                                                                    //如下是添加代码  配对密码是否匹配
      <span style="white-space:pre">	</span>       if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS)                                                                          sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);<span style="white-space:pre">		</span>
           break;
        default:
            // No implementation needed.
            break;
    }
}

实验:



是不是 密码配对框出来了。。。。。接下来输入密码正确可以正常连上 ,错误连接不上。。并且每次连上都素要密码。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页