藍牙設備端只能與指定APP連接

Date2015.2.1 Author:楊  QQ1209758756 <[email protected]> 

設備端與指定APP相連,即設備只能與自己開發的APP相連,而不能與別人所開發的APP相連。那麼,這個功能有什麼意義,它又是如何實現的呢?

 

原理:在應用層做一個連接密鑰,這個密鑰可以是數字或者是字母或者是兩者結合,比如:1234等。在設備與APP連接上時,在設備端開啓一個定時器,如果在定時器超時之前,收到APP發來雙方約定好的連接密鑰,那麼終止定時器,繼續保持連接狀態,否則斷開連接。

 

步驟:

1、 在main函數的timer_init()接口中,創建一個定時器,作爲連接密鑰的限定時間。

2、 在處理事件接口on_ble_evt()case BLE_GAP_EVT_CONNECTED分支中啓動定時器。

3、 在創建定時器時,在創建的超時處理函數中調用sd_ble_gap_disconnect斷開連接。如果在設定時間內沒有收到雙方約定的連接密鑰,則調用超時函數斷開連接。

4、 爲連接密鑰添加一個服務,這個服務用來向設備端寫入連接密鑰。

 

實現過程:

一、創建定時器。

1、 參照電池定時器,創建連接密鑰定時器。

#ifdefDEF_PASSWD_PAIR_TIMER

//Create passwd pairtimer

err_code = app_timer_create(&m_passwd_pair_timer_id,

                        APP_TIMER_MODE_SINGLE_SHOT,

                          passwd_pair_meas_timeout_handler);

APP_ERROR_CHECK(err_code);

#endif

 

2、 在處理事件接口on_ble_evt()的case BLE_GAP_EVT_CONNECTED分支中啓動定時器。

static voidon_ble_evt(ble_evt_t * p_ble_evt)

{

     uint32_t       err_code= NRF_SUCCESS;

 

 switch (p_ble_evt->header.evt_id)

    {

         caseBLE_GAP_EVT_CONNECTED:  

                                          

           #ifdefDEF_PASSWD_PAIR_TIMER           

            err_code = app_timer_start(m_passwd_pair_timer_id,PASSWD_PAIR_MEAS_INTERVAL,NULL);

            APP_ERROR_CHECK(err_code);

              #endif 

……

               

3、 添加定時器超時函數。

static voidpasswd_pair_meas_timeout_handler(void * p_context)

{

     uint32_t err_code;

     UNUSED_PARAMETER(p_context);

 

     if(m_conn_handle != BLE_CONN_HANDLE_INVALID)

    {               

err_code=sd_ble_gap_disconnect(m_conn_handle,  \

BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

           APP_ERROR_CHECK(err_code);

    }

}

 

 

二、創建服務

1、 以立即報警服務爲模板,創建連接密鑰服務。

static voidpwd_init(void)

{

uint32_t       err_code;

ble_pwd_init_tpwd_init_obj;

 

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

pwd_init_obj.pwd_evt_handler= on_pwd_evt;

 

err_code =ble_pwd_init(&m_pwd, &pwd_init_obj);

APP_ERROR_CHECK(err_code);

}

static void services_init(void)

{

     ……

#ifdef DEF_PASSWD_PAIR

     pwd_init();

#endif

}

 

nrf51822\Source\ble\ble_services中複製ble_ias.c,並命名爲ble_pwd.c

nrf51822\Include\ble\ble_services中複製ble_ias.h,並命名爲ble_pwd.h

ble_app_proximity工程中添加剛纔複製的兩個文件。

 

2、 修改各個文件及結構。

在ble_pwd.h和ble_pwd.c中,把所有ias替換成pwd;添加服務和特性可以模仿ble_ias.c和ble_ias.h。重點講一下如何添加服務和特性的uuid。

 

3、 添加服務、特性UUID

首先在nRFstudio中生成128位的uuid:打開nRFgo Studio—>在nRF8001 Setup菜單中,選擇Edit 128-bit UUIDs選項,點擊Add new。這就產生了一個隨機的UUID,可以用於定製服務中,新產生的基本UUID必須以數組的形式包含在源代碼中。16位的uuid可以是任意值。

爲了代碼可讀性,把數組定義成宏:
#define BLE_PWD_UUID_BASE  {0xDF,0xFE, 0xBE, 0x01, 0x54, 0xE7, 0x17, 0x17,               0x7B,0x44, 0x12, 0x95, 0x00,0x00, 0x49, 0x56}

#define BLE_UUID_PASSWD_PAIR_SERVICE                         0x1152  //隨便定義,但是不能與已使用的UID雷同

#define BLE_UUID_PASSWD_PAIR_CHAR                               0x1153  //隨便定義,但是不能與已使用的UID雷同

 

 

uint32_tble_pwd_init(ble_pwd_t * p_pwd, const ble_pwd_init_t *p_pwd_init)

{

uint32_t     err_code;

ble_uuid_t   ble_uuid;

ble_uuid128_t base_uuid = BLE_PWD_UUID_BASE;

        

 

err_code= sd_ble_uuid_vs_add(&base_uuid,&p_pwd->uuid_type);

if(err_code != NRF_SUCCESS)

     {

          return err_code;

      }

 

4、 在ble_evt_dispatch()中添加ble_ _pwd_on_ble_evt(&m_pwd,p_ble_evt)。

void ble_pwd_on_ble_evt(ble_pwd_t * p_pwd, ble_evt_t * p_ble_evt)

{        

switch(p_ble_evt->header.evt_id)

{                    

caseBLE_GATTS_EVT_WRITE;

on_write(p_pwd,p_ble_evt);

break;

 

default:

          // No implementation needed.

                break;

     }

}

 

當有寫入事件發生時,就調用這裏的on_write,然後觸發pwd_init()中的事件處理函數,如果寫入的值與預定義的值相同,則終止定時器,如果不同,則等待定時器超時。

 

5、驗證密鑰

static void on_pwd_evt(ble_pwd_t * p_pwd, ble_pwd_evt_t * p_evt)

{

              switch(p_evt->evt_type)

              {

                     caseBLE_PWD_EVT_PASSWD_PAIR_UPDATED:

                               //buzzer_set(1000);

                               pwd_signal(p_evt->params.passwd_pair_data);

                          break;

                    

                     default:

                               break;

              }

}

 

static void pwd_signal(uint8_t *passwd_pair_data)

{

if ( (*passwd_pair_data == (uint8_t)0x12) && \

(*(passwd_pair_data + 1) == (uint8_t)0x34) && \

(*(passwd_pair_data + 2) == (uint8_t)0x56) && \

              (*(passwd_pair_data+ 3) == (uint8_t)0x78) )                 

       {

              uint32_terr_code;

       

             

        // Stop timer ifrunning

        err_code = app_timer_stop(m_passwd_pair_timer_id);

        if ((err_code !=NRF_SUCCESS))

        {

            return;

        }

       }

}

 

 

因爲這個服務是模仿立即報警服務添加的,所以如果密鑰的長度大於一個字節,那個還需要做如下修改

typedef struct

{

  uint16_t                    handle;             /**< Attribute Handle. */

  uint8_t                     op;                 /**< Type of writeoperation, see @ref BLE_GATTS_OPS. */

 ble_gatts_attr_context_t   context;            /**<Attribute Context. */

  uint16_t                    offset;             /**< Offset for the writeoperation. */

  uint16_t                    len;                /**< Length of the incomingdata. */

  uint8_t                     data[4];            /**< Incomingdata, variable length. */ //根據密鑰長度來修改

} ble_gatts_evt_write_t;

 

typedef struct

{

    ble_pwd_evt_type_tevt_type;                        /**<Type of event. */

    union

    {

       uint8_t *passwd_pair_data;                            /**< passwd pairvalue. */

    } params;

} ble_pwd_evt_t;   //這個結構體是模仿立即報警服務自己添加的,但二者有區別

 

static void on_write(ble_pwd_t * p_pwd, ble_evt_t * p_ble_evt)

{

    ble_gatts_evt_write_t *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

 

    if((p_evt_write->handle == p_pwd->passwd_pair_handles.value_handle)&& (p_evt_write->len !=0))

    {

        // Alert levelwritten, call application event handler

        ble_pwd_evt_t evt;

 

        evt.evt_type           = BLE_PWD_EVT_PASSWD_PAIR_UPDATED;

        evt.params.passwd_pair_data= p_evt_write->data;

       p_pwd->pwd_evt_handler(p_pwd, &evt);

    }

//立即報警使用傳值的方式,而這裏使用傳指針

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