hostapd: add support for querying bss config parameters via ubus
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>
This commit is contained in:
parent
efb8764a69
commit
ed484caa03
@ -30,6 +30,23 @@ hostapd.data.iface_fields = {
|
|||||||
iapp_interface: true,
|
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)
|
function iface_remove(cfg)
|
||||||
{
|
{
|
||||||
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
||||||
@ -752,6 +769,17 @@ function ex_wrap(func) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = {
|
let main_obj = {
|
||||||
reload: {
|
reload: {
|
||||||
args: {
|
args: {
|
||||||
@ -896,6 +924,32 @@ let main_obj = {
|
|||||||
return 0;
|
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;
|
hostapd.data.ubus = ubus;
|
||||||
|
@ -245,6 +245,33 @@ let main_obj = {
|
|||||||
return 0;
|
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;
|
wpas.data.ubus = ubus;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "ap/hostapd.h"
|
#include "ap/hostapd.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
|
#include "ctrl_iface.h"
|
||||||
#include "bss.h"
|
#include "bss.h"
|
||||||
#include "ucode.h"
|
#include "ucode.h"
|
||||||
|
|
||||||
@ -255,6 +256,31 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
|
|||||||
return ret;
|
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)
|
int wpas_ucode_init(struct wpa_global *gl)
|
||||||
{
|
{
|
||||||
static const uc_function_list_t global_fns[] = {
|
static const uc_function_list_t global_fns[] = {
|
||||||
@ -266,6 +292,7 @@ int wpas_ucode_init(struct wpa_global *gl)
|
|||||||
};
|
};
|
||||||
static const uc_function_list_t iface_fns[] = {
|
static const uc_function_list_t iface_fns[] = {
|
||||||
{ "status", uc_wpas_iface_status },
|
{ "status", uc_wpas_iface_status },
|
||||||
|
{ "ctrl", uc_wpas_iface_ctrl },
|
||||||
};
|
};
|
||||||
uc_value_t *data, *proto;
|
uc_value_t *data, *proto;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user