OreBolt-OS/modules/orebolt-radar/noise_radar.c

171 lines
5.9 KiB
C
Executable File

/*
* noise_radar.c -- BLE Device Radar Scanner module
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* v1.5: Restored from v1.3. Uses BlueZ HCI inquiry (with RSSI when
* available, standard inquiry fallback) to discover BLE devices.
* Displays up to 4 nodes with RSSI-based heatmap coloring on a
* 19-cell hexagonal grid.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <linux/input.h>
#include "h2_ui.h"
#include "log_manager.h"
#define MAX_CELLS 19
#define SCAN_INTERVAL 8
#define RSSI_UNKNOWN 0
typedef struct {
bdaddr_t addr;
int8_t rssi;
uint8_t active;
} ble_node_t;
static ble_node_t nodes[MAX_CELLS];
static int node_count;
static int scan_ble_nodes(int dev_id) {
int max_rsp = 255, len = 8, flags = IREQ_CACHE_FLUSH;
int num_rsp, new_count = 0;
inquiry_info_with_rssi *rssi_info = NULL;
num_rsp = hci_inquiry_with_rssi(dev_id, len, max_rsp, NULL, &rssi_info, flags);
if (num_rsp >= 0) {
for (int i = 0; i < num_rsp && new_count < MAX_CELLS; i++) {
memcpy(&nodes[new_count].addr, &rssi_info[i].bdaddr, sizeof(bdaddr_t));
nodes[new_count].rssi = rssi_info[i].rssi;
nodes[new_count].active = 1;
new_count++;
}
free(rssi_info);
return new_count;
}
inquiry_info *std_info = NULL;
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &std_info, flags);
if (num_rsp < 0) return num_rsp;
for (int i = 0; i < num_rsp && new_count < MAX_CELLS; i++) {
memcpy(&nodes[new_count].addr, &std_info[i].bdaddr, sizeof(bdaddr_t));
nodes[new_count].rssi = RSSI_UNKNOWN;
nodes[new_count].active = 1;
new_count++;
}
free(std_info);
return new_count;
}
static lv_color_t rssi_to_color(int8_t rssi) {
if (rssi == RSSI_UNKNOWN) return COLOR_MUTED;
if (rssi > -50) return lv_color_make(50, 255, 100);
if (rssi > -70) return COLOR_ACCENT;
return COLOR_PRIMARY;
}
static void format_rssi(char *buf, size_t len, int8_t rssi) {
if (rssi == RSSI_UNKNOWN) snprintf(buf, len, "rssi:?");
else snprintf(buf, len, "rssi:%d", (int)rssi);
}
int main(void) {
init_h2_graphics_runtime("BLE RADAR SCANNER");
LOG_INF("radar module started");
lv_obj_t *scr = lv_scr_act();
lv_obj_t *title = lv_label_create(scr);
lv_label_set_text(title, "BLE DEVICE RADAR");
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);
lv_obj_set_style_text_color(title, COLOR_PRIMARY, LV_PART_MAIN);
lv_obj_t *console = lv_label_create(scr);
lv_obj_set_width(console, 300);
lv_label_set_long_mode(console, LV_LABEL_LONG_WRAP);
lv_obj_align(console, LV_ALIGN_CENTER, 0, 20);
lv_obj_t *hex_grid[MAX_CELLS];
int start_x = 160, start_y = 120, spacing_x = 32, spacing_y = 28;
int cell_count = 0;
for (int r = -2; r <= 2; r++) {
int max_c = 5 - abs(r);
for (int c = 0; c < max_c; c++) {
if (cell_count >= MAX_CELLS) break;
hex_grid[cell_count] = lv_obj_create(scr);
lv_obj_set_size(hex_grid[cell_count], 26, 26);
lv_obj_set_style_radius(hex_grid[cell_count], LV_RADIUS_CIRCLE, LV_PART_MAIN);
int px = start_x + (c * spacing_x) - ((max_c - 1) * spacing_x / 2);
int py = start_y + (r * spacing_y);
lv_obj_set_pos(hex_grid[cell_count], px - 13, py - 13);
lv_obj_set_style_bg_color(hex_grid[cell_count], lv_color_make(30, 40, 50), LV_PART_MAIN);
cell_count++;
}
}
lv_obj_t *status = lv_label_create(scr);
lv_obj_align(status, LV_ALIGN_BOTTOM_MID, 0, -8);
lv_obj_set_style_text_color(status, COLOR_MUTED, LV_PART_MAIN);
int dev_id = hci_get_route(NULL);
int h_fd = (dev_id >= 0) ? hci_open_dev(dev_id) : -1;
if (h_fd < 0) LOG_WRN("cannot open HCI device");
int scan_tick = 0;
int input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
struct input_event ev;
while (1) {
lv_timer_handler();
scan_tick++;
if (scan_tick >= SCAN_INTERVAL && h_fd >= 0) {
scan_tick = 0;
memset(nodes, 0, sizeof(nodes));
node_count = scan_ble_nodes(dev_id);
for (int i = 0; i < cell_count; i++)
lv_obj_set_style_bg_color(hex_grid[i], lv_color_make(30, 40, 50), LV_PART_MAIN);
for (int i = 0; i < node_count && i < cell_count; i++)
lv_obj_set_style_bg_color(hex_grid[i], rssi_to_color(nodes[i].rssi), LV_PART_MAIN);
char addr_str[24], buf[256];
buf[0] = '\0';
for (int i = 0; i < node_count && i < 4; i++) {
ba2str(&nodes[i].addr, addr_str);
char rssi_str[16];
format_rssi(rssi_str, sizeof(rssi_str), nodes[i].rssi);
char line[64];
snprintf(line, sizeof(line), "%s %s\n", addr_str, rssi_str);
strlcat(buf, line, sizeof(buf));
}
if (node_count == 0) snprintf(buf, sizeof(buf), "No BLE devices in range");
lv_label_set_text(console, buf);
char count_str[48];
if (node_count > 0 && nodes[0].rssi == RSSI_UNKNOWN)
snprintf(count_str, sizeof(count_str), "Scan: %d node(s) [RSSI n/a]", node_count);
else
snprintf(count_str, sizeof(count_str), "Scan: %d node(s)", node_count);
lv_label_set_text(status, count_str);
}
if (input_fd >= 0 && read(input_fd, &ev, sizeof(struct input_event)) > 0) {
if (ev.type == EV_KEY && ev.code == H2_KEY_BACK && ev.value == 1) break;
}
usleep(40000);
}
if (h_fd >= 0) close(h_fd);
if (input_fd >= 0) close(input_fd);
LOG_INF("radar module exited");
return 0;
}