diff --git a/src/include/datastorage.h b/src/include/datastorage.h index c47e2a4..6d7a6fd 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -33,6 +33,7 @@ struct probe_metric_s { int max_chan_util_val; int min_probe_count; int bandwith_threshold; + int use_station_count; }; struct time_config_s { @@ -128,6 +129,7 @@ typedef struct ap_s { uint8_t vht; uint32_t channel_utilization; time_t time; + uint32_t station_count; } ap; // ---------------- Defines ---------------- @@ -177,7 +179,7 @@ int mac_is_equal(uint8_t addr1[], uint8_t addr2[]); int mac_is_greater(uint8_t addr1[], uint8_t addr2[]); -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]); +int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick); /* List stuff */ diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index a80cccf..a07eae8 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -41,6 +41,8 @@ int probe_array_update_rssi(uint8_t bssid_addr[], uint8_t client_addr[], uint32_ int is_connected(uint8_t bssid_addr[], uint8_t client_addr[]); +int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, int automatic_kick); + int probe_entry_last = -1; int client_entry_last = -1; int ap_entry_last = -1; @@ -89,7 +91,28 @@ int eval_probe_metric(struct probe_entry_s probe_entry) { return score; } -int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) { +int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare, int automatic_kick) { + + ap ap_entry_own = ap_array_get_ap(bssid_addr_own); + ap ap_entry_to_compre = ap_array_get_ap(bssid_addr_to_compare); + + // check if ap entry is available + if (mac_is_equal(ap_entry_own.bssid_addr, bssid_addr_own) + && mac_is_equal(ap_entry_to_compre.bssid_addr, bssid_addr_to_compare) + ) { + printf("Comparing own %d to %d\n", ap_entry_own.station_count, ap_entry_to_compre.station_count); + if(automatic_kick){ + return (ap_entry_own.station_count - 1) > ap_entry_to_compre.station_count; + } else { + return ap_entry_own.station_count > ap_entry_to_compre.station_count; + } + } + + return 0; +} + + +int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick) { int own_score = -1; // find first client entry in probe array @@ -131,12 +154,18 @@ int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[]) { { return 1; } + if ( dawn_metric.use_station_count && !mac_is_equal(bssid_addr, probe_array[k].bssid_addr) && + own_score == eval_probe_metric(probe_array[k])) + { + // if ap have same value but station count is different... + return compare_station_count(bssid_addr, probe_array[k].bssid_addr, automatic_kick); + } } return 0; } int kick_client(struct client_s client_entry) { - return better_ap_available(client_entry.bssid_addr, client_entry.client_addr); + return better_ap_available(client_entry.bssid_addr, client_entry.client_addr, 1); } void kick_clients(uint8_t bssid[], uint32_t id) { diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index 9ca9938..05401a6 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -209,6 +209,14 @@ struct probe_metric_s uci_get_dawn_metric() { if (ptr.o->type == UCI_TYPE_STRING) ret.bandwith_threshold = atoi(ptr.o->v.string); + char tmp_use_station_count[] = "dawn.metric.use_station_count"; + if (uci_lookup_ptr(c, &ptr, tmp_use_station_count, 1) != UCI_OK) { + uci_perror(c, "uci_get_daw_metric Error"); + return ret; + } + if (ptr.o->type == UCI_TYPE_STRING) + ret.use_station_count = atoi(ptr.o->v.string); + printf("Loaded metric: %d\n", ret.min_probe_count); uci_free_context(c); diff --git a/src/utils/ubus.c b/src/utils/ubus.c index f9b0c53..f10e047 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -80,6 +80,7 @@ enum { CLIENT_TABLE_HT, CLIENT_TABLE_VHT, CLIENT_TABLE_CHAN_UTIL, + CLIENT_TABLE_NUM_STA, __CLIENT_TABLE_MAX, }; @@ -90,6 +91,7 @@ static const struct blobmsg_policy client_table_policy[__CLIENT_TABLE_MAX] = { [CLIENT_TABLE_HT] = {.name = "ht_supported", .type = BLOBMSG_TYPE_INT8}, [CLIENT_TABLE_VHT] = {.name = "vht_supported", .type = BLOBMSG_TYPE_INT8}, [CLIENT_TABLE_CHAN_UTIL] = {.name = "channel_utilization", .type = BLOBMSG_TYPE_INT32}, + [CLIENT_TABLE_NUM_STA] = {.name = "num_sta", .type = BLOBMSG_TYPE_INT32}, }; enum { @@ -215,7 +217,7 @@ static int decide_function(probe_entry *prob_req) { return 0; } - if(better_ap_available(prob_req->bssid_addr, prob_req->client_addr)) + if(better_ap_available(prob_req->bssid_addr, prob_req->client_addr, 0)) { return 0; } @@ -345,7 +347,7 @@ static int handle_probe_req(struct blob_attr *msg) { printf("[WC] Hostapd-Probe: %s : %s\n", "probe", str); - print_probe_array(); + //print_probe_array(); /* // deny access if (!decide_function(&tmp_probe)) { @@ -574,6 +576,15 @@ int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id) { ap_entry.ht = blobmsg_get_u8(tb[CLIENT_TABLE_HT]); ap_entry.vht = blobmsg_get_u8(tb[CLIENT_TABLE_VHT]); ap_entry.channel_utilization = blobmsg_get_u32(tb[CLIENT_TABLE_CHAN_UTIL]); + + if(tb[CLIENT_TABLE_NUM_STA]) + { + ap_entry.station_count = blobmsg_get_u32(tb[CLIENT_TABLE_NUM_STA]); + } else + { + ap_entry.station_count = 0; + } + insert_to_ap_array(ap_entry); if (do_kick) {