/* Proceed only if DFS is not offloaded to the driver */
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
return 0;
+--- a/src/ap/airtime_policy.c
++++ b/src/ap/airtime_policy.c
+@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta
+ {
+ struct sta_info *sta;
+
+- for (sta = hapd->sta_list; sta; sta = sta->next)
+- sta_set_airtime_weight(hapd, sta, weight);
++ for (sta = hapd->sta_list; sta; sta = sta->next) {
++ unsigned int sta_weight = weight;
++
++ if (sta->dyn_airtime_weight)
++ sta_weight = (weight * sta->dyn_airtime_weight) / 256;
++
++ sta_set_airtime_weight(hapd, sta, sta_weight);
++ }
+ }
+
+
+@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap
+ unsigned int weight;
+
+ if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) {
+- weight = get_weight_for_sta(hapd, sta->addr);
++ if (sta->dyn_airtime_weight)
++ weight = sta->dyn_airtime_weight;
++ else
++ weight = get_weight_for_sta(hapd, sta->addr);
+ if (weight)
+ return sta_set_airtime_weight(hapd, sta, weight);
+ }
+--- a/src/ap/sta_info.h
++++ b/src/ap/sta_info.h
+@@ -324,6 +324,7 @@ struct sta_info {
+ #endif /* CONFIG_TESTING_OPTIONS */
+ #ifdef CONFIG_AIRTIME_POLICY
+ unsigned int airtime_weight;
++ unsigned int dyn_airtime_weight;
+ struct os_reltime backlogged_until;
+ #endif /* CONFIG_AIRTIME_POLICY */
+
#include "rrm.h"
#include "wnm_ap.h"
#include "taxonomy.h"
+#include "airtime_policy.h"
static struct ubus_context *ctx;
static struct blob_buf b;
}
#endif
+#ifdef CONFIG_AIRTIME_POLICY
+enum {
+ UPDATE_AIRTIME_STA,
+ UPDATE_AIRTIME_WEIGHT,
+ __UPDATE_AIRTIME_MAX,
+};
+
+
+static const struct blobmsg_policy airtime_policy[__UPDATE_AIRTIME_MAX] = {
+ [UPDATE_AIRTIME_STA] = { "sta", BLOBMSG_TYPE_STRING },
+ [UPDATE_AIRTIME_WEIGHT] = { "weight", BLOBMSG_TYPE_INT32 },
+};
+
+static int
+hostapd_bss_update_airtime(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *ureq, const char *method,
+ struct blob_attr *msg)
+{
+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj);
+ struct blob_attr *tb[__UPDATE_AIRTIME_MAX];
+ struct sta_info *sta = NULL;
+ u8 addr[ETH_ALEN];
+ int weight;
+
+ blobmsg_parse(airtime_policy, __UPDATE_AIRTIME_MAX, tb, blob_data(msg), blob_len(msg));
+
+ if (!tb[UPDATE_AIRTIME_WEIGHT])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ weight = blobmsg_get_u32(tb[UPDATE_AIRTIME_WEIGHT]);
+
+ if (!tb[UPDATE_AIRTIME_STA]) {
+ if (!weight)
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ hapd->conf->airtime_weight = weight;
+ return 0;
+ }
+
+ if (hwaddr_aton(blobmsg_data(tb[UPDATE_AIRTIME_STA]), addr))
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ sta = ap_get_sta(hapd, addr);
+ if (!sta)
+ return UBUS_STATUS_NOT_FOUND;
+
+ sta->dyn_airtime_weight = weight;
+ airtime_policy_new_sta(hapd, sta);
+
+ return 0;
+}
+#endif
+
+
static const struct ubus_method bss_methods[] = {
UBUS_METHOD_NOARG("reload", hostapd_bss_reload),
UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients),
UBUS_METHOD_NOARG("get_status", hostapd_bss_get_status),
UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy),
+#ifdef CONFIG_AIRTIME_POLICY
+ UBUS_METHOD("update_airtime", hostapd_bss_update_airtime, airtime_policy),
+#endif
UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans),
#ifdef CONFIG_WPS
UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start),