mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 09:32:34 +00:00
ipq807x_5.4: fix hostapd ap+sta issue
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
committed by
John Crispin
parent
e56a53e541
commit
f6ea5dd273
@@ -2,9 +2,10 @@ let libubus = require("ubus");
|
||||
import { open, readfile } from "fs";
|
||||
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
|
||||
|
||||
let ubus = libubus.connect();
|
||||
let ubus = libubus.connect(null, 60);
|
||||
|
||||
hostapd.data.config = {};
|
||||
hostapd.data.pending_config = {};
|
||||
|
||||
hostapd.data.file_fields = {
|
||||
vlan_file: true,
|
||||
@@ -127,12 +128,114 @@ function iface_update_supplicant_macaddr(phy, config)
|
||||
let macaddr_list = [];
|
||||
for (let i = 0; i < length(config.bss); i++)
|
||||
push(macaddr_list, config.bss[i].bssid);
|
||||
ubus.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
|
||||
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
|
||||
}
|
||||
|
||||
function __iface_pending_next(pending, state, ret, data)
|
||||
{
|
||||
let config = pending.config;
|
||||
let phydev = pending.phydev;
|
||||
let phy = pending.phy;
|
||||
let bss = config.bss[0];
|
||||
|
||||
if (pending.defer)
|
||||
pending.defer.abort();
|
||||
delete pending.defer;
|
||||
switch (state) {
|
||||
case "init":
|
||||
let macaddr_list = [];
|
||||
for (let i = 0; i < length(config.bss); i++)
|
||||
push(macaddr_list, config.bss[i].bssid);
|
||||
pending.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
|
||||
return "create_bss";
|
||||
case "create_bss":
|
||||
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
|
||||
if (err) {
|
||||
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
pending.call("wpa_supplicant", "phy_status", { phy: phy });
|
||||
return "check_phy";
|
||||
case "check_phy":
|
||||
let phy_status = data;
|
||||
if (phy_status && phy_status.state == "COMPLETED") {
|
||||
if (iface_add(phy, config, phy_status))
|
||||
return "done";
|
||||
|
||||
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
|
||||
}
|
||||
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
|
||||
return "wpas_stopped";
|
||||
case "wpas_stopped":
|
||||
if (!iface_add(phy, config))
|
||||
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
|
||||
pending.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
|
||||
return null;
|
||||
case "done":
|
||||
default:
|
||||
delete hostapd.data.pending_config[phy];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function iface_pending_next(ret, data)
|
||||
{
|
||||
let pending = true;
|
||||
let cfg = this;
|
||||
|
||||
while (pending) {
|
||||
this.next_state = __iface_pending_next(cfg, this.next_state, ret, data);
|
||||
if (!this.next_state) {
|
||||
__iface_pending_next(cfg, "done");
|
||||
return;
|
||||
}
|
||||
pending = !this.defer;
|
||||
}
|
||||
}
|
||||
|
||||
function iface_pending_abort()
|
||||
{
|
||||
this.next_state = "done";
|
||||
this.next();
|
||||
}
|
||||
|
||||
function iface_pending_ubus_call(obj, method, arg)
|
||||
{
|
||||
let ubus = hostapd.data.ubus;
|
||||
let pending = this;
|
||||
this.defer = ubus.defer(obj, method, arg, (ret, data) => { delete pending.defer; pending.next(ret, data) });
|
||||
}
|
||||
|
||||
const iface_pending_proto = {
|
||||
next: iface_pending_next,
|
||||
call: iface_pending_ubus_call,
|
||||
abort: iface_pending_abort,
|
||||
};
|
||||
|
||||
function iface_pending_init(phydev, config)
|
||||
{
|
||||
let phy = phydev.name;
|
||||
|
||||
let pending = proto({
|
||||
next_state: "init",
|
||||
phydev: phydev,
|
||||
phy: phy,
|
||||
config: config,
|
||||
next: iface_pending_next,
|
||||
}, iface_pending_proto);
|
||||
|
||||
hostapd.data.pending_config[phy] = pending;
|
||||
pending.next();
|
||||
}
|
||||
|
||||
function iface_restart(phydev, config, old_config)
|
||||
{
|
||||
let phy = phydev.name;
|
||||
let pending = hostapd.data.pending_config[phy];
|
||||
|
||||
if (pending)
|
||||
pending.abort();
|
||||
|
||||
hostapd.remove_iface(phy);
|
||||
iface_remove(old_config);
|
||||
@@ -150,26 +253,7 @@ function iface_restart(phydev, config, old_config)
|
||||
bss.bssid = phydev.macaddr_next();
|
||||
}
|
||||
|
||||
iface_update_supplicant_macaddr(phy, config);
|
||||
|
||||
let bss = config.bss[0];
|
||||
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
|
||||
if (err)
|
||||
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
||||
|
||||
let ubus = hostapd.data.ubus;
|
||||
let phy_status = ubus.call("wpa_supplicant", "phy_status", { phy: phy });
|
||||
if (phy_status && phy_status.state == "COMPLETED") {
|
||||
if (iface_add(phy, config, phy_status))
|
||||
return;
|
||||
|
||||
hostapd.printf(`Failed to bring up phy ${phy} ifname=${bss.ifname} with supplicant provided frequency`);
|
||||
}
|
||||
|
||||
ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
|
||||
if (!iface_add(phy, config))
|
||||
hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
|
||||
ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
|
||||
iface_pending_init(phydev, config);
|
||||
}
|
||||
|
||||
function array_to_obj(arr, key, start)
|
||||
@@ -274,16 +358,19 @@ function iface_reload_config(phydev, config, old_config)
|
||||
if (is_equal(old_config.bss, config.bss))
|
||||
return true;
|
||||
|
||||
if (hostapd.data.pending_config[phy])
|
||||
return false;
|
||||
|
||||
if (!old_config.bss || !old_config.bss[0])
|
||||
return false;
|
||||
|
||||
let iface = hostapd.interfaces[phy];
|
||||
let iface_name = old_config.bss[0].ifname;
|
||||
if (!iface) {
|
||||
hostapd.printf(`Could not find previous interface ${iface_name}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let iface_name = old_config.bss[0].ifname;
|
||||
let first_bss = hostapd.bss[iface_name];
|
||||
if (!first_bss) {
|
||||
hostapd.printf(`Could not find bss of previous interface ${iface_name}`);
|
||||
@@ -571,7 +658,7 @@ function iface_load_config(filename)
|
||||
|
||||
let bss;
|
||||
let line;
|
||||
while ((line = trim(f.read("line"))) != null) {
|
||||
while ((line = rtrim(f.read("line"), "\n")) != null) {
|
||||
let val = split(line, "=", 2);
|
||||
if (!val[0])
|
||||
continue;
|
||||
@@ -593,7 +680,7 @@ function iface_load_config(filename)
|
||||
push(config.radio.data, line);
|
||||
}
|
||||
|
||||
while ((line = trim(f.read("line"))) != null) {
|
||||
while ((line = rtrim(f.read("line"), "\n")) != null) {
|
||||
if (line == "#default_macaddr")
|
||||
bss.default_macaddr = true;
|
||||
|
||||
|
||||
@@ -107,14 +107,14 @@
|
||||
hostapd_ubus_free_bss(hapd);
|
||||
accounting_deinit(hapd);
|
||||
hostapd_deinit_wpa(hapd);
|
||||
@@ -502,6 +505,7 @@ static void sta_track_deinit(struct host
|
||||
void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
|
||||
@@ -531,6 +534,7 @@ void hostapd_cleanup_iface_partial(struc
|
||||
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
|
||||
+ hostapd_ucode_free_iface(iface);
|
||||
eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
|
||||
#ifdef NEED_AP_MLME
|
||||
hostapd_stop_setup_timers(iface);
|
||||
eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
|
||||
NULL);
|
||||
|
||||
@@ -1104,7 +1108,7 @@ static int db_table_create_radius_attrib
|
||||
* initialized. Most of the modules that are initialized here will be
|
||||
* deinitialized in hostapd_cleanup().
|
||||
|
||||
@@ -1380,9 +1380,9 @@ Tested-by: Allen Ye <allen.ye@mediatek.com>
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
|
||||
+ hostapd_afc_stop(iface);
|
||||
hostapd_ucode_free_iface(iface);
|
||||
eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
|
||||
#ifdef NEED_AP_MLME
|
||||
hostapd_stop_setup_timers(iface);
|
||||
@@ -2149,6 +2150,16 @@ static int hostapd_setup_interface_compl
|
||||
}
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
Reference in New Issue
Block a user