Browse Source

Add current signal strength into signal quality change events

Jouni Malinen 14 years ago
parent
commit
60a972a68d

+ 1 - 0
src/drivers/driver.h

@@ -2452,6 +2452,7 @@ union wpa_event_data {
 	 */
 	struct signal_change {
 		int above_threshold;
+		int current_signal;
 	} signal_change;
 };
 

+ 54 - 0
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);
 }
 

+ 4 - 2
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);
 }

+ 5 - 3
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)
 {
 }
 

+ 3 - 2
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");

+ 3 - 2
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");

+ 2 - 1
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");