NRF51 使用设备管理器实现配对绑定(教程翻译)

教程原地址: https://devzone.nordicsemi.com/tutorials/15/

如何使用nrf51开发工具包的设备管理器库来绑定和连接对端蓝牙设备。

下面来讲讲如何使用设备管理器(devicce manager)来存储和删除绑定信息。

配对是每个BLE设备的安全功能的初始交互,创建一个临时加密。

设备配对后,可以选择和继续绑定。绑定就是交换一个长期安全秘钥,它被存储起来以便之后重连和加密。

设备管理器做到这一点,是利用存储模块pstorage,将绑定信息存储进flash,这样即使重新启动信息也依然存在。假如你绑定的设备数量达到了你自己设定的最大绑定数量,那么设备管理器将弹出事件,然后你编程可以自行处理。处理此问题的一个例子:the github-example ble-peripheral-bond-handling.

本教程使用的模板:ble_app_template

下面进入正题:

1、添加设备管理库文件(device manage library)

在main.c中包含头文件 #include "device_manage.h"

将.c文件添加到项目中(device_manager_central.c 或者 device_manager_peripheral.c) 。文件在"..\sdk_0.9\components\ble\device_manager"  下面我们用从机(peripheral)来做作示例:

在c/c++选项中包含相应.h文件的路径。如下图:

注意有两个路径,第二个路径中有一个文件 device_manage_cnfg.h,该文件包含设备管理器的配置,可以在这里设置最大绑定数,连接,等等。

接下里我们还需要将一个设备管理器依赖的模块加入工程。

#include "pstorage.h"

..\..\..\..\..\..\components\drivers_nrf\pstorage

and

..\..\..\..\..\..\components\drivers_nrf\pstorage\config

在这里你可以找到 pstorage_platform.h 文件,该文件包含pstorage模块的配置信息。

2、代码初始化

我们要将 pstorage 加入系统事件调度器(system event dispatch)。调度器其实就是一个事件处理程序,它决定了发送事件到哪个处理函数和发送的顺序。改动 sys_evt_dispatch 的内容如下:

static void sys_evt_dispatch(uint32_t sys_evt)
{
    ble_advertising_on_sys_evt(sys_evt);
}

to:

static void sys_evt_dispatch(uint32_t sys_evt)
{
    pstorage_sys_event_handler(sys_evt); //Add this line
    ble_advertising_on_sys_evt(sys_evt);
}

接下来初始化设备管理器,将下列代码加入main.c中:

static dm_application_instance_t         m_app_handle;                              /**< Application identifier allocated by device manager */

/**@brief Function for handling the Device Manager events.
 *
 * @param[in] p_evt  Data associated to the device manager event.
 */
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);

    return NRF_SUCCESS;
}

/**@brief Function for the Device Manager initialization.
 *
 * @param[in] erase_bonds  Indicates whether bonding information should be cleared from
 *                         persistent storage during initialization of the Device Manager.
 */
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);
}

可以看到,设备管理器初始化函数中设置了连接参数。在上面的配对例程中,我们使用了下面的参数

#define SEC_PARAM_BOND         1                 /**< Perform bonding. */
#define SEC_PARAM_MITM          0                 /**< Man In The Middle protection not required. */
#define SEC_PARAM_IO_CAPABILITIES    BLE_GAP_IO_CAPS_NONE        /**< 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. */

DM_PROTOCOL_CNTXT_GATT_SRVR_ID : 作为服务器

接下来在main()函数中完成初始化。我们还需要初始化局部变量 erase_bonds,这种操作能够支持我们通过按下一个按钮或者类似的东西来擦除所有的绑定。如下:
bool erase_bonds;
device_manager_init(erase_bonds);//放在协议栈初始化之后

我们还需要在BLE调度器(BLE dispatcher)中注册设备管理事件处理程序:ble_evt_dispatch()函数修改部分具体如下:from:
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
    on_ble_evt(p_ble_evt);
    ble_conn_params_on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);

    /*
    YOUR_JOB: Add service ble_evt handlers calls here, like, for example:
    ble_bas_on_ble_evt(&m_bas, p_ble_evt);
    */
}

to:

static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
    on_ble_evt(p_ble_evt);
    ble_conn_params_on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);

    /*
    YOUR_JOB: Add service ble_evt handlers calls here, like, for example:
    ble_bas_on_ble_evt(&m_bas, p_ble_evt);
    */
    dm_ble_evt_handler(p_ble_evt); //Add this line
}打开主控制面板(Master Control Panel)MCP并检查我们的新设备管理连接的功能。在编译和下载我们的工程之后,我们可以看到LED1在闪烁,这表明设备正在广播。我们也可以使用MCP连接它,这时观察到LED1的闪烁变为常亮。但是,当我们试图和它进行配对和绑定,这会让我们遇到麻烦,它会拒绝绑定然后重新返回到广播状态由于原始代码已经实现了手动配对,因此我们做了两次相同的事情,一次手动,一次使用设备管理器,这就是导致错误的原因。我们希望配对和绑定由设备管理器处理,我们可以将 on_ble_evt 处理程序更改为:
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;

        default:
            // No implementation needed.
            break;
    }
}

虽然教程上是这么写的,不过我们实际使用的时候一般会加多一条断开连接处理,经过验证这种写法是不会影响连接和绑定的,如下:
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;      AdvertisingStart();      break;
        default:
            // No implementation needed.
            break;
    }
}
现在我们可以使用MCP或者BLE手机与设备自由连接和绑定。请注意,在未连接时设备处于广播状态,LED1闪烁,在连接时LED1常亮。请注意,如果您对开发工具包(development kit)进行配对绑定,断开后重新连接时不需要再次进行绑定就能够获得加密的连接。这就是设备管理器的好处。



 
				
时间: 2024-11-04 20:08:28

NRF51 使用设备管理器实现配对绑定(教程翻译)的相关文章

NRF51822配对绑定要点

NRF51822配对绑定要点: 当手机发来配对请求,协议栈触发事件 BLE_GAP_EVT_SEC_PARAMS_REQUEST,将事件传送到设备管理器事件处理函数中: dm_ble_evt_handler() 该事件处理函数在ble_evt_dispatch()中注册. 在对该事件的处理中,需要调用回复API回复配对参数 sd_ble_gap_sec_params_replysd_ble_gap_sec_params_repl 的第三个参数g_pair_params参数就是要回复的配对绑定参数

Android Device Administration 设备管理器——一键锁屏的实现

Android Device Administration 设备管理器--锁屏的实现 最近研究了一下安全这一块的内容,当然,我是比较水的,所以也拿不出什么好知识点,但是有一些冷门的东西我还是可以聊聊的,就拿这个锁屏来说吧,我们现在市面上有一些一键锁屏的软件 我们可以看到,是数不胜数的,所以,其实他一开始使用的时候,都需要请求设备管理器 我们可以看到,只有当我们激活的时候,我们才可以使用它,那么,他到底是什么东西呢?其实,当我们激活之后,我们可以在我们手机的设置--安全--设备管理器里面看到他的所

每次插入U盘等设备都找不到,设备管理器中卸载 ,再扫描检测硬件改动才可以正常问题解决方法

每次插入U盘等设备都找不到,设备管理器查看通用串行总线控制器 点黄色叹号设备 右键 卸载 ,再扫描检测硬件改动 就可以正常问题 解决方法:进入注册表,开始运行中 输入regedit  回车 点击HKEY_LOCAL_MACHINE----------SYSTEM-----------CurrentControlSet-------------Control-----------Class Class项底下找到'通用串行总线控制器'这项,看右面窗口里发现有'upperfilter'或'lowerf

WIN2008访问设备管理器提示:由于您在远程计算机上运行设备管理器……的解决方案

原博客会员wosiyin反映,使用WIN2008,通过我的电脑右键访问设备管理器时提示:由于您在远程计算机上运行设备管理器,设备管理器在只读模式中运行.要卸载设备或改变设备属性或驱动程序,必须在要进行改动的计算机上运行设备管理器.问题,如下图: 但是通过开始,运行,输入:mmc compmgmt.msc访问则正常: 经过一番百度发现,该问题是由于计算机名过长导致的,解决方法很简单,把计算机名改短一点就正常了! 事实上我很好奇,这计算机名得有多长啊? 原文连接:http://goxia.mayti

设备管理器进行锁屏和数据清除等功能

1.首先创建一个类DeviceAdminSample继承DeviceAdminReceiver(android.app.admin.DeviceAdminReceiver),作为接收广播信息的处理类(其实不用实现,主要内部也是维护了DevicePolicyManager类的实例,主要操作的功能是这个类的内部方法实现的) package com.example.deviceadmi; import android.app.admin.DeviceAdminReceiver; import andr

等待超时,请打开设备管理器查看苹果驱动是否正常!

爱思助手,查询SHSH驱动问题 先把数据线插上,右键点击我的电脑→设备管理器→通用串行总线控制器找到Apple Mobile Device USB Driver,然后右键点击它,选择 ”更新驱动程序”,按照提示更新:然后右键点击我的电脑→管理→服务和应用程序→服务,然后把“请看图片”三项服务设置为启动!弄完后,拔掉数据线,重新插上.然后刷机试试.我出现驱动错误就是这样弄的,每次都成功.希望你们也成功.如果还是不行的话就我也没办法了!!  如果按照楼主提供的操作还是不行的话,那么就只能证明了是主板

Android设备管理器&mdash;&mdash;DevicePolicyManager

自从安卓2.2(API=8)以后,安卓手机是通过设备管理API对手机进行系统级的设备管理. 本篇通过大家熟悉的"一键锁屏"的小项目实现来介绍设备管理API如何通过强制设备管理策略创建一个安全敏感的应用程序. 一键锁屏的实现原理:当按锁屏键的时候,会发出一个广播,当用户界面接收到一个广播的时候就可以实现锁屏.而广播的发送是我们调用DevicePolicyManager(设备管理接收者)中的lockNow()方法来实现. 锁屏需要将应用程序提升为系统管理员的权限,如果当前的应用具备系统管理

Android设备管理器漏洞2--禁止用户取消激活设备管理器

2013年6月,俄罗斯安全厂商卡巴斯基发现了史上最强手机木马-Obad.A.该木马利用了一个未知的Android设备管理器漏洞(ANDROID-9067882),已激活设备管理器权限的手机木马利用该漏洞,能够在设置程序的设备管理器列表中隐藏,这样用户就无法通过正常途径取消该手机木马的设备管理器权限.从而达到无法卸载的目的.Android4.2版本号以上系统已经修复该漏洞.(漏洞详情:http://blog.csdn.net/androidsecurity/article/details/9124

启动设备管理器

/** * 激活设备管理器 * * @param context * 上下文对象 */ public static void activeApp(Context context) { if (context instanceof Activity) { activeApplication(context); } else { Intent in = new Intent(context, StartDeviceManagerActivity.class); in.addFlags(Intent.