It cannot be properly cloned, since it is attached to the resource type.
Use a separate registry for data. Fixes object confusion issues
Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (config.bss[0].ifname != old_config.bss[0].ifname)
return false;
- let iface = hostapd.interfaces[config.bss[0].ifname];
+ let iface_name = config.bss[0].ifname;
+ let iface = hostapd.interfaces[iface_name];
if (!iface)
return false;
+ let first_bss = hostapd.bss[iface_name];
+ if (!first_bss)
+ return false;
+
let config_inline = iface_gen_config(phy, config);
- bss_reload_psk(iface.bss[0], config.bss[0], old_config.bss[0]);
+ bss_reload_psk(first_bss, config.bss[0], old_config.bss[0]);
if (!is_equal(config.bss[0], old_config.bss[0])) {
if (phy_is_fullmac(phy))
return false;
return false;
hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
- if (iface.bss[0].set_config(config_inline, 0) < 0) {
+ if (first_bss.set_config(config_inline, 0) < 0) {
hostapd.printf(`Failed to set config`);
return false;
}
}
- let bss_list = array_to_obj(iface.bss, "name", 1);
let new_cfg = array_to_obj(config.bss, "ifname", 1);
let old_cfg = array_to_obj(old_config.bss, "ifname", 1);
for (let name in old_cfg) {
- let bss = bss_list[name];
+ let bss = hostapd.bss[name];
if (!bss) {
hostapd.printf(`bss '${name}' not found`);
return false;
if (!phy)
return libubus.STATUS_NOT_FOUND;
- if (req.args.stop) {
- for (let ifname in phy.data)
- iface_stop(phy.data[ifname]);
- } else {
- start_pending(req.args.phy);
+ try {
+ if (req.args.stop) {
+ for (let ifname in phy.data)
+ iface_stop(phy.data[ifname]);
+ } else {
+ start_pending(req.args.phy);
+ }
+ } catch (e) {
+ wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
+ return libubus.STATUS_INVALID_ARGUMENT;
}
return 0;
}
wpas.ubus.disconnect();
},
iface_add: function(name, obj) {
- obj.data.name = name;
iface_event("add", name);
},
iface_remove: function(name, obj) {
iface_event("remove", name);
},
- state: function(iface, state) {
- let ifname = iface.data.name;
+ state: function(ifname, iface, state) {
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
iface_hostapd_notify(phy, ifname, iface, state);
},
- event: function(iface, ev, info) {
- let ifname = iface.data.name;
+ event: function(ifname, iface, ev, info) {
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx);
val = uc_resource_new(bss_type, hapd);
- wpa_ucode_registry_add(bss_registry, val, &hapd->ucode.idx);
+ hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val);
return val;
}
return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx);
val = uc_resource_new(iface_type, hapd);
- wpa_ucode_registry_add(iface_registry, val, &hapd->ucode.idx);
+ hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
return val;
}
static void
-hostapd_ucode_update_bss_list(struct hostapd_iface *iface)
+hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss)
{
- uc_value_t *ifval, *list;
+ uc_value_t *list;
int i;
list = ucv_array_new(vm);
for (i = 0; i < iface->num_bss; i++) {
struct hostapd_data *hapd = iface->bss[i];
uc_value_t *val = hostapd_ucode_bss_get_uval(hapd);
- uc_value_t *proto = ucv_prototype_get(val);
- ucv_object_add(proto, "name", ucv_get(ucv_string_new(hapd->conf->iface)));
- ucv_object_add(proto, "index", ucv_int64_new(i));
- ucv_array_set(list, i, ucv_get(val));
+ ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface)));
+ ucv_object_add(bss, hapd->conf->iface, ucv_get(val));
}
-
- ifval = hostapd_ucode_iface_get_uval(iface);
- ucv_object_add(ucv_prototype_get(ifval), "bss", ucv_get(list));
+ ucv_object_add(if_bss, iface->phy, ucv_get(list));
}
static void
hostapd_ucode_update_interfaces(void)
{
uc_value_t *ifs = ucv_object_new(vm);
+ uc_value_t *if_bss = ucv_array_new(vm);
+ uc_value_t *bss = ucv_object_new(vm);
int i;
for (i = 0; i < interfaces->count; i++) {
struct hostapd_iface *iface = interfaces->iface[i];
ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface)));
- hostapd_ucode_update_bss_list(iface);
+ hostapd_ucode_update_bss_list(iface, if_bss, bss);
}
ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs));
+ ucv_object_add(ucv_prototype_get(global), "interface_bss", ucv_get(if_bss));
+ ucv_object_add(ucv_prototype_get(global), "bss", ucv_get(bss));
ucv_gc(vm);
}
hostapd_config_free_bss(hapd->conf);
os_free(hapd);
- hostapd_ucode_update_bss_list(iface);
+ hostapd_ucode_update_interfaces();
ucv_gc(vm);
return NULL;
iface->conf->bss[iface->conf->num_bss] = bss;
conf->bss[idx] = NULL;
ret = hostapd_ucode_bss_get_uval(hapd);
- hostapd_ucode_update_bss_list(iface);
+ hostapd_ucode_update_interfaces();
goto out;
deinit_ctrl:
return global;
}
-static uc_value_t *wpa_ucode_prototype_clone(uc_value_t *uval)
-{
- uc_value_t *proto, *proto_new;
-
- proto = ucv_prototype_get(uval);
- proto_new = ucv_object_new(&vm);
-
- ucv_object_foreach(proto, key, val)
- ucv_object_add(proto_new, key, ucv_get(val));
- ucv_prototype_set(uval, ucv_get(proto));
-
- return proto;
-}
-
-void wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val, int *idx)
+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val)
{
uc_value_t *data;
int i = 0;
ucv_array_set(reg, i, ucv_get(val));
- data = ucv_object_new(&vm);
- ucv_object_add(wpa_ucode_prototype_clone(val), "data", ucv_get(data));
-
- *idx = i + 1;
+ return i + 1;
}
uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx)
uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type);
-void wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val, int *idx);
+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val);
uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx);
uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx);
return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx);
val = uc_resource_new(iface_type, wpa_s);
- wpa_ucode_registry_add(iface_registry, val, &wpa_s->ucode.idx);
+ wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
return val;
}
return;
state = wpa_supplicant_state_txt(wpa_s->wpa_state);
+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
uc_value_push(ucv_get(val));
uc_value_push(ucv_get(ucv_string_new(state)));
- ucv_put(wpa_ucode_call(2));
+ ucv_put(wpa_ucode_call(3));
ucv_gc(vm);
}
if (wpa_ucode_call_prepare("event"))
return;
+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
uc_value_push(ucv_get(val));
uc_value_push(ucv_get(ucv_string_new(event_to_string(event))));
val = ucv_object_new(vm);
ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2));
}
- ucv_put(wpa_ucode_call(3));
+ ucv_put(wpa_ucode_call(4));
ucv_gc(vm);
}
iface_type = uc_type_declare(vm, "wpas.iface", iface_fns, NULL);
iface_registry = ucv_array_new(vm);
- uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry);
+ uc_vm_registry_set(vm, "wpas.iface_registry", iface_registry);
global = wpa_ucode_global_init("wpas", global_type);