[rdkb][common][bsp][Add hostapd ucode support]

[Description]
Add hostapd ucode support for wifi7

[Release-log]

Change-Id: Ic4c3cca4a36a11fc3f9f9fdc94842b66a00721bf
diff --git a/recipes-wifi/hostapd/files/wdev.uc b/recipes-wifi/hostapd/files/wdev.uc
index 5b32142..cf438f7 100644
--- a/recipes-wifi/hostapd/files/wdev.uc
+++ b/recipes-wifi/hostapd/files/wdev.uc
@@ -1,11 +1,14 @@
 #!/usr/bin/env ucode
 'use strict';
-import { vlist_new, is_equal, wdev_create, wdev_remove } from "/usr/share/hostap/common.uc";
+import { vlist_new, is_equal, wdev_create, wdev_remove, phy_open } from "/usr/share/hostap/common.uc";
 import { readfile, writefile, basename, readlink, glob } from "fs";
+let libubus = require("ubus");
 
 let keep_devices = {};
 let phy = shift(ARGV);
-let new_config = shift(ARGV);
+let command = shift(ARGV);
+let phydev;
+
 const mesh_params = [
 	"mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links",
 	"mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries",
@@ -33,7 +36,12 @@
 		system([ "ip", "link", "set", "dev", ifname, "down" ]);
 		wdev_remove(ifname);
 	}
-	wdev_create(phy, ifname, wdev);
+	let wdev_config = {};
+	for (let key in wdev)
+		wdev_config[key] = wdev[key];
+	if (!wdev_config.macaddr && wdev.mode != "monitor")
+		wdev_config.macaddr = phydev.macaddr_next();
+	wdev_create(phy, ifname, wdev_config);
 	system([ "ip", "link", "set", "dev", ifname, "up" ]);
 	if (wdev.freq)
 		system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
@@ -47,7 +55,7 @@
 		system(cmd);
 	} else if (wdev.mode == "mesh") {
 		let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
-		for (let key in [ "beacon-interval", "mcast-rate" ])
+		for (let key in [ "mcast-rate", "beacon-interval" ])
 			if (wdev[key])
 				push(cmd, key, wdev[key]);
 		system(cmd);
@@ -114,43 +122,86 @@
 	}
 }
 
-
-let statefile = `/var/run/wdev-${phy}.json`;
-
-for (let dev in ARGV)
-	keep_devices[dev] = true;
+function usage()
+{
+	warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
 
-if (!phy || !new_config) {
-	warn(`Usage: ${basename(sourcepath())} <phy> <config> [<device]...]\n`);
+Commands:
+	set_config <config> [<device]...] - set phy configuration
+	get_macaddr <id>		  - get phy MAC address for vif index <id>
+`);
 	exit(1);
 }
 
-if (!readfile(`/sys/class/ieee80211/${phy}/index`)) {
-	warn(`PHY ${phy} does not exist\n`);
-	exit(1);
-}
+const commands = {
+	set_config: function(args) {
+		let statefile = `/var/run/wdev-${phy}.json`;
 
-new_config = json(new_config);
-if (!new_config) {
-	warn("Invalid configuration\n");
-	exit(1);
-}
+		let new_config = shift(args);
+		for (let dev in ARGV)
+			keep_devices[dev] = true;
 
-let old_config = readfile(statefile);
-if (old_config)
-	old_config = json(old_config);
+		if (!new_config)
+			usage();
 
-let config = vlist_new(iface_cb);
-if (type(old_config) == "object")
-	config.data = old_config;
+		new_config = json(new_config);
+		if (!new_config) {
+			warn("Invalid configuration\n");
+			exit(1);
+		}
 
-add_existing(phy, config.data);
-add_ifname(config.data);
-drop_inactive(config.data);
+		let old_config = readfile(statefile);
+		if (old_config)
+			old_config = json(old_config);
 
-add_ifname(new_config);
-config.update(new_config);
+		let config = vlist_new(iface_cb);
+		if (type(old_config) == "object")
+			config.data = old_config;
+
+		add_existing(phy, config.data);
+		add_ifname(config.data);
+		drop_inactive(config.data);
+
+		let ubus = libubus.connect();
+		let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
+		let macaddr_list = [];
+		if (type(data) == "object" && data.macaddr)
+			macaddr_list = data.macaddr;
+		ubus.disconnect();
+		phydev.macaddr_init(macaddr_list);
+
+		add_ifname(new_config);
+		config.update(new_config);
+
+		drop_inactive(config.data);
+		delete_ifname(config.data);
+		writefile(statefile, sprintf("%J", config.data));
+	},
+	get_macaddr: function(args) {
+		let data = {};
+
+		for (let arg in args) {
+			arg = split(arg, "=", 2);
+			data[arg[0]] = arg[1];
+		}
+
+		let macaddr = phydev.macaddr_generate(data);
+		if (!macaddr) {
+			warn(`Could not get MAC address for phy ${phy}\n`);
+			exit(1);
+		}
+
+		print(macaddr + "\n");
+	},
+};
+
+if (!phy || !command | !commands[command])
+	usage();
+
+phydev = phy_open(phy);
+if (!phydev) {
+	warn(`PHY ${phy} does not exist\n`);
+	exit(1);
+}
 
-drop_inactive(config.data);
-delete_ifname(config.data);
-writefile(statefile, sprintf("%J", config.data));
+commands[command](ARGV);