蓝牙协议栈:simplelink_cc2640r2_sdk_1_40_00_45

IAR版本:IAR for ARM 8.11.3

开发板:CC2640R2F

蓝牙版本:BLE4.2

配对模式:PasscodeEntry 密码输入模式

主机端仅具有GAPBOND_IO_CAP_KEYBOARD_ONLY按键能力,从机端仅具有显示能力GAPBOND_IO_CAP_DISPLAY_ONLY。

从机端:

如果用手机做主机,开发板做从机,开发板显示密码,手机端输入密码,如果密码一直则配对成功。从机端使用协议栈自带例程simple_peropheral即可实现与手机的配对绑定,但此过程需要修改配对模式为uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;从机端初始化配对请求模式,否则主机端是不能收到配对过程中的输入密码请求的。

在此过程需要注意:手机大多是双模蓝牙,而手机配置界面大多是BDR蓝牙(非低功耗蓝牙),所以大多手机配置界面的自带蓝牙是不能与开发板进行配对绑定的,需要使用手机app,安卓建议nRF Connect,IOS端建议使用lightblue。

主机端

两个开发板一主一从,开发板作为从机实现与手机的配对与绑定后,从机端程序便可实现与另一开发板的配对绑定,我是基于simple_central例程修改主机端代码的。

初始化配置,在simple_central.c的static voidSimpleBLECentral_init(void)函数中,配置配对模式的初始化以及回调注册:

    uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;// 配置主机端初始化配对请求;uint8_t bonding = TRUE;//配对完成后,进行绑定uint8_t mitm = TRUE;//  使用authenticated pairinguint8_t ioCap = GAPBOND_IO_CAP_KEYBOARD_ONLY;GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);  GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);GAPBondMgr_Register(&SimpleBLECentral_bondCB);

接下来编写回调函数:

static gapBondCBs_t SimpleBLECentral_bondCB =
{(pfnPasscodeCB_t)SimpleBLECentral_passcodeCB, // Passcode callbackSimpleBLECentral_pairStateCB                // Pairing / Bonding state Callback
};static void SimpleBLECentral_passcodeCB(uint8_t *deviceAddr, uint16_t connHandle,uint8_t uiInputs, uint8_t uiOutputs, uint32_t numComparison)
{gapPasskeyNeededEvent_t *pData;// Allocate space for the passcode event.if ((pData = ICall_malloc(sizeof(gapPasskeyNeededEvent_t)))){memcpy(pData->deviceAddr, deviceAddr, B_ADDR_LEN);pData->connectionHandle = connHandle;    pData->uiInputs = uiInputs;pData->uiOutputs = uiOutputs;pData->numComparison = numComparison;// Enqueue the event.SimpleBLECentral_enqueueMsg(SBC_PASSCODE_NEEDED_EVT, 0, (uint8_t *) pData);}
}static void SimpleBLECentral_pairStateCB(uint16_t connHandle, uint8_t state,uint8_t status)
{uint8_t *pData;// Allocate space for the event data.if ((pData = ICall_malloc(sizeof(uint8_t)))){*pData = status;// Queue the event.SimpleBLECentral_enqueueMsg(SBC_PAIRING_STATE_EVT, state, pData);}
}
在static_processAppMsg(sbcEvt_t *pMsg)函数中添加对于SBC_PASSCODE_NEEDED_EVT和SBC_PAIRING_STATE_EVT两个事件的处理,代码如下

static void SimpleBLECentral_processAppMsg(sbcEvt_t *pMsg)
{switch (pMsg->hdr.event){case SBC_STATE_CHANGE_EVT:SimpleBLECentral_processStackMsg((ICall_Hdr *)pMsg->pData);// Free the stack messageICall_freeMsg(pMsg->pData);break;case SBC_KEY_CHANGE_EVT:SimpleBLECentral_handleKeys(0, pMsg->hdr.state);break;case SBC_RSSI_READ_EVT:{readRssi_t *pRssi = (readRssi_t *)pMsg->pData;// If link is up and RSSI reads activeif (pRssi->connHandle != GAP_CONNHANDLE_ALL &&linkDB_Up(pRssi->connHandle)){// Restart timerUtil_restartClock(pRssi->pClock, pRssi->period);// Read RSSIVOID HCI_ReadRssiCmd(pRssi->connHandle);}}break;// Pairing eventcase SBC_PAIRING_STATE_EVT:{SimpleBLECentral_processPairState(pMsg->hdr.state, *pMsg->pData);ICall_free(pMsg->pData);break;}// Passcode eventcase SBC_PASSCODE_NEEDED_EVT:{SimpleBLECentral_processPasscode(connHandle,(gapPasskeyNeededEvent_t *)pMsg->pData);ICall_free(pMsg->pData);break;}default:// Do nothing.break;}
}static void SimpleBLECentral_processPasscode(uint16_t connectionHandle, gapPasskeyNeededEvent_t *pData)
{if (pData->uiInputs) // if we are to enter passkey{
#if STATIC_PASSCODEpasscode = 123456;    //此处使用的是静态密码,不需要主机端手动输入,只要默认和从机端一致,就可实现配对GAPBondMgr_PasscodeRsp(connectionHandle, SUCCESS, passcode);  //发送密码响应
#else// user will enter passcodewaiting_for_passcode = TRUE;  //此处由主机端手动输入从机端显示的配对密码passcode_connHandle = connectionHandle;
#endif      Display_print0(dispHandle, 4, 0, "Enter Passcode:");Display_print1(dispHandle, 5, 0, "%d", passcode);      }else if (pData->uiOutputs) // if we are to display passkey{
#if STATIC_PASSCODEpasscode = 123456;
#else// Create random passcodepasscode = Util_GetTRNG();passcode %= 1000000;
#endif      Display_print1(dispHandle, 4, 0, "Passcode: %d", passcode);// Send passcode responseGAPBondMgr_PasscodeRsp(connectionHandle, SUCCESS, passcode);   }
}static void SimpleBLECentral_processPairState(uint8_t state, uint8_t status)
{if (state == GAPBOND_PAIRING_STATE_STARTED){Display_print0(dispHandle, 2, 0, "Pairing started");}else if (state == GAPBOND_PAIRING_STATE_COMPLETE){if (status == SUCCESS){Display_print0(dispHandle, 2, 0, "Pairing success");}else{Display_print1(dispHandle, 2, 0, "Pairing fail: %d", status);}}else if (state == GAPBOND_PAIRING_STATE_BONDED){if (status == SUCCESS){Display_print0(dispHandle, 2, 0, "Bonding success");}}else if (state == GAPBOND_PAIRING_STATE_BOND_SAVED){if (status == SUCCESS){Display_print0(dispHandle, 2, 0, "Bond save success");}else{Display_print1(dispHandle, 2, 0, "Bond save failed: %d", status);}}
}

至此,整个配对绑定过程,需要开发人员编写的代码便完成了,其余都是由底层实现,关于底层实现BLE4.0配对绑定过程的底层剖析这篇文章讲解很详细,有需要的朋友可以自行查阅。
绑定之后便存在解绑过程,经实际测试,单独在主机端解除绑定,在下次连接时会进行重新配对绑定,若单独在从机端解除绑定,主机连接从机会一直提示连接失败。
解除绑定是在连接断开后才执行,解绑有两种方式:一种是解除所有绑定设备 :

GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS, 0, NULL);

此模式调用这个函数,便可实现,不再赘述。
另一种是只解除单个设备绑定:

GAPBondMgr_SetParameter(GAPBOND_ERASE_SINGLEBOND, B_ADDR_LEN + 1, DevAddr);

解除单个设备绑定过程由于对参数含义不清楚,实现此功能颇费周折,在此详细说下各个参数的含义。
参数1:GAPBONG_ERASE_SINGLEBONG这个参数很容易理解,解除单个设备绑定;
参数2:B_ADDR_LEN+1表示要解绑设备的地址长度加1,此处为何加1呢?详见参数3的说明;
参数3:此参数是由要解绑设备的地址类型和地址共同组合的一个数组,所以要在地址长度上加1,此外连接完成后的设备地址是由低字节向高字节的,而此处是需要待解绑地址的字节由高到低,所以需要反向字节,具体操作如下:

uint8_t idx=0;
idx = GAPBondMgr_ResolveAddr(pEvent->linkCmpl.devAddrType, pEvent->linkCmpl.devAddr, NULL);//找到待解绑设备的索引
//此处pEvent->linkCmpl.devAddrType是待解绑设备的地址类型,pEvent->linkCmpl.devAddr是待解绑地址,这是连接完成后的地址,
Display_print1(dispHandle, 3, 0, "del idx: %d", idx);
if(idx < GAP_BONDINGS_MAX)//在bond manager中找到地址
{DevAddr[0] = pEvent->linkCmpl.devAddrType; //此处将待解绑地址的地址类型复制在DevAddr的最低字节;memcpy(lsdevaddr, pEvent->linkCmpl.devAddr, B_ADDR_LEN); //此处将待解绑地址复制到lsdevaddr中
//反向字节
VOID osal_revmemcpy(&DevAddr[1],lsdevaddr,B_ADDR_LEN);//将lsdevaddr的顺序颠倒放置在DevAddr的1~B_ADDR_LEN+1字节中
}
//最后将得到的字节传输至单个解绑的第三个参数
GAPBondMgr_SetParameter(GAPBOND_ERASE_SINGLEBOND, B_ADDR_LEN + 1, DevAddr);

CC2640R2F之配对绑定与解除绑定篇相关推荐

  1. 我的服装DRP之即时通讯——为WCF增加UDP绑定(应用篇)

    发个牢骚,博客园发博文竟然不能写副标题.这篇既为我的服装DRP系列第二篇,也给为WCF增加UDP绑定系列收个尾.原本我打算记录开发过程中遇到的一些问题和个人见解,不过写到一半发现要写的东西实在太多,有 ...

  2. 双网卡oracle rac,Linux+Oracle 10g RAC双网卡绑定和解除绑定的实现(2)

    解除双网卡绑定 十一.停数据库和crs 在rac1和rac2上停数据库和crs #cd  /u01/app/oracle/product/10.2.0/crs_1/bin 停数据库实例 #./srvc ...

  3. (百度云服务器的)域名不加www可以访问,添加就不能访问 (添加域名绑定)- 解决篇

    域名不加www可以访问,添加就不能访问: 解决这个问题,就是添加" 域名绑定 ". 403报错截图:(添加www的) 分析:是因为没有添加绑定对应的 · 域名解析规则导致的. 解决 ...

  4. Vue双向绑定:原理篇(详细)

    文章目录 前言 什么是响应式 数据劫持 发布者-订阅者模式 模式简介 发布者 Observer 订阅器 dep 订阅者 Watcher 整体流程 初始化data data变为响应式数据 解析模板 收集 ...

  5. Android——BLE配对绑定实现

    蓝牙配对绑定原理不再赘述了,终端的实现可以参照文章后的参考链接,本处主要记录总结下Android端的配对绑定实现过程. 1.动态注册系统广播,接收蓝牙配对请求 intentFilter = new I ...

  6. 一篇文章带你解读蓝牙配对绑定

    BLE配对绑定解读 什么是低功耗蓝牙配对?什么又是绑定?配对和绑定有什么区别?配对有什么好处?如何删除绑定信息?如何确定配对的安全等级?just work的配对一定就不安全吗?如何开发自己的配对应用? ...

  7. ble连接过程建立_BLE配对绑定过程梳理

    (一)BLE SM为以下三种procedure提供支持: 1. Pairing; 2. Bondig; 3. Encryption Re-establishment; 区别于传统蓝牙的配对过程,BLE ...

  8. BLE配对绑定过程梳理

    (一)BLE SM为以下三种procedure提供支持: 1. Pairing; 2. Bondig; 3. Encryption Re-establishment; 区别于传统蓝牙的配对过程,BLE ...

  9. Android Service的绑定 基础概念篇

    Creating a Bound Service 绑定Service的作用: 一个绑定的service(bound service)是客户端-服务器接口中的服务器. 绑定的service允许组件(比如 ...

最新文章

  1. Amazing ASP.NET Core 2.0
  2. Web服务cxf框架发布2
  3. Ubuntu 安装 opencv-nonfree
  4. activiti页面展示流程图乱码_activiti 5.17 流程图中文乱码问题
  5. 简练软考知识点整理-建设项目团队
  6. 从零开始通过 Artifactory 搭建公网的 maven 仓库
  7. 【分类汇总】110 天以来的题解分类汇总
  8. 2016峰会:项目管理与高级项目管理(广州站)
  9. mysql如何对字段加密_MySQL对指定字段进行加密(双向加密)
  10. 从数据库中读取数据,创建XML文件并更新维护XML
  11. android快速圣经,Android 中级圣经系列之Activity
  12. 华为服务器产品系列号查询,华为LIST全系列 服务器产品速查清单
  13. java keystore php,KeyStoreSpi
  14. Shader实现透明反射效果应用地板
  15. c语言中整数和实数能比较大小吗,c语言中,输入一个数字,怎么判断那个数字是整数还是实数,代码如下,输入实数后出现了死循环...
  16. 内网渗透-最实用的横向移动总结
  17. “免费午餐”成为销量第一,看明星吉杰淘宝直播如何抓取粉丝眼球
  18. 【Windows 安装JDK8】如何安装java JDK8
  19. 对苹果输入法产品评价
  20. 原理图中VCC、VDD、VEE、VSS等符号的意思

热门文章

  1. 共享充电宝有什么好拍? | 拍者手记
  2. 大脑构造图与功能解析_人类大脑的生理构造及功能分区
  3. 资源网站模板Emlog程序zytheme模板
  4. Neo4j 学习笔记 1:属性图
  5. Android网络编程入门解析
  6. 【图像去噪】基于matlab GUI butterworth+中值+维纳+小波图像去噪【含Matlab源码 520期】
  7. C#中的cs0116Error
  8. 1688按关键词搜索
  9. APP启动方式分析——冷启动、热启动、温启动
  10. 荣耀magic5和vivox90参数对比 荣耀magic5和vivox90哪个好