added reporting uplink

This commit is contained in:
2026-07-15 16:59:03 +00:00
parent 37c286e756
commit 39a9916351
2 changed files with 73 additions and 2 deletions
+1
View File
@@ -18,6 +18,7 @@ Daemon that makes an OpenWrt router appear as a UniFi AP to UniFi Network contro
| **Wired Clients** | MACs from bridge FDB | `clients.c``bridge fdb` |
| **CPU / RAM** | Real-time usage | `sysinfo.c``/proc/stat` + `/proc/meminfo` |
| **Interfaces** | Speed, duplex, rx/tx counters | `sysinfo.c``/proc/net/dev` |
| **Wired Uplink** | Link state, speed, duplex, and counters for topology | `inform.c``uplink` |
| **Channel / RF** | Channel utilization, noise, tx_power | `sysinfo.c``iw survey dump` |
| **LLDP Send** | Custom frames via AF_PACKET raw socket | `lldp.c``lldp_send_frame()` |
| **LLDP Read** | Neighbors for UniFi topology | `lldp.c``lldpctl -f json` |
+72 -2
View File
@@ -314,6 +314,73 @@ static struct json_object *build_scan_table(const char *iface)
return arr;
}
/* Build the wired uplink object expected by UniFi controllers.
* The model owns the interface mapping; live state and counters come from
* sysfs and /proc so third-party upstream switches still get a usable link. */
static struct json_object *build_uplink(const uf_model_t *m,
const openuf_state_t *st)
{
const uf_port_t *port = NULL;
for (int i = 0; i < m->port_table_len; i++) {
if (m->port_table[i].is_uplink) {
port = &m->port_table[i];
break;
}
}
if (!port && m->port_table_len > 0)
port = &m->port_table[0];
struct json_object *o = json_object_new_object();
if (!port)
return o;
iface_stats_t stats;
sysinfo_iface(port->ifname, &stats);
int speed = stats.speed > 0 ? stats.speed : port->speed;
json_object_object_add(o, "name",
json_object_new_string(port->ifname));
json_object_object_add(o, "type",
json_object_new_string("wire"));
json_object_object_add(o, "media",
json_object_new_string(port->media));
json_object_object_add(o, "mac",
json_object_new_string(stats.mac[0] ? stats.mac : st->mac));
json_object_object_add(o, "ip",
json_object_new_string(stats.ip[0] ? stats.ip : "0.0.0.0"));
json_object_object_add(o, "num_port",
json_object_new_int(1));
json_object_object_add(o, "port_idx",
json_object_new_int(port->port_idx));
json_object_object_add(o, "up",
json_object_new_boolean(stats.up));
json_object_object_add(o, "speed",
json_object_new_int(speed));
json_object_object_add(o, "max_speed",
json_object_new_int(port->speed));
json_object_object_add(o, "full_duplex",
json_object_new_boolean(stats.full_duplex));
json_object_object_add(o, "rx_bytes",
json_object_new_int64(stats.rx_bytes));
json_object_object_add(o, "tx_bytes",
json_object_new_int64(stats.tx_bytes));
json_object_object_add(o, "rx_packets",
json_object_new_int64(stats.rx_packets));
json_object_object_add(o, "tx_packets",
json_object_new_int64(stats.tx_packets));
json_object_object_add(o, "rx_errors",
json_object_new_int64(stats.rx_errors));
json_object_object_add(o, "tx_errors",
json_object_new_int64(stats.tx_errors));
json_object_object_add(o, "rx_dropped",
json_object_new_int64(stats.rx_dropped));
json_object_object_add(o, "tx_dropped",
json_object_new_int64(stats.tx_dropped));
json_object_object_add(o, "rx_multicast",
json_object_new_int64(stats.rx_multicast));
return o;
}
/* ═══════════════════════════════════════════════════════════════════
radio_table — static definition of the radio hardware
═══════════════════════════════════════════════════════════════════
@@ -875,8 +942,6 @@ static char *build_payload(const openuf_state_t *st,
json_object_new_boolean(false));
json_object_object_add(root, "locating",
json_object_new_boolean(false));
json_object_object_add(root, "uplink",
json_object_new_string("eth0"));
json_object_object_add(root, "country_code",
json_object_new_int(0));
@@ -891,6 +956,11 @@ static char *build_payload(const openuf_state_t *st,
/* ── Ethernet interfaces with real counters ──────────────── */
json_object_object_add(root, "if_table", build_if_table(m, st));
/* ── Structured wired uplink for controller topology ─────── */
json_object_object_add(root, "uplink", build_uplink(m, st));
json_object_object_add(root, "uplink_table",
json_object_new_array());
/* Native informs carry RF counters in radio_table[].athstats. Keep the
* normalized table too for controller versions that consume it directly. */
struct json_object *radio_stats = build_radio_table_stats(m);