[蓝牙 MESH] 基于 SDK 开发如何接收并转发三方 beacon 广播包
Posted: 2023年 Aug 30日 15:22
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时,停止发送(不然会造成一直发送的问题)