hostapd: add "force" parameter for channel switch
authorFelix Fietkau <nbd@nbd.name>
Thu, 15 Jul 2021 08:45:26 +0000 (10:45 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 15 Jul 2021 08:46:10 +0000 (10:46 +0200)
This will restart the interface in case the CSA fails and can be used to
force the device on a DFS channel (including full CAC)

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/services/hostapd/src/src/ap/ubus.c

index 9918f17d6709c794d7a96d0c77d412661c39865b..07c366508c4e323964a769309d588a6641f4b35d 100644 (file)
@@ -744,6 +744,7 @@ enum {
        CSA_VHT,
        CSA_HE,
        CSA_BLOCK_TX,
+       CSA_FORCE,
        __CSA_MAX
 };
 
@@ -758,8 +759,18 @@ static const struct blobmsg_policy csa_policy[__CSA_MAX] = {
        [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL },
        [CSA_HE] = { "he", BLOBMSG_TYPE_BOOL },
        [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL },
+       [CSA_FORCE] = { "force", BLOBMSG_TYPE_BOOL },
 };
 
+
+static void switch_chan_fallback_cb(void *eloop_data, void *user_ctx)
+{
+       struct hostapd_iface *iface = eloop_data;
+       struct hostapd_freq_params *freq_params = user_ctx;
+
+       hostapd_switch_channel_fallback(iface, freq_params);
+}
+
 #ifdef NEED_AP_MLME
 static int
 hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
@@ -769,6 +780,7 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
        struct blob_attr *tb[__CSA_MAX];
        struct hostapd_data *hapd = get_hapd_from_object(obj);
        struct hostapd_config *iconf = hapd->iface->conf;
+       struct hostapd_freq_params *freq_params;
        struct csa_settings css = {
                .freq_params = {
                        .ht_enabled = iconf->ieee80211n,
@@ -825,7 +837,15 @@ hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj,
                        ret = UBUS_STATUS_NOT_SUPPORTED;
        }
 
-       return ret;
+       if (!ret || !tb[CSA_FORCE] || !blobmsg_get_bool(tb[CSA_FORCE]))
+               return ret;
+
+       freq_params = malloc(sizeof(*freq_params));
+       memcpy(freq_params, &css.freq_params, sizeof(*freq_params));
+       eloop_register_timeout(0, 1, switch_chan_fallback_cb,
+                              hapd->iface, freq_params);
+
+       return 0;
 #undef SET_CSA_SETTING
 }
 #endif