diff --git a/wireless/wifictld/src/ubus_service.c b/wireless/wifictld/src/ubus_service.c index 39eb5d6..5c726af 100644 --- a/wireless/wifictld/src/ubus_service.c +++ b/wireless/wifictld/src/ubus_service.c @@ -21,6 +21,8 @@ static int ubus_get_clients(struct ubus_context *ctx, struct ubus_object *obj, sprintf(mac_buf, MACSTR, MAC2STR(el->addr)); c = blobmsg_open_table(&b, mac_buf); blobmsg_add_u32(&b, "try", el->try); + blobmsg_add_u32(&b, "time", el->time); + blobmsg_add_u32(&b, "authed", el->authed); blobmsg_add_u32(&b, "connected", el->connected); blobmsg_add_u32(&b, "freq_highest", el->freq_highest); blobmsg_add_u32(&b, "signal_lowfreq", el->signal_lowfreq); @@ -97,6 +99,43 @@ static int ubus_set_client_threashold(struct ubus_context *ctx, struct ubus_obje return 0; } +static int ubus_get_clean_values(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, struct blob_attr *msg) +{ + blob_buf_init(&b, 0); + blobmsg_add_u32(&b, "every", clean_every); + blobmsg_add_u32(&b, "older_then", clean_older_then); + ubus_send_reply(ctx, req, b.head); + return 0; +} + + +enum { + SET_CLEAN_EVERY, + SET_CLEAN_OLDER_THEN, + __SET_CLEAN_VALUES_MAX +}; + +static const struct blobmsg_policy ubus_set_clean_values_policy[__SET_CLEAN_VALUES_MAX] = { + [SET_CLEAN_EVERY] = { "every", BLOBMSG_TYPE_INT32 }, + [SET_CLEAN_OLDER_THEN] = { "older_then", BLOBMSG_TYPE_INT32 }, +}; + +static int ubus_set_clean_values(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, struct blob_attr *msg) +{ + struct blob_attr *tb[__SET_CLEAN_VALUES_MAX]; + + blobmsg_parse(ubus_set_clean_values_policy, __SET_CLEAN_VALUES_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[SET_CLEAN_EVERY] && !tb[SET_CLEAN_OLDER_THEN]) + return UBUS_STATUS_INVALID_ARGUMENT; + if (tb[SET_CLEAN_EVERY]) + clean_every = blobmsg_get_u32(tb[SET_CLEAN_EVERY]); + if (tb[SET_CLEAN_OLDER_THEN]) + clean_older_then = blobmsg_get_u32(tb[SET_CLEAN_OLDER_THEN]); + return 0; +} + static int ubus_is_client_probe_learning(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { @@ -127,6 +166,10 @@ static const struct ubus_method wifictld_ubus_methods[] = { UBUS_METHOD_NOARG("get_client_threasholds", ubus_get_client_threasholds), UBUS_METHOD("set_client_threasholds", ubus_set_client_threashold, ubus_set_client_threashold_policy), + // client threasholds + UBUS_METHOD_NOARG("get_clean_values", ubus_get_clean_values), + UBUS_METHOD("set_clean_values", ubus_set_clean_values, ubus_set_clean_values_policy), + // learn by probe (or only auth) UBUS_METHOD_NOARG("is_client_probe_learning", ubus_is_client_probe_learning), UBUS_METHOD_NOARG("toggle_client_probe_learning", ubus_toggle_client_probe_learning), diff --git a/wireless/wifictld/src/wifi_clients.c b/wireless/wifictld/src/wifi_clients.c index e458fa1..7d05e73 100644 --- a/wireless/wifictld/src/wifi_clients.c +++ b/wireless/wifictld/src/wifi_clients.c @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include "hostapd/ieee802_11_defs.h" // ETH_ALEN #include "log.h" #include "wifi_clients.h" @@ -9,8 +11,40 @@ int client_try_threashold = 4; int client_signal_threashold = -75; +int clean_every = 600; //in ms = 10min +int clean_older_then = 3600; //in sec = 1h + struct avl_tree clients_by_addr; + +void clean_cbhandler(struct uloop_timeout *t) +{ + int i = 0; + time_t now; + time(&now); + now -= clean_older_then; + struct wifi_client *client, *ptr; + avl_for_each_element_safe(&clients_by_addr, client, avl, ptr) { + if (client->time < now && client->authed == 0) { + avl_delete(&clients_by_addr, &client->avl); + log_verbose("clean_client(): "MACSTR" remove from memory\n", MAC2STR(client->addr)); + free(client); + i++; + } + } + uloop_timeout_set(t, clean_every * 1000); + + if (i > 0) { + log_info("remove %d clients from memory\n", i); + }else{ + log_verbose("clean_client(): remove %d clients from memory\n", i); + } +} + +struct uloop_timeout clean = { + .cb = clean_cbhandler +}; + static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) { return memcmp(k1, k2, ETH_ALEN); @@ -18,6 +52,8 @@ static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) int wifi_clients_init() { avl_init(&clients_by_addr, avl_compare_macaddr, false, NULL); + uloop_timeout_set(&clean, clean_every * 1000); + uloop_timeout_add(&clean); return 0; } @@ -37,6 +73,8 @@ struct wifi_client *__get_client(const u8 *address){ client = calloc(sizeof(*client), 1); memcpy(client->addr, address, sizeof(client->addr)); client->try = 0; + time(&client->time); + client->authed = 0; client->connected = 0; client->freq_highest = 0; client->signal_lowfreq = 0; @@ -60,7 +98,7 @@ void __client_learn(struct wifi_client *client, uint32_t freq, uint32_t ssi_sign client->signal_lowfreq = ssi_signal; } log_debug("\n"); - //TODO time set and reset clean + time(&client->time); } void wifi_clients_learn(const u8 *address, uint32_t freq, uint32_t ssi_signal) { @@ -80,6 +118,7 @@ int wifi_clients_try(const u8 *address, uint32_t freq, uint32_t ssi_signal) { if (freq > WIFI_CLIENT_FREQ_THREASHOLD) { log_info("accept\n"); client->try = 0; + client->authed = 1; client->connected = 1; return 0; } @@ -93,6 +132,7 @@ int wifi_clients_try(const u8 *address, uint32_t freq, uint32_t ssi_signal) { if(client->try > client_try_threashold) { log_info("accept - threashold\n"); client->try = 0; + client->authed = 1; client->connected = 1; return 0; } diff --git a/wireless/wifictld/src/wifi_clients.h b/wireless/wifictld/src/wifi_clients.h index 953ef27..88bb06d 100644 --- a/wireless/wifictld/src/wifi_clients.h +++ b/wireless/wifictld/src/wifi_clients.h @@ -2,20 +2,24 @@ #define __WIFICTLD_WIFI_CLIENTS_H #include +#include #include #include "hostapd/ieee802_11_defs.h" extern int client_try_threashold; extern int client_signal_threashold; +extern int clean_every; +extern int clean_older_then; extern struct avl_tree clients_by_addr; struct wifi_client { struct avl_node avl; u8 addr[ETH_ALEN]; - int time; + time_t time; int try; bool connected; + bool authed; uint32_t freq_highest; uint32_t signal_lowfreq; uint32_t signal_highfreq;