diff --git a/src/agent.c b/src/agent.c index daeaa1b1d42e90cce38f26d402468557041a8c28..e9627e061a66468d52d04b2fb5a45823fd4a4c8c 100644 --- a/src/agent.c +++ b/src/agent.c @@ -778,26 +778,10 @@ void agent_link_ap_to_cfg(struct agent *a) static void agent_config_load_post_action(struct agent *a) { - struct wifi_radio_element *re = NULL; - agent_link_ap_to_cfg(a); if (a->cfg.pcfg) a->pvid = a->cfg.pcfg->pvid; - - /* Update restrict_stalist from assoc_ctrllist */ - list_for_each_entry(re, &a->radiolist, list) { - struct netif_ap *p = NULL; - - list_for_each_entry(p, &re->aplist, list) { - - /* Copy restrictions from cfg to runtime */ - assoc_ctrl_sync_from_config(a, p); - - /* Block STAs in WiFi */ - assoc_ctrl_apply_restriction(a, p); - } - } } int agent_config_reload(struct agent *a) @@ -6586,6 +6570,9 @@ void agent_init_interfaces_post_actions(struct agent *a) list_for_each_entry(ap, &re->aplist, list) { int num_sta = ap->max_sta ? ap->max_sta : 128; + /* Block STas in WiFi if wifi is restarted at run-time */ + assoc_ctrl_apply_restriction(a, ap); + #if (EASYMESH_VERSION >= 6) if (ap->is_affiliated_ap) { struct wifi_mlsta mlsta[128] = {0}; @@ -6610,9 +6597,6 @@ void agent_init_interfaces_post_actions(struct agent *a) wifi_add_sta(a, ap->ifname, &sta[i * 6]); } - /* Block STas in WiFi if wifi is restarted at run-time */ - assoc_ctrl_apply_restriction(a, ap); - /* Notify ctrl once upon start if adding STA is allowed */ if (ap->max_sta && !ap->sent_assocnotif) { agent_notify_assoc_status(a, ap->bssid, num_sta >= ap->max_sta ? false : true); @@ -6748,6 +6732,9 @@ int agent_init_interfaces(struct agent *a) strncpy(fn->radio_name, re->name, IFNAMSIZ-1); fn->sent_assocnotif = false; + /* Copy STA restrictions from file to runtime */ + assoc_ctrl_sync_from_file(a, fn); + list_add(&fn->list, &re->aplist); } else continue; diff --git a/src/assoc_ctrl.c b/src/assoc_ctrl.c index 3fd867c201c75b05f56c00787bc55f3975431093..54ec5aef439d511a759f45c3bfccaff0aa6319a1 100644 --- a/src/assoc_ctrl.c +++ b/src/assoc_ctrl.c @@ -4,6 +4,9 @@ * Copyright (C) 2025 IOPSYS Software Solutions AB. All rights reserved. * */ +#include <json-c/json.h> +#include <libubox/blobmsg_json.h> + #include <easymesh.h> #include "agent.h" @@ -17,18 +20,328 @@ #include "utils/debug.h" #include "utils/utils.h" -static void assoc_ctrl_update_config(struct agent *a, uint8_t *mac, - struct netif_apcfg *cfg, int add) +static void assoc_ctrl_remove_client(struct json_object *arr, uint8_t *macaddr) +{ + int len, i; + + len = json_object_array_length(arr); + for (i = 0; i < len; i++) { + struct json_object *t; + const char *p; + uint8_t mac[6]; + + t = json_object_array_get_idx(arr, i); + if (!t) { + warn("%s: couldn't get entry:%d from restriction array", + __func__, i); + continue; + } + + p = json_get_string(t, "macaddr"); + if (!p) { + warn("%s: couldn't get macaddr from entry:%d", + __func__, i); + continue; + } + + if (hwaddr_aton(p, mac) < 0) { + warn("%s: couldn't convert macaddr from entry:%d", + __func__, i); + continue; + } + + if (!memcmp(mac, macaddr, 6)) { + if (json_object_array_del_idx(arr, i, 1) < 0) { + warn("%s: couldn't remove entry:%d from restriction array", + __func__, i); + return; + } + break; + } + } +} + +static void assoc_ctrl_write_client(struct json_object *arr, uint8_t *macaddr, + uint16_t validity, uint8_t mode) { - char stastr[18] = {0}; + struct json_object *val, *new; + char macstr[18] = {0}; + char time_str[64] = {0}; + + if (!arr) + return; + + if (!json_object_is_type(arr, json_type_array)) { + warn("%s: clients is not an array\n", __func__); + return; + } + + /* remove client if it already exists */ + assoc_ctrl_remove_client(arr, macaddr); + + if (mode == ASSOC_CTRL_UNBLOCK) + /* client is unblocked, no need to add */ + return; + + new = json_object_new_object(); + if (!new) + return; + + /* macaddr */ + snprintf(macstr, sizeof(macstr), MACFMT, MAC2STR(macaddr)); /* Flawfinder: ignore */ + val = json_object_new_string(macstr); + if (!val) + return; + json_object_object_add(new, "macaddr", val); + + /* start_time */ + time_to_timestr(NULL, time_str); + val = json_object_new_string(time_str); + if (!val) + return; + json_object_object_add(new, "start_time", val); + + /* duration */ + val = json_object_new_int(validity); + if (!val) + return; + json_object_object_add(new, "duration", val); - hwaddr_ntoa(mac, stastr); - config_update2("mapagent", &a->cfg, "ap", - "ifname", cfg->name, - "assoc_ctrl", add, stastr, 18); + /* mode */ + val = json_object_new_int(mode); + if (!val) + return; + json_object_object_add(new, "mode", val); - add ? stax_add_entry(&cfg->assoc_ctrllist, mac) - : stax_del_entry(&cfg->assoc_ctrllist, mac); + json_object_array_add(arr, new); +} + +/* generate a restricted client entry if it does not exist */ +static int assoc_ctrl_update_restrict_file(uint8_t *bssid, uint8_t *macaddr, + uint16_t validity, uint8_t mode) +{ + struct json_object *restr_json; + struct json_object *bssids, *bssid_obj = NULL; + struct json_object *clients; + json_bool ret; + int len, i; + + dbg("%s: file:%s\n", __func__, ASSOC_CTRL_FILE); + + /* Get the json object from the file */ + restr_json = json_object_from_file(ASSOC_CTRL_FILE); + if (!restr_json) { + dbg("%s: failed to read json:%s, error:%s. "\ + "Try to generate new\n", __func__, + ASSOC_CTRL_FILE, json_util_get_last_err()); + + restr_json = json_object_new_object(); + if (!restr_json) { + warn("%s: failed to create json obj, error:%s. ", + __func__, json_util_get_last_err()); + goto out; + } + } + + /* Get the bssids array */ + ret = json_object_object_get_ex(restr_json, "bssids", &bssids); + if (!ret) { + /* Create bssids array if not found */ + bssids = json_object_new_array(); + if (!bssids) { + warn("%s: failed to add bssid array, error:%s. ", + __func__, json_util_get_last_err()); + goto out_bssid; + } + json_object_object_add(restr_json, "bssids", bssids); + } else if (!json_object_is_type(bssids, json_type_array)) { + warn("%s: file: %s has wrong format\n", + __func__, ASSOC_CTRL_FILE); + goto out_bssid; + } + + /* Check if bssid already exists in bssid array */ + len = json_object_array_length(bssids); + for (i = 0; i < len; i++) { + struct json_object *t; + uint8_t t_bssid[6]; + const char *p; + + t = json_object_array_get_idx(bssids, i); + if (!t) { + warn("%s: couldn't get entry:%d from bssid array", __func__, i); + continue; + } + + p = json_get_string(t, "bssid"); + if (!p) { + warn("%s: couldn't get bssid from entry:%d", __func__, i); + continue; + } + + if (hwaddr_aton(p, t_bssid) < 0) { + warn("%s: couldn't convert bssid from entry:%d", __func__, i); + continue; + } + + if (!memcmp(bssid, t_bssid, ETH_ALEN)) { + /* bssid already exists in file */ + bssid_obj = t; + break; + } + } + + /* Create new bssid object if not found */ + if (!bssid_obj) { + char bssidstr[18] = {0}; + struct json_object *val; + + bssid_obj = json_object_new_object(); + if (WARN_ON(!bssid_obj)) + goto out_bssid; + + /* bssid */ + hwaddr_ntoa(bssid, bssidstr); + val = json_object_new_string(bssidstr); + if (!val) { + json_object_put(bssid_obj); + goto out_bssid; + } + json_object_object_add(bssid_obj, "bssid", val); + + /* Add bssid object to bssids array */ + json_object_array_add(bssids, bssid_obj); + } + + /* Get the clients array */ + ret = json_object_object_get_ex(bssid_obj, "clients", &clients); + if (!ret) { + /* Create client array if not found */ + clients = json_object_new_array(); + if (!clients) { + json_object_put(bssid_obj); + goto out_bssid; + } + json_object_object_add(bssid_obj, "clients", clients); + } else { + if (!json_object_is_type(clients, json_type_array)) { + warn("|%s:%d| file:%s is not expected format\n", __func__, + __LINE__, ASSOC_CTRL_FILE); + json_object_put(bssid_obj); + goto out_bssid; + } + } + + /* Add (or remove) the client entry */ + assoc_ctrl_write_client(clients, macaddr, validity, mode); + + /* Update restricted clients file */ + json_object_to_file(ASSOC_CTRL_FILE, restr_json); + +out_bssid: + json_object_put(restr_json); +out: + return 0; +} + +struct rsta { + uint8_t macaddr[6]; + uint8_t mode; + uint16_t validity; +}; + +int assoc_ctrl_read_restrictions(struct agent *a, uint8_t *bssid, + struct rsta *fr, int *num_fr) +{ + struct blob_buf bssids = { 0 }; + struct blob_attr *b; + static const struct blobmsg_policy attr[] = { + [0] = { .name = "bssids", .type = BLOBMSG_TYPE_ARRAY }, + }; + struct blob_attr *tb[ARRAY_SIZE(attr)]; + int rem; + int ret = 0; + + blob_buf_init(&bssids, 0); + + if (!blobmsg_add_json_from_file(&bssids, ASSOC_CTRL_FILE)) { + warn("Failed to parse %s\n", ASSOC_CTRL_FILE); + ret = -1; + goto out; + } + + blobmsg_parse(attr, ARRAY_SIZE(attr), tb, blob_data(bssids.head), blob_len(bssids.head)); + + if (!tb[0]) + goto out; + + blobmsg_for_each_attr(b, tb[0], rem) { + static const struct blobmsg_policy bssid_attr[2] = { + [0] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING }, + [1] = { .name = "clients", .type = BLOBMSG_TYPE_ARRAY }, + }; + struct blob_attr *tb1[ARRAY_SIZE(bssid_attr)]; + char bssid_str[18] = {0}; + uint8_t bssid_mac[6] = {0}; + struct blob_attr *client; + int rem1; + + blobmsg_parse(bssid_attr, ARRAY_SIZE(bssid_attr), tb1, blobmsg_data(b), blob_len(b)); + if (!tb1[0] || !tb1[1]) + continue; + + strncpy(bssid_str, blobmsg_data(tb1[0]), sizeof(bssid_str) - 1); + if (hwaddr_aton(bssid_str, bssid_mac) < 0) { + warn("Failed to convert macaddr %s\n", bssid_str); + continue; + } + + if (memcmp(bssid, bssid_mac, ETH_ALEN)) + continue; + + blobmsg_for_each_attr(client, tb1[1], rem1) { + static const struct blobmsg_policy client_attr[4] = { + [0] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING }, + [1] = { .name = "start_time", .type = BLOBMSG_TYPE_STRING }, + [2] = { .name = "duration", .type = BLOBMSG_TYPE_INT32 }, + [3] = { .name = "mode", .type = BLOBMSG_TYPE_INT32 }, + }; + struct blob_attr *tb2[ARRAY_SIZE(client_attr)]; + char mac_str[18] = {0}; + uint8_t macaddr[6] = {0}; + int32_t duration, elapsed; + time_t start, now = time(NULL); + + blobmsg_parse(client_attr, ARRAY_SIZE(client_attr), tb2, blobmsg_data(client), blob_len(client)); + if (!tb2[0] || !tb2[1] || !tb2[2] || !tb2[3]) + continue; + + strncpy(mac_str, blobmsg_data(tb2[0]), sizeof(mac_str) - 1); + if (hwaddr_aton(mac_str, macaddr) < 0) { + warn("Failed to convert macaddr %s\n", mac_str); + continue; + } + + memcpy(fr[*num_fr].macaddr, macaddr, ETH_ALEN); + fr[*num_fr].mode = blobmsg_get_u32(tb2[3]); + start = timestr_to_time(blobmsg_get_string(tb2[1])); + duration = blobmsg_get_u32(tb2[2]); + elapsed = (int32_t)difftime(now, start); + if (elapsed < 0 || elapsed > duration) { + fr[*num_fr].validity = 0; + } else { + fr[*num_fr].validity = duration - elapsed; + /* TODO: remove outdated entry from file */ + } + + (*num_fr)++; + } + } + +out: + blob_buf_free(&bssids); + + return ret; } static void agent_disconnect_stas(struct agent *a, int num_sta, @@ -110,6 +423,7 @@ static void wifi_sta_restrict_timeout_cb(atimer_t *t) /* Unblock STA */ wifi_restrict_sta(ap, s->macaddr, false); + assoc_ctrl_update_restrict_file(ap->bssid, s->macaddr, 0, ASSOC_CTRL_UNBLOCK); list_del(&s->list); free(s); } @@ -126,47 +440,49 @@ static struct restrict_sta_entry *find_restricted_sta(struct netif_ap *ap, uint8 } int assoc_ctrl_add_sta(struct agent *a, struct netif_ap *ap, - uint32_t num_sta, uint8_t sta_list[][6], - uint16_t validity_period, uint8_t mode, + uint32_t num_fr, struct rsta fr[], bool update_config) { trace("agent: %s: --->\n", __func__); int i = 0; - if (!sta_list) + if (!fr) return -1; - for (i = 0; i < num_sta; i++) { + for (i = 0; i < num_fr; i++) { struct restrict_sta_entry *s; - s = find_restricted_sta(ap, sta_list[i]); + s = find_restricted_sta(ap, fr[i].macaddr); if (!s) { /* Add new entry to restricted list */ s = calloc(1, sizeof(struct restrict_sta_entry)); if (!s) return -1; - memcpy(s->macaddr, sta_list[i], 6); + memcpy(s->macaddr, fr[i].macaddr, 6); memcpy(s->bssid, ap->bssid, 6); s->agent = a; - s->mode = mode; + s->mode = fr[i].mode; list_add_tail(&s->list, &ap->restrict_stalist); timer_init(&s->restrict_timer, wifi_sta_restrict_timeout_cb); } - if (validity_period > 0) - /* If timeout is positive, create a timed sta assoc-control - * entry but don't update config. At the timer expiry, remove - * sta from assoc-control list. - */ - timer_set(&s->restrict_timer, validity_period * 1000); - else if (update_config) - /* If timeout is 0 or negative, permanently add sta to the - * AP's assoc control list by creating a config entry. - */ - assoc_ctrl_update_config(a, sta_list[i], ap->cfg, 1); + /* Update validity timer */ + if ((s->mode == ASSOC_CTRL_TIMED_BLOCK || s->mode == ASSOC_CTRL_BLOCK)) { + if (fr[i].validity > 0) + timer_set(&s->restrict_timer, fr[i].validity * 1000); + else { + /* error */ + continue; + } + } + + /* Update restriction file */ + if (update_config) + assoc_ctrl_update_restrict_file(ap->bssid, + fr[i].macaddr, fr[i].validity, fr[i].mode); } return 0; @@ -177,13 +493,27 @@ int assoc_ctrl_block_sta(struct agent *a, struct netif_ap *ap, uint32_t num_sta, uint8_t sta_list[][6]) { trace("agent: %s: --->\n", __func__); + + struct rsta fr[ASSOC_CTRL_MAX_STA]; + int num_fr = 0; int ret = 0; - /* Add STA to restricted list */ - ret = assoc_ctrl_add_sta(a, ap, num_sta, sta_list, - validity_period, mode, true); + if (num_sta > ASSOC_CTRL_MAX_STA) { + err("[%s:%d] Invalid number of STAs\n", __func__, __LINE__); + return -1; + } + + for (int i = 0; i < num_sta; i++) { + memcpy(fr[num_fr].macaddr, sta_list[i], ETH_ALEN); + fr[num_fr].mode = mode; + fr[num_fr].validity = validity_period; + num_fr++; + } + + /* Add STAs to runtime & file lists */ + ret = assoc_ctrl_add_sta(a, ap, num_fr, fr, true); if (!ret) - /* Block STA in WiFi */ + /* Block STAs in WiFi */ ret = assoc_ctrl_restrict_sta(a, num_sta, sta_list, ap, mode); return ret; @@ -201,18 +531,21 @@ int assoc_ctrl_del_sta(struct agent *a, struct netif_ap *ap, return -1; for (i = 0; i < num_sta; i++) { - /* Stop validity timer and remove entry from restricted list */ + + /* Stop validity timer and remove entry from runtime list */ list_for_each_entry_safe(s, tmp, &ap->restrict_stalist, list) { if (!memcmp(s->macaddr, sta_list[i], 6)) { - if (update_config) - /* Update config to remove the STA */ - assoc_ctrl_update_config(a, sta_list[i], ap->cfg, 0); - timer_del(&s->restrict_timer); list_del(&s->list); free(s); } } + + /* Remove STA from restriction file */ + if (update_config) { + assoc_ctrl_update_restrict_file(ap->bssid, + sta_list[i], 0, ASSOC_CTRL_UNBLOCK); + } } return 0; @@ -224,52 +557,52 @@ int assoc_ctrl_unblock_sta(struct agent *a, struct netif_ap *ap, trace("agent: %s: --->\n", __func__); int ret = 0; - /* Remove STA from restricted list */ + /* Remove STAs from runtime and file lists */ ret = assoc_ctrl_del_sta(a, ap, num_sta, sta_list, true); if (!ret) - /* Unblock STA in WiFi */ + /* Unblock STAs in WiFi */ ret = assoc_ctrl_restrict_sta(a, num_sta, sta_list, ap, ASSOC_CTRL_UNBLOCK); return ret; } -int assoc_ctrl_sync_from_config(struct agent *a, struct netif_ap *ap) +/* Sync runtime list from file list only - do not apply restriction */ +int assoc_ctrl_sync_from_file(struct agent *a, struct netif_ap *ap) { trace("agent: %s: --->\n", __func__); - struct stax *x = NULL; + struct rsta fr[ASSOC_CTRL_MAX_STA]; + int num_fr = 0; struct restrict_sta_entry *s = NULL; - uint8_t stalist[MAX_STA][6] = {0}; - int num_sta = 0; int ret = 0; - /* 1. Add STAs missing in runtime list */ - list_for_each_entry(x, &ap->cfg->assoc_ctrllist, list) { - memcpy(stalist[num_sta++], x->macaddr, 6); - } + /* Read STA restrictions from file list */ + ret = assoc_ctrl_read_restrictions(a, ap->bssid, fr, &num_fr); + if (ret) + return ret; - if (num_sta > 0) - /* Update the runtime list and restart timer */ - ret |= assoc_ctrl_add_sta(a, ap, num_sta, stalist, - 0 /* FIXME tmo from cfg */, - ASSOC_CTRL_INDEF_BLOCK /* FIXME mode from cfg */, - false); + /* 1. Add/Update STAs: file list -> runtime list */ + if (num_fr > 0) + ret |= assoc_ctrl_add_sta(a, ap, num_fr, fr, false); - /* 2. Remove STAs that are not in config list */ + /* 2. Remove STAs from runtime if not present in file */ list_for_each_entry(s, &ap->restrict_stalist, list) { bool found = false; int i = 0; - for (i = 0; i < num_sta; i++) { - if (!memcmp(stalist[i], x->macaddr, 6)) { + for (i = 0; i < num_fr; i++) { + if (!memcmp(fr[i].macaddr, s->macaddr, 6)) { found = true; break; } } if (!found) { + uint8_t sta_list[1][6]; + /* Remove STA from runtime list */ - ret |= assoc_ctrl_del_sta(a, ap, 1, &x->macaddr, false); + memcpy(sta_list[0], s->macaddr, 6); + ret |= assoc_ctrl_del_sta(a, ap, 1, sta_list, false); } } @@ -284,7 +617,6 @@ int assoc_ctrl_apply_restriction(struct agent *a, struct netif_ap *ap) uint8_t wifi_res_stas[ASSOC_CTRL_MAX_STA * 6] = {0}; int num_wifi_res_stas = ASSOC_CTRL_MAX_STA; struct restrict_sta_entry *s = NULL; - int i; int ret = 0; if (list_empty(&ap->restrict_stalist)) @@ -297,24 +629,44 @@ int assoc_ctrl_apply_restriction(struct agent *a, struct netif_ap *ap) return -1; } - /* Invoke block_sta for STAs that are in runtime list but not in blocked_stas */ + /* Invoke block_sta for STAs on runtime list not blocked in Wi-Fi */ list_for_each_entry(s, &ap->restrict_stalist, list) { + bool blocked = false; + int i; for (i = 0; i < num_wifi_res_stas; i++) { + if (!memcmp(&wifi_res_stas[i * 6], s->macaddr, 6)) { + /* STA blocked in WiFi */ + blocked = true; + break; + } + } - if (!memcmp(&wifi_res_stas[i * 6], s->macaddr, 6)) - /* STA already blocked in WiFi */ - continue; + if (blocked) { + /* STA already blocked in WiFi */ + dbg("%s: STA already blocked in WiFi\n", __func__); + continue; + } - assoc_ctrl_restrict_sta(a, 1, &s->macaddr, ap, s->mode); + if ((s->mode == ASSOC_CTRL_TIMED_BLOCK || s->mode == ASSOC_CTRL_BLOCK) + && !timer_pending(&s->restrict_timer)) { + /* Timer expired: do not block in WiFi */ + dbg("%s: Timer expired for " MACFMT " - won't block in WiFi\n", + __func__, MAC2STR(s->macaddr)); + continue; } + + dbg("%s: Block STA: " MACFMT " in %s\n", + __func__, MAC2STR(s->macaddr), ap->ifname); + assoc_ctrl_restrict_sta(a, 1, &s->macaddr, ap, s->mode); } - /* Theoretically, it could be blocked for other reasons, i.e. network admin-issued block - * manually or via webGUI. Uncomment this part if we want to unblock STAs anyway. + /* Theoretically, it could be blocked for other reasons, + * i.e. network admin-issued block, manually or via webGUI. + * Uncomment following code if we want to unblock STAs anyway. */ #if 0 - /* Invoke unblock_sta for STAs that are in blocked_stas but not in runtime list */ + /* Unblock STAs in Wi-FI if not found on runtime list */ for (i = 0; i < num_wifi_res_stas; i++) { bool found = false; @@ -398,7 +750,7 @@ int assoc_ctrl_process_request(void *agent, uint8_t *p, } switch (data->control) { - case ASSOC_CTRL_BLOCK: + case ASSOC_CTRL_BLOCK: /* Client Blocking */ /* Block - check for an Error Scenario: * Send an error TLV in case STA is already associated * with the BSSID for which the 'Block' mode is being set. @@ -425,8 +777,8 @@ int assoc_ctrl_process_request(void *agent, uint8_t *p, goto send_ack; } /* no break - checkpatch ignore */ - case ASSOC_CTRL_TIMED_BLOCK: - /* tmo needed for block and timed block modes */ + case ASSOC_CTRL_TIMED_BLOCK: /* Timed Block */ + /* Validity Period mandatory for Client Blocking and Timed Block */ validity_period = BUF_GET_BE16(data->validity_period); if (!validity_period) { warn("Validity period unset, while expected!\n"); @@ -434,12 +786,12 @@ int assoc_ctrl_process_request(void *agent, uint8_t *p, goto send_ack; } /* no break - checkpatch ignore */ - case ASSOC_CTRL_INDEF_BLOCK: + case ASSOC_CTRL_INDEF_BLOCK: /* Indefinite Block */ /* Add STA to blocking list for block/timed block/indef block */ WARN_ON(assoc_ctrl_block_sta(a, ap, validity_period, data->control, data->num_sta, sta_list)); break; - case ASSOC_CTRL_UNBLOCK: + case ASSOC_CTRL_UNBLOCK: /* Client Unblocking */ /* Rem STA from blocking list and stop the restrict timer */ WARN_ON(assoc_ctrl_unblock_sta(a, ap, data->num_sta, sta_list)); break; diff --git a/src/assoc_ctrl.h b/src/assoc_ctrl.h index b16e0e68c11562f93aadd8f7d59c73bba1bfc723..575e7ff66ba732f546ae5df2a540f15e253db31a 100644 --- a/src/assoc_ctrl.h +++ b/src/assoc_ctrl.h @@ -7,16 +7,21 @@ struct agent; struct netif_ap; +#if defined MAX_STA && MAX_STA > 0 && MAX_STA <= 32 +#define ASSOC_CTRL_MAX_STA MAX_STA +#else #define ASSOC_CTRL_MAX_STA 32 +#endif + +#define ASSOC_CTRL_FILE "/etc/multiap/assoc_ctrl.json" int assoc_ctrl_block_sta(struct agent *a, struct netif_ap *ap, uint16_t validity_period, uint8_t mode, uint32_t sta_count, uint8_t stalist[][6]); int assoc_ctrl_unblock_sta(struct agent *a, struct netif_ap *ap, uint32_t sta_count, uint8_t stalist[][6]); -int assoc_ctrl_sync_from_config(struct agent *a, struct netif_ap *ap); +int assoc_ctrl_sync_from_file(struct agent *a, struct netif_ap *ap); int assoc_ctrl_apply_restriction(struct agent *a, struct netif_ap *ap); int assoc_ctrl_process_request(void *agent, uint8_t *p, struct cmdu_buff *cmdu); int assoc_ctrl_reapply(struct netif_ap *ap); - #endif