Use separate configs for 802.11g & 802.11a bands

This changes the metrics variables that invove scores to arrays.  At the
momemnt, there are two bands implemented, 802_11a and 802_11g.
Internally, they are chosen based on the frequency of the channel being
used.  Anything < 2500 MHz is 802_11g, and everything else is 802_11a.
Dawn will issue a warning if it finds a frequency greater or equal to
5925 MHz.  The upper limit of the 802.11a band, and the start of the
next band vary by country, so this will have to be reviewed.

The UCI configuration changes.  Instead of a single metric config, there
will be a global metric config, and one for each band.  The
non-band-specific configuration will only work in the global config.
Any per-band configuration present at the global config will be applied
to all bands.  Any configuration present at the specific band will
override any global values.

The following configuration options are split into bands:
 - ap_weight
 - ht_support
 - vht_support
 - no_ht_support
 - no_vht_support
 - rssi
 - rssi_val
 - low_rssi
 - low_rssi_val
 - freq
 - chan_util
 - max_chan_util
 - chan_util_val
 - max_chan_util_val

Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
This commit is contained in:
Eneas U de Queiroz 2021-06-28 14:01:49 -03:00 committed by Polynomdivision
parent 1e34357bdc
commit 6eb747b4d4
10 changed files with 367 additions and 201 deletions

View file

@ -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;
}

View file

@ -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]));

View file

@ -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");