首页 > 编程学习 > CC2540 Central与CC2540 Peripheral 密码配对

CC2540 Central与CC2540 Peripheral 密码配对

发布时间:2022/12/10 16:36:05

照例先扯点别的。
按常理这个其实应该并不难,毕竟BLE配对过程很好理解。但真正做起来的时候总会遇到一点问题。
我卡在拥有输入能力的主机向拥有显示能力而生成密码的从机发送密码回应这个地方上。
找遍文档也没看见Central向Peripheral发送密码回应的函数,最后才发现原来是自己理解错了一些东西——GAPBondMgr_PasscodeRsp这个函数既可以作为从机提交自己设定密码的接口,同时也作为Central向从机发送自己输入的密码的接口。
以下文章对我帮助很大。在此感谢博主的分享精神。

http://blog.csdn.net/happyppdog/article/details/51971545

好,下面开始正式的博文。

参数配置

首先讲解下对Central与Peripheral的配置。

Central:

  // Setup the GAP Bond Manager{uint32 passkey = 0;// 此处默认密码可任意设置uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;//主机相应从机的配对请求uint8 mitm = TRUE;//防止中间人攻击(选用 Passcode、OOB来进行Paring的必须为TRUE)uint8 ioCap = GAPBOND_IO_CAP_KEYBOARD_ONLY;//具有输入能力uint8 bonding = FALSE;//不进行绑定GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey );GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof( uint8 ), &pairMode );GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof( uint8 ), &mitm );GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof( uint8 ), &ioCap );GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof( uint8 ), &bonding );}  

Peripheral:

  // Setup the GAP Bond Manager{uint32 passkey = 0; // 此处默认密码可任意设置uint8 pairMode = GAPBOND_PAIRING_MODE_INITIATE;// 从机发起配对请求uint8 mitm = TRUE;//防止中间人攻击(选用 Passcode、OOB来进行Paring的必须为TRUE)uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;//有显示能力,无输入能力uint8 bonding = FALSE; //不进行绑定GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );}

至此基础配置就进行完了。

回调函数的配置

无论是Central还是Peripheral,我们都需要配置回调函数 —— gapBondCBs_t simpleBLEPeripheral_BondMgrCBs

这个结构体第一个函数指针为密码相关函数指针,第二个则为配对等状态的函数指针(这个网上很多讲解,不多说了)

在这里我们选用相同密码123456,同时为了简化代码,Central 与 Peripheral的 对应回调函数完全一致。
密码回调函数编写如下:

static void simpleBLEPeripheralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,uint8 uiInputs, uint8 uiOutputs )
{uint32  passcode;passcode = 123456;// Send passcode responseGAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode );
}

状态回调函数:

static void simpleBLECentralPairStateCB( uint16 connHandle, uint8 state, uint8 status )
{if ( state == GAPBOND_PAIRING_STATE_STARTED ){NPI_WriteTransport("Pairing started\r\n",17);}else if ( state == GAPBOND_PAIRING_STATE_COMPLETE ){if ( status == SUCCESS ){NPI_WriteTransport("Pairing success\r\n",17);gPairStatus = PAIRSTATUS_PAIRED;}else{NPI_WriteTransport("Pairing fail\r\n",14);}}else if ( state == GAPBOND_PAIRING_STATE_BONDED ){if ( status == SUCCESS ){NPI_WriteTransport("Bonding success\r\n",17);}}
}

对于密码回调函数这个我有一点想说。

网络上流行的配对教程等等忽略了一个很重要的问题,如果需要输入密码,那么密码应该从哪里输入、怎么判断是否需要输入密码。

1.密码应该从哪里输入?

你获得密码的途径无所谓,但最后你把密码提交给GAP的最终函数是GAPBondMgr_PasscodeRsp,并且你需要在底层调用密码回调函数的时候就将密码提交上去,延迟太久配对会失败,提示0x17错误(这个跟代码实现有关)。

2.如何判断是否需要输入密码?

判断方法在simpleBLEPeripheralPasscodeCB中的
uint8 uiInputs与uint8 uiOutputs
uiOutputs,这个代表是否输出,或者可以理解为有输出设备(>0代表有设备)
uiInputs,这个代表是否输入,或者是否拥有输入设备(同理 >0代表有设备)
(这两句我自己理解的,有错误欢迎指出)
通过判断uiInputs,即可确定是否需要输入密码。

实验现象

密码正确:

Server is Online
Start Discovering
BLE Central:0x78A5047A502A
Devices Found:1
0x78A5047A4956
Connected.
Device:0x78A5047A4956
Pairing success

密码错误:

Server is Online
Start Discovering
BLE Central:0x78A5047A502A
Devices Found:1
0x78A5047A4956
Connected.
Device:0x78A5047A4956
Pairing fail:4

于密码回调函数中下断点,延迟GAPBondMgr_PasscodeRsp运行,模拟用键盘输入密码:

Server is Online
Start Discovering
BLE Central:0x78A5047A502A
Devices Found:1
0x78A5047A4956
Connected.
Device:0x78A5047A4956
Pairing fail:17

发现失败。
原因我认为可能是下断点让CC2540停摆,其与Peripheral进行底层交流的其他函数也无法执行,导致Peripheral认为超时。

基本就这些。
耽误了三四天时间,希望能帮助后来的人。


本文链接:https://www.ngui.cc/zz/1568610.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000