常见问题:
一、BLE与APP首次配对后,再次连接则直接跳过配对过程?
BLE和APP首次配对成功后,BLE和APP都会保留对方的连接信息,很多除开发者都认为只要BLE测清楚SVN中的配对消息即可,其实不然,APP测也同样清除才可以。
二、初始化都是设置的GAPBOND_PAIRING_MODE_WAIT_FOR_REQ等待配对.
需要配对双方如果都设置成该模式,将无法配对,除非其中一个配置成GAPBOND_PAIRING_MODE_INITIATE, 如果是central的话会发起pairing request, 如果是peripheral的话会发起slave security request, 最终会导致central那端收到 GAP_SLAVE_REQUESTED_SECURITY_EVENT, 这个时候你看代码, 如果central也是出于GAPBOND_PAIRING_MODE_WAIT_FOR_REQ, 那么他还是会发起配对.所以, 只要其中一个设置成GAPBOND_PAIRING_MODE_INITIATE, 两边就会配对, 如果都是GAPBOND_PAIRING_MODE_WAIT_FOR_REQ, 那么就没有配对过程.
三、配对不成功是否就没办法进行数据交流?
这种想法是不对的,蓝牙4.0都是先连接后配对,所以即便配对不成功,双方也是可以进行特征值读写的。如果数据需要保密,就需要在BLE测将数据的读写特征进行修改(将GATT_PERMIT_READ修改为GATT_PERMIT_AUTHEN_READ,写也同样)。
下面共享一下CC2541实现配对的源码:
首先需要定义状态枚举类型:
typedef enum
{
PAIRSTATUS_PAIRED = 0,
PAIRSTATUS_NO_PAIRED,
}PAIRSTATUS;
static PAIRSTATUS gPairStatus = PAIRSTATUS_NO_PAIRED;//配对状态,默认是没配对
从这里可以看出,在配对过程中只有两种状态,成功或者失败。所以如果嫌麻烦也可以用BOOL的变量来表示。
到这里涉及到对匹配的初始化了:
{
uint32 passkey = 0; // passkey "000000"
uint8 pairMode = GAPBOND_PAIRING_MODE_INITIATE;
uint8 mitm = TRUE;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8 bonding = TRUE;
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 );
}
这里需要注意两点:一个是pairMode的赋值,请看问题二。另外就是 ioCap的赋值,这里要根据对应设备进行选取,是否有输入设备、是否有显示设备、是否可以选择是否等
下面就需要来添加两个回调函数了。
// GAP Bond Manager Callbacks
static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
ProcessPasscodeCB, // 密码回调
ProcessPairStateCB // 绑定状态回调
};
第一个回调函数是设定密码的:
static void ProcessPasscodeCB(uint8 *deviceAddr,uint16 connectionHandle,uint8 uiInputs,uint8 uiOutputs )
{
uint32 passcode;
uint8 str[7];
//设置密码
#if 0
LL_Rand( ((uint8 *) &passcode), sizeof( uint32 ));
passcode %= 1000000;
#else
passcode = 456890;
#endif
//在LCD上显示
if ( uiOutputs != 0 )
{
HalLcdWriteString( "Passcode:", HAL_LCD_LINE_1 );
HalLcdWriteString( (char *) _ltoa(passcode, str, 10), HAL_LCD_LINE_2 );
}
//发送密码响应给主机
GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode );
}
这个函数实现的是自动生成6位密码。并将密码通过LED屏幕显示出来,进行配对。有人想要设定固定密码,其实需要的就是将自动获取函数用读取FLASH的函数取代就可以,
不过前提是需要先通过特征值来设定一个密码到FLASH中。
最后就是对配对过程的判断了。
static void ProcessPairStateCB( uint16 connHandle, uint8 state, uint8 status )
{
//主机发起连接,会进入开始配对状态
if ( state == GAPBOND_PAIRING_STATE_STARTED )
{
HalLcdWriteString( "Pairing started", HAL_LCD_LINE_1 );
gPairStatus = PAIRSTATUS_NO_PAIRED;
}
//当主机提交密码后,会进入配对完成状态
else if ( state == GAPBOND_PAIRING_STATE_COMPLETE )
{
//配对成功
if ( status == SUCCESS )
{
HalLcdWriteString( "Pairing success", HAL_LCD_LINE_1 );
gPairStatus = PAIRSTATUS_PAIRED;
}
//已配对过
else if(status == SMP_PAIRING_FAILED_UNSPECIFIED)
{
HalLcdWriteString( "Paired device", HAL_LCD_LINE_1 );
gPairStatus = PAIRSTATUS_PAIRED;
}
//配对失败
else
{
HalLcdWriteStringValue( "Pairing fail", status, 10, HAL_LCD_LINE_1 );
gPairStatus = PAIRSTATUS_NO_PAIRED;
}
//配对失败则断开连接
if(gPairStatus == PAIRSTATUS_NO_PAIRED)
{
GAPRole_TerminateConnection();
}
}
else if ( state == GAPBOND_PAIRING_STATE_BONDED )
{
if ( status == SUCCESS )
{
HalLcdWriteString( "Bonding success", HAL_LCD_LINE_1 );
}
}
}
通过这个函数就可以对配对过程进行有效控制。到这里基本上的配对就完成了。不过别忘了将这两个函数在文件开头的地方申明一下哦!!
以上内容未经允许,请勿转载。
来自
QQ:2219468832