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

1. 定向广播(Directed Advertising)

定义

定向广播是一种蓝牙低功耗(BLE)广播模式,设备在广播数据包中明确指定目标设备的地址 ,只有该设备能接收到广播并响应。

特点

  • 目标明确 :广播数据包中携带目标设备的 MAC 地址(或蓝牙地址)。
  • 低延迟连接 :适用于快速重连(如设备已知对方地址时)。
  • 节能 :非目标设备会直接忽略广播,减少无效扫描。

典型应用场景

  • 快速与配对过的设备重新建立连接(如蓝牙耳机回连手机)。
  • 一对一的设备通信(如智能手环与手机)。

2. 白名单(Whitelist)

定义

白名单是一种设备过滤机制 ,主机设备(如手机、网关)预先存储一组允许通信的设备的地址(MAC/蓝牙地址),仅处理来自白名单内设备的请求。

特点

  • 批量管理 :可同时允许多个设备通信(如家庭 IoT 设备群)。
  • 安全性 :阻止未授权设备接入(如陌生人无法连接你的蓝牙音箱)。
  • 灵活性 :白名单可动态更新(添加/删除设备)。

典型应用场景

  • 蓝牙门锁仅允许家庭成员手机开锁。
  • 工厂设备仅接收授权传感器的数据。

3. 核心区别

 

特性
定向广播
白名单
作用对象
单设备(一对一)
多设备(一对多)
实现方式
广播包中指定目标地址
主机维护允许的地址列表
延迟
低(直接寻址)
较高(需查表匹配)
典型用途
快速重连、专用通信
安全过滤、群组管理
协议支持
BLE 定向广播模式
通用机制(蓝牙/Wi-Fi 均支持)

 


 

以CH582的Hid_Keyboard例程为例,

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

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

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

typedef struct
{
  uint8_t 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_SCAN;//设置仅允许白名单设备扫描和连接
     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  阅读(1370)  评论(4)    收藏  举报