BLE4.0配对绑定过程的底层剖析

一、实验目的

1、了解主从配对绑定的过程中底层是怎么运行的;


二、说明

1、关于配对于绑定,网上查了很多资料都没查到什么,问了很多人也没有回答的,所以我决定自己深入了解底层关于配对与绑定是如何运行的,我用了接近两个星期来理解的,效率很低,在这里总结一下,希望能帮助到别人。

2.这里之是大概讲了一个方向,因为涉及的点太多,无法一一列出,需要研究细节的,自己去探讨一下,不懂可以在群上讨论


三、实验平台

1、蓝牙协议栈:1.3.2

2、软件平台:IAR For 8051 8.10.3

5、硬件平台:Smart RF开发板(从机),Android_Lightblue(主机)


四、实验步骤

1.static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )

{
  switch ( pMsg->opcode )
  {
   case GAP_LINK_ESTABLISHED_EVENT:
        if ( pPkt->hdr.status == SUCCESS )
        {
          // Notify the Bond Manager to the connection  //通知绑定管理调出绑定当前连接主机的绑定信息如LTK等
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );
        }
 }



2.bStatus_t GAPBondMgr_LinkEst( uint8 addrType, uint8 *pDevAddr, uint16 connHandle, uint8 role )

{
  idx = GAPBondMgr_ResolveAddr( addrType, pDevAddr, publicAddr );//查看当前连接的主机是否绑定过
  if ( idx < GAP_BONDINGS_MAX ) //如果当前连接主机在NV的某个位置(绑定过)则将绑定信息调出,否则不管
  {
    // On peripheral, load the key information for the bonding 从机加载出绑定的密钥信息
    // On central and initiaiting security, load key to initiate encyption 主机加载出绑定的密钥信息并向从机发出加密请求
    gapBondMgrBondReq( connHandle, idx, stateFlags, role,
                       ((gapBond_PairingMode == GAPBOND_PAIRING_MODE_INITIATE ) ? TRUE : FALSE) )
  // If Peripheral and initiating, send a slave security request to initiate either pairing or encryption   
  //调用出绑定信息后,向主机发出安全请求,主机发起加密或配对(如果没绑定过)
  if ( role == GAP_PROFILE_PERIPHERAL &&
       gapBond_PairingMode == GAPBOND_PAIRING_MODE_INITIATE )
  {
    gapBondMgrSlaveSecurityReq( connHandle ); //向主机发送安全请求
  }
}



3.等待主机发送配对(没绑定)或加密请求(绑定过)


一、没绑定过

1.static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )

{
  switch ( pMsg->opcode )
  {
GAP_PAIRING_REQ_EVENT:  //接收到主机的配对请求
{
   // Send pairing response //配对响应
   gapBondMgrAuthenticate( pPkt->connectionHandle, pLinkItem->addrType, &(pPkt->pairReq) ); //启动认证
}
  }
}



2.static void gapBondMgrAuthenticate( uint16 connHandle, uint8 addrType,gapPairingReq_t *pPairReq )

{
  VOID GAP_Authenticate( ¶ms, pPairReq ); //认证,根据配对请求接收到的主机信息(如主机的配对能力等)跟自己的配对能力做比较然后执行下一步动作(由于从机设置成GAPBOND_IO_CAP_DISPLAY_ONLY,所以主机索求密码)
}


3.static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )

{
  switch ( pMsg->opcode )
  {
  case  GAP_PASSKEY_NEEDED_EVENT: //向主机索求密码
{
    if ( pGapBondCB && pGapBondCB->passcodeCB ) //用回调函数发送密码请求
    {
       // Ask app for a passcode
       pGapBondCB->passcodeCB( pPkt->deviceAddr, pPkt->connectionHandle, pPkt->uiInputs, pPkt->uiOutputs );
    }
   }
}


4.static void ProcessPasscodeCB(uint8 *deviceAddr,uint16 connectionHandle,uint8 uiInputs,uint8 uiOutputs )

{
  passcode = 123456;   //使用固定密码123456
  // Send passcode response  
  GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode );  //发送密码请求给主机
}


5.等待主机回复密码,从机接收到主机的密码回复后,在底层对接收到的密码做校验,要么密码不正确(status=SMP_PAIRING_FAILED_CONFIRM_VALUE),要么正确(status=SUCCESS),要么主机取消输入操作(status=SMP_PAIRING_FAILED_PASSKEY_ENTRY_FAILED),在校验密码完成后,从机触发GAP_AUTHENTICATION_COMPLETE_EVENT事件并向主机发送自己的认证信息TLK等(认证成功)或发送认证status=Msg Buffer Not Available(密码错误),发送消息是底层完成的,不开源;


6.static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )

{
  switch ( pMsg->opcode )
  {
  case  GAP_AUTHENTICATION_COMPLETE_EVENT:  //认证完成
{
     if ( (pPkt->hdr.status == SUCCESS) && (pPkt->authState & SM_AUTH_STATE_BONDING) )//判断认证是否成功
        {       
          // Save off of the authentication state
          VOID gapBondMgrAddBond( &bondRec, //绑定
                             (gapBondLTK_t *)pPkt->pSecurityInfo,
                             (gapBondLTK_t *)pPkt->pDevSecInfo,
                             ((uint8 *)((pPkt->pIdentityInfo) ? pPkt->pIdentityInfo->irk : NULL )),
                             ((uint8 *)((pPkt->pSigningInfo) ? pPkt->pSigningInfo->srk : NULL )),
                          ((uint32)((pPkt->pSigningInfo)?pPkt->pSigningInfo->signCounter :GAP_INIT_SIGN_COUNTER ))
        }
        // Call app state callback
        if ( pGapBondCB && pGapBondCB->pairStateCB ) //通知回调函数当前认证的状态,密码正确或不正确
        {
          pGapBondCB->pairStateCB( pPkt->connectionHandle, GAPBOND_PAIRING_STATE_COMPLETE, pPkt->hdr.status );
        }
    }
}



二、绑定过

1.主机接收到从机的安全请求后,会检查当前连接的从机是否绑定过,绑定过的话,利用绑定的信息做加密并向从机发送加密请求;


2.从机接收到主机的加密请求后,用GAP_LINK_ESTABLISHED_EVENT中的调出来的绑定信息跟主机进行三次加密握手(底层完成),如果加密成功,从机向主机发送绑定完成事件(status=SUCCESS)并触发GAP_BOND_COMPLETE_EVENT事件如果加密不成功(从机删除绑定信息)从机向主机发送绑定完成事件(status=LL_REJECT_IND)事件但不触发GAP_BOND_COMPLETE_EVENT事件


3.static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )

{
  switch ( pMsg->opcode )
  {
    case GAP_BOND_COMPLETE_EVENT:  //绑定完成
#if ( HOST_CONFIG & CENTRAL_CFG )  //主机
      if ( pPkt->hdr.status == LL_ENC_KEY_REQ_REJECTED ) //如果加密失败且status =LL_ENC_KEY_REQ_REJECTED    
      {
            switch ( gapBond_BondFailOption )  //当绑定过,但是加密失败的时候,主机可以启动重新配对
            {
              case GAPBOND_FAIL_INITIATE_PAIRING:
                // Initiate pairing
                gapBondMgrAuthenticate( pPkt->connectionHandle, pLinkItem->addrType, NULL );
                break;
            }
          }
        }
#endif
        if ( pGapBondCB && pGapBondCB->pairStateCB )  //加密成功,通知回调函数
        {
          pGapBondCB->pairStateCB( pPkt->connectionHandle, GAPBOND_PAIRING_STATE_BONDED, pMsg->hdr.status );
        }
      }
    }  
}


 

五、总结

1.每次连接后,从机都会向主机发送安全请求gapBondMgrSlaveSecurityReq( connHandle ),如果没有相互绑定过,主机会发起配对(配对数据中包括主机的密钥等),配对完成后,从机触发GAP_AUTHENTICATION_COMPLETE_EVENT并向主机发送自己的认证信息LTK,这样相互保存认证信息LTK后就算绑定了;


2.每次连接后,从机都会向主机发送安全请求gapBondMgrSlaveSecurityReq( connHandle )如果配对绑定过,主机和从机会以保存下来的认证信息LTK来做加密认证,如果加密成,从机触发GAP_BOND_COMPLETE_EVENT事件并向主机发送绑定完成消息(status=0x00SUCCESS如果认证失败(从机删除绑定信息),从机会向主机发送绑定完成消息(status=0x06LL_REJECT_IND事件当不触发GAP_BOND_COMPLETE_EVENT事件;

 

六、补充

1.问题一:从机跟主机配对过一次后,不会再次配对;

答:从机跟主机配对过后,相互保存绑定的认证信息,当再次连接时,主机先会去检查当前从机是否绑定过,如果有,就不会在发起配对了,即使是从机更改了配对密码也是一样,因为再次连接加密认证时是用保存好的绑定信息(LTK)来做加密认证的,而不是配对密码,配对密码只是临时密码(TK),用来在配对时产生LTK的,如果不用配对,更改配对密码是没有任何意义的;


2.问题二:主从机如何删除绑定?

答:主机:在手机的系统蓝牙设置里面有取消配对;

从机:GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS,0, NULL );  这个函数可以删除所有绑定,但前提它不会立即执行,它要先确认从机当前是在连接状态还是在无连接状态,无连接状态时,删除绑定是立即执行,连接状态时,需要等断开连接后自动执行,详情可以自己看一下这个函数的代码就好,想在连接状态下删除绑定可以直接用gapBondMgrEraseAllBondings(),想删除某个绑定可以用gapBondMgrEraseBonding()


3.问题三:为什么从机删除绑定后,IOS lightblue 不会重新配对,Android lightblue会重新配对,IOS lightblue只有在系统蓝牙中取消配对在可以重新配对;

答:上面的实验步骤二.2讲到在从机删除绑定后,主机再和从机连接时,最终会加密失败,从机会发送失败消息给主机,主机可以在接收到加密失败消息后重新启动配对,像二.3一样,至于IOS lightblue 不会重新配对,android lightblue会重新配对,那只是APP程序编写不同而已了;


4.很多人问为什么在阿莫资料中的蓝牙4.0连接之配对与绑定实验中,OLED显示bonding success 是在配对后的第二次连接才会显示

答:依总结.2看来,第一次配对绑定并不会触发GAP_BOND_COMPLETE_EVENT事件的,而阿莫的OLED显示bonding success 就是放在GAP_BOND_COMPLETE_EVENT事件,,所以第一次配对OLED不会显示bonding success,在主从配对绑定后,每次连接时,如果加密成功都会触发GAP_BOND_COMPLETE_EVENT事件,所以在配对之后的第一次连接才会显示bonding success,实际上绑定相当与保存认证信息而已,在GAP_AUTHENTICATION_COMPLETE_EVENTgapBondMgrAddBond就已经做了,你也可以在GAP_AUTHENTICATION_COMPLETE_EVENT事件中做OLED显示bonding success 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
菜鸟哥玩蓝牙BLE4.0系列,我想首先说明一下BLE4.0是一种低功耗的蓝牙技术,广泛应用于物联网、智能家居等领域。菜鸟哥选择玩BLE4.0系列可能有如下原因。 首先,BLE4.0具有低功耗特性。相比于传统蓝牙技术,BLE4.0在连接传输过程中的电量消耗更低,这意味着设备可以更长时间地使用电池,延长使用寿命。对于菜鸟哥来说,这意味着可以更长时间地玩耍和开发蓝牙设备,更好地学习和了解这项技术。 其次,BLE4.0具有广泛的应用领域。如今,物联网技术发展迅猛,智能家居、健康监测、智能穿戴设备等应用场景普遍采用BLE4.0技术。因此,通过玩蓝牙BLE4.0系列,菜鸟哥可以了解和学习到这些领域的应用特点和开发方法,为将来的工作和研究奠定坚实基础。 此外,BLE4.0具有较高的可靠性和稳定性。该技术在传输过程中采用了自适应频率跳跃和数据包检测等机制,能够自动调整工作频率和纠错,提高了数据传输的可靠性和稳定性。对于菜鸟哥来说,这意味着他在学习和开发过程中可以更好地理解和应用蓝牙BLE4.0的稳定性优势,提升自己的技术水平。 综上所述,菜鸟哥选择玩蓝牙BLE4.0系列可能是因为它具有低功耗、广泛的应用领域和较高的可靠性。通过深入学习和实践,他可以更好地掌握和应用这项蓝牙技术,为未来的工作和学习打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值