mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 18:07:52 +00:00 
			
		
		
		
	hostapd: update v5.4 version to latest hot-reload version
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		| @@ -84,6 +84,8 @@ ifneq ($(CONFIG_DRIVER_11AX_SUPPORT),) | |||||||
|   HOSTAPD_IEEE80211AX:=y |   HOSTAPD_IEEE80211AX:=y | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | CORE_DEPENDS = +libubus +libucode +ucode-mod-fs +ucode-mod-nl80211 +ucode-mod-ubus +ucode-mod-uloop +libblobmsg-json | ||||||
|  |  | ||||||
| DRIVER_MAKEOPTS= \ | DRIVER_MAKEOPTS= \ | ||||||
| 	CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ | 	CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ | ||||||
| 	CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ | 	CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ | ||||||
| @@ -91,6 +93,7 @@ DRIVER_MAKEOPTS= \ | |||||||
| 	CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ | 	CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ | ||||||
| 	CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ | 	CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ | ||||||
| 	CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ | 	CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ | ||||||
|  | 	CONFIG_UCODE=y | ||||||
|  |  | ||||||
| ifeq ($(SSL_VARIANT),openssl) | ifeq ($(SSL_VARIANT),openssl) | ||||||
|   DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_SAE=y |   DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_SAE=y | ||||||
| @@ -142,7 +145,7 @@ define Package/hostapd/Default | |||||||
|   SUBMENU:=WirelessAPD |   SUBMENU:=WirelessAPD | ||||||
|   TITLE:=IEEE 802.1x Authenticator |   TITLE:=IEEE 802.1x Authenticator | ||||||
|   URL:=http://hostap.epitest.fi/ |   URL:=http://hostap.epitest.fi/ | ||||||
|   DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus |   DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) | ||||||
|   USERID:=network=101:network=101 |   USERID:=network=101:network=101 | ||||||
|   PROVIDES:=hostapd |   PROVIDES:=hostapd | ||||||
|   CONFLICTS:=$(HOSTAPD_PROVIDERS) |   CONFLICTS:=$(HOSTAPD_PROVIDERS) | ||||||
| @@ -226,7 +229,7 @@ define Package/wpad/Default | |||||||
|   CATEGORY:=Network |   CATEGORY:=Network | ||||||
|   SUBMENU:=WirelessAPD |   SUBMENU:=WirelessAPD | ||||||
|   TITLE:=IEEE 802.1x Auth/Supplicant |   TITLE:=IEEE 802.1x Auth/Supplicant | ||||||
|   DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus |   DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) | ||||||
|   USERID:=network=101:network=101 |   USERID:=network=101:network=101 | ||||||
|   URL:=http://hostap.epitest.fi/ |   URL:=http://hostap.epitest.fi/ | ||||||
|   PROVIDES:=hostapd wpa-supplicant |   PROVIDES:=hostapd wpa-supplicant | ||||||
| @@ -341,7 +344,7 @@ define Package/wpa-supplicant/Default | |||||||
|   SUBMENU:=WirelessAPD |   SUBMENU:=WirelessAPD | ||||||
|   TITLE:=WPA Supplicant |   TITLE:=WPA Supplicant | ||||||
|   URL:=http://hostap.epitest.fi/wpa_supplicant/ |   URL:=http://hostap.epitest.fi/wpa_supplicant/ | ||||||
|   DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus |   DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) | ||||||
|   USERID:=network=101:network=101 |   USERID:=network=101:network=101 | ||||||
|   PROVIDES:=wpa-supplicant |   PROVIDES:=wpa-supplicant | ||||||
|   CONFLICTS:=$(SUPPLICANT_PROVIDERS) |   CONFLICTS:=$(SUPPLICANT_PROVIDERS) | ||||||
| @@ -446,7 +449,7 @@ define Package/eapol-test/Default | |||||||
|   SECTION:=net |   SECTION:=net | ||||||
|   SUBMENU:=WirelessAPD |   SUBMENU:=WirelessAPD | ||||||
|   CATEGORY:=Network |   CATEGORY:=Network | ||||||
|   DEPENDS:=$(DRV_DEPENDS) +libubus |   DEPENDS:=$(DRV_DEPENDS) $(CORE_DEPENDS) | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Package/eapol-test | define Package/eapol-test | ||||||
| @@ -503,7 +506,7 @@ TARGET_CPPFLAGS := \ | |||||||
| 	$(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) | 	$(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) | ||||||
|  |  | ||||||
| TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto | TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto | ||||||
| TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin -lubox -lubus | TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin -lubox -lubus -lucode | ||||||
|  |  | ||||||
| ifdef CONFIG_PACKAGE_kmod-cfg80211 | ifdef CONFIG_PACKAGE_kmod-cfg80211 | ||||||
|   TARGET_LDFLAGS += -lm -lnl-tiny |   TARGET_LDFLAGS += -lm -lnl-tiny | ||||||
| @@ -587,20 +590,24 @@ define Build/Compile | |||||||
| endef | endef | ||||||
|  |  | ||||||
| define Install/hostapd | define Install/hostapd | ||||||
| 	$(INSTALL_DIR) $(1)/usr/sbin | 	$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap | ||||||
|  | 	$(INSTALL_DATA) ./files/hostapd.uc $(1)/usr/share/hostap/ | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Install/supplicant | define Install/supplicant | ||||||
| 	$(INSTALL_DIR) $(1)/usr/sbin | 	$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap | ||||||
|  | 	$(INSTALL_DATA) ./files/wpa_supplicant.uc $(1)/usr/share/hostap/ | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Package/hostapd-common/install | define Package/hostapd-common/install | ||||||
| 	$(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd  $(1)/usr/share/acl.d | 	$(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd  $(1)/usr/share/acl.d $(1)/usr/share/hostap | ||||||
| 	$(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh | 	$(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh | ||||||
| 	$(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad | 	$(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad | ||||||
| 	$(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps | 	$(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps | ||||||
| 	$(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d | 	$(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d | ||||||
| 	$(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities | 	$(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities | ||||||
|  | 	$(INSTALL_DATA) ./files/common.uc $(1)/usr/share/hostap/ | ||||||
|  | 	$(INSTALL_DATA) ./files/wdev.uc $(1)/usr/share/hostap/ | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Package/hostapd/install | define Package/hostapd/install | ||||||
|   | |||||||
							
								
								
									
										168
									
								
								feeds/ipq807x_v5.4/hostapd/files/common.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								feeds/ipq807x_v5.4/hostapd/files/common.uc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | |||||||
|  | import * as nl80211 from "nl80211"; | ||||||
|  | import * as rtnl from "rtnl"; | ||||||
|  | import { readfile } from "fs"; | ||||||
|  |  | ||||||
|  | const iftypes = { | ||||||
|  | 	ap: nl80211.const.NL80211_IFTYPE_AP, | ||||||
|  | 	mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT, | ||||||
|  | 	sta: nl80211.const.NL80211_IFTYPE_STATION, | ||||||
|  | 	adhoc: nl80211.const.NL80211_IFTYPE_ADHOC, | ||||||
|  | 	monitor: nl80211.const.NL80211_IFTYPE_MONITOR, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | function wdev_remove(name) | ||||||
|  | { | ||||||
|  | 	nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function __phy_is_fullmac(phyidx) | ||||||
|  | { | ||||||
|  | 	let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx }); | ||||||
|  |  | ||||||
|  | 	return !data.software_iftypes.ap_vlan; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function phy_is_fullmac(phy) | ||||||
|  | { | ||||||
|  | 	let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`))); | ||||||
|  |  | ||||||
|  | 	return __phy_is_fullmac(phyidx); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function find_reusable_wdev(phyidx) | ||||||
|  | { | ||||||
|  | 	if (!__phy_is_fullmac(phyidx)) | ||||||
|  | 		return null; | ||||||
|  |  | ||||||
|  | 	let data = nl80211.request( | ||||||
|  | 		nl80211.const.NL80211_CMD_GET_INTERFACE, | ||||||
|  | 		nl80211.const.NLM_F_DUMP, | ||||||
|  | 		{ wiphy: phyidx }); | ||||||
|  | 	for (let res in data) | ||||||
|  | 		if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down") | ||||||
|  | 			return res.ifname; | ||||||
|  | 	return null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function wdev_create(phy, name, data) | ||||||
|  | { | ||||||
|  | 	let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`)); | ||||||
|  |  | ||||||
|  | 	wdev_remove(name); | ||||||
|  |  | ||||||
|  | 	if (!iftypes[data.mode]) | ||||||
|  | 		return `Invalid mode: ${data.mode}`; | ||||||
|  |  | ||||||
|  | 	let req = { | ||||||
|  | 		wiphy: phyidx, | ||||||
|  | 		ifname: name, | ||||||
|  | 		iftype: iftypes[data.mode], | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	if (data["4addr"]) | ||||||
|  | 		req["4addr"] = data["4addr"]; | ||||||
|  | 	if (data.macaddr) | ||||||
|  | 		req.mac = data.macaddr; | ||||||
|  |  | ||||||
|  | 	nl80211.error(); | ||||||
|  |  | ||||||
|  | 	let reuse_ifname = find_reusable_wdev(phyidx); | ||||||
|  | 	if (reuse_ifname && | ||||||
|  | 	    (reuse_ifname == name || | ||||||
|  | 	     rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false)) | ||||||
|  | 		nl80211.request( | ||||||
|  | 			nl80211.const.NL80211_CMD_SET_INTERFACE, 0, { | ||||||
|  | 				wiphy: phyidx, | ||||||
|  | 				dev: name, | ||||||
|  | 				iftype: iftypes[data.mode], | ||||||
|  | 			}); | ||||||
|  | 	else | ||||||
|  | 		nl80211.request( | ||||||
|  | 			nl80211.const.NL80211_CMD_NEW_INTERFACE, | ||||||
|  | 			nl80211.const.NLM_F_CREATE, | ||||||
|  | 			req); | ||||||
|  |  | ||||||
|  | 	let error = nl80211.error(); | ||||||
|  | 	if (error) | ||||||
|  | 		return error; | ||||||
|  |  | ||||||
|  | 	if (data.powersave != null) { | ||||||
|  | 		nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0, | ||||||
|  | 			{ dev: name, ps_state: data.powersave ? 1 : 0}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const vlist_proto = { | ||||||
|  | 	update: function(values, arg) { | ||||||
|  | 		let data = this.data; | ||||||
|  | 		let cb = this.cb; | ||||||
|  | 		let seq = { }; | ||||||
|  | 		let new_data = {}; | ||||||
|  | 		let old_data = {}; | ||||||
|  |  | ||||||
|  | 		this.data = new_data; | ||||||
|  |  | ||||||
|  | 		if (type(values) == "object") { | ||||||
|  | 			for (let key in values) { | ||||||
|  | 				old_data[key] = data[key]; | ||||||
|  | 				new_data[key] = values[key]; | ||||||
|  | 				delete data[key]; | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			for (let val in values) { | ||||||
|  | 				let cur_key = val[0]; | ||||||
|  | 				let cur_obj = val[1]; | ||||||
|  |  | ||||||
|  | 				old_data[cur_key] = data[cur_key]; | ||||||
|  | 				new_data[cur_key] = val[1]; | ||||||
|  | 				delete data[cur_key]; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for (let key in data) { | ||||||
|  | 			cb(null, data[key], arg); | ||||||
|  | 			delete data[key]; | ||||||
|  | 		} | ||||||
|  | 		for (let key in new_data) | ||||||
|  | 			cb(new_data[key], old_data[key], arg); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | function is_equal(val1, val2) { | ||||||
|  | 	let t1 = type(val1); | ||||||
|  |  | ||||||
|  | 	if (t1 != type(val2)) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	if (t1 == "array") { | ||||||
|  | 		if (length(val1) != length(val2)) | ||||||
|  | 			return false; | ||||||
|  |  | ||||||
|  | 		for (let i = 0; i < length(val1); i++) | ||||||
|  | 			if (!is_equal(val1[i], val2[i])) | ||||||
|  | 				return false; | ||||||
|  |  | ||||||
|  | 		return true; | ||||||
|  | 	} else if (t1 == "object") { | ||||||
|  | 		for (let key in val1) | ||||||
|  | 			if (!is_equal(val1[key], val2[key])) | ||||||
|  | 				return false; | ||||||
|  | 		for (let key in val2) | ||||||
|  | 			if (!val1[key]) | ||||||
|  | 				return false; | ||||||
|  | 		return true; | ||||||
|  | 	} else { | ||||||
|  | 		return val1 == val2; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function vlist_new(cb) { | ||||||
|  | 	return proto({ | ||||||
|  | 			cb: cb, | ||||||
|  | 			data: {} | ||||||
|  | 		}, vlist_proto); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac }; | ||||||
| @@ -1203,9 +1203,6 @@ hostapd_set_bss_options() { | |||||||
| 		append bss_conf "$val" "$N" | 		append bss_conf "$val" "$N" | ||||||
| 	done | 	done | ||||||
|  |  | ||||||
| 	bss_md5sum=$(echo $bss_conf | md5sum | cut -d" " -f1) |  | ||||||
| 	append bss_conf "config_id=$bss_md5sum" "$N" |  | ||||||
|  |  | ||||||
| 	append "$var" "$bss_conf" "$N" | 	append "$var" "$bss_conf" "$N" | ||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										486
									
								
								feeds/ipq807x_v5.4/hostapd/files/hostapd.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								feeds/ipq807x_v5.4/hostapd/files/hostapd.uc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,486 @@ | |||||||
|  | let libubus = require("ubus"); | ||||||
|  | import { open, readfile } from "fs"; | ||||||
|  | import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac } from "common"; | ||||||
|  |  | ||||||
|  | let ubus = libubus.connect(); | ||||||
|  |  | ||||||
|  | hostapd.data.config = {}; | ||||||
|  |  | ||||||
|  | hostapd.data.file_fields = { | ||||||
|  | 	vlan_file: true, | ||||||
|  | 	wpa_psk_file: true, | ||||||
|  | 	accept_mac_file: true, | ||||||
|  | 	deny_mac_file: true, | ||||||
|  | 	eap_user_file: true, | ||||||
|  | 	ca_cert: true, | ||||||
|  | 	server_cert: true, | ||||||
|  | 	server_cert2: true, | ||||||
|  | 	private_key: true, | ||||||
|  | 	private_key2: true, | ||||||
|  | 	dh_file: true, | ||||||
|  | 	eap_sim_db: true, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | function iface_remove(cfg) | ||||||
|  | { | ||||||
|  | 	if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	hostapd.remove_iface(cfg.bss[0].ifname); | ||||||
|  | 	for (let bss in cfg.bss) | ||||||
|  | 		wdev_remove(bss.ifname); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_gen_config(phy, config) | ||||||
|  | { | ||||||
|  | 	let str = `data: | ||||||
|  | ${join("\n", config.radio.data)} | ||||||
|  | channel=${config.radio.channel} | ||||||
|  | `; | ||||||
|  |  | ||||||
|  | 	for (let i = 0; i < length(config.bss); i++) { | ||||||
|  | 		let bss = config.bss[i]; | ||||||
|  | 		let type = i > 0 ? "bss" : "interface"; | ||||||
|  |  | ||||||
|  | 		str += ` | ||||||
|  | ${type}=${bss.ifname} | ||||||
|  | ${join("\n", bss.data)} | ||||||
|  | `; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return str; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_restart(phy, config, old_config) | ||||||
|  | { | ||||||
|  | 	iface_remove(old_config); | ||||||
|  | 	iface_remove(config); | ||||||
|  |  | ||||||
|  | 	if (!config.bss || !config.bss[0]) { | ||||||
|  | 		hostapd.printf(`No bss for phy ${phy}`); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	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 config_inline = iface_gen_config(phy, config); | ||||||
|  |  | ||||||
|  | 	let ubus = hostapd.data.ubus; | ||||||
|  | 	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true }); | ||||||
|  | 	if (hostapd.add_iface(`bss_config=${bss.ifname}:${config_inline}`) < 0) | ||||||
|  | 		hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`); | ||||||
|  | 	ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function array_to_obj(arr, key, start) | ||||||
|  | { | ||||||
|  | 	let obj = {}; | ||||||
|  |  | ||||||
|  | 	start ??= 0; | ||||||
|  | 	for (let i = start; i < length(arr); i++) { | ||||||
|  | 		let cur = arr[i]; | ||||||
|  | 		obj[cur[key]] = cur; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return obj; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function find_array_idx(arr, key, val) | ||||||
|  | { | ||||||
|  | 	for (let i = 0; i < length(arr); i++) | ||||||
|  | 		if (arr[i][key] == val) | ||||||
|  | 			return i; | ||||||
|  |  | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function bss_reload_psk(bss, config, old_config) | ||||||
|  | { | ||||||
|  | 	if (is_equal(old_config.hash.wpa_psk_file, config.hash.wpa_psk_file)) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	old_config.hash.wpa_psk_file = config.hash.wpa_psk_file; | ||||||
|  | 	if (!is_equal(old_config, config)) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	let ret = bss.ctrl("RELOAD_WPA_PSK"); | ||||||
|  | 	ret ??= "failed"; | ||||||
|  |  | ||||||
|  | 	hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_reload_config(phy, config, old_config) | ||||||
|  | { | ||||||
|  | 	if (!old_config || !is_equal(old_config.radio, config.radio)) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	if (is_equal(old_config.bss, config.bss)) | ||||||
|  | 		return true; | ||||||
|  |  | ||||||
|  | 	if (!old_config.bss || !old_config.bss[0]) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	if (config.bss[0].ifname != old_config.bss[0].ifname) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	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(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; | ||||||
|  |  | ||||||
|  | 		if (config.bss[0].bssid != old_config.bss[0].bssid) | ||||||
|  | 			return false; | ||||||
|  |  | ||||||
|  | 		hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`); | ||||||
|  | 		if (first_bss.set_config(config_inline, 0) < 0) { | ||||||
|  | 			hostapd.printf(`Failed to set config`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	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 = hostapd.bss[name]; | ||||||
|  | 		if (!bss) { | ||||||
|  | 			hostapd.printf(`bss '${name}' not found`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!new_cfg[name]) { | ||||||
|  | 			hostapd.printf(`Remove bss '${name}' on phy '${phy}'`); | ||||||
|  | 			bss.delete(); | ||||||
|  | 			wdev_remove(name); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		let new_cfg_data = new_cfg[name]; | ||||||
|  | 		delete new_cfg[name]; | ||||||
|  |  | ||||||
|  | 		if (is_equal(old_cfg[name], new_cfg_data)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		hostapd.printf(`Reload config for bss '${name}' on phy '${phy}'`); | ||||||
|  | 		let idx = find_array_idx(config.bss, "ifname", name); | ||||||
|  | 		if (idx < 0) { | ||||||
|  | 			hostapd.printf(`bss index not found`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (bss.set_config(config_inline, idx) < 0) { | ||||||
|  | 			hostapd.printf(`Failed to set config`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for (let name in new_cfg) { | ||||||
|  | 		hostapd.printf(`Add bss '${name}' on phy '${phy}'`); | ||||||
|  |  | ||||||
|  | 		let idx = find_array_idx(config.bss, "ifname", name); | ||||||
|  | 		if (idx < 0) { | ||||||
|  | 			hostapd.printf(`bss index not found`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (iface.add_bss(config_inline, idx) < 0) { | ||||||
|  | 			hostapd.printf(`Failed to add bss`); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_set_config(phy, config) | ||||||
|  | { | ||||||
|  | 	let old_config = hostapd.data.config[phy]; | ||||||
|  |  | ||||||
|  | 	hostapd.data.config[phy] = config; | ||||||
|  |  | ||||||
|  | 	if (!config) | ||||||
|  | 		return iface_remove(old_config); | ||||||
|  |  | ||||||
|  | 	let ret = iface_reload_config(phy, config, old_config); | ||||||
|  | 	if (ret) { | ||||||
|  | 		hostapd.printf(`Reloaded settings for phy ${phy}`); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	hostapd.printf(`Restart interface for phy ${phy}`); | ||||||
|  | 	return iface_restart(phy, config, old_config); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function config_add_bss(config, name) | ||||||
|  | { | ||||||
|  | 	let bss = { | ||||||
|  | 		ifname: name, | ||||||
|  | 		data: [], | ||||||
|  | 		hash: {} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	push(config.bss, bss); | ||||||
|  |  | ||||||
|  | 	return bss; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_load_config(filename) | ||||||
|  | { | ||||||
|  | 	let f = open(filename, "r"); | ||||||
|  | 	if (!f) | ||||||
|  | 		return null; | ||||||
|  |  | ||||||
|  | 	let config = { | ||||||
|  | 		radio: { | ||||||
|  | 			data: [] | ||||||
|  | 		}, | ||||||
|  | 		bss: [], | ||||||
|  | 		orig_file: filename, | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	let bss; | ||||||
|  | 	let line; | ||||||
|  | 	while ((line = trim(f.read("line"))) != null) { | ||||||
|  | 		let val = split(line, "=", 2); | ||||||
|  | 		if (!val[0]) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (val[0] == "interface") { | ||||||
|  | 			bss = config_add_bss(config, val[1]); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (val[0] == "channel") { | ||||||
|  | 			config.radio.channel = val[1]; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		push(config.radio.data, line); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	while ((line = trim(f.read("line"))) != null) { | ||||||
|  | 		let val = split(line, "=", 2); | ||||||
|  | 		if (!val[0]) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (val[0] == "bssid") | ||||||
|  | 			bss.bssid = val[1]; | ||||||
|  |  | ||||||
|  | 		if (val[0] == "bss") { | ||||||
|  | 			bss = config_add_bss(config, val[1]); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (hostapd.data.file_fields[val[0]]) | ||||||
|  | 			bss.hash[val[0]] = hostapd.sha1(readfile(val[1])); | ||||||
|  |  | ||||||
|  | 		push(bss.data, line); | ||||||
|  | 	} | ||||||
|  | 	f.close(); | ||||||
|  |  | ||||||
|  | 	return config; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | let main_obj = { | ||||||
|  | 	reload: { | ||||||
|  | 		args: { | ||||||
|  | 			phy: "", | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			try { | ||||||
|  | 				let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config); | ||||||
|  | 				for (let phy_name in phy_list) { | ||||||
|  | 					let phy = hostapd.data.config[phy_name]; | ||||||
|  | 					let config = iface_load_config(phy.orig_file); | ||||||
|  | 					iface_set_config(phy_name, config); | ||||||
|  | 				} | ||||||
|  | 			} catch(e) { | ||||||
|  | 				hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`); | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			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: "", | ||||||
|  | 			config: "", | ||||||
|  | 			prev_config: "", | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			let phy = req.args.phy; | ||||||
|  | 			let file = req.args.config; | ||||||
|  | 			let prev_file = req.args.prev_config; | ||||||
|  |  | ||||||
|  | 			if (!phy) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			try { | ||||||
|  | 				if (prev_file && !hostapd.data.config[phy]) { | ||||||
|  | 					let config = iface_load_config(prev_file); | ||||||
|  | 					if (config) | ||||||
|  | 						config.radio.data = []; | ||||||
|  | 					hostapd.data.config[phy] = config; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				let config = iface_load_config(file); | ||||||
|  |  | ||||||
|  | 				hostapd.printf(`Set new config for phy ${phy}: ${file}`); | ||||||
|  | 				iface_set_config(phy, config); | ||||||
|  | 			} catch(e) { | ||||||
|  | 				hostapd.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`); | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return { | ||||||
|  | 				pid: hostapd.getpid() | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	config_add: { | ||||||
|  | 		args: { | ||||||
|  | 			iface: "", | ||||||
|  | 			config: "", | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.iface || !req.args.config) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			if (hostapd.add_iface(`bss_config=${req.args.iface}:${req.args.config}`) < 0) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			return { | ||||||
|  | 				pid: hostapd.getpid() | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	config_remove: { | ||||||
|  | 		args: { | ||||||
|  | 			iface: "" | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.iface) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			hostapd.remove_iface(req.args.iface); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | hostapd.data.ubus = ubus; | ||||||
|  | hostapd.data.obj = ubus.publish("hostapd", main_obj); | ||||||
|  |  | ||||||
|  | function bss_event(type, name, data) { | ||||||
|  | 	let ubus = hostapd.data.ubus; | ||||||
|  |  | ||||||
|  | 	data ??= {}; | ||||||
|  | 	data.name = name; | ||||||
|  | 	hostapd.data.obj.notify(`bss.${type}`, data, null, null, null, -1); | ||||||
|  | 	ubus.call("service", "event", { type: `hostapd.${name}.${type}`, data: {} }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | return { | ||||||
|  | 	shutdown: function() { | ||||||
|  | 		for (let phy in hostapd.data.config) | ||||||
|  | 			iface_set_config(phy, null); | ||||||
|  | 		hostapd.ubus.disconnect(); | ||||||
|  | 	}, | ||||||
|  | 	bss_add: function(name, obj) { | ||||||
|  | 		bss_event("add", name); | ||||||
|  | 	}, | ||||||
|  | 	bss_reload: function(name, obj, reconf) { | ||||||
|  | 		bss_event("reload", name, { reconf: reconf != 0 }); | ||||||
|  | 	}, | ||||||
|  | 	bss_remove: function(name, obj) { | ||||||
|  | 		bss_event("remove", name); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
							
								
								
									
										156
									
								
								feeds/ipq807x_v5.4/hostapd/files/wdev.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								feeds/ipq807x_v5.4/hostapd/files/wdev.uc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | |||||||
|  | #!/usr/bin/env ucode | ||||||
|  | 'use strict'; | ||||||
|  | import { vlist_new, is_equal, wdev_create, wdev_remove } from "/usr/share/hostap/common.uc"; | ||||||
|  | import { readfile, writefile, basename, readlink, glob } from "fs"; | ||||||
|  |  | ||||||
|  | let keep_devices = {}; | ||||||
|  | let phy = shift(ARGV); | ||||||
|  | let new_config = shift(ARGV); | ||||||
|  | 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", | ||||||
|  | 	"mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout", | ||||||
|  | 	"mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode", | ||||||
|  | 	"mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor", | ||||||
|  | 	"mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval", | ||||||
|  | 	"mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout", | ||||||
|  | 	"mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode" | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | function iface_stop(wdev) | ||||||
|  | { | ||||||
|  | 	if (keep_devices[wdev.ifname]) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	wdev_remove(wdev.ifname); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_start(wdev) | ||||||
|  | { | ||||||
|  | 	let ifname = wdev.ifname; | ||||||
|  |  | ||||||
|  | 	if (readfile(`/sys/class/net/${ifname}/ifindex`)) { | ||||||
|  | 		system([ "ip", "link", "set", "dev", ifname, "down" ]); | ||||||
|  | 		wdev_remove(ifname); | ||||||
|  | 	} | ||||||
|  | 	wdev_create(phy, ifname, wdev); | ||||||
|  | 	system([ "ip", "link", "set", "dev", ifname, "up" ]); | ||||||
|  | 	if (wdev.freq) | ||||||
|  | 		system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`); | ||||||
|  | 	if (wdev.mode == "adhoc") { | ||||||
|  | 		let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ]; | ||||||
|  | 		if (wdev.bssid) | ||||||
|  | 			push(cmd, wdev.bssid); | ||||||
|  | 		for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ]) | ||||||
|  | 			if (wdev[key]) | ||||||
|  | 				push(cmd, key, wdev[key]); | ||||||
|  | 		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" ]) | ||||||
|  | 			if (wdev[key]) | ||||||
|  | 				push(cmd, key, wdev[key]); | ||||||
|  | 		system(cmd); | ||||||
|  |  | ||||||
|  | 		cmd = ["iw", "dev", ifname, "set", "mesh_param" ]; | ||||||
|  | 		let len = length(cmd); | ||||||
|  |  | ||||||
|  | 		for (let param in mesh_params) | ||||||
|  | 			if (wdev[param]) | ||||||
|  | 				push(cmd, param, wdev[param]); | ||||||
|  |  | ||||||
|  | 		if (len == length(cmd)) | ||||||
|  | 			return; | ||||||
|  |  | ||||||
|  | 		system(cmd); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_cb(new_if, old_if) | ||||||
|  | { | ||||||
|  | 	if (old_if && new_if && is_equal(old_if, new_if)) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (old_if) | ||||||
|  | 		iface_stop(old_if); | ||||||
|  | 	if (new_if) | ||||||
|  | 		iface_start(new_if); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function drop_inactive(config) | ||||||
|  | { | ||||||
|  | 	for (let key in config) { | ||||||
|  | 		if (!readfile(`/sys/class/net/${key}/ifindex`)) | ||||||
|  | 			delete config[key]; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function add_ifname(config) | ||||||
|  | { | ||||||
|  | 	for (let key in config) | ||||||
|  | 		config[key].ifname = key; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function delete_ifname(config) | ||||||
|  | { | ||||||
|  | 	for (let key in config) | ||||||
|  | 		delete config[key].ifname; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function add_existing(phy, config) | ||||||
|  | { | ||||||
|  | 	let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`); | ||||||
|  | 	wdevs = map(wdevs, (arg) => basename(arg)); | ||||||
|  | 	for (let wdev in wdevs) { | ||||||
|  | 		if (config[wdev]) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down") | ||||||
|  | 			config[wdev] = {}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | let statefile = `/var/run/wdev-${phy}.json`; | ||||||
|  |  | ||||||
|  | for (let dev in ARGV) | ||||||
|  | 	keep_devices[dev] = true; | ||||||
|  |  | ||||||
|  | if (!phy || !new_config) { | ||||||
|  | 	warn(`Usage: ${basename(sourcepath())} <phy> <config> [<device]...]\n`); | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if (!readfile(`/sys/class/ieee80211/${phy}/index`)) { | ||||||
|  | 	warn(`PHY ${phy} does not exist\n`); | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | new_config = json(new_config); | ||||||
|  | if (!new_config) { | ||||||
|  | 	warn("Invalid configuration\n"); | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | let old_config = readfile(statefile); | ||||||
|  | if (old_config) | ||||||
|  | 	old_config = json(old_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); | ||||||
|  |  | ||||||
|  | add_ifname(new_config); | ||||||
|  | config.update(new_config); | ||||||
|  |  | ||||||
|  | drop_inactive(config.data); | ||||||
|  | delete_ifname(config.data); | ||||||
|  | writefile(statefile, sprintf("%J", config.data)); | ||||||
							
								
								
									
										253
									
								
								feeds/ipq807x_v5.4/hostapd/files/wpa_supplicant.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								feeds/ipq807x_v5.4/hostapd/files/wpa_supplicant.uc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,253 @@ | |||||||
|  | let libubus = require("ubus"); | ||||||
|  | import { open, readfile } from "fs"; | ||||||
|  | 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; | ||||||
|  |  | ||||||
|  | 	if (!iface.running) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	delete wpas.data.iface_phy[ifname]; | ||||||
|  | 	wpas.remove_iface(ifname); | ||||||
|  | 	wdev_remove(ifname); | ||||||
|  | 	iface.running = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_start(phy, iface) | ||||||
|  | { | ||||||
|  | 	if (iface.running) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	let ifname = iface.config.iface; | ||||||
|  |  | ||||||
|  | 	wpas.data.iface_phy[ifname] = phy; | ||||||
|  | 	wdev_remove(ifname); | ||||||
|  | 	let ret = wdev_create(phy, ifname, iface.config); | ||||||
|  | 	if (ret) | ||||||
|  | 		wpas.printf(`Failed to create device ${ifname}: ${ret}`); | ||||||
|  | 	wpas.add_iface(iface.config); | ||||||
|  | 	iface.running = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function iface_cb(new_if, old_if) | ||||||
|  | { | ||||||
|  | 	if (old_if && new_if && is_equal(old_if.config, new_if.config)) { | ||||||
|  | 		new_if.running = old_if.running; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (old_if) | ||||||
|  | 		iface_stop(old_if); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function prepare_config(config) | ||||||
|  | { | ||||||
|  | 	config.config_data = readfile(config.config); | ||||||
|  |  | ||||||
|  | 	return { config: config }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function set_config(phy_name, config_list) | ||||||
|  | { | ||||||
|  | 	let phy = wpas.data.config[phy_name]; | ||||||
|  |  | ||||||
|  | 	if (!phy) { | ||||||
|  | 		phy = vlist_new(iface_cb, false); | ||||||
|  | 		wpas.data.config[phy_name] = phy; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	let values = []; | ||||||
|  | 	for (let config in config_list) | ||||||
|  | 		push(values, [ config.iface, prepare_config(config) ]); | ||||||
|  |  | ||||||
|  | 	phy.update(values); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function start_pending(phy_name) | ||||||
|  | { | ||||||
|  | 	let phy = wpas.data.config[phy_name]; | ||||||
|  |  | ||||||
|  | 	for (let ifname in phy.data) | ||||||
|  | 		iface_start(phy_name, phy.data[ifname]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | let main_obj = { | ||||||
|  | 	phy_set_state: { | ||||||
|  | 		args: { | ||||||
|  | 			phy: "", | ||||||
|  | 			stop: true, | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.phy || req.args.stop == null) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			let phy = wpas.data.config[req.args.phy]; | ||||||
|  | 			if (!phy) | ||||||
|  | 				return libubus.STATUS_NOT_FOUND; | ||||||
|  |  | ||||||
|  | 			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; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	config_set: { | ||||||
|  | 		args: { | ||||||
|  | 			phy: "", | ||||||
|  | 			config: [], | ||||||
|  | 			defer: true, | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.phy) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			try { | ||||||
|  | 				if (req.args.config) | ||||||
|  | 					set_config(req.args.phy, req.args.config); | ||||||
|  |  | ||||||
|  | 				if (!req.args.defer) | ||||||
|  | 					start_pending(req.args.phy); | ||||||
|  | 			} catch (e) { | ||||||
|  | 				wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`); | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return { | ||||||
|  | 				pid: wpas.getpid() | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	config_add: { | ||||||
|  | 		args: { | ||||||
|  | 			driver: "", | ||||||
|  | 			iface: "", | ||||||
|  | 			bridge: "", | ||||||
|  | 			hostapd_ctrl: "", | ||||||
|  | 			ctrl: "", | ||||||
|  | 			config: "", | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.iface || !req.args.config) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			if (wpas.add_iface(req.args) < 0) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			return { | ||||||
|  | 				pid: wpas.getpid() | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	config_remove: { | ||||||
|  | 		args: { | ||||||
|  | 			iface: "" | ||||||
|  | 		}, | ||||||
|  | 		call: function(req) { | ||||||
|  | 			if (!req.args.iface) | ||||||
|  | 				return libubus.STATUS_INVALID_ARGUMENT; | ||||||
|  |  | ||||||
|  | 			wpas.remove_iface(req.args.iface); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | wpas.data.ubus = ubus; | ||||||
|  | wpas.data.obj = ubus.publish("wpa_supplicant", main_obj); | ||||||
|  |  | ||||||
|  | function iface_event(type, name, data) { | ||||||
|  | 	let ubus = wpas.data.ubus; | ||||||
|  |  | ||||||
|  | 	data ??= {}; | ||||||
|  | 	data.name = name; | ||||||
|  | 	wpas.data.obj.notify(`iface.${type}`, data, null, null, null, -1); | ||||||
|  | 	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) { | ||||||
|  | 		iface_event("add", name); | ||||||
|  | 	}, | ||||||
|  | 	iface_remove: function(name, obj) { | ||||||
|  | 		iface_event("remove", name); | ||||||
|  | 	}, | ||||||
|  | 	state: function(ifname, iface, state) { | ||||||
|  | 		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(ifname, iface, ev, info) { | ||||||
|  | 		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); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
| @@ -68,7 +68,7 @@ Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de> | |||||||
|  	if (!chan) { |  	if (!chan) { | ||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -9872,6 +9872,10 @@ static int nl80211_switch_channel(void * | @@ -9797,6 +9797,10 @@ static int nl80211_switch_channel(void * | ||||||
|  	if (ret) |  	if (ret) | ||||||
|  		goto error; |  		goto error; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  #define MAX_STA_COUNT 2007 |  #define MAX_STA_COUNT 2007 | ||||||
| @@ -696,6 +697,7 @@ struct hostapd_bss_config { | @@ -694,6 +695,7 @@ struct hostapd_bss_config { | ||||||
|   |   | ||||||
|  #define MESH_ENABLED BIT(0) |  #define MESH_ENABLED BIT(0) | ||||||
|  	int mesh; |  	int mesh; | ||||||
| @@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> | |||||||
|   |   | ||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -10456,6 +10456,9 @@ static int nl80211_put_mesh_config(struc | @@ -10381,6 +10381,9 @@ static int nl80211_put_mesh_config(struc | ||||||
|  	if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) && |  	if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) && | ||||||
|  	     nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, |  	     nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, | ||||||
|  			params->auto_plinks)) || |  			params->auto_plinks)) || | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/ap/ieee802_11.c | --- a/src/ap/ieee802_11.c | ||||||
| +++ b/src/ap/ieee802_11.c | +++ b/src/ap/ieee802_11.c | ||||||
| @@ -4942,6 +4942,13 @@ static int add_associated_sta(struct hos | @@ -4810,6 +4810,13 @@ static int add_associated_sta(struct hos | ||||||
|  	 * drivers to accept the STA parameter configuration. Since this is |  	 * drivers to accept the STA parameter configuration. Since this is | ||||||
|  	 * after a new FT-over-DS exchange, a new TK has been derived, so key |  	 * after a new FT-over-DS exchange, a new TK has been derived, so key | ||||||
|  	 * reinstallation is not a concern for this case. |  	 * reinstallation is not a concern for this case. | ||||||
| @@ -14,7 +14,7 @@ | |||||||
|  	 */ |  	 */ | ||||||
|  	wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR |  	wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR | ||||||
|  		   " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", |  		   " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", | ||||||
| @@ -4955,7 +4962,8 @@ static int add_associated_sta(struct hos | @@ -4823,7 +4830,8 @@ static int add_associated_sta(struct hos | ||||||
|  	    (!(sta->flags & WLAN_STA_AUTHORIZED) || |  	    (!(sta->flags & WLAN_STA_AUTHORIZED) || | ||||||
|  	     (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || |  	     (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || | ||||||
|  	     (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && |  	     (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  |  | ||||||
| --- a/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| +++ b/src/ap/hostapd.c | +++ b/src/ap/hostapd.c | ||||||
| @@ -3431,7 +3431,7 @@ static int hostapd_change_config_freq(st | @@ -3403,7 +3403,7 @@ static int hostapd_change_config_freq(st | ||||||
|  				      struct hostapd_freq_params *old_params) |  				      struct hostapd_freq_params *old_params) | ||||||
|  { |  { | ||||||
|  	int channel; |  	int channel; | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  #include <linux/rtnetlink.h> |  #include <linux/rtnetlink.h> | ||||||
|  #include <netpacket/packet.h> |  #include <netpacket/packet.h> | ||||||
|  #include <linux/errqueue.h> |  #include <linux/errqueue.h> | ||||||
| @@ -5284,26 +5281,29 @@ fail: | @@ -5233,26 +5230,29 @@ fail: | ||||||
|   |   | ||||||
|  static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) |  static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) | ||||||
|  { |  { | ||||||
| @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	if (err < 0) { |  	if (err < 0) { | ||||||
|  		wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " |  		wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " | ||||||
|  			   MACSTR " ifindex=%d failed: %s", MAC2STR(addr), |  			   MACSTR " ifindex=%d failed: %s", MAC2STR(addr), | ||||||
| @@ -5313,9 +5313,8 @@ static void rtnl_neigh_delete_fdb_entry( | @@ -5262,9 +5262,8 @@ static void rtnl_neigh_delete_fdb_entry( | ||||||
|  			   MACSTR, MAC2STR(addr)); |  			   MACSTR, MAC2STR(addr)); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -7691,7 +7690,6 @@ static void *i802_init(struct hostapd_da | @@ -7633,7 +7632,6 @@ static void *i802_init(struct hostapd_da | ||||||
|  	    (params->num_bridge == 0 || !params->bridge[0])) |  	    (params->num_bridge == 0 || !params->bridge[0])) | ||||||
|  		add_ifidx(drv, br_ifindex, drv->ifindex); |  		add_ifidx(drv, br_ifindex, drv->ifindex); | ||||||
|   |   | ||||||
| @@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	if (bss->added_if_into_bridge || bss->already_in_bridge) { |  	if (bss->added_if_into_bridge || bss->already_in_bridge) { | ||||||
|  		int err; |  		int err; | ||||||
|   |   | ||||||
| @@ -7708,7 +7706,6 @@ static void *i802_init(struct hostapd_da | @@ -7650,7 +7648,6 @@ static void *i802_init(struct hostapd_da | ||||||
|  			goto failed; |  			goto failed; | ||||||
|  		} |  		} | ||||||
|  	} |  	} | ||||||
| @@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { |  	if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { | ||||||
|  		wpa_printf(MSG_DEBUG, |  		wpa_printf(MSG_DEBUG, | ||||||
| @@ -10655,13 +10652,14 @@ static int wpa_driver_br_add_ip_neigh(vo | @@ -10581,13 +10578,14 @@ static int wpa_driver_br_add_ip_neigh(vo | ||||||
|  				      const u8 *ipaddr, int prefixlen, |  				      const u8 *ipaddr, int prefixlen, | ||||||
|  				      const u8 *addr) |  				      const u8 *addr) | ||||||
|  { |  { | ||||||
| @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	int res; |  	int res; | ||||||
|   |   | ||||||
|  	if (!ipaddr || prefixlen == 0 || !addr) |  	if (!ipaddr || prefixlen == 0 || !addr) | ||||||
| @@ -10680,85 +10678,66 @@ static int wpa_driver_br_add_ip_neigh(vo | @@ -10606,85 +10604,66 @@ static int wpa_driver_br_add_ip_neigh(vo | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	if (version == 4) { |  	if (version == 4) { | ||||||
| @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		addrsize = 16; |  		addrsize = 16; | ||||||
|  	} else { |  	} else { | ||||||
|  		return -EINVAL; |  		return -EINVAL; | ||||||
| @@ -10776,41 +10755,30 @@ static int wpa_driver_br_delete_ip_neigh | @@ -10702,41 +10681,30 @@ static int wpa_driver_br_delete_ip_neigh | ||||||
|  		return -1; |  		return -1; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ | |||||||
|  include ../src/build.rules |  include ../src/build.rules | ||||||
|   |   | ||||||
|  ifdef LIBS |  ifdef LIBS | ||||||
| @@ -359,7 +360,9 @@ endif | @@ -354,7 +355,9 @@ endif | ||||||
|  ifdef CONFIG_IBSS_RSN |  ifdef CONFIG_IBSS_RSN | ||||||
|  NEED_RSN_AUTHENTICATOR=y |  NEED_RSN_AUTHENTICATOR=y | ||||||
|  CFLAGS += -DCONFIG_IBSS_RSN |  CFLAGS += -DCONFIG_IBSS_RSN | ||||||
| @@ -82,7 +82,7 @@ | |||||||
|  OBJS += ibss_rsn.o |  OBJS += ibss_rsn.o | ||||||
|  endif |  endif | ||||||
|   |   | ||||||
| @@ -897,6 +900,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS | @@ -886,6 +889,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS | ||||||
|  CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS |  CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS | ||||||
|  LIBS += -ldl -rdynamic |  LIBS += -ldl -rdynamic | ||||||
|  endif |  endif | ||||||
| @@ -93,7 +93,7 @@ | |||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  ifdef CONFIG_AP |  ifdef CONFIG_AP | ||||||
| @@ -904,9 +911,11 @@ NEED_EAP_COMMON=y | @@ -893,9 +900,11 @@ NEED_EAP_COMMON=y | ||||||
|  NEED_RSN_AUTHENTICATOR=y |  NEED_RSN_AUTHENTICATOR=y | ||||||
|  CFLAGS += -DCONFIG_AP |  CFLAGS += -DCONFIG_AP | ||||||
|  OBJS += ap.o |  OBJS += ap.o | ||||||
| @@ -105,7 +105,7 @@ | |||||||
|  OBJS += ../src/ap/hostapd.o |  OBJS += ../src/ap/hostapd.o | ||||||
|  OBJS += ../src/ap/wpa_auth_glue.o |  OBJS += ../src/ap/wpa_auth_glue.o | ||||||
|  OBJS += ../src/ap/utils.o |  OBJS += ../src/ap/utils.o | ||||||
| @@ -986,6 +995,12 @@ endif | @@ -975,6 +984,12 @@ endif | ||||||
|  ifdef CONFIG_HS20 |  ifdef CONFIG_HS20 | ||||||
|  OBJS += ../src/ap/hs20.o |  OBJS += ../src/ap/hs20.o | ||||||
|  endif |  endif | ||||||
| @@ -118,7 +118,7 @@ | |||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  ifdef CONFIG_MBO |  ifdef CONFIG_MBO | ||||||
| @@ -994,7 +1009,9 @@ CFLAGS += -DCONFIG_MBO | @@ -983,7 +998,9 @@ CFLAGS += -DCONFIG_MBO | ||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  ifdef NEED_RSN_AUTHENTICATOR |  ifdef NEED_RSN_AUTHENTICATOR | ||||||
| @@ -128,7 +128,7 @@ | |||||||
|  NEED_AES_WRAP=y |  NEED_AES_WRAP=y | ||||||
|  OBJS += ../src/ap/wpa_auth.o |  OBJS += ../src/ap/wpa_auth.o | ||||||
|  OBJS += ../src/ap/wpa_auth_ie.o |  OBJS += ../src/ap/wpa_auth_ie.o | ||||||
| @@ -1889,6 +1906,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) | @@ -1878,6 +1895,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) | ||||||
|   |   | ||||||
|  _OBJS_VAR := OBJS |  _OBJS_VAR := OBJS | ||||||
|  include ../src/objs.mk |  include ../src/objs.mk | ||||||
| @@ -141,7 +141,7 @@ | |||||||
|  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) |  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) | ||||||
|  	$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) |  	$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) | ||||||
|  	@$(E) "  LD " $@ |  	@$(E) "  LD " $@ | ||||||
| @@ -2021,6 +2044,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) | @@ -1983,6 +2006,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c .. | ||||||
|  	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ |  	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ | ||||||
|  	@$(E) "  sed" $< |  	@$(E) "  sed" $< | ||||||
|   |   | ||||||
| @@ -156,7 +156,7 @@ | |||||||
|  wpa_cli.exe: wpa_cli |  wpa_cli.exe: wpa_cli | ||||||
| --- a/src/drivers/driver.h | --- a/src/drivers/driver.h | ||||||
| +++ b/src/drivers/driver.h | +++ b/src/drivers/driver.h | ||||||
| @@ -6025,8 +6025,8 @@ union wpa_event_data { | @@ -6018,8 +6018,8 @@ union wpa_event_data { | ||||||
|   * Driver wrapper code should call this function whenever an event is received |   * Driver wrapper code should call this function whenever an event is received | ||||||
|   * from the driver. |   * from the driver. | ||||||
|   */ |   */ | ||||||
| @@ -167,7 +167,7 @@ | |||||||
|   |   | ||||||
|  /** |  /** | ||||||
|   * wpa_supplicant_event_global - Report a driver event for wpa_supplicant |   * wpa_supplicant_event_global - Report a driver event for wpa_supplicant | ||||||
| @@ -6038,7 +6038,7 @@ void wpa_supplicant_event(void *ctx, enu | @@ -6031,7 +6031,7 @@ void wpa_supplicant_event(void *ctx, enu | ||||||
|   * Same as wpa_supplicant_event(), but we search for the interface in |   * Same as wpa_supplicant_event(), but we search for the interface in | ||||||
|   * wpa_global. |   * wpa_global. | ||||||
|   */ |   */ | ||||||
| @@ -178,7 +178,7 @@ | |||||||
|  /* |  /* | ||||||
| --- a/src/ap/drv_callbacks.c | --- a/src/ap/drv_callbacks.c | ||||||
| +++ b/src/ap/drv_callbacks.c | +++ b/src/ap/drv_callbacks.c | ||||||
| @@ -1836,8 +1836,8 @@ err: | @@ -1827,8 +1827,8 @@ err: | ||||||
|  #endif /* CONFIG_OWE */ |  #endif /* CONFIG_OWE */ | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -189,7 +189,7 @@ | |||||||
|  { |  { | ||||||
|  	struct hostapd_data *hapd = ctx; |  	struct hostapd_data *hapd = ctx; | ||||||
|  #ifndef CONFIG_NO_STDOUT_DEBUG |  #ifndef CONFIG_NO_STDOUT_DEBUG | ||||||
| @@ -2082,7 +2082,7 @@ void wpa_supplicant_event(void *ctx, enu | @@ -2073,7 +2073,7 @@ void wpa_supplicant_event(void *ctx, enu | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -231,7 +231,7 @@ | |||||||
|  	os_memset(&global, 0, sizeof(global)); |  	os_memset(&global, 0, sizeof(global)); | ||||||
| --- a/wpa_supplicant/events.c | --- a/wpa_supplicant/events.c | ||||||
| +++ b/wpa_supplicant/events.c | +++ b/wpa_supplicant/events.c | ||||||
| @@ -4665,8 +4665,8 @@ static void wpas_event_unprot_beacon(str | @@ -4666,8 +4666,8 @@ static void wpas_event_unprot_beacon(str | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -242,7 +242,7 @@ | |||||||
|  { |  { | ||||||
|  	struct wpa_supplicant *wpa_s = ctx; |  	struct wpa_supplicant *wpa_s = ctx; | ||||||
|  	int resched; |  	int resched; | ||||||
| @@ -5511,7 +5511,7 @@ void wpa_supplicant_event(void *ctx, enu | @@ -5512,7 +5512,7 @@ void wpa_supplicant_event(void *ctx, enu | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -253,7 +253,7 @@ | |||||||
|  	struct wpa_supplicant *wpa_s; |  	struct wpa_supplicant *wpa_s; | ||||||
| --- a/wpa_supplicant/wpa_supplicant.c | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
| +++ b/wpa_supplicant/wpa_supplicant.c | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
| @@ -6819,7 +6819,6 @@ struct wpa_interface * wpa_supplicant_ma | @@ -6814,7 +6814,6 @@ struct wpa_interface * wpa_supplicant_ma | ||||||
|  	return NULL; |  	return NULL; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -261,7 +261,7 @@ | |||||||
|  /** |  /** | ||||||
|   * wpa_supplicant_match_existing - Match existing interfaces |   * wpa_supplicant_match_existing - Match existing interfaces | ||||||
|   * @global: Pointer to global data from wpa_supplicant_init() |   * @global: Pointer to global data from wpa_supplicant_init() | ||||||
| @@ -6854,6 +6853,11 @@ static int wpa_supplicant_match_existing | @@ -6849,6 +6848,11 @@ static int wpa_supplicant_match_existing | ||||||
|   |   | ||||||
|  #endif /* CONFIG_MATCH_IFACE */ |  #endif /* CONFIG_MATCH_IFACE */ | ||||||
|   |   | ||||||
| @@ -273,7 +273,7 @@ | |||||||
|   |   | ||||||
|  /** |  /** | ||||||
|   * wpa_supplicant_add_iface - Add a new network interface |   * wpa_supplicant_add_iface - Add a new network interface | ||||||
| @@ -7110,6 +7114,8 @@ struct wpa_global * wpa_supplicant_init( | @@ -7105,6 +7109,8 @@ struct wpa_global * wpa_supplicant_init( | ||||||
|  #ifndef CONFIG_NO_WPA_MSG |  #ifndef CONFIG_NO_WPA_MSG | ||||||
|  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); |  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); | ||||||
|  #endif /* CONFIG_NO_WPA_MSG */ |  #endif /* CONFIG_NO_WPA_MSG */ | ||||||
| @@ -333,7 +333,7 @@ | |||||||
|   |   | ||||||
|  const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; |  const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; | ||||||
|   |   | ||||||
| @@ -1291,6 +1296,10 @@ static void usage(void) | @@ -1292,6 +1297,10 @@ static void usage(void) | ||||||
|  	       "option several times.\n"); |  	       "option several times.\n"); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -344,7 +344,7 @@ | |||||||
|   |   | ||||||
|  int main(int argc, char *argv[]) |  int main(int argc, char *argv[]) | ||||||
|  { |  { | ||||||
| @@ -1311,6 +1320,8 @@ int main(int argc, char *argv[]) | @@ -1312,6 +1321,8 @@ int main(int argc, char *argv[]) | ||||||
|  	if (os_program_init()) |  	if (os_program_init()) | ||||||
|  		return -1; |  		return -1; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| +++ b/hostapd/config_file.c | +++ b/hostapd/config_file.c | ||||||
| @@ -3459,6 +3459,10 @@ static int hostapd_config_fill(struct ho | @@ -3439,6 +3439,10 @@ static int hostapd_config_fill(struct ho | ||||||
|  		if (bss->ocv && !bss->ieee80211w) |  		if (bss->ocv && !bss->ieee80211w) | ||||||
|  			bss->ieee80211w = 1; |  			bss->ieee80211w = 1; | ||||||
|  #endif /* CONFIG_OCV */ |  #endif /* CONFIG_OCV */ | ||||||
| @@ -13,7 +13,7 @@ | |||||||
|  	} else if (os_strcmp(buf, "ht_capab") == 0) { |  	} else if (os_strcmp(buf, "ht_capab") == 0) { | ||||||
| --- a/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| +++ b/src/ap/ap_config.h | +++ b/src/ap/ap_config.h | ||||||
| @@ -1009,6 +1009,8 @@ struct hostapd_config { | @@ -995,6 +995,8 @@ struct hostapd_config { | ||||||
|   |   | ||||||
|  	int ht_op_mode_fixed; |  	int ht_op_mode_fixed; | ||||||
|  	u16 ht_capab; |  	u16 ht_capab; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/wpa_supplicant/wpa_supplicant.c | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
| +++ b/wpa_supplicant/wpa_supplicant.c | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
| @@ -5154,7 +5154,7 @@ wpa_supplicant_alloc(struct wpa_supplica | @@ -5147,7 +5147,7 @@ wpa_supplicant_alloc(struct wpa_supplica | ||||||
|  	if (wpa_s == NULL) |  	if (wpa_s == NULL) | ||||||
|  		return NULL; |  		return NULL; | ||||||
|  	wpa_s->scan_req = INITIAL_SCAN_REQ; |  	wpa_s->scan_req = INITIAL_SCAN_REQ; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/drivers/drivers.mak | --- a/src/drivers/drivers.mak | ||||||
| +++ b/src/drivers/drivers.mak | +++ b/src/drivers/drivers.mak | ||||||
| @@ -54,7 +54,6 @@ NEED_SME=y | @@ -50,7 +50,6 @@ NEED_SME=y | ||||||
|  NEED_AP_MLME=y |  NEED_AP_MLME=y | ||||||
|  NEED_NETLINK=y |  NEED_NETLINK=y | ||||||
|  NEED_LINUX_IOCTL=y |  NEED_LINUX_IOCTL=y | ||||||
| @@ -8,7 +8,7 @@ | |||||||
|  NEED_RADIOTAP=y |  NEED_RADIOTAP=y | ||||||
|  NEED_LIBNL=y |  NEED_LIBNL=y | ||||||
|  endif |  endif | ||||||
| @@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT | @@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT | ||||||
|  CONFIG_WIRELESS_EXTENSION=y |  CONFIG_WIRELESS_EXTENSION=y | ||||||
|  NEED_NETLINK=y |  NEED_NETLINK=y | ||||||
|  NEED_LINUX_IOCTL=y |  NEED_LINUX_IOCTL=y | ||||||
| @@ -16,7 +16,7 @@ | |||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  ifdef CONFIG_DRIVER_NDIS |  ifdef CONFIG_DRIVER_NDIS | ||||||
| @@ -137,7 +135,6 @@ endif | @@ -133,7 +131,6 @@ endif | ||||||
|  ifdef CONFIG_WIRELESS_EXTENSION |  ifdef CONFIG_WIRELESS_EXTENSION | ||||||
|  DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION |  DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION | ||||||
|  DRV_WPA_OBJS += ../src/drivers/driver_wext.o |  DRV_WPA_OBJS += ../src/drivers/driver_wext.o | ||||||
| @@ -24,7 +24,7 @@ | |||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  ifdef NEED_NETLINK |  ifdef NEED_NETLINK | ||||||
| @@ -146,6 +143,7 @@ endif | @@ -142,6 +139,7 @@ endif | ||||||
|   |   | ||||||
|  ifdef NEED_RFKILL |  ifdef NEED_RFKILL | ||||||
|  DRV_OBJS += ../src/drivers/rfkill.o |  DRV_OBJS += ../src/drivers/rfkill.o | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -4973,7 +4973,7 @@ static int nl80211_set_channel(struct i8 | @@ -4919,7 +4919,7 @@ static int nl80211_set_channel(struct i8 | ||||||
|  		   freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, |  		   freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, | ||||||
|  		   freq->bandwidth, freq->center_freq1, freq->center_freq2); |  		   freq->bandwidth, freq->center_freq1, freq->center_freq2); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,75 +0,0 @@ | |||||||
| --- a/src/ap/hostapd.c |  | ||||||
| +++ b/src/ap/hostapd.c |  | ||||||
| @@ -115,6 +115,28 @@ static void hostapd_reload_bss(struct ho |  | ||||||
|  #endif /* CONFIG_NO_RADIUS */ |  | ||||||
|   |  | ||||||
|  	ssid = &hapd->conf->ssid; |  | ||||||
| + |  | ||||||
| +	hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq, |  | ||||||
| +			 hapd->iconf->channel, |  | ||||||
| +			 hapd->iconf->enable_edmg, |  | ||||||
| +			 hapd->iconf->edmg_channel, |  | ||||||
| +			 hapd->iconf->ieee80211n, |  | ||||||
| +			 hapd->iconf->ieee80211ac, |  | ||||||
| +			 hapd->iconf->ieee80211ax, |  | ||||||
| +			 hapd->iconf->secondary_channel, |  | ||||||
| +			 hostapd_get_oper_chwidth(hapd->iconf), |  | ||||||
| +			 hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf), |  | ||||||
| +			 hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf)); |  | ||||||
| + |  | ||||||
| +	if (hapd->iface->current_mode) { |  | ||||||
| +		if (hostapd_prepare_rates(hapd->iface, hapd->iface->current_mode)) { |  | ||||||
| +			wpa_printf(MSG_ERROR, "Failed to prepare rates table."); |  | ||||||
| +			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, |  | ||||||
| +				       HOSTAPD_LEVEL_WARNING, |  | ||||||
| +				       "Failed to prepare rates table."); |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && |  | ||||||
|  	    ssid->wpa_passphrase_set && ssid->wpa_passphrase) { |  | ||||||
|  		/* |  | ||||||
| @@ -216,6 +238,7 @@ int hostapd_reload_config(struct hostapd |  | ||||||
|  	struct hostapd_data *hapd = iface->bss[0]; |  | ||||||
|  	struct hostapd_config *newconf, *oldconf; |  | ||||||
|  	size_t j; |  | ||||||
| +	int i; |  | ||||||
|   |  | ||||||
|  	if (iface->config_fname == NULL) { |  | ||||||
|  		/* Only in-memory config in use - assume it has been updated */ |  | ||||||
| @@ -266,24 +289,20 @@ int hostapd_reload_config(struct hostapd |  | ||||||
|  	} |  | ||||||
|  	iface->conf = newconf; |  | ||||||
|   |  | ||||||
| +	for (i = 0; i < iface->num_hw_features; i++) { |  | ||||||
| +		struct hostapd_hw_modes *mode = &iface->hw_features[i]; |  | ||||||
| +		if (mode->mode == iface->conf->hw_mode) { |  | ||||||
| +			iface->current_mode = mode; |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (iface->conf->channel) |  | ||||||
| +		iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); |  | ||||||
| + |  | ||||||
|  	for (j = 0; j < iface->num_bss; j++) { |  | ||||||
|  		hapd = iface->bss[j]; |  | ||||||
|  		hapd->iconf = newconf; |  | ||||||
| -		hapd->iconf->channel = oldconf->channel; |  | ||||||
| -		hapd->iconf->acs = oldconf->acs; |  | ||||||
| -		hapd->iconf->secondary_channel = oldconf->secondary_channel; |  | ||||||
| -		hapd->iconf->ieee80211n = oldconf->ieee80211n; |  | ||||||
| -		hapd->iconf->ieee80211ac = oldconf->ieee80211ac; |  | ||||||
| -		hapd->iconf->ht_capab = oldconf->ht_capab; |  | ||||||
| -		hapd->iconf->vht_capab = oldconf->vht_capab; |  | ||||||
| -		hostapd_set_oper_chwidth(hapd->iconf, |  | ||||||
| -					 hostapd_get_oper_chwidth(oldconf)); |  | ||||||
| -		hostapd_set_oper_centr_freq_seg0_idx( |  | ||||||
| -			hapd->iconf, |  | ||||||
| -			hostapd_get_oper_centr_freq_seg0_idx(oldconf)); |  | ||||||
| -		hostapd_set_oper_centr_freq_seg1_idx( |  | ||||||
| -			hapd->iconf, |  | ||||||
| -			hostapd_get_oper_centr_freq_seg1_idx(oldconf)); |  | ||||||
|  		hapd->conf = newconf->bss[j]; |  | ||||||
|  		hostapd_reload_bss(hapd); |  | ||||||
|  	} |  | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -2918,10 +2918,15 @@ static int wpa_driver_nl80211_del_beacon | @@ -2891,10 +2891,15 @@ static int wpa_driver_nl80211_del_beacon | ||||||
|  	struct nl_msg *msg; |  	struct nl_msg *msg; | ||||||
|  	struct wpa_driver_nl80211_data *drv = bss->drv; |  	struct wpa_driver_nl80211_data *drv = bss->drv; | ||||||
|   |   | ||||||
| @@ -18,7 +18,7 @@ | |||||||
|  	return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); |  	return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -5602,7 +5607,7 @@ static void nl80211_teardown_ap(struct i | @@ -5550,7 +5555,7 @@ static void nl80211_teardown_ap(struct i | ||||||
|  		nl80211_mgmt_unsubscribe(bss, "AP teardown"); |  		nl80211_mgmt_unsubscribe(bss, "AP teardown"); | ||||||
|   |   | ||||||
|  	nl80211_put_wiphy_data_ap(bss); |  	nl80211_put_wiphy_data_ap(bss); | ||||||
| @@ -27,7 +27,7 @@ | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -8051,8 +8056,6 @@ static int wpa_driver_nl80211_if_remove( | @@ -7990,8 +7995,6 @@ static int wpa_driver_nl80211_if_remove( | ||||||
|  	} else { |  	} else { | ||||||
|  		wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); |  		wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); | ||||||
|  		nl80211_teardown_ap(bss); |  		nl80211_teardown_ap(bss); | ||||||
| @@ -36,7 +36,7 @@ | |||||||
|  		nl80211_destroy_bss(bss); |  		nl80211_destroy_bss(bss); | ||||||
|  		if (!bss->added_if) |  		if (!bss->added_if) | ||||||
|  			i802_set_iface_flags(bss, 0); |  			i802_set_iface_flags(bss, 0); | ||||||
| @@ -8449,7 +8452,6 @@ static int wpa_driver_nl80211_deinit_ap( | @@ -8388,7 +8391,6 @@ static int wpa_driver_nl80211_deinit_ap( | ||||||
|  	if (!is_ap_interface(drv->nlmode)) |  	if (!is_ap_interface(drv->nlmode)) | ||||||
|  		return -1; |  		return -1; | ||||||
|  	wpa_driver_nl80211_del_beacon(bss); |  	wpa_driver_nl80211_del_beacon(bss); | ||||||
| @@ -44,7 +44,7 @@ | |||||||
|   |   | ||||||
|  	/* |  	/* | ||||||
|  	 * If the P2P GO interface was dynamically added, then it is |  	 * If the P2P GO interface was dynamically added, then it is | ||||||
| @@ -8469,7 +8471,6 @@ static int wpa_driver_nl80211_stop_ap(vo | @@ -8408,7 +8410,6 @@ static int wpa_driver_nl80211_stop_ap(vo | ||||||
|  	if (!is_ap_interface(drv->nlmode)) |  	if (!is_ap_interface(drv->nlmode)) | ||||||
|  		return -1; |  		return -1; | ||||||
|  	wpa_driver_nl80211_del_beacon(bss); |  	wpa_driver_nl80211_del_beacon(bss); | ||||||
|   | |||||||
| @@ -1,106 +0,0 @@ | |||||||
| --- a/hostapd/ctrl_iface.c |  | ||||||
| +++ b/hostapd/ctrl_iface.c |  | ||||||
| @@ -67,6 +67,7 @@ |  | ||||||
|  #include "fst/fst_ctrl_iface.h" |  | ||||||
|  #include "config_file.h" |  | ||||||
|  #include "ctrl_iface.h" |  | ||||||
| +#include "config_file.h" |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256 |  | ||||||
| @@ -82,6 +83,7 @@ static void hostapd_ctrl_iface_send(stru |  | ||||||
|  				    enum wpa_msg_type type, |  | ||||||
|  				    const char *buf, size_t len); |  | ||||||
|   |  | ||||||
| +static char *reload_opts = NULL; |  | ||||||
|   |  | ||||||
|  static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, |  | ||||||
|  				     struct sockaddr_storage *from, |  | ||||||
| @@ -133,6 +135,61 @@ static int hostapd_ctrl_iface_new_sta(st |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static char *get_option(char *opt, char *str) |  | ||||||
| +{ |  | ||||||
| +	int len = strlen(str); |  | ||||||
| + |  | ||||||
| +	if (!strncmp(opt, str, len)) |  | ||||||
| +		return opt + len; |  | ||||||
| +	else |  | ||||||
| +		return NULL; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) |  | ||||||
| +{ |  | ||||||
| +	struct hostapd_config *conf; |  | ||||||
| +	char *opt, *val; |  | ||||||
| + |  | ||||||
| +	conf = hostapd_config_read(fname); |  | ||||||
| +	if (!conf) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	for (opt = strtok(reload_opts, " "); |  | ||||||
| +	     opt; |  | ||||||
| +		 opt = strtok(NULL, " ")) { |  | ||||||
| + |  | ||||||
| +		if ((val = get_option(opt, "channel="))) |  | ||||||
| +			conf->channel = atoi(val); |  | ||||||
| +		else if ((val = get_option(opt, "ht_capab="))) |  | ||||||
| +			conf->ht_capab = atoi(val); |  | ||||||
| +		else if ((val = get_option(opt, "ht_capab_mask="))) |  | ||||||
| +			conf->ht_capab &= atoi(val); |  | ||||||
| +		else if ((val = get_option(opt, "sec_chan="))) |  | ||||||
| +			conf->secondary_channel = atoi(val); |  | ||||||
| +		else if ((val = get_option(opt, "hw_mode="))) |  | ||||||
| +			conf->hw_mode = atoi(val); |  | ||||||
| +		else if ((val = get_option(opt, "ieee80211n="))) |  | ||||||
| +			conf->ieee80211n = atoi(val); |  | ||||||
| +		else |  | ||||||
| +			break; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return conf; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) |  | ||||||
| +{ |  | ||||||
| +	struct hostapd_config * (*config_read_cb)(const char *config_fname); |  | ||||||
| +	struct hostapd_iface *iface = hapd->iface; |  | ||||||
| + |  | ||||||
| +	config_read_cb = iface->interfaces->config_read_cb; |  | ||||||
| +	iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; |  | ||||||
| +	reload_opts = txt; |  | ||||||
| + |  | ||||||
| +	hostapd_reload_config(iface); |  | ||||||
| + |  | ||||||
| +	iface->interfaces->config_read_cb = config_read_cb; |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  #ifdef NEED_AP_MLME |  | ||||||
|  static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd, |  | ||||||
| @@ -3754,6 +3811,8 @@ static int hostapd_ctrl_iface_receive_pr |  | ||||||
|  	} else if (os_strncmp(buf, "VENDOR ", 7) == 0) { |  | ||||||
|  		reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, |  | ||||||
|  						      reply_size); |  | ||||||
| +	} else if (os_strncmp(buf, "UPDATE ", 7) == 0) { |  | ||||||
| +		hostapd_ctrl_iface_update(hapd, buf + 7); |  | ||||||
|  	} else if (os_strcmp(buf, "ERP_FLUSH") == 0) { |  | ||||||
|  		ieee802_1x_erp_flush(hapd); |  | ||||||
|  #ifdef RADIUS_SERVER |  | ||||||
| --- a/src/ap/ctrl_iface_ap.c |  | ||||||
| +++ b/src/ap/ctrl_iface_ap.c |  | ||||||
| @@ -919,7 +919,13 @@ int hostapd_parse_csa_settings(const cha |  | ||||||
|   |  | ||||||
|  int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) |  | ||||||
|  { |  | ||||||
| -	return hostapd_drv_stop_ap(hapd); |  | ||||||
| +	struct hostapd_iface *iface = hapd->iface; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < iface->num_bss; i++) |  | ||||||
| +		hostapd_drv_stop_ap(iface->bss[i]); |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -1,414 +0,0 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile |  | ||||||
| @@ -103,6 +103,8 @@ OBJS_c += ../src/utils/common.o |  | ||||||
|  OBJS_c += ../src/common/cli.o |  | ||||||
|  OBJS += wmm_ac.o |  | ||||||
|   |  | ||||||
| +OBJS += ../src/common/wpa_ctrl.o |  | ||||||
| + |  | ||||||
|  ifndef CONFIG_OS |  | ||||||
|  ifdef CONFIG_NATIVE_WINDOWS |  | ||||||
|  CONFIG_OS=win32 |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/bss.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.c |  | ||||||
| @@ -11,6 +11,7 @@ |  | ||||||
|  #include "utils/common.h" |  | ||||||
|  #include "utils/eloop.h" |  | ||||||
|  #include "common/ieee802_11_defs.h" |  | ||||||
| +#include "common/ieee802_11_common.h" |  | ||||||
|  #include "drivers/driver.h" |  | ||||||
|  #include "eap_peer/eap.h" |  | ||||||
|  #include "wpa_supplicant_i.h" |  | ||||||
| @@ -282,6 +283,10 @@ void calculate_update_time(const struct |  | ||||||
|  static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, |  | ||||||
|  			     struct os_reltime *fetch_time) |  | ||||||
|  { |  | ||||||
| +	struct ieee80211_ht_capabilities *capab; |  | ||||||
| +	struct ieee80211_ht_operation *oper; |  | ||||||
| +	struct ieee802_11_elems elems; |  | ||||||
| + |  | ||||||
|  	dst->flags = src->flags; |  | ||||||
|  	os_memcpy(dst->bssid, src->bssid, ETH_ALEN); |  | ||||||
|  	dst->freq = src->freq; |  | ||||||
| @@ -294,6 +299,15 @@ static void wpa_bss_copy_res(struct wpa_ |  | ||||||
|  	dst->est_throughput = src->est_throughput; |  | ||||||
|  	dst->snr = src->snr; |  | ||||||
|   |  | ||||||
| +	memset(&elems, 0, sizeof(elems)); |  | ||||||
| +	ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); |  | ||||||
| +	capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; |  | ||||||
| +	oper = (struct ieee80211_ht_operation *) elems.ht_operation; |  | ||||||
| +	if (capab) |  | ||||||
| +		dst->ht_capab = le_to_host16(capab->ht_capabilities_info); |  | ||||||
| +	if (oper) |  | ||||||
| +		dst->ht_param = oper->ht_param; |  | ||||||
| + |  | ||||||
|  	calculate_update_time(fetch_time, src->age, &dst->last_update); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.h |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/bss.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.h |  | ||||||
| @@ -94,6 +94,10 @@ struct wpa_bss { |  | ||||||
|  	u8 ssid[SSID_MAX_LEN]; |  | ||||||
|  	/** Length of SSID */ |  | ||||||
|  	size_t ssid_len; |  | ||||||
| +	/** HT capabilities */ |  | ||||||
| +	u16 ht_capab; |  | ||||||
| +	/* Five octets of HT Operation Information */ |  | ||||||
| +	u8 ht_param; |  | ||||||
|  	/** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ |  | ||||||
|  	int freq; |  | ||||||
|  	/** Beacon interval in TUs (host byte order) */ |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c |  | ||||||
| @@ -34,7 +34,7 @@ static void usage(void) |  | ||||||
|  	       "vW] [-P<pid file>] " |  | ||||||
|  	       "[-g<global ctrl>] \\\n" |  | ||||||
|  	       "        [-G<group>] \\\n" |  | ||||||
| -	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] " |  | ||||||
| +	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-H<hostapd path>] " |  | ||||||
|  	       "[-p<driver_param>] \\\n" |  | ||||||
|  	       "        [-b<br_ifname>] [-e<entropy file>]" |  | ||||||
|  #ifdef CONFIG_DEBUG_FILE |  | ||||||
| @@ -74,6 +74,7 @@ static void usage(void) |  | ||||||
|  	       "  -g = global ctrl_interface\n" |  | ||||||
|  	       "  -G = global ctrl_interface group\n" |  | ||||||
|  	       "  -h = show this help text\n" |  | ||||||
| +	       "  -H = connect to a hostapd instance to manage state changes\n" |  | ||||||
|  	       "  -i = interface name\n" |  | ||||||
|  	       "  -I = additional configuration file\n" |  | ||||||
|  	       "  -K = include keys (passwords, etc.) in debug output\n" |  | ||||||
| @@ -201,7 +202,7 @@ int main(int argc, char *argv[]) |  | ||||||
|   |  | ||||||
|  	for (;;) { |  | ||||||
|  		c = getopt(argc, argv, |  | ||||||
| -			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); |  | ||||||
| +			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); |  | ||||||
|  		if (c < 0) |  | ||||||
|  			break; |  | ||||||
|  		switch (c) { |  | ||||||
| @@ -248,6 +249,9 @@ int main(int argc, char *argv[]) |  | ||||||
|  			usage(); |  | ||||||
|  			exitcode = 0; |  | ||||||
|  			goto out; |  | ||||||
| +		case 'H': |  | ||||||
| +			iface->hostapd_ctrl = optarg; |  | ||||||
| +			break; |  | ||||||
|  		case 'i': |  | ||||||
|  			iface->ifname = optarg; |  | ||||||
|  			break; |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c |  | ||||||
| @@ -130,6 +130,54 @@ static void wpas_update_fils_connect_par |  | ||||||
|  static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s); |  | ||||||
|  #endif /* CONFIG_OWE */ |  | ||||||
|   |  | ||||||
| +static int hostapd_stop(struct wpa_supplicant *wpa_s) |  | ||||||
| +{ |  | ||||||
| +	const char *cmd = "STOP_AP"; |  | ||||||
| +	char buf[256]; |  | ||||||
| +	size_t len = sizeof(buf); |  | ||||||
| + |  | ||||||
| +	if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { |  | ||||||
| +		wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); |  | ||||||
| +		return -1; |  | ||||||
| +	} |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) |  | ||||||
| +{ |  | ||||||
| +	char *cmd = NULL; |  | ||||||
| +	char buf[256]; |  | ||||||
| +	size_t len = sizeof(buf); |  | ||||||
| +	enum hostapd_hw_mode hw_mode; |  | ||||||
| +	u8 channel; |  | ||||||
| +	int sec_chan = 0; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	if (!bss) |  | ||||||
| +		return -1; |  | ||||||
| + |  | ||||||
| +	if (bss->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) { |  | ||||||
| +		int sec = bss->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; |  | ||||||
| +		if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) |  | ||||||
| +			sec_chan = 1; |  | ||||||
| +		else if (sec ==  HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) |  | ||||||
| +			sec_chan = -1; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); |  | ||||||
| +	if (asprintf(&cmd, "UPDATE channel=%d sec_chan=%d hw_mode=%d", |  | ||||||
| +		     channel, sec_chan, hw_mode) < 0) |  | ||||||
| +		return -1; |  | ||||||
| + |  | ||||||
| +	ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); |  | ||||||
| +	free(cmd); |  | ||||||
| + |  | ||||||
| +	if (ret < 0) { |  | ||||||
| +		wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); |  | ||||||
| +		return -1; |  | ||||||
| +	} |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_WEP |  | ||||||
|  /* Configure default/group WEP keys for static WEP */ |  | ||||||
| @@ -1007,6 +1055,8 @@ void wpa_supplicant_set_state(struct wpa |  | ||||||
|   |  | ||||||
|  		sme_sched_obss_scan(wpa_s, 1); |  | ||||||
|   |  | ||||||
| +		if (wpa_s->hostapd) |  | ||||||
| +			hostapd_reload(wpa_s, wpa_s->current_bss); |  | ||||||
|  #if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL) |  | ||||||
|  		if (!fils_hlp_sent && ssid && ssid->eap.erp) |  | ||||||
|  			update_fils_connect_params = true; |  | ||||||
| @@ -1017,6 +1067,8 @@ void wpa_supplicant_set_state(struct wpa |  | ||||||
|  #endif /* CONFIG_OWE */ |  | ||||||
|  	} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || |  | ||||||
|  		   state == WPA_ASSOCIATED) { |  | ||||||
| +		if (wpa_s->hostapd) |  | ||||||
| +			hostapd_stop(wpa_s); |  | ||||||
|  		wpa_s->new_connection = 1; |  | ||||||
|  		wpa_drv_set_operstate(wpa_s, 0); |  | ||||||
|  #ifndef IEEE8021X_EAPOL |  | ||||||
| @@ -2276,6 +2328,8 @@ void wpa_supplicant_associate(struct wpa |  | ||||||
|  			return; |  | ||||||
|  		} |  | ||||||
|  		wpa_s->current_bss = bss; |  | ||||||
| +		if (wpa_s->hostapd) |  | ||||||
| +			hostapd_reload(wpa_s, wpa_s->current_bss); |  | ||||||
|  #else /* CONFIG_MESH */ |  | ||||||
|  		wpa_msg(wpa_s, MSG_ERROR, |  | ||||||
|  			"mesh mode support not included in the build"); |  | ||||||
| @@ -6419,6 +6473,16 @@ static int wpa_supplicant_init_iface(str |  | ||||||
|  			   sizeof(wpa_s->bridge_ifname)); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if (iface->hostapd_ctrl) { |  | ||||||
| +		wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); |  | ||||||
| +		if (!wpa_s->hostapd) { |  | ||||||
| +			wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); |  | ||||||
| +			return -1; |  | ||||||
| +		} |  | ||||||
| +		if (hostapd_stop(wpa_s) < 0) |  | ||||||
| +			return -1; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* RSNA Supplicant Key Management - INITIALIZE */ |  | ||||||
|  	eapol_sm_notify_portEnabled(wpa_s->eapol, false); |  | ||||||
|  	eapol_sm_notify_portValid(wpa_s->eapol, false); |  | ||||||
| @@ -6756,6 +6820,11 @@ static void wpa_supplicant_deinit_iface( |  | ||||||
|  	if (terminate) |  | ||||||
|  		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); |  | ||||||
|   |  | ||||||
| +	if (wpa_s->hostapd) { |  | ||||||
| +		wpa_ctrl_close(wpa_s->hostapd); |  | ||||||
| +		wpa_s->hostapd = NULL; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	if (wpa_s->ctrl_iface) { |  | ||||||
|  		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); |  | ||||||
|  		wpa_s->ctrl_iface = NULL; |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h |  | ||||||
| @@ -103,6 +103,11 @@ struct wpa_interface { |  | ||||||
|  	const char *ifname; |  | ||||||
|   |  | ||||||
|  	/** |  | ||||||
| +	 * hostapd_ctrl - path to hostapd control socket for notification |  | ||||||
| +	 */ |  | ||||||
| +	const char *hostapd_ctrl; |  | ||||||
| + |  | ||||||
| +	/** |  | ||||||
|  	 * bridge_ifname - Optional bridge interface name |  | ||||||
|  	 * |  | ||||||
|  	 * If the driver interface (ifname) is included in a Linux bridge |  | ||||||
| @@ -611,6 +616,8 @@ struct wpa_supplicant { |  | ||||||
|  #endif /* CONFIG_CTRL_IFACE_BINDER */ |  | ||||||
|  	char bridge_ifname[16]; |  | ||||||
|   |  | ||||||
| +	struct wpa_ctrl *hostapd; |  | ||||||
| + |  | ||||||
|  	char *confname; |  | ||||||
|  	char *confanother; |  | ||||||
|   |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/ctrl_iface.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c |  | ||||||
| @@ -2781,6 +2781,11 @@ static int hostapd_ctrl_iface_chan_switc |  | ||||||
|  		return 0; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if (os_strstr(pos, " auto-ht")) { |  | ||||||
| +		settings.freq_params.ht_enabled = iface->conf->ieee80211n; |  | ||||||
| +		settings.freq_params.vht_enabled = iface->conf->ieee80211ac; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	for (i = 0; i < iface->num_bss; i++) { |  | ||||||
|   |  | ||||||
|  		/* Save CHAN_SWITCH VHT and HE config */ |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c |  | ||||||
| @@ -1753,11 +1753,6 @@ int ieee802_11_set_beacon(struct hostapd |  | ||||||
|  	struct wpabuf *beacon, *proberesp, *assocresp; |  | ||||||
|  	int res, ret = -1; |  | ||||||
|   |  | ||||||
| -	if (hapd->csa_in_progress) { |  | ||||||
| -		wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); |  | ||||||
| -		return -1; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	hapd->beacon_set_done = 1; |  | ||||||
|   |  | ||||||
|  	if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/events.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/events.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/events.c |  | ||||||
| @@ -4666,6 +4666,60 @@ static void wpas_event_unprot_beacon(str |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| +static void |  | ||||||
| +supplicant_ch_switch_started(struct wpa_supplicant *wpa_s, |  | ||||||
| +			    union wpa_event_data *data) |  | ||||||
| +{ |  | ||||||
| +	char buf[256]; |  | ||||||
| +	size_t len = sizeof(buf); |  | ||||||
| +	char *cmd = NULL; |  | ||||||
| +	int width = 20; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	if (!wpa_s->hostapd) |  | ||||||
| +		return; |  | ||||||
| + |  | ||||||
| +	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH |  | ||||||
| +		"count=%d freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", |  | ||||||
| +		data->ch_switch.count, |  | ||||||
| +		data->ch_switch.freq, |  | ||||||
| +		data->ch_switch.ht_enabled, |  | ||||||
| +		data->ch_switch.ch_offset, |  | ||||||
| +		channel_width_to_string(data->ch_switch.ch_width), |  | ||||||
| +		data->ch_switch.cf1, |  | ||||||
| +		data->ch_switch.cf2); |  | ||||||
| + |  | ||||||
| +	switch (data->ch_switch.ch_width) { |  | ||||||
| +	case CHAN_WIDTH_20_NOHT: |  | ||||||
| +	case CHAN_WIDTH_20: |  | ||||||
| +		width = 20; |  | ||||||
| +		break; |  | ||||||
| +	case CHAN_WIDTH_40: |  | ||||||
| +		width = 40; |  | ||||||
| +		break; |  | ||||||
| +	case CHAN_WIDTH_80: |  | ||||||
| +		width = 80; |  | ||||||
| +		break; |  | ||||||
| +	case CHAN_WIDTH_160: |  | ||||||
| +	case CHAN_WIDTH_80P80: |  | ||||||
| +		width = 160; |  | ||||||
| +		break; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	asprintf(&cmd, "CHAN_SWITCH %d %d sec_channel_offset=%d center_freq1=%d center_freq2=%d, bandwidth=%d auto-ht\n", |  | ||||||
| +		data->ch_switch.count - 1, |  | ||||||
| +		data->ch_switch.freq, |  | ||||||
| +		data->ch_switch.ch_offset, |  | ||||||
| +		data->ch_switch.cf1, |  | ||||||
| +		data->ch_switch.cf2, |  | ||||||
| +		width); |  | ||||||
| +	ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); |  | ||||||
| +	free(cmd); |  | ||||||
| + |  | ||||||
| +	if (ret < 0) |  | ||||||
| +		wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  void supplicant_event(void *ctx, enum wpa_event_type event, |  | ||||||
|  		      union wpa_event_data *data) |  | ||||||
|  { |  | ||||||
| @@ -4981,8 +5035,10 @@ void supplicant_event(void *ctx, enum wp |  | ||||||
|  			channel_width_to_string(data->ch_switch.ch_width), |  | ||||||
|  			data->ch_switch.cf1, |  | ||||||
|  			data->ch_switch.cf2); |  | ||||||
| -		if (event == EVENT_CH_SWITCH_STARTED) |  | ||||||
| +		if (event == EVENT_CH_SWITCH_STARTED) { |  | ||||||
| +			supplicant_ch_switch_started(wpa_s, data); |  | ||||||
|  			break; |  | ||||||
| +		} |  | ||||||
|   |  | ||||||
|  		wpa_s->assoc_freq = data->ch_switch.freq; |  | ||||||
|  		wpa_s->current_ssid->frequency = data->ch_switch.freq; |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h |  | ||||||
| @@ -5822,6 +5822,7 @@ union wpa_event_data { |  | ||||||
|   |  | ||||||
|  	/** |  | ||||||
|  	 * struct ch_switch |  | ||||||
| +	 * @count: Count until channel switch activates |  | ||||||
|  	 * @freq: Frequency of new channel in MHz |  | ||||||
|  	 * @ht_enabled: Whether this is an HT channel |  | ||||||
|  	 * @ch_offset: Secondary channel offset |  | ||||||
| @@ -5830,6 +5831,7 @@ union wpa_event_data { |  | ||||||
|  	 * @cf2: Center frequency 2 |  | ||||||
|  	 */ |  | ||||||
|  	struct ch_switch { |  | ||||||
| +		int count; |  | ||||||
|  		int freq; |  | ||||||
|  		int ht_enabled; |  | ||||||
|  		int ch_offset; |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211_event.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver_nl80211_event.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211_event.c |  | ||||||
| @@ -655,7 +655,7 @@ static void mlme_event_ch_switch(struct |  | ||||||
|  				 struct nlattr *ifindex, struct nlattr *freq, |  | ||||||
|  				 struct nlattr *type, struct nlattr *bw, |  | ||||||
|  				 struct nlattr *cf1, struct nlattr *cf2, |  | ||||||
| -				 int finished) |  | ||||||
| +				 struct nlattr *count, int finished) |  | ||||||
|  { |  | ||||||
|  	struct i802_bss *bss; |  | ||||||
|  	union wpa_event_data data; |  | ||||||
| @@ -714,6 +714,8 @@ static void mlme_event_ch_switch(struct |  | ||||||
|  		data.ch_switch.cf1 = nla_get_u32(cf1); |  | ||||||
|  	if (cf2) |  | ||||||
|  		data.ch_switch.cf2 = nla_get_u32(cf2); |  | ||||||
| +	if (count) |  | ||||||
| +		data.ch_switch.count = nla_get_u32(count); |  | ||||||
|   |  | ||||||
|  	if (finished) |  | ||||||
|  		bss->freq = data.ch_switch.freq; |  | ||||||
| @@ -2886,6 +2888,7 @@ static void do_process_drv_event(struct |  | ||||||
|  				     tb[NL80211_ATTR_CHANNEL_WIDTH], |  | ||||||
|  				     tb[NL80211_ATTR_CENTER_FREQ1], |  | ||||||
|  				     tb[NL80211_ATTR_CENTER_FREQ2], |  | ||||||
| +				     tb[NL80211_ATTR_CH_SWITCH_COUNT], |  | ||||||
|  				     0); |  | ||||||
|  		break; |  | ||||||
|  	case NL80211_CMD_CH_SWITCH_NOTIFY: |  | ||||||
| @@ -2896,6 +2899,7 @@ static void do_process_drv_event(struct |  | ||||||
|  				     tb[NL80211_ATTR_CHANNEL_WIDTH], |  | ||||||
|  				     tb[NL80211_ATTR_CENTER_FREQ1], |  | ||||||
|  				     tb[NL80211_ATTR_CENTER_FREQ2], |  | ||||||
| +				     NULL, |  | ||||||
|  				     1); |  | ||||||
|  		break; |  | ||||||
|  	case NL80211_CMD_DISCONNECT: |  | ||||||
| @@ -12,7 +12,7 @@ | |||||||
|  else |  else | ||||||
| --- a/hostapd/ctrl_iface.c | --- a/hostapd/ctrl_iface.c | ||||||
| +++ b/hostapd/ctrl_iface.c | +++ b/hostapd/ctrl_iface.c | ||||||
| @@ -3569,6 +3569,7 @@ static int hostapd_ctrl_iface_receive_pr | @@ -3388,6 +3388,7 @@ static int hostapd_ctrl_iface_receive_pr | ||||||
|  						      reply_size); |  						      reply_size); | ||||||
|  	} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { |  	} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { | ||||||
|  		reply_len = hostapd_drv_status(hapd, reply, reply_size); |  		reply_len = hostapd_drv_status(hapd, reply, reply_size); | ||||||
| @@ -20,7 +20,7 @@ | |||||||
|  	} else if (os_strcmp(buf, "MIB") == 0) { |  	} else if (os_strcmp(buf, "MIB") == 0) { | ||||||
|  		reply_len = ieee802_11_get_mib(hapd, reply, reply_size); |  		reply_len = ieee802_11_get_mib(hapd, reply, reply_size); | ||||||
|  		if (reply_len >= 0) { |  		if (reply_len >= 0) { | ||||||
| @@ -3610,6 +3611,7 @@ static int hostapd_ctrl_iface_receive_pr | @@ -3429,6 +3430,7 @@ static int hostapd_ctrl_iface_receive_pr | ||||||
|  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { |  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { | ||||||
|  		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, |  		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, | ||||||
|  							reply_size); |  							reply_size); | ||||||
| @@ -30,7 +30,7 @@ | |||||||
|  			reply_len = -1; |  			reply_len = -1; | ||||||
| --- a/wpa_supplicant/Makefile | --- a/wpa_supplicant/Makefile | ||||||
| +++ b/wpa_supplicant/Makefile | +++ b/wpa_supplicant/Makefile | ||||||
| @@ -955,6 +955,9 @@ ifdef CONFIG_FILS | @@ -942,6 +942,9 @@ ifdef CONFIG_FILS | ||||||
|  OBJS += ../src/ap/fils_hlp.o |  OBJS += ../src/ap/fils_hlp.o | ||||||
|  endif |  endif | ||||||
|  ifdef CONFIG_CTRL_IFACE |  ifdef CONFIG_CTRL_IFACE | ||||||
| @@ -42,7 +42,7 @@ | |||||||
|   |   | ||||||
| --- a/wpa_supplicant/ctrl_iface.c | --- a/wpa_supplicant/ctrl_iface.c | ||||||
| +++ b/wpa_supplicant/ctrl_iface.c | +++ b/wpa_supplicant/ctrl_iface.c | ||||||
| @@ -2308,7 +2308,7 @@ static int wpa_supplicant_ctrl_iface_sta | @@ -2294,7 +2294,7 @@ static int wpa_supplicant_ctrl_iface_sta | ||||||
|  			pos += ret; |  			pos += ret; | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
| @@ -51,7 +51,7 @@ | |||||||
|  		if (wpa_s->ap_iface) { |  		if (wpa_s->ap_iface) { | ||||||
|  			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, |  			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, | ||||||
|  							    end - pos, |  							    end - pos, | ||||||
| @@ -10919,6 +10919,7 @@ char * wpa_supplicant_ctrl_iface_process | @@ -10602,6 +10602,7 @@ char * wpa_supplicant_ctrl_iface_process | ||||||
|  			reply_len = -1; |  			reply_len = -1; | ||||||
|  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) { |  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) { | ||||||
|  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); |  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); | ||||||
| @@ -59,7 +59,7 @@ | |||||||
|  	} else if (os_strcmp(buf, "MIB") == 0) { |  	} else if (os_strcmp(buf, "MIB") == 0) { | ||||||
|  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); |  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); | ||||||
|  		if (reply_len >= 0) { |  		if (reply_len >= 0) { | ||||||
| @@ -10931,6 +10932,7 @@ char * wpa_supplicant_ctrl_iface_process | @@ -10614,6 +10615,7 @@ char * wpa_supplicant_ctrl_iface_process | ||||||
|  				reply_size - reply_len); |  				reply_size - reply_len); | ||||||
|  #endif /* CONFIG_MACSEC */ |  #endif /* CONFIG_MACSEC */ | ||||||
|  		} |  		} | ||||||
| @@ -67,7 +67,7 @@ | |||||||
|  	} else if (os_strncmp(buf, "STATUS", 6) == 0) { |  	} else if (os_strncmp(buf, "STATUS", 6) == 0) { | ||||||
|  		reply_len = wpa_supplicant_ctrl_iface_status( |  		reply_len = wpa_supplicant_ctrl_iface_status( | ||||||
|  			wpa_s, buf + 6, reply, reply_size); |  			wpa_s, buf + 6, reply, reply_size); | ||||||
| @@ -11419,6 +11421,7 @@ char * wpa_supplicant_ctrl_iface_process | @@ -11102,6 +11104,7 @@ char * wpa_supplicant_ctrl_iface_process | ||||||
|  		reply_len = wpa_supplicant_ctrl_iface_bss( |  		reply_len = wpa_supplicant_ctrl_iface_bss( | ||||||
|  			wpa_s, buf + 4, reply, reply_size); |  			wpa_s, buf + 4, reply, reply_size); | ||||||
|  #ifdef CONFIG_AP |  #ifdef CONFIG_AP | ||||||
| @@ -75,7 +75,7 @@ | |||||||
|  	} else if (os_strcmp(buf, "STA-FIRST") == 0) { |  	} else if (os_strcmp(buf, "STA-FIRST") == 0) { | ||||||
|  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); |  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); | ||||||
|  	} else if (os_strncmp(buf, "STA ", 4) == 0) { |  	} else if (os_strncmp(buf, "STA ", 4) == 0) { | ||||||
| @@ -11427,12 +11430,15 @@ char * wpa_supplicant_ctrl_iface_process | @@ -11110,12 +11113,15 @@ char * wpa_supplicant_ctrl_iface_process | ||||||
|  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { |  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { | ||||||
|  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, |  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, | ||||||
|  						   reply_size); |  						   reply_size); | ||||||
| @@ -144,7 +144,7 @@ | |||||||
|  static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) |  static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) | ||||||
| --- a/src/ap/wpa_auth.c | --- a/src/ap/wpa_auth.c | ||||||
| +++ b/src/ap/wpa_auth.c | +++ b/src/ap/wpa_auth.c | ||||||
| @@ -4519,6 +4519,7 @@ static const char * wpa_bool_txt(int val | @@ -4503,6 +4503,7 @@ static const char * wpa_bool_txt(int val | ||||||
|  	return val ? "TRUE" : "FALSE"; |  	return val ? "TRUE" : "FALSE"; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -152,7 +152,7 @@ | |||||||
|   |   | ||||||
|  #define RSN_SUITE "%02x-%02x-%02x-%d" |  #define RSN_SUITE "%02x-%02x-%02x-%d" | ||||||
|  #define RSN_SUITE_ARG(s) \ |  #define RSN_SUITE_ARG(s) \ | ||||||
| @@ -4669,7 +4670,7 @@ int wpa_get_mib_sta(struct wpa_state_mac | @@ -4653,7 +4654,7 @@ int wpa_get_mib_sta(struct wpa_state_mac | ||||||
|   |   | ||||||
|  	return len; |  	return len; | ||||||
|  } |  } | ||||||
| @@ -163,7 +163,7 @@ | |||||||
|  { |  { | ||||||
| --- a/src/rsn_supp/wpa.c | --- a/src/rsn_supp/wpa.c | ||||||
| +++ b/src/rsn_supp/wpa.c | +++ b/src/rsn_supp/wpa.c | ||||||
| @@ -2767,6 +2767,8 @@ static u32 wpa_key_mgmt_suite(struct wpa | @@ -2763,6 +2763,8 @@ static u32 wpa_key_mgmt_suite(struct wpa | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -172,7 +172,7 @@ | |||||||
|  #define RSN_SUITE "%02x-%02x-%02x-%d" |  #define RSN_SUITE "%02x-%02x-%02x-%d" | ||||||
|  #define RSN_SUITE_ARG(s) \ |  #define RSN_SUITE_ARG(s) \ | ||||||
|  ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff |  ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff | ||||||
| @@ -2848,6 +2850,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch | @@ -2844,6 +2846,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch | ||||||
|   |   | ||||||
|  	return (int) len; |  	return (int) len; | ||||||
|  } |  } | ||||||
|   | |||||||
| @@ -36,16 +36,16 @@ | |||||||
|  #include "fst/fst.h" |  #include "fst/fst.h" | ||||||
|  #include "wpa_supplicant_i.h" |  #include "wpa_supplicant_i.h" | ||||||
|  #include "driver_i.h" |  #include "driver_i.h" | ||||||
| @@ -202,7 +203,7 @@ int main(int argc, char *argv[]) | @@ -201,7 +202,7 @@ int main(int argc, char *argv[]) | ||||||
|   |   | ||||||
|  	for (;;) { |  	for (;;) { | ||||||
|  		c = getopt(argc, argv, |  		c = getopt(argc, argv, | ||||||
| -			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); | -			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); | ||||||
| +			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); | +			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); | ||||||
|  		if (c < 0) |  		if (c < 0) | ||||||
|  			break; |  			break; | ||||||
|  		switch (c) { |  		switch (c) { | ||||||
| @@ -305,8 +306,12 @@ int main(int argc, char *argv[]) | @@ -301,8 +302,12 @@ int main(int argc, char *argv[]) | ||||||
|  			break; |  			break; | ||||||
|  #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ |  #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ | ||||||
|  		case 'v': |  		case 'v': | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ | |||||||
|   |   | ||||||
|   |   | ||||||
|  static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, |  static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, | ||||||
| @@ -1579,13 +1575,10 @@ static const struct hostapd_cli_cmd host | @@ -1571,13 +1567,10 @@ static const struct hostapd_cli_cmd host | ||||||
|  	{ "disassociate", hostapd_cli_cmd_disassociate, |  	{ "disassociate", hostapd_cli_cmd_disassociate, | ||||||
|  	  hostapd_complete_stations, |  	  hostapd_complete_stations, | ||||||
|  	  "<addr> = disassociate a station" }, |  	  "<addr> = disassociate a station" }, | ||||||
| @@ -46,7 +46,7 @@ | |||||||
|  	{ "wps_pin", hostapd_cli_cmd_wps_pin, NULL, |  	{ "wps_pin", hostapd_cli_cmd_wps_pin, NULL, | ||||||
|  	  "<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" }, |  	  "<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" }, | ||||||
|  	{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, |  	{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, | ||||||
| @@ -1610,7 +1603,6 @@ static const struct hostapd_cli_cmd host | @@ -1602,7 +1595,6 @@ static const struct hostapd_cli_cmd host | ||||||
|  	  "<SSID> <auth> <encr> <key> = configure AP" }, |  	  "<SSID> <auth> <encr> <key> = configure AP" }, | ||||||
|  	{ "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, |  	{ "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, | ||||||
|  	  "= show current WPS status" }, |  	  "= show current WPS status" }, | ||||||
|   | |||||||
| @@ -1,73 +0,0 @@ | |||||||
| --- a/hostapd/main.c |  | ||||||
| +++ b/hostapd/main.c |  | ||||||
| @@ -39,6 +39,8 @@ struct hapd_global { |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  static struct hapd_global global; |  | ||||||
| +static int daemonize = 0; |  | ||||||
| +static char *pid_file = NULL; |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #ifndef CONFIG_NO_HOSTAPD_LOGGER |  | ||||||
| @@ -146,6 +148,14 @@ static void hostapd_logger_cb(void *ctx, |  | ||||||
|  } |  | ||||||
|  #endif /* CONFIG_NO_HOSTAPD_LOGGER */ |  | ||||||
|   |  | ||||||
| +static void hostapd_setup_complete_cb(void *ctx) |  | ||||||
| +{ |  | ||||||
| +	if (daemonize && os_daemonize(pid_file)) { |  | ||||||
| +		perror("daemon"); |  | ||||||
| +		return; |  | ||||||
| +	} |  | ||||||
| +	daemonize = 0; |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
|   * hostapd_driver_init - Preparate driver interface |  | ||||||
| @@ -164,6 +174,8 @@ static int hostapd_driver_init(struct ho |  | ||||||
|  		return -1; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	hapd->setup_complete_cb = hostapd_setup_complete_cb; |  | ||||||
| + |  | ||||||
|  	/* Initialize the driver interface */ |  | ||||||
|  	if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) |  | ||||||
|  		b = NULL; |  | ||||||
| @@ -404,8 +416,6 @@ static void hostapd_global_deinit(const |  | ||||||
|  #endif /* CONFIG_NATIVE_WINDOWS */ |  | ||||||
|   |  | ||||||
|  	eap_server_unregister_methods(); |  | ||||||
| - |  | ||||||
| -	os_daemonize_terminate(pid_file); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -431,18 +441,6 @@ static int hostapd_global_run(struct hap |  | ||||||
|  	} |  | ||||||
|  #endif /* EAP_SERVER_TNC */ |  | ||||||
|   |  | ||||||
| -	if (daemonize) { |  | ||||||
| -		if (os_daemonize(pid_file)) { |  | ||||||
| -			wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); |  | ||||||
| -			return -1; |  | ||||||
| -		} |  | ||||||
| -		if (eloop_sock_requeue()) { |  | ||||||
| -			wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s", |  | ||||||
| -				   strerror(errno)); |  | ||||||
| -			return -1; |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	eloop_run(); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
| @@ -645,8 +643,7 @@ int main(int argc, char *argv[]) |  | ||||||
|  	struct hapd_interfaces interfaces; |  | ||||||
|  	int ret = 1; |  | ||||||
|  	size_t i, j; |  | ||||||
| -	int c, debug = 0, daemonize = 0; |  | ||||||
| -	char *pid_file = NULL; |  | ||||||
| +	int c, debug = 0; |  | ||||||
|  	const char *log_file = NULL; |  | ||||||
|  	const char *entropy_file = NULL; |  | ||||||
|  	char **bss_config = NULL, **tmp_bss; |  | ||||||
| @@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org> | |||||||
|  	 * macsec_policy - Determines the policy for MACsec secure session |  	 * macsec_policy - Determines the policy for MACsec secure session | ||||||
| --- a/wpa_supplicant/wpa_supplicant.c | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
| +++ b/wpa_supplicant/wpa_supplicant.c | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
| @@ -3726,6 +3726,12 @@ static void wpas_start_assoc_cb(struct w | @@ -3673,6 +3673,12 @@ static void wpas_start_assoc_cb(struct w | ||||||
|  			params.beacon_int = ssid->beacon_int; |  			params.beacon_int = ssid->beacon_int; | ||||||
|  		else |  		else | ||||||
|  			params.beacon_int = wpa_s->conf->beacon_int; |  			params.beacon_int = wpa_s->conf->beacon_int; | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org> | |||||||
|  |  | ||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -5951,7 +5951,7 @@ static int wpa_driver_nl80211_ibss(struc | @@ -5886,7 +5886,7 @@ static int wpa_driver_nl80211_ibss(struc | ||||||
|  				   struct wpa_driver_associate_params *params) |  				   struct wpa_driver_associate_params *params) | ||||||
|  { |  { | ||||||
|  	struct nl_msg *msg; |  	struct nl_msg *msg; | ||||||
| @@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org> | |||||||
|  	int count = 0; |  	int count = 0; | ||||||
|   |   | ||||||
|  	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); |  	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); | ||||||
| @@ -5978,6 +5978,37 @@ retry: | @@ -5913,6 +5913,37 @@ retry: | ||||||
|  	    nl80211_put_beacon_int(msg, params->beacon_int)) |  	    nl80211_put_beacon_int(msg, params->beacon_int)) | ||||||
|  		goto fail; |  		goto fail; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com> | |||||||
|  struct wpa_driver_set_key_params { |  struct wpa_driver_set_key_params { | ||||||
| --- a/src/drivers/driver_nl80211.c | --- a/src/drivers/driver_nl80211.c | ||||||
| +++ b/src/drivers/driver_nl80211.c | +++ b/src/drivers/driver_nl80211.c | ||||||
| @@ -10476,6 +10476,18 @@ static int nl80211_put_mesh_id(struct nl | @@ -10398,6 +10398,18 @@ static int nl80211_put_mesh_id(struct nl | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com> | |||||||
|  static int nl80211_put_mesh_config(struct nl_msg *msg, |  static int nl80211_put_mesh_config(struct nl_msg *msg, | ||||||
|  				   struct wpa_driver_mesh_bss_params *params) |  				   struct wpa_driver_mesh_bss_params *params) | ||||||
|  { |  { | ||||||
| @@ -10537,6 +10549,7 @@ static int nl80211_join_mesh(struct i802 | @@ -10459,6 +10471,7 @@ static int nl80211_join_mesh(struct i802 | ||||||
|  	    nl80211_put_basic_rates(msg, params->basic_rates) || |  	    nl80211_put_basic_rates(msg, params->basic_rates) || | ||||||
|  	    nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || |  	    nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || | ||||||
|  	    nl80211_put_beacon_int(msg, params->beacon_int) || |  	    nl80211_put_beacon_int(msg, params->beacon_int) || | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/wpa_supplicant/wpa_supplicant.c | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
| +++ b/wpa_supplicant/wpa_supplicant.c | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
| @@ -2457,11 +2457,13 @@ void ibss_mesh_setup_freq(struct wpa_sup | @@ -2403,11 +2403,13 @@ void ibss_mesh_setup_freq(struct wpa_sup | ||||||
|  	for (j = 0; j < wpa_s->last_scan_res_used; j++) { |  	for (j = 0; j < wpa_s->last_scan_res_used; j++) { | ||||||
|  		struct wpa_bss *bss = wpa_s->last_scan_res[j]; |  		struct wpa_bss *bss = wpa_s->last_scan_res[j]; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ | |||||||
|   |   | ||||||
|  	total = survey->channel_time; |  	total = survey->channel_time; | ||||||
|   |   | ||||||
| @@ -422,20 +416,19 @@ static int acs_usable_bw160_chan(const s | @@ -415,20 +409,19 @@ static int acs_usable_vht160_chan(const | ||||||
|  static int acs_survey_is_sufficient(struct freq_survey *survey) |  static int acs_survey_is_sufficient(struct freq_survey *survey) | ||||||
|  { |  { | ||||||
|  	if (!(survey->filled & SURVEY_HAS_NF)) { |  	if (!(survey->filled & SURVEY_HAS_NF)) { | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ | |||||||
|  NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) |  NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) | ||||||
| --- a/wpa_supplicant/Makefile | --- a/wpa_supplicant/Makefile | ||||||
| +++ b/wpa_supplicant/Makefile | +++ b/wpa_supplicant/Makefile | ||||||
| @@ -1918,31 +1918,31 @@ wpa_supplicant_multi.a: .config $(BCHECK | @@ -1905,31 +1905,31 @@ wpa_supplicant_multi.a: .config $(BCHECK | ||||||
|  	@$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) |  	@$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) | ||||||
|   |   | ||||||
|  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) |  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net> | |||||||
|  |  | ||||||
| --- a/hostapd/ctrl_iface.c | --- a/hostapd/ctrl_iface.c | ||||||
| +++ b/hostapd/ctrl_iface.c | +++ b/hostapd/ctrl_iface.c | ||||||
| @@ -897,7 +897,7 @@ static int hostapd_ctrl_iface_bss_tm_req | @@ -840,7 +840,7 @@ static int hostapd_ctrl_iface_bss_tm_req | ||||||
|  	const char *pos, *end; |  	const char *pos, *end; | ||||||
|  	int disassoc_timer = 0; |  	int disassoc_timer = 0; | ||||||
|  	struct sta_info *sta; |  	struct sta_info *sta; | ||||||
| @@ -28,7 +28,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net> | |||||||
|  	u8 bss_term_dur[12]; |  	u8 bss_term_dur[12]; | ||||||
|  	char *url = NULL; |  	char *url = NULL; | ||||||
|  	int ret; |  	int ret; | ||||||
| @@ -935,6 +935,12 @@ static int hostapd_ctrl_iface_bss_tm_req | @@ -878,6 +878,12 @@ static int hostapd_ctrl_iface_bss_tm_req | ||||||
|  		valid_int = atoi(pos); |  		valid_int = atoi(pos); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -41,7 +41,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net> | |||||||
|  	pos = os_strstr(cmd, " bss_term="); |  	pos = os_strstr(cmd, " bss_term="); | ||||||
|  	if (pos) { |  	if (pos) { | ||||||
|  		pos += 10; |  		pos += 10; | ||||||
| @@ -1041,7 +1047,7 @@ static int hostapd_ctrl_iface_bss_tm_req | @@ -984,7 +990,7 @@ static int hostapd_ctrl_iface_bss_tm_req | ||||||
|  #endif /* CONFIG_MBO */ |  #endif /* CONFIG_MBO */ | ||||||
|   |   | ||||||
|  	ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, |  	ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/ap/hostapd.h | --- a/src/ap/hostapd.h | ||||||
| +++ b/src/ap/hostapd.h | +++ b/src/ap/hostapd.h | ||||||
| @@ -150,6 +150,21 @@ struct hostapd_sae_commit_queue { | @@ -148,6 +148,21 @@ struct hostapd_sae_commit_queue { | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| @@ -22,7 +22,7 @@ | |||||||
|   * struct hostapd_data - hostapd per-BSS data structure |   * struct hostapd_data - hostapd per-BSS data structure | ||||||
|   */ |   */ | ||||||
|  struct hostapd_data { |  struct hostapd_data { | ||||||
| @@ -163,6 +178,9 @@ struct hostapd_data { | @@ -161,6 +176,9 @@ struct hostapd_data { | ||||||
|   |   | ||||||
|  	u8 own_addr[ETH_ALEN]; |  	u8 own_addr[ETH_ALEN]; | ||||||
|   |   | ||||||
| @@ -71,7 +71,7 @@ | |||||||
|  	if (disassoc_timer) { |  	if (disassoc_timer) { | ||||||
|  		/* send disassociation frame after time-out */ |  		/* send disassociation frame after time-out */ | ||||||
|  		set_disassoc_timer(hapd, sta, disassoc_timer); |  		set_disassoc_timer(hapd, sta, disassoc_timer); | ||||||
| @@ -857,6 +862,7 @@ int wnm_send_bss_tm_req(struct hostapd_d | @@ -856,6 +861,7 @@ int wnm_send_bss_tm_req(struct hostapd_d | ||||||
|  	} |  	} | ||||||
|  	os_free(buf); |  	os_free(buf); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,23 +1,20 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/hostapd/Makefile | --- a/hostapd/Makefile | ||||||
| =================================================================== | +++ b/hostapd/Makefile | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/Makefile | @@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/Makefile |  | ||||||
| @@ -166,6 +166,11 @@ OBJS += ../src/common/hw_features_common |  | ||||||
|   |   | ||||||
|  OBJS += ../src/eapol_auth/eapol_auth_sm.o |  OBJS += ../src/eapol_auth/eapol_auth_sm.o | ||||||
|   |   | ||||||
| +ifdef CONFIG_UBUS | +ifdef CONFIG_UBUS | ||||||
| +CFLAGS += -DUBUS_SUPPORT | +CFLAGS += -DUBUS_SUPPORT | ||||||
|  | +OBJS += ../src/utils/uloop.o | ||||||
| +OBJS += ../src/ap/ubus.o | +OBJS += ../src/ap/ubus.o | ||||||
| +LIBS += -lubox -lubus | +LIBS += -lubox -lubus | ||||||
| +endif | +endif | ||||||
|   |   | ||||||
|  ifdef CONFIG_CODE_COVERAGE |  ifdef CONFIG_CODE_COVERAGE | ||||||
|  CFLAGS += -O0 -fprofile-arcs -ftest-coverage |  CFLAGS += -O0 -fprofile-arcs -ftest-coverage | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | --- a/src/ap/hostapd.h | ||||||
| =================================================================== | +++ b/src/ap/hostapd.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h |  | ||||||
| @@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||||||
|  #include "utils/list.h" |  #include "utils/list.h" | ||||||
|  #include "ap_config.h" |  #include "ap_config.h" | ||||||
| @@ -26,15 +23,6 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | |||||||
|   |   | ||||||
|  #define OCE_STA_CFON_ENABLED(hapd) \ |  #define OCE_STA_CFON_ENABLED(hapd) \ | ||||||
|  	((hapd->conf->oce & OCE_STA_CFON) && \ |  	((hapd->conf->oce & OCE_STA_CFON) && \ | ||||||
| @@ -80,7 +81,7 @@ struct hapd_interfaces { |  | ||||||
|  #ifdef CONFIG_CTRL_IFACE_UDP |  | ||||||
|         unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; |  | ||||||
|  #endif /* CONFIG_CTRL_IFACE_UDP */ |  | ||||||
| - |  | ||||||
| +	struct ubus_object ubus; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  enum hostapd_chan_status { |  | ||||||
| @@ -169,6 +170,7 @@ struct hostapd_data { | @@ -169,6 +170,7 @@ struct hostapd_data { | ||||||
|  	struct hostapd_iface *iface; |  	struct hostapd_iface *iface; | ||||||
|  	struct hostapd_config *iconf; |  	struct hostapd_config *iconf; | ||||||
| @@ -51,11 +39,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | |||||||
|  void hostapd_interface_deinit(struct hostapd_iface *iface); |  void hostapd_interface_deinit(struct hostapd_iface *iface); | ||||||
|  void hostapd_interface_free(struct hostapd_iface *iface); |  void hostapd_interface_free(struct hostapd_iface *iface); | ||||||
|  struct hostapd_iface * hostapd_alloc_iface(void); |  struct hostapd_iface * hostapd_alloc_iface(void); | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| =================================================================== | +++ b/src/ap/hostapd.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c | @@ -376,6 +376,7 @@ void hostapd_free_hapd_data(struct hosta | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c |  | ||||||
| @@ -395,6 +395,7 @@ void hostapd_free_hapd_data(struct hosta |  | ||||||
|  	hapd->beacon_set_done = 0; |  	hapd->beacon_set_done = 0; | ||||||
|   |   | ||||||
|  	wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); |  	wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); | ||||||
| @@ -63,7 +49,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  	accounting_deinit(hapd); |  	accounting_deinit(hapd); | ||||||
|  	hostapd_deinit_wpa(hapd); |  	hostapd_deinit_wpa(hapd); | ||||||
|  	vlan_deinit(hapd); |  	vlan_deinit(hapd); | ||||||
| @@ -1417,6 +1418,8 @@ static int hostapd_setup_bss(struct host | @@ -1398,6 +1399,8 @@ static int hostapd_setup_bss(struct host | ||||||
|  	if (hapd->driver && hapd->driver->set_operstate) |  	if (hapd->driver && hapd->driver->set_operstate) | ||||||
|  		hapd->driver->set_operstate(hapd->drv_priv, 1); |  		hapd->driver->set_operstate(hapd->drv_priv, 1); | ||||||
|   |   | ||||||
| @@ -72,7 +58,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -2002,6 +2005,7 @@ static int hostapd_setup_interface_compl | @@ -1983,6 +1986,7 @@ static int hostapd_setup_interface_compl | ||||||
|  	if (err) |  	if (err) | ||||||
|  		goto fail; |  		goto fail; | ||||||
|   |   | ||||||
| @@ -80,7 +66,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  	wpa_printf(MSG_DEBUG, "Completing interface initialization"); |  	wpa_printf(MSG_DEBUG, "Completing interface initialization"); | ||||||
|  	if (iface->freq) { |  	if (iface->freq) { | ||||||
|  #ifdef NEED_AP_MLME |  #ifdef NEED_AP_MLME | ||||||
| @@ -2199,6 +2203,7 @@ dfs_offload: | @@ -2180,6 +2184,7 @@ dfs_offload: | ||||||
|   |   | ||||||
|  fail: |  fail: | ||||||
|  	wpa_printf(MSG_ERROR, "Interface initialization failed"); |  	wpa_printf(MSG_ERROR, "Interface initialization failed"); | ||||||
| @@ -88,7 +74,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  	hostapd_set_state(iface, HAPD_IFACE_DISABLED); |  	hostapd_set_state(iface, HAPD_IFACE_DISABLED); | ||||||
|  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); |  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); | ||||||
|  #ifdef CONFIG_FST |  #ifdef CONFIG_FST | ||||||
| @@ -2672,6 +2677,7 @@ void hostapd_interface_deinit_free(struc | @@ -2653,6 +2658,7 @@ void hostapd_interface_deinit_free(struc | ||||||
|  		   (unsigned int) iface->conf->num_bss); |  		   (unsigned int) iface->conf->num_bss); | ||||||
|  	driver = iface->bss[0]->driver; |  	driver = iface->bss[0]->driver; | ||||||
|  	drv_priv = iface->bss[0]->drv_priv; |  	drv_priv = iface->bss[0]->drv_priv; | ||||||
| @@ -96,10 +82,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  	hostapd_interface_deinit(iface); |  	hostapd_interface_deinit(iface); | ||||||
|  	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", |  	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", | ||||||
|  		   __func__, driver, drv_priv); |  		   __func__, driver, drv_priv); | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c | --- a/src/ap/ieee802_11.c | ||||||
| =================================================================== | +++ b/src/ap/ieee802_11.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_11.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c |  | ||||||
| @@ -3421,13 +3421,18 @@ static void handle_auth(struct hostapd_d | @@ -3421,13 +3421,18 @@ static void handle_auth(struct hostapd_d | ||||||
|  	u16 auth_alg, auth_transaction, status_code; |  	u16 auth_alg, auth_transaction, status_code; | ||||||
|  	u16 resp = WLAN_STATUS_SUCCESS; |  	u16 resp = WLAN_STATUS_SUCCESS; | ||||||
| @@ -186,10 +170,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c | |||||||
|  	sta = ap_get_sta(hapd, mgmt->sa); |  	sta = ap_get_sta(hapd, mgmt->sa); | ||||||
|  	if (sta == NULL) { |  	if (sta == NULL) { | ||||||
|  		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " |  		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | --- a/src/ap/beacon.c | ||||||
| =================================================================== | +++ b/src/ap/beacon.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c |  | ||||||
| @@ -823,6 +823,12 @@ void handle_probe_req(struct hostapd_dat | @@ -823,6 +823,12 @@ void handle_probe_req(struct hostapd_dat | ||||||
|  	u16 csa_offs[2]; |  	u16 csa_offs[2]; | ||||||
|  	size_t csa_offs_len; |  	size_t csa_offs_len; | ||||||
| @@ -216,10 +198,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | |||||||
|  	/* TODO: verify that supp_rates contains at least one matching rate |  	/* TODO: verify that supp_rates contains at least one matching rate | ||||||
|  	 * with AP configuration */ |  	 * with AP configuration */ | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c | --- a/src/ap/drv_callbacks.c | ||||||
| =================================================================== | +++ b/src/ap/drv_callbacks.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/drv_callbacks.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c |  | ||||||
| @@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d | @@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d | ||||||
|  	u16 reason = WLAN_REASON_UNSPECIFIED; |  	u16 reason = WLAN_REASON_UNSPECIFIED; | ||||||
|  	int status = WLAN_STATUS_SUCCESS; |  	int status = WLAN_STATUS_SUCCESS; | ||||||
| @@ -244,10 +224,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c | |||||||
|  #ifdef CONFIG_P2P |  #ifdef CONFIG_P2P | ||||||
|  	if (elems.p2p) { |  	if (elems.p2p) { | ||||||
|  		wpabuf_free(sta->p2p_ie); |  		wpabuf_free(sta->p2p_ie); | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c | --- a/src/ap/sta_info.c | ||||||
| =================================================================== | +++ b/src/ap/sta_info.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c |  | ||||||
| @@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo | @@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo | ||||||
|  		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, |  		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, | ||||||
|  			       HOSTAPD_LEVEL_INFO, "deauthenticated due to " |  			       HOSTAPD_LEVEL_INFO, "deauthenticated due to " | ||||||
| @@ -264,26 +242,70 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c | |||||||
|  		ap_free_sta(hapd, sta); |  		ap_free_sta(hapd, sta); | ||||||
|  		break; |  		break; | ||||||
|  	} |  	} | ||||||
| @@ -1319,6 +1321,7 @@ void ap_sta_set_authorized(struct hostap | @@ -1298,12 +1300,25 @@ void ap_sta_set_authorized(struct hostap | ||||||
|  |  					sta->addr, authorized, dev_addr); | ||||||
|  |   | ||||||
|  |  	if (authorized) { | ||||||
|  | +		static const char * const auth_algs[] = { | ||||||
|  | +			[WLAN_AUTH_OPEN] = "open", | ||||||
|  | +			[WLAN_AUTH_SHARED_KEY] = "shared", | ||||||
|  | +			[WLAN_AUTH_FT] = "ft", | ||||||
|  | +			[WLAN_AUTH_SAE] = "sae", | ||||||
|  | +			[WLAN_AUTH_FILS_SK] = "fils-sk", | ||||||
|  | +			[WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", | ||||||
|  | +			[WLAN_AUTH_FILS_PK] = "fils-pk", | ||||||
|  | +			[WLAN_AUTH_PASN] = "pasn", | ||||||
|  | +		}; | ||||||
|  | +		const char *auth_alg = NULL; | ||||||
|  |  		const char *keyid; | ||||||
|  |  		char keyid_buf[100]; | ||||||
|  |  		char ip_addr[100]; | ||||||
|  | +		char alg_buf[100]; | ||||||
|  |   | ||||||
|  |  		keyid_buf[0] = '\0'; | ||||||
|  |  		ip_addr[0] = '\0'; | ||||||
|  | +		alg_buf[0] = '\0'; | ||||||
|  |  #ifdef CONFIG_P2P | ||||||
|  |  		if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { | ||||||
|  |  			os_snprintf(ip_addr, sizeof(ip_addr), | ||||||
|  | @@ -1313,22 +1328,31 @@ void ap_sta_set_authorized(struct hostap | ||||||
|  |  		} | ||||||
|  |  #endif /* CONFIG_P2P */ | ||||||
|  |   | ||||||
|  | +		if (sta->auth_alg < ARRAY_SIZE(auth_algs)) | ||||||
|  | +			auth_alg = auth_algs[sta->auth_alg]; | ||||||
|  | + | ||||||
|  | +		if (auth_alg) | ||||||
|  | +			os_snprintf(alg_buf, sizeof(alg_buf), | ||||||
|  | +				" auth_alg=%s", auth_alg); | ||||||
|  | + | ||||||
|  |  		keyid = ap_sta_wpa_get_keyid(hapd, sta); | ||||||
|  |  		if (keyid) { | ||||||
|  |  			os_snprintf(keyid_buf, sizeof(keyid_buf), | ||||||
|  				    " keyid=%s", keyid); |  				    " keyid=%s", keyid); | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
|  | -		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", | ||||||
|  | -			buf, ip_addr, keyid_buf); | ||||||
| +		hostapd_ubus_notify_authorized(hapd, sta); | +		hostapd_ubus_notify_authorized(hapd, sta); | ||||||
|  		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", | +		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", | ||||||
|  			buf, ip_addr, keyid_buf); | +			buf, ip_addr, keyid_buf, alg_buf); | ||||||
|   |   | ||||||
| @@ -1329,6 +1332,7 @@ void ap_sta_set_authorized(struct hostap |  		if (hapd->msg_ctx_parent && | ||||||
|  					  buf, ip_addr, keyid_buf); |  		    hapd->msg_ctx_parent != hapd->msg_ctx) | ||||||
|  |  			wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, | ||||||
|  | -					  AP_STA_CONNECTED "%s%s%s", | ||||||
|  | -					  buf, ip_addr, keyid_buf); | ||||||
|  | +					  AP_STA_CONNECTED "%s%s%s%s", | ||||||
|  | +					  buf, ip_addr, keyid_buf, alg_buf); | ||||||
|  	} else { |  	} else { | ||||||
|  		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); |  		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); | ||||||
| +		hostapd_ubus_notify(hapd, "disassoc", sta->addr); | +		hostapd_ubus_notify(hapd, "disassoc", sta->addr); | ||||||
|   |   | ||||||
|  		if (hapd->msg_ctx_parent && |  		if (hapd->msg_ctx_parent && | ||||||
|  		    hapd->msg_ctx_parent != hapd->msg_ctx) |  		    hapd->msg_ctx_parent != hapd->msg_ctx) | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c | --- a/src/ap/wpa_auth_glue.c | ||||||
| =================================================================== | +++ b/src/ap/wpa_auth_glue.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_glue.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c |  | ||||||
| @@ -265,6 +265,7 @@ static void hostapd_wpa_auth_psk_failure | @@ -265,6 +265,7 @@ static void hostapd_wpa_auth_psk_failure | ||||||
|  	struct hostapd_data *hapd = ctx; |  	struct hostapd_data *hapd = ctx; | ||||||
|  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, |  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, | ||||||
| @@ -292,24 +314,23 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile | --- a/wpa_supplicant/Makefile | ||||||
| =================================================================== | +++ b/wpa_supplicant/Makefile | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile | @@ -169,6 +169,13 @@ ifdef CONFIG_EAPOL_TEST | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile |  | ||||||
| @@ -171,6 +171,12 @@ ifdef CONFIG_EAPOL_TEST |  | ||||||
|  CFLAGS += -Werror -DEAPOL_TEST |  CFLAGS += -Werror -DEAPOL_TEST | ||||||
|  endif |  endif | ||||||
|   |   | ||||||
| +ifdef CONFIG_UBUS | +ifdef CONFIG_UBUS | ||||||
| +CFLAGS += -DUBUS_SUPPORT | +CFLAGS += -DUBUS_SUPPORT | ||||||
| +OBJS += ubus.o | +OBJS += ubus.o | ||||||
|  | +OBJS += ../src/utils/uloop.o | ||||||
| +LIBS += -lubox -lubus | +LIBS += -lubox -lubus | ||||||
| +endif | +endif | ||||||
| + | + | ||||||
|  ifdef CONFIG_CODE_COVERAGE |  ifdef CONFIG_CODE_COVERAGE | ||||||
|  CFLAGS += -O0 -fprofile-arcs -ftest-coverage |  CFLAGS += -O0 -fprofile-arcs -ftest-coverage | ||||||
|  LIBS += -lgcov |  LIBS += -lgcov | ||||||
| @@ -948,6 +954,9 @@ ifdef CONFIG_CTRL_IFACE_MIB | @@ -946,6 +953,9 @@ ifdef CONFIG_CTRL_IFACE_MIB | ||||||
|  CFLAGS += -DCONFIG_CTRL_IFACE_MIB |  CFLAGS += -DCONFIG_CTRL_IFACE_MIB | ||||||
|  endif |  endif | ||||||
|  OBJS += ../src/ap/ctrl_iface_ap.o |  OBJS += ../src/ap/ctrl_iface_ap.o | ||||||
| @@ -319,11 +340,9 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile | |||||||
|  endif |  endif | ||||||
|   |   | ||||||
|  CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY |  CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
| =================================================================== | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c | @@ -6943,6 +6943,8 @@ struct wpa_supplicant * wpa_supplicant_a | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c |  | ||||||
| @@ -7012,6 +7012,8 @@ struct wpa_supplicant * wpa_supplicant_a |  | ||||||
|  	} |  	} | ||||||
|  #endif /* CONFIG_P2P */ |  #endif /* CONFIG_P2P */ | ||||||
|   |   | ||||||
| @@ -332,7 +351,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c | |||||||
|  	return wpa_s; |  	return wpa_s; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -7038,6 +7040,8 @@ int wpa_supplicant_remove_iface(struct w | @@ -6969,6 +6971,8 @@ int wpa_supplicant_remove_iface(struct w | ||||||
|  	struct wpa_supplicant *parent = wpa_s->parent; |  	struct wpa_supplicant *parent = wpa_s->parent; | ||||||
|  #endif /* CONFIG_MESH */ |  #endif /* CONFIG_MESH */ | ||||||
|   |   | ||||||
| @@ -341,7 +360,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c | |||||||
|  	/* Remove interface from the global list of interfaces */ |  	/* Remove interface from the global list of interfaces */ | ||||||
|  	prev = global->ifaces; |  	prev = global->ifaces; | ||||||
|  	if (prev == wpa_s) { |  	if (prev == wpa_s) { | ||||||
| @@ -7341,8 +7345,12 @@ int wpa_supplicant_run(struct wpa_global | @@ -7272,8 +7276,12 @@ int wpa_supplicant_run(struct wpa_global | ||||||
|  	eloop_register_signal_terminate(wpa_supplicant_terminate, global); |  	eloop_register_signal_terminate(wpa_supplicant_terminate, global); | ||||||
|  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); |  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); | ||||||
|   |   | ||||||
| @@ -354,10 +373,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c | |||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h | --- a/wpa_supplicant/wpa_supplicant_i.h | ||||||
| =================================================================== | +++ b/wpa_supplicant/wpa_supplicant_i.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h |  | ||||||
| @@ -19,6 +19,7 @@ | @@ -19,6 +19,7 @@ | ||||||
|  #include "wps/wps_defs.h" |  #include "wps/wps_defs.h" | ||||||
|  #include "config_ssid.h" |  #include "config_ssid.h" | ||||||
| @@ -366,7 +383,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h | |||||||
|   |   | ||||||
|  extern const char *const wpa_supplicant_version; |  extern const char *const wpa_supplicant_version; | ||||||
|  extern const char *const wpa_supplicant_license; |  extern const char *const wpa_supplicant_license; | ||||||
| @@ -321,6 +322,8 @@ struct wpa_global { | @@ -316,6 +317,8 @@ struct wpa_global { | ||||||
|  #endif /* CONFIG_WIFI_DISPLAY */ |  #endif /* CONFIG_WIFI_DISPLAY */ | ||||||
|   |   | ||||||
|  	struct psk_list_entry *add_psk; /* From group formation */ |  	struct psk_list_entry *add_psk; /* From group formation */ | ||||||
| @@ -375,7 +392,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h | |||||||
|  }; |  }; | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -601,6 +604,7 @@ struct wpa_supplicant { | @@ -596,6 +599,7 @@ struct wpa_supplicant { | ||||||
|  	unsigned char own_addr[ETH_ALEN]; |  	unsigned char own_addr[ETH_ALEN]; | ||||||
|  	unsigned char perm_addr[ETH_ALEN]; |  	unsigned char perm_addr[ETH_ALEN]; | ||||||
|  	char ifname[100]; |  	char ifname[100]; | ||||||
| @@ -383,10 +400,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h | |||||||
|  #ifdef CONFIG_MATCH_IFACE |  #ifdef CONFIG_MATCH_IFACE | ||||||
|  	int matched; |  	int matched; | ||||||
|  #endif /* CONFIG_MATCH_IFACE */ |  #endif /* CONFIG_MATCH_IFACE */ | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c | --- a/wpa_supplicant/wps_supplicant.c | ||||||
| =================================================================== | +++ b/wpa_supplicant/wps_supplicant.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wps_supplicant.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c |  | ||||||
| @@ -33,6 +33,7 @@ | @@ -33,6 +33,7 @@ | ||||||
|  #include "p2p/p2p.h" |  #include "p2p/p2p.h" | ||||||
|  #include "p2p_supplicant.h" |  #include "p2p_supplicant.h" | ||||||
| @@ -404,40 +419,18 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c | |||||||
|  	if (wpa_s->conf->wps_cred_processing == 1) |  	if (wpa_s->conf->wps_cred_processing == 1) | ||||||
|  		return 0; |  		return 0; | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/hostapd/main.c | --- a/wpa_supplicant/main.c | ||||||
| =================================================================== | +++ b/wpa_supplicant/main.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/main.c | @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/main.c |  | ||||||
| @@ -895,6 +895,7 @@ int main(int argc, char *argv[]) |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	hostapd_global_ctrl_iface_init(&interfaces); |  | ||||||
| +	hostapd_ubus_add(&interfaces); |  | ||||||
|   |  | ||||||
|  	if (hostapd_global_run(&interfaces, daemonize, pid_file)) { |  | ||||||
|  		wpa_printf(MSG_ERROR, "Failed to start eloop"); |  | ||||||
| @@ -904,6 +905,7 @@ int main(int argc, char *argv[]) |  | ||||||
|  	ret = 0; |  | ||||||
|   |  | ||||||
|   out: |  | ||||||
| +	hostapd_ubus_free(&interfaces); |  | ||||||
|  	hostapd_global_ctrl_iface_deinit(&interfaces); |  | ||||||
|  	/* Deinitialize all interfaces */ |  | ||||||
|  	for (i = 0; i < interfaces.count; i++) { |  | ||||||
| Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c |  | ||||||
| @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) |  | ||||||
|   |   | ||||||
|  	for (;;) { |  	for (;;) { | ||||||
|  		c = getopt(argc, argv, |  		c = getopt(argc, argv, | ||||||
| -			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); | -			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); | ||||||
| +			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W"); | +			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); | ||||||
|  		if (c < 0) |  		if (c < 0) | ||||||
|  			break; |  			break; | ||||||
|  		switch (c) { |  		switch (c) { | ||||||
| @@ -271,6 +271,9 @@ int main(int argc, char *argv[]) | @@ -267,6 +267,9 @@ int main(int argc, char *argv[]) | ||||||
|  			params.conf_p2p_dev = optarg; |  			params.conf_p2p_dev = optarg; | ||||||
|  			break; |  			break; | ||||||
|  #endif /* CONFIG_P2P */ |  #endif /* CONFIG_P2P */ | ||||||
| @@ -447,10 +440,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c | |||||||
|  		case 'o': |  		case 'o': | ||||||
|  			params.override_driver = optarg; |  			params.override_driver = optarg; | ||||||
|  			break; |  			break; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c | --- a/src/ap/rrm.c | ||||||
| =================================================================== | +++ b/src/ap/rrm.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/rrm.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/rrm.c |  | ||||||
| @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report | @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report | ||||||
|  		return; |  		return; | ||||||
|  	wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", |  	wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", | ||||||
| @@ -461,10 +452,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | --- a/src/ap/vlan_init.c | ||||||
| =================================================================== | +++ b/src/ap/vlan_init.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c |  | ||||||
| @@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||||||
|  static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |  static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, | ||||||
|  		       int existsok) |  		       int existsok) | ||||||
| @@ -501,11 +490,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c | |||||||
|  	return hostapd_vlan_if_remove(hapd, vlan->ifname); |  	return hostapd_vlan_if_remove(hapd, vlan->ifname); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c | --- a/src/ap/dfs.c | ||||||
| =================================================================== | +++ b/src/ap/dfs.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c | @@ -1226,6 +1226,8 @@ int hostapd_dfs_nop_finished(struct host | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c |  | ||||||
| @@ -1193,6 +1193,8 @@ int hostapd_dfs_radar_detected(struct ho |  | ||||||
|  		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", |  		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", | ||||||
|  		freq, ht_enabled, chan_offset, chan_width, cf1, cf2); |  		freq, ht_enabled, chan_offset, chan_width, cf1, cf2); | ||||||
|   |   | ||||||
| @@ -514,10 +501,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c | |||||||
|  	/* Proceed only if DFS is not offloaded to the driver */ |  	/* Proceed only if DFS is not offloaded to the driver */ | ||||||
|  	if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) |  	if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) | ||||||
|  		return 0; |  		return 0; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c | --- a/src/ap/airtime_policy.c | ||||||
| =================================================================== | +++ b/src/ap/airtime_policy.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/airtime_policy.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c |  | ||||||
| @@ -108,8 +108,14 @@ static void set_sta_weights(struct hosta | @@ -108,8 +108,14 @@ static void set_sta_weights(struct hosta | ||||||
|  { |  { | ||||||
|  	struct sta_info *sta; |  	struct sta_info *sta; | ||||||
| @@ -547,10 +532,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c | |||||||
|  		if (weight) |  		if (weight) | ||||||
|  			return sta_set_airtime_weight(hapd, sta, weight); |  			return sta_set_airtime_weight(hapd, sta, weight); | ||||||
|  	} |  	} | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h | --- a/src/ap/sta_info.h | ||||||
| =================================================================== | +++ b/src/ap/sta_info.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h |  | ||||||
| @@ -323,6 +323,7 @@ struct sta_info { | @@ -323,6 +323,7 @@ struct sta_info { | ||||||
|  #endif /* CONFIG_TESTING_OPTIONS */ |  #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
|  #ifdef CONFIG_AIRTIME_POLICY |  #ifdef CONFIG_AIRTIME_POLICY | ||||||
| @@ -559,10 +542,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h | |||||||
|  	struct os_reltime backlogged_until; |  	struct os_reltime backlogged_until; | ||||||
|  #endif /* CONFIG_AIRTIME_POLICY */ |  #endif /* CONFIG_AIRTIME_POLICY */ | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c | --- a/src/ap/wnm_ap.c | ||||||
| =================================================================== | +++ b/src/ap/wnm_ap.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/wnm_ap.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c |  | ||||||
| @@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt | @@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt | ||||||
|  	wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", |  	wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", | ||||||
|  		    pos, end - pos); |  		    pos, end - pos); | ||||||
| @@ -601,3 +582,151 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c | |||||||
|  	wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", |  	wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", | ||||||
|  		    pos, end - pos); |  		    pos, end - pos); | ||||||
|  } |  } | ||||||
|  | --- a/src/utils/eloop.c | ||||||
|  | +++ b/src/utils/eloop.c | ||||||
|  | @@ -77,6 +77,9 @@ struct eloop_sock_table { | ||||||
|  |  struct eloop_data { | ||||||
|  |  	int max_sock; | ||||||
|  |   | ||||||
|  | +	eloop_timeout_poll_handler timeout_poll_cb; | ||||||
|  | +	eloop_poll_handler poll_cb; | ||||||
|  | + | ||||||
|  |  	size_t count; /* sum of all table counts */ | ||||||
|  |  #ifdef CONFIG_ELOOP_POLL | ||||||
|  |  	size_t max_pollfd_map; /* number of pollfds_map currently allocated */ | ||||||
|  | @@ -1116,6 +1119,12 @@ void eloop_run(void) | ||||||
|  |  				os_reltime_sub(&timeout->time, &now, &tv); | ||||||
|  |  			else | ||||||
|  |  				tv.sec = tv.usec = 0; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) | ||||||
|  | +			timeout = (void *)1; | ||||||
|  | + | ||||||
|  | +		if (timeout) { | ||||||
|  |  #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) | ||||||
|  |  			timeout_ms = tv.sec * 1000 + tv.usec / 1000; | ||||||
|  |  #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ | ||||||
|  | @@ -1185,7 +1194,8 @@ void eloop_run(void) | ||||||
|  |  		eloop.exceptions.changed = 0; | ||||||
|  |   | ||||||
|  |  		eloop_process_pending_signals(); | ||||||
|  | - | ||||||
|  | +		if (eloop.poll_cb) | ||||||
|  | +			eloop.poll_cb(); | ||||||
|  |   | ||||||
|  |  		/* check if some registered timeouts have occurred */ | ||||||
|  |  		timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, | ||||||
|  | @@ -1247,6 +1257,14 @@ out: | ||||||
|  |  	return; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int eloop_register_cb(eloop_poll_handler poll_cb, | ||||||
|  | +		      eloop_timeout_poll_handler timeout_cb) | ||||||
|  | +{ | ||||||
|  | +	eloop.poll_cb = poll_cb; | ||||||
|  | +	eloop.timeout_poll_cb = timeout_cb; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  |  void eloop_terminate(void) | ||||||
|  |  { | ||||||
|  | --- a/src/utils/eloop.h | ||||||
|  | +++ b/src/utils/eloop.h | ||||||
|  | @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo | ||||||
|  |   */ | ||||||
|  |  typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); | ||||||
|  |   | ||||||
|  | +typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); | ||||||
|  | +typedef void (*eloop_poll_handler)(void); | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   * eloop_init() - Initialize global event loop data | ||||||
|  |   * Returns: 0 on success, -1 on failure | ||||||
|  | @@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int | ||||||
|  |   */ | ||||||
|  |  int eloop_init(void); | ||||||
|  |   | ||||||
|  | +int eloop_register_cb(eloop_poll_handler poll_cb, | ||||||
|  | +		      eloop_timeout_poll_handler timeout_cb); | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   * eloop_register_read_sock - Register handler for read events | ||||||
|  |   * @sock: File descriptor number for the socket | ||||||
|  | @@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop | ||||||
|  |   */ | ||||||
|  |  int eloop_sock_requeue(void); | ||||||
|  |   | ||||||
|  | +void eloop_add_uloop(void); | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   * eloop_run - Start the event loop | ||||||
|  |   * | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/src/utils/uloop.c | ||||||
|  | @@ -0,0 +1,64 @@ | ||||||
|  | +#include <libubox/uloop.h> | ||||||
|  | +#include "includes.h" | ||||||
|  | +#include "common.h" | ||||||
|  | +#include "eloop.h" | ||||||
|  | + | ||||||
|  | +static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) | ||||||
|  | +{ | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) | ||||||
|  | +{ | ||||||
|  | +	unsigned int changed = events ^ fd->flags; | ||||||
|  | + | ||||||
|  | +	if (changed & ULOOP_READ) { | ||||||
|  | +		if (events & ULOOP_READ) | ||||||
|  | +			eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); | ||||||
|  | +		else | ||||||
|  | +			eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (changed & ULOOP_WRITE) { | ||||||
|  | +		if (events & ULOOP_WRITE) | ||||||
|  | +			eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); | ||||||
|  | +		else | ||||||
|  | +			eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) | ||||||
|  | +{ | ||||||
|  | +	struct os_reltime tv_uloop; | ||||||
|  | +	int timeout_ms = uloop_get_next_timeout(); | ||||||
|  | + | ||||||
|  | +	if (timeout_ms < 0) | ||||||
|  | +		return false; | ||||||
|  | + | ||||||
|  | +	tv_uloop.sec = timeout_ms / 1000; | ||||||
|  | +	tv_uloop.usec = (timeout_ms % 1000) * 1000; | ||||||
|  | + | ||||||
|  | +	if (!tv_set || os_reltime_before(&tv_uloop, tv)) { | ||||||
|  | +		*tv = tv_uloop; | ||||||
|  | +		return true; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return false; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void uloop_poll_handler(void) | ||||||
|  | +{ | ||||||
|  | +	uloop_run_timeout(0); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void eloop_add_uloop(void) | ||||||
|  | +{ | ||||||
|  | +	static bool init_done = false; | ||||||
|  | + | ||||||
|  | +	if (!init_done) { | ||||||
|  | +		uloop_init(); | ||||||
|  | +		uloop_fd_set_cb = eloop_uloop_fd_cb; | ||||||
|  | +		init_done = true; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); | ||||||
|  | +} | ||||||
|   | |||||||
							
								
								
									
										350
									
								
								feeds/ipq807x_v5.4/hostapd/patches/601-ucode_support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								feeds/ipq807x_v5.4/hostapd/patches/601-ucode_support.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,350 @@ | |||||||
|  | --- a/hostapd/Makefile | ||||||
|  | +++ b/hostapd/Makefile | ||||||
|  | @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. | ||||||
|  |   | ||||||
|  |  ifdef CONFIG_UBUS | ||||||
|  |  CFLAGS += -DUBUS_SUPPORT | ||||||
|  | -OBJS += ../src/utils/uloop.o | ||||||
|  |  OBJS += ../src/ap/ubus.o | ||||||
|  | -LIBS += -lubox -lubus | ||||||
|  | +LIBS += -lubus | ||||||
|  | +NEED_ULOOP:=y | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  | +ifdef CONFIG_UCODE | ||||||
|  | +CFLAGS += -DUCODE_SUPPORT | ||||||
|  | +OBJS += ../src/utils/ucode.o | ||||||
|  | +OBJS += ../src/ap/ucode.o | ||||||
|  | +NEED_ULOOP:=y | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  | +ifdef NEED_ULOOP | ||||||
|  | +OBJS += ../src/utils/uloop.o | ||||||
|  | +LIBS += -lubox | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  |  ifdef CONFIG_CODE_COVERAGE | ||||||
|  | --- a/hostapd/main.c | ||||||
|  | +++ b/hostapd/main.c | ||||||
|  | @@ -898,6 +898,7 @@ int main(int argc, char *argv[]) | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	hostapd_global_ctrl_iface_init(&interfaces); | ||||||
|  | +	hostapd_ucode_init(&interfaces); | ||||||
|  |   | ||||||
|  |  	if (hostapd_global_run(&interfaces, daemonize, pid_file)) { | ||||||
|  |  		wpa_printf(MSG_ERROR, "Failed to start eloop"); | ||||||
|  | @@ -907,6 +908,7 @@ int main(int argc, char *argv[]) | ||||||
|  |  	ret = 0; | ||||||
|  |   | ||||||
|  |   out: | ||||||
|  | +	hostapd_ucode_free(); | ||||||
|  |  	hostapd_global_ctrl_iface_deinit(&interfaces); | ||||||
|  |  	/* Deinitialize all interfaces */ | ||||||
|  |  	for (i = 0; i < interfaces.count; i++) { | ||||||
|  | --- a/src/ap/hostapd.h | ||||||
|  | +++ b/src/ap/hostapd.h | ||||||
|  | @@ -18,6 +18,7 @@ | ||||||
|  |  #include "ap_config.h" | ||||||
|  |  #include "drivers/driver.h" | ||||||
|  |  #include "ubus.h" | ||||||
|  | +#include "ucode.h" | ||||||
|  |   | ||||||
|  |  #define OCE_STA_CFON_ENABLED(hapd) \ | ||||||
|  |  	((hapd->conf->oce & OCE_STA_CFON) && \ | ||||||
|  | @@ -50,6 +51,10 @@ struct hapd_interfaces { | ||||||
|  |  	struct hostapd_config * (*config_read_cb)(const char *config_fname); | ||||||
|  |  	int (*ctrl_iface_init)(struct hostapd_data *hapd); | ||||||
|  |  	void (*ctrl_iface_deinit)(struct hostapd_data *hapd); | ||||||
|  | +	int (*ctrl_iface_recv)(struct hostapd_data *hapd, | ||||||
|  | +			       char *buf, char *reply, int reply_size, | ||||||
|  | +			       struct sockaddr_storage *from, | ||||||
|  | +			       socklen_t fromlen); | ||||||
|  |  	int (*for_each_interface)(struct hapd_interfaces *interfaces, | ||||||
|  |  				  int (*cb)(struct hostapd_iface *iface, | ||||||
|  |  					    void *ctx), void *ctx); | ||||||
|  | @@ -171,6 +176,7 @@ struct hostapd_data { | ||||||
|  |  	struct hostapd_config *iconf; | ||||||
|  |  	struct hostapd_bss_config *conf; | ||||||
|  |  	struct hostapd_ubus_bss ubus; | ||||||
|  | +	struct hostapd_ucode_bss ucode; | ||||||
|  |  	int interface_added; /* virtual interface added for this BSS */ | ||||||
|  |  	unsigned int started:1; | ||||||
|  |  	unsigned int disabled:1; | ||||||
|  | @@ -463,6 +469,7 @@ struct hostapd_sta_info { | ||||||
|  |   */ | ||||||
|  |  struct hostapd_iface { | ||||||
|  |  	struct hapd_interfaces *interfaces; | ||||||
|  | +	struct hostapd_ucode_iface ucode; | ||||||
|  |  	void *owner; | ||||||
|  |  	char *config_fname; | ||||||
|  |  	struct hostapd_config *conf; | ||||||
|  | @@ -637,6 +644,8 @@ struct hostapd_iface * hostapd_init(stru | ||||||
|  |  struct hostapd_iface * | ||||||
|  |  hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, | ||||||
|  |  			   const char *config_fname, int debug); | ||||||
|  | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); | ||||||
|  | +void hostapd_bss_deinit(struct hostapd_data *hapd); | ||||||
|  |  void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, | ||||||
|  |  			   int reassoc); | ||||||
|  |  void hostapd_interface_deinit_free(struct hostapd_iface *iface); | ||||||
|  | --- a/src/ap/hostapd.c | ||||||
|  | +++ b/src/ap/hostapd.c | ||||||
|  | @@ -216,6 +216,8 @@ int hostapd_reload_config(struct hostapd | ||||||
|  |  	struct hostapd_config *newconf, *oldconf; | ||||||
|  |  	size_t j; | ||||||
|  |   | ||||||
|  | +	hostapd_ucode_reload_bss(hapd); | ||||||
|  | + | ||||||
|  |  	if (iface->config_fname == NULL) { | ||||||
|  |  		/* Only in-memory config in use - assume it has been updated */ | ||||||
|  |  		hostapd_clear_old(iface); | ||||||
|  | @@ -376,6 +378,7 @@ void hostapd_free_hapd_data(struct hosta | ||||||
|  |  	hapd->beacon_set_done = 0; | ||||||
|  |   | ||||||
|  |  	wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); | ||||||
|  | +	hostapd_ucode_free_bss(hapd); | ||||||
|  |  	hostapd_ubus_free_bss(hapd); | ||||||
|  |  	accounting_deinit(hapd); | ||||||
|  |  	hostapd_deinit_wpa(hapd); | ||||||
|  | @@ -530,6 +533,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); | ||||||
|  |  	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(). | ||||||
|  |   */ | ||||||
|  | -static int hostapd_setup_bss(struct hostapd_data *hapd, int first) | ||||||
|  | +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool set_beacon) | ||||||
|  |  { | ||||||
|  |  	struct hostapd_bss_config *conf = hapd->conf; | ||||||
|  |  	u8 ssid[SSID_MAX_LEN + 1]; | ||||||
|  | @@ -1400,6 +1404,7 @@ static int hostapd_setup_bss(struct host | ||||||
|  |  		hapd->driver->set_operstate(hapd->drv_priv, 1); | ||||||
|  |   | ||||||
|  |  	hostapd_ubus_add_bss(hapd); | ||||||
|  | +	hostapd_ucode_add_bss(hapd); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | @@ -2090,7 +2095,7 @@ static int hostapd_setup_interface_compl | ||||||
|  |  		hapd = iface->bss[j]; | ||||||
|  |  		if (j) | ||||||
|  |  			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); | ||||||
|  | -		if (hostapd_setup_bss(hapd, j == 0)) { | ||||||
|  | +		if (hostapd_setup_bss(hapd, j == 0, true)) { | ||||||
|  |  			for (;;) { | ||||||
|  |  				hapd = iface->bss[j]; | ||||||
|  |  				hostapd_bss_deinit_no_free(hapd); | ||||||
|  | @@ -2368,7 +2373,7 @@ hostapd_alloc_bss_data(struct hostapd_if | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | -static void hostapd_bss_deinit(struct hostapd_data *hapd) | ||||||
|  | +void hostapd_bss_deinit(struct hostapd_data *hapd) | ||||||
|  |  { | ||||||
|  |  	if (!hapd) | ||||||
|  |  		return; | ||||||
|  | @@ -2985,7 +2990,7 @@ int hostapd_add_iface(struct hapd_interf | ||||||
|  |   | ||||||
|  |  			if (start_ctrl_iface_bss(hapd) < 0 || | ||||||
|  |  			    (hapd_iface->state == HAPD_IFACE_ENABLED && | ||||||
|  | -			     hostapd_setup_bss(hapd, -1))) { | ||||||
|  | +			     hostapd_setup_bss(hapd, -1, true))) { | ||||||
|  |  				hostapd_cleanup(hapd); | ||||||
|  |  				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; | ||||||
|  |  				hapd_iface->conf->num_bss--; | ||||||
|  | --- a/wpa_supplicant/Makefile | ||||||
|  | +++ b/wpa_supplicant/Makefile | ||||||
|  | @@ -172,8 +172,20 @@ endif | ||||||
|  |  ifdef CONFIG_UBUS | ||||||
|  |  CFLAGS += -DUBUS_SUPPORT | ||||||
|  |  OBJS += ubus.o | ||||||
|  | +LIBS += -lubus | ||||||
|  | +NEED_ULOOP:=y | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  | +ifdef CONFIG_UCODE | ||||||
|  | +CFLAGS += -DUCODE_SUPPORT | ||||||
|  | +OBJS += ../src/utils/ucode.o | ||||||
|  | +OBJS += ucode.o | ||||||
|  | +NEED_ULOOP:=y | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  | +ifdef NEED_ULOOP | ||||||
|  |  OBJS += ../src/utils/uloop.o | ||||||
|  | -LIBS += -lubox -lubus | ||||||
|  | +LIBS += -lubox | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  |  ifdef CONFIG_CODE_COVERAGE | ||||||
|  | @@ -956,6 +968,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o | ||||||
|  |  ifdef CONFIG_UBUS | ||||||
|  |  OBJS += ../src/ap/ubus.o | ||||||
|  |  endif | ||||||
|  | +ifdef CONFIG_UCODE | ||||||
|  | +OBJS += ../src/ap/ucode.o | ||||||
|  | +endif | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  |  CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY | ||||||
|  | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
|  | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
|  | @@ -1025,6 +1025,7 @@ void wpa_supplicant_set_state(struct wpa | ||||||
|  |  		sme_sched_obss_scan(wpa_s, 0); | ||||||
|  |  	} | ||||||
|  |  	wpa_s->wpa_state = state; | ||||||
|  | +	wpas_ucode_update_state(wpa_s); | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_BGSCAN | ||||||
|  |  	if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) | ||||||
|  | @@ -6944,6 +6945,7 @@ struct wpa_supplicant * wpa_supplicant_a | ||||||
|  |  #endif /* CONFIG_P2P */ | ||||||
|  |   | ||||||
|  |  	wpas_ubus_add_bss(wpa_s); | ||||||
|  | +	wpas_ucode_add_bss(wpa_s); | ||||||
|  |   | ||||||
|  |  	return wpa_s; | ||||||
|  |  } | ||||||
|  | @@ -6971,6 +6973,7 @@ int wpa_supplicant_remove_iface(struct w | ||||||
|  |  	struct wpa_supplicant *parent = wpa_s->parent; | ||||||
|  |  #endif /* CONFIG_MESH */ | ||||||
|  |   | ||||||
|  | +	wpas_ucode_free_bss(wpa_s); | ||||||
|  |  	wpas_ubus_free_bss(wpa_s); | ||||||
|  |   | ||||||
|  |  	/* Remove interface from the global list of interfaces */ | ||||||
|  | @@ -7238,6 +7241,7 @@ struct wpa_global * wpa_supplicant_init( | ||||||
|  |   | ||||||
|  |  	eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, | ||||||
|  |  			       wpas_periodic, global, NULL); | ||||||
|  | +	wpas_ucode_init(global); | ||||||
|  |   | ||||||
|  |  	return global; | ||||||
|  |  } | ||||||
|  | @@ -7276,12 +7280,8 @@ int wpa_supplicant_run(struct wpa_global | ||||||
|  |  	eloop_register_signal_terminate(wpa_supplicant_terminate, global); | ||||||
|  |  	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); | ||||||
|  |   | ||||||
|  | -	wpas_ubus_add(global); | ||||||
|  | - | ||||||
|  |  	eloop_run(); | ||||||
|  |   | ||||||
|  | -	wpas_ubus_free(global); | ||||||
|  | - | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -7314,6 +7314,8 @@ void wpa_supplicant_deinit(struct wpa_gl | ||||||
|  |   | ||||||
|  |  	wpas_notify_supplicant_deinitialized(global); | ||||||
|  |   | ||||||
|  | +	wpas_ucode_free(); | ||||||
|  | + | ||||||
|  |  	eap_peer_unregister_methods(); | ||||||
|  |  #ifdef CONFIG_AP | ||||||
|  |  	eap_server_unregister_methods(); | ||||||
|  | --- a/wpa_supplicant/wpa_supplicant_i.h | ||||||
|  | +++ b/wpa_supplicant/wpa_supplicant_i.h | ||||||
|  | @@ -20,6 +20,7 @@ | ||||||
|  |  #include "config_ssid.h" | ||||||
|  |  #include "wmm_ac.h" | ||||||
|  |  #include "ubus.h" | ||||||
|  | +#include "ucode.h" | ||||||
|  |   | ||||||
|  |  extern const char *const wpa_supplicant_version; | ||||||
|  |  extern const char *const wpa_supplicant_license; | ||||||
|  | @@ -600,6 +601,7 @@ struct wpa_supplicant { | ||||||
|  |  	unsigned char perm_addr[ETH_ALEN]; | ||||||
|  |  	char ifname[100]; | ||||||
|  |  	struct wpas_ubus_bss ubus; | ||||||
|  | +	struct wpas_ucode_bss ucode; | ||||||
|  |  #ifdef CONFIG_MATCH_IFACE | ||||||
|  |  	int matched; | ||||||
|  |  #endif /* CONFIG_MATCH_IFACE */ | ||||||
|  | --- a/hostapd/ctrl_iface.c | ||||||
|  | +++ b/hostapd/ctrl_iface.c | ||||||
|  | @@ -4877,6 +4877,7 @@ try_again: | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; | ||||||
|  |  	wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | @@ -4978,6 +4979,7 @@ fail: | ||||||
|  |  	os_free(fname); | ||||||
|  |   | ||||||
|  |  	interface->global_ctrl_sock = s; | ||||||
|  | +	interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; | ||||||
|  |  	eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, | ||||||
|  |  				 interface, NULL); | ||||||
|  |   | ||||||
|  | --- a/src/drivers/driver.h | ||||||
|  | +++ b/src/drivers/driver.h | ||||||
|  | @@ -5827,6 +5827,7 @@ union wpa_event_data { | ||||||
|  |   | ||||||
|  |  	/** | ||||||
|  |  	 * struct ch_switch | ||||||
|  | +	 * @count: Count until channel switch activates | ||||||
|  |  	 * @freq: Frequency of new channel in MHz | ||||||
|  |  	 * @ht_enabled: Whether this is an HT channel | ||||||
|  |  	 * @ch_offset: Secondary channel offset | ||||||
|  | @@ -5835,6 +5836,7 @@ union wpa_event_data { | ||||||
|  |  	 * @cf2: Center frequency 2 | ||||||
|  |  	 */ | ||||||
|  |  	struct ch_switch { | ||||||
|  | +		int count; | ||||||
|  |  		int freq; | ||||||
|  |  		int ht_enabled; | ||||||
|  |  		int ch_offset; | ||||||
|  | --- a/src/drivers/driver_nl80211_event.c | ||||||
|  | +++ b/src/drivers/driver_nl80211_event.c | ||||||
|  | @@ -655,6 +655,7 @@ static void mlme_event_ch_switch(struct | ||||||
|  |  				 struct nlattr *ifindex, struct nlattr *freq, | ||||||
|  |  				 struct nlattr *type, struct nlattr *bw, | ||||||
|  |  				 struct nlattr *cf1, struct nlattr *cf2, | ||||||
|  | +				 struct nlattr *count, | ||||||
|  |  				 int finished) | ||||||
|  |  { | ||||||
|  |  	struct i802_bss *bss; | ||||||
|  | @@ -714,6 +715,8 @@ static void mlme_event_ch_switch(struct | ||||||
|  |  		data.ch_switch.cf1 = nla_get_u32(cf1); | ||||||
|  |  	if (cf2) | ||||||
|  |  		data.ch_switch.cf2 = nla_get_u32(cf2); | ||||||
|  | +	if (count) | ||||||
|  | +		data.ch_switch.count = nla_get_u32(count); | ||||||
|  |   | ||||||
|  |  	if (finished) | ||||||
|  |  		bss->freq = data.ch_switch.freq; | ||||||
|  | @@ -2886,6 +2889,7 @@ static void do_process_drv_event(struct | ||||||
|  |  				     tb[NL80211_ATTR_CHANNEL_WIDTH], | ||||||
|  |  				     tb[NL80211_ATTR_CENTER_FREQ1], | ||||||
|  |  				     tb[NL80211_ATTR_CENTER_FREQ2], | ||||||
|  | +				     tb[NL80211_ATTR_CH_SWITCH_COUNT], | ||||||
|  |  				     0); | ||||||
|  |  		break; | ||||||
|  |  	case NL80211_CMD_CH_SWITCH_NOTIFY: | ||||||
|  | @@ -2896,6 +2900,7 @@ static void do_process_drv_event(struct | ||||||
|  |  				     tb[NL80211_ATTR_CHANNEL_WIDTH], | ||||||
|  |  				     tb[NL80211_ATTR_CENTER_FREQ1], | ||||||
|  |  				     tb[NL80211_ATTR_CENTER_FREQ2], | ||||||
|  | +					 NULL, | ||||||
|  |  				     1); | ||||||
|  |  		break; | ||||||
|  |  	case NL80211_CMD_DISCONNECT: | ||||||
|  | --- a/wpa_supplicant/events.c | ||||||
|  | +++ b/wpa_supplicant/events.c | ||||||
|  | @@ -4702,6 +4702,7 @@ void supplicant_event(void *ctx, enum wp | ||||||
|  |  		event_to_string(event), event); | ||||||
|  |  #endif /* CONFIG_NO_STDOUT_DEBUG */ | ||||||
|  |   | ||||||
|  | +	wpas_ucode_event(wpa_s, event, data); | ||||||
|  |  	switch (event) { | ||||||
|  |  	case EVENT_AUTH: | ||||||
|  |  #ifdef CONFIG_FST | ||||||
| @@ -1,220 +0,0 @@ | |||||||
| --- a/hostapd/config_file.c |  | ||||||
| +++ b/hostapd/config_file.c |  | ||||||
| @@ -2453,6 +2453,8 @@ static int hostapd_config_fill(struct ho |  | ||||||
|  		bss->isolate = atoi(pos); |  | ||||||
|  	} else if (os_strcmp(buf, "ap_max_inactivity") == 0) { |  | ||||||
|  		bss->ap_max_inactivity = atoi(pos); |  | ||||||
| +	} else if (os_strcmp(buf, "config_id") == 0) { |  | ||||||
| +		bss->config_id = os_strdup(pos); |  | ||||||
|  	} else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { |  | ||||||
|  		bss->skip_inactivity_poll = atoi(pos); |  | ||||||
|  	} else if (os_strcmp(buf, "country_code") == 0) { |  | ||||||
| @@ -3153,6 +3155,8 @@ static int hostapd_config_fill(struct ho |  | ||||||
|  		} |  | ||||||
|  	} else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { |  | ||||||
|  		conf->acs_exclude_dfs = atoi(pos); |  | ||||||
| +	} else if (os_strcmp(buf, "radio_config_id") == 0) { |  | ||||||
| +			conf->config_id = os_strdup(pos); |  | ||||||
|  	} else if (os_strcmp(buf, "op_class") == 0) { |  | ||||||
|  		conf->op_class = atoi(pos); |  | ||||||
|  	} else if (os_strcmp(buf, "channel") == 0) { |  | ||||||
| --- a/src/ap/ap_config.c |  | ||||||
| +++ b/src/ap/ap_config.c |  | ||||||
| @@ -791,6 +791,7 @@ void hostapd_config_free_bss(struct host |  | ||||||
|  	os_free(conf->radius_req_attr_sqlite); |  | ||||||
|  	os_free(conf->rsn_preauth_interfaces); |  | ||||||
|  	os_free(conf->ctrl_interface); |  | ||||||
| +	os_free(conf->config_id); |  | ||||||
|  	os_free(conf->ca_cert); |  | ||||||
|  	os_free(conf->server_cert); |  | ||||||
|  	os_free(conf->server_cert2); |  | ||||||
| @@ -987,6 +988,7 @@ void hostapd_config_free(struct hostapd_ |  | ||||||
|   |  | ||||||
|  	for (i = 0; i < conf->num_bss; i++) |  | ||||||
|  		hostapd_config_free_bss(conf->bss[i]); |  | ||||||
| +	os_free(conf->config_id); |  | ||||||
|  	os_free(conf->bss); |  | ||||||
|  	os_free(conf->supported_rates); |  | ||||||
|  	os_free(conf->basic_rates); |  | ||||||
| --- a/src/ap/ap_config.h |  | ||||||
| +++ b/src/ap/ap_config.h |  | ||||||
| @@ -279,6 +279,8 @@ struct hostapd_bss_config { |  | ||||||
|  	char vlan_bridge[IFNAMSIZ + 1]; |  | ||||||
|  	char wds_bridge[IFNAMSIZ + 1]; |  | ||||||
|   |  | ||||||
| +	char *config_id; |  | ||||||
| + |  | ||||||
|  	enum hostapd_logger_level logger_syslog_level, logger_stdout_level; |  | ||||||
|   |  | ||||||
|  	unsigned int logger_syslog; /* module bitfield */ |  | ||||||
| @@ -938,6 +940,7 @@ struct spatial_reuse { |  | ||||||
|  struct hostapd_config { |  | ||||||
|  	struct hostapd_bss_config **bss, *last_bss; |  | ||||||
|  	size_t num_bss; |  | ||||||
| +	char *config_id; |  | ||||||
|   |  | ||||||
|  	u16 beacon_int; |  | ||||||
|  	int rts_threshold; |  | ||||||
| --- a/src/ap/hostapd.c |  | ||||||
| +++ b/src/ap/hostapd.c |  | ||||||
| @@ -219,6 +219,10 @@ static int hostapd_iface_conf_changed(st |  | ||||||
|  { |  | ||||||
|  	size_t i; |  | ||||||
|   |  | ||||||
| +	if (newconf->config_id != oldconf->config_id) |  | ||||||
| +		if (strcmp(newconf->config_id, oldconf->config_id)) |  | ||||||
| +			return 1; |  | ||||||
| + |  | ||||||
|  	if (newconf->num_bss != oldconf->num_bss) |  | ||||||
|  		return 1; |  | ||||||
|   |  | ||||||
| @@ -232,7 +236,7 @@ static int hostapd_iface_conf_changed(st |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -int hostapd_reload_config(struct hostapd_iface *iface) |  | ||||||
| +int hostapd_reload_config(struct hostapd_iface *iface, int reconf) |  | ||||||
|  { |  | ||||||
|  	struct hapd_interfaces *interfaces = iface->interfaces; |  | ||||||
|  	struct hostapd_data *hapd = iface->bss[0]; |  | ||||||
| @@ -255,13 +259,16 @@ int hostapd_reload_config(struct hostapd |  | ||||||
|  	if (newconf == NULL) |  | ||||||
|  		return -1; |  | ||||||
|   |  | ||||||
| -	hostapd_clear_old(iface); |  | ||||||
| - |  | ||||||
|  	oldconf = hapd->iconf; |  | ||||||
|  	if (hostapd_iface_conf_changed(newconf, oldconf)) { |  | ||||||
|  		char *fname; |  | ||||||
|  		int res; |  | ||||||
|   |  | ||||||
| +		if (reconf) |  | ||||||
| +			return -1; |  | ||||||
| + |  | ||||||
| +		hostapd_clear_old(iface); |  | ||||||
| + |  | ||||||
|  		wpa_printf(MSG_DEBUG, |  | ||||||
|  			   "Configuration changes include interface/BSS modification - force full disable+enable sequence"); |  | ||||||
|  		fname = os_strdup(iface->config_fname); |  | ||||||
| @@ -286,6 +293,24 @@ int hostapd_reload_config(struct hostapd |  | ||||||
|  			wpa_printf(MSG_ERROR, |  | ||||||
|  				   "Failed to enable interface on config reload"); |  | ||||||
|  		return res; |  | ||||||
| +	} else { |  | ||||||
| +		for (j = 0; j < iface->num_bss; j++) { |  | ||||||
| +			hapd = iface->bss[j]; |  | ||||||
| +			if (!hapd->config_id || strcmp(hapd->config_id, newconf->bss[j]->config_id)) { |  | ||||||
| +				hostapd_flush_old_stations(iface->bss[j], |  | ||||||
| +							   WLAN_REASON_PREV_AUTH_NOT_VALID); |  | ||||||
| +#ifdef CONFIG_WEP |  | ||||||
| +				hostapd_broadcast_wep_clear(iface->bss[j]); |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +#ifndef CONFIG_NO_RADIUS |  | ||||||
| +				/* TODO: update dynamic data based on changed configuration |  | ||||||
| +				 * items (e.g., open/close sockets, etc.) */ |  | ||||||
| +				radius_client_flush(iface->bss[j]->radius, 0); |  | ||||||
| +#endif /* CONFIG_NO_RADIUS */ |  | ||||||
| +				wpa_printf(MSG_INFO, "bss %zu changed", j); |  | ||||||
| +			} |  | ||||||
| +		} |  | ||||||
|  	} |  | ||||||
|  	iface->conf = newconf; |  | ||||||
|   |  | ||||||
| @@ -302,6 +327,12 @@ int hostapd_reload_config(struct hostapd |  | ||||||
|   |  | ||||||
|  	for (j = 0; j < iface->num_bss; j++) { |  | ||||||
|  		hapd = iface->bss[j]; |  | ||||||
| +		if (hapd->config_id) { |  | ||||||
| +			os_free(hapd->config_id); |  | ||||||
| +			hapd->config_id = NULL; |  | ||||||
| +		} |  | ||||||
| +		if (newconf->bss[j]->config_id) |  | ||||||
| +			hapd->config_id = strdup(newconf->bss[j]->config_id); |  | ||||||
|  		hapd->iconf = newconf; |  | ||||||
|  		hapd->conf = newconf->bss[j]; |  | ||||||
|  		hostapd_reload_bss(hapd); |  | ||||||
| @@ -2397,6 +2428,10 @@ hostapd_alloc_bss_data(struct hostapd_if |  | ||||||
|  	hapd->iconf = conf; |  | ||||||
|  	hapd->conf = bss; |  | ||||||
|  	hapd->iface = hapd_iface; |  | ||||||
| +	if (bss && bss->config_id) |  | ||||||
| +		hapd->config_id = strdup(bss->config_id); |  | ||||||
| +	else |  | ||||||
| +		hapd->config_id = NULL; |  | ||||||
|  	if (conf) |  | ||||||
|  		hapd->driver = conf->driver; |  | ||||||
|  	hapd->ctrl_sock = -1; |  | ||||||
| --- a/src/ap/hostapd.h |  | ||||||
| +++ b/src/ap/hostapd.h |  | ||||||
| @@ -46,7 +46,7 @@ struct mesh_conf; |  | ||||||
|  struct hostapd_iface; |  | ||||||
|   |  | ||||||
|  struct hapd_interfaces { |  | ||||||
| -	int (*reload_config)(struct hostapd_iface *iface); |  | ||||||
| +	int (*reload_config)(struct hostapd_iface *iface, int reconf); |  | ||||||
|  	struct hostapd_config * (*config_read_cb)(const char *config_fname); |  | ||||||
|  	int (*ctrl_iface_init)(struct hostapd_data *hapd); |  | ||||||
|  	void (*ctrl_iface_deinit)(struct hostapd_data *hapd); |  | ||||||
| @@ -156,6 +156,7 @@ struct hostapd_data { |  | ||||||
|  	struct hostapd_config *iconf; |  | ||||||
|  	struct hostapd_bss_config *conf; |  | ||||||
|  	struct hostapd_ubus_bss ubus; |  | ||||||
| +	char *config_id; |  | ||||||
|  	int interface_added; /* virtual interface added for this BSS */ |  | ||||||
|  	unsigned int started:1; |  | ||||||
|  	unsigned int disabled:1; |  | ||||||
| @@ -604,7 +605,7 @@ struct hostapd_iface { |  | ||||||
|  int hostapd_for_each_interface(struct hapd_interfaces *interfaces, |  | ||||||
|  			       int (*cb)(struct hostapd_iface *iface, |  | ||||||
|  					 void *ctx), void *ctx); |  | ||||||
| -int hostapd_reload_config(struct hostapd_iface *iface); |  | ||||||
| +int hostapd_reload_config(struct hostapd_iface *iface, int reconf); |  | ||||||
|  void hostapd_reconfig_encryption(struct hostapd_data *hapd); |  | ||||||
|  struct hostapd_data * |  | ||||||
|  hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, |  | ||||||
| --- a/src/drivers/driver_nl80211.c |  | ||||||
| +++ b/src/drivers/driver_nl80211.c |  | ||||||
| @@ -4820,6 +4820,9 @@ static int wpa_driver_nl80211_set_ap(voi |  | ||||||
|  	if (ret) { |  | ||||||
|  		wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", |  | ||||||
|  			   ret, strerror(-ret)); |  | ||||||
| +		if (!bss->beacon_set) |  | ||||||
| +			ret = 0; |  | ||||||
| +		bss->beacon_set = 0; |  | ||||||
|  	} else { |  | ||||||
|  		bss->beacon_set = 1; |  | ||||||
|  		nl80211_set_bss(bss, params->cts_protect, params->preamble, |  | ||||||
| --- a/hostapd/ctrl_iface.c |  | ||||||
| +++ b/hostapd/ctrl_iface.c |  | ||||||
| @@ -186,7 +186,7 @@ static int hostapd_ctrl_iface_update(str |  | ||||||
|  	iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; |  | ||||||
|  	reload_opts = txt; |  | ||||||
|   |  | ||||||
| -	hostapd_reload_config(iface); |  | ||||||
| +	hostapd_reload_config(iface, 0); |  | ||||||
|   |  | ||||||
|  	iface->interfaces->config_read_cb = config_read_cb; |  | ||||||
|  } |  | ||||||
| --- a/hostapd/main.c |  | ||||||
| +++ b/hostapd/main.c |  | ||||||
| @@ -317,7 +317,7 @@ static void handle_term(int sig, void *s |  | ||||||
|   |  | ||||||
|  static int handle_reload_iface(struct hostapd_iface *iface, void *ctx) |  | ||||||
|  { |  | ||||||
| -	if (hostapd_reload_config(iface) < 0) { |  | ||||||
| +	if (hostapd_reload_config(iface, 0) < 0) { |  | ||||||
|  		wpa_printf(MSG_WARNING, "Failed to read new configuration " |  | ||||||
|  			   "file - continuing with old."); |  | ||||||
|  	} |  | ||||||
| --- a/src/ap/wps_hostapd.c |  | ||||||
| +++ b/src/ap/wps_hostapd.c |  | ||||||
| @@ -315,7 +315,7 @@ static void wps_reload_config(void *eloo |  | ||||||
|   |  | ||||||
|  	wpa_printf(MSG_DEBUG, "WPS: Reload configuration data"); |  | ||||||
|  	if (iface->interfaces == NULL || |  | ||||||
| -	    iface->interfaces->reload_config(iface) < 0) { |  | ||||||
| +	    iface->interfaces->reload_config(iface, 1) < 0) { |  | ||||||
|  		wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated " |  | ||||||
|  			   "configuration"); |  | ||||||
|  	} |  | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | --- a/hostapd/config_file.c | ||||||
|  | +++ b/hostapd/config_file.c | ||||||
|  | @@ -4699,7 +4699,12 @@ struct hostapd_config * hostapd_config_r | ||||||
|  |  	int errors = 0; | ||||||
|  |  	size_t i; | ||||||
|  |   | ||||||
|  | -	f = fopen(fname, "r"); | ||||||
|  | +	if (!strncmp(fname, "data:", 5)) { | ||||||
|  | +		f = fmemopen((void *)(fname + 5), strlen(fname + 5), "r"); | ||||||
|  | +		fname = "<inline>"; | ||||||
|  | +	} else { | ||||||
|  | +		f = fopen(fname, "r"); | ||||||
|  | +	} | ||||||
|  |  	if (f == NULL) { | ||||||
|  |  		wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " | ||||||
|  |  			   "for reading.", fname); | ||||||
|  | --- a/wpa_supplicant/config_file.c | ||||||
|  | +++ b/wpa_supplicant/config_file.c | ||||||
|  | @@ -318,8 +318,13 @@ struct wpa_config * wpa_config_read(cons | ||||||
|  |  	while (cred_tail && cred_tail->next) | ||||||
|  |  		cred_tail = cred_tail->next; | ||||||
|  |   | ||||||
|  | +	if (!strncmp(name, "data:", 5)) { | ||||||
|  | +		f = fmemopen((void *)(name + 5), strlen(name + 5), "r"); | ||||||
|  | +		name = "<inline>"; | ||||||
|  | +	} else { | ||||||
|  | +		f = fopen(name, "r"); | ||||||
|  | +	} | ||||||
|  |  	wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); | ||||||
|  | -	f = fopen(name, "r"); | ||||||
|  |  	if (f == NULL) { | ||||||
|  |  		wpa_printf(MSG_ERROR, "Failed to open config file '%s', " | ||||||
|  |  			   "error: %s", name, strerror(errno)); | ||||||
| @@ -30,7 +30,7 @@ | |||||||
|   |   | ||||||
| --- a/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| +++ b/hostapd/config_file.c | +++ b/hostapd/config_file.c | ||||||
| @@ -3366,6 +3366,8 @@ static int hostapd_config_fill(struct ho | @@ -3342,6 +3342,8 @@ static int hostapd_config_fill(struct ho | ||||||
|  #ifndef CONFIG_NO_VLAN |  #ifndef CONFIG_NO_VLAN | ||||||
|  	} else if (os_strcmp(buf, "dynamic_vlan") == 0) { |  	} else if (os_strcmp(buf, "dynamic_vlan") == 0) { | ||||||
|  		bss->ssid.dynamic_vlan = atoi(pos); |  		bss->ssid.dynamic_vlan = atoi(pos); | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| =================================================================== | +++ b/hostapd/config_file.c | ||||||
| --- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c | @@ -2341,6 +2341,8 @@ static int hostapd_config_fill(struct ho | ||||||
| +++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c |  | ||||||
| @@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho |  | ||||||
|  			   sizeof(conf->bss[0]->iface)); |  			   sizeof(conf->bss[0]->iface)); | ||||||
|  	} else if (os_strcmp(buf, "bridge") == 0) { |  	} else if (os_strcmp(buf, "bridge") == 0) { | ||||||
|  		os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); |  		os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); | ||||||
| @@ -11,10 +9,8 @@ Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c | |||||||
|  	} else if (os_strcmp(buf, "vlan_bridge") == 0) { |  	} else if (os_strcmp(buf, "vlan_bridge") == 0) { | ||||||
|  		os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); |  		os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); | ||||||
|  	} else if (os_strcmp(buf, "wds_bridge") == 0) { |  	} else if (os_strcmp(buf, "wds_bridge") == 0) { | ||||||
| Index: hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c | --- a/src/ap/ap_drv_ops.c | ||||||
| =================================================================== | +++ b/src/ap/ap_drv_ops.c | ||||||
| --- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_drv_ops.c |  | ||||||
| +++ hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c |  | ||||||
| @@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d | @@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d | ||||||
|  		return -1; |  		return -1; | ||||||
|  	if (hapd->conf->wds_bridge[0]) |  	if (hapd->conf->wds_bridge[0]) | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| +++ b/hostapd/config_file.c | +++ b/hostapd/config_file.c | ||||||
| @@ -2873,6 +2873,14 @@ static int hostapd_config_fill(struct ho | @@ -2853,6 +2853,14 @@ static int hostapd_config_fill(struct ho | ||||||
|  				   line, bss->max_num_sta, MAX_STA_COUNT); |  				   line, bss->max_num_sta, MAX_STA_COUNT); | ||||||
|  			return 1; |  			return 1; | ||||||
|  		} |  		} | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|  	} else if (os_strcmp(buf, "extended_key_id") == 0) { |  	} else if (os_strcmp(buf, "extended_key_id") == 0) { | ||||||
| --- a/src/ap/hostapd.h | --- a/src/ap/hostapd.h | ||||||
| +++ b/src/ap/hostapd.h | +++ b/src/ap/hostapd.h | ||||||
| @@ -648,6 +648,7 @@ void hostapd_cleanup_cs_params(struct ho | @@ -672,6 +672,7 @@ void hostapd_cleanup_cs_params(struct ho | ||||||
|  void hostapd_periodic_iface(struct hostapd_iface *iface); |  void hostapd_periodic_iface(struct hostapd_iface *iface); | ||||||
|  int hostapd_owe_trans_get_info(struct hostapd_data *hapd); |  int hostapd_owe_trans_get_info(struct hostapd_data *hapd); | ||||||
|  void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); |  void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); | ||||||
| @@ -27,7 +27,7 @@ | |||||||
|  int hostapd_register_probereq_cb(struct hostapd_data *hapd, |  int hostapd_register_probereq_cb(struct hostapd_data *hapd, | ||||||
| --- a/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| +++ b/src/ap/hostapd.c | +++ b/src/ap/hostapd.c | ||||||
| @@ -236,6 +236,30 @@ static int hostapd_iface_conf_changed(st | @@ -209,6 +209,30 @@ static int hostapd_iface_conf_changed(st | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -55,7 +55,7 @@ | |||||||
| +	return 0; | +	return 0; | ||||||
| +} | +} | ||||||
| + | + | ||||||
|  int hostapd_reload_config(struct hostapd_iface *iface, int reconf) |  int hostapd_reload_config(struct hostapd_iface *iface) | ||||||
|  { |  { | ||||||
|  	struct hapd_interfaces *interfaces = iface->interfaces; |  	struct hapd_interfaces *interfaces = iface->interfaces; | ||||||
| --- a/src/ap/beacon.c | --- a/src/ap/beacon.c | ||||||
| @@ -71,7 +71,7 @@ | |||||||
|  			   " since no room for additional STA", |  			   " since no room for additional STA", | ||||||
| --- a/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| +++ b/src/ap/ap_config.h | +++ b/src/ap/ap_config.h | ||||||
| @@ -976,6 +976,8 @@ struct hostapd_config { | @@ -959,6 +959,8 @@ struct hostapd_config { | ||||||
|  	unsigned int track_sta_max_num; |  	unsigned int track_sta_max_num; | ||||||
|  	unsigned int track_sta_max_age; |  	unsigned int track_sta_max_age; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| +++ b/hostapd/config_file.c | +++ b/hostapd/config_file.c | ||||||
| @@ -3031,6 +3031,8 @@ static int hostapd_config_fill(struct ho | @@ -3011,6 +3011,8 @@ static int hostapd_config_fill(struct ho | ||||||
|  		wpa_printf(MSG_INFO, |  		wpa_printf(MSG_INFO, | ||||||
|  			   "Line %d: Obsolete peerkey parameter ignored", line); |  			   "Line %d: Obsolete peerkey parameter ignored", line); | ||||||
|  #ifdef CONFIG_IEEE80211R_AP |  #ifdef CONFIG_IEEE80211R_AP | ||||||
| @@ -11,7 +11,7 @@ | |||||||
|  		    hexstr2bin(pos, bss->mobility_domain, |  		    hexstr2bin(pos, bss->mobility_domain, | ||||||
| --- a/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| +++ b/src/ap/ap_config.h | +++ b/src/ap/ap_config.h | ||||||
| @@ -277,6 +277,7 @@ struct airtime_sta_weight { | @@ -275,6 +275,7 @@ struct airtime_sta_weight { | ||||||
|  struct hostapd_bss_config { |  struct hostapd_bss_config { | ||||||
|  	char iface[IFNAMSIZ + 1]; |  	char iface[IFNAMSIZ + 1]; | ||||||
|  	char bridge[IFNAMSIZ + 1]; |  	char bridge[IFNAMSIZ + 1]; | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| =================================================================== | +++ b/src/ap/ap_config.h | ||||||
| --- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_config.h | @@ -276,6 +276,7 @@ struct hostapd_bss_config { | ||||||
| +++ hostapd-2021-05-22-b102f19b/src/ap/ap_config.h |  | ||||||
| @@ -278,6 +278,7 @@ struct hostapd_bss_config { |  | ||||||
|  	char iface[IFNAMSIZ + 1]; |  	char iface[IFNAMSIZ + 1]; | ||||||
|  	char bridge[IFNAMSIZ + 1]; |  	char bridge[IFNAMSIZ + 1]; | ||||||
|  	char ft_iface[IFNAMSIZ + 1]; |  	char ft_iface[IFNAMSIZ + 1]; | ||||||
| @@ -10,10 +8,8 @@ Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h | |||||||
|  	char vlan_bridge[IFNAMSIZ + 1]; |  	char vlan_bridge[IFNAMSIZ + 1]; | ||||||
|  	char wds_bridge[IFNAMSIZ + 1]; |  	char wds_bridge[IFNAMSIZ + 1]; | ||||||
|   |   | ||||||
| Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c | --- a/src/ap/x_snoop.c | ||||||
| =================================================================== | +++ b/src/ap/x_snoop.c | ||||||
| --- hostapd-2021-05-22-b102f19b.orig/src/ap/x_snoop.c |  | ||||||
| +++ hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c |  | ||||||
| @@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha | @@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha | ||||||
|  		return -1; |  		return -1; | ||||||
|  	} |  	} | ||||||
| @@ -57,11 +53,9 @@ Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c | |||||||
|  	if (l2 == NULL) { |  	if (l2 == NULL) { | ||||||
|  		wpa_printf(MSG_DEBUG, |  		wpa_printf(MSG_DEBUG, | ||||||
|  			   "x_snoop: Failed to initialize L2 packet processing %s", |  			   "x_snoop: Failed to initialize L2 packet processing %s", | ||||||
| Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| =================================================================== | +++ b/hostapd/config_file.c | ||||||
| --- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c | @@ -2343,6 +2343,8 @@ static int hostapd_config_fill(struct ho | ||||||
| +++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c |  | ||||||
| @@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho |  | ||||||
|  		os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); |  		os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); | ||||||
|  		if (!bss->wds_bridge[0]) |  		if (!bss->wds_bridge[0]) | ||||||
|  			os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); |  			os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c | --- a/src/ap/ieee802_1x.c | ||||||
| =================================================================== | +++ b/src/ap/ieee802_1x.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_1x.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c |  | ||||||
| @@ -1904,6 +1904,25 @@ static int ieee802_1x_update_vlan(struct | @@ -1904,6 +1904,25 @@ static int ieee802_1x_update_vlan(struct | ||||||
|  } |  } | ||||||
|  #endif /* CONFIG_NO_VLAN */ |  #endif /* CONFIG_NO_VLAN */ | ||||||
| @@ -36,11 +34,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c | |||||||
|  		break; |  		break; | ||||||
|  	case RADIUS_CODE_ACCESS_REJECT: |  	case RADIUS_CODE_ACCESS_REJECT: | ||||||
|  		sm->eap_if->aaaFail = true; |  		sm->eap_if->aaaFail = true; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h | --- a/src/ap/sta_info.h | ||||||
| =================================================================== | +++ b/src/ap/sta_info.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h | @@ -116,6 +116,7 @@ struct sta_info { | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h |  | ||||||
| @@ -117,6 +117,7 @@ struct sta_info { |  | ||||||
|  	u8 supported_rates[WLAN_SUPP_RATES_MAX]; |  	u8 supported_rates[WLAN_SUPP_RATES_MAX]; | ||||||
|  	int supported_rates_len; |  	int supported_rates_len; | ||||||
|  	u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ |  	u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ | ||||||
| @@ -48,10 +44,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h | |||||||
|   |   | ||||||
|  #ifdef CONFIG_MESH |  #ifdef CONFIG_MESH | ||||||
|  	enum mesh_plink_state plink_state; |  	enum mesh_plink_state plink_state; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/radius/radius.c | --- a/src/radius/radius.c | ||||||
| =================================================================== | +++ b/src/radius/radius.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/radius/radius.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/radius/radius.c |  | ||||||
| @@ -1182,6 +1182,35 @@ radius_msg_get_cisco_keys(struct radius_ | @@ -1182,6 +1182,35 @@ radius_msg_get_cisco_keys(struct radius_ | ||||||
|  	return keys; |  	return keys; | ||||||
|  } |  } | ||||||
| @@ -88,10 +82,8 @@ Index: hostapd-2021-02-20-59e9794c/src/radius/radius.c | |||||||
|   |   | ||||||
|  int radius_msg_add_mppe_keys(struct radius_msg *msg, |  int radius_msg_add_mppe_keys(struct radius_msg *msg, | ||||||
|  			     const u8 *req_authenticator, |  			     const u8 *req_authenticator, | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/radius/radius.h | --- a/src/radius/radius.h | ||||||
| =================================================================== | +++ b/src/radius/radius.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/radius/radius.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/radius/radius.h |  | ||||||
| @@ -205,6 +205,10 @@ enum { | @@ -205,6 +205,10 @@ enum { | ||||||
|  	RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL = 10, |  	RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL = 10, | ||||||
|  }; |  }; | ||||||
| @@ -111,16 +103,3 @@ Index: hostapd-2021-02-20-59e9794c/src/radius/radius.h | |||||||
|  int radius_msg_add_mppe_keys(struct radius_msg *msg, |  int radius_msg_add_mppe_keys(struct radius_msg *msg, | ||||||
|  			     const u8 *req_authenticator, |  			     const u8 *req_authenticator, | ||||||
|  			     const u8 *secret, size_t secret_len, |  			     const u8 *secret, size_t secret_len, | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c |  | ||||||
| =================================================================== |  | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c |  | ||||||
| @@ -1292,7 +1292,7 @@ void ap_sta_set_authorized(struct hostap |  | ||||||
|  			    MAC2STR(sta->addr), MAC2STR(dev_addr)); |  | ||||||
|  	else |  | ||||||
|  #endif /* CONFIG_P2P */ |  | ||||||
| -		os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); |  | ||||||
| +		os_snprintf(buf, sizeof(buf), MACSTR " %d %d", MAC2STR(sta->addr), sta->bandwidth[0] / 1000000, sta->bandwidth[1] / 1000000); |  | ||||||
|   |  | ||||||
|  	if (hapd->sta_authorized_cb) |  | ||||||
|  		hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx, |  | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/acs.c | --- a/src/ap/acs.c | ||||||
| =================================================================== | +++ b/src/ap/acs.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/acs.c | @@ -668,6 +668,10 @@ acs_find_ideal_chan_mode(struct hostapd_ | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/acs.c |  | ||||||
| @@ -672,6 +672,10 @@ acs_find_ideal_chan_mode(struct hostapd_ |  | ||||||
|  			continue; |  			continue; | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| +++ b/src/ap/ap_config.h | +++ b/src/ap/ap_config.h | ||||||
| @@ -311,6 +311,7 @@ struct hostapd_bss_config { | @@ -301,6 +301,7 @@ struct hostapd_bss_config { | ||||||
|  	unsigned int eap_sim_db_timeout; |  	unsigned int eap_sim_db_timeout; | ||||||
|  	int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ |  	int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ | ||||||
|  	struct hostapd_ip_addr own_ip_addr; |  	struct hostapd_ip_addr own_ip_addr; | ||||||
| @@ -10,7 +10,7 @@ | |||||||
|  	int acct_interim_interval; |  	int acct_interim_interval; | ||||||
| --- a/src/radius/radius_client.c | --- a/src/radius/radius_client.c | ||||||
| +++ b/src/radius/radius_client.c | +++ b/src/radius/radius_client.c | ||||||
| @@ -163,6 +163,8 @@ struct radius_client_data { | @@ -162,6 +162,8 @@ struct radius_client_data { | ||||||
|  	 */ |  	 */ | ||||||
|  	void *ctx; |  	void *ctx; | ||||||
|   |   | ||||||
| @@ -19,7 +19,7 @@ | |||||||
|  	/** |  	/** | ||||||
|  	 * conf - RADIUS client configuration (list of RADIUS servers to use) |  	 * conf - RADIUS client configuration (list of RADIUS servers to use) | ||||||
|  	 */ |  	 */ | ||||||
| @@ -720,6 +722,30 @@ static void radius_client_list_add(struc | @@ -719,6 +721,30 @@ static void radius_client_list_add(struc | ||||||
|   |   | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| @@ -50,7 +50,7 @@ | |||||||
|   * radius_client_send - Send a RADIUS request |   * radius_client_send - Send a RADIUS request | ||||||
|   * @radius: RADIUS client context from radius_client_init() |   * @radius: RADIUS client context from radius_client_init() | ||||||
|   * @msg: RADIUS message to be sent |   * @msg: RADIUS message to be sent | ||||||
| @@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien | @@ -1219,6 +1245,10 @@ radius_change_server(struct radius_clien | ||||||
|  			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", |  			wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", | ||||||
|  				   inet_ntoa(claddr.sin_addr), |  				   inet_ntoa(claddr.sin_addr), | ||||||
|  				   ntohs(claddr.sin_port)); |  				   ntohs(claddr.sin_port)); | ||||||
| @@ -61,7 +61,7 @@ | |||||||
|  		} |  		} | ||||||
|  		break; |  		break; | ||||||
|  #ifdef CONFIG_IPV6 |  #ifdef CONFIG_IPV6 | ||||||
| @@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien | @@ -1230,6 +1260,10 @@ radius_change_server(struct radius_clien | ||||||
|  				   inet_ntop(AF_INET6, &claddr6.sin6_addr, |  				   inet_ntop(AF_INET6, &claddr6.sin6_addr, | ||||||
|  					     abuf, sizeof(abuf)), |  					     abuf, sizeof(abuf)), | ||||||
|  				   ntohs(claddr6.sin6_port)); |  				   ntohs(claddr6.sin6_port)); | ||||||
| @@ -74,7 +74,7 @@ | |||||||
|  	} |  	} | ||||||
| --- a/src/radius/radius_client.h | --- a/src/radius/radius_client.h | ||||||
| +++ b/src/radius/radius_client.h | +++ b/src/radius/radius_client.h | ||||||
| @@ -249,6 +249,8 @@ int radius_client_register(struct radius | @@ -244,6 +244,8 @@ int radius_client_register(struct radius | ||||||
|  void radius_client_set_interim_error_cb(struct radius_client_data *radius, |  void radius_client_set_interim_error_cb(struct radius_client_data *radius, | ||||||
|  					void (*cb)(const u8 *addr, void *ctx), |  					void (*cb)(const u8 *addr, void *ctx), | ||||||
|  					void *ctx); |  					void *ctx); | ||||||
| @@ -98,7 +98,7 @@ | |||||||
|  	    hapd->conf->own_ip_addr.af == AF_INET && |  	    hapd->conf->own_ip_addr.af == AF_INET && | ||||||
| --- a/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| +++ b/hostapd/config_file.c | +++ b/hostapd/config_file.c | ||||||
| @@ -2681,6 +2681,8 @@ static int hostapd_config_fill(struct ho | @@ -2696,6 +2696,8 @@ static int hostapd_config_fill(struct ho | ||||||
|  	} else if (os_strcmp(buf, "iapp_interface") == 0) { |  	} else if (os_strcmp(buf, "iapp_interface") == 0) { | ||||||
|  		wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); |  		wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); | ||||||
|  #endif /* CONFIG_IAPP */ |  #endif /* CONFIG_IAPP */ | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| =================================================================== | +++ b/src/ap/hostapd.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c |  | ||||||
| @@ -11,6 +11,8 @@ | @@ -11,6 +11,8 @@ | ||||||
|  #include <sqlite3.h> |  #include <sqlite3.h> | ||||||
|  #endif /* CONFIG_SQLITE */ |  #endif /* CONFIG_SQLITE */ | ||||||
| @@ -10,8 +8,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
| + | + | ||||||
|  #include "utils/common.h" |  #include "utils/common.h" | ||||||
|  #include "utils/eloop.h" |  #include "utils/eloop.h" | ||||||
|  #include "common/ieee802_11_defs.h" |  #include "utils/crc32.h" | ||||||
| @@ -1316,6 +1318,22 @@ static int hostapd_setup_bss(struct host | @@ -1198,6 +1200,22 @@ int hostapd_setup_bss(struct hostapd_dat | ||||||
|  			os_memcpy(hapd->own_addr, if_addr, ETH_ALEN); |  			os_memcpy(hapd->own_addr, if_addr, ETH_ALEN); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -32,5 +30,5 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
| +	} | +	} | ||||||
| + | + | ||||||
|  	if (conf->wmm_enabled < 0) |  	if (conf->wmm_enabled < 0) | ||||||
|  		conf->wmm_enabled = hapd->iconf->ieee80211n | hapd->iconf->ieee80211ax; |  		conf->wmm_enabled = hapd->iconf->ieee80211n; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c | --- a/src/ap/sta_info.c | ||||||
| =================================================================== | +++ b/src/ap/sta_info.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c |  | ||||||
| @@ -717,7 +717,7 @@ struct sta_info * ap_sta_add(struct host | @@ -717,7 +717,7 @@ struct sta_info * ap_sta_add(struct host | ||||||
|  		return sta; |  		return sta; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c |  | ||||||
| index ad2aebf..355b4a8 100644 |  | ||||||
| --- a/src/common/hw_features_common.c | --- a/src/common/hw_features_common.c | ||||||
| +++ b/src/common/hw_features_common.c | +++ b/src/common/hw_features_common.c | ||||||
| @@ -615,9 +615,21 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, | @@ -609,9 +609,21 @@ int hostapd_set_freq_params(struct hosta | ||||||
|  			    center_segment0 == channel - 6) |  			    center_segment0 == channel - 6) | ||||||
|  				data->center_freq1 = 5000 + center_segment0 * 5; |  				data->center_freq1 = 5000 + center_segment0 * 5; | ||||||
|  			else { |  			else { | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c | --- a/src/radius/radius_das.c | ||||||
| =================================================================== | +++ b/src/radius/radius_das.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c |  | ||||||
| @@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di | @@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di | ||||||
|  		RADIUS_ATTR_EVENT_TIMESTAMP, |  		RADIUS_ATTR_EVENT_TIMESTAMP, | ||||||
|  		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, |  		RADIUS_ATTR_MESSAGE_AUTHENTICATOR, | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
|  	unsigned int time_window; |  	unsigned int time_window; | ||||||
| --- a/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| +++ b/src/ap/hostapd.c | +++ b/src/ap/hostapd.c | ||||||
| @@ -1367,6 +1367,7 @@ static int hostapd_setup_bss(struct host | @@ -1325,6 +1325,7 @@ int hostapd_setup_bss(struct hostapd_dat | ||||||
|  		struct radius_das_conf das_conf; |  		struct radius_das_conf das_conf; | ||||||
|  		os_memset(&das_conf, 0, sizeof(das_conf)); |  		os_memset(&das_conf, 0, sizeof(das_conf)); | ||||||
|  		das_conf.port = conf->radius_das_port; |  		das_conf.port = conf->radius_das_port; | ||||||
| @@ -48,7 +48,7 @@ | |||||||
|  	size_t shared_secret_len; |  	size_t shared_secret_len; | ||||||
|  	struct hostapd_ip_addr client_addr; |  	struct hostapd_ip_addr client_addr; | ||||||
|  	unsigned int time_window; |  	unsigned int time_window; | ||||||
| @@ -378,56 +391,17 @@ fail: | @@ -379,56 +392,17 @@ fail: | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -111,7 +111,7 @@ | |||||||
|   |   | ||||||
|  	if (radius_msg_verify_das_req(msg, das->shared_secret, |  	if (radius_msg_verify_das_req(msg, das->shared_secret, | ||||||
|  				       das->shared_secret_len, |  				       das->shared_secret_len, | ||||||
| @@ -494,9 +468,8 @@ static void radius_das_receive(int sock, | @@ -495,9 +469,8 @@ static void radius_das_receive(int sock, | ||||||
|  			radius_msg_dump(reply); |  			radius_msg_dump(reply); | ||||||
|   |   | ||||||
|  		rbuf = radius_msg_get_buf(reply); |  		rbuf = radius_msg_get_buf(reply); | ||||||
| @@ -123,7 +123,11 @@ | |||||||
|  		if (res < 0) { |  		if (res < 0) { | ||||||
|  			wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", |  			wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", | ||||||
|  				   abuf, from_port, strerror(errno)); |  				   abuf, from_port, strerror(errno)); | ||||||
| @@ -508,6 +481,72 @@ fail: | @@ -505,10 +478,76 @@ static void radius_das_receive(int sock, | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  fail: | ||||||
|  | -	radius_msg_free(msg); | ||||||
|  	radius_msg_free(reply); |  	radius_msg_free(reply); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -189,6 +193,7 @@ | |||||||
| +				       fromlen, abuf, from_port); | +				       fromlen, abuf, from_port); | ||||||
| +	} | +	} | ||||||
| + | + | ||||||
|  | +	radius_msg_free(msg); | ||||||
| +	if (!found) | +	if (!found) | ||||||
| +		wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); | +		wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); | ||||||
| +} | +} | ||||||
| @@ -196,7 +201,7 @@ | |||||||
|   |   | ||||||
|  static int radius_das_open_socket(int port) |  static int radius_das_open_socket(int port) | ||||||
|  { |  { | ||||||
| @@ -533,6 +572,49 @@ static int radius_das_open_socket(int po | @@ -534,6 +573,49 @@ static int radius_das_open_socket(int po | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -246,7 +251,7 @@ | |||||||
|  struct radius_das_data * |  struct radius_das_data * | ||||||
|  radius_das_init(struct radius_das_conf *conf) |  radius_das_init(struct radius_das_conf *conf) | ||||||
|  { |  { | ||||||
| @@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * | @@ -554,6 +636,8 @@ radius_das_init(struct radius_das_conf * | ||||||
|  	das->ctx = conf->ctx; |  	das->ctx = conf->ctx; | ||||||
|  	das->disconnect = conf->disconnect; |  	das->disconnect = conf->disconnect; | ||||||
|  	das->coa = conf->coa; |  	das->coa = conf->coa; | ||||||
| @@ -255,7 +260,7 @@ | |||||||
|   |   | ||||||
|  	os_memcpy(&das->client_addr, conf->client_addr, |  	os_memcpy(&das->client_addr, conf->client_addr, | ||||||
|  		  sizeof(das->client_addr)); |  		  sizeof(das->client_addr)); | ||||||
| @@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * | @@ -566,19 +650,15 @@ radius_das_init(struct radius_das_conf * | ||||||
|  	} |  	} | ||||||
|  	das->shared_secret_len = conf->shared_secret_len; |  	das->shared_secret_len = conf->shared_secret_len; | ||||||
|   |   | ||||||
| @@ -278,7 +283,7 @@ | |||||||
|   |   | ||||||
|  	return das; |  	return das; | ||||||
|  } |  } | ||||||
| @@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das | @@ -589,11 +669,14 @@ void radius_das_deinit(struct radius_das | ||||||
|  	if (das == NULL) |  	if (das == NULL) | ||||||
|  		return; |  		return; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| =================================================================== | +++ b/hostapd/config_file.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c |  | ||||||
| @@ -2366,6 +2366,8 @@ static int hostapd_config_fill(struct ho | @@ -2366,6 +2366,8 @@ static int hostapd_config_fill(struct ho | ||||||
|  			return 1; |  			return 1; | ||||||
|  		} |  		} | ||||||
| @@ -11,23 +9,19 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c | |||||||
|  	} else if (os_strcmp(buf, "driver_params") == 0) { |  	} else if (os_strcmp(buf, "driver_params") == 0) { | ||||||
|  		os_free(conf->driver_params); |  		os_free(conf->driver_params); | ||||||
|  		conf->driver_params = os_strdup(pos); |  		conf->driver_params = os_strdup(pos); | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| =================================================================== | +++ b/src/ap/ap_config.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h |  | ||||||
| @@ -279,6 +279,7 @@ struct hostapd_bss_config { | @@ -279,6 +279,7 @@ struct hostapd_bss_config { | ||||||
|  	char snoop_iface[IFNAMSIZ + 1]; |  	char snoop_iface[IFNAMSIZ + 1]; | ||||||
|  	char vlan_bridge[IFNAMSIZ + 1]; |  	char vlan_bridge[IFNAMSIZ + 1]; | ||||||
|  	char wds_bridge[IFNAMSIZ + 1]; |  	char wds_bridge[IFNAMSIZ + 1]; | ||||||
| +	char *uci_section; | +	char *uci_section; | ||||||
|   |   | ||||||
|  	char *config_id; |  	enum hostapd_logger_level logger_syslog_level, logger_stdout_level; | ||||||
|   |   | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c | --- a/src/ap/ubus.c | ||||||
| =================================================================== | +++ b/src/ap/ubus.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ubus.c | @@ -424,6 +424,9 @@ hostapd_bss_get_status(struct ubus_conte | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ubus.c |  | ||||||
| @@ -467,6 +467,9 @@ hostapd_bss_get_status(struct ubus_conte |  | ||||||
|  			hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); |  			hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); | ||||||
|  	blobmsg_close_table(&b, dfs_table); |  	blobmsg_close_table(&b, dfs_table); | ||||||
|   |   | ||||||
| @@ -37,15 +31,13 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c | |||||||
|  	ubus_send_reply(ctx, req, b.head); |  	ubus_send_reply(ctx, req, b.head); | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.c | --- a/src/ap/ap_config.c | ||||||
| =================================================================== | +++ b/src/ap/ap_config.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.c |  | ||||||
| @@ -785,6 +785,7 @@ void hostapd_config_free_bss(struct host | @@ -785,6 +785,7 @@ void hostapd_config_free_bss(struct host | ||||||
|  	os_free(conf->radius_req_attr_sqlite); |  	os_free(conf->radius_req_attr_sqlite); | ||||||
|  	os_free(conf->rsn_preauth_interfaces); |  	os_free(conf->rsn_preauth_interfaces); | ||||||
|  	os_free(conf->ctrl_interface); |  	os_free(conf->ctrl_interface); | ||||||
| +	os_free(conf->uci_section); | +	os_free(conf->uci_section); | ||||||
|  	os_free(conf->config_id); |  | ||||||
|  	os_free(conf->ca_cert); |  	os_free(conf->ca_cert); | ||||||
|  	os_free(conf->server_cert); |  	os_free(conf->server_cert); | ||||||
|  |  	os_free(conf->server_cert2); | ||||||
|   | |||||||
							
								
								
									
										91
									
								
								feeds/ipq807x_v5.4/hostapd/patches/920-sta_driver_data.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								feeds/ipq807x_v5.4/hostapd/patches/920-sta_driver_data.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | --- a/src/drivers/driver.h | ||||||
|  | +++ b/src/drivers/driver.h | ||||||
|  | @@ -2175,6 +2175,10 @@ struct hostap_sta_driver_data { | ||||||
|  |  	u8 tx_mcs; | ||||||
|  |  	u8 rx_vht_nss; | ||||||
|  |  	u8 tx_vht_nss; | ||||||
|  | +	u8 rx_hemcs; | ||||||
|  | +	u8 tx_hemcs; | ||||||
|  | +	u8 rx_he_nss; | ||||||
|  | +	u8 tx_he_nss; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct hostapd_sta_add_params { | ||||||
|  | --- a/src/drivers/driver_nl80211.c | ||||||
|  | +++ b/src/drivers/driver_nl80211.c | ||||||
|  | @@ -7010,6 +7010,8 @@ static int get_sta_handler(struct nl_msg | ||||||
|  |  		[NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 }, | ||||||
|  |  		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, | ||||||
|  |  		[NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 }, | ||||||
|  | +		[NL80211_RATE_INFO_HE_NSS] = { .type = NLA_U8 }, | ||||||
|  | +		[NL80211_RATE_INFO_HE_MCS] = { .type = NLA_U8 }, | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), | ||||||
|  | @@ -7102,6 +7104,10 @@ static int get_sta_handler(struct nl_msg | ||||||
|  |  				nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); | ||||||
|  |  			data->flags |= STA_DRV_DATA_TX_VHT_NSS; | ||||||
|  |  		} | ||||||
|  | +		if (rate[NL80211_RATE_INFO_HE_MCS]) | ||||||
|  | +			data->tx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); | ||||||
|  | +		if (rate[NL80211_RATE_INFO_HE_NSS]) | ||||||
|  | +			data->tx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (stats[NL80211_STA_INFO_RX_BITRATE] && | ||||||
|  | @@ -7132,11 +7138,16 @@ static int get_sta_handler(struct nl_msg | ||||||
|  |  				nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); | ||||||
|  |  			data->flags |= STA_DRV_DATA_RX_VHT_NSS; | ||||||
|  |  		} | ||||||
|  | +		if (rate[NL80211_RATE_INFO_HE_MCS]) | ||||||
|  | +			data->rx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); | ||||||
|  | +		if (rate[NL80211_RATE_INFO_HE_NSS]) | ||||||
|  | +			data->rx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (stats[NL80211_STA_INFO_TID_STATS]) | ||||||
|  |  		get_sta_tid_stats(data, stats[NL80211_STA_INFO_TID_STATS]); | ||||||
|  |   | ||||||
|  | + | ||||||
|  |  	return NL_SKIP; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/src/ap/ubus.c | ||||||
|  | +++ b/src/ap/ubus.c | ||||||
|  | @@ -306,6 +306,36 @@ hostapd_bss_get_clients(struct ubus_cont | ||||||
|  |  			blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); | ||||||
|  |  			blobmsg_close_table(&b, r); | ||||||
|  |  			blobmsg_add_u32(&b, "signal", sta_driver_data.signal); | ||||||
|  | +		 | ||||||
|  | +			r = blobmsg_open_table(&b, "mcs"); | ||||||
|  | +			if (sta_driver_data.rx_hemcs) { | ||||||
|  | +				blobmsg_add_u32(&b, "he", 1); | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_hemcs); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_hemcs); | ||||||
|  | +			} else if (sta_driver_data.rx_vhtmcs) { | ||||||
|  | +				blobmsg_add_u32(&b, "vht", 1); | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vhtmcs); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vhtmcs); | ||||||
|  | +			} else { | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); | ||||||
|  | +			} | ||||||
|  | +			blobmsg_close_table(&b, r); | ||||||
|  | + | ||||||
|  | +			r = blobmsg_open_table(&b, "nss"); | ||||||
|  | +			if (sta_driver_data.rx_he_nss) { | ||||||
|  | +				blobmsg_add_u32(&b, "he", 1); | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_he_nss); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_he_nss); | ||||||
|  | +			} else if (sta_driver_data.rx_vht_nss) { | ||||||
|  | +				blobmsg_add_u32(&b, "vht", 1); | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vht_nss); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vht_nss); | ||||||
|  | +			} else { | ||||||
|  | +				blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); | ||||||
|  | +				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); | ||||||
|  | +			} | ||||||
|  | +			blobmsg_close_table(&b, r); | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		hostapd_parse_capab_blobmsg(sta); | ||||||
| @@ -1,8 +1,6 @@ | |||||||
| Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c | --- a/hostapd/config_file.c | ||||||
| =================================================================== | +++ b/hostapd/config_file.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c | @@ -3337,6 +3337,8 @@ static int hostapd_config_fill(struct ho | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c |  | ||||||
| @@ -3339,6 +3339,8 @@ static int hostapd_config_fill(struct ho |  | ||||||
|  		bss->ignore_broadcast_ssid = atoi(pos); |  		bss->ignore_broadcast_ssid = atoi(pos); | ||||||
|  	} else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) { |  	} else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) { | ||||||
|  		bss->no_probe_resp_if_max_sta = atoi(pos); |  		bss->no_probe_resp_if_max_sta = atoi(pos); | ||||||
| @@ -11,11 +9,9 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c | |||||||
|  #ifdef CONFIG_WEP |  #ifdef CONFIG_WEP | ||||||
|  	} else if (os_strcmp(buf, "wep_default_key") == 0) { |  	} else if (os_strcmp(buf, "wep_default_key") == 0) { | ||||||
|  		bss->ssid.wep.idx = atoi(pos); |  		bss->ssid.wep.idx = atoi(pos); | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h | --- a/src/ap/ap_config.h | ||||||
| =================================================================== | +++ b/src/ap/ap_config.h | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h | @@ -459,6 +459,7 @@ struct hostapd_bss_config { | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h |  | ||||||
| @@ -460,6 +460,7 @@ struct hostapd_bss_config { |  | ||||||
|  	int ap_max_inactivity; |  	int ap_max_inactivity; | ||||||
|  	int ignore_broadcast_ssid; |  	int ignore_broadcast_ssid; | ||||||
|  	int no_probe_resp_if_max_sta; |  	int no_probe_resp_if_max_sta; | ||||||
| @@ -23,10 +19,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h | |||||||
|   |   | ||||||
|  	int wmm_enabled; |  	int wmm_enabled; | ||||||
|  	int wmm_uapsd; |  	int wmm_uapsd; | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | --- a/src/ap/beacon.c | ||||||
| =================================================================== | +++ b/src/ap/beacon.c | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c |  | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c |  | ||||||
| @@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat | @@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat | ||||||
|  	} |  	} | ||||||
|  #endif /* CONFIG_P2P */ |  #endif /* CONFIG_P2P */ | ||||||
|   | |||||||
							
								
								
									
										95
									
								
								feeds/ipq807x_v5.4/hostapd/patches/999-ssi_signal.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								feeds/ipq807x_v5.4/hostapd/patches/999-ssi_signal.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | --- a/src/ap/ieee802_11.c | ||||||
|  | +++ b/src/ap/ieee802_11.c | ||||||
|  | @@ -57,6 +57,15 @@ | ||||||
|  |  #include "gas_query_ap.h" | ||||||
|  |   | ||||||
|  |   | ||||||
|  | +static int | ||||||
|  | +ewma(int new, int old) | ||||||
|  | +{ | ||||||
|  | +	#define ALPHA	10 | ||||||
|  | +	if (new >= 0) | ||||||
|  | +		return old; | ||||||
|  | +	return ((ALPHA * new) + ((100 - ALPHA) * old)) / 100; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  #ifdef CONFIG_FILS | ||||||
|  |  static struct wpabuf * | ||||||
|  |  prepare_auth_resp_fils(struct hostapd_data *hapd, | ||||||
|  | @@ -5873,7 +5882,7 @@ static int robust_action_frame(u8 catego | ||||||
|  |   | ||||||
|  |  static int handle_action(struct hostapd_data *hapd, | ||||||
|  |  			 const struct ieee80211_mgmt *mgmt, size_t len, | ||||||
|  | -			 unsigned int freq) | ||||||
|  | +			 unsigned int freq, int ssi_signal) | ||||||
|  |  { | ||||||
|  |  	struct sta_info *sta; | ||||||
|  |  	u8 *action __maybe_unused; | ||||||
|  | @@ -5930,6 +5939,7 @@ static int handle_action(struct hostapd_ | ||||||
|  |   | ||||||
|  |  		sta->last_seq_ctrl = seq_ctrl; | ||||||
|  |  		sta->last_subtype = WLAN_FC_STYPE_ACTION; | ||||||
|  | +		sta->signal_mgmt = ewma(ssi_signal, sta->signal_mgmt);; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	switch (mgmt->u.action.category) { | ||||||
|  | @@ -6109,6 +6119,8 @@ int ieee802_11_mgmt(struct hostapd_data | ||||||
|  |  	unsigned int freq; | ||||||
|  |  	int ssi_signal = fi ? fi->ssi_signal : 0; | ||||||
|  |   | ||||||
|  | +	hapd->signal_mgmt = ewma(ssi_signal, hapd->signal_mgmt);; | ||||||
|  | + | ||||||
|  |  	if (len < 24) | ||||||
|  |  		return 0; | ||||||
|  |   | ||||||
|  | @@ -6208,7 +6220,7 @@ int ieee802_11_mgmt(struct hostapd_data | ||||||
|  |  		break; | ||||||
|  |  	case WLAN_FC_STYPE_ACTION: | ||||||
|  |  		wpa_printf(MSG_DEBUG, "mgmt::action"); | ||||||
|  | -		ret = handle_action(hapd, mgmt, len, freq); | ||||||
|  | +		ret = handle_action(hapd, mgmt, len, freq, ssi_signal); | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, | ||||||
|  | --- a/src/ap/sta_info.h | ||||||
|  | +++ b/src/ap/sta_info.h | ||||||
|  | @@ -331,6 +331,7 @@ struct sta_info { | ||||||
|  |  #ifdef CONFIG_PASN | ||||||
|  |  	struct pasn_data *pasn; | ||||||
|  |  #endif /* CONFIG_PASN */ | ||||||
|  | +	int signal_mgmt; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |   | ||||||
|  | --- a/src/ap/ubus.c | ||||||
|  | +++ b/src/ap/ubus.c | ||||||
|  | @@ -336,6 +336,9 @@ hostapd_bss_get_clients(struct ubus_cont | ||||||
|  |  				blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); | ||||||
|  |  			} | ||||||
|  |  			blobmsg_close_table(&b, r); | ||||||
|  | +		 | ||||||
|  | +			if (sta->signal_mgmt) | ||||||
|  | +				blobmsg_add_u32(&b, "signal_mgmt", sta->signal_mgmt); | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		hostapd_parse_capab_blobmsg(sta); | ||||||
|  | @@ -457,6 +460,9 @@ hostapd_bss_get_status(struct ubus_conte | ||||||
|  |  	if (hapd->conf->uci_section) | ||||||
|  |  		blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section); | ||||||
|  |   | ||||||
|  | +	if (hapd->signal_mgmt) | ||||||
|  | +		blobmsg_add_u32(&b, "signal_mgmt", hapd->signal_mgmt); | ||||||
|  | + | ||||||
|  |  	ubus_send_reply(ctx, req, b.head); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | --- a/src/ap/hostapd.h | ||||||
|  | +++ b/src/ap/hostapd.h | ||||||
|  | @@ -451,6 +451,7 @@ struct hostapd_data { | ||||||
|  |  #ifdef CONFIG_CTRL_IFACE_UDP | ||||||
|  |         unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; | ||||||
|  |  #endif /* CONFIG_CTRL_IFACE_UDP */ | ||||||
|  | +       int signal_mgmt; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |   | ||||||
| @@ -16,7 +16,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c | |||||||
| =================================================================== | =================================================================== | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c | --- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c | ||||||
| +++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c | +++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c | ||||||
| @@ -4683,6 +4683,8 @@ static int hostapd_config_fill(struct ho | @@ -4685,6 +4685,8 @@ static int hostapd_config_fill(struct ho | ||||||
|  		} |  		} | ||||||
|  		bss->mka_psk_set |= MKA_PSK_SET_CKN; |  		bss->mka_psk_set |= MKA_PSK_SET_CKN; | ||||||
|  #endif /* CONFIG_MACSEC */ |  #endif /* CONFIG_MACSEC */ | ||||||
| @@ -69,7 +69,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|  void hostapd_reconfig_encryption(struct hostapd_data *hapd) |  void hostapd_reconfig_encryption(struct hostapd_data *hapd) | ||||||
|  { |  { | ||||||
|  	if (hapd->wpa_auth) |  	if (hapd->wpa_auth) | ||||||
| @@ -1208,6 +1228,13 @@ static int hostapd_setup_bss(struct host | @@ -1162,6 +1182,13 @@ int hostapd_setup_bss(struct hostapd_dat | ||||||
|   |   | ||||||
|  	if (!first || first == -1) { |  	if (!first || first == -1) { | ||||||
|  		u8 *addr = hapd->own_addr; |  		u8 *addr = hapd->own_addr; | ||||||
| @@ -83,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c | |||||||
|   |   | ||||||
|  		if (!is_zero_ether_addr(conf->bssid)) { |  		if (!is_zero_ether_addr(conf->bssid)) { | ||||||
|  			/* Allocate the configured BSSID. */ |  			/* Allocate the configured BSSID. */ | ||||||
| @@ -1235,7 +1262,7 @@ static int hostapd_setup_bss(struct host | @@ -1189,7 +1216,7 @@ int hostapd_setup_bss(struct hostapd_dat | ||||||
|  				   conf->iface, addr, hapd, |  				   conf->iface, addr, hapd, | ||||||
|  				   &hapd->drv_priv, force_ifname, if_addr, |  				   &hapd->drv_priv, force_ifname, if_addr, | ||||||
|  				   conf->bridge[0] ? conf->bridge : NULL, |  				   conf->bridge[0] ? conf->bridge : NULL, | ||||||
| @@ -96,13 +96,13 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | |||||||
| =================================================================== | =================================================================== | ||||||
| --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h | --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h | ||||||
| +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h | ||||||
| @@ -621,6 +621,8 @@ struct hostapd_iface { | @@ -628,6 +628,8 @@ struct hostapd_iface { | ||||||
|  int hostapd_for_each_interface(struct hapd_interfaces *interfaces, |  int hostapd_for_each_interface(struct hapd_interfaces *interfaces, | ||||||
|  			       int (*cb)(struct hostapd_iface *iface, |  			       int (*cb)(struct hostapd_iface *iface, | ||||||
|  					 void *ctx), void *ctx); |  					 void *ctx), void *ctx); | ||||||
| +int hostapd_get_bss_index(struct hostapd_data *hapd); | +int hostapd_get_bss_index(struct hostapd_data *hapd); | ||||||
| +struct hostapd_data * hostapd_get_primary_bss(struct hostapd_data *hapd); | +struct hostapd_data * hostapd_get_primary_bss(struct hostapd_data *hapd); | ||||||
|  int hostapd_reload_config(struct hostapd_iface *iface, int reconf); |  int hostapd_reload_config(struct hostapd_iface *iface); | ||||||
|  void hostapd_reconfig_encryption(struct hostapd_data *hapd); |  void hostapd_reconfig_encryption(struct hostapd_data *hapd); | ||||||
|  struct hostapd_data * |  struct hostapd_data * | ||||||
| Index: hostapd-2021-02-20-59e9794c/src/ap/ap_drv_ops.c | Index: hostapd-2021-02-20-59e9794c/src/ap/ap_drv_ops.c | ||||||
| @@ -203,7 +203,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | |||||||
|  	if (len < IEEE80211_HDRLEN) |  	if (len < IEEE80211_HDRLEN) | ||||||
|  		return; |  		return; | ||||||
|  	ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN; |  	ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN; | ||||||
| @@ -1085,7 +1097,7 @@ void handle_probe_req(struct hostapd_dat | @@ -1087,7 +1099,7 @@ void handle_probe_req(struct hostapd_dat | ||||||
|  				hapd->cs_c_off_ecsa_proberesp; |  				hapd->cs_c_off_ecsa_proberesp; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -212,7 +212,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | |||||||
|  				    csa_offs_len ? csa_offs : NULL, |  				    csa_offs_len ? csa_offs : NULL, | ||||||
|  				    csa_offs_len, 0); |  				    csa_offs_len, 0); | ||||||
|   |   | ||||||
| @@ -1746,6 +1758,8 @@ void ieee802_11_free_ap_params(struct wp | @@ -1748,6 +1760,8 @@ void ieee802_11_free_ap_params(struct wp | ||||||
|  	params->head = NULL; |  	params->head = NULL; | ||||||
|  	os_free(params->proberesp); |  	os_free(params->proberesp); | ||||||
|  	params->proberesp = NULL; |  	params->proberesp = NULL; | ||||||
| @@ -221,7 +221,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c | |||||||
|  #ifdef CONFIG_FILS |  #ifdef CONFIG_FILS | ||||||
|  	os_free(params->fd_frame_tmpl); |  	os_free(params->fd_frame_tmpl); | ||||||
|  	params->fd_frame_tmpl = NULL; |  	params->fd_frame_tmpl = NULL; | ||||||
| @@ -1802,6 +1816,22 @@ int ieee802_11_set_beacon(struct hostapd | @@ -1809,6 +1823,22 @@ int ieee802_11_set_beacon(struct hostapd | ||||||
|  	params.unsol_bcast_probe_resp_tmpl = |  	params.unsol_bcast_probe_resp_tmpl = | ||||||
|  		hostapd_unsol_bcast_probe_resp(hapd, ¶ms); |  		hostapd_unsol_bcast_probe_resp(hapd, ¶ms); | ||||||
|  #endif /* CONFIG_IEEE80211AX */ |  #endif /* CONFIG_IEEE80211AX */ | ||||||
| @@ -299,7 +299,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h | |||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  struct wpa_driver_mesh_bss_params { |  struct wpa_driver_mesh_bss_params { | ||||||
| @@ -3344,7 +3381,8 @@ struct wpa_driver_ops { | @@ -3348,7 +3385,8 @@ struct wpa_driver_ops { | ||||||
|  	int (*if_add)(void *priv, enum wpa_driver_if_type type, |  	int (*if_add)(void *priv, enum wpa_driver_if_type type, | ||||||
|  		      const char *ifname, const u8 *addr, void *bss_ctx, |  		      const char *ifname, const u8 *addr, void *bss_ctx, | ||||||
|  		      void **drv_priv, char *force_ifname, u8 *if_addr, |  		      void **drv_priv, char *force_ifname, u8 *if_addr, | ||||||
| @@ -354,7 +354,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, |  	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, | ||||||
|  				       NULL, NULL, NULL, NULL); |  				       NULL, NULL, NULL, NULL); | ||||||
|  	if (ret) { |  	if (ret) { | ||||||
| @@ -5405,13 +5426,13 @@ const char * nl80211_iftype_str(enum nl8 | @@ -5402,13 +5423,13 @@ const char * nl80211_iftype_str(enum nl8 | ||||||
|  	} |  	} | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -370,7 +370,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  { |  { | ||||||
|  	struct nl_msg *msg; |  	struct nl_msg *msg; | ||||||
|  	int ifidx; |  	int ifidx; | ||||||
| @@ -5440,6 +5461,17 @@ static int nl80211_create_iface_once(str | @@ -5437,6 +5458,17 @@ static int nl80211_create_iface_once(str | ||||||
|  			goto fail; |  			goto fail; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -388,7 +388,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  	/* |  	/* | ||||||
|  	 * Tell cfg80211 that the interface belongs to the socket that created |  	 * Tell cfg80211 that the interface belongs to the socket that created | ||||||
|  	 * it, and the interface should be deleted when the socket is closed. |  	 * it, and the interface should be deleted when the socket is closed. | ||||||
| @@ -5497,12 +5529,15 @@ int nl80211_create_iface(struct wpa_driv | @@ -5494,12 +5526,15 @@ int nl80211_create_iface(struct wpa_driv | ||||||
|  			 const char *ifname, enum nl80211_iftype iftype, |  			 const char *ifname, enum nl80211_iftype iftype, | ||||||
|  			 const u8 *addr, int wds, |  			 const u8 *addr, int wds, | ||||||
|  			 int (*handler)(struct nl_msg *, void *), |  			 int (*handler)(struct nl_msg *, void *), | ||||||
| @@ -406,7 +406,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|   |   | ||||||
|  	/* if error occurred and interface exists already */ |  	/* if error occurred and interface exists already */ | ||||||
|  	if (ret == -ENFILE && if_nametoindex(ifname)) { |  	if (ret == -ENFILE && if_nametoindex(ifname)) { | ||||||
| @@ -5528,7 +5563,9 @@ int nl80211_create_iface(struct wpa_driv | @@ -5525,7 +5560,9 @@ int nl80211_create_iface(struct wpa_driv | ||||||
|   |   | ||||||
|  		/* Try to create the interface again */ |  		/* Try to create the interface again */ | ||||||
|  		ret = nl80211_create_iface_once(drv, ifname, iftype, addr, |  		ret = nl80211_create_iface_once(drv, ifname, iftype, addr, | ||||||
| @@ -417,7 +417,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	if (ret >= 0 && is_p2p_net_interface(iftype)) { |  	if (ret >= 0 && is_p2p_net_interface(iftype)) { | ||||||
| @@ -7518,7 +7555,7 @@ static int i802_set_wds_sta(void *priv, | @@ -7526,7 +7563,7 @@ static int i802_set_wds_sta(void *priv, | ||||||
|  		if (!if_nametoindex(name)) { |  		if (!if_nametoindex(name)) { | ||||||
|  			if (nl80211_create_iface(drv, name, |  			if (nl80211_create_iface(drv, name, | ||||||
|  						 NL80211_IFTYPE_AP_VLAN, |  						 NL80211_IFTYPE_AP_VLAN, | ||||||
| @@ -426,7 +426,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  			    0) |  			    0) | ||||||
|  				return -1; |  				return -1; | ||||||
|  			if (bridge_ifname && |  			if (bridge_ifname && | ||||||
| @@ -7863,7 +7900,9 @@ static int wpa_driver_nl80211_if_add(voi | @@ -7871,7 +7908,9 @@ static int wpa_driver_nl80211_if_add(voi | ||||||
|  				     void *bss_ctx, void **drv_priv, |  				     void *bss_ctx, void **drv_priv, | ||||||
|  				     char *force_ifname, u8 *if_addr, |  				     char *force_ifname, u8 *if_addr, | ||||||
|  				     const char *bridge, int use_existing, |  				     const char *bridge, int use_existing, | ||||||
| @@ -437,7 +437,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  { |  { | ||||||
|  	enum nl80211_iftype nlmode; |  	enum nl80211_iftype nlmode; | ||||||
|  	struct i802_bss *bss = priv; |  	struct i802_bss *bss = priv; | ||||||
| @@ -7880,7 +7919,8 @@ static int wpa_driver_nl80211_if_add(voi | @@ -7888,7 +7927,8 @@ static int wpa_driver_nl80211_if_add(voi | ||||||
|  		os_memset(&p2pdev_info, 0, sizeof(p2pdev_info)); |  		os_memset(&p2pdev_info, 0, sizeof(p2pdev_info)); | ||||||
|  		ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, |  		ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, | ||||||
|  					     0, nl80211_wdev_handler, |  					     0, nl80211_wdev_handler, | ||||||
| @@ -447,7 +447,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c | |||||||
|  		if (!p2pdev_info.wdev_id_set || ifidx != 0) { |  		if (!p2pdev_info.wdev_id_set || ifidx != 0) { | ||||||
|  			wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s", |  			wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s", | ||||||
|  				   ifname); |  				   ifname); | ||||||
| @@ -7896,7 +7936,9 @@ static int wpa_driver_nl80211_if_add(voi | @@ -7904,7 +7944,9 @@ static int wpa_driver_nl80211_if_add(voi | ||||||
|  			   (long long unsigned int) p2pdev_info.wdev_id); |  			   (long long unsigned int) p2pdev_info.wdev_id); | ||||||
|  	} else { |  	} else { | ||||||
|  		ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, |  		ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, | ||||||
| @@ -537,7 +537,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c | |||||||
|  #include "utils/includes.h" |  #include "utils/includes.h" | ||||||
|   |   | ||||||
|  #ifndef CONFIG_NATIVE_WINDOWS |  #ifndef CONFIG_NATIVE_WINDOWS | ||||||
| @@ -3859,7 +3860,11 @@ int hostapd_get_aid(struct hostapd_data | @@ -3868,7 +3869,11 @@ int hostapd_get_aid(struct hostapd_data | ||||||
|  	} |  	} | ||||||
|  	if (j == 32) |  	if (j == 32) | ||||||
|  		return -1; |  		return -1; | ||||||
| @@ -550,7 +550,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c | |||||||
|  	if (aid > 2007) |  	if (aid > 2007) | ||||||
|  		return -1; |  		return -1; | ||||||
|   |   | ||||||
| @@ -5560,7 +5565,7 @@ static void handle_assoc(struct hostapd_ | @@ -5569,7 +5574,7 @@ static void handle_assoc(struct hostapd_ | ||||||
|  		goto fail; |  		goto fail; | ||||||
|  	omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX); |  	omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX); | ||||||
|   |   | ||||||
| @@ -559,7 +559,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c | |||||||
|  		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, |  		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, | ||||||
|  			       HOSTAPD_LEVEL_INFO, "No room for more AIDs"); |  			       HOSTAPD_LEVEL_INFO, "No room for more AIDs"); | ||||||
|  		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; |  		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; | ||||||
| @@ -6969,4 +6974,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct | @@ -6981,4 +6986,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct | ||||||
|  	return eid; |  	return eid; | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|  |  | ||||||
| --- a/src/ap/beacon.c | --- a/src/ap/beacon.c | ||||||
| +++ b/src/ap/beacon.c | +++ b/src/ap/beacon.c | ||||||
| @@ -1788,6 +1788,7 @@ int ieee802_11_build_ap_params(struct ho | @@ -1774,6 +1774,7 @@ int ieee802_11_build_ap_params(struct ho | ||||||
|  		if ((params->multiple_bssid_ie_count <= 1) && |  		if ((params->multiple_bssid_ie_count <= 1) && | ||||||
|  		    (ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08)) |  		    (ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08)) | ||||||
|  			ext_cap_pos[12] |= 0x01; |  			ext_cap_pos[12] |= 0x01; | ||||||
| @@ -43,10 +43,10 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|  	return 0; |  	return 0; | ||||||
| --- a/src/ap/hostapd.c | --- a/src/ap/hostapd.c | ||||||
| +++ b/src/ap/hostapd.c | +++ b/src/ap/hostapd.c | ||||||
| @@ -1109,19 +1109,60 @@ static int db_table_create_radius_attrib | @@ -1203,11 +1203,52 @@ static int db_table_create_radius_attrib | ||||||
|   |  | ||||||
|  #endif /* CONFIG_NO_RADIUS */ |  #endif /* CONFIG_NO_RADIUS */ | ||||||
|   |   | ||||||
|  |   | ||||||
| +static int hostapd_set_beacon(struct hostapd_data *hapd) | +static int hostapd_set_beacon(struct hostapd_data *hapd) | ||||||
| +{ | +{ | ||||||
| +	struct hostapd_bss_config *conf = hapd->conf; | +	struct hostapd_bss_config *conf = hapd->conf; | ||||||
| @@ -84,7 +84,7 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
| +	hostapd_ubus_add_bss(hapd); | +	hostapd_ubus_add_bss(hapd); | ||||||
| +	return 0; | +	return 0; | ||||||
| +} | +} | ||||||
|   | +  | ||||||
|  /** |  /** | ||||||
|   * hostapd_setup_bss - Per-BSS setup (initialization) |   * hostapd_setup_bss - Per-BSS setup (initialization) | ||||||
|   * @hapd: Pointer to BSS data |   * @hapd: Pointer to BSS data | ||||||
| @@ -96,16 +96,7 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|   * |   * | ||||||
|   * This function is used to initialize all per-BSS data structures and |   * This function is used to initialize all per-BSS data structures and | ||||||
|   * resources. This gets called in a loop for each BSS when an interface is |   * resources. This gets called in a loop for each BSS when an interface is | ||||||
|   * initialized. Most of the modules that are initialized here will be | @@ -1503,32 +1544,8 @@ int hostapd_setup_bss(struct hostapd_dat | ||||||
|   * deinitialized in hostapd_cleanup(). |  | ||||||
|   */ |  | ||||||
| -static int hostapd_setup_bss(struct hostapd_data *hapd, int first) |  | ||||||
| +static int hostapd_setup_bss(struct hostapd_data *hapd, int first, |  | ||||||
| +			     bool set_beacon) |  | ||||||
|  { |  | ||||||
|  	struct hostapd_bss_config *conf = hapd->conf; |  | ||||||
|  	u8 ssid[SSID_MAX_LEN + 1]; |  | ||||||
| @@ -1393,31 +1434,8 @@ static int hostapd_setup_bss(struct host |  | ||||||
|  		return -1; |  		return -1; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -134,22 +125,23 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
| -		hapd->driver->set_operstate(hapd->drv_priv, 1); | -		hapd->driver->set_operstate(hapd->drv_priv, 1); | ||||||
| - | - | ||||||
| -	hostapd_ubus_add_bss(hapd); | -	hostapd_ubus_add_bss(hapd); | ||||||
|  | -	hostapd_ucode_add_bss(hapd); | ||||||
| +	if (set_beacon) | +	if (set_beacon) | ||||||
| +		return hostapd_set_beacon(hapd); | +		return hostapd_set_beacon(hapd); | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
| @@ -2109,7 +2127,8 @@ static int hostapd_setup_interface_compl | @@ -2223,7 +2240,8 @@ static int hostapd_setup_interface_compl | ||||||
|  		hapd = iface->bss[j]; |  		hapd = iface->bss[j]; | ||||||
|  		if (j) |  		if (j) | ||||||
|  			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); |  			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); | ||||||
| -		if (hostapd_setup_bss(hapd, j == 0)) { | -		if (hostapd_setup_bss(hapd, j == 0, true)) { | ||||||
| +		if (hostapd_setup_bss(hapd, j == 0, | +		if (hostapd_setup_bss(hapd, j == 0, | ||||||
| +				      hapd->iconf->multiple_bssid? 0 : 1)) { | +				      hapd->iconf->multiple_bssid? 0 : 1)) { | ||||||
|  			for (;;) { |  			for (;;) { | ||||||
|  				hapd = iface->bss[j]; |  				hapd = iface->bss[j]; | ||||||
|  				hostapd_bss_deinit_no_free(hapd); |  				hostapd_bss_deinit_no_free(hapd); | ||||||
| @@ -2123,6 +2142,24 @@ static int hostapd_setup_interface_compl | @@ -2237,6 +2255,24 @@ static int hostapd_setup_interface_compl | ||||||
|  		if (is_zero_ether_addr(hapd->conf->bssid)) |  		if (is_zero_ether_addr(hapd->conf->bssid)) | ||||||
|  			prev_addr = hapd->own_addr; |  			prev_addr = hapd->own_addr; | ||||||
|  	} |  	} | ||||||
| @@ -174,18 +166,18 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|  	hapd = iface->bss[0]; |  	hapd = iface->bss[0]; | ||||||
|   |   | ||||||
|  	hostapd_tx_queue_params(iface); |  	hostapd_tx_queue_params(iface); | ||||||
| @@ -2989,7 +3026,7 @@ int hostapd_add_iface(struct hapd_interf | @@ -3123,7 +3159,7 @@ int hostapd_add_iface(struct hapd_interf | ||||||
|   |   | ||||||
|  			if (start_ctrl_iface_bss(hapd) < 0 || |  			if (start_ctrl_iface_bss(hapd) < 0 || | ||||||
|  			    (hapd_iface->state == HAPD_IFACE_ENABLED && |  			    (hapd_iface->state == HAPD_IFACE_ENABLED && | ||||||
| -			     hostapd_setup_bss(hapd, -1))) { | -			     hostapd_setup_bss(hapd, -1, true))) { | ||||||
| +			     hostapd_setup_bss(hapd, -1, 1))) { | +			     hostapd_setup_bss(hapd, -1, 1))) { | ||||||
|  				hostapd_cleanup(hapd); |  				hostapd_cleanup(hapd); | ||||||
|  				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; |  				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; | ||||||
|  				hapd_iface->conf->num_bss--; |  				hapd_iface->conf->num_bss--; | ||||||
| --- a/src/ap/ieee802_11.c | --- a/src/ap/ieee802_11.c | ||||||
| +++ b/src/ap/ieee802_11.c | +++ b/src/ap/ieee802_11.c | ||||||
| @@ -5721,7 +5721,7 @@ int hostapd_eid_multiple_bssid_len(struc | @@ -7036,7 +7036,7 @@ int hostapd_eid_multiple_bssid_len(struc | ||||||
|   |   | ||||||
|  static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd, |  static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd, | ||||||
|  					     u8 *eid, u8 *end, int *count, |  					     u8 *eid, u8 *end, int *count, | ||||||
| @@ -194,7 +186,7 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|  { |  { | ||||||
|  	u8 *size_offset, *num_offset; |  	u8 *size_offset, *num_offset; | ||||||
|  	int i; |  	int i; | ||||||
| @@ -5753,6 +5753,7 @@ static u8 * hostapd_eid_multiple_bssid_c | @@ -7068,6 +7068,7 @@ static u8 * hostapd_eid_multiple_bssid_c | ||||||
|  		index_size_offset = eid++; |  		index_size_offset = eid++; | ||||||
|  		*eid++ = i; |  		*eid++ = i; | ||||||
|  		if (is_beacon) { |  		if (is_beacon) { | ||||||
| @@ -202,7 +194,7 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org> | |||||||
|  			*eid++ = bss->conf->dtim_period; |  			*eid++ = bss->conf->dtim_period; | ||||||
|  			*eid++ = 0xFF; |  			*eid++ = 0xFF; | ||||||
|  		} |  		} | ||||||
| @@ -5783,17 +5784,53 @@ u8 * hostapd_eid_multiple_bssid(struct h | @@ -7098,17 +7099,53 @@ u8 * hostapd_eid_multiple_bssid(struct h | ||||||
|  				u8 is_beacon, u8 **eid_offsets, int *eid_count, |  				u8 is_beacon, u8 **eid_offsets, int *eid_count, | ||||||
|  				int eid_max, u8 ema_beacon) |  				int eid_max, u8 ema_beacon) | ||||||
|  { |  { | ||||||
|   | |||||||
| @@ -29,11 +29,6 @@ static struct ubus_context *ctx; | |||||||
| static struct blob_buf b; | static struct blob_buf b; | ||||||
| static int ctx_ref; | static int ctx_ref; | ||||||
|  |  | ||||||
| static inline struct hapd_interfaces *get_hapd_interfaces_from_object(struct ubus_object *obj) |  | ||||||
| { |  | ||||||
| 	return container_of(obj, struct hapd_interfaces, ubus); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) | static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) | ||||||
| { | { | ||||||
| 	return container_of(obj, struct hostapd_data, ubus.obj); | 	return container_of(obj, struct hostapd_data, ubus.obj); | ||||||
| @@ -44,12 +39,6 @@ struct ubus_banned_client { | |||||||
| 	u8 addr[ETH_ALEN]; | 	u8 addr[ETH_ALEN]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) |  | ||||||
| { |  | ||||||
| 	struct ubus_context *ctx = eloop_ctx; |  | ||||||
| 	ubus_handle_event(ctx); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | ||||||
| { | { | ||||||
| 	if (ubus_reconnect(ctx, NULL)) { | 	if (ubus_reconnect(ctx, NULL)) { | ||||||
| @@ -57,12 +46,12 @@ static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | 	ubus_add_uloop(ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void hostapd_ubus_connection_lost(struct ubus_context *ctx) | static void hostapd_ubus_connection_lost(struct ubus_context *ctx) | ||||||
| { | { | ||||||
| 	eloop_unregister_read_sock(ctx->sock.fd); | 	uloop_fd_delete(&ctx->sock); | ||||||
| 	eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | 	eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -71,12 +60,14 @@ static bool hostapd_ubus_init(void) | |||||||
| 	if (ctx) | 	if (ctx) | ||||||
| 		return true; | 		return true; | ||||||
|  |  | ||||||
|  | 	eloop_add_uloop(); | ||||||
| 	ctx = ubus_connect(NULL); | 	ctx = ubus_connect(NULL); | ||||||
| 	if (!ctx) | 	if (!ctx) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	ctx->connection_lost = hostapd_ubus_connection_lost; | 	ctx->connection_lost = hostapd_ubus_connection_lost; | ||||||
| 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | 	ubus_add_uloop(ctx); | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -94,7 +85,7 @@ static void hostapd_ubus_ref_dec(void) | |||||||
| 	if (ctx_ref) | 	if (ctx_ref) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	eloop_unregister_read_sock(ctx->sock.fd); | 	uloop_fd_delete(&ctx->sock); | ||||||
| 	ubus_free(ctx); | 	ubus_free(ctx); | ||||||
| 	ctx = NULL; | 	ctx = NULL; | ||||||
| } | } | ||||||
| @@ -127,38 +118,6 @@ static void hostapd_notify_ubus(struct ubus_object *obj, char *bssname, char *ev | |||||||
| 	free(event_type); | 	free(event_type); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void hostapd_send_procd_event(char *bssname, char *event) |  | ||||||
| { |  | ||||||
| 	char *name, *s; |  | ||||||
| 	uint32_t id; |  | ||||||
| 	void *v; |  | ||||||
|  |  | ||||||
| 	if (!ctx || ubus_lookup_id(ctx, "service", &id)) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	if (asprintf(&name, "hostapd.%s.%s", bssname, event) < 0) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	blob_buf_init(&b, 0); |  | ||||||
|  |  | ||||||
| 	s = blobmsg_alloc_string_buffer(&b, "type", strlen(name) + 1); |  | ||||||
| 	sprintf(s, "%s", name); |  | ||||||
| 	blobmsg_add_string_buffer(&b); |  | ||||||
|  |  | ||||||
| 	v = blobmsg_open_table(&b, "data"); |  | ||||||
| 	blobmsg_close_table(&b, v); |  | ||||||
|  |  | ||||||
| 	ubus_invoke(ctx, id, "event", b.head, NULL, NULL, 1000); |  | ||||||
|  |  | ||||||
| 	free(name); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void hostapd_send_shared_event(struct ubus_object *obj, char *bssname, char *event) |  | ||||||
| { |  | ||||||
| 	hostapd_send_procd_event(bssname, event); |  | ||||||
| 	hostapd_notify_ubus(obj, bssname, event); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void | static void | ||||||
| hostapd_bss_del_ban(void *eloop_data, void *user_ctx) | hostapd_bss_del_ban(void *eloop_data, void *user_ctx) | ||||||
| { | { | ||||||
| @@ -203,10 +162,8 @@ hostapd_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, | |||||||
| 		   struct blob_attr *msg) | 		   struct blob_attr *msg) | ||||||
| { | { | ||||||
| 	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | 	struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); | ||||||
| 	int ret = hostapd_reload_config(hapd->iface, 1); |  | ||||||
|  |  | ||||||
| 	hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "reload"); | 	return hostapd_reload_config(hapd->iface); | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -693,68 +650,6 @@ enum { | |||||||
| 	__CONFIG_MAX | 	__CONFIG_MAX | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static const struct blobmsg_policy config_add_policy[__CONFIG_MAX] = { |  | ||||||
| 	[CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| hostapd_config_add(struct ubus_context *ctx, struct ubus_object *obj, |  | ||||||
| 		   struct ubus_request_data *req, const char *method, |  | ||||||
| 		   struct blob_attr *msg) |  | ||||||
| { |  | ||||||
| 	struct blob_attr *tb[__CONFIG_MAX]; |  | ||||||
| 	struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); |  | ||||||
| 	char buf[128]; |  | ||||||
|  |  | ||||||
| 	blobmsg_parse(config_add_policy, __CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); |  | ||||||
|  |  | ||||||
| 	if (!tb[CONFIG_FILE] || !tb[CONFIG_IFACE]) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	snprintf(buf, sizeof(buf), "bss_config=%s:%s", |  | ||||||
| 		blobmsg_get_string(tb[CONFIG_IFACE]), |  | ||||||
| 		blobmsg_get_string(tb[CONFIG_FILE])); |  | ||||||
|  |  | ||||||
| 	if (hostapd_add_iface(interfaces, buf)) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	blob_buf_init(&b, 0); |  | ||||||
| 	blobmsg_add_u32(&b, "pid", getpid()); |  | ||||||
| 	ubus_send_reply(ctx, req, b.head); |  | ||||||
|  |  | ||||||
| 	return UBUS_STATUS_OK; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| enum { |  | ||||||
| 	CONFIG_REM_IFACE, |  | ||||||
| 	__CONFIG_REM_MAX |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct blobmsg_policy config_remove_policy[__CONFIG_REM_MAX] = { |  | ||||||
| 	[CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| hostapd_config_remove(struct ubus_context *ctx, struct ubus_object *obj, |  | ||||||
| 		      struct ubus_request_data *req, const char *method, |  | ||||||
| 		      struct blob_attr *msg) |  | ||||||
| { |  | ||||||
| 	struct blob_attr *tb[__CONFIG_REM_MAX]; |  | ||||||
| 	struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); |  | ||||||
| 	char buf[128]; |  | ||||||
|  |  | ||||||
| 	blobmsg_parse(config_remove_policy, __CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); |  | ||||||
|  |  | ||||||
| 	if (!tb[CONFIG_REM_IFACE]) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	if (hostapd_remove_iface(interfaces, blobmsg_get_string(tb[CONFIG_REM_IFACE]))) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	return UBUS_STATUS_OK; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| enum { | enum { | ||||||
| 	CSA_FREQ, | 	CSA_FREQ, | ||||||
| 	CSA_BCN_COUNT, | 	CSA_BCN_COUNT, | ||||||
| @@ -1622,8 +1517,6 @@ void hostapd_ubus_add_bss(struct hostapd_data *hapd) | |||||||
| 	obj->n_methods = bss_object_type.n_methods; | 	obj->n_methods = bss_object_type.n_methods; | ||||||
| 	ret = ubus_add_object(ctx, obj); | 	ret = ubus_add_object(ctx, obj); | ||||||
| 	hostapd_ubus_ref_inc(); | 	hostapd_ubus_ref_inc(); | ||||||
|  |  | ||||||
| 	hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "add"); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void hostapd_ubus_free_bss(struct hostapd_data *hapd) | void hostapd_ubus_free_bss(struct hostapd_data *hapd) | ||||||
| @@ -1639,8 +1532,6 @@ void hostapd_ubus_free_bss(struct hostapd_data *hapd) | |||||||
| 	if (!ctx) | 	if (!ctx) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "remove"); |  | ||||||
|  |  | ||||||
| 	if (obj->id) { | 	if (obj->id) { | ||||||
| 		ubus_remove_object(ctx, obj); | 		ubus_remove_object(ctx, obj); | ||||||
| 		hostapd_ubus_ref_dec(); | 		hostapd_ubus_ref_dec(); | ||||||
| @@ -1686,47 +1577,6 @@ void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vl | |||||||
| 	hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); | 	hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static const struct ubus_method daemon_methods[] = { |  | ||||||
| 	UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), |  | ||||||
| 	UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct ubus_object_type daemon_object_type = |  | ||||||
| 	UBUS_OBJECT_TYPE("hostapd", daemon_methods); |  | ||||||
|  |  | ||||||
| void hostapd_ubus_add(struct hapd_interfaces *interfaces) |  | ||||||
| { |  | ||||||
| 	struct ubus_object *obj = &interfaces->ubus; |  | ||||||
| 	int ret; |  | ||||||
|  |  | ||||||
| 	if (!hostapd_ubus_init()) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	obj->name = strdup("hostapd"); |  | ||||||
|  |  | ||||||
| 	obj->type = &daemon_object_type; |  | ||||||
| 	obj->methods = daemon_object_type.methods; |  | ||||||
| 	obj->n_methods = daemon_object_type.n_methods; |  | ||||||
| 	ret = ubus_add_object(ctx, obj); |  | ||||||
| 	hostapd_ubus_ref_inc(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void hostapd_ubus_free(struct hapd_interfaces *interfaces) |  | ||||||
| { |  | ||||||
| 	struct ubus_object *obj = &interfaces->ubus; |  | ||||||
| 	char *name = (char *) obj->name; |  | ||||||
|  |  | ||||||
| 	if (!ctx) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	if (obj->id) { |  | ||||||
| 		ubus_remove_object(ctx, obj); |  | ||||||
| 		hostapd_ubus_ref_dec(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	free(name); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct ubus_event_req { | struct ubus_event_req { | ||||||
| 	struct ubus_notify_request nreq; | 	struct ubus_notify_request nreq; | ||||||
| 	int resp; | 	int resp; | ||||||
|   | |||||||
							
								
								
									
										544
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										544
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,544 @@ | |||||||
|  | #include <sys/un.h> | ||||||
|  |  | ||||||
|  | #include "utils/includes.h" | ||||||
|  | #include "utils/common.h" | ||||||
|  | #include "utils/ucode.h" | ||||||
|  | #include "hostapd.h" | ||||||
|  | #include "beacon.h" | ||||||
|  | #include "hw_features.h" | ||||||
|  | #include "ap_drv_ops.h" | ||||||
|  | #include <libubox/uloop.h> | ||||||
|  |  | ||||||
|  | static uc_resource_type_t *global_type, *bss_type, *iface_type; | ||||||
|  | static struct hapd_interfaces *interfaces; | ||||||
|  | static uc_value_t *global, *bss_registry, *iface_registry; | ||||||
|  | static uc_vm_t *vm; | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | hostapd_ucode_bss_get_uval(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (hapd->ucode.idx) | ||||||
|  | 		return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx); | ||||||
|  |  | ||||||
|  | 	val = uc_resource_new(bss_type, hapd); | ||||||
|  | 	hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val); | ||||||
|  |  | ||||||
|  | 	return val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (hapd->ucode.idx) | ||||||
|  | 		return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx); | ||||||
|  |  | ||||||
|  | 	val = uc_resource_new(iface_type, hapd); | ||||||
|  | 	hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val); | ||||||
|  |  | ||||||
|  | 	return val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss) | ||||||
|  | { | ||||||
|  | 	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); | ||||||
|  |  | ||||||
|  | 		ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface))); | ||||||
|  | 		ucv_object_add(bss, hapd->conf->iface, ucv_get(val)); | ||||||
|  | 	} | ||||||
|  | 	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, 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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_add_iface(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	uc_value_t *iface = uc_fn_arg(0); | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(iface) != UC_STRING) | ||||||
|  | 		return ucv_int64_new(-1); | ||||||
|  |  | ||||||
|  | 	ret = hostapd_add_iface(interfaces, ucv_string_get(iface)); | ||||||
|  | 	hostapd_ucode_update_interfaces(); | ||||||
|  |  | ||||||
|  | 	return ucv_int64_new(ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_remove_iface(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	uc_value_t *iface = uc_fn_arg(0); | ||||||
|  |  | ||||||
|  | 	if (ucv_type(iface) != UC_STRING) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	hostapd_remove_iface(interfaces, ucv_string_get(iface)); | ||||||
|  | 	hostapd_ucode_update_interfaces(); | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); | ||||||
|  | 	struct hostapd_bss_config *old_bss; | ||||||
|  | 	struct hostapd_iface *iface; | ||||||
|  | 	struct hostapd_config *conf; | ||||||
|  | 	uc_value_t *file = uc_fn_arg(0); | ||||||
|  | 	uc_value_t *index = uc_fn_arg(1); | ||||||
|  | 	unsigned int i, idx = 0; | ||||||
|  | 	int ret = -1; | ||||||
|  |  | ||||||
|  | 	if (!hapd || ucv_type(file) != UC_STRING) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(index) == UC_INTEGER) | ||||||
|  | 		idx = ucv_int64_get(index); | ||||||
|  |  | ||||||
|  | 	iface = hapd->iface; | ||||||
|  | 	conf = interfaces->config_read_cb(ucv_string_get(file)); | ||||||
|  | 	if (!conf || idx > conf->num_bss || !conf->bss[idx]) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	hostapd_bss_deinit_no_free(hapd); | ||||||
|  | 	hostapd_drv_stop_ap(hapd); | ||||||
|  | 	hostapd_free_hapd_data(hapd); | ||||||
|  |  | ||||||
|  | 	old_bss = hapd->conf; | ||||||
|  | 	for (i = 0; i < iface->conf->num_bss; i++) | ||||||
|  | 		if (iface->conf->bss[i] == hapd->conf) | ||||||
|  | 			iface->conf->bss[i] = conf->bss[idx]; | ||||||
|  | 	hapd->conf = conf->bss[idx]; | ||||||
|  | 	conf->bss[idx] = old_bss; | ||||||
|  | 	hostapd_config_free(conf); | ||||||
|  |  | ||||||
|  | 	hostapd_setup_bss(hapd, hapd == iface->bss[0], !iface->conf->multiple_bssid); | ||||||
|  |  | ||||||
|  | 	ret = 0; | ||||||
|  |  | ||||||
|  | out: | ||||||
|  | 	return ucv_int64_new(ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | hostapd_remove_iface_bss_conf(struct hostapd_config *iconf, | ||||||
|  | 			      struct hostapd_bss_config *conf) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < iconf->num_bss; i++) | ||||||
|  | 		if (iconf->bss[i] == conf) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 	if (i == iconf->num_bss) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	for (i++; i < iconf->num_bss; i++) | ||||||
|  | 		iconf->bss[i - 1] = iconf->bss[i]; | ||||||
|  | 	iconf->num_bss--; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); | ||||||
|  | 	struct hostapd_iface *iface; | ||||||
|  | 	int i, idx; | ||||||
|  |  | ||||||
|  | 	if (!hapd || hapd == hapd->iface->bss[0]) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	iface = hapd->iface; | ||||||
|  | 	for (idx = 0; idx < iface->num_bss; idx++) | ||||||
|  | 		if (iface->bss[idx] == hapd) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 	if (idx == iface->num_bss) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	for (i = idx + 1; i < iface->num_bss; i++) | ||||||
|  | 		iface->bss[i - 1] = iface->bss[i]; | ||||||
|  | 	iface->num_bss--; | ||||||
|  |  | ||||||
|  | 	hostapd_drv_stop_ap(hapd); | ||||||
|  | 	hostapd_bss_deinit(hapd); | ||||||
|  | 	hostapd_remove_iface_bss_conf(iface->conf, hapd->conf); | ||||||
|  | 	hostapd_config_free_bss(hapd->conf); | ||||||
|  | 	os_free(hapd); | ||||||
|  |  | ||||||
|  | 	hostapd_ucode_update_interfaces(); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); | ||||||
|  | 	struct hostapd_bss_config *bss; | ||||||
|  | 	struct hostapd_config *conf; | ||||||
|  | 	struct hostapd_data *hapd; | ||||||
|  | 	uc_value_t *file = uc_fn_arg(0); | ||||||
|  | 	uc_value_t *index = uc_fn_arg(1); | ||||||
|  | 	unsigned int idx = 0; | ||||||
|  | 	uc_value_t *ret = NULL; | ||||||
|  |  | ||||||
|  | 	if (!iface || ucv_type(file) != UC_STRING) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(index) == UC_INTEGER) | ||||||
|  | 		idx = ucv_int64_get(index); | ||||||
|  |  | ||||||
|  | 	conf = interfaces->config_read_cb(ucv_string_get(file)); | ||||||
|  | 	if (!conf || idx > conf->num_bss || !conf->bss[idx]) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	bss = conf->bss[idx]; | ||||||
|  | 	hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); | ||||||
|  | 	if (!hapd) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	hapd->driver = iface->bss[0]->driver; | ||||||
|  | 	hapd->drv_priv = iface->bss[0]->drv_priv; | ||||||
|  | 	if (interfaces->ctrl_iface_init && | ||||||
|  | 	    interfaces->ctrl_iface_init(hapd) < 0) | ||||||
|  | 		goto free_hapd; | ||||||
|  |  | ||||||
|  | 	if (iface->state == HAPD_IFACE_ENABLED && | ||||||
|  | 	    hostapd_setup_bss(hapd, -1, true)) | ||||||
|  | 		goto deinit_ctrl; | ||||||
|  |  | ||||||
|  | 	iface->bss = os_realloc_array(iface->bss, iface->num_bss + 1, | ||||||
|  | 				      sizeof(*iface->bss)); | ||||||
|  | 	iface->bss[iface->num_bss++] = hapd; | ||||||
|  |  | ||||||
|  | 	iface->conf->bss = os_realloc_array(iface->conf->bss, | ||||||
|  | 					    iface->conf->num_bss + 1, | ||||||
|  | 					    sizeof(*iface->conf->bss)); | ||||||
|  | 	iface->conf->bss[iface->conf->num_bss] = bss; | ||||||
|  | 	conf->bss[idx] = NULL; | ||||||
|  | 	ret = hostapd_ucode_bss_get_uval(hapd); | ||||||
|  | 	hostapd_ucode_update_interfaces(); | ||||||
|  | 	goto out; | ||||||
|  |  | ||||||
|  | deinit_ctrl: | ||||||
|  | 	if (interfaces->ctrl_iface_deinit) | ||||||
|  | 		interfaces->ctrl_iface_deinit(hapd); | ||||||
|  | free_hapd: | ||||||
|  | 	hostapd_free_hapd_data(hapd); | ||||||
|  | 	os_free(hapd); | ||||||
|  | out: | ||||||
|  | 	hostapd_config_free(conf); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); | ||||||
|  | 	uc_value_t *arg = uc_fn_arg(0); | ||||||
|  | 	struct sockaddr_storage from = {}; | ||||||
|  | 	static char reply[4096]; | ||||||
|  | 	int reply_len; | ||||||
|  |  | ||||||
|  | 	if (!hapd || !interfaces->ctrl_iface_recv || | ||||||
|  | 	    ucv_type(arg) != UC_STRING) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	reply_len = interfaces->ctrl_iface_recv(hapd, ucv_string_get(arg), | ||||||
|  | 						reply, sizeof(reply), | ||||||
|  | 						&from, sizeof(from)); | ||||||
|  | 	if (reply_len < 0) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	if (reply_len && reply[reply_len - 1] == '\n') | ||||||
|  | 		reply_len--; | ||||||
|  |  | ||||||
|  | 	return ucv_string_new_length(reply, reply_len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < iface->num_bss; i++) { | ||||||
|  | 		struct hostapd_data *hapd = iface->bss[i]; | ||||||
|  |  | ||||||
|  | 		hostapd_drv_stop_ap(hapd); | ||||||
|  | 		hapd->started = 0; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); | ||||||
|  | 	uc_value_t *info = uc_fn_arg(0); | ||||||
|  | 	struct hostapd_config *conf; | ||||||
|  | 	uint64_t intval; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	if (!iface) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	if (!info) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(info) != UC_OBJECT) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	conf = iface->conf; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) &&	!errno) | ||||||
|  | 		conf->op_class = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno) | ||||||
|  | 		conf->hw_mode = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno) | ||||||
|  | 		conf->channel = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) | ||||||
|  | 		conf->secondary_channel = intval; | ||||||
|  | #ifdef CONFIG_IEEE80211AC | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL))) && !errno) { | ||||||
|  | 		conf->vht_oper_centr_freq_seg0_idx = intval; | ||||||
|  | #ifdef CONFIG_IEEE80211AX | ||||||
|  | 		conf->he_oper_centr_freq_seg0_idx = intval; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_IEEE80211BE | ||||||
|  | 		conf->eht_oper_centr_freq_seg0_idx = intval; | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg1_idx", NULL))) && !errno) { | ||||||
|  | 		conf->vht_oper_centr_freq_seg1_idx = intval; | ||||||
|  | #ifdef CONFIG_IEEE80211AX | ||||||
|  | 		conf->he_oper_centr_freq_seg1_idx = intval; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_IEEE80211BE | ||||||
|  | 		conf->eht_oper_centr_freq_seg1_idx = intval; | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | 	intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); | ||||||
|  | 	if (!errno) { | ||||||
|  | 		conf->vht_oper_chwidth = intval; | ||||||
|  | #ifdef CONFIG_IEEE80211AX | ||||||
|  | 		conf->he_oper_chwidth = intval; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_IEEE80211BE | ||||||
|  | 		conf->eht_oper_chwidth = intval; | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | out: | ||||||
|  | 	if (conf->channel) | ||||||
|  | 		iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel); | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < iface->num_bss; i++) { | ||||||
|  | 		struct hostapd_data *hapd = iface->bss[i]; | ||||||
|  | 		int ret; | ||||||
|  |  | ||||||
|  | 		hapd->started = 1; | ||||||
|  | 		hostapd_set_freq(hapd, conf->hw_mode, iface->freq, | ||||||
|  | 				 conf->channel, | ||||||
|  | 				 conf->enable_edmg, | ||||||
|  | 				 conf->edmg_channel, | ||||||
|  | 				 conf->ieee80211n, | ||||||
|  | 				 conf->ieee80211ac, | ||||||
|  | 				 conf->ieee80211ax, | ||||||
|  | 				 conf->secondary_channel, | ||||||
|  | 				 hostapd_get_oper_chwidth(conf), | ||||||
|  | 				 hostapd_get_oper_centr_freq_seg0_idx(conf), | ||||||
|  | 				 hostapd_get_oper_centr_freq_seg1_idx(conf)); | ||||||
|  |  | ||||||
|  | 		ieee802_11_set_beacon(hapd); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return ucv_boolean_new(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); | ||||||
|  | 	uc_value_t *info = uc_fn_arg(0); | ||||||
|  | 	struct hostapd_config *conf; | ||||||
|  | 	struct csa_settings csa = {}; | ||||||
|  | 	uint64_t intval; | ||||||
|  | 	int i, ret = 0; | ||||||
|  |  | ||||||
|  | 	if (!iface || ucv_type(info) != UC_OBJECT) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	conf = iface->conf; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "csa_count", NULL))) && !errno) | ||||||
|  | 		csa.cs_count = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) | ||||||
|  | 		csa.freq_params.sec_channel_offset = intval; | ||||||
|  |  | ||||||
|  | 	csa.freq_params.ht_enabled = conf->ieee80211n; | ||||||
|  | 	csa.freq_params.vht_enabled = conf->ieee80211ac; | ||||||
|  | 	csa.freq_params.he_enabled = conf->ieee80211ax; | ||||||
|  | #ifdef CONFIG_IEEE80211BE | ||||||
|  | 	csa.freq_params.eht_enabled = conf->ieee80211be; | ||||||
|  | #endif | ||||||
|  | 	intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); | ||||||
|  | 	if (errno) | ||||||
|  | 		intval = hostapd_get_oper_chwidth(conf); | ||||||
|  | 	if (intval) | ||||||
|  | 		csa.freq_params.bandwidth = 40 << intval; | ||||||
|  | 	else | ||||||
|  | 		csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20; | ||||||
|  |  | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL))) && !errno) | ||||||
|  | 		csa.freq_params.freq = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq1", NULL))) && !errno) | ||||||
|  | 		csa.freq_params.center_freq1 = intval; | ||||||
|  | 	if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno) | ||||||
|  | 		csa.freq_params.center_freq2 = intval; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < iface->num_bss; i++) | ||||||
|  | 		ret = hostapd_switch_channel(iface->bss[i], &csa); | ||||||
|  |  | ||||||
|  | 	return ucv_boolean_new(!ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int hostapd_ucode_init(struct hapd_interfaces *ifaces) | ||||||
|  | { | ||||||
|  | 	static const uc_function_list_t global_fns[] = { | ||||||
|  | 		{ "printf",	uc_wpa_printf }, | ||||||
|  | 		{ "getpid", uc_wpa_getpid }, | ||||||
|  | 		{ "sha1", uc_wpa_sha1 }, | ||||||
|  | 		{ "freq_info", uc_wpa_freq_info }, | ||||||
|  | 		{ "add_iface", uc_hostapd_add_iface }, | ||||||
|  | 		{ "remove_iface", uc_hostapd_remove_iface }, | ||||||
|  | 	}; | ||||||
|  | 	static const uc_function_list_t bss_fns[] = { | ||||||
|  | 		{ "ctrl", uc_hostapd_bss_ctrl }, | ||||||
|  | 		{ "set_config", uc_hostapd_bss_set_config }, | ||||||
|  | 		{ "delete", uc_hostapd_bss_delete }, | ||||||
|  | 	}; | ||||||
|  | 	static const uc_function_list_t iface_fns[] = { | ||||||
|  | 		{ "add_bss", uc_hostapd_iface_add_bss }, | ||||||
|  | 		{ "stop", uc_hostapd_iface_stop }, | ||||||
|  | 		{ "start", uc_hostapd_iface_start }, | ||||||
|  | 		{ "switch_channel", uc_hostapd_iface_switch_channel }, | ||||||
|  | 	}; | ||||||
|  | 	uc_value_t *data, *proto; | ||||||
|  |  | ||||||
|  | 	interfaces = ifaces; | ||||||
|  | 	vm = wpa_ucode_create_vm(); | ||||||
|  |  | ||||||
|  | 	global_type = uc_type_declare(vm, "hostapd.global", global_fns, NULL); | ||||||
|  | 	bss_type = uc_type_declare(vm, "hostapd.bss", bss_fns, NULL); | ||||||
|  | 	iface_type = uc_type_declare(vm, "hostapd.iface", iface_fns, NULL); | ||||||
|  |  | ||||||
|  | 	bss_registry = ucv_array_new(vm); | ||||||
|  | 	uc_vm_registry_set(vm, "hostap.bss_registry", bss_registry); | ||||||
|  |  | ||||||
|  | 	iface_registry = ucv_array_new(vm); | ||||||
|  | 	uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry); | ||||||
|  |  | ||||||
|  | 	global = wpa_ucode_global_init("hostapd", global_type); | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_run(HOSTAPD_UC_PATH "hostapd.uc")) | ||||||
|  | 		goto free_vm; | ||||||
|  | 	ucv_gc(vm); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | free_vm: | ||||||
|  | 	wpa_ucode_free_vm(); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hostapd_ucode_free(void) | ||||||
|  | { | ||||||
|  | 	if (wpa_ucode_call_prepare("shutdown") == 0) | ||||||
|  | 		ucv_put(wpa_ucode_call(0)); | ||||||
|  | 	wpa_ucode_free_vm(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hostapd_ucode_free_iface(struct hostapd_iface *iface) | ||||||
|  | { | ||||||
|  | 	wpa_ucode_registry_remove(iface_registry, iface->ucode.idx); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hostapd_ucode_add_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_call_prepare("bss_add")) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	val = hostapd_ucode_bss_get_uval(hapd); | ||||||
|  | 	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); | ||||||
|  | 	uc_value_push(ucv_get(val)); | ||||||
|  | 	ucv_put(wpa_ucode_call(2)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hostapd_ucode_reload_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_call_prepare("bss_reload")) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	val = hostapd_ucode_bss_get_uval(hapd); | ||||||
|  | 	uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); | ||||||
|  | 	uc_value_push(ucv_get(val)); | ||||||
|  | 	ucv_put(wpa_ucode_call(2)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hostapd_ucode_free_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	val = wpa_ucode_registry_remove(bss_registry, hapd->ucode.idx); | ||||||
|  | 	if (!val) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	hapd->ucode.idx = 0; | ||||||
|  | 	if (wpa_ucode_call_prepare("bss_remove")) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	uc_value_push(ucv_string_new(hapd->conf->iface)); | ||||||
|  | 	uc_value_push(ucv_get(val)); | ||||||
|  | 	ucv_put(wpa_ucode_call(2)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | #ifndef __HOSTAPD_AP_UCODE_H | ||||||
|  | #define __HOSTAPD_AP_UCODE_H | ||||||
|  |  | ||||||
|  | #include "utils/ucode.h" | ||||||
|  |  | ||||||
|  | struct hostapd_data; | ||||||
|  |  | ||||||
|  | struct hostapd_ucode_bss { | ||||||
|  | #ifdef UCODE_SUPPORT | ||||||
|  | 	int idx; | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct hostapd_ucode_iface { | ||||||
|  | #ifdef UCODE_SUPPORT | ||||||
|  | 	int idx; | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #ifdef UCODE_SUPPORT | ||||||
|  |  | ||||||
|  | int hostapd_ucode_init(struct hapd_interfaces *ifaces); | ||||||
|  |  | ||||||
|  | void hostapd_ucode_free(void); | ||||||
|  | void hostapd_ucode_free_iface(struct hostapd_iface *iface); | ||||||
|  | void hostapd_ucode_add_bss(struct hostapd_data *hapd); | ||||||
|  | void hostapd_ucode_free_bss(struct hostapd_data *hapd); | ||||||
|  | void hostapd_ucode_reload_bss(struct hostapd_data *hapd); | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | static inline int hostapd_ucode_init(struct hapd_interfaces *ifaces) | ||||||
|  | { | ||||||
|  | 	return -EINVAL; | ||||||
|  | } | ||||||
|  | static inline void hostapd_ucode_free(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | static inline void hostapd_ucode_free_iface(struct hostapd_iface *iface) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -7,10 +7,6 @@ static inline int has_feature(const char *feat) | |||||||
| 	if (!strcmp(feat, "eap")) | 	if (!strcmp(feat, "eap")) | ||||||
| 		return 1; | 		return 1; | ||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_IEEE80211N |  | ||||||
| 	if (!strcmp(feat, "11n")) |  | ||||||
| 		return 1; |  | ||||||
| #endif |  | ||||||
| #ifdef CONFIG_IEEE80211AC | #ifdef CONFIG_IEEE80211AC | ||||||
| 	if (!strcmp(feat, "11ac")) | 	if (!strcmp(feat, "11ac")) | ||||||
| 		return 1; | 		return 1; | ||||||
| @@ -50,6 +46,18 @@ static inline int has_feature(const char *feat) | |||||||
| #ifdef CONFIG_WPS | #ifdef CONFIG_WPS | ||||||
| 	if (!strcmp(feat, "wps")) | 	if (!strcmp(feat, "wps")) | ||||||
| 		return 1; | 		return 1; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_FILS | ||||||
|  | 	if (!strcmp(feat, "fils")) | ||||||
|  | 		return 1; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_OCV | ||||||
|  | 	if (!strcmp(feat, "ocv")) | ||||||
|  | 		return 1; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_MESH | ||||||
|  | 	if (!strcmp(feat, "mesh")) | ||||||
|  | 		return 1; | ||||||
| #endif | #endif | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										326
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | |||||||
|  | #include <unistd.h> | ||||||
|  | #include "ucode.h" | ||||||
|  | #include "utils/eloop.h" | ||||||
|  | #include "crypto/crypto.h" | ||||||
|  | #include "crypto/sha1.h" | ||||||
|  | #include "common/ieee802_11_common.h" | ||||||
|  | #include <libubox/uloop.h> | ||||||
|  | #include <ucode/compiler.h> | ||||||
|  |  | ||||||
|  | static uc_value_t *registry; | ||||||
|  | static uc_vm_t vm; | ||||||
|  | static struct uloop_timeout gc_timer; | ||||||
|  |  | ||||||
|  | static void uc_gc_timer(struct uloop_timeout *timeout) | ||||||
|  | { | ||||||
|  | 	ucv_gc(&vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	uc_value_t *level = uc_fn_arg(0); | ||||||
|  | 	uc_value_t *ret, **args; | ||||||
|  | 	uc_cfn_ptr_t _sprintf; | ||||||
|  | 	int l = MSG_INFO; | ||||||
|  | 	int i, start = 0; | ||||||
|  |  | ||||||
|  | 	_sprintf = uc_stdlib_function("sprintf"); | ||||||
|  | 	if (!sprintf) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(level) == UC_INTEGER) { | ||||||
|  | 		l = ucv_int64_get(level); | ||||||
|  | 		start++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (nargs <= start) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	ret = _sprintf(vm, nargs - start); | ||||||
|  | 	if (ucv_type(ret) != UC_STRING) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	wpa_printf(l, "%s", ucv_string_get(ret)); | ||||||
|  | 	ucv_put(ret); | ||||||
|  |  | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	uc_value_t *freq = uc_fn_arg(0); | ||||||
|  | 	uc_value_t *sec = uc_fn_arg(1); | ||||||
|  | 	int width = ucv_uint64_get(uc_fn_arg(2)); | ||||||
|  | 	int freq_val, center_idx, center_ofs; | ||||||
|  | 	enum hostapd_hw_mode hw_mode; | ||||||
|  | 	u8 op_class, channel, tmp_channel; | ||||||
|  | 	const char *modestr; | ||||||
|  | 	int sec_channel = 0; | ||||||
|  | 	uc_value_t *ret; | ||||||
|  | 	int chanwidth; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(freq) != UC_INTEGER) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	freq_val = ucv_int64_get(freq); | ||||||
|  | 	if (ucv_type(sec) == UC_INTEGER) | ||||||
|  | 		sec_channel = ucv_int64_get(sec); | ||||||
|  | 	else if (sec) | ||||||
|  | 		return NULL; | ||||||
|  | 	else if (freq_val > 4000) | ||||||
|  | 		sec_channel = (freq_val / 20) & 1 ? 1 : -1; | ||||||
|  | 	else | ||||||
|  | 		sec_channel = freq_val < 2442 ? 1 : -1; | ||||||
|  |  | ||||||
|  | 	if (sec_channel != -1 && sec_channel != 1 && sec_channel != 0) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	switch (width) { | ||||||
|  | 	case 0: | ||||||
|  | 		chanwidth = CHANWIDTH_USE_HT; | ||||||
|  | 		break; | ||||||
|  | 	case 1: | ||||||
|  | 		chanwidth = CHANWIDTH_80MHZ; | ||||||
|  | 		break; | ||||||
|  | 	case 2: | ||||||
|  | 		chanwidth = CHANWIDTH_160MHZ; | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	hw_mode = ieee80211_freq_to_channel_ext(freq_val, sec_channel, | ||||||
|  | 						chanwidth, &op_class, &channel); | ||||||
|  | 	switch (hw_mode) { | ||||||
|  | 	case HOSTAPD_MODE_IEEE80211B: | ||||||
|  | 		modestr = "b"; | ||||||
|  | 		break; | ||||||
|  | 	case HOSTAPD_MODE_IEEE80211G: | ||||||
|  | 		modestr = "g"; | ||||||
|  | 		break; | ||||||
|  | 	case HOSTAPD_MODE_IEEE80211A: | ||||||
|  | 		modestr = "a"; | ||||||
|  | 		break; | ||||||
|  | 	case HOSTAPD_MODE_IEEE80211AD: | ||||||
|  | 		modestr = "ad"; | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ret = ucv_object_new(vm); | ||||||
|  | 	ucv_object_add(ret, "op_class", ucv_int64_new(op_class)); | ||||||
|  | 	ucv_object_add(ret, "channel", ucv_int64_new(channel)); | ||||||
|  | 	ucv_object_add(ret, "hw_mode", ucv_int64_new(hw_mode)); | ||||||
|  | 	ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr))); | ||||||
|  | 	ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel)); | ||||||
|  | 	ucv_object_add(ret, "frequency", ucv_int64_new(freq_val)); | ||||||
|  |  | ||||||
|  | 	if (!sec_channel) | ||||||
|  | 		return ret; | ||||||
|  |  | ||||||
|  | 	if (freq_val >= 5900) | ||||||
|  | 		center_ofs = 0; | ||||||
|  | 	else if (freq_val >= 5745) | ||||||
|  | 		center_ofs = 20; | ||||||
|  | 	else | ||||||
|  | 		center_ofs = 35; | ||||||
|  | 	tmp_channel = channel - center_ofs; | ||||||
|  | 	tmp_channel &= ~((8 << width) - 1); | ||||||
|  | 	center_idx = tmp_channel + center_ofs + (4 << width) - 1; | ||||||
|  |  | ||||||
|  | 	ucv_object_add(ret, "center_seg0_idx", ucv_int64_new(center_idx)); | ||||||
|  | 	center_idx = (center_idx - channel) * 5 + freq_val; | ||||||
|  | 	ucv_object_add(ret, "center_freq1", ucv_int64_new(center_idx)); | ||||||
|  |  | ||||||
|  | out: | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	return ucv_int64_new(getpid()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	u8 hash[SHA1_MAC_LEN]; | ||||||
|  | 	char hash_hex[2 * ARRAY_SIZE(hash) + 1]; | ||||||
|  | 	uc_value_t *val; | ||||||
|  | 	size_t *lens; | ||||||
|  | 	const u8 **args; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	if (!nargs) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	args = alloca(nargs * sizeof(*args)); | ||||||
|  | 	lens = alloca(nargs * sizeof(*lens)); | ||||||
|  | 	for (i = 0; i < nargs; i++) { | ||||||
|  | 		val = uc_fn_arg(i); | ||||||
|  | 		if (ucv_type(val) != UC_STRING) | ||||||
|  | 			return NULL; | ||||||
|  |  | ||||||
|  | 		args[i] = ucv_string_get(val); | ||||||
|  | 		lens[i] = ucv_string_length(val); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (sha1_vector(nargs, args, lens, hash)) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < ARRAY_SIZE(hash); i++) | ||||||
|  | 		sprintf(hash_hex + 2 * i, "%02x", hash[i]); | ||||||
|  |  | ||||||
|  | 	return ucv_string_new_length(hash_hex, 2 * ARRAY_SIZE(hash)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_vm_t *wpa_ucode_create_vm(void) | ||||||
|  | { | ||||||
|  | 	static uc_parse_config_t config = { | ||||||
|  | 		.strict_declarations = true, | ||||||
|  | 		.lstrip_blocks = true, | ||||||
|  | 		.trim_blocks = true, | ||||||
|  | 		.raw_mode = true | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	uc_search_path_init(&config.module_search_path); | ||||||
|  | 	uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.so"); | ||||||
|  | 	uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.uc"); | ||||||
|  |  | ||||||
|  | 	uc_vm_init(&vm, &config); | ||||||
|  |  | ||||||
|  | 	uc_stdlib_load(uc_vm_scope_get(&vm)); | ||||||
|  | 	eloop_add_uloop(); | ||||||
|  | 	gc_timer.cb = uc_gc_timer; | ||||||
|  |  | ||||||
|  | 	return &vm; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int wpa_ucode_run(const char *script) | ||||||
|  | { | ||||||
|  | 	uc_source_t *source; | ||||||
|  | 	uc_program_t *prog; | ||||||
|  | 	uc_value_t *ops; | ||||||
|  | 	char *err; | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	source = uc_source_new_file(script); | ||||||
|  | 	if (!source) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	prog = uc_compile(vm.config, source, &err); | ||||||
|  | 	uc_source_put(source); | ||||||
|  | 	if (!prog) { | ||||||
|  | 		wpa_printf(MSG_ERROR, "Error loading ucode: %s\n", err); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ret = uc_vm_execute(&vm, prog, &ops); | ||||||
|  | 	uc_program_put(prog); | ||||||
|  | 	if (ret || !ops) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	registry = ucv_array_new(&vm); | ||||||
|  | 	uc_vm_registry_set(&vm, "hostap.registry", registry); | ||||||
|  | 	ucv_array_set(registry, 0, ucv_get(ops)); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int wpa_ucode_call_prepare(const char *fname) | ||||||
|  | { | ||||||
|  | 	uc_value_t *obj, *func; | ||||||
|  |  | ||||||
|  | 	if (!registry) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	obj = ucv_array_get(registry, 0); | ||||||
|  | 	if (!obj) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	func = ucv_object_get(obj, fname, NULL); | ||||||
|  | 	if (!ucv_is_callable(func)) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	uc_vm_stack_push(&vm, ucv_get(obj)); | ||||||
|  | 	uc_vm_stack_push(&vm, ucv_get(func)); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type) | ||||||
|  | { | ||||||
|  | 	uc_value_t *global = uc_resource_new(global_type, NULL); | ||||||
|  | 	uc_value_t *proto; | ||||||
|  |  | ||||||
|  | 	uc_vm_registry_set(&vm, "hostap.global", global); | ||||||
|  | 	proto = ucv_prototype_get(global); | ||||||
|  | 	ucv_object_add(proto, "data", ucv_get(ucv_object_new(&vm))); | ||||||
|  |  | ||||||
|  | #define ADD_CONST(x) ucv_object_add(proto, #x, ucv_int64_new(x)) | ||||||
|  | 	ADD_CONST(MSG_EXCESSIVE); | ||||||
|  | 	ADD_CONST(MSG_MSGDUMP); | ||||||
|  | 	ADD_CONST(MSG_DEBUG); | ||||||
|  | 	ADD_CONST(MSG_INFO); | ||||||
|  | 	ADD_CONST(MSG_WARNING); | ||||||
|  | 	ADD_CONST(MSG_ERROR); | ||||||
|  | #undef ADD_CONST | ||||||
|  |  | ||||||
|  | 	ucv_object_add(uc_vm_scope_get(&vm), name, ucv_get(global)); | ||||||
|  |  | ||||||
|  | 	return global; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val) | ||||||
|  | { | ||||||
|  | 	uc_value_t *data; | ||||||
|  | 	int i = 0; | ||||||
|  |  | ||||||
|  | 	while (ucv_array_get(reg, i)) | ||||||
|  | 		i++; | ||||||
|  |  | ||||||
|  | 	ucv_array_set(reg, i, ucv_get(val)); | ||||||
|  |  | ||||||
|  | 	return i + 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx) | ||||||
|  | { | ||||||
|  | 	if (!idx) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	return ucv_array_get(reg, idx - 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val = wpa_ucode_registry_get(reg, idx); | ||||||
|  |  | ||||||
|  | 	if (val) | ||||||
|  | 		ucv_array_set(reg, idx - 1, NULL); | ||||||
|  |  | ||||||
|  | 	return val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | uc_value_t *wpa_ucode_call(size_t nargs) | ||||||
|  | { | ||||||
|  | 	if (uc_vm_call(&vm, true, nargs) != EXCEPTION_NONE) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	if (!gc_timer.pending) | ||||||
|  | 		uloop_timeout_set(&gc_timer, 10); | ||||||
|  |  | ||||||
|  | 	return uc_vm_stack_pop(&vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpa_ucode_free_vm(void) | ||||||
|  | { | ||||||
|  | 	if (!vm.config) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	uc_search_path_free(&vm.config->module_search_path); | ||||||
|  | 	uc_vm_free(&vm); | ||||||
|  | 	registry = NULL; | ||||||
|  | 	vm = (uc_vm_t){}; | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | #ifndef __HOSTAPD_UTILS_UCODE_H | ||||||
|  | #define __HOSTAPD_UTILS_UCODE_H | ||||||
|  |  | ||||||
|  | #include "utils/includes.h" | ||||||
|  | #include "utils/common.h" | ||||||
|  | #include <ucode/lib.h> | ||||||
|  | #include <ucode/vm.h> | ||||||
|  |  | ||||||
|  | #define HOSTAPD_UC_PATH	"/usr/share/hostap/" | ||||||
|  |  | ||||||
|  | extern uc_value_t *uc_registry; | ||||||
|  | uc_vm_t *wpa_ucode_create_vm(void); | ||||||
|  | int wpa_ucode_run(const char *script); | ||||||
|  | int wpa_ucode_call_prepare(const char *fname); | ||||||
|  | uc_value_t *wpa_ucode_call(size_t nargs); | ||||||
|  | void wpa_ucode_free_vm(void); | ||||||
|  |  | ||||||
|  | uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type); | ||||||
|  |  | ||||||
|  | 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); | ||||||
|  |  | ||||||
|  | uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs); | ||||||
|  | uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs); | ||||||
|  | uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs); | ||||||
|  | uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs); | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -30,12 +30,6 @@ static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *ob | |||||||
| 	return container_of(obj, struct wpa_supplicant, ubus.obj); | 	return container_of(obj, struct wpa_supplicant, ubus.obj); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) |  | ||||||
| { |  | ||||||
| 	struct ubus_context *ctx = eloop_ctx; |  | ||||||
| 	ubus_handle_event(ctx); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | ||||||
| { | { | ||||||
| 	if (ubus_reconnect(ctx, NULL)) { | 	if (ubus_reconnect(ctx, NULL)) { | ||||||
| @@ -43,12 +37,12 @@ static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | 	ubus_add_uloop(ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void wpas_ubus_connection_lost(struct ubus_context *ctx) | static void wpas_ubus_connection_lost(struct ubus_context *ctx) | ||||||
| { | { | ||||||
| 	eloop_unregister_read_sock(ctx->sock.fd); | 	uloop_fd_delete(&ctx->sock); | ||||||
| 	eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | 	eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -57,12 +51,14 @@ static bool wpas_ubus_init(void) | |||||||
| 	if (ctx) | 	if (ctx) | ||||||
| 		return true; | 		return true; | ||||||
|  |  | ||||||
|  | 	eloop_add_uloop(); | ||||||
| 	ctx = ubus_connect(NULL); | 	ctx = ubus_connect(NULL); | ||||||
| 	if (!ctx) | 	if (!ctx) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	ctx->connection_lost = wpas_ubus_connection_lost; | 	ctx->connection_lost = wpas_ubus_connection_lost; | ||||||
| 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | 	ubus_add_uloop(ctx); | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -80,7 +76,7 @@ static void wpas_ubus_ref_dec(void) | |||||||
| 	if (ctx_ref) | 	if (ctx_ref) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	eloop_unregister_read_sock(ctx->sock.fd); | 	uloop_fd_delete(&ctx->sock); | ||||||
| 	ubus_free(ctx); | 	ubus_free(ctx); | ||||||
| 	ctx = NULL; | 	ctx = NULL; | ||||||
| } | } | ||||||
| @@ -211,152 +207,6 @@ void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) | |||||||
| 	free(name); | 	free(name); | ||||||
| } | } | ||||||
|  |  | ||||||
| enum { |  | ||||||
| 	WPAS_CONFIG_DRIVER, |  | ||||||
| 	WPAS_CONFIG_IFACE, |  | ||||||
| 	WPAS_CONFIG_BRIDGE, |  | ||||||
| 	WPAS_CONFIG_HOSTAPD_CTRL, |  | ||||||
| 	WPAS_CONFIG_CTRL, |  | ||||||
| 	WPAS_CONFIG_FILE, |  | ||||||
| 	__WPAS_CONFIG_MAX |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct blobmsg_policy wpas_config_add_policy[__WPAS_CONFIG_MAX] = { |  | ||||||
| 	[WPAS_CONFIG_DRIVER] = { "driver", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[WPAS_CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[WPAS_CONFIG_BRIDGE] = { "bridge", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[WPAS_CONFIG_HOSTAPD_CTRL] = { "hostapd_ctrl", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[WPAS_CONFIG_CTRL] = { "ctrl", BLOBMSG_TYPE_STRING }, |  | ||||||
| 	[WPAS_CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| wpas_config_add(struct ubus_context *ctx, struct ubus_object *obj, |  | ||||||
| 		struct ubus_request_data *req, const char *method, |  | ||||||
| 		struct blob_attr *msg) |  | ||||||
| { |  | ||||||
| 	struct blob_attr *tb[__WPAS_CONFIG_MAX]; |  | ||||||
| 	struct wpa_global *global = get_wpa_global_from_object(obj); |  | ||||||
| 	struct wpa_interface *iface; |  | ||||||
|  |  | ||||||
| 	blobmsg_parse(wpas_config_add_policy, __WPAS_CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); |  | ||||||
|  |  | ||||||
| 	if (!tb[WPAS_CONFIG_FILE] || !tb[WPAS_CONFIG_IFACE] || !tb[WPAS_CONFIG_DRIVER]) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	iface = os_zalloc(sizeof(struct wpa_interface)); |  | ||||||
| 	if (iface == NULL) |  | ||||||
| 		return UBUS_STATUS_UNKNOWN_ERROR; |  | ||||||
|  |  | ||||||
| 	iface->driver = blobmsg_get_string(tb[WPAS_CONFIG_DRIVER]); |  | ||||||
| 	iface->ifname = blobmsg_get_string(tb[WPAS_CONFIG_IFACE]); |  | ||||||
| 	iface->confname = blobmsg_get_string(tb[WPAS_CONFIG_FILE]); |  | ||||||
|  |  | ||||||
| 	if (tb[WPAS_CONFIG_BRIDGE]) |  | ||||||
| 		iface->bridge_ifname = blobmsg_get_string(tb[WPAS_CONFIG_BRIDGE]); |  | ||||||
|  |  | ||||||
| 	if (tb[WPAS_CONFIG_CTRL]) |  | ||||||
| 		iface->ctrl_interface = blobmsg_get_string(tb[WPAS_CONFIG_CTRL]); |  | ||||||
|  |  | ||||||
| 	if (tb[WPAS_CONFIG_HOSTAPD_CTRL]) |  | ||||||
| 		iface->hostapd_ctrl = blobmsg_get_string(tb[WPAS_CONFIG_HOSTAPD_CTRL]); |  | ||||||
|  |  | ||||||
| 	if (!wpa_supplicant_add_iface(global, iface, NULL)) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	blob_buf_init(&b, 0); |  | ||||||
| 	blobmsg_add_u32(&b, "pid", getpid()); |  | ||||||
| 	ubus_send_reply(ctx, req, b.head); |  | ||||||
|  |  | ||||||
| 	return UBUS_STATUS_OK; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| enum { |  | ||||||
| 	WPAS_CONFIG_REM_IFACE, |  | ||||||
| 	__WPAS_CONFIG_REM_MAX |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct blobmsg_policy wpas_config_remove_policy[__WPAS_CONFIG_REM_MAX] = { |  | ||||||
| 	[WPAS_CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| wpas_config_remove(struct ubus_context *ctx, struct ubus_object *obj, |  | ||||||
| 		   struct ubus_request_data *req, const char *method, |  | ||||||
| 		   struct blob_attr *msg) |  | ||||||
| { |  | ||||||
| 	struct blob_attr *tb[__WPAS_CONFIG_REM_MAX]; |  | ||||||
| 	struct wpa_global *global = get_wpa_global_from_object(obj); |  | ||||||
| 	struct wpa_supplicant *wpa_s = NULL; |  | ||||||
| 	unsigned int found = 0; |  | ||||||
|  |  | ||||||
| 	blobmsg_parse(wpas_config_remove_policy, __WPAS_CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); |  | ||||||
|  |  | ||||||
| 	if (!tb[WPAS_CONFIG_REM_IFACE]) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	/* find wpa_s object for to-be-removed interface */ |  | ||||||
| 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { |  | ||||||
| 		if (!strncmp(wpa_s->ifname, |  | ||||||
| 			     blobmsg_get_string(tb[WPAS_CONFIG_REM_IFACE]), |  | ||||||
| 			     sizeof(wpa_s->ifname))) |  | ||||||
| 		{ |  | ||||||
| 			found = 1; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (!found) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	if (wpa_supplicant_remove_iface(global, wpa_s, 0)) |  | ||||||
| 		return UBUS_STATUS_INVALID_ARGUMENT; |  | ||||||
|  |  | ||||||
| 	return UBUS_STATUS_OK; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static const struct ubus_method wpas_daemon_methods[] = { |  | ||||||
| 	UBUS_METHOD("config_add", wpas_config_add, wpas_config_add_policy), |  | ||||||
| 	UBUS_METHOD("config_remove", wpas_config_remove, wpas_config_remove_policy), |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct ubus_object_type wpas_daemon_object_type = |  | ||||||
| 	UBUS_OBJECT_TYPE("wpa_supplicant", wpas_daemon_methods); |  | ||||||
|  |  | ||||||
| void wpas_ubus_add(struct wpa_global *global) |  | ||||||
| { |  | ||||||
| 	struct ubus_object *obj = &global->ubus_global; |  | ||||||
| 	int ret; |  | ||||||
|  |  | ||||||
| 	if (!wpas_ubus_init()) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	obj->name = strdup("wpa_supplicant"); |  | ||||||
|  |  | ||||||
| 	obj->type = &wpas_daemon_object_type; |  | ||||||
| 	obj->methods = wpas_daemon_object_type.methods; |  | ||||||
| 	obj->n_methods = wpas_daemon_object_type.n_methods; |  | ||||||
| 	ret = ubus_add_object(ctx, obj); |  | ||||||
| 	wpas_ubus_ref_inc(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void wpas_ubus_free(struct wpa_global *global) |  | ||||||
| { |  | ||||||
| 	struct ubus_object *obj = &global->ubus_global; |  | ||||||
| 	char *name = (char *) obj->name; |  | ||||||
|  |  | ||||||
| 	if (!ctx) |  | ||||||
| 		return; |  | ||||||
|  |  | ||||||
| 	if (obj->id) { |  | ||||||
| 		ubus_remove_object(ctx, obj); |  | ||||||
| 		wpas_ubus_ref_dec(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	free(name); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef CONFIG_WPS | #ifdef CONFIG_WPS | ||||||
| void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) | void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -24,9 +24,6 @@ struct wpas_ubus_bss { | |||||||
| void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); | void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); | ||||||
| void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); | void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); | ||||||
|  |  | ||||||
| void wpas_ubus_add(struct wpa_global *global); |  | ||||||
| void wpas_ubus_free(struct wpa_global *global); |  | ||||||
|  |  | ||||||
| #ifdef CONFIG_WPS | #ifdef CONFIG_WPS | ||||||
| void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); | void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); | ||||||
| #endif | #endif | ||||||
| @@ -34,14 +31,6 @@ void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential | |||||||
| #else | #else | ||||||
| struct wpas_ubus_bss {}; | struct wpas_ubus_bss {}; | ||||||
|  |  | ||||||
| static inline void wpas_ubus_add_iface(struct wpa_supplicant *wpa_s) |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline void wpas_ubus_free_iface(struct wpa_supplicant *wpa_s) |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) | static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) | ||||||
| { | { | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										270
									
								
								feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,270 @@ | |||||||
|  | #include "utils/includes.h" | ||||||
|  | #include "utils/common.h" | ||||||
|  | #include "utils/ucode.h" | ||||||
|  | #include "drivers/driver.h" | ||||||
|  | #include "wpa_supplicant_i.h" | ||||||
|  | #include "wps_supplicant.h" | ||||||
|  | #include "bss.h" | ||||||
|  | #include "ucode.h" | ||||||
|  |  | ||||||
|  | static struct wpa_global *wpa_global; | ||||||
|  | static uc_resource_type_t *global_type, *iface_type; | ||||||
|  | static uc_value_t *global, *iface_registry; | ||||||
|  | static uc_vm_t *vm; | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (wpa_s->ucode.idx) | ||||||
|  | 		return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); | ||||||
|  |  | ||||||
|  | 	val = uc_resource_new(iface_type, wpa_s); | ||||||
|  | 	wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val); | ||||||
|  |  | ||||||
|  | 	return val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | wpas_ucode_update_interfaces(void) | ||||||
|  | { | ||||||
|  | 	uc_value_t *ifs = ucv_object_new(vm); | ||||||
|  | 	struct wpa_supplicant *wpa_s; | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) | ||||||
|  | 		ucv_object_add(ifs, wpa_s->ifname, ucv_get(wpas_ucode_iface_get_uval(wpa_s))); | ||||||
|  |  | ||||||
|  | 	ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_call_prepare("iface_add")) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); | ||||||
|  | 	uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s))); | ||||||
|  | 	ucv_put(wpa_ucode_call(2)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	val = wpa_ucode_registry_remove(iface_registry, wpa_s->ucode.idx); | ||||||
|  | 	if (!val) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	wpa_s->ucode.idx = 0; | ||||||
|  | 	if (wpa_ucode_call_prepare("iface_remove")) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); | ||||||
|  | 	uc_value_push(ucv_get(val)); | ||||||
|  | 	ucv_put(wpa_ucode_call(2)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	const char *state; | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); | ||||||
|  | 	if (!val) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_call_prepare("state")) | ||||||
|  | 		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(3)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) | ||||||
|  | { | ||||||
|  | 	const char *state; | ||||||
|  | 	uc_value_t *val; | ||||||
|  |  | ||||||
|  | 	if (event != EVENT_CH_SWITCH_STARTED) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); | ||||||
|  | 	if (!val) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	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); | ||||||
|  | 	uc_value_push(ucv_get(val)); | ||||||
|  |  | ||||||
|  | 	if (event == EVENT_CH_SWITCH_STARTED) { | ||||||
|  | 		ucv_object_add(val, "csa_count", ucv_int64_new(data->ch_switch.count)); | ||||||
|  | 		ucv_object_add(val, "frequency", ucv_int64_new(data->ch_switch.freq)); | ||||||
|  | 		ucv_object_add(val, "sec_chan_offset", ucv_int64_new(data->ch_switch.ch_offset)); | ||||||
|  | 		ucv_object_add(val, "center_freq1", ucv_int64_new(data->ch_switch.cf1)); | ||||||
|  | 		ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ucv_put(wpa_ucode_call(4)); | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const char *obj_stringval(uc_value_t *obj, const char *name) | ||||||
|  | { | ||||||
|  | 	uc_value_t *val = ucv_object_get(obj, name, NULL); | ||||||
|  |  | ||||||
|  | 	return ucv_string_get(val); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_wpas_add_iface(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	uc_value_t *info = uc_fn_arg(0); | ||||||
|  | 	uc_value_t *ifname = ucv_object_get(info, "iface", NULL); | ||||||
|  | 	uc_value_t *bridge = ucv_object_get(info, "bridge", NULL); | ||||||
|  | 	uc_value_t *config = ucv_object_get(info, "config", NULL); | ||||||
|  | 	uc_value_t *ctrl = ucv_object_get(info, "ctrl", NULL); | ||||||
|  | 	struct wpa_interface iface; | ||||||
|  | 	int ret = -1; | ||||||
|  |  | ||||||
|  | 	if (ucv_type(info) != UC_OBJECT) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	iface = (struct wpa_interface){ | ||||||
|  | 		.driver = "nl80211", | ||||||
|  | 		.ifname = ucv_string_get(ifname), | ||||||
|  | 		.bridge_ifname = ucv_string_get(bridge), | ||||||
|  | 		.confname = ucv_string_get(config), | ||||||
|  | 		.ctrl_interface = ucv_string_get(ctrl), | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	if (!iface.ifname || !iface.confname) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	ret = wpa_supplicant_add_iface(wpa_global, &iface, 0) ? 0 : -1; | ||||||
|  | 	wpas_ucode_update_interfaces(); | ||||||
|  |  | ||||||
|  | out: | ||||||
|  | 	return ucv_int64_new(ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_wpas_remove_iface(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct wpa_supplicant *wpa_s = NULL; | ||||||
|  | 	uc_value_t *ifname_arg = uc_fn_arg(0); | ||||||
|  | 	const char *ifname = ucv_string_get(ifname_arg); | ||||||
|  | 	int ret = -1; | ||||||
|  |  | ||||||
|  | 	if (!ifname) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) | ||||||
|  | 		if (!strcmp(wpa_s->ifname, ifname)) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 	if (!wpa_s) | ||||||
|  | 		goto out; | ||||||
|  |  | ||||||
|  | 	ret = wpa_supplicant_remove_iface(wpa_global, wpa_s, 0); | ||||||
|  | 	wpas_ucode_update_interfaces(); | ||||||
|  |  | ||||||
|  | out: | ||||||
|  | 	return ucv_int64_new(ret); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uc_value_t * | ||||||
|  | uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) | ||||||
|  | { | ||||||
|  | 	struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); | ||||||
|  | 	struct wpa_bss *bss; | ||||||
|  | 	uc_value_t *ret, *val; | ||||||
|  |  | ||||||
|  | 	if (!wpa_s) | ||||||
|  | 		return NULL; | ||||||
|  |  | ||||||
|  | 	ret = ucv_object_new(vm); | ||||||
|  |  | ||||||
|  | 	val = ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state)); | ||||||
|  | 	ucv_object_add(ret, "state", ucv_get(val)); | ||||||
|  |  | ||||||
|  | 	bss = wpa_s->current_bss; | ||||||
|  | 	if (bss) { | ||||||
|  | 		int sec_chan = 0; | ||||||
|  | 		const u8 *ie; | ||||||
|  |  | ||||||
|  | 		ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION); | ||||||
|  | 		if (ie && ie[1] >= 2) { | ||||||
|  | 			const struct ieee80211_ht_operation *ht_oper; | ||||||
|  |  | ||||||
|  | 			ht_oper = (const void *) (ie + 2); | ||||||
|  | 			if (ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) | ||||||
|  | 				sec_chan = 1; | ||||||
|  | 			else if (ht_oper->ht_param & | ||||||
|  | 				 HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) | ||||||
|  | 				sec_chan = -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan)); | ||||||
|  | 		ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int wpas_ucode_init(struct wpa_global *gl) | ||||||
|  | { | ||||||
|  | 	static const uc_function_list_t global_fns[] = { | ||||||
|  | 		{ "printf",	uc_wpa_printf }, | ||||||
|  | 		{ "getpid", uc_wpa_getpid }, | ||||||
|  | 		{ "add_iface", uc_wpas_add_iface }, | ||||||
|  | 		{ "remove_iface", uc_wpas_remove_iface }, | ||||||
|  | 	}; | ||||||
|  | 	static const uc_function_list_t iface_fns[] = { | ||||||
|  | 		{ "status", uc_wpas_iface_status }, | ||||||
|  | 	}; | ||||||
|  | 	uc_value_t *data, *proto; | ||||||
|  |  | ||||||
|  | 	wpa_global = gl; | ||||||
|  | 	vm = wpa_ucode_create_vm(); | ||||||
|  |  | ||||||
|  | 	global_type = uc_type_declare(vm, "wpas.global", global_fns, NULL); | ||||||
|  | 	iface_type = uc_type_declare(vm, "wpas.iface", iface_fns, NULL); | ||||||
|  |  | ||||||
|  | 	iface_registry = ucv_array_new(vm); | ||||||
|  | 	uc_vm_registry_set(vm, "wpas.iface_registry", iface_registry); | ||||||
|  |  | ||||||
|  | 	global = wpa_ucode_global_init("wpas", global_type); | ||||||
|  |  | ||||||
|  | 	if (wpa_ucode_run(HOSTAPD_UC_PATH "wpa_supplicant.uc")) | ||||||
|  | 		goto free_vm; | ||||||
|  |  | ||||||
|  | 	ucv_gc(vm); | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | free_vm: | ||||||
|  | 	wpa_ucode_free_vm(); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ucode_free(void) | ||||||
|  | { | ||||||
|  | 	if (wpa_ucode_call_prepare("shutdown") == 0) | ||||||
|  | 		ucv_put(wpa_ucode_call(0)); | ||||||
|  | 	wpa_ucode_free_vm(); | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | #ifndef __WPAS_UCODE_H | ||||||
|  | #define __WPAS_UCODE_H | ||||||
|  |  | ||||||
|  | #include "utils/ucode.h" | ||||||
|  |  | ||||||
|  | struct wpa_global; | ||||||
|  | union wpa_event_data; | ||||||
|  | struct wpa_supplicant; | ||||||
|  |  | ||||||
|  | struct wpas_ucode_bss { | ||||||
|  | #ifdef UCODE_SUPPORT | ||||||
|  | 	unsigned int idx; | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #ifdef UCODE_SUPPORT | ||||||
|  | int wpas_ucode_init(struct wpa_global *gl); | ||||||
|  | void wpas_ucode_free(void); | ||||||
|  | void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s); | ||||||
|  | void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s); | ||||||
|  | void wpas_ucode_update_state(struct wpa_supplicant *wpa_s); | ||||||
|  | void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data); | ||||||
|  | #else | ||||||
|  | static inline int wpas_ucode_init(struct wpa_global *gl) | ||||||
|  | { | ||||||
|  | 	return -EINVAL; | ||||||
|  | } | ||||||
|  | static inline void wpas_ucode_free(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | static inline void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
| . /lib/netifd/netifd-wireless.sh | . /lib/netifd/netifd-wireless.sh | ||||||
| . /lib/netifd/hostapd.sh | . /lib/netifd/hostapd.sh | ||||||
|  | . /lib/functions/system.sh | ||||||
|  |  | ||||||
| init_wireless_driver "$@" | init_wireless_driver "$@" | ||||||
|  |  | ||||||
| @@ -14,12 +15,9 @@ MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh | |||||||
| MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" | MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" | ||||||
| MP_CONFIG_STRING="mesh_power_mode" | MP_CONFIG_STRING="mesh_power_mode" | ||||||
|  |  | ||||||
| NEWAPLIST= | wdev_tool() { | ||||||
| OLDAPLIST= | 	ucode /usr/share/hostap/wdev.uc "$@" | ||||||
| NEWSPLIST= | } | ||||||
| OLDSPLIST= |  | ||||||
| NEWUMLIST= |  | ||||||
| OLDUMLIST= |  | ||||||
|  |  | ||||||
| drv_mac80211_init_device_config() { | drv_mac80211_init_device_config() { | ||||||
| 	hostapd_common_add_device_config | 	hostapd_common_add_device_config | ||||||
| @@ -28,9 +26,9 @@ drv_mac80211_init_device_config() { | |||||||
| 	config_add_string tx_burst | 	config_add_string tx_burst | ||||||
| 	config_add_string distance | 	config_add_string distance | ||||||
| 	config_add_int beacon_int chanbw frag rts | 	config_add_int beacon_int chanbw frag rts | ||||||
| 	config_add_int rxantenna txantenna antenna_gain txpower | 	config_add_int rxantenna txantenna antenna_gain txpower min_tx_power | ||||||
| 	config_add_int num_global_macaddr | 	config_add_int num_global_macaddr | ||||||
| 	config_add_boolean noscan ht_coex acs_exclude_dfs | 	config_add_boolean noscan ht_coex acs_exclude_dfs background_radar | ||||||
| 	config_add_array ht_capab | 	config_add_array ht_capab | ||||||
| 	config_add_array channels | 	config_add_array channels | ||||||
| 	config_add_array scan_list | 	config_add_array scan_list | ||||||
| @@ -140,13 +138,15 @@ mac80211_hostapd_setup_base() { | |||||||
| 	[ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && | 	[ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && | ||||||
| 		append base_cfg "acs_exclude_dfs=1" "$N" | 		append base_cfg "acs_exclude_dfs=1" "$N" | ||||||
|  |  | ||||||
| 	json_get_vars noscan ht_coex | 	json_get_vars noscan ht_coex min_tx_power:0 tx_burst | ||||||
| 	json_get_values ht_capab_list ht_capab tx_burst | 	json_get_values ht_capab_list ht_capab | ||||||
| 	json_get_values channel_list channels | 	json_get_values channel_list channels | ||||||
|  |  | ||||||
| 	[ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ | 	[ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ | ||||||
| 		channel_list="$channel" | 		channel_list="$channel" | ||||||
|  |  | ||||||
|  | 	[ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" | ||||||
|  |  | ||||||
| 	set_default noscan 0 | 	set_default noscan 0 | ||||||
|  |  | ||||||
| 	[ "$noscan" -gt 0 ] && hostapd_noscan=1 | 	[ "$noscan" -gt 0 ] && hostapd_noscan=1 | ||||||
| @@ -276,6 +276,11 @@ mac80211_hostapd_setup_base() { | |||||||
| 			vht_center_seg0=$idx | 			vht_center_seg0=$idx | ||||||
| 		;; | 		;; | ||||||
| 	esac | 	esac | ||||||
|  | 	[ "$band" = "5g" ] && { | ||||||
|  | 		json_get_vars background_radar:0 | ||||||
|  |  | ||||||
|  | 		[ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N" | ||||||
|  | 	} | ||||||
| 	[ "$band" = "6g" ] && { | 	[ "$band" = "6g" ] && { | ||||||
| 		op_class= | 		op_class= | ||||||
| 		case "$htmode" in | 		case "$htmode" in | ||||||
| @@ -409,20 +414,21 @@ mac80211_hostapd_setup_base() { | |||||||
| 	if [ "$enable_ax" != "0" ]; then | 	if [ "$enable_ax" != "0" ]; then | ||||||
| 		json_get_vars \ | 		json_get_vars \ | ||||||
| 			he_su_beamformer:1 \ | 			he_su_beamformer:1 \ | ||||||
| 			he_su_beamformee:0 \ | 			he_su_beamformee:1 \ | ||||||
| 			he_mu_beamformer:1 \ | 			he_mu_beamformer:1 \ | ||||||
| 			he_twt_required:0 \ | 			he_twt_required:0 \ | ||||||
| 			he_spr_sr_control:0 \ | 			he_spr_sr_control:3 \ | ||||||
| 			he_spr_non_srg_obss_pd_max_offset:1 \ | 			he_spr_psr_enabled:0 \ | ||||||
| 			he_bss_color | 			he_spr_non_srg_obss_pd_max_offset:0 \ | ||||||
|  | 			he_bss_color:128 \ | ||||||
|  | 			he_bss_color_enabled:1 | ||||||
|  |  | ||||||
| 		he_phy_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) | 		he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) | ||||||
| 		he_phy_cap=${he_phy_cap:2} | 		he_phy_cap=${he_phy_cap:2} | ||||||
| 		he_mac_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) | 		he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) | ||||||
| 		he_mac_cap=${he_mac_cap:2} | 		he_mac_cap=${he_mac_cap:2} | ||||||
|  |  | ||||||
| 		append base_cfg "ieee80211ax=1" "$N" | 		append base_cfg "ieee80211ax=1" "$N" | ||||||
| 		[ -n "$he_bss_color" ] && append base_cfg "he_bss_color=$he_bss_color" "$N" |  | ||||||
| 		[ "$hwmode" = "a" ] && { | 		[ "$hwmode" = "a" ] && { | ||||||
| 			append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" | 			append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" | ||||||
| 			append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" | 			append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" | ||||||
| @@ -432,10 +438,21 @@ mac80211_hostapd_setup_base() { | |||||||
| 			he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ | 			he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ | ||||||
| 			he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ | 			he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ | ||||||
| 			he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ | 			he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ | ||||||
| 			he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \ | 			he_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ | ||||||
| 			he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required | 			he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required | ||||||
|  |  | ||||||
| 		[ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" | 		if [ "$he_bss_color_enabled" -gt 0 ]; then | ||||||
|  | 			append base_cfg "he_bss_color=$he_bss_color" "$N" | ||||||
|  | 			[ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ | ||||||
|  | 				append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" | ||||||
|  | 				he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) | ||||||
|  | 			} | ||||||
|  | 			[ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) | ||||||
|  | 			append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" | ||||||
|  | 		else | ||||||
|  | 			append base_cfg "he_bss_color_disabled=1" "$N" | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  |  | ||||||
| 		append base_cfg "he_default_pe_duration=4" "$N" | 		append base_cfg "he_default_pe_duration=4" "$N" | ||||||
| 		append base_cfg "he_rts_threshold=1023" "$N" | 		append base_cfg "he_rts_threshold=1023" "$N" | ||||||
| @@ -475,8 +492,6 @@ $base_cfg | |||||||
|  |  | ||||||
| EOF | EOF | ||||||
| 	json_select .. | 	json_select .. | ||||||
| 	radio_md5sum=$(md5sum $hostapd_conf_file | cut -d" " -f1) |  | ||||||
| 	echo "radio_config_id=${radio_md5sum}" >> $hostapd_conf_file |  | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_hostapd_setup_bss() { | mac80211_hostapd_setup_bss() { | ||||||
| @@ -533,7 +548,7 @@ mac80211_generate_mac() { | |||||||
| 	local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" | 	local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" | ||||||
| 	local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)" | 	local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)" | ||||||
|  |  | ||||||
| 	[ "$mask" = "00:00:00:00:00:00" ] && { | 	[ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" != 1 ] && { | ||||||
| 		mask="ff:ff:ff:ff:ff:ff"; | 		mask="ff:ff:ff:ff:ff:ff"; | ||||||
|  |  | ||||||
| 		[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && { | 		[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && { | ||||||
| @@ -598,76 +613,7 @@ mac80211_check_ap() { | |||||||
| 	has_ap=1 | 	has_ap=1 | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_iw_interface_add() { |  | ||||||
| 	local phy="$1" |  | ||||||
| 	local ifname="$2" |  | ||||||
| 	local type="$3" |  | ||||||
| 	local wdsflag="$4" |  | ||||||
| 	local rc |  | ||||||
| 	local oldifname |  | ||||||
|  |  | ||||||
| 	iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 |  | ||||||
| 	rc="$?" |  | ||||||
|  |  | ||||||
| 	[ "$rc" = 233 ] && { |  | ||||||
| 		# Device might have just been deleted, give the kernel some time to finish cleaning it up |  | ||||||
| 		sleep 1 |  | ||||||
|  |  | ||||||
| 		iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 |  | ||||||
| 		rc="$?" |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	[ "$rc" = 233 ] && { |  | ||||||
| 		# Keep matching pre-existing interface |  | ||||||
| 		[ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && \ |  | ||||||
| 		case "$(iw dev $ifname info | grep "^\ttype" | cut -d' ' -f2- 2>/dev/null)" in |  | ||||||
| 			"AP") |  | ||||||
| 				[ "$type" = "__ap" ] && rc=0 |  | ||||||
| 				;; |  | ||||||
| 			"IBSS") |  | ||||||
| 				[ "$type" = "adhoc" ] && rc=0 |  | ||||||
| 				;; |  | ||||||
| 			"managed") |  | ||||||
| 				[ "$type" = "managed" ] && rc=0 |  | ||||||
| 				;; |  | ||||||
| 			"mesh point") |  | ||||||
| 				[ "$type" = "mp" ] && rc=0 |  | ||||||
| 				;; |  | ||||||
| 			"monitor") |  | ||||||
| 				[ "$type" = "monitor" ] && rc=0 |  | ||||||
| 				;; |  | ||||||
| 		esac |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	[ "$rc" = 233 ] && { |  | ||||||
| 		iw dev "$ifname" del >/dev/null 2>&1 |  | ||||||
| 		[ "$?" = 0 ] && { |  | ||||||
| 			sleep 1 |  | ||||||
|  |  | ||||||
| 			iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 |  | ||||||
| 			rc="$?" |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	[ "$rc" != 0 ] && { |  | ||||||
| 		# Device might not support virtual interfaces, so the interface never got deleted in the first place. |  | ||||||
| 		# Check if the interface already exists, and avoid failing in this case. |  | ||||||
| 		[ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && rc=0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	[ "$rc" != 0 ] && { |  | ||||||
| 		# Device doesn't support virtual interfaces and may have existing interface other than ifname. |  | ||||||
| 		oldifname="$(basename "/sys/class/ieee80211/${phy}/device/net"/* 2>/dev/null)" |  | ||||||
| 		[ "$oldifname" ] && ip link set "$oldifname" name "$ifname" 1>/dev/null 2>&1 |  | ||||||
| 		rc="$?" |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	[ "$rc" != 0 ] && echo "Failed to create interface $ifname" |  | ||||||
| 	return $rc |  | ||||||
| } |  | ||||||
|  |  | ||||||
| mac80211_prepare_vif() { | mac80211_prepare_vif() { | ||||||
| 	local multiple_bssid=$1 |  | ||||||
| 	json_select config | 	json_select config | ||||||
|  |  | ||||||
| 	json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file | 	json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file | ||||||
| @@ -675,19 +621,18 @@ mac80211_prepare_vif() { | |||||||
| 	[ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" | 	[ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" | ||||||
| 	if_idx=$((${if_idx:-0} + 1)) | 	if_idx=$((${if_idx:-0} + 1)) | ||||||
|  |  | ||||||
|  | 	append active_ifnames "$ifname" | ||||||
| 	set_default wds 0 | 	set_default wds 0 | ||||||
| 	set_default powersave 0 | 	set_default powersave 0 | ||||||
|  | 	json_add_string _ifname "$ifname" | ||||||
| 	json_select .. |  | ||||||
|  |  | ||||||
| 	[ -n "$macaddr" ] || { | 	[ -n "$macaddr" ] || { | ||||||
| 		macaddr="$(mac80211_generate_mac $phy $multiple_bssid)" | 		macaddr="$(mac80211_generate_mac $phy $multiple_bssid)" | ||||||
|  		macidx="$(($macidx + 1))" |  		macidx="$(($macidx + 1))" | ||||||
| 	} | 	} | ||||||
|  | 	json_add_string _macaddr "$macaddr" | ||||||
|  | 	json_select .. | ||||||
|  |  | ||||||
| 	json_add_object data |  | ||||||
| 	json_add_string ifname "$ifname" |  | ||||||
| 	json_close_object |  | ||||||
|  |  | ||||||
| 	[ "$mode" == "ap" ] && { | 	[ "$mode" == "ap" ] && { | ||||||
| 		[ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" | 		[ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" | ||||||
| @@ -698,9 +643,6 @@ mac80211_prepare_vif() { | |||||||
|  |  | ||||||
| 	# It is far easier to delete and create the desired interface | 	# It is far easier to delete and create the desired interface | ||||||
| 	case "$mode" in | 	case "$mode" in | ||||||
| 		adhoc) |  | ||||||
| 			mac80211_iw_interface_add "$phy" "$ifname" adhoc || return |  | ||||||
| 		;; |  | ||||||
| 		ap) | 		ap) | ||||||
| 			# Hostapd will handle recreating the interface and | 			# Hostapd will handle recreating the interface and | ||||||
| 			# subsequent virtual APs belonging to the same PHY | 			# subsequent virtual APs belonging to the same PHY | ||||||
| @@ -712,119 +654,20 @@ mac80211_prepare_vif() { | |||||||
|  |  | ||||||
| 			mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return | 			mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return | ||||||
|  |  | ||||||
| 			NEWAPLIST="${NEWAPLIST}$ifname " |  | ||||||
| 			[ -n "$hostapd_ctrl" ] || { | 			[ -n "$hostapd_ctrl" ] || { | ||||||
| 				ap_ifname="${ifname}" | 				ap_ifname="${ifname}" | ||||||
| 				hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" | 				hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" | ||||||
| 			} | 			} | ||||||
| 		;; | 		;; | ||||||
| 		mesh) |  | ||||||
| 			mac80211_iw_interface_add "$phy" "$ifname" mp || return |  | ||||||
| 		;; |  | ||||||
| 		monitor) |  | ||||||
| 			mac80211_iw_interface_add "$phy" "$ifname" monitor || return |  | ||||||
| 		;; |  | ||||||
| 		sta) |  | ||||||
| 			local wdsflag= |  | ||||||
| 			[ "$enable" = 0 ] || staidx="$(($staidx + 1))" |  | ||||||
| 			[ "$wds" -gt 0 ] && wdsflag="4addr on" |  | ||||||
| 			mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return |  | ||||||
| 			if [ "$wds" -gt 0 ]; then |  | ||||||
| 				echo 1 > /sys/kernel/debug/ieee80211/$phy/netdev\:$ifname/disable_offload |  | ||||||
| 				iw "$ifname" set 4addr on |  | ||||||
| 			else |  | ||||||
| 				iw "$ifname" set 4addr off |  | ||||||
| 			fi |  | ||||||
| 			[ "$powersave" -gt 0 ] && powersave="on" || powersave="off" |  | ||||||
| 			iw "$ifname" set power_save "$powersave" |  | ||||||
| 		;; |  | ||||||
| 	esac | 	esac | ||||||
|  |  | ||||||
| 	case "$mode" in |  | ||||||
| 		monitor|mesh) |  | ||||||
| 			[ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $iw_htmode |  | ||||||
| 		;; |  | ||||||
| 	esac |  | ||||||
|  |  | ||||||
| 	if [ "$mode" != "ap" ]; then |  | ||||||
| 		# ALL ap functionality will be passed to hostapd |  | ||||||
| 		# All interfaces must have unique mac addresses |  | ||||||
| 		# which can either be explicitly set in the device |  | ||||||
| 		# section, or automatically generated |  | ||||||
| 		ip link set dev "$ifname" address "$macaddr" |  | ||||||
| 	fi |  | ||||||
|  |  | ||||||
| 	json_select .. | 	json_select .. | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_setup_supplicant() { |  | ||||||
| 	local enable=$1 |  | ||||||
| 	local add_sp=0 |  | ||||||
| 	local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" |  | ||||||
|  |  | ||||||
| 	[ "$enable" = 0 ] && { |  | ||||||
| 		ubus call wpa_supplicant.${phy} config_remove "{\"iface\":\"$ifname\"}" |  | ||||||
| 		ip link set dev "$ifname" down |  | ||||||
| 		iw dev "$ifname" del |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wpa_supplicant_prepare_interface "$ifname" nl80211 || { |  | ||||||
| 		iw dev "$ifname" del |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	if [ "$mode" = "sta" ]; then |  | ||||||
| 		wpa_supplicant_add_network "$ifname" |  | ||||||
| 	else |  | ||||||
| 		wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" |  | ||||||
| 	fi |  | ||||||
|  |  | ||||||
| 	NEWSPLIST="${NEWSPLIST}$ifname " |  | ||||||
|  |  | ||||||
| 	if [ "${NEWAPLIST%% *}" != "${OLDAPLIST%% *}" ]; then |  | ||||||
| 		[ "$spobj" ] && ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" |  | ||||||
| 		add_sp=1 |  | ||||||
| 	fi |  | ||||||
| 	[ -z "$spobj" ] && add_sp=1 |  | ||||||
|  |  | ||||||
| 	NEW_MD5_SP=$(test -e "${_config}" && md5sum ${_config}) |  | ||||||
| 	OLD_MD5_SP=$(uci -q -P /var/state get wireless._${phy}.md5_${ifname}) |  | ||||||
| 	if [ "$add_sp" = "1" ]; then |  | ||||||
| 		wpa_supplicant_run "$ifname" "$hostapd_ctrl" |  | ||||||
| 	else |  | ||||||
| 		[ "${NEW_MD5_SP}" == "${OLD_MD5_SP}" ] || ubus call $spobj reload |  | ||||||
| 	fi |  | ||||||
| 	uci -q -P /var/state set wireless._${phy}.md5_${ifname}="${NEW_MD5_SP}" |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| mac80211_setup_supplicant_noctl() { |  | ||||||
| 	local enable=$1 |  | ||||||
| 	local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" |  | ||||||
| 	wpa_supplicant_prepare_interface "$ifname" nl80211 || { |  | ||||||
| 		iw dev "$ifname" del |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" |  | ||||||
|  |  | ||||||
| 	NEWSPLIST="${NEWSPLIST}$ifname " |  | ||||||
| 	[ "$enable" = 0 ] && { |  | ||||||
| 		ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" |  | ||||||
| 		ip link set dev "$ifname" down |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 	if [ -z "$spobj" ]; then |  | ||||||
| 		wpa_supplicant_run "$ifname" |  | ||||||
| 	else |  | ||||||
| 		ubus call $spobj reload |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| mac80211_prepare_iw_htmode() { | mac80211_prepare_iw_htmode() { | ||||||
| 	case "$htmode" in | 	case "$htmode" in | ||||||
| 		VHT20|HT20) iw_htmode=HT20;; | 		VHT20|HT20|HE20) iw_htmode=HT20;; | ||||||
| 		HT40*|VHT40|VHT160) | 		HT40*|VHT40|VHT160|HE40) | ||||||
| 			case "$band" in | 			case "$band" in | ||||||
| 				2g) | 				2g) | ||||||
| 					case "$htmode" in | 					case "$htmode" in | ||||||
| @@ -848,7 +691,7 @@ mac80211_prepare_iw_htmode() { | |||||||
| 			esac | 			esac | ||||||
| 			[ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" | 			[ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" | ||||||
| 		;; | 		;; | ||||||
| 		VHT80) | 		VHT80|HE80) | ||||||
| 			iw_htmode="80MHZ" | 			iw_htmode="80MHZ" | ||||||
| 		;; | 		;; | ||||||
| 		NONE|NOHT) | 		NONE|NOHT) | ||||||
| @@ -858,6 +701,13 @@ mac80211_prepare_iw_htmode() { | |||||||
| 	esac | 	esac | ||||||
| } | } | ||||||
|  |  | ||||||
|  | mac80211_add_mesh_params() { | ||||||
|  | 	for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do | ||||||
|  | 		eval "mp_val=\"\$$var\"" | ||||||
|  | 		[ -n "$mp_val" ] && json_add_string "$var" "$mp_val" | ||||||
|  | 	done | ||||||
|  | } | ||||||
|  |  | ||||||
| mac80211_setup_adhoc() { | mac80211_setup_adhoc() { | ||||||
| 	local enable=$1 | 	local enable=$1 | ||||||
| 	json_get_vars bssid ssid key mcast_rate | 	json_get_vars bssid ssid key mcast_rate | ||||||
| @@ -899,81 +749,218 @@ mac80211_setup_adhoc() { | |||||||
| 	mcval= | 	mcval= | ||||||
| 	[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" | 	[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" | ||||||
|  |  | ||||||
| 	iw dev "$ifname" ibss join "$ssid" $freq $iw_htmode fixed-freq $bssid \ | 	local prev | ||||||
| 		beacon-interval $beacon_int \ | 	json_set_namespace wdev_uc prev | ||||||
| 		${brstr:+basic-rates $brstr} \ |  | ||||||
| 		${mcval:+mcast-rate $mcval} \ | 	json_add_object "$ifname" | ||||||
| 		${keyspec:+keys $keyspec} | 	json_add_string mode adhoc | ||||||
|  | 	json_add_string macaddr "$macaddr" | ||||||
|  | 	json_add_string ssid "$ssid" | ||||||
|  | 	json_add_string freq "$freq" | ||||||
|  | 	json_add_string htmode "$iw_htmode" | ||||||
|  | 	[ -n "$bssid" ] && json_add_string bssid "$bssid" | ||||||
|  | 	json_add_int beacon-interval "$beacon_int" | ||||||
|  | 	[ -n "$brstr" ] && json_add_string basic-rates "$brstr" | ||||||
|  | 	[ -n "$mcval" ] && json_add_string mcast-rate "$mcval" | ||||||
|  | 	[ -n "$keyspec" ] && json_add_string keys "$keyspec" | ||||||
|  | 	json_close_object | ||||||
|  |  | ||||||
|  | 	json_set_namespace "$prev" | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_setup_mesh() { | mac80211_setup_mesh() { | ||||||
| 	local enable=$1 |  | ||||||
| 	json_get_vars ssid mesh_id mcast_rate | 	json_get_vars ssid mesh_id mcast_rate | ||||||
|  |  | ||||||
| 	NEWUMLIST="${NEWUMLIST}$ifname " |  | ||||||
|  |  | ||||||
| 	[ "$enable" = 0 ] && { |  | ||||||
| 		ip link set dev "$ifname" down |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	mcval= | 	mcval= | ||||||
| 	[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" | 	[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" | ||||||
| 	[ -n "$mesh_id" ] && ssid="$mesh_id" | 	[ -n "$mesh_id" ] && ssid="$mesh_id" | ||||||
|  |  | ||||||
| 	iw dev "$ifname" mesh join "$ssid" freq $freq $iw_htmode \ | 	local prev | ||||||
| 		${mcval:+mcast-rate $mcval} \ | 	json_set_namespace wdev_uc prev | ||||||
| 		beacon-interval $beacon_int |  | ||||||
|  | 	json_add_object "$ifname" | ||||||
|  | 	json_add_string mode mesh | ||||||
|  | 	json_add_string macaddr "$macaddr" | ||||||
|  | 	json_add_string ssid "$ssid" | ||||||
|  | 	json_add_string freq "$freq" | ||||||
|  | 	json_add_string htmode "$iw_htmode" | ||||||
|  | 	[ -n "$mcval" ] && json_add_string mcast-rate "$mcval" | ||||||
|  | 	json_add_int beacon-interval "$beacon_int" | ||||||
|  | 	mac80211_add_mesh_params | ||||||
|  |  | ||||||
|  | 	json_close_object | ||||||
|  |  | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mac80211_setup_monitor() { | ||||||
|  | 	local prev | ||||||
|  | 	json_set_namespace wdev_uc prev | ||||||
|  |  | ||||||
|  | 	json_add_object "$ifname" | ||||||
|  | 	json_add_string mode monitor | ||||||
|  | 	[ -n "$freq" ] && json_add_string freq "$freq" | ||||||
|  | 	json_add_string htmode "$iw_htmode" | ||||||
|  | 	json_close_object | ||||||
|  |  | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mac80211_set_vif_txpower() { | ||||||
|  | 	local name="$1" | ||||||
|  |  | ||||||
|  | 	json_select config | ||||||
|  | 	json_get_var ifname _ifname | ||||||
|  | 	json_get_vars vif_txpower wds | ||||||
|  | 	json_select .. | ||||||
|  |  | ||||||
|  | 	set_default wds 0 | ||||||
|  | 	[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" | ||||||
|  | 	[ "$wds" -gt 0 ] && echo 1 > /sys/kernel/debug/ieee80211/$phy/netdev\:$ifname/disable_offload | ||||||
|  | } | ||||||
|  |  | ||||||
|  | wpa_supplicant_init_config() { | ||||||
|  | 	json_set_namespace wpa_supp prev | ||||||
|  |  | ||||||
|  | 	json_init | ||||||
|  | 	json_add_array config | ||||||
|  |  | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | wpa_supplicant_add_interface() { | ||||||
|  | 	local ifname="$1" | ||||||
|  | 	local mode="$2" | ||||||
|  | 	local hostapd_ctrl="$3" | ||||||
|  | 	local prev | ||||||
|  |  | ||||||
|  | 	_wpa_supplicant_common "$ifname" | ||||||
|  |  | ||||||
|  | 	json_set_namespace wpa_supp prev | ||||||
|  |  | ||||||
|  | 	json_add_object | ||||||
|  | 	json_add_string ctrl "$_rpath" | ||||||
|  | 	json_add_string iface "$ifname" | ||||||
|  | 	json_add_string mode "$mode" | ||||||
|  | 	json_add_string config "$_config" | ||||||
|  | 	json_add_string macaddr "$macaddr" | ||||||
|  | 	[ -n "$network_bridge" ] && json_add_string bridge "$network_bridge" | ||||||
|  | 	[ -n "$hostapd_ctrl" ] && json_add_string hostapd_ctrl "$hostapd_ctrl" | ||||||
|  | 	[ -n "$wds" ] && json_add_boolean 4addr "$wds" | ||||||
|  | 	json_add_boolean powersave "$powersave" | ||||||
|  | 	[ "$mode" = "mesh" ] && mac80211_add_mesh_params | ||||||
|  | 	json_close_object | ||||||
|  |  | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  |  | ||||||
|  | 	wpa_supp_init=1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | wpa_supplicant_set_config() { | ||||||
|  | 	local phy="$1" | ||||||
|  | 	local prev | ||||||
|  |  | ||||||
|  | 	json_set_namespace wpa_supp prev | ||||||
|  | 	json_close_array | ||||||
|  | 	json_add_string phy "$phy" | ||||||
|  | 	json_add_boolean defer 1 | ||||||
|  | 	local data="$(json_dump)" | ||||||
|  |  | ||||||
|  | 	json_cleanup | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  |  | ||||||
|  | 	ubus -S -t 0 wait_for wpa_supplicant || { | ||||||
|  | 		[ -n "$wpa_supp_init" ] || return 0 | ||||||
|  |  | ||||||
|  | 		ubus wait_for wpa_supplicant | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	local supplicant_res="$(ubus call wpa_supplicant config_set "$data")" | ||||||
|  | 	ret="$?" | ||||||
|  | 	[ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED | ||||||
|  |  | ||||||
|  | 	wireless_add_process "$(jsonfilter -s "$supplicant_res" -l 1 -e @.pid)" "/usr/sbin/wpa_supplicant" 1 1 | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hostapd_set_config() { | ||||||
|  | 	[ -n "$hostapd_ctrl" ] || { | ||||||
|  | 		ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ubus wait_for hostapd | ||||||
|  | 	local hostapd_res="$(ubus call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")" | ||||||
|  | 	ret="$?" | ||||||
|  | 	[ "$ret" != 0 -o -z "$hostapd_res" ] && { | ||||||
|  | 		wireless_setup_failed HOSTAPD_START_FAILED | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | wpa_supplicant_start() { | ||||||
|  | 	local phy="$1" | ||||||
|  |  | ||||||
|  | 	[ -n "$wpa_supp_init" ] || return 0 | ||||||
|  |  | ||||||
|  | 	ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null | ||||||
|  | } | ||||||
|  |  | ||||||
|  | mac80211_setup_supplicant() { | ||||||
|  | 	local enable=$1 | ||||||
|  | 	local add_sp=0 | ||||||
|  |  | ||||||
|  | 	wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1 | ||||||
|  |  | ||||||
|  | 	if [ "$mode" = "sta" ]; then | ||||||
|  | 		wpa_supplicant_add_network "$ifname" | ||||||
|  | 	else | ||||||
|  | 		wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	wpa_supplicant_add_interface "$ifname" "$mode" "$hostapd_ctrl" | ||||||
|  |  | ||||||
|  | 	return 0 | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_setup_vif() { | mac80211_setup_vif() { | ||||||
| 	local name="$1" | 	local name="$1" | ||||||
| 	local failed | 	local failed | ||||||
| 	local action=up |  | ||||||
|  |  | ||||||
| 	json_select data |  | ||||||
| 	json_get_vars ifname |  | ||||||
| 	json_select .. |  | ||||||
|  |  | ||||||
| 	json_select config | 	json_select config | ||||||
| 	json_get_vars mode | 	json_get_var ifname _ifname | ||||||
| 	json_get_var vif_txpower | 	json_get_var macaddr _macaddr | ||||||
| 	json_get_var vif_enable enable 1 | 	json_get_vars mode wds powersave | ||||||
|  |  | ||||||
| 	[ "$vif_enable" = 1 ] || action=down | 	set_default powersave 0 | ||||||
| 	if [ "$mode" != "ap" ] || [ "$ifname" = "$ap_ifname" ]; then | 	set_default wds 0 | ||||||
| 		ip link set dev "$ifname" "$action" || { |  | ||||||
| 			wireless_setup_vif_failed IFUP_ERROR |  | ||||||
| 			json_select .. |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" |  | ||||||
| 	fi |  | ||||||
|  |  | ||||||
| 	case "$mode" in | 	case "$mode" in | ||||||
| 		mesh) | 		mesh) | ||||||
|  | 			json_get_vars $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING | ||||||
| 			wireless_vif_parse_encryption | 			wireless_vif_parse_encryption | ||||||
| 			[ -z "$htmode" ] && htmode="NOHT"; | 			[ -z "$htmode" ] && htmode="NOHT"; | ||||||
| 			if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then | 			if wpa_supplicant -vmesh; then | ||||||
| 				mac80211_setup_supplicant $vif_enable || failed=1 | 				mac80211_setup_supplicant || failed=1 | ||||||
| 			else | 			else | ||||||
| 				mac80211_setup_mesh $vif_enable | 				mac80211_setup_mesh | ||||||
| 			fi | 			fi | ||||||
| 			for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do |  | ||||||
| 				json_get_var mp_val "$var" |  | ||||||
| 				[ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val" |  | ||||||
| 			done |  | ||||||
| 		;; | 		;; | ||||||
| 		adhoc) | 		adhoc) | ||||||
| 			wireless_vif_parse_encryption | 			wireless_vif_parse_encryption | ||||||
| 			if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then | 			if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then | ||||||
| 				mac80211_setup_supplicant_noctl $vif_enable || failed=1 | 				mac80211_setup_supplicant || failed=1 | ||||||
| 			else | 			else | ||||||
| 				mac80211_setup_adhoc $vif_enable | 				mac80211_setup_adhoc | ||||||
| 			fi | 			fi | ||||||
| 		;; | 		;; | ||||||
| 		sta) | 		sta) | ||||||
| 			mac80211_setup_supplicant $vif_enable || failed=1 | 			mac80211_setup_supplicant || failed=1 | ||||||
|  | 		;; | ||||||
|  | 		monitor) | ||||||
|  | 			mac80211_setup_monitor | ||||||
| 		;; | 		;; | ||||||
| 	esac | 	esac | ||||||
|  |  | ||||||
| @@ -1006,7 +993,6 @@ band_match && $3 == "MHz" && $4 == channel { | |||||||
| ' | ' | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| chan_is_dfs() { | chan_is_dfs() { | ||||||
| 	local phy="$1" | 	local phy="$1" | ||||||
| 	local chan="$2" | 	local chan="$2" | ||||||
| @@ -1014,27 +1000,6 @@ chan_is_dfs() { | |||||||
| 	return $! | 	return $! | ||||||
| } | } | ||||||
|  |  | ||||||
| mac80211_vap_cleanup() { |  | ||||||
| 	local service="$1" |  | ||||||
| 	local vaps="$2" |  | ||||||
|  |  | ||||||
| 	for wdev in $vaps; do |  | ||||||
| 		[ "$service" != "none" ] && ubus call ${service} config_remove "{\"iface\":\"$wdev\"}" |  | ||||||
| 		ip link set dev "$wdev" down 2>/dev/null |  | ||||||
| 		iw dev "$wdev" del |  | ||||||
| 	done |  | ||||||
| } |  | ||||||
|  |  | ||||||
| mac80211_interface_cleanup() { |  | ||||||
| 	local phy="$1" |  | ||||||
| 	local primary_ap=$(uci -q -P /var/state get wireless._${phy}.aplist) |  | ||||||
| 	primary_ap=${primary_ap%% *} |  | ||||||
|  |  | ||||||
| 	mac80211_vap_cleanup hostapd "${primary_ap}" |  | ||||||
| 	mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" |  | ||||||
| 	mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| mac80211_set_noscan() { | mac80211_set_noscan() { | ||||||
| 	hostapd_noscan=1 | 	hostapd_noscan=1 | ||||||
| } | } | ||||||
| @@ -1043,6 +1008,15 @@ drv_mac80211_cleanup() { | |||||||
| 	hostapd_common_cleanup | 	hostapd_common_cleanup | ||||||
| } | } | ||||||
|  |  | ||||||
|  | mac80211_reset_config() { | ||||||
|  | 	local phy="$1" | ||||||
|  |  | ||||||
|  | 	hostapd_conf_file="/var/run/hostapd-$phy.conf" | ||||||
|  | 	ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null | ||||||
|  | 	ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null | ||||||
|  | 	wdev_tool "$phy" '{}' | ||||||
|  | } | ||||||
|  |  | ||||||
| drv_mac80211_setup() { | drv_mac80211_setup() { | ||||||
| 	json_select config | 	json_select config | ||||||
| 	json_get_vars \ | 	json_get_vars \ | ||||||
| @@ -1057,39 +1031,24 @@ drv_mac80211_setup() { | |||||||
| 	json_get_values scan_list scan_list | 	json_get_values scan_list scan_list | ||||||
| 	json_select .. | 	json_select .. | ||||||
|  |  | ||||||
|  | 	json_select data && { | ||||||
|  | 		json_get_var prev_rxantenna rxantenna | ||||||
|  | 		json_get_var prev_txantenna txantenna | ||||||
|  | 		json_select .. | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	find_phy || { | 	find_phy || { | ||||||
| 		echo "Could not find PHY for device '$1'" | 		echo "Could not find PHY for device '$1'" | ||||||
| 		wireless_set_retry 0 | 		wireless_set_retry 0 | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	[ "$band" = "6g" ] && multiple_bssid=1 | 	[ "$band" = "6g" ] && set_default multiple_bssid 1 | ||||||
|  |  | ||||||
| 	wireless_set_data phy="$phy" |  | ||||||
| 	[ -z "$(uci -q -P /var/state show wireless._${phy})" ] && uci -q -P /var/state set wireless._${phy}=phy |  | ||||||
|  |  | ||||||
| 	OLDAPLIST=$(uci -q -P /var/state get wireless._${phy}.aplist) |  | ||||||
| 	OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist) |  | ||||||
| 	OLDUMLIST=$(uci -q -P /var/state get wireless._${phy}.umlist) |  | ||||||
|  |  | ||||||
| 	local wdev | 	local wdev | ||||||
| 	local cwdev | 	local cwdev | ||||||
| 	local found | 	local found | ||||||
|  |  | ||||||
| 	for wdev in $(list_phy_interfaces "$phy"); do |  | ||||||
| 		found=0 |  | ||||||
| 		for cwdev in $OLDAPLIST $OLDSPLIST $OLDUMLIST; do |  | ||||||
| 			if [ "$wdev" = "$cwdev" ]; then |  | ||||||
| 				found=1 |  | ||||||
| 				break |  | ||||||
| 			fi |  | ||||||
| 		done |  | ||||||
| 		if [ "$found" = "0" ]; then |  | ||||||
| 			ip link set dev "$wdev" down |  | ||||||
| 			iw dev "$wdev" del |  | ||||||
| 		fi |  | ||||||
| 	done |  | ||||||
|  |  | ||||||
| 	# convert channel to frequency | 	# convert channel to frequency | ||||||
| 	[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" | 	[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" | ||||||
|  |  | ||||||
| @@ -1102,7 +1061,6 @@ drv_mac80211_setup() { | |||||||
|  |  | ||||||
| 	hostapd_conf_file="/var/run/hostapd-$phy.conf" | 	hostapd_conf_file="/var/run/hostapd-$phy.conf" | ||||||
|  |  | ||||||
| 	no_ap=1 |  | ||||||
| 	macidx=0 | 	macidx=0 | ||||||
| 	staidx=0 | 	staidx=0 | ||||||
|  |  | ||||||
| @@ -1121,6 +1079,9 @@ drv_mac80211_setup() { | |||||||
| 	[ "$txantenna" = "all" ] && txantenna=0xffffffff | 	[ "$txantenna" = "all" ] && txantenna=0xffffffff | ||||||
| 	[ "$rxantenna" = "all" ] && rxantenna=0xffffffff | 	[ "$rxantenna" = "all" ] && rxantenna=0xffffffff | ||||||
|  |  | ||||||
|  | 	[ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy" | ||||||
|  | 	wireless_set_data phy="$phy" txantenna="$txantenna" rxantenna="$rxantenna" | ||||||
|  |  | ||||||
| 	iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 | 	iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 | ||||||
| 	iw phy "$phy" set antenna_gain $antenna_gain >/dev/null 2>&1 | 	iw phy "$phy" set antenna_gain $antenna_gain >/dev/null 2>&1 | ||||||
| 	iw phy "$phy" set distance "$distance" >/dev/null 2>&1 | 	iw phy "$phy" set distance "$distance" >/dev/null 2>&1 | ||||||
| @@ -1138,81 +1099,36 @@ drv_mac80211_setup() { | |||||||
| 	hostapd_ctrl= | 	hostapd_ctrl= | ||||||
| 	ap_ifname= | 	ap_ifname= | ||||||
| 	hostapd_noscan= | 	hostapd_noscan= | ||||||
|  | 	wpa_supp_init= | ||||||
| 	for_each_interface "ap" mac80211_check_ap | 	for_each_interface "ap" mac80211_check_ap | ||||||
|  |  | ||||||
| 	rm -f "$hostapd_conf_file" | 	[ -f "$hostapd_conf_file" ] && mv "$hostapd_conf_file" "$hostapd_conf_file.prev" | ||||||
|  |  | ||||||
| 	for_each_interface "sta adhoc mesh" mac80211_set_noscan | 	for_each_interface "sta adhoc mesh" mac80211_set_noscan | ||||||
| 	[ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" | 	[ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" | ||||||
|  |  | ||||||
|  | 	local prev | ||||||
|  | 	json_set_namespace wdev_uc prev | ||||||
|  | 	json_init | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  |  | ||||||
|  | 	wpa_supplicant_init_config | ||||||
|  |  | ||||||
| 	mac80211_prepare_iw_htmode | 	mac80211_prepare_iw_htmode | ||||||
| 	for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif | 	active_ifnames= | ||||||
| 	NEWAPLIST= | 	for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif ${multiple_bssid} | ||||||
| 	for_each_interface "ap" mac80211_prepare_vif ${multiple_bssid} | 	for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif | ||||||
| 	NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) |  | ||||||
| 	OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) |  | ||||||
| 	if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then |  | ||||||
| 		mac80211_vap_cleanup hostapd "${OLDAPLIST}" |  | ||||||
| 	fi |  | ||||||
| 	[ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap |  | ||||||
| 	local add_ap=0 |  | ||||||
| 	local primary_ap=${NEWAPLIST%% *} |  | ||||||
| 	[ -n "$hostapd_ctrl" ] && { |  | ||||||
| 		local no_reload=1 |  | ||||||
| 		if [ -n "$(ubus list | grep hostapd.$primary_ap)" ]; then |  | ||||||
| 			no_reload=0 |  | ||||||
| 			[ "${NEW_MD5}" = "${OLD_MD5}" ] || { |  | ||||||
| 				ubus call hostapd.$primary_ap reload |  | ||||||
| 				no_reload=$? |  | ||||||
| 				if [ "$no_reload" != "0" ]; then |  | ||||||
| 					mac80211_vap_cleanup hostapd "${OLDAPLIST}" |  | ||||||
| 					mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" |  | ||||||
| 					mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" |  | ||||||
| 					sleep 2 |  | ||||||
| 					mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap |  | ||||||
| 					for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif |  | ||||||
| 				fi |  | ||||||
| 			} |  | ||||||
| 		fi |  | ||||||
| 		if [ "$no_reload" != "0" ]; then |  | ||||||
| 			add_ap=1 |  | ||||||
| 			ubus wait_for hostapd |  | ||||||
| 			local hostapd_res |  | ||||||
| 			[ -f /tmp/wifi_fail_test ] || hostapd_res="$(ubus call hostapd config_add "{\"iface\":\"$primary_ap\", \"config\":\"${hostapd_conf_file}\"}")" |  | ||||||
| 			ret="$?" |  | ||||||
| 			rm -f /tmp/wifi_fail_test |  | ||||||
| 			[ "$ret" != 0 -o -z "$hostapd_res" ] && { |  | ||||||
| 				logger failed to start wifi trying again |  | ||||||
| 			#	wireless_setup_failed HOSTAPD_START_FAILED |  | ||||||
| 				return |  | ||||||
| 			} |  | ||||||
| 			wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 |  | ||||||
| 		fi |  | ||||||
| 	} |  | ||||||
| 	uci -q -P /var/state set wireless._${phy}.aplist="${NEWAPLIST}" |  | ||||||
| 	uci -q -P /var/state set wireless._${phy}.md5="${NEW_MD5}" |  | ||||||
|  |  | ||||||
| 	[ "${add_ap}" = 1 ] && sleep 1 | 	[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy" | ||||||
| 	for_each_interface "ap" mac80211_setup_vif | 	[ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy" | ||||||
|  |  | ||||||
| 	NEWSPLIST= | 	[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy" | ||||||
| 	NEWUMLIST= |  | ||||||
|  |  | ||||||
| 	for_each_interface "sta adhoc mesh monitor" mac80211_setup_vif | 	json_set_namespace wdev_uc prev | ||||||
|  | 	wdev_tool "$phy" "$(json_dump)" $active_ifnames | ||||||
|  | 	json_set_namespace "$prev" | ||||||
|  |  | ||||||
| 	uci -q -P /var/state set wireless._${phy}.splist="${NEWSPLIST}" | 	for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower | ||||||
| 	uci -q -P /var/state set wireless._${phy}.umlist="${NEWUMLIST}" |  | ||||||
|  |  | ||||||
| 	local foundvap |  | ||||||
| 	local dropvap="" |  | ||||||
| 	for oldvap in $OLDSPLIST; do |  | ||||||
| 		foundvap=0 |  | ||||||
| 		for newvap in $NEWSPLIST; do |  | ||||||
| 			[ "$oldvap" = "$newvap" ] && foundvap=1 |  | ||||||
| 		done |  | ||||||
| 		[ "$foundvap" = "0" ] && dropvap="$dropvap $oldvap" |  | ||||||
| 	done |  | ||||||
| 	[ -n "$dropvap" ] && mac80211_vap_cleanup wpa_supplicant "$dropvap" |  | ||||||
| 	wireless_set_up | 	wireless_set_up | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1243,8 +1159,12 @@ drv_mac80211_teardown() { | |||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mac80211_interface_cleanup "$phy" | 	mac80211_reset_config "$phy" | ||||||
| 	uci -q -P /var/state revert wireless._${phy} |  | ||||||
|  | 	for wdev in $(list_phy_interfaces "$phy"); do | ||||||
|  | 		ip link set dev "$wdev" down | ||||||
|  | 		iw dev "$wdev" del | ||||||
|  | 	done | ||||||
| } | } | ||||||
|  |  | ||||||
| add_driver mac80211 | add_driver mac80211 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin