From 519898ea3b957d40072a8bbae9fddf65ea75dac9 Mon Sep 17 00:00:00 2001 From: Chaitanya Godavarthi Date: Tue, 29 Jun 2021 16:42:31 -0400 Subject: [PATCH] wifi-2648:Config RRM params without wifi vif reload Configure the following without vif reload: Tx power probe_response_threshold client disconnect threshold Beacon and multicast rates Signed-off-by: Chaitanya Godavarthi --- .../f00-015-ubus-change-conf-param.patch | 68 +++++++ .../patches/905-ubus-change-conf-param.patch | 65 +++++++ .../33-add-apc-radsecproxy-schema.patch | 57 ------ .../openwrt/src/lib/target/inc/radio.h | 2 + .../openwrt/src/lib/target/inc/rrm_config.h | 2 + .../openwrt/src/lib/target/src/radio.c | 3 + .../openwrt/src/lib/target/src/radio_ubus.c | 65 +++++++ .../openwrt/src/lib/target/src/rrm_config.c | 182 +++++++++++++++++- 8 files changed, 384 insertions(+), 60 deletions(-) create mode 100644 feeds/wifi-ax/hostapd/patches/f00-015-ubus-change-conf-param.patch create mode 100644 feeds/wifi-trunk/hostapd/patches/905-ubus-change-conf-param.patch diff --git a/feeds/wifi-ax/hostapd/patches/f00-015-ubus-change-conf-param.patch b/feeds/wifi-ax/hostapd/patches/f00-015-ubus-change-conf-param.patch new file mode 100644 index 000000000..8c1497b0a --- /dev/null +++ b/feeds/wifi-ax/hostapd/patches/f00-015-ubus-change-conf-param.patch @@ -0,0 +1,68 @@ +Index: hostapd-2020-07-02-58b384f4/src/ap/ubus.c +=================================================================== +--- hostapd-2020-07-02-58b384f4.orig/src/ap/ubus.c ++++ hostapd-2020-07-02-58b384f4/src/ap/ubus.c +@@ -1483,7 +1483,63 @@ static int hostapd_get_bss_list(struct u + return 0; + } + ++enum { ++ MOD_IFACE, ++ MOD_PARAM, ++ MOD_PARAM_VAL, ++ __PARAM_MAX ++}; ++ ++static const struct blobmsg_policy mod_param_policy[__PARAM_MAX] = { ++ [MOD_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, ++ [MOD_PARAM] = { "param", BLOBMSG_TYPE_STRING }, ++ [MOD_PARAM_VAL] = { "param_val", BLOBMSG_TYPE_STRING }, ++}; ++ ++ ++static int ++hostapd_param_modify(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct blob_attr *tb[__PARAM_MAX]; ++ struct hapd_interfaces *interfaces = NULL; ++ struct hostapd_data *hapd_bss = NULL; ++ struct hostapd_config *iconf = NULL; ++ struct hostapd_iface *iface = NULL; ++ size_t i = 0; ++ ++ interfaces = get_hapd_interfaces_from_object(obj); ++ blobmsg_parse(mod_param_policy, __PARAM_MAX, tb, blob_data(msg), ++ blob_len(msg)); ++ ++ if (!tb[MOD_PARAM] || !tb[MOD_IFACE] || !tb[MOD_PARAM_VAL]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ wpa_printf(MSG_DEBUG, "Modifyint %s=%s for %s", ++ blobmsg_get_string(tb[MOD_PARAM]), ++ blobmsg_get_string(tb[MOD_PARAM_VAL]), ++ blobmsg_get_string(tb[MOD_IFACE])); ++ ++ hapd_bss = hostapd_get_iface(interfaces, ++ blobmsg_get_string(tb[MOD_IFACE])); ++ ++ if (hapd_bss) { ++ iconf = hapd_bss->iconf; ++ if (os_strcmp(blobmsg_get_string(tb[MOD_PARAM]), ++ "rssi_ignore_probe_request") == 0) { ++ iconf->rssi_ignore_probe_request = atoi(blobmsg_get_string(tb[MOD_PARAM_VAL])); ++ ++ } ++ } ++ ++ return UBUS_STATUS_OK; ++} ++ ++ ++ + static const struct ubus_method daemon_methods[] = { ++ UBUS_METHOD("param_mod", hostapd_param_modify, mod_param_policy), + UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), + UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), + UBUS_METHOD_NOARG("get_bss_list", hostapd_get_bss_list), diff --git a/feeds/wifi-trunk/hostapd/patches/905-ubus-change-conf-param.patch b/feeds/wifi-trunk/hostapd/patches/905-ubus-change-conf-param.patch new file mode 100644 index 000000000..1609c749b --- /dev/null +++ b/feeds/wifi-trunk/hostapd/patches/905-ubus-change-conf-param.patch @@ -0,0 +1,65 @@ +Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c +=================================================================== +--- hostapd-2020-06-08-5a8b3662.orig/src/ap/ubus.c ++++ hostapd-2020-06-08-5a8b3662/src/ap/ubus.c +@@ -1486,7 +1486,60 @@ static int hostapd_get_bss_list(struct u + return 0; + } + ++enum { ++ MOD_IFACE, ++ MOD_PARAM, ++ MOD_PARAM_VAL, ++ __PARAM_MAX ++}; ++ ++static const struct blobmsg_policy mod_param_policy[__PARAM_MAX] = { ++ [MOD_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, ++ [MOD_PARAM] = { "param", BLOBMSG_TYPE_STRING }, ++ [MOD_PARAM_VAL] = { "param_val", BLOBMSG_TYPE_STRING }, ++}; ++ ++static int ++hostapd_param_modify(struct ubus_context *ctx, struct ubus_object *obj, ++ struct ubus_request_data *req, const char *method, ++ struct blob_attr *msg) ++{ ++ struct blob_attr *tb[__PARAM_MAX]; ++ struct hapd_interfaces *interfaces = NULL; ++ struct hostapd_data *hapd_bss = NULL; ++ struct hostapd_config *iconf = NULL; ++ struct hostapd_iface *iface = NULL; ++ size_t i = 0; ++ ++ interfaces = get_hapd_interfaces_from_object(obj); ++ blobmsg_parse(mod_param_policy, __PARAM_MAX, tb, blob_data(msg), ++ blob_len(msg)); ++ if (!tb[MOD_PARAM] || !tb[MOD_IFACE] || !tb[MOD_PARAM_VAL]) ++ return UBUS_STATUS_INVALID_ARGUMENT; ++ ++ wpa_printf(MSG_DEBUG, "Modifyint %s=%s for %s", ++ blobmsg_get_string(tb[MOD_PARAM]), ++ blobmsg_get_string(tb[MOD_PARAM_VAL]), ++ blobmsg_get_string(tb[MOD_IFACE])); ++ ++ hapd_bss = hostapd_get_iface(interfaces, ++ blobmsg_get_string(tb[MOD_IFACE])); ++ ++ if (hapd_bss) { ++ iconf = hapd_bss->iconf; ++ if (os_strcmp(blobmsg_get_string(tb[MOD_PARAM]), ++ "rssi_ignore_probe_request") == 0) { ++ iconf->rssi_ignore_probe_request = atoi(blobmsg_get_string(tb[MOD_PARAM_VAL])); ++ ++ } ++ } ++ ++ return UBUS_STATUS_OK; ++} ++ ++ + static const struct ubus_method daemon_methods[] = { ++ UBUS_METHOD("param_mod", hostapd_param_modify, mod_param_policy), + UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), + UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), + UBUS_METHOD_NOARG("get_bss_list", hostapd_get_bss_list), diff --git a/feeds/wlan-ap/opensync/patches/33-add-apc-radsecproxy-schema.patch b/feeds/wlan-ap/opensync/patches/33-add-apc-radsecproxy-schema.patch index 3980fef1e..ffe1b881e 100644 --- a/feeds/wlan-ap/opensync/patches/33-add-apc-radsecproxy-schema.patch +++ b/feeds/wlan-ap/opensync/patches/33-add-apc-radsecproxy-schema.patch @@ -72,63 +72,6 @@ Index: opensync-2.0.5.0/interfaces/opensync.ovsschema } } } -Index: opensync-2.0.5.0/platform/openwrt/src/lib/target/src/radio_ubus.c -=================================================================== ---- opensync-2.0.5.0.orig/platform/openwrt/src/lib/target/src/radio_ubus.c -+++ opensync-2.0.5.0/platform/openwrt/src/lib/target/src/radio_ubus.c -@@ -10,6 +10,7 @@ - extern struct ev_loop *wifihal_evloop; - static struct ubus_context *ubus; - extern struct ev_loop *wifihal_evloop; -+extern void apc_state_set(struct blob_attr *msg); - - int hapd_rrm_enable(char *name, int neighbor, int beacon) - { -@@ -179,6 +180,7 @@ radio_ubus_add_vif_cb(struct ubus_contex - return UBUS_STATUS_OK; - } - -+ - static const struct ubus_method radio_ubus_methods[] = { - UBUS_METHOD("dbg_add_vif", radio_ubus_add_vif_cb, add_vif_policy), - UBUS_METHOD("dummy", radio_ubus_dummy_cb, dummy_policy), -@@ -201,8 +203,36 @@ static void radio_ubus_connect(struct ub - ubus_add_object(ubus, &radio_ubus_object); - } - -+static int radio_ubus_notify(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ char *str; -+ -+ str = blobmsg_format_json(msg, true); -+ LOGD("ubus: Received ubus notify '%s': %s\n", method, str); -+ free(str); -+ -+ if (!strncmp(method, "apc", 3)) { -+ LOGD("APC notification Received"); -+ apc_state_set(msg); -+ } -+ -+ return 0; -+} -+ -+ -+ - static struct ubus_instance ubus_instance = { - .connect = radio_ubus_connect, -+ .notify = radio_ubus_notify, -+ .list = { -+ { -+ .path = "apc", -+ }, -+ }, -+ .len = 1, -+ - }; - - int radio_ubus_init(void) Index: opensync-2.0.5.0/src/lib/schema/inc/schema_consts.h =================================================================== --- opensync-2.0.5.0.orig/src/lib/schema/inc/schema_consts.h diff --git a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/radio.h b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/radio.h index bd68fdf0c..57f8bdad9 100644 --- a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/radio.h +++ b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/radio.h @@ -19,6 +19,8 @@ extern struct uci_context *uci; extern int radio_ubus_init(void); +int ubus_set_hapd_param(const char *if_name, const char *param, const char *pval); +int ubus_set_signal_thresholds(const char *if_name, int connect, int stay); extern int hapd_rrm_enable(char *name, int neighbor, int beacon); extern int hapd_rrm_set_neighbors(char *name, struct rrm_neighbor *neigh, int count); diff --git a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/rrm_config.h b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/rrm_config.h index 026e1f6fa..508994b0f 100644 --- a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/rrm_config.h +++ b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/inc/rrm_config.h @@ -34,6 +34,8 @@ extern ovsdb_table_t table_Wifi_RRM_Config; void rrm_config_vif(struct blob_buf *b, struct blob_buf *del, const char * freq_band, const char * if_name); int rrm_get_backup_channel(const char * freq_band); +bool rrm_config_txpower(const char *rname, unsigned int txpower); + void callback_Wifi_RRM_Config(ovsdb_update_monitor_t *mon, struct schema_Wifi_RRM_Config *old, struct schema_Wifi_RRM_Config *conf); diff --git a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio.c b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio.c index 3c3980c33..5260e2b89 100755 --- a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio.c +++ b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio.c @@ -388,9 +388,12 @@ bool target_radio_config_set2(const struct schema_Wifi_Radio_Config *rconf, int max_tx_power; max_tx_power=phy_get_max_tx_power(phy,rconf->channel); if (rconf->tx_power<=max_tx_power) { + + rrm_config_txpower(rconf->if_name, rconf->tx_power); blobmsg_add_u32(&b, "txpower", rconf->tx_power); } else { + rrm_config_txpower(rconf->if_name, max_tx_power); blobmsg_add_u32(&b, "txpower", max_tx_power); } } diff --git a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio_ubus.c b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio_ubus.c index 7678033a3..d7807309f 100644 --- a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio_ubus.c +++ b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/radio_ubus.c @@ -10,6 +10,46 @@ extern struct ev_loop *wifihal_evloop; static struct ubus_context *ubus; extern struct ev_loop *wifihal_evloop; +extern void apc_state_set(struct blob_attr *msg); + +int ubus_set_signal_thresholds(const char *if_name, int connect, int stay) +{ + uint32_t id; + char path[64]; + + if (connect > 0 && stay > 0) + return -1; + + snprintf(path, sizeof(path), "hostapd.%s", if_name); + + if (ubus_lookup_id(ubus, path, &id)) + return -1; + blob_buf_init(&b, 0); + + blobmsg_add_u32(&b, "connect", connect); + blobmsg_add_u32(&b, "stay", stay); + + return ubus_invoke(ubus, id, "set_required_signal", b.head, NULL, NULL, 1000); +} + +int ubus_set_hapd_param(const char *if_name, const char *param, const char *pval) +{ + + uint32_t id; + char path[64]; + + snprintf(path, sizeof(path), "hostapd"); + + if (ubus_lookup_id(ubus, path, &id)) + return -1; + blob_buf_init(&b, 0); + + blobmsg_add_string(&b, "iface", if_name); + blobmsg_add_string(&b, "param", param); + blobmsg_add_string(&b, "param_val", pval); + + return ubus_invoke(ubus, id, "param_mod", b.head, NULL, NULL, 1000); +} int hapd_rrm_enable(char *name, int neighbor, int beacon) { @@ -201,8 +241,33 @@ static void radio_ubus_connect(struct ubus_context *ctx) ubus_add_object(ubus, &radio_ubus_object); } +static int radio_ubus_notify(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + char *str; + + str = blobmsg_format_json(msg, true); + LOGD("ubus: Received ubus notify '%s': %s\n", method, str); + free(str); + + if (!strncmp(method, "apc", 3)) { + LOGD("APC notification Received"); + apc_state_set(msg); + } + + return 0; +} + static struct ubus_instance ubus_instance = { .connect = radio_ubus_connect, + .notify = radio_ubus_notify, + .list = { + { + .path = "apc", + }, + }, + .len = 1, }; int radio_ubus_init(void) diff --git a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/rrm_config.c b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/rrm_config.c index 4667adc3b..ec66da504 100644 --- a/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/rrm_config.c +++ b/feeds/wlan-ap/opensync/src/platform/openwrt/src/lib/target/src/rrm_config.c @@ -24,10 +24,130 @@ #include "uci.h" #include "utils.h" #include "captive.h" +#include ovsdb_table_t table_Wifi_RRM_Config; extern ovsdb_table_t table_Wifi_Radio_Config; extern ovsdb_table_t table_Wifi_VIF_Config; +#define PHY_NAME_LEN 32 + +bool rrm_config_txpower(const char *rname, unsigned int txpower) +{ + char cmd[126] = {0}; + int rid = 0; + txpower = txpower * 100; + + sscanf(rname, "radio%d", &rid); + + memset(cmd, 0, sizeof(cmd)); + /* iw dev set txpower []*/ + snprintf(cmd, sizeof(cmd), + "iw phy phy%d set txpower fixed %d", rid, txpower); + system(cmd); + + return true; +} + +/* get phy name */ +bool get_80211phy(const char *ifname, char *phy) +{ + char path[126] = {0}; + int fd, l = 0; + + snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211/name", ifname); + + fd = open(path, O_RDONLY); + if (fd < 0) { + LOGE("%s: Unable to read sysfs phy name", __func__); + close(fd); + return false; + } + read(fd, phy, PHY_NAME_LEN); + close(fd); + l = strlen(phy); + phy[l-1] = '\0'; + + return true; +} + +bool set_rates_sysfs(const char *type, int rate_code, const char *ifname, + char *band) +{ + int fd = 0; + char path[126] = {0}; + char value[126] = {0}; + char phy[PHY_NAME_LEN] = {0}; + unsigned int band_id = 0; + + /* get phy name */ + if (!get_80211phy(ifname, phy)) + return false; + + if (!strcmp(band, "2.4G")) + band_id = 2; + else + band_id = 5; + + snprintf(path, sizeof(path), + "/sys/kernel/debug/ieee80211/%s/ath10k/set_rates", phy); + + snprintf(value, sizeof(value), "%s %s %d 0x%x", + ifname, type, band_id, rate_code); + + fd = open(path, O_WRONLY); + if (fd < 0) { + LOGE("%s: Unable to read sysfs set_rates", __func__); + close(fd); + return false; + } + write(fd, value, sizeof(value)); + close(fd); + LOGI("Kiran: wrote: %s to %s", value, path); + return true; +} + +#define NUM_OF_RATES 12 +bool rrm_config_mcast_bcast_rate(const char *ifname, char *band, + unsigned int bcn_rate, unsigned int mcast_rate) +{ + int i = 0; + bool rc = true; + unsigned int bcn_code = 0xFF; + unsigned int mcast_code = 0xFF; + unsigned int rate_code[NUM_OF_RATES][2] = {{1,0x43}, {2,0x42}, {5,0x41}, + {11,0x40}, {6,0x3}, {9,0x7}, + {12,0x2}, {18,0x6}, {24,0x1}, + {36,0x5}, {48,0x0}, {54,0x4}}; + + /* beacon rate given by cloud in multiples of 10 */ + if (bcn_rate > 0) + bcn_rate = bcn_rate/10; + + /* Get rate code of given rate */ + for (i = 0; i < NUM_OF_RATES; i++) + { + if (rate_code[i][0] == bcn_rate) + bcn_code = rate_code[i][1]; + + if (rate_code[i][0] == mcast_rate) + mcast_code = rate_code[i][1]; + } + + /* Set the rates to sysfs */ + if (bcn_code != 0xFF) + { + if (set_rates_sysfs("beacon", bcn_code, ifname, band) == false) + rc = false; + } + + if (mcast_code != 0xFF) + { + if (set_rates_sysfs("mcast", mcast_code, ifname, band) == false) + rc = false; + } + + return rc; +} void rrm_config_vif(struct blob_buf *b, struct blob_buf *del, const char * freq_band, const char * if_name) { @@ -80,6 +200,46 @@ int rrm_get_backup_channel(const char * freq_band) } +bool rrm_noreload_config(struct schema_Wifi_RRM_Config *conf, const char *rname) +{ + char pval[16]; + char wlanif[8]; + int rid = 0; + + sscanf(rname, "radio%d", &rid); + snprintf(wlanif, sizeof(wlanif), "wlan%d", rid); + + if (conf->probe_resp_threshold_changed) { + /* rssi_ignore_probe_request and signal_connect should + * both be probe_resp_threshold */ + snprintf(pval, sizeof(pval), "%d", + conf->probe_resp_threshold); + ubus_set_hapd_param(wlanif, + "rssi_ignore_probe_request", pval); + ubus_set_signal_thresholds(wlanif, + conf->probe_resp_threshold, + conf->client_disconnect_threshold); + + } + + if (conf->client_disconnect_threshold_changed) { + ubus_set_signal_thresholds(wlanif, + conf->probe_resp_threshold, + conf->client_disconnect_threshold); + } + + if (conf->mcast_rate_changed) { + rrm_config_mcast_bcast_rate(wlanif, conf->freq_band, 0, + conf->mcast_rate); + } + + if (conf->beacon_rate_changed) { + rrm_config_mcast_bcast_rate(wlanif, conf->freq_band, + conf->beacon_rate, 0); + } + return true; +} + static bool rrm_config_update( struct schema_Wifi_RRM_Config *conf, bool addNotDelete) { struct schema_Wifi_Radio_Config rconf; @@ -89,12 +249,29 @@ static bool rrm_config_update( struct schema_Wifi_RRM_Config *conf, bool addNotD int i; if (false == ovsdb_table_select_one(&table_Wifi_Radio_Config, - SCHEMA_COLUMN(Wifi_Radio_Config, freq_band), conf->freq_band, &rconf)) + SCHEMA_COLUMN(Wifi_Radio_Config, freq_band), + conf->freq_band, &rconf)) { - LOG(WARN, "Wifi_RRM_Config: No radio for band %s", conf->freq_band ); + LOG(WARN, "Wifi_RRM_Config: No radio for band %s", + conf->freq_band ); return false; } + /* Set RRM configurations which do not require a wifi vifs reload + * and return */ + if (conf->mcast_rate_changed || conf->beacon_rate_changed || + conf->probe_resp_threshold_changed || + conf->client_disconnect_threshold_changed) { + LOGI("RRM Config: beacon_rate:%s mcast_rate:%s probe_resp_threshold:%s client_disconnect_threshold_changed:%s", + (conf->beacon_rate_changed)? "changed":"unchanged", + (conf->mcast_rate_changed)? "changed":"unchanged", + (conf->probe_resp_threshold_changed)? "changed":"unchanged", + (conf->client_disconnect_threshold_changed)? "changed":"unchanged"); + if(rrm_noreload_config(conf, rconf.if_name) == true) { + } + } + + /*Reload the vifs to configure the RRM configurations*/ memset(&changed, 0, sizeof(changed)); for (i = 0; i < rconf.vif_configs_len; i++) { if (!(where = ovsdb_where_uuid("_uuid", rconf.vif_configs[i].uuid))) @@ -179,7 +356,6 @@ void callback_Wifi_RRM_Config(ovsdb_update_monitor_t *self, LOG(ERR, "Wifi_RRM_Config: unexpected mon_type %d %s", self->mon_type, self->mon_uuid); break; } - set_config_apply_timeout(self); return; }