Page 1 of 1

[蓝牙 MESH] 基于 SDK 开发如何接收并转发三方 beacon 广播包

Posted: 2023年 Aug 30日 15:22
by beautifulzzzz

1、在 VOID app_ble_data_recv(TAL_BLE_EVT_PARAMS_T *p_event) 插入自己写的广播接收处理函数

Code: Select all

VOID app_ble_data_recv(TAL_BLE_EVT_PARAMS_T *p_event){
    switch(p_event->type) {
        case TAL_BLE_EVT_PERIPHERAL_CONNECT:
            ...
        break;
        case TAL_BLE_EVT_DISCONNECT:
            ...
        break;
        case TAL_BLE_EVT_ADV_REPORT:
#if 1
            tbl_beacon_pair_config_protocol_recv(p_event->ble_event.adv_report.p_data, p_event->ble_event.adv_report.data_len, 
                                            p_event->ble_event.adv_report.peer_addr.addr, p_event->ble_event.adv_report.rssi);
#endif
            tal_rssi_test_ble_adv_recv(p_event->ble_event.adv_report.p_data, p_event->ble_event.adv_report.data_len, 
                                            p_event->ble_event.adv_report.peer_addr.addr, p_event->ble_event.adv_report.rssi);
        break;
        case TAL_BLE_EVT_WRITE_REQ:
            ...
        break;
        default:
        break;
    }
}
 

2. 编写字节的广播接收函数

Code: Select all

OPERATE_RET tbl_beacon_pair_config_protocol_recv(UINT8_T *adv, UINT8_T adv_len, UINT8_T *mac, int rssi){
#if 1
    #define FILTERS_NUM 10
    static UINT8_T filters[FILTERS_NUM][5];
    static UINT8_T filters_idx = 0;

    if(mac[0] == 0xE8 && mac[1] == 0x6E && mac[2] == 0xB0 && mac[3] == 0xF7 && mac[4] == 0x2D && mac[5] == 0x74){
        for(UINT8_T i=0;i<FILTERS_NUM;i++){
            if(memcmp(filters[i],&adv[adv_len-5],5) == 0)
                return OPRT_COM_ERROR;
        }
        memcpy(filters[filters_idx++],&adv[adv_len-5],5);
        if(filters_idx >= FILTERS_NUM)filters_idx=0;

        TBL_BEACON_PAIR_CONFIG_PROTOCOL_DEBUG("ADV:[%02X%02X%02X%02X%02X%02X][L:%02d][RSSI:%02d]:",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],adv_len,(INT8_T)rssi);
        TBL_BEACON_PAIR_CONFIG_PROTOCOL_DEBUG_HEX_ARRAY(adv,adv_len);
        TBL_BEACON_PAIR_CONFIG_PROTOCOL_DEBUG_RAW("\n");       

        app_ble_data_adv_send_start(adv,adv_len);
    }
#endif
}

上面例子只是个参考,不过具体框架请严格有以下几点:

  • 粗过滤(一般是根据 MAC、广播数据长度、三方广播格式的特征进行初次过滤广播数据,不然会收到较多无用数据影响性能)
  • 重复过滤(根据三方广播协议特性,设计一个 3~10 个大小的 filters,用来过滤掉相同的数据)
  • 解密+校验数据合法性
  • 命令处理(转发)
 

3、app_ble_data_adv_send_start 广播发送函数参考

Code: Select all

#include "ble/ble_common.h"
UINT8_T __adv_data_send_start = 0;
UINT8_T __adv_data[31];
UINT8_T __adv_data_len;
UINT8_T __adv_mac_is_default = 1;
UINT8_T __adv_mac[6];

VOID_T app_ble_data_adv_send_set_mac(UINT8_T *mac){
    if(mac == NULL){//use node default mac
        __adv_mac_is_default = 1;
    }else{//use new mac send adv
        memcpy(__adv_mac,mac,6);
        __adv_mac_is_default = 0;
    }
}

VOID_T app_ble_data_adv_send_start(UINT8_T *adv_data, UINT8_T adv_len){
    __adv_data_send_start = 0;
    memcpy(__adv_data,adv_data,adv_len);
    __adv_data_len = adv_len;
    __adv_data_send_start = 1;
}

VOID_T app_ble_data_adv_send_stop(){
    __adv_data_send_start = 0;
}

INT32_T app_ble_data_adv_send(rf_packet_adv_t *par){
    if(__adv_data_send_start == 1){
        if(__adv_mac_is_default == 0)
            for(UINT8_T i=0;i<6;i++)
                par->advA[i] = __adv_mac[5-i];

        memcpy(par->data, __adv_data, __adv_data_len);
        par->header.type = 2;//LL_TYPE_ADV_NONCONN_IND;
        par->rf_len = __adv_data_len + 6;
        par->dma_len = par->rf_len + 2;

        return 1;
    }else{
        return 0;
    }
} 

注意实际用时,还要加个发包计数,每次调用 start 时发包计数设置为 x, 每次app_ble_data_adv_send被调用 x--,当x为0时,停止发送(不然会造成一直发送的问题)