diff --git a/files/dawn.config b/files/dawn.config index 83e67c2..6a6efbc 100644 --- a/files/dawn.config +++ b/files/dawn.config @@ -31,3 +31,4 @@ config settings metric option rssi_val '-60' option low_rssi_val '-79' option min_probe_count '2' + option bandwith_threshold '6' diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 589f2b8..ae445a9 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,7 @@ SET(SOURCES crypto/base64.c include/base64.h - utils/utils.c include/rssi.h utils/rssi.c) + utils/utils.c include/dawn_iwinfo.h utils/dawn_iwinfo.c) SET(LIBS ubox ubus json-c blobmsg_json config uci gcrypt iwinfo) diff --git a/src/include/datastorage.h b/src/include/datastorage.h index 6371c6c..979063c 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -30,6 +30,7 @@ struct probe_metric_s { int rssi_val; int low_rssi_val; int min_probe_count; + int bandwith_threshold; }; struct time_config_s { diff --git a/src/include/rssi.h b/src/include/dawn_iwinfo.h similarity index 69% rename from src/include/rssi.h rename to src/include/dawn_iwinfo.h index 863f25b..215d817 100644 --- a/src/include/rssi.h +++ b/src/include/dawn_iwinfo.h @@ -8,4 +8,6 @@ int get_rssi_iwinfo(__uint8_t *client_addr); +int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate); + #endif //DAWN_RSSI_H diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 5f4cfb2..a7d8a65 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -4,7 +4,7 @@ #include #include "ubus.h" -#include "rssi.h" +#include "dawn_iwinfo.h" #include "utils.h" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] @@ -174,6 +174,21 @@ void kick_clients(uint8_t bssid[], uint32_t id) { if (kick_client(client_array[j]) > 0) { printf("Better AP available. Kicking client:\n"); print_client_entry(client_array[j]); + printf("Check if client is active receiving!\n"); + + float rx_rate, tx_rate; + if(get_bandwidth_iwinfo(client_array[j].client_addr, &rx_rate, &tx_rate)) + { + // only use rx_rate for indicating if transmission is going on + // <= 6MBits <- probably no transmission + // tx_rate has always some weird value so don't use ist + if(rx_rate > dawn_metric.bandwith_threshold){ + printf("Client is probably in active transmisison. Don't kick! RxRate is: %f\n", rx_rate); + continue; + } + } + printf("Client is probably NOT in active transmisison. KICK! RxRate is: %f\n", rx_rate); + del_client_interface(id, client_array[j].client_addr, 5, 1, 60000); client_array_delete(client_array[j]); diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c new file mode 100644 index 0000000..28ef62d --- /dev/null +++ b/src/utils/dawn_iwinfo.c @@ -0,0 +1,140 @@ +#include "dawn_iwinfo.h" + +#include +#include +#include + +#include "utils.h" +#include "ubus.h" + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] + +int call_iwinfo(char *client_addr); + +int parse_rssi(char *iwinfo_string); + +int get_rssi(const char *ifname, uint8_t *client_addr); + +int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate); + +#define IWINFO_BUFSIZE 24 * 1024 + +int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) { + + DIR *dirp; + struct dirent *entry; + dirp = opendir(hostapd_dir_glob); // error handling? + if (!dirp) { + fprintf(stderr, "No hostapd sockets!\n"); + return 0; + } + + int sucess = 0; + + int count = 0; + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_SOCK) { + if(get_bandwith(entry->d_name, client_addr, rx_rate, tx_rate)) + { + sucess = 1; + break; + } + } + } + closedir(dirp); + return sucess; +} + +int get_bandwith(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate){ + + int i, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_assoclist_entry *e; + const struct iwinfo_ops *iw; + + iw = iwinfo_backend(ifname); + + if (iw->assoclist(ifname, buf, &len)) + { + printf("No information available\n"); + return 0; + } + else if (len <= 0) + { + printf("No station connected\n"); + return 0; + } + + for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) + { + e = (struct iwinfo_assoclist_entry *) &buf[i]; + + if(mac_is_equal(client_addr, e->mac)) + { + //struct iwinfo_assoclist_entry * rx_rate = e->rx_rate; + //struct iwinfo_assoclist_entry * tx_rate = e->tx_rate; + *rx_rate = e->rx_rate.rate / 1000; + *tx_rate = e->tx_rate.rate / 1000; + return 1; + } + // return e->signal; + + + } + + return 0; +} + +int get_rssi_iwinfo(__uint8_t *client_addr) { + + DIR *dirp; + struct dirent *entry; + dirp = opendir(hostapd_dir_glob); // error handling? + if (!dirp) { + fprintf(stderr, "No hostapd sockets!\n"); + return INT_MIN; + } + + int rssi = INT_MIN; + + while ((entry = readdir(dirp)) != NULL) { + if (entry->d_type == DT_SOCK) { + rssi = get_rssi(entry->d_name, client_addr); + if(rssi != INT_MIN) + break; + } + } + closedir(dirp); + return rssi; +} + +int get_rssi(const char *ifname, uint8_t *client_addr){ + + int i, len; + char buf[IWINFO_BUFSIZE]; + struct iwinfo_assoclist_entry *e; + const struct iwinfo_ops *iw; + + iw = iwinfo_backend(ifname); + + if (iw->assoclist(ifname, buf, &len)) + { + printf("No information available\n"); + return INT_MIN; + } + else if (len <= 0) + { + printf("No station connected\n"); + return INT_MIN; + } + + for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) + { + e = (struct iwinfo_assoclist_entry *) &buf[i]; + + if(mac_is_equal(client_addr, e->mac)) + return e->signal; + } + + return INT_MIN; +} \ No newline at end of file diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index 687f3dc..f694084 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -184,6 +184,14 @@ struct probe_metric_s uci_get_dawn_metric() { if (ptr.o->type == UCI_TYPE_STRING) ret.low_rssi_val = atoi(ptr.o->v.string); + char tmp_bandwith_threshold[] = "dawn.metric.bandwith_threshold"; + if (uci_lookup_ptr(c, &ptr, tmp_bandwith_threshold, 1) != UCI_OK) { + uci_perror(c, "uci_get_daw_metric Error"); + return ret; + } + if (ptr.o->type == UCI_TYPE_STRING) + ret.bandwith_threshold = atoi(ptr.o->v.string); + printf("Loaded metric: %d\n", ret.min_probe_count); uci_free_context(c); diff --git a/src/utils/rssi.c b/src/utils/rssi.c deleted file mode 100644 index 7474613..0000000 --- a/src/utils/rssi.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "rssi.h" - -#include -#include -#include - -#include "utils.h" -#include "ubus.h" - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] - -int call_iwinfo(char *client_addr); - -int parse_rssi(char *iwinfo_string); - -int get_rssi(const char *ifname, uint8_t *client_addr); - -#define IWINFO_BUFSIZE 24 * 1024 - -int get_rssi_iwinfo(__uint8_t *client_addr) { - - DIR *dirp; - struct dirent *entry; - dirp = opendir(hostapd_dir_glob); // error handling? - if (!dirp) { - fprintf(stderr, "No hostapd sockets!\n"); - return -1; - } - - int rssi = INT_MIN; - - while ((entry = readdir(dirp)) != NULL) { - if (entry->d_type == DT_SOCK) { - rssi = get_rssi(entry->d_name, client_addr); - if(rssi != INT_MIN) - break; - } - } - closedir(dirp); - return rssi; -} - -int get_rssi(const char *ifname, uint8_t *client_addr){ - - int i, len; - char buf[IWINFO_BUFSIZE]; - struct iwinfo_assoclist_entry *e; - const struct iwinfo_ops *iw; - - iw = iwinfo_backend(ifname); - - if (iw->assoclist(ifname, buf, &len)) - { - printf("No information available\n"); - return INT_MIN; - } - else if (len <= 0) - { - printf("No station connected\n"); - return INT_MIN; - } - - for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) - { - e = (struct iwinfo_assoclist_entry *) &buf[i]; - - if(mac_is_equal(client_addr, e->mac)) - return e->signal; - } - - return INT_MIN; -} \ No newline at end of file