3 import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, wdev_remove, wdev_set_up, phy_open } from "/usr/share/hostap/common.uc";
4 import { readfile, writefile, basename, readlink, glob } from "fs";
5 let libubus = require("ubus");
9 let command = shift(ARGV);
12 function iface_stop(wdev)
14 if (keep_devices[wdev.ifname])
17 wdev_remove(wdev.ifname);
20 function iface_start(wdev)
22 let ifname = wdev.ifname;
24 if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
25 wdev_set_up(ifname, false);
30 wdev_config[key] = wdev[key];
31 if (!wdev_config.macaddr && wdev.mode != "monitor")
32 wdev_config.macaddr = phydev.macaddr_next();
33 wdev_create(phy, ifname, wdev_config);
34 wdev_set_up(ifname, true);
35 let htmode = wdev.htmode || "NOHT";
37 system(`iw dev ${ifname} set freq ${wdev.freq} ${htmode}`);
38 if (wdev.mode == "adhoc") {
39 let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, htmode, "fixed-freq" ];
41 push(cmd, wdev.bssid);
42 for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
44 push(cmd, key, wdev[key]);
46 } else if (wdev.mode == "mesh") {
47 let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, htmode ];
48 for (let key in [ "mcast-rate", "beacon-interval" ])
50 push(cmd, key, wdev[key]);
53 wdev_set_mesh_params(ifname, wdev);
57 function iface_cb(new_if, old_if)
59 if (old_if && new_if && is_equal(old_if, new_if))
68 function drop_inactive(config)
70 for (let key in config) {
71 if (!readfile(`/sys/class/net/${key}/ifindex`))
76 function add_ifname(config)
78 for (let key in config)
79 config[key].ifname = key;
82 function delete_ifname(config)
84 for (let key in config)
85 delete config[key].ifname;
88 function add_existing(phy, config)
90 let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
91 wdevs = map(wdevs, (arg) => basename(arg));
92 for (let wdev in wdevs) {
96 if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
99 if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
106 warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
109 set_config <config> [<device]...] - set phy configuration
110 get_macaddr <id> - get phy MAC address for vif index <id>
116 set_config: function(args) {
117 let statefile = `/var/run/wdev-${phy}.json`;
119 let new_config = shift(args);
120 for (let dev in ARGV)
121 keep_devices[dev] = true;
126 new_config = json(new_config);
128 warn("Invalid configuration\n");
132 let old_config = readfile(statefile);
134 old_config = json(old_config);
136 let config = vlist_new(iface_cb);
137 if (type(old_config) == "object")
138 config.data = old_config;
140 add_existing(phy, config.data);
141 add_ifname(config.data);
142 drop_inactive(config.data);
144 let ubus = libubus.connect();
145 let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
146 let macaddr_list = [];
147 if (type(data) == "object" && data.macaddr)
148 macaddr_list = data.macaddr;
150 phydev.macaddr_init(macaddr_list);
152 add_ifname(new_config);
153 config.update(new_config);
155 drop_inactive(config.data);
156 delete_ifname(config.data);
157 writefile(statefile, sprintf("%J", config.data));
159 get_macaddr: function(args) {
162 for (let arg in args) {
163 arg = split(arg, "=", 2);
164 data[arg[0]] = arg[1];
167 let macaddr = phydev.macaddr_generate(data);
169 warn(`Could not get MAC address for phy ${phy}\n`);
173 print(macaddr + "\n");
177 if (!phy || !command | !commands[command])
180 phydev = phy_open(phy);
182 warn(`PHY ${phy} does not exist\n`);
186 commands[command](ARGV);