policy: don't select better candidate with bad signal
[project/usteer.git] / policy.c
index 04a1b3c8ccd2443e01d535f80115e8add130b847..445abdefe8d9d57d3420bf01b387b557c67756b3 100644 (file)
--- a/policy.c
+++ b/policy.c
@@ -72,6 +72,18 @@ below_max_assoc(struct sta_info *si)
        return !node->max_assoc || node->n_assoc < node->max_assoc;
 }
 
+static bool
+over_min_signal(struct sta_info *si)
+{
+       if (config.min_snr && si->signal < usteer_snr_to_signal(si->node, config.min_snr))
+               return false;
+
+       if (config.roam_trigger_snr && si->signal < usteer_snr_to_signal(si->node, config.roam_trigger_snr))
+               return false;
+       
+       return true;
+}
+
 static uint32_t
 is_better_candidate(struct sta_info *si_cur, struct sta_info *si_new)
 {
@@ -80,6 +92,9 @@ is_better_candidate(struct sta_info *si_cur, struct sta_info *si_new)
        if (!below_max_assoc(si_new))
                return 0;
 
+       if (!over_min_signal(si_new))
+               return 0;
+
        if (below_assoc_threshold(si_cur, si_new) &&
            !below_assoc_threshold(si_new, si_cur))
                reasons |= (1 << UEV_SELECT_REASON_NUM_ASSOC);
@@ -115,9 +130,6 @@ find_better_candidate(struct sta_info *si_ref, struct uevent *ev, uint32_t requi
                if (!reasons)
                        continue;
 
-               if (is_better_candidate(si, si_ref))
-                       continue;
-
                if (!(reasons & required_criteria))
                        continue;
 
@@ -132,8 +144,8 @@ find_better_candidate(struct sta_info *si_ref, struct uevent *ev, uint32_t requi
        return NULL;
 }
 
-static int
-snr_to_signal(struct usteer_node *node, int snr)
+int
+usteer_snr_to_signal(struct usteer_node *node, int snr)
 {
        int noise = -95;
 
@@ -164,10 +176,10 @@ usteer_check_request(struct sta_info *si, enum usteer_event_type type)
                 *
                 * Otherwise, the client potentially ends up in a assoc - kick loop.
                 */
-               if (config.min_snr && si->signal < snr_to_signal(si->node, config.min_snr)) {
+               if (config.min_snr && si->signal < usteer_snr_to_signal(si->node, config.min_snr)) {
                        ev.reason = UEV_REASON_LOW_SIGNAL;
                        ev.threshold.cur = si->signal;
-                       ev.threshold.ref = snr_to_signal(si->node, config.min_snr);
+                       ev.threshold.ref = usteer_snr_to_signal(si->node, config.min_snr);
                        ret = false;
                        goto out;
                } else if (!config.assoc_steering) {
@@ -175,7 +187,7 @@ usteer_check_request(struct sta_info *si, enum usteer_event_type type)
                }
        }
 
-       min_signal = snr_to_signal(si->node, config.min_connect_snr);
+       min_signal = usteer_snr_to_signal(si->node, config.min_connect_snr);
        if (si->signal < min_signal) {
                ev.reason = UEV_REASON_LOW_SIGNAL;
                ev.threshold.cur = si->signal;
@@ -268,7 +280,7 @@ usteer_roam_trigger_sm(struct sta_info *si)
        };
        int min_signal;
 
-       min_signal = snr_to_signal(si->node, config.roam_trigger_snr);
+       min_signal = usteer_snr_to_signal(si->node, config.roam_trigger_snr);
 
        switch (si->roam_state) {
        case ROAM_TRIGGER_SCAN:
@@ -348,7 +360,7 @@ usteer_local_node_roam_check(struct usteer_local_node *ln, struct uevent *ev)
                return;
 
        usteer_update_time();
-       min_signal = snr_to_signal(&ln->node, min_signal);
+       min_signal = usteer_snr_to_signal(&ln->node, min_signal);
 
        list_for_each_entry(si, &ln->node.sta_info, node_list) {
                if (si->connected != STA_CONNECTED || si->signal >= min_signal ||
@@ -378,7 +390,7 @@ usteer_local_node_snr_kick(struct usteer_local_node *ln)
        if (!config.min_snr)
                return;
 
-       min_signal = snr_to_signal(&ln->node, config.min_snr);
+       min_signal = usteer_snr_to_signal(&ln->node, config.min_snr);
        ev.threshold.ref = min_signal;
 
        list_for_each_entry(si, &ln->node.sta_info, node_list) {
@@ -457,7 +469,7 @@ usteer_local_node_kick(struct usteer_local_node *ln)
                if (is_more_kickable(kick1, si))
                        kick1 = si;
 
-               tmp = find_better_candidate(si, NULL, 0);
+               tmp = find_better_candidate(si, NULL, (1 << UEV_SELECT_REASON_LOAD));
                if (!tmp)
                        continue;