WLG/wifi_5g/scan_blueteeth.cpp
2025-05-30 18:31:15 +08:00

196 lines
6.8 KiB
C++

#include "scan_blueteeth.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdint.h>
#include <fcntl.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <zlog.h>
#include "common/common_func.hpp"
#include "dbaccess/sql_db.hpp"
extern zlog_category_t *zct;
ScanBlueteeth::ScanBlueteeth() : device_id(-1), sock(-1) {
retry_count = 0;
max_retries = 5;
// Constructor initializes device_id and sock to invalid values
}
ScanBlueteeth::~ScanBlueteeth() {
// Destructor ensures resources are released
if (sock >= 0) {
hci_le_set_scan_enable(sock, 0x00, 0x00, 1000); // Disable scanning
close(sock); // Close the socket
}
}
// 初始化 socket 成为非阻塞模式
int set_nonblocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) return -1;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
int ScanBlueteeth::InitDevice(){
zlog_info(zct,"Initializing HCI device...");
system("hciconfig hci0 reset");
device_id = hci_get_route(NULL);
sock = hci_open_dev(device_id);
if (device_id < 0 || sock < 0) {
zlog_error(zct,"Failed to open HCI device.");
return -1;
}
// 设置扫描参数 扫描间隔450ms
if (hci_le_set_scan_parameters(sock, 0x01, 0x02D0, 0x02D0, 0x00, 0x00, 1000) < 0) {
zlog_error(zct,"Set scan parameters failed");
close(sock);
return -2;
}
// 启动扫描
if (hci_le_set_scan_enable(sock, 0x01, 0x00, 1000) < 0) {
zlog_error(zct,"Enable scan failed");
close(sock);
return -3;
}
// 设置事件过滤器
struct hci_filter nf;
hci_filter_clear(&nf);
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
setsockopt(sock, SOL_HCI, HCI_FILTER, &nf, sizeof(nf));
retry_count = 0;
if (sock >= 0) {
set_nonblocking(sock); // 设置非阻塞
}
return 0;
}
void ScanBlueteeth::StartScan(){
while (1) {
if (sock < 0 || retry_count > max_retries) {
zlog_error(zct,"Reinitializing HCI device...");
if (sock >= 0) close(sock);
if (InitDevice() != 0) {
zlog_error(zct,"Failed to initialize HCI device.");
sleep(3);
retry_count++;
continue;
}
retry_count = 0;
}
unsigned char buf[HCI_MAX_EVENT_SIZE];
int len = read(sock, buf, sizeof(buf));
if (len < 0) {
if (errno == EAGAIN || errno == EINTR) {
continue; // Ignore temporary errors
} else {
zlog_error(zct,"Read error: %s", strerror(errno));
retry_count++;
sleep(1);
continue;
}
continue;
}
evt_le_meta_event *meta = (evt_le_meta_event *)(buf + (1 + HCI_EVENT_HDR_SIZE));
if (meta->subevent != EVT_LE_ADVERTISING_REPORT) continue;
uint8_t *ptr = meta->data;
uint8_t reports = *ptr++;
for (int i = 0; i < reports; i++) {
le_advertising_info *info = (le_advertising_info *)ptr;
char addr[18];
ba2str(&info->bdaddr, addr);
int info_len = info->length;
int rssi_offset = (uint8_t *)info->data - buf + info_len;
int8_t rssi = (int8_t)buf[rssi_offset];
ParseData(info->data, info->length,rssi);
ptr += sizeof(le_advertising_info) + info->length + 1; // 最后的 +1 是 RSSI 字节
}
}
hci_le_set_scan_enable(sock, 0x00, 0x00, 1000);
close(sock);
}
void ScanBlueteeth::ParseData(unsigned char *data, int len,int8_t rssi){
if (len < 25) return;
// 找到 Manufacturer Specific 区块开头
for (int i = 0; i < len - 4; i++) {
if (data[i] == 0x06 && data[i+1] == 0x09 && data[i+2] == 0x43 && data[i+3] == 0x68 && data[i+4] == 0x61) {
char device_id[15]={0},mac[15] = {0},temp_bl[5]={0};
int count = 0;
sprintf(device_id,"%02x%02x%02x%02x%02x%02x",data[2],data[3],data[4],data[5],data[6],data[7]);
sprintf(mac,"%02x%02x%02x%02x%02x%02x",data[13],data[14],data[15],data[16],data[17],data[18]);
sprintf(temp_bl,"%02x%02x",data[i + 24],data[i + 25]);
int temp_ch = (data[i + 26] << 8) | data[i + 27];
int volt = data[i + 23];
short temp1001 = ((data[i + 28] << 8) | data[i + 29]) >> 4;
count = (data[i + 19] << 24) | (data[i + 20] << 16) | (data[i + 21] << 8) | data[i + 22];
long num = strtol(temp_bl, NULL, 16);
short signed_num = (short)num;
float blueteeth_temp = (float)signed_num*0.01;
float chip_temp = 0.0;
if (temp_ch == 0)
{
chip_temp = 1000;
}else{
chip_temp = ((float)temp_ch*0.0625) - 50.0625;
}
float env_temp = 0.0;
if (temp1001 < 0x800)
{
env_temp = (float)temp1001 * 0.0625;
}else{
env_temp = float((~temp1001) & 0xfff) * (-1) * 0.0625;
}
float volt_ = (double)volt * 0.03125;
// 打印原始广播数据十六进制
printf(" Raw Adv Data: ");
for (int k = 0; k < len; k++) {
printf("%02x ", data[k]);
}
printf("\n");
//printf("time %s Bluetooth temp :%f ℃ , NST 1001 temp: %f ℃\n",GetCurrentTime().c_str(),(float)temp*0.01, ((float)temp1*0.0625) - 50.0625);
//printf(" volt : %f v\n", (double)volt * 0.03125 );
char insertSql[512] = {0},whereCon[128] = {0};
char localtimestamp[32] = {0};
memset(whereCon,0,sizeof(whereCon));
sprintf(whereCon, "mac='%s' order by timeStamp desc limit 1", mac);
std::string timestamp_last = sqlite_db_ctrl::instance().GetData(" blueteeth_info ", " timeStamp ", whereCon);
GetTimeNet(localtimestamp, 1);
if (atol(localtimestamp) - atol(timestamp_last.c_str()) < 10) {
zlog_info(zct, "blueteeth_info already exist, mac = %s, timeStamp = %s", mac, timestamp_last.c_str());
return;
} else {
sprintf(insertSql,"'%s','%s','%d',%d,'%.1f','%.1f','%.1f','%.1f','%s'",device_id,mac,rssi,count,volt_,blueteeth_temp,chip_temp,env_temp,localtimestamp);
sqlite_db_ctrl::instance().InsertData(" blueteeth_info ", insertSql);
}
return;
}
}
}