@@ -212,6 +212,8 @@ static bool mac_per_ssid;
/* Threshold RSSI for roaming to trigger, configurable in main.conf */
static int LOW_SIGNAL_THRESHOLD;
static int LOW_SIGNAL_THRESHOLD_5GHZ;
+static int CRITICAL_SIGNAL_THRESHOLD;
+static int CRITICAL_SIGNAL_THRESHOLD_5GHZ;
static unsigned int iov_ie_append(struct iovec *iov,
unsigned int n_iov, unsigned int c,
@@ -841,6 +843,10 @@ static void netdev_connect_free(struct netdev *netdev)
l_genl_family_cancel(nl80211, netdev->get_oci_cmd_id);
netdev->get_oci_cmd_id = 0;
}
+
+ /* Reset thresholds back to default */
+ netdev->low_signal_threshold = LOW_SIGNAL_THRESHOLD;
+ netdev->low_signal_threshold_5ghz = LOW_SIGNAL_THRESHOLD_5GHZ;
}
static void netdev_connect_failed(struct netdev *netdev,
@@ -3674,6 +3680,39 @@ static int netdev_cqm_rssi_update(struct netdev *netdev)
return 0;
}
+static int netdev_set_signal_thresholds(struct netdev *netdev, int threshold,
+ int threshold_5ghz)
+{
+ int current = netdev->frequency > 4000 ?
+ netdev->low_signal_threshold_5ghz :
+ netdev->low_signal_threshold;
+ int new = netdev->frequency > 4000 ? threshold_5ghz : threshold;
+
+ if (current == new)
+ return -EALREADY;
+
+ l_debug("changing low signal threshold to %d", new);
+
+ netdev->low_signal_threshold = threshold;
+ netdev->low_signal_threshold_5ghz = threshold_5ghz;
+
+ netdev_cqm_rssi_update(netdev);
+
+ return 0;
+}
+
+int netdev_lower_signal_threshold(struct netdev *netdev)
+{
+ return netdev_set_signal_thresholds(netdev, CRITICAL_SIGNAL_THRESHOLD,
+ CRITICAL_SIGNAL_THRESHOLD_5GHZ);
+}
+
+int netdev_raise_signal_threshold(struct netdev *netdev)
+{
+ return netdev_set_signal_thresholds(netdev, LOW_SIGNAL_THRESHOLD,
+ LOW_SIGNAL_THRESHOLD_5GHZ);
+}
+
static bool netdev_connection_work_ready(struct wiphy_radio_work_item *item)
{
struct netdev *netdev = l_container_of(item, struct netdev, work);
@@ -3887,6 +3926,8 @@ done:
netdev->handshake = hs;
netdev->sm = sm;
netdev->cur_rssi = bss->signal_strength / 100;
+ netdev->low_signal_threshold = LOW_SIGNAL_THRESHOLD;
+ netdev->low_signal_threshold_5ghz = LOW_SIGNAL_THRESHOLD_5GHZ;
if (netdev->rssi_levels_num)
netdev_set_rssi_level_idx(netdev);
@@ -4260,6 +4301,8 @@ int netdev_ft_reassociate(struct netdev *netdev,
netdev->event_filter = event_filter;
netdev->connect_cb = cb;
netdev->user_data = user_data;
+ netdev->low_signal_threshold = LOW_SIGNAL_THRESHOLD;
+ netdev->low_signal_threshold_5ghz = LOW_SIGNAL_THRESHOLD_5GHZ;
/*
* Cancel commands that could be running because of EAPoL activity
@@ -6278,6 +6321,14 @@ static int netdev_init(void)
&LOW_SIGNAL_THRESHOLD_5GHZ))
LOW_SIGNAL_THRESHOLD_5GHZ = -76;
+ if (!l_settings_get_int(settings, NETDEV_CRITICAL_ROAM_THRESHOLD,
+ &CRITICAL_SIGNAL_THRESHOLD))
+ CRITICAL_SIGNAL_THRESHOLD = -80;
+
+ if (!l_settings_get_int(settings, NETDEV_CRITICAL_ROAM_THRESHOLD_5G,
+ &CRITICAL_SIGNAL_THRESHOLD_5GHZ))
+ CRITICAL_SIGNAL_THRESHOLD_5GHZ = -82;
+
rand_addr_str = l_settings_get_value(settings,
NETDEV_ADDRESS_RANDOMIZATION);
if (rand_addr_str && !strcmp(rand_addr_str, "network"))
@@ -33,6 +33,9 @@ struct diagnostic_station_info;
#define NETDEV_ADDRESS_RANDOMIZATION GENERAL, "AddressRandomization"
#define NETDEV_ROAM_THRESHOLD GENERAL, "RoamTreshold"
#define NETDEV_ROAM_TRHESHOLD_5G GENERAL, "RoamThreshold5G"
+#define NETDEV_CRITICAL_ROAM_THRESHOLD GENERAL, "CriticalRoamThreshold"
+#define NETDEV_CRITICAL_ROAM_THRESHOLD_5G GENERAL, "CriticalRoamThreshold5G"
+
enum netdev_result {
NETDEV_RESULT_OK,
@@ -202,6 +205,8 @@ int netdev_neighbor_report_req(struct netdev *netdev,
int netdev_set_rssi_report_levels(struct netdev *netdev, const int8_t *levels,
size_t levels_num);
+int netdev_lower_signal_threshold(struct netdev *netdev);
+int netdev_raise_signal_threshold(struct netdev *netdev);
int netdev_get_station(struct netdev *netdev, const uint8_t *mac,
netdev_get_station_cb_t cb, void *user_data,