[OpenWrt-Devel] [PATCH] netifd: proto-dhcp: handle alias interfaces
The alias interfaces for interfaces with proto dhcp are very useful for specialised builds with proto dhcp on lan by default but with backup static addresses. The default way has one shortage. It left backup address configured on interface with address configured by odchp. This can lead to network overlapping (when dhcp server configured on the same subnet with alias interface) and to the addresses duplication inside broadcast domain (when more then one board with same firmware running in subnet). This patch introduces new option to dhcp proto. Just add option alias '' to the interface configuration and it will automatically downs alias interfaces you specified upon dhcp address receiving. Signed-off-by: Yury Shvedov --- .../config/netifd/files/lib/netifd/dhcp.script| 11 ++- .../config/netifd/files/lib/netifd/proto/dhcp.sh | 11 +-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/package/network/config/netifd/files/lib/netifd/dhcp.script b/package/network/config/netifd/files/lib/netifd/dhcp.script index 00604f40e7..8055b472ff 100755 --- a/package/network/config/netifd/files/lib/netifd/dhcp.script +++ b/package/network/config/netifd/files/lib/netifd/dhcp.script @@ -14,6 +14,11 @@ set_classless_routes() { } setup_interface () { + local i + for i in $ALIAS; do + ubus call network.interface."$i" down '{}' + done + proto_init_update "*" 1 proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}" # TODO: apply $broadcast @@ -21,7 +26,6 @@ setup_interface () { local ip_net eval "$(ipcalc.sh "$ip/$mask")";ip_net="$NETWORK" - local i for i in $router; do local gw_net eval "$(ipcalc.sh "$i/$mask")";gw_net="$NETWORK" @@ -93,6 +97,11 @@ setup_interface () { deconfig_interface() { proto_init_update "*" 0 proto_send_update "$INTERFACE" + + local i + for i in $ALIAS; do + ubus call network.interface."$i" up '{}' + done } case "$1" in diff --git a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh index a2b0ccedbf..15edab13bc 100755 --- a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh +++ b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh @@ -25,6 +25,7 @@ proto_dhcp_init_config() { proto_config_add_string mtu6rd proto_config_add_string customroutes proto_config_add_boolean classlessroute + proto_config_add_string 'alias' } proto_dhcp_add_sendopts() { @@ -35,8 +36,8 @@ proto_dhcp_setup() { local config="$1" local iface="$2" - local ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute - json_get_vars ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute + local ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute alias + json_get_vars ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute alias local opt dhcpopts for opt in $reqopts; do @@ -60,6 +61,12 @@ proto_dhcp_setup() { # Request classless route option (see RFC 3442) by default [ "$classlessroute" = "0" ] || append dhcpopts "-O 121" + proto_export "ALIAS=$alias" + local i + for i in $alias; do + ubus call network.interface."$i" up '{}' + done + proto_export "INTERFACE=$config" proto_run_command "$config" udhcpc \ -p /var/run/udhcpc-$iface.pid \ -- 2.18.0 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Re: [OpenWrt-Devel] project: online image and sysupgrade builder
On 09/04/2018 11:32 PM, Paul wrote: Hi all, some time ago I stumbled over the two difficulties for new users: * Finding the initial firmware to flash a router * Upgrade a modified image without reinstalling all packages For this reason I created an *image on demand server*[0] which fetches ImageBuilders and creates the desired image, allowing the modification of installed packages and uci-defaults (if desired) via a simple API[1]. The images are build within seconds and offered to the user. While the project was initially created to simplify sysupgrades the service is mostly used with a *online ImageBuilder* fronted[2]. About 3000 firmware images where created over the last 6 month (some database resets dilute the statistics). I was wondering if this service could eventually become somewhat officially used. It offers a great simplification for user to get started with OpenWrt and also keep devices up to date. Next steps would be two allow multiple builders in parallel [3] and use ucert [4] to establish a trust chain. While build logs already contain all required information to "rebuild" (and verify) the image locally, sqaushfs needs to become reproducible[6] before it makes real sense. Please share your thoughts regarding this project, I'd be happy to receive some feedback! Sunshine, Paul [0] https://github.com/aparcar/attendedsysupgrade-server [1] https://github.com/aparcar/attendedsysupgrade-server#api [2] http://as-test.stephen304.com/chef/ [3] https://github.com/aparcar/attendedsysupgrade-server/pull/126 [4] https://git.openwrt.org/?p=project/ucert.git;a=summary [5] https://as-test.stephen304.com/download/openwrt/18.06.1/ar71xx/generic/archer-c7-v2/ba5cbe70ba1237b//buildlog-26ac67a4132b017.txt [6] https://git.openwrt.org/?p=openwrt/staging/lynxis.git;a=commit;h=1ad9d341434e6cf123213928d9a2e86ceec59c55 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel Hi Paul! This is a great step toward the user friendliness. But as I know the major difficulty for users who far from embedded system is to flash the board from original firmware. Sometimes there is very tricky process, sometimes there is huge red warning of the third word war in case of installing non-official firmware, etc. So as I think, sometimes user who can not find the wiki-page with device or build their own firmware with ImageBuilder could stuck on this step. For others, the set of packages is not the only way to customize the firmware. I don't tell about hand-created software but about the customization of packages (e.g. great list of busybox options or extra kernel modules). This is one of the shortage of ImageBuilder and the reason to use the BuildRoot more often. So maybe there is any sense to thought about *online BuildRoot* too? When it is warm enough it takes not much time to build a firmware for one board. Regarding to clients. May be there is any reason to automate it more? I.e. allow user to configure it to sysupgrage at night when the new service release is out? This was just thoughts as you ask. May be I was wrong in some cases, please correct me then. P.S. I mentioned the tricky process for flashing from original firmware. Maybe there is any reason to automate building of additional software for desktops? I.e. there is many scripts for flashing mikrotik devises, so why not to build deb packages in the BuildRoot, which will rise dhcp server and flash boards automatically? -- Kind regards, Yury Shvedov WiMark Systems ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Re: [OpenWrt-Devel] project: online image and sysupgrade builder
On 09/05/2018 09:13 PM, Paul wrote: Sorry I can't follow this idea - maybe as I'm not aware of any mikrotik related scripts... There is several steps to flash routerboard devices: 1. Download sysupgrade and netboot images 2. Configure and run dhcp server with tftpboot functionality 3. Run the body in netboot mode 4. Transfer sysupgrade image to it 5. Ssh to it and flash it This steps are little bit painful when you flashing often many devices and very painful for new users. There is an example script on wiki pages which creates dhcp server, but other you have to do yourself. I have a set of scripts which automates all of this steps (except #3). And additional script which packs newly built images for mikrotik into the self-unpacking archive with scripts mentioned above. So the output of my build is one executable binary which can flash any routerboard device automatically - you only have to connect the body in netboot mode and wait. So, why not to make such executables with buildroot? -- Kind regards, Yury Shvedov WiMark Systems ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel
[OpenWrt-Devel] [PATCH 3/5] hostapd: Add ubus accounting
This implements ubus accounting events. This accounting works the same manner as the RADIUS accounting, except the interim (see below). There tree types of messages: start, stop and interim. Start sent when new client connected. There just current time, address and session_id of client in message. Stop sent when client disconnected. This message contains extra counters and terminate_cause. Interim sent by timeout, configured with ubus_accounting_interval variable. This message contains an information about all connected to bss clients. Payload example: { "clients": [ { "session_time": 9, "address": "68:3e:34:f5:61:3f", "session_id": "A6367C8F6C0662C1", "accounting": { "rx_bytes": 2336, "tx_packets": 5, "tx_bytes": 533, "rx_packets": 17 }, "terminate_cause": 1 } ], "device": "radio0", "bssid": "44:d1:fa:12:4c:74", "freq": 5260, "iface": "wlan0" } Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 165 +++- .../services/hostapd/src/src/ap/ubus.c| 238 +- .../services/hostapd/src/src/ap/ubus.h| 14 ++ 3 files changed, 405 insertions(+), 12 deletions(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index c63b85c079..c0db5be4e9 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -99,7 +99,15 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); -@@ -3114,6 +3120,7 @@ void hostapd_set_state(struct hostapd_if +@@ -3050,6 +3056,7 @@ void hostapd_new_assoc_sta(struct hostap + ap_sta_set_authorized(hapd, sta, 1); + os_get_reltime(&sta->connected_time); + accounting_sta_start(hapd, sta); ++ hostapd_ubus_event_sta_account_start(hapd,sta); + } + + /* Start IEEE 802.1X authentication process for new stations */ +@@ -3114,6 +3121,7 @@ void hostapd_set_state(struct hostapd_if wpa_printf(MSG_INFO, "%s: interface state %s->%s", iface->conf ? iface->conf->bss[0]->iface : "N/A", hostapd_state_text(iface->state), hostapd_state_text(s)); @@ -201,7 +209,15 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { -@@ -3630,6 +3657,8 @@ static void handle_deauth(struct hostapd +@@ -3584,6 +3611,7 @@ static void handle_disassoc(struct hosta + /* Stop Accounting and IEEE 802.1X sessions, but leave the STA +* authenticated. */ + accounting_sta_stop(hapd, sta); ++ hostapd_ubus_event_sta_account_stop(hapd, sta); + ieee802_1x_free_station(hapd, sta); + if (sta->ipaddr) + hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr); +@@ -3630,6 +3658,8 @@ static void handle_deauth(struct hostapd " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); @@ -210,7 +226,7 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " -@@ -3949,7 +3978,7 @@ int ieee802_11_mgmt(struct hostapd_data +@@ -3949,7 +3979,7 @@ int ieee802_11_mgmt(struct hostapd_data if (stype == WLAN_FC_STYPE_PROBE_REQ) { @@ -219,7 +235,7 @@ return 1; } -@@ -3969,17 +3998,17 @@ int ieee802_11_mgmt(struct hostapd_data +@@ -3969,17 +3999,17 @@ int ieee802_11_mgmt(struct hostapd_data switch (stype) { case WLAN_FC_STYPE_AUTH: wpa_printf(MSG_DEBUG, "mgmt::auth"); @@ -240,6 +256,14 @@ ret = 1; break; case WLAN_FC_STYPE_DISASSOC: +@@ -4128,6 +4158,7 @@ static void handle_assoc_cb(struct hosta + /* Stop previous accounting session, if one is started, and allocate +* new session id for the new session. */ + accounting_sta_stop(hapd, sta); ++ hostapd_ubus_event_sta_account_stop(hapd, sta); + + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -720,7 +720,7 @@ void sta_track_claim_taxonomy_info(struc @@ -309,7 +333,15 @@ if (addr == NULL) { /* -@@ -195,6 +199,12 @@ int hostapd_notif_assoc(struct hostapd_d +@@ -164,6 +168,7 @@ in
[OpenWrt-Devel] [PATCH 4/5] hostapd: Add channel information to iface state event
This adds wide information about current channel of interface to hostapd.iface_state event. Additional event sent when interface completes csa operation. Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 8 +++ .../services/hostapd/src/src/ap/ubus.c| 69 +-- .../services/hostapd/src/src/ap/ubus.h| 4 ++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index c0db5be4e9..0bba0ba752 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -354,6 +354,14 @@ #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); +@@ -816,6 +827,7 @@ void hostapd_event_ch_switch(struct host + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED + "freq=%d dfs=%d", freq, is_dfs); + } ++hostapd_ubus_event_ch_switch(hapd->iface); + #endif /* NEED_AP_MLME */ + } + --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -162,6 +162,7 @@ void ap_free_sta(struct hostapd_data *ha diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 2ceb2de159..abbe3fac88 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -1300,6 +1300,53 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); } +static void blobmsg_add_iface_state(struct blob_buf *buff, + struct hostapd_iface *iface, int cur, int old) +{ + blobmsg_add_u32(buff, "oldstate_num", old); + blobmsg_add_string(buff, "oldstate", hostapd_state_text(old)); + blobmsg_add_u32(buff, "state_num", cur); + blobmsg_add_string(buff, "state", hostapd_state_text(cur)); +} +static void blobmsg_add_iface_channel(struct blob_buf *buff, + struct hostapd_iface *iface) +{ + struct hostapd_config *conf = iface->conf; + int width = 20; + void *chan; + + if (!iface->freq) { + return; + } + + chan = blobmsg_open_table(buff, "channel"); + + blobmsg_add_u32(buff, "freq", iface->freq); + blobmsg_add_u32(buff, "channel", conf->channel); + blobmsg_add_u8(buff, "ht", conf->ieee80211n); + blobmsg_add_u8(buff, "vht", conf->ieee80211ac); + blobmsg_add_u32(buff, "secondary_channel", conf->secondary_channel); + switch (conf->vht_oper_chwidth) { + case VHT_CHANWIDTH_USE_HT: + width = conf->secondary_channel ? 40 : 20; + break; + case VHT_CHANWIDTH_80MHZ: + width = 80; + break; + case VHT_CHANWIDTH_160MHZ: + width = 160; + break; + case VHT_CHANWIDTH_80P80MHZ: + width = 8080; + break; + } + blobmsg_add_u32(buff, "width", width); + blobmsg_add_u32(buff, "center_idx0", conf->vht_oper_centr_freq_seg0_idx); + blobmsg_add_u32(buff, "center_idx1", conf->vht_oper_centr_freq_seg1_idx); + blobmsg_add_u8(buff, "is_dfs", ieee80211_is_dfs(iface->freq, + iface->hw_features, iface->num_hw_features)); + blobmsg_close_table(buff, chan); +} /* Send ubus event in case new event differs. */ void hostapd_ubus_event_iface_state(struct hostapd_iface *iface, int s) { @@ -1316,10 +1363,24 @@ void hostapd_ubus_event_iface_state(struct hostapd_iface *iface, int s) blobmsg_add_string(&b, "device", hapd->conf->uci_device); if (iface->ubus.obj.id) blobmsg_add_string(&b, "uobject", iface->ubus.obj.name); - blobmsg_add_u32(&b, "oldstate_num", iface->state); - blobmsg_add_string(&b, "oldstate", hostapd_state_text(iface->state)); - blobmsg_add_u32(&b, "state_num", s); - blobmsg_add_string(&b, "state", hostapd_state_text(s)); + blobmsg_add_iface_state(&b, iface, s, iface->state); + blobmsg_add_iface_channel(&b, iface); + ubus_send_event(ctx, "hostapd.iface_state", b.head); +} +void hostapd_ubus_event_ch_switch(struct hostapd_iface *iface) +{ + struct hostapd_data *hapd = iface->bss[0]; + + if (!hostapd_ubus_init()) + return; + hostapd_ubus_add_iface(iface); + blob_buf_init(&
[OpenWrt-Devel] [PATCH 5/5] hostapd: update switch_channel methods
This patch implements more complex procedure of channel switching. It can accept the list of channel features witch can contain the list of channel numbers or frequencies. There two type of operation - fast and not fast. To be more, accurate, there two operations now - switch_chan and switch_chan_list. The first accepts nearly the same arguments as old, except next: * Instead of freq and chan parameters there could be one of four: freq - the same as old, channel - the same as old, freqs - the list of frequencies and channels - the list of channels. Only one of them will be used and translates to the list of channels. The priority order is the same as listed. * There no segment 0 and 1 indexes variables. They will be predicted automatically by vht_oper_cwidth. * The variable vht_oper_chwidth could be one of VHT_CHANWIDTH_ values, or 20, 40, 80, 160 and 8080 to be more user-friendly. * New variables fast and allow_acs will be described later. The switch_can_list has bcn_count, block_tx, fast and allow_acs variables with the same meanings as in switch_chan. The list variable is a list of object with switch_chan arguments. Let's call this list the features list. The fast (defined by boolean variable fast) will try only to perform the channel_switch operation via the driver. With the most drivers and channel (except the DFS) this will successfully works. The operation will roll over features and channels lists until successful driver's switch_chan. The non-fast operation will take the first feature, assemble the chanlist configuration and restarts ap. The full configuring operation occurs including acs (if allow_acs) and DFS. The result channel will be chosen from the channel list. In case when all listed channels are prohibited by DFS the hostapd will stay switched off. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 510 -- 1 file changed, 473 insertions(+), 37 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index abbe3fac88..a3e2c00777 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -23,6 +23,8 @@ #include "rrm.h" #include "wnm_ap.h" #include "taxonomy.h" +#include "hw_features.h" +#include "common/hw_features_common.h" #define ACCT_DEFAULT_UPDATE_INTERVAL 300 @@ -153,63 +155,405 @@ hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, #ifdef NEED_AP_MLME enum { CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, + CSA_CHANNEL, + CSA_FREQS, + CSA_CHANNELS, CSA_HT, CSA_VHT, + CSA_SECONDARY_CHANNEL, + CSA_VHT_OPER_CWIDTH, + CSA_BCN_COUNT, CSA_BLOCK_TX, - __CSA_MAX + CSA_FAST, + CSA_ALLOW_ACS, + __CSA_MAX, }; static const struct blobmsg_policy csa_policy[__CSA_MAX] = { [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, - [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, - [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_CHANNEL] = { "channel", BLOBMSG_TYPE_INT32 }, + [CSA_FREQS] = { "freqs", BLOBMSG_TYPE_ARRAY }, + [CSA_CHANNELS] = { "channels", BLOBMSG_TYPE_ARRAY }, [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_SECONDARY_CHANNEL] = { "secondary_channel", BLOBMSG_TYPE_INT32 }, + [CSA_VHT_OPER_CWIDTH] = { "vht_oper_chwidth", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, + [CSA_FAST] = { "fast", BLOBMSG_TYPE_BOOL }, + [CSA_ALLOW_ACS] = { "allow_acs", BLOBMSG_TYPE_BOOL }, }; +static void ubus_adjust_vht_center_freq(struct hostapd_iface *iface, + int chan, int secondary_channel, int *vht_oper_chwidth, + int ht, int vht, + u8 *vht_oper_centr_freq_seg0_idx, + u8 *vht_oper_centr_freq_seg1_idx) +{ + *vht_oper_centr_freq_seg1_idx = 0; + if (!chan) + return; + if (!ht && !vht) { + *vht_oper_chwidth = VHT_CHANWIDTH_USE_HT; + *vht_oper_centr_freq_seg0
[OpenWrt-Devel] [PATCH 2/5] hostapd: add ubus switch_chan method to ifaces
switch_chan method now could be called directly by hostapd_iface object. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 145 +++--- 1 file changed, 86 insertions(+), 59 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index a393451af2..6d12126a1a 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -145,9 +145,88 @@ hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, return 0; } + +#ifdef NEED_AP_MLME +enum { + CSA_FREQ, + CSA_BCN_COUNT, + CSA_CENTER_FREQ1, + CSA_CENTER_FREQ2, + CSA_BANDWIDTH, + CSA_SEC_CHANNEL_OFFSET, + CSA_HT, + CSA_VHT, + CSA_BLOCK_TX, + __CSA_MAX +}; + +static const struct blobmsg_policy csa_policy[__CSA_MAX] = { + [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, + [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, + [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, + [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, +}; + +static int +hostapd_switch_chan(struct hostapd_data *hapd, struct blob_attr *msg) +{ + struct blob_attr *tb[__CSA_MAX]; + struct csa_settings css; + + blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[CSA_FREQ]) + return UBUS_STATUS_INVALID_ARGUMENT; + + memset(&css, 0, sizeof(css)); + css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); + +#define SET_CSA_SETTING(name, field, type) \ + do { \ + if (tb[name]) \ + css.field = blobmsg_get_ ## type(tb[name]); \ + } while(0) + + SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); + SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); + SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); + SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); + SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); + SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); + + + if (hostapd_switch_channel(hapd, &css) != 0) + return UBUS_STATUS_NOT_SUPPORTED; + return UBUS_STATUS_OK; +#undef SET_CSA_SETTING +} + +static int +hostapd_iface_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_iface *iface = container_of(obj, struct hostapd_iface, + ubus.obj); + if (iface && iface->bss[0]) + return hostapd_switch_chan(iface->bss[0], msg); + return UBUS_STATUS_INVALID_ARGUMENT; +} +#endif + static const struct ubus_method iface_methods[] = { UBUS_METHOD_NOARG("get_state", hostapd_iface_get_state), UBUS_METHOD_NOARG("get_bss", hostapd_iface_get_bss), +#ifdef NEED_AP_MLME + UBUS_METHOD("switch_chan", hostapd_iface_switch_chan, csa_policy), +#endif }; static struct ubus_object_type iface_object_type = UBUS_OBJECT_TYPE("hostapd_iface", iface_methods); @@ -472,69 +551,17 @@ hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -enum { - CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, - CSA_HT, - CSA_VHT, - CSA_BLOCK_TX, - __CSA_MAX -}; - -static const struct blobmsg_policy csa_policy[__CSA_MAX] = { - [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, - [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, - [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, - [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, - [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, - [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, -}; #ifdef NEED_AP_MLME static int -hostapd_switch_ch
[OpenWrt-Devel] [PATCH 4/5] hostapd: Add channel information to iface state event
This adds wide information about current channel of interface to hostapd.iface_state event. Additional event sent when interface completes csa operation. Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 8 +++ .../services/hostapd/src/src/ap/ubus.c| 69 +-- .../services/hostapd/src/src/ap/ubus.h| 4 ++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index c0db5be4e9..0bba0ba752 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -354,6 +354,14 @@ #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); +@@ -816,6 +827,7 @@ void hostapd_event_ch_switch(struct host + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED + "freq=%d dfs=%d", freq, is_dfs); + } ++hostapd_ubus_event_ch_switch(hapd->iface); + #endif /* NEED_AP_MLME */ + } + --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -162,6 +162,7 @@ void ap_free_sta(struct hostapd_data *ha diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 2ceb2de159..abbe3fac88 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -1300,6 +1300,53 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); } +static void blobmsg_add_iface_state(struct blob_buf *buff, + struct hostapd_iface *iface, int cur, int old) +{ + blobmsg_add_u32(buff, "oldstate_num", old); + blobmsg_add_string(buff, "oldstate", hostapd_state_text(old)); + blobmsg_add_u32(buff, "state_num", cur); + blobmsg_add_string(buff, "state", hostapd_state_text(cur)); +} +static void blobmsg_add_iface_channel(struct blob_buf *buff, + struct hostapd_iface *iface) +{ + struct hostapd_config *conf = iface->conf; + int width = 20; + void *chan; + + if (!iface->freq) { + return; + } + + chan = blobmsg_open_table(buff, "channel"); + + blobmsg_add_u32(buff, "freq", iface->freq); + blobmsg_add_u32(buff, "channel", conf->channel); + blobmsg_add_u8(buff, "ht", conf->ieee80211n); + blobmsg_add_u8(buff, "vht", conf->ieee80211ac); + blobmsg_add_u32(buff, "secondary_channel", conf->secondary_channel); + switch (conf->vht_oper_chwidth) { + case VHT_CHANWIDTH_USE_HT: + width = conf->secondary_channel ? 40 : 20; + break; + case VHT_CHANWIDTH_80MHZ: + width = 80; + break; + case VHT_CHANWIDTH_160MHZ: + width = 160; + break; + case VHT_CHANWIDTH_80P80MHZ: + width = 8080; + break; + } + blobmsg_add_u32(buff, "width", width); + blobmsg_add_u32(buff, "center_idx0", conf->vht_oper_centr_freq_seg0_idx); + blobmsg_add_u32(buff, "center_idx1", conf->vht_oper_centr_freq_seg1_idx); + blobmsg_add_u8(buff, "is_dfs", ieee80211_is_dfs(iface->freq, + iface->hw_features, iface->num_hw_features)); + blobmsg_close_table(buff, chan); +} /* Send ubus event in case new event differs. */ void hostapd_ubus_event_iface_state(struct hostapd_iface *iface, int s) { @@ -1316,10 +1363,24 @@ void hostapd_ubus_event_iface_state(struct hostapd_iface *iface, int s) blobmsg_add_string(&b, "device", hapd->conf->uci_device); if (iface->ubus.obj.id) blobmsg_add_string(&b, "uobject", iface->ubus.obj.name); - blobmsg_add_u32(&b, "oldstate_num", iface->state); - blobmsg_add_string(&b, "oldstate", hostapd_state_text(iface->state)); - blobmsg_add_u32(&b, "state_num", s); - blobmsg_add_string(&b, "state", hostapd_state_text(s)); + blobmsg_add_iface_state(&b, iface, s, iface->state); + blobmsg_add_iface_channel(&b, iface); + ubus_send_event(ctx, "hostapd.iface_state", b.head); +} +void hostapd_ubus_event_ch_switch(struct hostapd_iface *iface) +{ + struct hostapd_data *hapd = iface->bss[0]; + + if (!hostapd_ubus_init()) + return; + hostapd_ubus_add_iface(iface); + blob_buf_init(&
[OpenWrt-Devel] [PATCH 2/5] hostapd: add ubus switch_chan method to ifaces
switch_chan method now could be called directly by hostapd_iface object. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 145 +++--- 1 file changed, 86 insertions(+), 59 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index a393451af2..6d12126a1a 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -145,9 +145,88 @@ hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, return 0; } + +#ifdef NEED_AP_MLME +enum { + CSA_FREQ, + CSA_BCN_COUNT, + CSA_CENTER_FREQ1, + CSA_CENTER_FREQ2, + CSA_BANDWIDTH, + CSA_SEC_CHANNEL_OFFSET, + CSA_HT, + CSA_VHT, + CSA_BLOCK_TX, + __CSA_MAX +}; + +static const struct blobmsg_policy csa_policy[__CSA_MAX] = { + [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, + [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, + [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, + [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, +}; + +static int +hostapd_switch_chan(struct hostapd_data *hapd, struct blob_attr *msg) +{ + struct blob_attr *tb[__CSA_MAX]; + struct csa_settings css; + + blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[CSA_FREQ]) + return UBUS_STATUS_INVALID_ARGUMENT; + + memset(&css, 0, sizeof(css)); + css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); + +#define SET_CSA_SETTING(name, field, type) \ + do { \ + if (tb[name]) \ + css.field = blobmsg_get_ ## type(tb[name]); \ + } while(0) + + SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); + SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); + SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); + SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); + SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); + SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); + + + if (hostapd_switch_channel(hapd, &css) != 0) + return UBUS_STATUS_NOT_SUPPORTED; + return UBUS_STATUS_OK; +#undef SET_CSA_SETTING +} + +static int +hostapd_iface_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_iface *iface = container_of(obj, struct hostapd_iface, + ubus.obj); + if (iface && iface->bss[0]) + return hostapd_switch_chan(iface->bss[0], msg); + return UBUS_STATUS_INVALID_ARGUMENT; +} +#endif + static const struct ubus_method iface_methods[] = { UBUS_METHOD_NOARG("get_state", hostapd_iface_get_state), UBUS_METHOD_NOARG("get_bss", hostapd_iface_get_bss), +#ifdef NEED_AP_MLME + UBUS_METHOD("switch_chan", hostapd_iface_switch_chan, csa_policy), +#endif }; static struct ubus_object_type iface_object_type = UBUS_OBJECT_TYPE("hostapd_iface", iface_methods); @@ -472,69 +551,17 @@ hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -enum { - CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, - CSA_HT, - CSA_VHT, - CSA_BLOCK_TX, - __CSA_MAX -}; - -static const struct blobmsg_policy csa_policy[__CSA_MAX] = { - [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, - [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, - [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, - [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, - [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, - [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, -}; #ifdef NEED_AP_MLME static int -hostapd_switch_ch
[OpenWrt-Devel] [PATCH 5/5] hostapd: update switch_channel methods
This patch implements more complex procedure of channel switching. It can accept the list of channel features witch can contain the list of channel numbers or frequencies. There two type of operation - fast and not fast. To be more, accurate, there two operations now - switch_chan and switch_chan_list. The first accepts nearly the same arguments as old, except next: * Instead of freq and chan parameters there could be one of four: freq - the same as old, channel - the same as old, freqs - the list of frequencies and channels - the list of channels. Only one of them will be used and translates to the list of channels. The priority order is the same as listed. * There no segment 0 and 1 indexes variables. They will be predicted automatically by vht_oper_cwidth. * The variable vht_oper_chwidth could be one of VHT_CHANWIDTH_ values, or 20, 40, 80, 160 and 8080 to be more user-friendly. * New variables fast and allow_acs will be described later. The switch_can_list has bcn_count, block_tx, fast and allow_acs variables with the same meanings as in switch_chan. The list variable is a list of object with switch_chan arguments. Let's call this list the features list. The fast (defined by boolean variable fast) will try only to perform the channel_switch operation via the driver. With the most drivers and channel (except the DFS) this will successfully works. The operation will roll over features and channels lists until successful driver's switch_chan. The non-fast operation will take the first feature, assemble the chanlist configuration and restarts ap. The full configuring operation occurs including acs (if allow_acs) and DFS. The result channel will be chosen from the channel list. In case when all listed channels are prohibited by DFS the hostapd will stay switched off. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 510 -- 1 file changed, 473 insertions(+), 37 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index abbe3fac88..a3e2c00777 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -23,6 +23,8 @@ #include "rrm.h" #include "wnm_ap.h" #include "taxonomy.h" +#include "hw_features.h" +#include "common/hw_features_common.h" #define ACCT_DEFAULT_UPDATE_INTERVAL 300 @@ -153,63 +155,405 @@ hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, #ifdef NEED_AP_MLME enum { CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, + CSA_CHANNEL, + CSA_FREQS, + CSA_CHANNELS, CSA_HT, CSA_VHT, + CSA_SECONDARY_CHANNEL, + CSA_VHT_OPER_CWIDTH, + CSA_BCN_COUNT, CSA_BLOCK_TX, - __CSA_MAX + CSA_FAST, + CSA_ALLOW_ACS, + __CSA_MAX, }; static const struct blobmsg_policy csa_policy[__CSA_MAX] = { [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, - [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, - [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_CHANNEL] = { "channel", BLOBMSG_TYPE_INT32 }, + [CSA_FREQS] = { "freqs", BLOBMSG_TYPE_ARRAY }, + [CSA_CHANNELS] = { "channels", BLOBMSG_TYPE_ARRAY }, [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_SECONDARY_CHANNEL] = { "secondary_channel", BLOBMSG_TYPE_INT32 }, + [CSA_VHT_OPER_CWIDTH] = { "vht_oper_chwidth", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, + [CSA_FAST] = { "fast", BLOBMSG_TYPE_BOOL }, + [CSA_ALLOW_ACS] = { "allow_acs", BLOBMSG_TYPE_BOOL }, }; +static void ubus_adjust_vht_center_freq(struct hostapd_iface *iface, + int chan, int secondary_channel, int *vht_oper_chwidth, + int ht, int vht, + u8 *vht_oper_centr_freq_seg0_idx, + u8 *vht_oper_centr_freq_seg1_idx) +{ + *vht_oper_centr_freq_seg1_idx = 0; + if (!chan) + return; + if (!ht && !vht) { + *vht_oper_chwidth = VHT_CHANWIDTH_USE_HT; + *vht_oper_centr_freq_seg0
[OpenWrt-Devel] [PATCH 1/5] hostapd: add ubus hostapd_iface object
Ubus hostapd_iface object has get_state and get_bss methods, this patch additionally sends events with interfaces' states. This allows outer system to watch interfaces prior they enabled and handle the errors. This actually reverts the f0ac9afe695ed297caf093f02144b2adf04bca87 patch and adds functionality using hostapd_ubus_iface struct. Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 54 +++- .../services/hostapd/src/src/ap/ubus.c| 127 ++ .../services/hostapd/src/src/ap/ubus.h| 13 ++ 3 files changed, 193 insertions(+), 1 deletion(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index cb2c54d57c..c63b85c079 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -30,7 +30,16 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -544,6 +546,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -392,6 +394,8 @@ struct hostapd_iface { + struct hostapd_config *conf; + char phy[16]; /* Name of the PHY (radio) */ + ++ struct hostapd_ubus_iface ubus; ++ + enum hostapd_iface_state { + HAPD_IFACE_UNINITIALIZED, + HAPD_IFACE_DISABLED, +@@ -544,6 +548,7 @@ hostapd_alloc_bss_data(struct hostapd_if struct hostapd_bss_config *bss); int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); @@ -90,6 +99,14 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); +@@ -3114,6 +3120,7 @@ void hostapd_set_state(struct hostapd_if + wpa_printf(MSG_INFO, "%s: interface state %s->%s", + iface->conf ? iface->conf->bss[0]->iface : "N/A", + hostapd_state_text(iface->state), hostapd_state_text(s)); ++ hostapd_ubus_event_iface_state(iface, s); + iface->state = s; + } + --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1712,12 +1712,13 @@ ieee802_11_set_radius_info(struct hostap @@ -341,3 +358,38 @@ } +--- a/hostapd/config_file.c b/hostapd/config_file.c +@@ -2663,6 +2663,11 @@ static int hostapd_config_fill(struct ho + 0) { + bss->radius_das_require_message_authenticator = atoi(pos); + #endif /* CONFIG_NO_RADIUS */ ++#ifdef UBUS_SUPPORT ++ } else if (os_strcmp(buf, "uci_device") == 0) { ++ os_free(bss->uci_device); ++ bss->uci_device = os_strdup(pos); ++#endif /* UBUS_SUPPORT */ + } else if (os_strcmp(buf, "auth_algs") == 0) { + bss->auth_algs = atoi(pos); + if (bss->auth_algs == 0) { +--- a/src/ap/ap_config.c b/src/ap/ap_config.c +@@ -587,6 +587,7 @@ void hostapd_config_free_bss(struct host + os_free(conf->model_description); + os_free(conf->model_url); + os_free(conf->upc); ++ os_free(conf->uci_device); + { + unsigned int i; + +--- a/src/ap/ap_config.h b/src/ap/ap_config.h +@@ -470,6 +470,8 @@ struct hostapd_bss_config { + int pbc_in_m1; + char *server_id; + ++ char *uci_device; ++ + #define P2P_ENABLED BIT(0) + #define P2P_GROUP_OWNER BIT(1) + #define P2P_GROUP_FORMATION BIT(2) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 3375ac49f7..a393451af2 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -92,16 +92,109 @@ static void hostapd_ubus_ref_dec(void) ctx = NULL; } +static int +hostapd_iface_get_state(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_iface *iface = container_of(obj, struct hostapd_iface, + ubus.obj); + + blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "state_num", iface->state); + blobmsg_add_string(&b, "state", hostapd_state_text(iface->state)); + blobmsg_add_u32(&b, "freq", iface->freq); + if (iface->bss[0] && iface->bss[0]->conf->uci_device) + blobmsg_add_string(&b, "device", iface->bss[0]->conf->uci_device); + ubus_send_reply(ctx, req, b.head); + + return 0; +} +static int +hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, + struct
[OpenWrt-Devel] [PATCH 3/5] hostapd: Add ubus accounting
This implements ubus accounting events. This accounting works the same manner as the RADIUS accounting, except the interim (see below). There tree types of messages: start, stop and interim. Start sent when new client connected. There just current time, address and session_id of client in message. Stop sent when client disconnected. This message contains extra counters and terminate_cause. Interim sent by timeout, configured with ubus_accounting_interval variable. This message contains an information about all connected to bss clients. Payload example: { "clients": [ { "session_time": 9, "address": "68:3e:34:f5:61:3f", "session_id": "A6367C8F6C0662C1", "accounting": { "rx_bytes": 2336, "tx_packets": 5, "tx_bytes": 533, "rx_packets": 17 }, "terminate_cause": 1 } ], "device": "radio0", "bssid": "44:d1:fa:12:4c:74", "freq": 5260, "iface": "wlan0" } Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 165 +++- .../services/hostapd/src/src/ap/ubus.c| 238 +- .../services/hostapd/src/src/ap/ubus.h| 14 ++ 3 files changed, 405 insertions(+), 12 deletions(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index c63b85c079..c0db5be4e9 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -99,7 +99,15 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); -@@ -3114,6 +3120,7 @@ void hostapd_set_state(struct hostapd_if +@@ -3050,6 +3056,7 @@ void hostapd_new_assoc_sta(struct hostap + ap_sta_set_authorized(hapd, sta, 1); + os_get_reltime(&sta->connected_time); + accounting_sta_start(hapd, sta); ++ hostapd_ubus_event_sta_account_start(hapd,sta); + } + + /* Start IEEE 802.1X authentication process for new stations */ +@@ -3114,6 +3121,7 @@ void hostapd_set_state(struct hostapd_if wpa_printf(MSG_INFO, "%s: interface state %s->%s", iface->conf ? iface->conf->bss[0]->iface : "N/A", hostapd_state_text(iface->state), hostapd_state_text(s)); @@ -201,7 +209,15 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { -@@ -3630,6 +3657,8 @@ static void handle_deauth(struct hostapd +@@ -3584,6 +3611,7 @@ static void handle_disassoc(struct hosta + /* Stop Accounting and IEEE 802.1X sessions, but leave the STA +* authenticated. */ + accounting_sta_stop(hapd, sta); ++ hostapd_ubus_event_sta_account_stop(hapd, sta); + ieee802_1x_free_station(hapd, sta); + if (sta->ipaddr) + hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr); +@@ -3630,6 +3658,8 @@ static void handle_deauth(struct hostapd " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); @@ -210,7 +226,7 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " -@@ -3949,7 +3978,7 @@ int ieee802_11_mgmt(struct hostapd_data +@@ -3949,7 +3979,7 @@ int ieee802_11_mgmt(struct hostapd_data if (stype == WLAN_FC_STYPE_PROBE_REQ) { @@ -219,7 +235,7 @@ return 1; } -@@ -3969,17 +3998,17 @@ int ieee802_11_mgmt(struct hostapd_data +@@ -3969,17 +3999,17 @@ int ieee802_11_mgmt(struct hostapd_data switch (stype) { case WLAN_FC_STYPE_AUTH: wpa_printf(MSG_DEBUG, "mgmt::auth"); @@ -240,6 +256,14 @@ ret = 1; break; case WLAN_FC_STYPE_DISASSOC: +@@ -4128,6 +4158,7 @@ static void handle_assoc_cb(struct hosta + /* Stop previous accounting session, if one is started, and allocate +* new session id for the new session. */ + accounting_sta_stop(hapd, sta); ++ hostapd_ubus_event_sta_account_stop(hapd, sta); + + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -720,7 +720,7 @@ void sta_track_claim_taxonomy_info(struc @@ -309,7 +333,15 @@ if (addr == NULL) { /* -@@ -195,6 +199,12 @@ int hostapd_notif_assoc(struct hostapd_d +@@ -164,6 +168,7 @@ in
[OpenWrt-Devel] [PATCH 1/5] hostapd: add ubus hostapd_iface object
Ubus hostapd_iface object has get_state and get_bss methods, this patch additionally sends events with interfaces' states. This allows outer system to watch interfaces prior they enabled and handle the errors. This actually reverts the f0ac9afe695ed297caf093f02144b2adf04bca87 patch and adds functionality using hostapd_ubus_iface struct. Signed-off-by: Yury Shvedov --- .../hostapd/patches/600-ubus_support.patch| 54 +++- .../services/hostapd/src/src/ap/ubus.c| 127 ++ .../services/hostapd/src/src/ap/ubus.h| 13 ++ 3 files changed, 193 insertions(+), 1 deletion(-) diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch index cb2c54d57c..c63b85c079 100644 --- a/package/network/services/hostapd/patches/600-ubus_support.patch +++ b/package/network/services/hostapd/patches/600-ubus_support.patch @@ -30,7 +30,16 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -544,6 +546,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -392,6 +394,8 @@ struct hostapd_iface { + struct hostapd_config *conf; + char phy[16]; /* Name of the PHY (radio) */ + ++ struct hostapd_ubus_iface ubus; ++ + enum hostapd_iface_state { + HAPD_IFACE_UNINITIALIZED, + HAPD_IFACE_DISABLED, +@@ -544,6 +548,7 @@ hostapd_alloc_bss_data(struct hostapd_if struct hostapd_bss_config *bss); int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); @@ -90,6 +99,14 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); +@@ -3114,6 +3120,7 @@ void hostapd_set_state(struct hostapd_if + wpa_printf(MSG_INFO, "%s: interface state %s->%s", + iface->conf ? iface->conf->bss[0]->iface : "N/A", + hostapd_state_text(iface->state), hostapd_state_text(s)); ++ hostapd_ubus_event_iface_state(iface, s); + iface->state = s; + } + --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1712,12 +1712,13 @@ ieee802_11_set_radius_info(struct hostap @@ -341,3 +358,38 @@ } +--- a/hostapd/config_file.c b/hostapd/config_file.c +@@ -2663,6 +2663,11 @@ static int hostapd_config_fill(struct ho + 0) { + bss->radius_das_require_message_authenticator = atoi(pos); + #endif /* CONFIG_NO_RADIUS */ ++#ifdef UBUS_SUPPORT ++ } else if (os_strcmp(buf, "uci_device") == 0) { ++ os_free(bss->uci_device); ++ bss->uci_device = os_strdup(pos); ++#endif /* UBUS_SUPPORT */ + } else if (os_strcmp(buf, "auth_algs") == 0) { + bss->auth_algs = atoi(pos); + if (bss->auth_algs == 0) { +--- a/src/ap/ap_config.c b/src/ap/ap_config.c +@@ -587,6 +587,7 @@ void hostapd_config_free_bss(struct host + os_free(conf->model_description); + os_free(conf->model_url); + os_free(conf->upc); ++ os_free(conf->uci_device); + { + unsigned int i; + +--- a/src/ap/ap_config.h b/src/ap/ap_config.h +@@ -470,6 +470,8 @@ struct hostapd_bss_config { + int pbc_in_m1; + char *server_id; + ++ char *uci_device; ++ + #define P2P_ENABLED BIT(0) + #define P2P_GROUP_OWNER BIT(1) + #define P2P_GROUP_FORMATION BIT(2) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 3375ac49f7..a393451af2 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -92,16 +92,109 @@ static void hostapd_ubus_ref_dec(void) ctx = NULL; } +static int +hostapd_iface_get_state(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_iface *iface = container_of(obj, struct hostapd_iface, + ubus.obj); + + blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "state_num", iface->state); + blobmsg_add_string(&b, "state", hostapd_state_text(iface->state)); + blobmsg_add_u32(&b, "freq", iface->freq); + if (iface->bss[0] && iface->bss[0]->conf->uci_device) + blobmsg_add_string(&b, "device", iface->bss[0]->conf->uci_device); + ubus_send_reply(ctx, req, b.head); + + return 0; +} +static int +hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, + struct
Re: [OpenWrt-Devel] [PATCH 2/5] hostapd: add ubus switch_chan method to ifaces
Hi! Here is the series of patches on hostapd, I'm using in my project. They are introduces more informative communication with ubus, used by me. I thought it could be useful for someone. But something hell strange happened with the series while sending. Sorry for this mess. Can someone explain what is wrong? The git-send-email messages was okay. I tried to send the series twice. The second attempt - with --thread and --in-reply to 3/5 patch. On 10/8/18 3:28 PM, Yury Shvedov wrote: switch_chan method now could be called directly by hostapd_iface object. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 145 +++--- 1 file changed, 86 insertions(+), 59 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index a393451af2..6d12126a1a 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -145,9 +145,88 @@ hostapd_iface_get_bss(struct ubus_context *ctx, struct ubus_object *obj, return 0; } + +#ifdef NEED_AP_MLME +enum { + CSA_FREQ, + CSA_BCN_COUNT, + CSA_CENTER_FREQ1, + CSA_CENTER_FREQ2, + CSA_BANDWIDTH, + CSA_SEC_CHANNEL_OFFSET, + CSA_HT, + CSA_VHT, + CSA_BLOCK_TX, + __CSA_MAX +}; + +static const struct blobmsg_policy csa_policy[__CSA_MAX] = { + [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, + [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, + [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, + [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, + [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, +}; + +static int +hostapd_switch_chan(struct hostapd_data *hapd, struct blob_attr *msg) +{ + struct blob_attr *tb[__CSA_MAX]; + struct csa_settings css; + + blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[CSA_FREQ]) + return UBUS_STATUS_INVALID_ARGUMENT; + + memset(&css, 0, sizeof(css)); + css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); + +#define SET_CSA_SETTING(name, field, type) \ + do { \ + if (tb[name]) \ + css.field = blobmsg_get_ ## type(tb[name]); \ + } while(0) + + SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); + SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); + SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); + SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); + SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); + SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); + + + if (hostapd_switch_channel(hapd, &css) != 0) + return UBUS_STATUS_NOT_SUPPORTED; + return UBUS_STATUS_OK; +#undef SET_CSA_SETTING +} + +static int +hostapd_iface_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_iface *iface = container_of(obj, struct hostapd_iface, + ubus.obj); + if (iface && iface->bss[0]) + return hostapd_switch_chan(iface->bss[0], msg); + return UBUS_STATUS_INVALID_ARGUMENT; +} +#endif + static const struct ubus_method iface_methods[] = { UBUS_METHOD_NOARG("get_state", hostapd_iface_get_state), UBUS_METHOD_NOARG("get_bss", hostapd_iface_get_bss), +#ifdef NEED_AP_MLME + UBUS_METHOD("switch_chan", hostapd_iface_switch_chan, csa_policy), +#endif }; static struct ubus_object_type iface_object_type = UBUS_OBJECT_TYPE("hostapd_iface", iface_methods); @@ -472,69 +551,17 @@ hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -enum { - CSA_FREQ, - CSA_BCN_COUNT, - CSA_CENTER_FREQ1, - CSA_CENTER_FREQ2, - CSA_BANDWIDTH, - CSA_SEC_CHANNEL_OFFSET, - CSA_HT, - CSA_VHT, - CSA_BLOCK_TX, - __CSA_MAX -}; - -static const struct blobmsg_policy csa_policy[__CSA_MAX] = { - [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, - [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, - [CSA_CENTER_FREQ1] = { "center_freq1"
[OpenWrt-Devel] [PATCH 1/2] add htmodelist for scan results
The knowledge about HT and VHT modes could be useful for user experience. So grab it via nl80211 and make it available in both C and LUA APIs, and show htmodelist on CLI scan results. --- include/iwinfo.h | 1 + iwinfo_cli.c | 13 ++-- iwinfo_lua.c | 16 +- iwinfo_nl80211.c | 77 4 files changed, 104 insertions(+), 3 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index 929f697..c3c25ff 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -154,6 +154,7 @@ struct iwinfo_scanlist_entry { uint8_t signal; uint8_t quality; uint8_t quality_max; +int htmodelist; struct iwinfo_crypto_entry crypto; }; diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 49c9035..2d58020 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -572,7 +572,7 @@ static void print_info(const struct iwinfo_ops *iw, const char *ifname) static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) { - int i, x, len; + int i, h, x, len; char buf[IWINFO_BUFSIZE]; struct iwinfo_scanlist_entry *e; @@ -603,8 +603,17 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) format_signal(e->signal - 0x100), format_quality(e->quality), format_quality_max(e->quality_max)); - printf(" Encryption: %s\n\n", + printf(" Encryption: %s\n", format_encryption(&e->crypto)); + if (e->htmodelist) + { + printf(" HT Capabilities: "); + for (h = 0; h < ARRAY_SIZE(IWINFO_HTMODE_NAMES); h++) + if (e->htmodelist & (1 << h)) + printf("%s ", IWINFO_HTMODE_NAMES[h]); + printf ("\n"); + } + printf ("\n"); } } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index eebab8e..01581a3 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -378,7 +378,7 @@ static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, in /* Wrapper for scan list */ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int *)) { - int i, x, len = 0; + int i, x, h, len = 0; char rv[IWINFO_BUFSIZE]; char macstr[18]; const char *ifname = luaL_checkstring(L, 1); @@ -432,6 +432,20 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int iwinfo_L_cryptotable(L, &e->crypto); lua_setfield(L, -2, "encryption"); + /* HT Modes */ + if (e->htmodelist) + { + lua_newtable(L); + for (h = 0; h < ARRAY_SIZE(IWINFO_HTMODE_NAMES); h++) + { + lua_pushboolean(L, e->htmodelist & (1 << h)); + lua_setfield(L, -2, IWINFO_HTMODE_NAMES[h]); + } + } + else + lua_pushnil(L); + lua_setfield(L, -2, "htmodelist"); + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index ecd2d6a..542ac7d 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1980,6 +1980,71 @@ struct nl80211_scanlist { int len; }; +static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + int capa; + if (len < 2) + return; + e->htmodelist |= IWINFO_HTMODE_HT20; + capa = ie[0] | (ie[8] << 8); + if (capa & (1 << 1)) + { + e->htmodelist |= IWINFO_HTMODE_HT40; + if (e->htmodelist & IWINFO_HTMODE_VHT20) + e->htmodelist |= IWINFO_HTMODE_VHT40; + } +} +static void nl80211_parse_vht_capa(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + int capa; + if (len < 4) + return; + capa = ie[0] | (ie[1] << 8) | (ie[2] << 16) | (ie[3] << 24); + + e->htmodelist |= IWINFO_HTMODE_VHT20; + if (e->htmodelist & IWINFO_HTMODE_HT40) + e->htmodelist |= IWINFO_HTMODE_VHT40; + + switch ((capa >> 2) & 3) { + /*case 0: neither 160 nor 80+80 */ + case 1: + e->htmodelist |= IWINFO_HTMODE_VHT160; + break; + case 2: + e->htmodelist |= IWINF
[OpenWrt-Devel] [PATCH 2/2] add channel information for scan results
Besides channel number the secondary channel for HT40 and center idx0 and idx1 gives full understanding about real channel position and width on the spectra. So grab it via nl80211 and make it available in both C and LUA APIs, and show detailed channel information on CLI scan results. --- include/iwinfo.h | 21 - iwinfo_cli.c | 10 ++ iwinfo_lua.c | 11 +++ iwinfo_nl80211.c | 32 ++-- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index c3c25ff..b1b39a1 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -145,6 +145,24 @@ struct iwinfo_crypto_entry { uint8_t auth_suites; uint8_t auth_algs; }; +struct iwinfo_channel_info_entry { + /** +* sec_channel_offset - Secondary channel offset for HT40 +* +* 0 = HT40 disabled, +* -1 = HT40 enabled, secondary channel below primary, +* 1 = HT40 enabled, secondary channel above primary +*/ + int sec_channel_offset; + /** +* Center channel for VHT80 +*/ + int center_idx0; + /** +* Center channel for VHT160 +*/ + int center_idx1; +}; struct iwinfo_scanlist_entry { uint8_t mac[6]; @@ -154,8 +172,9 @@ struct iwinfo_scanlist_entry { uint8_t signal; uint8_t quality; uint8_t quality_max; -int htmodelist; + int htmodelist; struct iwinfo_crypto_entry crypto; + struct iwinfo_channel_info_entry channel_info; }; struct iwinfo_country_entry { diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 2d58020..0d899e0 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -612,6 +612,16 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) if (e->htmodelist & (1 << h)) printf("%s ", IWINFO_HTMODE_NAMES[h]); printf ("\n"); + if (e->channel_info.sec_channel_offset) + printf (" HT secondary channel is %s\n", + e->channel_info.sec_channel_offset < 0 ? "below" : + "above"); + if (e->channel_info.center_idx0) + printf (" VHT Center IDX0: %d\n", + e->channel_info.center_idx0); + if (e->channel_info.center_idx1) + printf (" VHT Center IDX1: %d\n", + e->channel_info.center_idx1); } printf ("\n"); } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index 01581a3..bd7f0d3 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -446,6 +446,17 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int lua_pushnil(L); lua_setfield(L, -2, "htmodelist"); + lua_pushinteger(L, e->channel_info.sec_channel_offset); + lua_setfield(L, -2, "sec_channel_offset"); + if (e->channel_info.center_idx0) { + lua_pushinteger(L, e->channel_info.center_idx0); + lua_setfield(L, -2, "center_idx0"); + } + if (e->channel_info.center_idx1) { + lua_pushinteger(L, e->channel_info.center_idx1); + lua_setfield(L, -2, "center_idx1"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 542ac7d..fb137b2 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1996,6 +1996,27 @@ static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, e->htmodelist |= IWINFO_HTMODE_VHT40; } } +static void nl80211_parse_ht_oper(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + uint8_t oper_info; + + if (len < 6) + return; + oper_info = ie[1]; + switch (oper_info & 3) { + case 0: + e->channel_info.sec_channel_offset = 0; + break; + case 1: + e->channel_info.sec_channel_offset = 1; + break; + case 3: + e->channel_info.sec_channel_offset = -1; + break; + } +} static void nl80211_parse_vht_capa(struct iwinfo_scanlist_entry *e, unsigned char *ie, int
Re: [OpenWrt-Devel] [PATCH 2/2] add channel information for scan results
Hi! This patches are for iwinfo repo. I think I sent them to the wrong place. Please, say me so. This patches add extra information to scan list. I've made them for my own usage. But they may be useful for someone. On 07/13/2018 11:57 AM, Yury Shvedov wrote: Besides channel number the secondary channel for HT40 and center idx0 and idx1 gives full understanding about real channel position and width on the spectra. So grab it via nl80211 and make it available in both C and LUA APIs, and show detailed channel information on CLI scan results. --- include/iwinfo.h | 21 - iwinfo_cli.c | 10 ++ iwinfo_lua.c | 11 +++ iwinfo_nl80211.c | 32 ++-- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index c3c25ff..b1b39a1 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -145,6 +145,24 @@ struct iwinfo_crypto_entry { uint8_t auth_suites; uint8_t auth_algs; }; +struct iwinfo_channel_info_entry { + /** +* sec_channel_offset - Secondary channel offset for HT40 +* +* 0 = HT40 disabled, +* -1 = HT40 enabled, secondary channel below primary, +* 1 = HT40 enabled, secondary channel above primary +*/ + int sec_channel_offset; + /** +* Center channel for VHT80 +*/ + int center_idx0; + /** +* Center channel for VHT160 +*/ + int center_idx1; +}; struct iwinfo_scanlist_entry { uint8_t mac[6]; @@ -154,8 +172,9 @@ struct iwinfo_scanlist_entry { uint8_t signal; uint8_t quality; uint8_t quality_max; -int htmodelist; + int htmodelist; struct iwinfo_crypto_entry crypto; + struct iwinfo_channel_info_entry channel_info; }; struct iwinfo_country_entry { diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 2d58020..0d899e0 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -612,6 +612,16 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) if (e->htmodelist & (1 << h)) printf("%s ", IWINFO_HTMODE_NAMES[h]); printf ("\n"); + if (e->channel_info.sec_channel_offset) + printf (" HT secondary channel is %s\n", + e->channel_info.sec_channel_offset < 0 ? "below" : + "above"); + if (e->channel_info.center_idx0) + printf (" VHT Center IDX0: %d\n", + e->channel_info.center_idx0); + if (e->channel_info.center_idx1) + printf (" VHT Center IDX1: %d\n", + e->channel_info.center_idx1); } printf ("\n"); } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index 01581a3..bd7f0d3 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -446,6 +446,17 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int lua_pushnil(L); lua_setfield(L, -2, "htmodelist"); + lua_pushinteger(L, e->channel_info.sec_channel_offset); + lua_setfield(L, -2, "sec_channel_offset"); + if (e->channel_info.center_idx0) { + lua_pushinteger(L, e->channel_info.center_idx0); + lua_setfield(L, -2, "center_idx0"); + } + if (e->channel_info.center_idx1) { + lua_pushinteger(L, e->channel_info.center_idx1); + lua_setfield(L, -2, "center_idx1"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 542ac7d..fb137b2 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1996,6 +1996,27 @@ static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, e->htmodelist |= IWINFO_HTMODE_VHT40; } } +static void nl80211_parse_ht_oper(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + uint8_t oper_info; + + if (len < 6) + return; + oper_info = ie[1]; + switch (oper_info & 3) { + case 0: + e->channel_info.sec_channel_offset =
[OpenWrt-Devel] [PATCH 2/2] add channel information for scan results
Besides channel number the secondary channel for HT40 and center idx0 and idx1 gives full understanding about real channel position and width on the spectra. So grab it via nl80211 and make it available in both C and LUA APIs, and show detailed channel information on CLI scan results. Signed-off-by: Yury Shvedov --- include/iwinfo.h | 19 +++ iwinfo_cli.c | 10 ++ iwinfo_lua.c | 11 +++ iwinfo_nl80211.c | 32 ++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index b3f5470..1559837 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -145,6 +145,24 @@ struct iwinfo_crypto_entry { uint8_t auth_suites; uint8_t auth_algs; }; +struct iwinfo_channel_info_entry { + /** +* sec_channel_offset - Secondary channel offset for HT40 +* +* 0 = HT40 disabled, +* -1 = HT40 enabled, secondary channel below primary, +* 1 = HT40 enabled, secondary channel above primary +*/ + int8_t sec_channel_offset; + /** +* Center channel for VHT80 +*/ + uint8_t center_idx0; + /** +* Center channel for VHT160 +*/ + uint8_t center_idx1; +}; struct iwinfo_scanlist_entry { uint8_t mac[6]; @@ -156,6 +174,7 @@ struct iwinfo_scanlist_entry { uint8_t quality_max; uint16_t htmodelist; struct iwinfo_crypto_entry crypto; + struct iwinfo_channel_info_entry channel_info; }; struct iwinfo_country_entry { diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 0429fbc..7bd2da2 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -612,6 +612,16 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) if (e->htmodelist & (1 << h)) printf("%s ", IWINFO_HTMODE_NAMES[h]); printf("\n"); + if (e->channel_info.sec_channel_offset) + printf(" HT secondary channel is %s\n", + e->channel_info.sec_channel_offset < 0 ? "below" : + "above"); + if (e->channel_info.center_idx0) + printf(" VHT Center IDX0: %d\n", + e->channel_info.center_idx0); + if (e->channel_info.center_idx1) + printf(" VHT Center IDX1: %d\n", + e->channel_info.center_idx1); } printf("\n"); } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index 303fd08..9f95017 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -444,6 +444,17 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int lua_setfield(L, -2, "htmodelist"); } + lua_pushinteger(L, e->channel_info.sec_channel_offset); + lua_setfield(L, -2, "sec_channel_offset"); + if (e->channel_info.center_idx0) { + lua_pushinteger(L, e->channel_info.center_idx0); + lua_setfield(L, -2, "center_idx0"); + } + if (e->channel_info.center_idx1) { + lua_pushinteger(L, e->channel_info.center_idx1); + lua_setfield(L, -2, "center_idx1"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 542ac7d..fb137b2 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1996,6 +1996,27 @@ static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, e->htmodelist |= IWINFO_HTMODE_VHT40; } } +static void nl80211_parse_ht_oper(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + uint8_t oper_info; + + if (len < 6) + return; + oper_info = ie[1]; + switch (oper_info & 3) { + case 0: + e->channel_info.sec_channel_offset = 0; + break; + case 1: + e->channel_info.sec_channel_offset = 1; + break; + case 3: + e->channel_info.sec_channel_offset = -1; + break; + } +} static void nl80211_parse_vht_capa(struct iwinfo_scanlist_entry *e,
[OpenWrt-Devel] [PATCH 1/2] add htmodelist for scan results
The knowledge about HT and VHT modes could be useful for user experience. So grab it via nl80211 and make it available in both C and LUA APIs, and show htmodelist on CLI scan results. Signed-off-by: Yury Shvedov --- include/iwinfo.h | 1 + iwinfo_cli.c | 13 ++-- iwinfo_lua.c | 14 - iwinfo_nl80211.c | 77 4 files changed, 102 insertions(+), 3 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index 929f697..b3f5470 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -154,6 +154,7 @@ struct iwinfo_scanlist_entry { uint8_t signal; uint8_t quality; uint8_t quality_max; +uint16_t htmodelist; struct iwinfo_crypto_entry crypto; }; diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 49c9035..0429fbc 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -572,7 +572,7 @@ static void print_info(const struct iwinfo_ops *iw, const char *ifname) static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) { - int i, x, len; + int i, h, x, len; char buf[IWINFO_BUFSIZE]; struct iwinfo_scanlist_entry *e; @@ -603,8 +603,17 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) format_signal(e->signal - 0x100), format_quality(e->quality), format_quality_max(e->quality_max)); - printf(" Encryption: %s\n\n", + printf(" Encryption: %s\n", format_encryption(&e->crypto)); + if (e->htmodelist) + { + printf(" HT Capabilities: "); + for (h = 0; h < ARRAY_SIZE(IWINFO_HTMODE_NAMES); h++) + if (e->htmodelist & (1 << h)) + printf("%s ", IWINFO_HTMODE_NAMES[h]); + printf("\n"); + } + printf("\n"); } } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index eebab8e..303fd08 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -378,7 +378,7 @@ static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, in /* Wrapper for scan list */ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int *)) { - int i, x, len = 0; + int i, x, h, len = 0; char rv[IWINFO_BUFSIZE]; char macstr[18]; const char *ifname = luaL_checkstring(L, 1); @@ -432,6 +432,18 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int iwinfo_L_cryptotable(L, &e->crypto); lua_setfield(L, -2, "encryption"); + /* HT Modes */ + if (e->htmodelist) + { + lua_newtable(L); + for (h = 0; h < ARRAY_SIZE(IWINFO_HTMODE_NAMES); h++) + { + lua_pushboolean(L, e->htmodelist & (1 << h)); + lua_setfield(L, -2, IWINFO_HTMODE_NAMES[h]); + } +lua_setfield(L, -2, "htmodelist"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index ecd2d6a..542ac7d 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1980,6 +1980,71 @@ struct nl80211_scanlist { int len; }; +static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + int capa; + if (len < 2) + return; + e->htmodelist |= IWINFO_HTMODE_HT20; + capa = ie[0] | (ie[8] << 8); + if (capa & (1 << 1)) + { + e->htmodelist |= IWINFO_HTMODE_HT40; + if (e->htmodelist & IWINFO_HTMODE_VHT20) + e->htmodelist |= IWINFO_HTMODE_VHT40; + } +} +static void nl80211_parse_vht_capa(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + int capa; + if (len < 4) + return; + capa = ie[0] | (ie[1] << 8) | (ie[2] << 16) | (ie[3] << 24); + + e->htmodelist |= IWINFO_HTMODE_VHT20; + if (e->htmodelist & IWINFO_HTMODE_HT40) + e->htmodelist |= IWINFO_HTMODE_VHT40; + + switch ((capa >> 2) & 3) { + /*c
[OpenWrt-Devel] [PATCH 2/2] add channel information for scan results
Sorry, some mistakes in previous patch. Besides channel number the secondary channel for HT40 and center idx0 and idx1 gives full understanding about real channel position and width on the spectra. So grab it via nl80211 and make it available in both C and LUA APIs, and show detailed channel information on CLI scan results. Signed-off-by: Yury Shvedov --- include/iwinfo.h | 19 +++ iwinfo_cli.c | 10 ++ iwinfo_lua.c | 11 +++ iwinfo_nl80211.c | 32 ++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index b3f5470..1559837 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -145,6 +145,24 @@ struct iwinfo_crypto_entry { uint8_t auth_suites; uint8_t auth_algs; }; +struct iwinfo_channel_info_entry { + /** +* sec_channel_offset - Secondary channel offset for HT40 +* +* 0 = HT40 disabled, +* -1 = HT40 enabled, secondary channel below primary, +* 1 = HT40 enabled, secondary channel above primary +*/ + int8_t sec_channel_offset; + /** +* Center channel for VHT80 +*/ + uint8_t center_idx0; + /** +* Center channel for VHT160 +*/ + uint8_t center_idx1; +}; struct iwinfo_scanlist_entry { uint8_t mac[6]; @@ -156,6 +174,7 @@ struct iwinfo_scanlist_entry { uint8_t quality_max; uint16_t htmodelist; struct iwinfo_crypto_entry crypto; + struct iwinfo_channel_info_entry channel_info; }; struct iwinfo_country_entry { diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 0429fbc..7f897c1 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -612,6 +612,16 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) if (e->htmodelist & (1 << h)) printf("%s ", IWINFO_HTMODE_NAMES[h]); printf("\n"); + if (e->channel_info.sec_channel_offset) + printf(" HT secondary channel is %s\n", + e->channel_info.sec_channel_offset < 0 ? "below" : + "above"); + if (e->channel_info.center_idx0) + printf(" VHT Center IDX0: %hhu\n", + e->channel_info.center_idx0); + if (e->channel_info.center_idx1) + printf(" VHT Center IDX1: %hhu\n", + e->channel_info.center_idx1); } printf("\n"); } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index 303fd08..9f95017 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -444,6 +444,17 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int lua_setfield(L, -2, "htmodelist"); } + lua_pushinteger(L, e->channel_info.sec_channel_offset); + lua_setfield(L, -2, "sec_channel_offset"); + if (e->channel_info.center_idx0) { + lua_pushinteger(L, e->channel_info.center_idx0); + lua_setfield(L, -2, "center_idx0"); + } + if (e->channel_info.center_idx1) { + lua_pushinteger(L, e->channel_info.center_idx1); + lua_setfield(L, -2, "center_idx1"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 542ac7d..fb137b2 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1996,6 +1996,27 @@ static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, e->htmodelist |= IWINFO_HTMODE_VHT40; } } +static void nl80211_parse_ht_oper(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + uint8_t oper_info; + + if (len < 6) + return; + oper_info = ie[1]; + switch (oper_info & 3) { + case 0: + e->channel_info.sec_channel_offset = 0; + break; + case 1: + e->channel_info.sec_channel_offset = 1; + break; + case 3: + e->channel_info.sec_channel_offset = -1; + break; + } +} static void nl80211_parse_vht_capa(struct iwinfo_scan
[OpenWrt-Devel] [PATCH 2/2] add channel information for scan results
Besides channel number the secondary channel for HT40 and center idx0 and idx1 gives full understanding about real channel position and width on the spectra. So grab it via nl80211 and make it available in both C and LUA APIs, and show detailed channel information on CLI scan results. Signed-off-by: Yury Shvedov --- Sorry, I do not use git mailer frequently. Is this a right place for comments? include/iwinfo.h | 19 +++ iwinfo_cli.c | 10 ++ iwinfo_lua.c | 11 +++ iwinfo_nl80211.c | 32 ++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index b3f5470..1559837 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -145,6 +145,24 @@ struct iwinfo_crypto_entry { uint8_t auth_suites; uint8_t auth_algs; }; +struct iwinfo_channel_info_entry { + /** +* sec_channel_offset - Secondary channel offset for HT40 +* +* 0 = HT40 disabled, +* -1 = HT40 enabled, secondary channel below primary, +* 1 = HT40 enabled, secondary channel above primary +*/ + int8_t sec_channel_offset; + /** +* Center channel for VHT80 +*/ + uint8_t center_idx0; + /** +* Center channel for VHT160 +*/ + uint8_t center_idx1; +}; struct iwinfo_scanlist_entry { uint8_t mac[6]; @@ -156,6 +174,7 @@ struct iwinfo_scanlist_entry { uint8_t quality_max; uint16_t htmodelist; struct iwinfo_crypto_entry crypto; + struct iwinfo_channel_info_entry channel_info; }; struct iwinfo_country_entry { diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 0429fbc..7f897c1 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -612,6 +612,16 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) if (e->htmodelist & (1 << h)) printf("%s ", IWINFO_HTMODE_NAMES[h]); printf("\n"); + if (e->channel_info.sec_channel_offset) + printf(" HT secondary channel is %s\n", + e->channel_info.sec_channel_offset < 0 ? "below" : + "above"); + if (e->channel_info.center_idx0) + printf(" VHT Center IDX0: %hhu\n", + e->channel_info.center_idx0); + if (e->channel_info.center_idx1) + printf(" VHT Center IDX1: %hhu\n", + e->channel_info.center_idx1); } printf("\n"); } diff --git a/iwinfo_lua.c b/iwinfo_lua.c index 303fd08..9f95017 100644 --- a/iwinfo_lua.c +++ b/iwinfo_lua.c @@ -444,6 +444,17 @@ static int iwinfo_L_scanlist(lua_State *L, int (*func)(const char *, char *, int lua_setfield(L, -2, "htmodelist"); } + lua_pushinteger(L, e->channel_info.sec_channel_offset); + lua_setfield(L, -2, "sec_channel_offset"); + if (e->channel_info.center_idx0) { + lua_pushinteger(L, e->channel_info.center_idx0); + lua_setfield(L, -2, "center_idx0"); + } + if (e->channel_info.center_idx1) { + lua_pushinteger(L, e->channel_info.center_idx1); + lua_setfield(L, -2, "center_idx1"); + } + lua_rawseti(L, -2, x); } } diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 542ac7d..fb137b2 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -1996,6 +1996,27 @@ static void nl80211_parse_ht_capa(struct iwinfo_scanlist_entry *e, e->htmodelist |= IWINFO_HTMODE_VHT40; } } +static void nl80211_parse_ht_oper(struct iwinfo_scanlist_entry *e, + unsigned char *ie, + int len) +{ + uint8_t oper_info; + + if (len < 6) + return; + oper_info = ie[1]; + switch (oper_info & 3) { + case 0: + e->channel_info.sec_channel_offset = 0; + break; + case 1: + e->channel_info.sec_channel_offset = 1; + break; + case 3: + e->channel_info.sec_channel_offset = -1; +
[OpenWrt-Devel] [PATCH] hostapd: process all CSA parameters
This adds processing of all CSA arguments from ubus switch_chan request in the same manner as in the control interface API. Signed-off-by: Yury Shvedov --- .../services/hostapd/src/src/ap/ubus.c| 37 --- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 37a20ed774..4ce4ca5742 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -367,16 +367,26 @@ hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, enum { CSA_FREQ, CSA_BCN_COUNT, + CSA_CENTER_FREQ1, + CSA_CENTER_FREQ2, + CSA_BANDWIDTH, + CSA_SEC_CHANNEL_OFFSET, + CSA_HT, + CSA_VHT, + CSA_BLOCK_TX, __CSA_MAX }; static const struct blobmsg_policy csa_policy[__CSA_MAX] = { - /* -* for now, frequency and beacon count are enough, add more -* parameters on demand -*/ [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, + [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, + [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, + [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, + [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, + [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, + [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, }; #ifdef NEED_AP_MLME @@ -396,12 +406,27 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, memset(&css, 0, sizeof(css)); css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); - if (tb[CSA_BCN_COUNT]) - css.cs_count = blobmsg_get_u32(tb[CSA_BCN_COUNT]); + +#define SET_CSA_SETTING(name, field, type) \ + do { \ + if (tb[name]) \ + css.field = blobmsg_get_ ## type(tb[name]); \ + } while(0) + + SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); + SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); + SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); + SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); + SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); + SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); + SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); + if (hostapd_switch_channel(hapd, &css) != 0) return UBUS_STATUS_NOT_SUPPORTED; return UBUS_STATUS_OK; +#undef SET_CSA_SETTING } #endif -- 2.17.1 ___ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel