From 61fab057a8471d2a6096e96985719fce71274bf1 Mon Sep 17 00:00:00 2001
From: Jakob Olsson <jakob.olsson@iopsys.eu>
Date: Mon, 19 May 2025 10:13:09 +0200
Subject: [PATCH] add ubus stations method

---
 src/agent_ubus.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/src/agent_ubus.c b/src/agent_ubus.c
index 14bcfca93..200f23744 100644
--- a/src/agent_ubus.c
+++ b/src/agent_ubus.c
@@ -207,6 +207,16 @@ static const struct blobmsg_policy search_policy_params[__SEARCH_POLICY_MAX] = {
 	[SEARCH_POLICY_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
 };
 
+enum {
+	STATIONS_MACADDR,
+	__STATIONS_MAX,
+};
+
+static const struct blobmsg_policy station_params[__STATIONS_MAX] = {
+	[STATIONS_MACADDR] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING },
+};
+
+
 enum {
 	SET_BH_BAND,
 	SET_BH_TARGET_BSSID,
@@ -1129,6 +1139,82 @@ static int agent_set_backhaul(struct ubus_context *ctx, struct ubus_object *obj,
 	return UBUS_STATUS_OK;
 }
 
+static void agent_add_sta_info(struct blob_buf *bb, struct sta *s)
+{
+	void *t;
+
+	t = blobmsg_open_table(bb, "sta");
+	blobmsg_add_macaddr(bb, "macaddr", s->macaddr);
+	blobmsg_add_u64(bb, "connected_ms", s->connected_ms);
+	if (s->assoc_frame) {
+		char *frame;
+
+		frame = calloc(1, (s->assoc_frame->len * 2) + 1);
+		if (frame)
+			btostr(s->assoc_frame->frame, s->assoc_frame->len, frame);
+		blobmsg_add_string(bb, "assoc_request", frame);
+	} else
+		blobmsg_add_string(bb, "assoc_request", "");
+
+	blobmsg_close_table(bb, t);
+}
+
+static int agent_stations(struct ubus_context *ctx, struct ubus_object *obj,
+		struct ubus_request_data *req, const char *method,
+		struct blob_attr *msg)
+{
+	struct agent *a = container_of(obj, struct agent, obj);
+	struct blob_attr *tb[__STATIONS_MAX];
+	struct wifi_radio_element *re = NULL;
+	struct blob_buf bb = {0};
+	uint8_t macaddr[6] = {0};
+	void *t;
+
+	blobmsg_parse(station_params, __STATIONS_MAX, tb, blob_data(msg),
+			blob_len(msg));
+
+	blob_buf_init(&bb, 0);
+	t = blobmsg_open_array(&bb, "stations");
+
+	if (tb[STATIONS_MACADDR]) {
+		struct sta *s;
+
+		if (!hwaddr_aton(blobmsg_get_string(tb[STATIONS_MACADDR]),
+			    macaddr)) {
+			dbg("%s: invalid macaddr\n", __func__);
+			blob_buf_free(&bb);
+			return UBUS_STATUS_INVALID_ARGUMENT;
+		}
+
+		s = agent_get_sta(a, macaddr);
+		if (!s) {
+			dbg("%s: sta not found\n", __func__);
+			blob_buf_free(&bb);
+			return UBUS_STATUS_INVALID_ARGUMENT;
+		}
+
+		agent_add_sta_info(&bb, s);
+	} else {
+		list_for_each_entry(re, &a->radiolist, list) {
+			struct netif_ap *ap = NULL;
+
+			list_for_each_entry(ap, &re->aplist, list) {
+				struct sta *s = NULL;
+
+				list_for_each_entry(s, &ap->stalist, list)
+					agent_add_sta_info(&bb, s);
+			}
+		}
+	}
+
+
+	blobmsg_close_array(&bb, t);
+
+	ubus_send_reply(ctx, req, bb.head);
+	blob_buf_free(&bb);
+	return UBUS_STATUS_OK;
+}
+
 static int agent_trigger_dynamic_upgrade(struct ubus_context *ctx, struct ubus_object *obj,
 		struct ubus_request_data *req, const char *method,
 		struct blob_attr *msg)
@@ -1452,6 +1538,7 @@ int agent_publish_object(struct agent *a, const char *objname)
 		UBUS_METHOD_NOARG("dynamic_backhaul_upgrade", agent_trigger_dynamic_upgrade),
 		UBUS_METHOD_NOARG("backhaul_blacklist", agent_backhaul_blacklist),
 		UBUS_METHOD("set_backhaul", agent_set_backhaul, set_bh_params),
+		UBUS_METHOD("stations", agent_stations, station_params),
 #if (EASYMESH_VERSION > 2)
 		UBUS_METHOD_NOARG("bss_config_request", bss_config_request),
 #if 0
-- 
GitLab