3.2 bonding连接OTA
我们在3.1节基础上,再加上bonding功能,以让ble_app_uart同时支持DFU和bonding。
1) 打开3.1节的工程
2) 添加如下文件:
3) 在main函数中添加peer_manager_init,定义如下:
static void peer_manager_init() { ble_gap_sec_params_t sec_param; ret_code_t err_code; err_code = pm_init(); APP_ERROR_CHECK(err_code); memset(&sec_param, 0, sizeof(ble_gap_sec_params_t)); // Security parameters to be used for all security procedures. sec_param.bond = SEC_PARAM_BOND; sec_param.mitm = SEC_PARAM_MITM; sec_param.lesc = SEC_PARAM_LESC; sec_param.keypress = SEC_PARAM_KEYPRESS; sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; sec_param.oob = SEC_PARAM_OOB; sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; sec_param.kdist_own.enc = 1; sec_param.kdist_own.id = 1; sec_param.kdist_peer.enc = 1; sec_param.kdist_peer.id = 1; err_code = pm_sec_params_set(&sec_param); APP_ERROR_CHECK(err_code); err_code = pm_register(pm_evt_handler); APP_ERROR_CHECK(err_code); }
然后将上面新出现的符号定义一一拷贝过来,这里不再赘述
4) 修改advertising_start定义,增加删除bonding信息功能(如果你不需要这个功能,也可以不改)
static void advertising_start(bool erase_bonds) { if (erase_bonds == true) { delete_bonds(); // Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event. } else { uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); NRF_LOG_DEBUG("advertising is started"); } }
5) 修改allow_repairing = true,这一步也是可选的。allow_repairing = true的好处是,当手机端的bonding信息被用户误删掉了,设备会允许这台手机的第二次配对bonding请求。如果allow_repairing = false,在这种情况下,就会拒绝手机的第二次配对请求,以提高安全性。
6) 在main.c文件开头,包含如下头文件:
#include "peer_manager.h"
7) 在ble_evt_handler中删除BLE_GAP_EVT_SEC_PARAMS_REQUEST分支,因为这个分支在peer_manager模块中已经进行处理了,这里再处理一次,会产生异常:
// 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); // APP_ERROR_CHECK(err_code); // break;
8) 将ble_nus.c文件从\components目录中拷出来,放在自己工程目录下,因为我们接下来需要对它进行修改,后续项目直接引用自己的ble_nus,而不要再引用components目录下的原始文件了。将TX characteristic的CCCD写属性从open改为加密,这样将自动触发手机端的bonding请求,修改代码如下:
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
9) 修改sdk_config.h文件,需要修改多个地方,如下:
#define PEER_MANAGER_ENABLED 1 #define FDS_ENABLED 1 #define NRF_SDH_BLE_SERVICE_CHANGED 1 #define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 0
请注意NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS可以为0,也可以为1,两种情况下,DFU成功后,bonding信息都可以保持。两者的区别是,当NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS为0,进入DFU模式后,bootloader将用普通模式跟手机相连,这种方式兼容性好,可靠性高,但安全等级稍低;当NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS为1时,bootloader将共享application的bonding信息,也就是说,哪怕进入bootloader模式,设备还是跟手机处于bonding状态,这种方式安全级别比较高,但容易产生兼容性问题,极端情况下,如果DFU过程中用户把手机端的bonding信息删除,系统将会变砖,而且无法恢复。推荐将NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS设为0,以获得最好的兼容性和可靠性。
如果你在应用中把NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS设为1,那么还需要添加ble_dfu_bonded.c文件,如下:
而且,如果NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS设为1,那么bootloader代码也就不能采用默认配置,请修改bootloader工程中的sdk_config.h如下宏定义,然后重新编译生成新的bootloader hex。
#define NRF_DFU_BLE_REQUIRES_BONDS 1 #define NRF_SDH_BLE_SERVICE_CHANGED 1
10) 在C/C++ define里面定义“BONDING_SUPPORT”宏。
11) 编译工程,将hex改为app.hex
12) 按照2.1节“nRF5 SDK v15.0.0 OTA”步骤来执行OTA过程,不过如下几点需要注意:
-
- 在nRF Connect中勾选“keep bond information”选项,如下:
-
- 当你使能CCCD的时候,手机将会自动与设备进行bonding,如下
-
- DFU升级成功后,设备将会与手机自动重连,此时需点击“Refresh services”,以获得设备最新服务列表,如下:
上述代码工程我已打包成:OTA_ble_app_uart_SDK15_0_0.rar,另外三种DFU模式对应的脚本,我也打成了包,其中没有bonding对应Script_SDK15_S132_NUS_NoBonding.rar,application单独bonding对应Script_SDK15_S132_NUS_Bonding_SUPPORTS_BONDS_0.rar,application和bootloader同时bonding对应Script_SDK15_S132_NUS_Bonding_SUPPORTS_BONDS_1.rar,请大家到百度云盘目录DFU\ble_app_uart中下载。代码工程解压缩到nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral这个目录下,就可以直接编译和运行。
回复于 2020-02-18 5#
块
导
航
举报
请选择举报类别
- 广告垃圾
- 违规内容
- 恶意灌水
- 重复发帖