Browse Source

nl80211: Notify reason for connection timeout failure

This adds reason for timeout in event CTRL-EVENT-ASSOC-REJECT whenever
connection failure happens because of timeout. This extends the
"timeout" parameter in the event to include the reason, if available:
timeout=scan, timeout=auth, timeout=assoc.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Purushottam Kushwaha 8 years ago
parent
commit
3f23260da8
3 changed files with 38 additions and 5 deletions
  1. 5 0
      src/drivers/driver.h
  2. 21 1
      src/drivers/driver_nl80211_event.c
  3. 12 4
      wpa_supplicant/events.c

+ 5 - 0
src/drivers/driver.h

@@ -4707,6 +4707,11 @@ union wpa_event_data {
 		 * than explicit rejection response from the AP.
 		 */
 		int timed_out;
+
+		/**
+		 * timeout_reason - Reason for the timeout
+		 */
+		const char *timeout_reason;
 	} assoc_reject;
 
 	struct timeout_event {

+ 21 - 1
src/drivers/driver_nl80211_event.c

@@ -279,6 +279,7 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
 			       struct nlattr *addr, struct nlattr *req_ie,
 			       struct nlattr *resp_ie,
 			       struct nlattr *timed_out,
+			       struct nlattr *timeout_reason,
 			       struct nlattr *authorized,
 			       struct nlattr *key_replay_ctr,
 			       struct nlattr *ptk_kck,
@@ -338,6 +339,24 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
 		}
 		event.assoc_reject.status_code = status_code;
 		event.assoc_reject.timed_out = timed_out != NULL;
+		if (timed_out && timeout_reason) {
+			enum nl80211_timeout_reason reason;
+
+			reason = nla_get_u32(timeout_reason);
+			switch (reason) {
+			case NL80211_TIMEOUT_SCAN:
+				event.assoc_reject.timeout_reason = "scan";
+				break;
+			case NL80211_TIMEOUT_AUTH:
+				event.assoc_reject.timeout_reason = "auth";
+				break;
+			case NL80211_TIMEOUT_ASSOC:
+				event.assoc_reject.timeout_reason = "assoc";
+				break;
+			default:
+				break;
+			}
+		}
 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
 		return;
 	}
@@ -1726,7 +1745,7 @@ static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
-			   NULL,
+			   NULL, NULL,
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
@@ -2246,6 +2265,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
 				   tb[NL80211_ATTR_REQ_IE],
 				   tb[NL80211_ATTR_RESP_IE],
 				   tb[NL80211_ATTR_TIMED_OUT],
+				   tb[NL80211_ATTR_TIMEOUT_REASON],
 				   NULL, NULL, NULL, NULL, NULL);
 		break;
 	case NL80211_CMD_CH_SWITCH_NOTIFY:

+ 12 - 4
wpa_supplicant/events.c

@@ -3618,6 +3618,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 			  union wpa_event_data *data)
 {
 	struct wpa_supplicant *wpa_s = ctx;
+	char buf[100];
 	int resched;
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
@@ -3786,17 +3787,24 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 		break;
 #endif /* CONFIG_IBSS_RSN */
 	case EVENT_ASSOC_REJECT:
+		if (data->assoc_reject.timeout_reason)
+			os_snprintf(buf, sizeof(buf), "=%s",
+				    data->assoc_reject.timeout_reason);
+		else
+			buf[0] = '\0';
 		if (data->assoc_reject.bssid)
 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-				"bssid=" MACSTR	" status_code=%u%s",
+				"bssid=" MACSTR	" status_code=%u%s%s",
 				MAC2STR(data->assoc_reject.bssid),
 				data->assoc_reject.status_code,
-				data->assoc_reject.timed_out ? " timeout" : "");
+				data->assoc_reject.timed_out ? " timeout" : "",
+				buf);
 		else
 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-				"status_code=%u%s",
+				"status_code=%u%s%s",
 				data->assoc_reject.status_code,
-				data->assoc_reject.timed_out ? " timeout" : "");
+				data->assoc_reject.timed_out ? " timeout" : "",
+				buf);
 		wpa_s->assoc_status_code = data->assoc_reject.status_code;
 		wpas_notify_assoc_status_code(wpa_s);
 		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)