#include "scan_blueteeth.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #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; } } }