diff --git a/src/include/datastorage.h b/src/include/datastorage.h index 96f073c..007909b 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -48,31 +48,34 @@ struct mac_entry_s* insert_to_mac_array(struct mac_entry_s* entry, struct mac_en void mac_array_delete(struct mac_entry_s* entry); +int get_band(int freq); // ---------------- Global variables ---------------- /*** Metrics and configuration data ***/ // TODO: Define a proper version string #ifndef DAWN_CONFIG_VERSION -#define DAWN_CONFIG_VERSION "1" +#define DAWN_CONFIG_VERSION "2" #endif +// Band definitions +// Keep them sorted by frequency, in ascending order +enum dawn_bands { + DAWN_BAND_80211G, + DAWN_BAND_80211A, + __DAWN_BAND_MAX +}; + +// config section name +extern const char *band_config_name[__DAWN_BAND_MAX]; + +// starting frequency +// TODO: make this configurable +extern const int max_band_freq[__DAWN_BAND_MAX]; + // ---------------- Structs ---------------- struct probe_metric_s { - int ap_weight; // TODO: Never evaluated? - int ht_support; // eval_probe_metric()() - int vht_support; // eval_probe_metric()() - int no_ht_support; // eval_probe_metric()() - int no_vht_support; // eval_probe_metric()() - int rssi; // eval_probe_metric()() - int low_rssi; // eval_probe_metric()() - int freq; // eval_probe_metric()() - int chan_util; // eval_probe_metric()() - int max_chan_util; // eval_probe_metric()() - int rssi_val; // eval_probe_metric()() - int low_rssi_val; // eval_probe_metric()() - int chan_util_val; // eval_probe_metric()() - int max_chan_util_val; // eval_probe_metric()() + // Global Configuration int min_probe_count; int bandwidth_threshold; // kick_clients() int use_station_count; // better_ap_available() @@ -83,13 +86,29 @@ struct probe_metric_s { int deny_auth_reason; int deny_assoc_reason; int use_driver_recog; - int min_kick_count; // kick_clients() + int min_number_to_kick; // kick_clients() int chan_util_avg_period; int set_hostapd_nr; int kicking; int duration; int rrm_mode_mask; int rrm_mode_order[__RRM_BEACON_RQST_MODE_MAX]; + + // Per-band Configuration + int ap_weight[__DAWN_BAND_MAX]; // TODO: Never evaluated? + int ht_support[__DAWN_BAND_MAX]; // eval_probe_metric()() + int vht_support[__DAWN_BAND_MAX]; // eval_probe_metric()() + int no_ht_support[__DAWN_BAND_MAX]; // eval_probe_metric()() + int no_vht_support[__DAWN_BAND_MAX]; // eval_probe_metric()() + int rssi[__DAWN_BAND_MAX]; // eval_probe_metric()() + int low_rssi[__DAWN_BAND_MAX]; // eval_probe_metric()() + int freq[__DAWN_BAND_MAX]; // eval_probe_metric()() + int chan_util[__DAWN_BAND_MAX]; // eval_probe_metric()() + int max_chan_util[__DAWN_BAND_MAX]; // eval_probe_metric()() + int rssi_val[__DAWN_BAND_MAX]; // eval_probe_metric()() + int low_rssi_val[__DAWN_BAND_MAX]; // eval_probe_metric()() + int chan_util_val[__DAWN_BAND_MAX]; // eval_probe_metric()() + int max_chan_util_val[__DAWN_BAND_MAX]; // eval_probe_metric()() }; struct time_config_s { diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index d3fe5c6..0b84f2c 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -34,6 +34,19 @@ struct auth_entry_s *denied_req_set = NULL; int denied_req_last = 0; pthread_mutex_t denied_array_mutex; +// config section name +const char *band_config_name[__DAWN_BAND_MAX] = { + "802_11g", + "802_11a" +}; + +// starting frequency +// TODO: make this configurable +const int max_band_freq[__DAWN_BAND_MAX] = { + 2500, + 5925 // This may cause trouble because there's overlap between bands in different countries +}; + // Ratio of skiping entries to all entries. // Approx sqrt() of large data set, and power of 2 for efficient division when adding entries. #define DAWN_PROBE_SKIP_RATIO 128 @@ -404,36 +417,48 @@ void send_beacon_reports(ap *a, int id) { pthread_mutex_unlock(&client_array_mutex); } +int get_band(int freq) { + int band; + + for (band=0; band < __DAWN_BAND_MAX; band++) + if (freq <= max_band_freq[band]) + return band; + band--; + fprintf(stderr, "Warning: frequency %d is beyond the last known band. " + "Using '%s' band parameters.\n", freq, band_config_name[band]); + return band; +} + // TODO: Can metric be cached once calculated? Add score_fresh indicator and reset when signal changes // TODO: as rest of values look to be static fr any given entry. int eval_probe_metric(struct probe_entry_s* probe_entry, ap* ap_entry) { - int score = 0; - - // check if ap entry is available - if (ap_entry != NULL) { - score += probe_entry->ht_capabilities && ap_entry->ht_support ? dawn_metric.ht_support : 0; - score += !probe_entry->ht_capabilities && !ap_entry->ht_support ? dawn_metric.no_ht_support : 0; // TODO: Is both devices not having a capability worthy of scoring? - - // performance anomaly? - if (network_config.bandwidth >= 1000 || network_config.bandwidth == -1) { - score += probe_entry->vht_capabilities && ap_entry->vht_support ? dawn_metric.vht_support : 0; - } - - score += !probe_entry->vht_capabilities && !ap_entry->vht_support ? dawn_metric.no_vht_support : 0; // TODO: Is both devices not having a capability worthy of scoring? - score += ap_entry->channel_utilization <= dawn_metric.chan_util_val ? dawn_metric.chan_util : 0; - score += ap_entry->channel_utilization > dawn_metric.max_chan_util_val ? dawn_metric.max_chan_util : 0; - - score += ap_entry->ap_weight; - } - - score += (probe_entry->freq > 5000) ? dawn_metric.freq : 0; + int band, score = 0; // TODO: Should RCPI be used here as well? // TODO: Should this be more scaled? Should -63dB on current and -77dB on other both score 0 if low / high are -80db and -60dB? // TODO: That then lets device capabilites dominate score - making them more important than RSSI difference of 14dB. - score += (probe_entry->signal >= dawn_metric.rssi_val) ? dawn_metric.rssi : 0; - score += (probe_entry->signal <= dawn_metric.low_rssi_val) ? dawn_metric.low_rssi : 0; + band = get_band(probe_entry->freq); + score = dawn_metric.freq[band]; + score += probe_entry->signal >= dawn_metric.rssi_val[band] ? dawn_metric.rssi[band] : 0; + score += probe_entry->signal <= dawn_metric.low_rssi_val[band] ? dawn_metric.low_rssi[band] : 0; + + // check if ap entry is available + if (ap_entry != NULL) { + score += probe_entry->ht_capabilities && ap_entry->ht_support ? dawn_metric.ht_support[band] : 0; + score += !probe_entry->ht_capabilities && !ap_entry->ht_support ? dawn_metric.no_ht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring? + + // performance anomaly? + if (network_config.bandwidth >= 1000 || network_config.bandwidth == -1) { + score += probe_entry->vht_capabilities && ap_entry->vht_support ? dawn_metric.vht_support[band] : 0; + } + + score += !probe_entry->vht_capabilities && !ap_entry->vht_support ? dawn_metric.no_vht_support[band] : 0; // TODO: Is both devices not having a capability worthy of scoring? + score += ap_entry->channel_utilization <= dawn_metric.chan_util_val[band] ? dawn_metric.chan_util[band] : 0; + score += ap_entry->channel_utilization > dawn_metric.max_chan_util_val[band] ? dawn_metric.max_chan_util[band] : 0; + + score += ap_entry->ap_weight; + } // TODO: This magic value never checked by caller. What does it achieve? if (score < 0) @@ -623,9 +648,9 @@ int kick_clients(ap* kicking_ap, uint32_t id) { // + chan util is changing a lot // + ping pong behavior of clients will be reduced j->kick_count++; - printf("Comparing kick count! kickcount: %d to min_kick_count: %d!\n", j->kick_count, - dawn_metric.min_kick_count); - if (j->kick_count >= dawn_metric.min_kick_count) { + printf("Comparing kick count! kickcount: %d to min_number_to_kick: %d!\n", j->kick_count, + dawn_metric.min_number_to_kick); + if (j->kick_count >= dawn_metric.min_number_to_kick) { printf("Better AP available. Kicking client:\n"); print_client_entry(j); printf("Check if client is active receiving!\n"); diff --git a/src/test/kick_deep.script b/src/test/kick_deep.script index 60516e2..242371c 100644 --- a/src/test/kick_deep.script +++ b/src/test/kick_deep.script @@ -8,7 +8,7 @@ dawn max_chan_util=0 dawn ap_weight=4 dawn rssi=32 dawn low_rssi=0 -dawn min_kick_count=1 +dawn min_number_to_kick=1 #AP diff --git a/src/test/scale_kick_100_3000_b.script b/src/test/scale_kick_100_3000_b.script index 6fe6e0a..09b058c 100644 --- a/src/test/scale_kick_100_3000_b.script +++ b/src/test/scale_kick_100_3000_b.script @@ -8,7 +8,7 @@ dawn max_chan_util=0 dawn ap_weight=4 dawn rssi=32 dawn low_rssi=0 -dawn min_kick_count=1 +dawn min_number_to_kick=1 # AP ap bssid=20:C9:AA:00:01:00 ht_sup=0 vht_sup=0 util=65 stations=5 ssid=aTestSSID weight=10 neighbors=20C9AA000100 diff --git a/src/test/scale_test_A.script b/src/test/scale_test_A.script index 60516e2..242371c 100644 --- a/src/test/scale_test_A.script +++ b/src/test/scale_test_A.script @@ -8,7 +8,7 @@ dawn max_chan_util=0 dawn ap_weight=4 dawn rssi=32 dawn low_rssi=0 -dawn min_kick_count=1 +dawn min_number_to_kick=1 #AP diff --git a/src/test/simple_kick.script b/src/test/simple_kick.script index 6b283c7..586e8ed 100644 --- a/src/test/simple_kick.script +++ b/src/test/simple_kick.script @@ -1,5 +1,5 @@ dawn default -dawn min_kick_count=2 +dawn min_number_to_kick=2 ap bssid=11:22:33:44:55:66 neighbors=112233445566 ap bssid=22:33:44:55:66:77 neighbors=223344556677 client bssid=11:22:33:44:55:66 client=ff:ee:dd:cc:bb:aa diff --git a/src/test/test_storage.c b/src/test/test_storage.c index 8882575..484b343 100644 --- a/src/test/test_storage.c +++ b/src/test/test_storage.c @@ -301,6 +301,15 @@ static int load_int(int* v, char* s) return ret; } +static int load_int_band(int* v, char* s); +static int load_int_band(int* v, char* s) +{ + int ret = 0; + sscanf(s, "%" "d", v); + v[1] = v[0]; + return ret; +} + static int load_string(size_t l, char* v, char* s); static int load_string(size_t l, char* v, char* s) { @@ -631,20 +640,34 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) if (!strcmp(fn, "default")) { - dawn_metric.ap_weight = 0; // Sum component - dawn_metric.ht_support = 10; // Sum component - dawn_metric.vht_support = 100; // Sum component - dawn_metric.no_ht_support = 0; // Sum component - dawn_metric.no_vht_support = 0; // Sum component - dawn_metric.rssi = 10; // Sum component - dawn_metric.low_rssi = -500; // Sum component - dawn_metric.freq = 100; // Sum component - dawn_metric.chan_util = 0; // Sum component - dawn_metric.max_chan_util = -500; // Sum component - dawn_metric.rssi_val = -60; - dawn_metric.low_rssi_val = -80; - dawn_metric.chan_util_val = 140; - dawn_metric.max_chan_util_val = 170; + dawn_metric.ap_weight[0] = 0; // Sum component + dawn_metric.ap_weight[1] = 0; // Sum component + dawn_metric.ht_support[0] = 10; // Sum component + dawn_metric.ht_support[1] = 10; // Sum component + dawn_metric.vht_support[0] = 100; // Sum component + dawn_metric.vht_support[1] = 100; // Sum component + dawn_metric.no_ht_support[0] = 0; // Sum component + dawn_metric.no_ht_support[1] = 0; // Sum component + dawn_metric.no_vht_support[0] = 0; // Sum component + dawn_metric.no_vht_support[1] = 0; // Sum component + dawn_metric.rssi[0] = 10; // Sum component + dawn_metric.rssi[1] = 10; // Sum component + dawn_metric.low_rssi[0] = -500; // Sum component + dawn_metric.low_rssi[1] = -500; // Sum component + dawn_metric.freq[0] = 0; // Sum component + dawn_metric.freq[1] = 100; // Sum component + dawn_metric.chan_util[0] = 0; // Sum component + dawn_metric.chan_util[1] = 0; // Sum component + dawn_metric.max_chan_util[0] = -500; // Sum component + dawn_metric.max_chan_util[1] = -500; // Sum component + dawn_metric.rssi_val[0] = -60; + dawn_metric.rssi_val[1] = -60; + dawn_metric.low_rssi_val[0] = -80; + dawn_metric.low_rssi_val[1] = -80; + dawn_metric.chan_util_val[0] = 140; + dawn_metric.chan_util_val[1] = 140; + dawn_metric.max_chan_util_val[0] = 170; + dawn_metric.max_chan_util_val[1] = 170; dawn_metric.min_probe_count = 2; dawn_metric.bandwidth_threshold = 6; dawn_metric.use_station_count = 1; @@ -655,7 +678,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) dawn_metric.deny_auth_reason = 1; dawn_metric.deny_assoc_reason = 17; dawn_metric.use_driver_recog = 1; - dawn_metric.min_kick_count = 3; + dawn_metric.min_number_to_kick = 3; dawn_metric.chan_util_avg_period = 3; dawn_metric.set_hostapd_nr = 1; dawn_metric.kicking = 0; @@ -667,20 +690,20 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) dawn_metric.rrm_mode_order[1] = WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE; dawn_metric.rrm_mode_order[2] = WLAN_RRM_CAPS_BEACON_REPORT_TABLE; } - else if (!strncmp(fn, "ap_weight=", 10)) load_int(&dawn_metric.ap_weight, fn + 10); - else if (!strncmp(fn, "ht_support=", 11)) load_int(&dawn_metric.ht_support, fn + 11); - else if (!strncmp(fn, "vht_support=", 12)) load_int(&dawn_metric.vht_support, fn + 12); - else if (!strncmp(fn, "no_ht_support=", 14)) load_int(&dawn_metric.no_ht_support, fn + 14); - else if (!strncmp(fn, "no_vht_support=", 15)) load_int(&dawn_metric.no_vht_support, fn + 15); - else if (!strncmp(fn, "rssi=", 5)) load_int(&dawn_metric.rssi, fn + 5); - else if (!strncmp(fn, "low_rssi=", 9)) load_int(&dawn_metric.low_rssi, fn + 9); - else if (!strncmp(fn, "freq=", 5)) load_int(&dawn_metric.freq, fn + 5); - else if (!strncmp(fn, "chan_util=", 10)) load_int(&dawn_metric.chan_util, fn + 10); - else if (!strncmp(fn, "max_chan_util=", 14)) load_int(&dawn_metric.max_chan_util, fn + 14); - else if (!strncmp(fn, "rssi_val=", 9)) load_int(&dawn_metric.rssi_val, fn + 9); - else if (!strncmp(fn, "low_rssi_val=", 13)) load_int(&dawn_metric.low_rssi_val, fn + 13); - else if (!strncmp(fn, "chan_util_val=", 14)) load_int(&dawn_metric.chan_util_val, fn + 14); - else if (!strncmp(fn, "max_chan_util_val=", 18)) load_int(&dawn_metric.max_chan_util_val, fn + 18); + else if (!strncmp(fn, "ap_weight=", 10)) load_int_band(dawn_metric.ap_weight, fn + 10); + else if (!strncmp(fn, "ht_support=", 11)) load_int_band(dawn_metric.ht_support, fn + 11); + else if (!strncmp(fn, "vht_support=", 12)) load_int_band(dawn_metric.vht_support, fn + 12); + else if (!strncmp(fn, "no_ht_support=", 14)) load_int_band(dawn_metric.no_ht_support, fn + 14); + else if (!strncmp(fn, "no_vht_support=", 15)) load_int_band(dawn_metric.no_vht_support, fn + 15); + else if (!strncmp(fn, "rssi=", 5)) load_int_band(dawn_metric.rssi, fn + 5); + else if (!strncmp(fn, "low_rssi=", 9)) load_int_band(dawn_metric.low_rssi, fn + 9); + else if (!strncmp(fn, "freq=", 5)) load_int(&dawn_metric.freq[1], fn + 5); + else if (!strncmp(fn, "chan_util=", 10)) load_int_band(dawn_metric.chan_util, fn + 10); + else if (!strncmp(fn, "max_chan_util=", 14)) load_int_band(dawn_metric.max_chan_util, fn + 14); + else if (!strncmp(fn, "rssi_val=", 9)) load_int_band(dawn_metric.rssi_val, fn + 9); + else if (!strncmp(fn, "low_rssi_val=", 13)) load_int_band(dawn_metric.low_rssi_val, fn + 13); + else if (!strncmp(fn, "chan_util_val=", 14)) load_int_band(dawn_metric.chan_util_val, fn + 14); + else if (!strncmp(fn, "max_chan_util_val=", 18)) load_int_band(dawn_metric.max_chan_util_val, fn + 18); else if (!strncmp(fn, "min_probe_count=", 16)) load_int(&dawn_metric.min_probe_count, fn + 16); else if (!strncmp(fn, "bandwidth_threshold=", 20)) load_int(&dawn_metric.bandwidth_threshold, fn + 20); else if (!strncmp(fn, "use_station_count=", 18)) load_int(&dawn_metric.use_station_count, fn + 18); @@ -691,7 +714,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) else if (!strncmp(fn, "deny_auth_reason=", 17)) load_int(&dawn_metric.deny_auth_reason, fn + 17); else if (!strncmp(fn, "deny_assoc_reason=", 18)) load_int(&dawn_metric.deny_assoc_reason, fn + 18); else if (!strncmp(fn, "use_driver_recog=", 17)) load_int(&dawn_metric.use_driver_recog, fn + 17); - else if (!strncmp(fn, "min_kick_count=", 15)) load_int(&dawn_metric.min_kick_count, fn + 15); + else if (!strncmp(fn, "min_number_to_kick=", 19)) load_int(&dawn_metric.min_number_to_kick, fn + 19); else if (!strncmp(fn, "chan_util_avg_period=", 21)) load_int(&dawn_metric.chan_util_avg_period, fn + 21); else if (!strncmp(fn, "set_hostapd_nr=", 15)) load_int(&dawn_metric.set_hostapd_nr, fn + 15); else if (!strncmp(fn, "kicking=", 8)) load_int(&dawn_metric.kicking, fn + 8); diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index db73cce..d523565 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -116,50 +116,88 @@ static int parse_rrm_mode(int *rrm_mode_order, const char *mode_string) { } -struct probe_metric_s uci_get_dawn_metric() { - struct probe_metric_s ret = {0}; +static void set_if_present(int *ret, struct uci_section *s, const char* option) { + const char *str; + if (s && (str = uci_lookup_option_string(uci_ctx, s, option))) + *ret = atoi(str); +} + +static struct uci_section *uci_find_metric_section(const char *name) { + struct uci_section *s; struct uci_element *e; - uci_foreach_element(&uci_pkg->sections, e) - { - struct uci_section *s = uci_to_section(e); - if (strcmp(s->type, "metric") == 0) { - ret.ap_weight = uci_lookup_option_int(uci_ctx, s, "ap_weight"); - ret.kicking = uci_lookup_option_int(uci_ctx, s, "kicking"); - ret.ht_support = uci_lookup_option_int(uci_ctx, s, "ht_support"); - ret.vht_support = uci_lookup_option_int(uci_ctx, s, "vht_support"); - ret.no_ht_support = uci_lookup_option_int(uci_ctx, s, "no_ht_support"); - ret.no_vht_support = uci_lookup_option_int(uci_ctx, s, "no_vht_support"); - ret.rssi = uci_lookup_option_int(uci_ctx, s, "rssi"); - ret.freq = uci_lookup_option_int(uci_ctx, s, "freq"); - ret.rssi_val = uci_lookup_option_int(uci_ctx, s, "rssi_val"); - ret.chan_util = uci_lookup_option_int(uci_ctx, s, "chan_util"); - ret.max_chan_util = uci_lookup_option_int(uci_ctx, s, "max_chan_util"); - ret.chan_util_val = uci_lookup_option_int(uci_ctx, s, "chan_util_val"); - ret.max_chan_util_val = uci_lookup_option_int(uci_ctx, s, "max_chan_util_val"); - ret.min_probe_count = uci_lookup_option_int(uci_ctx, s, "min_probe_count"); - ret.low_rssi = uci_lookup_option_int(uci_ctx, s, "low_rssi"); - ret.low_rssi_val = uci_lookup_option_int(uci_ctx, s, "low_rssi_val"); - ret.bandwidth_threshold = uci_lookup_option_int(uci_ctx, s, "bandwidth_threshold"); - ret.use_station_count = uci_lookup_option_int(uci_ctx, s, "use_station_count"); - ret.eval_probe_req = uci_lookup_option_int(uci_ctx, s, "eval_probe_req"); - ret.eval_auth_req = uci_lookup_option_int(uci_ctx, s, "eval_auth_req"); - ret.eval_assoc_req = uci_lookup_option_int(uci_ctx, s, "eval_assoc_req"); - ret.deny_auth_reason = uci_lookup_option_int(uci_ctx, s, "deny_auth_reason"); - ret.deny_assoc_reason = uci_lookup_option_int(uci_ctx, s, "deny_assoc_reason"); - ret.max_station_diff = uci_lookup_option_int(uci_ctx, s, "max_station_diff"); - ret.use_driver_recog = uci_lookup_option_int(uci_ctx, s, "use_driver_recog"); - ret.min_kick_count = uci_lookup_option_int(uci_ctx, s, "min_number_to_kick"); - ret.chan_util_avg_period = uci_lookup_option_int(uci_ctx, s, "chan_util_avg_period"); - ret.set_hostapd_nr = uci_lookup_option_int(uci_ctx, s, "set_hostapd_nr"); - ret.duration = uci_lookup_option_int(uci_ctx, s, "duration"); - ret.rrm_mode_mask = parse_rrm_mode(ret.rrm_mode_order, - uci_lookup_option_string(uci_ctx, s, "rrm_mode")); - return ret; + uci_foreach_element(&uci_pkg->sections, e) { + s = uci_to_section(e); + if (strcmp(s->type, "metric") == 0 && + ((!name && s->anonymous) || strcmp(e->name, name) == 0)) { + return s; } } + return NULL; +} +#define DAWN_SET_CONFIG_INT(m, s, conf) \ + set_if_present(&m.conf, s, #conf) + +#define DAWN_SET_BANDS_CONFIG_INT(m, global_s, band_s, conf) \ + do for (int band = 0; band < __DAWN_BAND_MAX; band++) { \ + if (global_s) \ + set_if_present(&m.conf[band], global_s, #conf); \ + if (band_s[band]) \ + set_if_present(&m.conf[band], band_s[band], #conf); \ + } while (0) + +struct probe_metric_s uci_get_dawn_metric() { + struct probe_metric_s ret = {0}; // TODO: Set reasonable defaults + struct uci_section *global_s, *band_s[__DAWN_BAND_MAX]; + + if (!(global_s = uci_find_metric_section("global"))) { + if (!(global_s = uci_find_metric_section(NULL))) { + fprintf(stderr, "Warning: config metric global section not found! Using defaults.\n"); + } else { + fprintf(stderr, "Warning: config metric global section not found. " + "Using first unnamed config metric.\n" + "Consider naming a 'global' metric section to avoid ambiguity.\n"); + } + } + if (global_s) { + // True global configuration + DAWN_SET_CONFIG_INT(ret, global_s, kicking); + DAWN_SET_CONFIG_INT(ret, global_s, min_probe_count); + DAWN_SET_CONFIG_INT(ret, global_s, use_station_count); + DAWN_SET_CONFIG_INT(ret, global_s, eval_auth_req); + DAWN_SET_CONFIG_INT(ret, global_s, eval_assoc_req); + DAWN_SET_CONFIG_INT(ret, global_s, deny_auth_reason); + DAWN_SET_CONFIG_INT(ret, global_s, deny_assoc_reason); + DAWN_SET_CONFIG_INT(ret, global_s, eval_probe_req); + DAWN_SET_CONFIG_INT(ret, global_s, min_number_to_kick); + DAWN_SET_CONFIG_INT(ret, global_s, set_hostapd_nr); + DAWN_SET_CONFIG_INT(ret, global_s, max_station_diff); + DAWN_SET_CONFIG_INT(ret, global_s, bandwidth_threshold); + DAWN_SET_CONFIG_INT(ret, global_s, use_driver_recog); + DAWN_SET_CONFIG_INT(ret, global_s, chan_util_avg_period); + DAWN_SET_CONFIG_INT(ret, global_s, duration); + ret.rrm_mode_mask = parse_rrm_mode(ret.rrm_mode_order, + uci_lookup_option_string(uci_ctx, global_s, "rrm_mode")); + } + for (int band = 0; band < __DAWN_BAND_MAX; band++) + band_s[band] = uci_find_metric_section(band_config_name[band]); + + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, ap_weight); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, ht_support); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, vht_support); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, no_ht_support); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, no_vht_support); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, rssi); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, rssi_val); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, freq); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, chan_util); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, max_chan_util); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, chan_util_val); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, max_chan_util_val); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, low_rssi); + DAWN_SET_BANDS_CONFIG_INT(ret, global_s, band_s, low_rssi_val); return ret; } diff --git a/src/utils/msghandler.c b/src/utils/msghandler.c index c033ab7..5f5d164 100644 --- a/src/utils/msghandler.c +++ b/src/utils/msghandler.c @@ -560,19 +560,6 @@ enum { }; enum { - UCI_HT_SUPPORT, - UCI_VHT_SUPPORT, - UCI_NO_HT_SUPPORT, - UCI_NO_VHT_SUPPORT, - UCI_RSSI, - UCI_LOW_RSSI, - UCI_FREQ, - UCI_CHAN_UTIL, - UCI_MAX_CHAN_UTIL, - UCI_RSSI_VAL, - UCI_LOW_RSSI_VAL, - UCI_CHAN_UTIL_VAL, - UCI_MAX_CHAN_UTIL_VAL, UCI_MIN_PROBE_COUNT, UCI_BANDWIDTH_THRESHOLD, UCI_USE_STATION_COUNT, @@ -589,7 +576,27 @@ enum { UCI_SET_HOSTAPD_NR, UCI_DURATION, UCI_RRM_MODE, - __UCI_METIC_MAX + UCI_BAND_METRICS, + __UCI_METRIC_MAX +}; + +enum { + UCI_BAND, + UCI_FREQ, + UCI_AP_WEIGHT, + UCI_HT_SUPPORT, + UCI_VHT_SUPPORT, + UCI_NO_HT_SUPPORT, + UCI_NO_VHT_SUPPORT, + UCI_RSSI, + UCI_LOW_RSSI, + UCI_CHAN_UTIL, + UCI_MAX_CHAN_UTIL, + UCI_RSSI_VAL, + UCI_LOW_RSSI_VAL, + UCI_CHAN_UTIL_VAL, + UCI_MAX_CHAN_UTIL_VAL, + __UCI_BAND_METRIC_MAX }; enum { @@ -611,20 +618,7 @@ static const struct blobmsg_policy uci_table_policy[__UCI_TABLE_MAX] = { [UCI_TABLE_TIMES] = {.name = "times", .type = BLOBMSG_TYPE_TABLE} }; -static const struct blobmsg_policy uci_metric_policy[__UCI_METIC_MAX] = { - [UCI_HT_SUPPORT] = {.name = "ht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_VHT_SUPPORT] = {.name = "vht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_NO_HT_SUPPORT] = {.name = "no_ht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_NO_VHT_SUPPORT] = {.name = "no_vht_support", .type = BLOBMSG_TYPE_INT32}, - [UCI_RSSI] = {.name = "rssi", .type = BLOBMSG_TYPE_INT32}, - [UCI_LOW_RSSI] = {.name = "low_rssi", .type = BLOBMSG_TYPE_INT32}, - [UCI_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, - [UCI_CHAN_UTIL] = {.name = "chan_util", .type = BLOBMSG_TYPE_INT32}, - [UCI_MAX_CHAN_UTIL] = {.name = "max_chan_util", .type = BLOBMSG_TYPE_INT32}, - [UCI_RSSI_VAL] = {.name = "rssi_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_LOW_RSSI_VAL] = {.name = "low_rssi_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_CHAN_UTIL_VAL] = {.name = "chan_util_val", .type = BLOBMSG_TYPE_INT32}, - [UCI_MAX_CHAN_UTIL_VAL] = {.name = "max_chan_util_val", .type = BLOBMSG_TYPE_INT32}, +static const struct blobmsg_policy uci_metric_policy[__UCI_METRIC_MAX] = { [UCI_MIN_PROBE_COUNT] = {.name = "min_probe_count", .type = BLOBMSG_TYPE_INT32}, [UCI_BANDWIDTH_THRESHOLD] = {.name = "bandwidth_threshold", .type = BLOBMSG_TYPE_INT32}, [UCI_USE_STATION_COUNT] = {.name = "use_station_count", .type = BLOBMSG_TYPE_INT32}, @@ -641,6 +635,23 @@ static const struct blobmsg_policy uci_metric_policy[__UCI_METIC_MAX] = { [UCI_SET_HOSTAPD_NR] = {.name = "set_hostapd_nr", .type = BLOBMSG_TYPE_INT32}, [UCI_DURATION] = {.name = "duration", .type = BLOBMSG_TYPE_INT32}, [UCI_RRM_MODE] = {.name = "rrm_mode", .type = BLOBMSG_TYPE_STRING}, + [UCI_BAND_METRICS] = {.name = "band_metrics", .type = BLOBMSG_TYPE_TABLE}, +}; + +static const struct blobmsg_policy uci_band_metric_policy[__UCI_METRIC_MAX] = { + [UCI_FREQ] = {.name = "freq", .type = BLOBMSG_TYPE_INT32}, + [UCI_HT_SUPPORT] = {.name = "ht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_VHT_SUPPORT] = {.name = "vht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_NO_HT_SUPPORT] = {.name = "no_ht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_NO_VHT_SUPPORT] = {.name = "no_vht_support", .type = BLOBMSG_TYPE_INT32}, + [UCI_RSSI] = {.name = "rssi", .type = BLOBMSG_TYPE_INT32}, + [UCI_RSSI_VAL] = {.name = "rssi_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_LOW_RSSI] = {.name = "low_rssi", .type = BLOBMSG_TYPE_INT32}, + [UCI_LOW_RSSI_VAL] = {.name = "low_rssi_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_CHAN_UTIL] = {.name = "chan_util", .type = BLOBMSG_TYPE_INT32}, + [UCI_MAX_CHAN_UTIL] = {.name = "max_chan_util", .type = BLOBMSG_TYPE_INT32}, + [UCI_CHAN_UTIL_VAL] = {.name = "chan_util_val", .type = BLOBMSG_TYPE_INT32}, + [UCI_MAX_CHAN_UTIL_VAL] = {.name = "max_chan_util_val", .type = BLOBMSG_TYPE_INT32}, }; static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = { @@ -667,97 +678,125 @@ static int handle_uci_config(struct blob_attr* msg) { return -1; } - struct blob_attr* tb_metric[__UCI_METIC_MAX]; - blobmsg_parse(uci_metric_policy, __UCI_METIC_MAX, tb_metric, blobmsg_data(tb[UCI_TABLE_METRIC]), blobmsg_len(tb[UCI_TABLE_METRIC])); + struct blob_attr* tb_metric[__UCI_METRIC_MAX]; + blobmsg_parse(uci_metric_policy, __UCI_METRIC_MAX, tb_metric, blobmsg_data(tb[UCI_TABLE_METRIC]), blobmsg_len(tb[UCI_TABLE_METRIC])); // TODO: Magic number? char cmd_buffer[1024]; - sprintf(cmd_buffer, "dawn.@metric[0].ht_support=%d", blobmsg_get_u32(tb_metric[UCI_HT_SUPPORT])); + + sprintf(cmd_buffer, "%s", "dawn.global=metric"); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].vht_support=%d", blobmsg_get_u32(tb_metric[UCI_VHT_SUPPORT])); + sprintf(cmd_buffer, "dawn.global.min_probe_count=%d", blobmsg_get_u32(tb_metric[UCI_MIN_PROBE_COUNT])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].no_ht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_HT_SUPPORT])); + sprintf(cmd_buffer, "dawn.global.bandwidth_threshold=%d", blobmsg_get_u32(tb_metric[UCI_BANDWIDTH_THRESHOLD])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].no_vht_support=%d", blobmsg_get_u32(tb_metric[UCI_NO_VHT_SUPPORT])); + sprintf(cmd_buffer, "dawn.global.use_station_count=%d", blobmsg_get_u32(tb_metric[UCI_USE_STATION_COUNT])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].rssi=%d", blobmsg_get_u32(tb_metric[UCI_RSSI])); + sprintf(cmd_buffer, "dawn.global.max_station_diff=%d", blobmsg_get_u32(tb_metric[UCI_MAX_STATION_DIFF])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].low_rssi=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI])); + sprintf(cmd_buffer, "dawn.global.eval_probe_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_PROBE_REQ])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].freq=%d", blobmsg_get_u32(tb_metric[UCI_FREQ])); + sprintf(cmd_buffer, "dawn.global.eval_auth_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_AUTH_REQ])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].chan_util=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL])); + sprintf(cmd_buffer, "dawn.global.eval_assoc_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_ASSOC_REQ])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_RSSI_VAL])); + sprintf(cmd_buffer, "dawn.global.kicking=%d", blobmsg_get_u32(tb_metric[UCI_KICKING])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].low_rssi_val=%d", blobmsg_get_u32(tb_metric[UCI_LOW_RSSI_VAL])); + sprintf(cmd_buffer, "dawn.global.deny_auth_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_AUTH_REASON])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_VAL])); + sprintf(cmd_buffer, "dawn.global.deny_assoc_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_ASSOC_REASON])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL])); + sprintf(cmd_buffer, "dawn.global.use_driver_recog=%d", blobmsg_get_u32(tb_metric[UCI_USE_DRIVER_RECOG])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].max_chan_util_val=%d", blobmsg_get_u32(tb_metric[UCI_MAX_CHAN_UTIL_VAL])); + sprintf(cmd_buffer, "dawn.global.min_number_to_kick=%d", blobmsg_get_u32(tb_metric[UCI_MIN_NUMBER_TO_KICK])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].min_probe_count=%d", blobmsg_get_u32(tb_metric[UCI_MIN_PROBE_COUNT])); + sprintf(cmd_buffer, "dawn.global.chan_util_avg_period=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_AVG_PERIOD])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].bandwidth_threshold=%d", blobmsg_get_u32(tb_metric[UCI_BANDWIDTH_THRESHOLD])); + sprintf(cmd_buffer, "dawn.global.set_hostapd_nr=%d", blobmsg_get_u32(tb_metric[UCI_SET_HOSTAPD_NR])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].use_station_count=%d", blobmsg_get_u32(tb_metric[UCI_USE_STATION_COUNT])); + sprintf(cmd_buffer, "dawn.global.duration=%d", blobmsg_get_u32(tb_metric[UCI_DURATION])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].max_station_diff=%d", blobmsg_get_u32(tb_metric[UCI_MAX_STATION_DIFF])); + sprintf(cmd_buffer, "dawn.global.rrm_mode=%s", blobmsg_get_string(tb_metric[UCI_RRM_MODE])); uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].eval_probe_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_PROBE_REQ])); - uci_set_network(cmd_buffer); + struct blob_attr *tb_band_metric[__UCI_BAND_METRIC_MAX], *attr; + int band_len = blobmsg_len(tb_metric[UCI_BAND_METRICS]); + struct blob_attr *band_data = blobmsg_data(tb_metric[UCI_BAND_METRICS]); + __blob_for_each_attr(attr, band_data, band_len) { + struct blobmsg_hdr *hdr = blob_data(attr); + const char *band_name = (const char *)hdr->name; + int band; - sprintf(cmd_buffer, "dawn.@metric[0].eval_auth_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_AUTH_REQ])); - uci_set_network(cmd_buffer); + blobmsg_parse(uci_band_metric_policy, __UCI_BAND_METRIC_MAX, tb_band_metric, + blobmsg_data(attr), blobmsg_len(attr)); - sprintf(cmd_buffer, "dawn.@metric[0].evalcd_assoc_req=%d", blobmsg_get_u32(tb_metric[UCI_EVAL_ASSOC_REQ])); - uci_set_network(cmd_buffer); + for (band = 0; band < __DAWN_BAND_MAX; band++) { + if (!strcmp(band_name, band_config_name[band])) + break; + } + if (band == __DAWN_BAND_MAX) { + fprintf(stderr, "handle_uci_config: Warning: unknown band '%s'.\n", band_name); + continue; // Should we write the metrics of an unknown band to the config file? + } - sprintf(cmd_buffer, "dawn.@metric[0].kicking=%d", blobmsg_get_u32(tb_metric[UCI_KICKING])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s=metric", band_name); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].deny_auth_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_AUTH_REASON])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.freq=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_FREQ])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].deny_assoc_reason=%d", blobmsg_get_u32(tb_metric[UCI_DENY_ASSOC_REASON])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.ht_support=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_HT_SUPPORT])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].use_driver_recog=%d", blobmsg_get_u32(tb_metric[UCI_USE_DRIVER_RECOG])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.vht_support=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_VHT_SUPPORT])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].min_number_to_kick=%d", blobmsg_get_u32(tb_metric[UCI_MIN_NUMBER_TO_KICK])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.no_ht_support=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_NO_HT_SUPPORT])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].chan_util_avg_period=%d", blobmsg_get_u32(tb_metric[UCI_CHAN_UTIL_AVG_PERIOD])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.no_vht_support=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_NO_VHT_SUPPORT])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].set_hostapd_nr=%d", blobmsg_get_u32(tb_metric[UCI_SET_HOSTAPD_NR])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.rssi=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_RSSI])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].duration=%d", blobmsg_get_u32(tb_metric[UCI_DURATION])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.rssi_val=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_RSSI_VAL])); + uci_set_network(cmd_buffer); - sprintf(cmd_buffer, "dawn.@metric[0].rrm_mode=%s", blobmsg_get_string(tb_metric[UCI_RRM_MODE])); - uci_set_network(cmd_buffer); + sprintf(cmd_buffer, "dawn.%s.low_rssi_val=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_LOW_RSSI_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.%s.low_rssi=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_LOW_RSSI])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.%s.chan_util=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_CHAN_UTIL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.%s.chan_util_val=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_CHAN_UTIL_VAL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.%s.max_chan_util=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_MAX_CHAN_UTIL])); + uci_set_network(cmd_buffer); + + sprintf(cmd_buffer, "dawn.%s.max_chan_util_val=%d", band_name, blobmsg_get_u32(tb_band_metric[UCI_MAX_CHAN_UTIL_VAL])); + uci_set_network(cmd_buffer); + } struct blob_attr* tb_times[__UCI_TIMES_MAX]; blobmsg_parse(uci_times_policy, __UCI_TIMES_MAX, tb_times, blobmsg_data(tb[UCI_TABLE_TIMES]), blobmsg_len(tb[UCI_TABLE_TIMES])); diff --git a/src/utils/ubus.c b/src/utils/ubus.c index eccae24..5896a61 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -104,6 +104,7 @@ struct hostapd_sock_entry { int chan_util_samples_sum; int chan_util_num_sample_periods; int chan_util_average; //TODO: Never evaluated? + int band; // add neighbor report string /* @@ -648,6 +649,15 @@ int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { return 0; } +static int get_band_from_bssid(struct dawn_mac bssid) { + ap *a; + for (a = ap_set; a; a = a->next_ap) { + if (mac_is_equal_bb(a->bssid_addr, bssid)) + return get_band(a->freq); + } + return -1; +} + static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_attr *msg) { struct hostapd_sock_entry *sub, *entry = NULL; @@ -685,7 +695,10 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ blobmsg_add_u8(&b_domain, "ht_supported", entry->ht_support); blobmsg_add_u8(&b_domain, "vht_supported", entry->vht_support); - blobmsg_add_u32(&b_domain, "ap_weight", dawn_metric.ap_weight); + if (entry->band < 0) + entry->band = get_band_from_bssid(entry->bssid_addr); + if (entry->band >= 0) + blobmsg_add_u32(&b_domain, "ap_weight", dawn_metric.ap_weight[entry->band]); //int channel_util = get_channel_utilization(entry->iface_name, &entry->last_channel_time, &entry->last_channel_time_busy); blobmsg_add_u32(&b_domain, "channel_utilization", entry->chan_util_average); @@ -1237,6 +1250,7 @@ bool subscribe(struct hostapd_sock_entry *hostapd_entry) { hostapd_entry->ht_support = (uint8_t) support_ht(hostapd_entry->iface_name); hostapd_entry->vht_support = (uint8_t) support_vht(hostapd_entry->iface_name); + hostapd_entry->band = -1; respond_to_notify(hostapd_entry->id); enable_rrm(hostapd_entry->id); @@ -1363,26 +1377,12 @@ const static char* get_rrm_mode_string(int *rrm_mode_order) { int uci_send_via_network() { - void *metric, *times; + void *metric, *times, *band_table, *band_entry; blob_buf_init(&b, 0); blobmsg_add_string(&b, "version", DAWN_CONFIG_VERSION); metric = blobmsg_open_table(&b, "metric"); - blobmsg_add_u32(&b, "ht_support", dawn_metric.ht_support); - blobmsg_add_u32(&b, "vht_support", dawn_metric.vht_support); - blobmsg_add_u32(&b, "no_ht_support", dawn_metric.no_ht_support); - blobmsg_add_u32(&b, "no_vht_support", dawn_metric.no_vht_support); - blobmsg_add_u32(&b, "rssi", dawn_metric.rssi); - blobmsg_add_u32(&b, "low_rssi", dawn_metric.low_rssi); - blobmsg_add_u32(&b, "freq", dawn_metric.freq); - blobmsg_add_u32(&b, "chan_util", dawn_metric.chan_util); - - blobmsg_add_u32(&b, "max_chan_util", dawn_metric.max_chan_util); - blobmsg_add_u32(&b, "rssi_val", dawn_metric.rssi_val); - blobmsg_add_u32(&b, "low_rssi_val", dawn_metric.low_rssi_val); - blobmsg_add_u32(&b, "chan_util_val", dawn_metric.chan_util_val); - blobmsg_add_u32(&b, "max_chan_util_val", dawn_metric.max_chan_util_val); blobmsg_add_u32(&b, "min_probe_count", dawn_metric.min_probe_count); blobmsg_add_u32(&b, "bandwidth_threshold", dawn_metric.bandwidth_threshold); blobmsg_add_u32(&b, "use_station_count", dawn_metric.use_station_count); @@ -1394,11 +1394,33 @@ int uci_send_via_network() blobmsg_add_u32(&b, "deny_auth_reason", dawn_metric.deny_auth_reason); blobmsg_add_u32(&b, "deny_assoc_reason", dawn_metric.deny_assoc_reason); blobmsg_add_u32(&b, "use_driver_recog", dawn_metric.use_driver_recog); - blobmsg_add_u32(&b, "min_number_to_kick", dawn_metric.min_kick_count); + blobmsg_add_u32(&b, "min_number_to_kick", dawn_metric.min_number_to_kick); blobmsg_add_u32(&b, "chan_util_avg_period", dawn_metric.chan_util_avg_period); blobmsg_add_u32(&b, "set_hostapd_nr", dawn_metric.set_hostapd_nr); blobmsg_add_u32(&b, "duration", dawn_metric.duration); blobmsg_add_string(&b, "rrm_mode", get_rrm_mode_string(dawn_metric.rrm_mode_order)); + band_table = blobmsg_open_table(&b, "band_metrics"); + + for (int band=0; band < __DAWN_BAND_MAX; band++) { + band_entry = blobmsg_open_table(&b, band_config_name[band]); + blobmsg_add_u32(&b, "ap_weight", dawn_metric.ap_weight[band]); + blobmsg_add_u32(&b, "ht_support", dawn_metric.ht_support[band]); + blobmsg_add_u32(&b, "vht_support", dawn_metric.vht_support[band]); + blobmsg_add_u32(&b, "no_ht_support", dawn_metric.no_ht_support[band]); + blobmsg_add_u32(&b, "no_vht_support", dawn_metric.no_vht_support[band]); + blobmsg_add_u32(&b, "rssi", dawn_metric.rssi[band]); + blobmsg_add_u32(&b, "rssi_val", dawn_metric.rssi_val[band]); + blobmsg_add_u32(&b, "low_rssi", dawn_metric.low_rssi[band]); + blobmsg_add_u32(&b, "low_rssi_val", dawn_metric.low_rssi_val[band]); + blobmsg_add_u32(&b, "freq", dawn_metric.freq[band]); + blobmsg_add_u32(&b, "chan_util", dawn_metric.chan_util[band]); + blobmsg_add_u32(&b, "max_chan_util", dawn_metric.max_chan_util[band]); + blobmsg_add_u32(&b, "chan_util_val", dawn_metric.chan_util_val[band]); + blobmsg_add_u32(&b, "max_chan_util_val", dawn_metric.max_chan_util_val[band]); + blobmsg_close_table(&b, band_entry); + } + blobmsg_close_table(&b, band_table); + blobmsg_close_table(&b, metric); times = blobmsg_open_table(&b, "times");