Skip to content

Commit

Permalink
hostapd: reimplement AP/STA support via ucode
Browse files Browse the repository at this point in the history
Drop obsolete control interface patches.
This fixes some corner cases in the previous code where the segment 0 center
frequency was not adjusted properly, leading to logspam and non-working AP
interfaces.
Additionally, shutting down the AP was broken, because the next beacon update
would re-enable it, leading to a race condition on assoc.

Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
nbd168 committed Aug 10, 2023
1 parent ed0ad77 commit 847984c
Show file tree
Hide file tree
Showing 30 changed files with 643 additions and 958 deletions.
2 changes: 1 addition & 1 deletion package/network/services/hostapd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=hostapd
PKG_RELEASE:=1.2
PKG_RELEASE:=2

PKG_SOURCE_URL:=http://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
Expand Down
72 changes: 72 additions & 0 deletions package/network/services/hostapd/files/hostapd.uc
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,78 @@ let main_obj = {
return 0;
}
},
apsta_state: {
args: {
phy: "",
up: true,
frequency: 0,
sec_chan_offset: 0,
csa: true,
csa_count: 0,
},
call: function(req) {
if (req.args.up == null || !req.args.phy)
return libubus.STATUS_INVALID_ARGUMENT;

let phy = req.args.phy;
let config = hostapd.data.config[phy];
if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname)
return 0;

let iface = hostapd.interfaces[config.bss[0].ifname];
if (!iface)
return 0;

if (!req.args.up) {
iface.stop();
return 0;
}

let freq = req.args.frequency;
if (!freq)
return libubus.STATUS_INVALID_ARGUMENT;

let sec_offset = req.args.sec_chan_offset;
if (sec_offset != -1 && sec_offset != 1)
sec_offset = 0;

let width = 0;
for (let line in config.radio.data) {
if (!sec_offset && match(line, /^ht_capab=.*HT40/)) {
sec_offset = null; // auto-detect
continue;
}

let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth)=(\d+)/);
if (!val)
continue;

val = int(val[2]);
if (val > width)
width = val;
}

if (freq < 4000)
width = 0;

let freq_info = hostapd.freq_info(freq, sec_offset, width);
if (!freq_info)
return libubus.STATUS_UNKNOWN_ERROR;

let ret;
if (req.args.csa) {
freq_info.csa_count = req.args.csa_count ?? 10;
ret = iface.switch_channel(freq_info);
} else {
iface.stop();
ret = iface.start(freq_info);
}
if (!ret)
return libubus.STATUS_UNKNOWN_ERROR;

return 0;
}
},
config_set: {
args: {
phy: "",
Expand Down
65 changes: 65 additions & 0 deletions package/network/services/hostapd/files/wpa_supplicant.uc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { wdev_create, wdev_remove, is_equal, vlist_new } from "common";
let ubus = libubus.connect();
wpas.data.config = {};
wpas.data.iface_phy = {};
function iface_stop(iface)
{
let ifname = iface.config.iface;
delete wpas.data.iface_phy[ifname];
wpas.remove_iface(ifname);
wdev_remove(ifname);
iface.running = false;
Expand All @@ -22,6 +24,7 @@ function iface_start(phy, iface)
let ifname = iface.config.iface;
wpas.data.iface_phy[ifname] = phy;
wdev_remove(ifname);
let ret = wdev_create(phy, ifname, iface.config);
if (ret)
Expand Down Expand Up @@ -146,16 +149,78 @@ function iface_event(type, name, data) {
ubus.call("service", "event", { type: `wpa_supplicant.${name}.${type}`, data: {} });
}
function iface_hostapd_notify(phy, ifname, iface, state)
{
let ubus = wpas.data.ubus;
let status = iface.status();
let msg = { phy: phy };
switch (state) {
case "DISCONNECTED":
case "AUTHENTICATING":
msg.up = false;
break;
case "INTERFACE_DISABLED":
case "INACTIVE":
msg.up = true;
break;
case "COMPLETED":
msg.up = true;
msg.frequency = status.frequency;
msg.sec_chan_offset = status.sec_chan_offset;
break;
default:
return;
}
ubus.call("hostapd", "apsta_state", msg);
}
function iface_channel_switch(phy, ifname, iface, info)
{
let msg = {
phy: phy,
up: true,
csa: true,
csa_count: info.csa_count ? info.csa_count - 1 : 0,
frequency: info.frequency,
sec_chan_offset: info.sec_chan_offset,
};
ubus.call("hostapd", "apsta_state", msg);
}
return {
shutdown: function() {
for (let phy in wpas.data.config)
set_config(phy, []);
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;
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
return;
}
iface_hostapd_notify(phy, ifname, iface, state);
},
event: function(iface, ev, info) {
let ifname = iface.data.name;
let phy = wpas.data.iface_phy[ifname];
if (!phy) {
wpas.printf(`no PHY for ifname ${ifname}`);
return;
}
if (ev == "CH_SWITCH_STARTED")
iface_channel_switch(phy, ifname, iface, info);
}
};

This file was deleted.

106 changes: 0 additions & 106 deletions package/network/services/hostapd/patches/360-ctrl_iface_reload.patch

This file was deleted.

Loading

0 comments on commit 847984c

Please sign in to comment.