CH571,CH573,CH582,CH592低功耗蓝牙定向广播/白名单广播回连

以CH582的Hid_Keyboard例程为例,

1、CH582首次广播面向对象为所有扫描设备,例程默认就是这种广播方式;

2、我们主机设备与CH582建立配对之后,可以利用hidDevPairStateCB回调添加代码找到我们主机设备的地址信息(remote_addr)以及地址类型(addr_type);

/*这里自定义了一个结构体,以便后面赋值使用*/

typedef struct
{
  BOOL isbond;
  uint8_t remote_addr_type;
  uint8_t remote_addr[6];
}Device_ID_t;

/*定义一个结构体变量,便于后面赋值使用*/

Device_ID_t mydevinfo;

 

/**BLE状态回调函数**/
/*********************************************************************
 * @fn      hidEmuStateCB
 *
 * @brief   GAP state change callback.
 *
 * @param   newState - new state
 *
 * @return  none
 */
static void hidEmuStateCB(gapRole_States_t newState, gapRoleEvent_t * pEvent) {
    switch (newState & GAPROLE_STATE_ADV_MASK) {
......
    case GAPROLE_CONNECTED:
        if (pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT) {
            gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *) pEvent;// get connection handle
            hidEmuConnHandle = event->connectionHandle;
            tmos_start_task(hidEmuTaskId, START_PARAM_UPDATE_EVT,START_PARAM_UPDATE_EVT_DELAY);
            conn_params.interval_current = event->connInterval;
            PRINT("Connected..\n");
            tmos_memcpy(devAddr, event->devAddr, 6);//获取设备地址
            devAddrType = event->devAddrType;//获取设备地址类型
        }
        break;
......
    default:
        break;
    }
}

 


/*该回调函数在hiddev.c文件中*/
static void hidDevPairStateCB(uint16_t connHandle, uint8_t state, uint8_t status)
{
    if(state == GAPBOND_PAIRING_STATE_COMPLETE)
    {
        if(status == SUCCESS)
        {
            hidDevConnSecure = TRUE;
        }
        pairingStatus = status;
    }
    else if(state == GAPBOND_PAIRING_STATE_BONDED)
    {
        if(status == SUCCESS)
        {
            hidDevConnSecure = TRUE;

#if DEFAULT_SCAN_PARAM_NOTIFY_TEST == TRUE
            ScanParam_RefreshNotify(gapConnHandle);
#endif
        }
    }
    else if(state == GAPBOND_PAIRING_STATE_BOND_SAVED)
    {
/******************************添加代码***************************************/ gapBondRec_t bond_info; uint8_t addr_type; tmos_snv_read(mainRecordNvID(
0), sizeof(gapBondRec_t), &bond_info);//读取当前SNV存储地址处所存储的绑定信息,该结构体中可以读到此次配对的主机唯一身份地址 PRINT("identity addr ("); for(int i = 0 ; i < 6; i ++) { PRINT("%02x ", bond_info.publicAddr[i]);//将配对的主机地址打印出来 } PRINT(")\n"); tmos_memcpy(mydevinfo.remote_addr,bond_info.publicAddr, 6);//将此次绑定的地址赋值到自己定义的地址数组中去,以便定向广播或者白名单回连使用 //为identity address, 可能为public address,也可能是random static address if( (bond_info.publicAddr[5] & 0xC0) == 0x80 ) //判断地址类型
     { addr_type
= 0; }
    
else
     { addr_type
= 1; } extern uint8_t devAddrType; (devAddrType)?1:(addr_type = 0);

      if(devAddrType == 3)
      {
        addr_type |= devAddrType<<4;
      }

        mydevinfo.remote_addr_type = addr_type;//获取主机的地址类型
        mydevinfo.isbond = 1;//此次设备绑定生效
/*****************************END*************************************/
} }

3、将上次绑定的设备地址(remote_addr)和地址类型(addr_type)传入定向广播的参数中;

static inline void bt_adv_direct(uint8_t addr_type, uint8_t *addr)
{
    uint8_t adv_event_type;
    adv_event_type = GAP_ADTYPE_ADV_HDC_DIRECT_IND;


    uint8_t Adv_Direct_Addr[B_ADDR_LEN];
    uint8_t Adv_Direct_Type = addr_type;

    tmos_memcpy(Adv_Direct_Addr, addr,sizeof(Adv_Direct_Addr));

    PRINT("Adv Direct type %#x (", Adv_Direct_Type);
    for (int i = 0; i < 6; i++) {
        if(i) PRINT(" ");
        PRINT("%#x", Adv_Direct_Addr[i]);
    }
    PRINT(")\n");
    GAPRole_SetParameter( GAPROLE_ADV_DIRECT_ADDR, sizeof(Adv_Direct_Addr),Adv_Direct_Addr);
    GAPRole_SetParameter( GAPROLE_ADV_DIRECT_TYPE, sizeof(Adv_Direct_Type),&Adv_Direct_Type);
    GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof(adv_event_type),&adv_event_type);
}

4、利用结构体中的是否绑定参数(mydevinfo.isbond)做判断,每次上电广播时是否进行定向广播;

void adv_init(void)
{
    uint8_t initial_advertising_enable = TRUE;
if (mydevinfo.isbond) { PRINT("type = %d\n",mydevinfo.remote_addr_type); uint8_t enable = ENABLE; if(mydevinfo.remote_addr_type&0x30){ GAPBondMgr_SetParameter( GAPBOND_AUTO_SYNC_RL, sizeof(uint8), &enable); } else{ enable = DISABLE; GAPBondMgr_SetParameter( GAPBOND_AUTO_SYNC_RL, sizeof(uint8), &enable); } bt_adv_direct(mydevinfo.remote_addr_type, mydevinfo.remote_addr); } else{ GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof(advertData), advertData); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData); } // Set the GAP Role Parameters GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable); }

5、定向广播为3.75ms进行一次快速广播,并且最多持续1.28s,且部分苹果手机和华为手机无法利用该方式回连,可借助下面的白名单回连的方式;

void adv_init(void)
{
    uint8_t initial_advertising_enable = TRUE;

    uint16 advInt =32; //0.625us * 32 = 20ms,20ms一包广播包
    GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
    GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);

    if(mydevinfo.isbond)
    {

     uint8_t reconAdvertData[1] = {0};

     GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(reconAdvertData), reconAdvertData);//将广播包数据清空
     GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(reconAdvertData), reconAdvertData);//扫描应答包数据清空

     uint8_t filter_policy = GAP_FILTER_POLICY_WHITE;//设置仅允许白名单设备扫描和连接
     GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(uint8_t), &filter_policy);

  }else {
       uint8_t policy = GAP_FILTER_POLICY_ALL;
       GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(policy), &policy);
    }
}

 

posted @ 2023-08-22 17:18  oTvTo  阅读(600)  评论(4编辑  收藏  举报