Supports reading the same parameters currently being used by iwinfo.
Preparation for replacing iwinfo with a rewrite in ucode.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
iapp_interface: true,
};
+hostapd.data.bss_info_fields = {
+ // radio
+ hw_mode: true,
+ channel: true,
+ ieee80211ac: true,
+ ieee80211ax: true,
+
+ // bss
+ bssid: true,
+ ssid: true,
+ wpa: true,
+ wpa_key_mgmt: true,
+ wpa_pairwise: true,
+ auth_algs: true,
+ ieee80211w: true,
+};
+
function iface_remove(cfg)
{
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
};
}
+function bss_config(bss_name) {
+ for (let phy, config in hostapd.data.config) {
+ if (!config)
+ continue;
+
+ for (let bss in config.bss)
+ if (bss.ifname == bss_name)
+ return [ config, bss ];
+ }
+}
+
let main_obj = {
reload: {
args: {
return 0;
})
},
+ bss_info: {
+ args: {
+ iface: ""
+ },
+ call: ex_wrap(function(req) {
+ if (!req.args.iface)
+ return libubus.STATUS_INVALID_ARGUMENT;
+
+ let config = bss_config(req.args.iface);
+ if (!config)
+ return libubus.STATUS_NOT_FOUND;
+
+ let bss = config[1];
+ config = config[0];
+ let ret = {};
+
+ for (let line in [ ...config.radio.data, ...bss.data ]) {
+ let fields = split(line, "=", 2);
+ let name = fields[0];
+ if (hostapd.data.bss_info_fields[name])
+ ret[name] = fields[1];
+ }
+
+ return ret;
+ })
+ },
};
hostapd.data.ubus = ubus;
return 0;
}
},
+ bss_info: {
+ args: {
+ iface: "",
+ },
+ call: function(req) {
+ let ifname = req.args.iface;
+ if (!ifname)
+ return libubus.STATUS_INVALID_ARGUMENT;
+
+ let iface = wpas.interfaces[ifname];
+ if (!iface)
+ return libubus.STATUS_NOT_FOUND;
+
+ let status = iface.ctrl("STATUS");
+ if (!status)
+ return libubus.STATUS_NOT_FOUND;
+
+ let ret = {};
+ status = split(status, "\n");
+ for (let line in status) {
+ line = split(line, "=", 2);
+ ret[line[0]] = line[1];
+ }
+
+ return ret;
+ }
+ },
};
wpas.data.ubus = ubus;
#include "ap/hostapd.h"
#include "wpa_supplicant_i.h"
#include "wps_supplicant.h"
+#include "ctrl_iface.h"
#include "bss.h"
#include "ucode.h"
return ret;
}
+static uc_value_t *
+uc_wpas_iface_ctrl(uc_vm_t *vm, size_t nargs)
+{
+ struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface");
+ uc_value_t *arg = uc_fn_arg(0);
+ size_t reply_len;
+ uc_value_t *ret;
+ char *reply;
+
+ if (!wpa_s || ucv_type(arg) != UC_STRING)
+ return NULL;
+
+ reply = wpa_supplicant_ctrl_iface_process(wpa_s, ucv_string_get(arg), &reply_len);
+ if (reply_len < 0)
+ return NULL;
+
+ if (reply_len && reply[reply_len - 1] == '\n')
+ reply_len--;
+
+ ret = ucv_string_new_length(reply, reply_len);
+ free(reply);
+
+ return ret;
+}
+
int wpas_ucode_init(struct wpa_global *gl)
{
static const uc_function_list_t global_fns[] = {
};
static const uc_function_list_t iface_fns[] = {
{ "status", uc_wpas_iface_status },
+ { "ctrl", uc_wpas_iface_ctrl },
};
uc_value_t *data, *proto;