aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/driver.h1
-rw-r--r--src/drivers/driver_nl80211.c54
-rw-r--r--wpa_supplicant/bgscan.c6
-rw-r--r--wpa_supplicant/bgscan.h8
-rw-r--r--wpa_supplicant/bgscan_learn.c5
-rw-r--r--wpa_supplicant/bgscan_simple.c5
-rw-r--r--wpa_supplicant/events.c3
7 files changed, 72 insertions, 10 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 85ca0a5..3c3bf9c 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2452,6 +2452,7 @@ union wpa_event_data {
*/
struct signal_change {
int above_threshold;
+ int current_signal;
} signal_change;
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3ad8812..0590fed 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -946,6 +946,53 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
}
+static int get_link_signal(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
+ static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
+ [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
+ };
+ int *sig = arg;
+
+ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+ if (!tb[NL80211_ATTR_STA_INFO] ||
+ nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
+ tb[NL80211_ATTR_STA_INFO], policy))
+ return NL_SKIP;
+ if (!sinfo[NL80211_STA_INFO_SIGNAL])
+ return NL_SKIP;
+
+ *sig = (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
+ return NL_SKIP;
+}
+
+
+static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
+ int *sig)
+{
+ struct nl_msg *msg;
+
+ *sig = -9999;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+ 0, NL80211_CMD_GET_STATION, 0);
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
+
+ return send_and_recv_msgs(drv, msg, get_link_signal, sig);
+ nla_put_failure:
+ return -ENOBUFS;
+}
+
+
static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
struct nlattr *tb[])
{
@@ -957,6 +1004,7 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
enum nl80211_cqm_rssi_threshold_event event;
union wpa_event_data ed;
+ int sig, res;
if (tb[NL80211_ATTR_CQM] == NULL ||
nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
@@ -982,6 +1030,12 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
} else
return;
+ res = nl80211_get_link_signal(drv, &sig);
+ if (res == 0) {
+ ed.signal_change.current_signal = sig;
+ wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm", sig);
+ }
+
wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
}
diff --git a/wpa_supplicant/bgscan.c b/wpa_supplicant/bgscan.c
index e5fdfc4..e76e954 100644
--- a/wpa_supplicant/bgscan.c
+++ b/wpa_supplicant/bgscan.c
@@ -111,8 +111,10 @@ void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
}
-void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above)
+void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
+ int current_signal)
{
if (wpa_s->bgscan && wpa_s->bgscan_priv)
- wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above);
+ wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above,
+ current_signal);
}
diff --git a/wpa_supplicant/bgscan.h b/wpa_supplicant/bgscan.h
index e0c9eb0..9f2ba2f 100644
--- a/wpa_supplicant/bgscan.h
+++ b/wpa_supplicant/bgscan.h
@@ -27,7 +27,8 @@ struct bgscan_ops {
int (*notify_scan)(void *priv, struct wpa_scan_results *scan_res);
void (*notify_beacon_loss)(void *priv);
- void (*notify_signal_change)(void *priv, int above);
+ void (*notify_signal_change)(void *priv, int above,
+ int current_signal);
};
#ifdef CONFIG_BGSCAN
@@ -37,7 +38,8 @@ void bgscan_deinit(struct wpa_supplicant *wpa_s);
int bgscan_notify_scan(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res);
void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s);
-void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above);
+void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
+ int current_signal);
#else /* CONFIG_BGSCAN */
@@ -62,7 +64,7 @@ static inline void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
}
static inline void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s,
- int above)
+ int above, int current_signal)
{
}
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
index 32305a4..865347b 100644
--- a/wpa_supplicant/bgscan_learn.c
+++ b/wpa_supplicant/bgscan_learn.c
@@ -546,7 +546,8 @@ static void bgscan_learn_notify_beacon_loss(void *priv)
}
-static void bgscan_learn_notify_signal_change(void *priv, int above)
+static void bgscan_learn_notify_signal_change(void *priv, int above,
+ int current_signal)
{
struct bgscan_learn_data *data = priv;
@@ -555,7 +556,7 @@ static void bgscan_learn_notify_signal_change(void *priv, int above)
return;
wpa_printf(MSG_DEBUG, "bgscan learn: signal level changed "
- "(above=%d)", above);
+ "(above=%d current_signal=%d)", above, current_signal);
if (data->scan_interval == data->long_interval && !above) {
wpa_printf(MSG_DEBUG, "bgscan learn: Trigger immediate scan "
"and start using short bgscan interval");
diff --git a/wpa_supplicant/bgscan_simple.c b/wpa_supplicant/bgscan_simple.c
index aeecc01..b58cb76 100644
--- a/wpa_supplicant/bgscan_simple.c
+++ b/wpa_supplicant/bgscan_simple.c
@@ -167,7 +167,8 @@ static void bgscan_simple_notify_beacon_loss(void *priv)
}
-static void bgscan_simple_notify_signal_change(void *priv, int above)
+static void bgscan_simple_notify_signal_change(void *priv, int above,
+ int current_signal)
{
struct bgscan_simple_data *data = priv;
@@ -176,7 +177,7 @@ static void bgscan_simple_notify_signal_change(void *priv, int above)
return;
wpa_printf(MSG_DEBUG, "bgscan simple: signal level changed "
- "(above=%d)", above);
+ "(above=%d current_signal=%d)", above, current_signal);
if (data->scan_interval == data->long_interval && !above) {
wpa_printf(MSG_DEBUG, "bgscan simple: Trigger immediate scan "
"and start using short bgscan interval");
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2ca55d8..80a9f85 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1752,7 +1752,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
case EVENT_SIGNAL_CHANGE:
bgscan_notify_signal_change(
- wpa_s, data->signal_change.above_threshold);
+ wpa_s, data->signal_change.above_threshold,
+ data->signal_change.current_signal);
break;
case EVENT_INTERFACE_ENABLED:
wpa_printf(MSG_DEBUG, "Interface was enabled");