[PATCH] dbus_new: add property to track reason for a state change
mukesh agrawal
quiche
Mon Oct 24 15:54:59 PDT 2011
In the connection manager, it is sometimes useful to disambiguate the
reason for a connection failure. For example, if a connection attempt
fails due to WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT, it is more likely
that the connection manager has the wrong key than if the connection
attempt fails due to WLAN_REASON_DEAUTH_LEAVING.
This patch
- adds a new D-Bus property, "StateChangeReason"
- adds a reason_code argument to wpa_supplicant_set_state
- modifies wpa_supplicant_event_disassoc to pass the disconnect_reason
down to wpa_supplicant_set_state (via wpa_supplicant_mark_disassoc)
- modifies sme_event_assoc_reject to pass the status_code down to
wpa_supplicant_set_state (via sme_deauth)
- modifies wpa_supplicant_disassociate and wpa_supplicant_deauthenticate
to pass the reason_code down to wpa_supplicant_set_state
(via wpa_supplicant_clear_connection and wpa_supplicant_mark_disassoc)
- sets the state change reason to -1 in all other cases (where no reason
is readily available)
Change-Id: I91e17f02d79c841c0a81ea71a547857bad2a7a27
---
wpa_supplicant/ap.c | 2 +-
wpa_supplicant/dbus/dbus_new.c | 9 ++++++
wpa_supplicant/dbus/dbus_new.h | 1 +
wpa_supplicant/dbus/dbus_new_handlers.c | 17 ++++++++++++
wpa_supplicant/dbus/dbus_new_handlers.h | 3 ++
wpa_supplicant/events.c | 42 +++++++++++++++++++-----------
wpa_supplicant/notify.c | 2 +
wpa_supplicant/scan.c | 12 ++++++---
wpa_supplicant/sme.c | 20 ++++++++------
wpa_supplicant/wpa_supplicant.c | 34 +++++++++++++++++-------
wpa_supplicant/wpa_supplicant_i.h | 9 +++++-
wpa_supplicant/wpas_glue.c | 10 ++++---
12 files changed, 115 insertions(+), 46 deletions(-)
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 95279d3..494ea76 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -297,7 +297,7 @@ static void wpas_ap_configured_cb(void *ctx)
{
struct wpa_supplicant *wpa_s = ctx;
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED, LOCAL_REASON_UNKNOWN);
if (wpa_s->ap_configured_cb)
wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 49a0895..377e0da 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -700,6 +700,11 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
wpas_dbus_getter_current_auth_mode;
prop = "CurrentAuthMode";
break;
+ case WPAS_DBUS_PROP_STATE_CHANGE_REASON:
+ getter = (WPADBusPropertyAccessor)
+ wpas_dbus_getter_state_change_reason;
+ prop = "StateChangeReason";
+ break;
default:
wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
__func__, property);
@@ -1444,6 +1449,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
RW
},
#endif /* CONFIG_WPS */
+ { "StateChangeReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
+ (WPADBusPropertyAccessor) wpas_dbus_getter_state_change_reason,
+ NULL, R
+ },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 377e381..eab8406 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -32,6 +32,7 @@ enum wpas_dbus_prop {
WPAS_DBUS_PROP_CURRENT_NETWORK,
WPAS_DBUS_PROP_CURRENT_AUTH_MODE,
WPAS_DBUS_PROP_BSSS,
+ WPAS_DBUS_PROP_STATE_CHANGE_REASON,
};
enum wpas_dbus_bss_prop {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index e954020..26975b2 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -2459,6 +2459,23 @@ DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message,
/**
+ * wpas_dbus_getter_state_change_reason - Get reason code for last state change
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A message containing value of state_change_reason variable. Value
+ * is -1 if reason is unknown to wpa_supplicant.
+ *
+ * Getter for "StateChangeReason" property.
+ */
+DBusMessage * wpas_dbus_getter_state_change_reason(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT32,
+ &wpa_s->state_change_reason);
+}
+
+
+/**
* wpas_dbus_getter_bridge_ifname - Get interface name
* @message: Pointer to incoming dbus message
* @wpa_s: wpa_supplicant structure for a network interface
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 742d33c..97274e9 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -152,6 +152,9 @@ DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
DBusMessage * wpas_dbus_getter_current_auth_mode(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_getter_state_change_reason(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
struct wpa_supplicant *wpa_s);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 69d2191..3ee87d0 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -109,7 +109,8 @@ static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
}
-void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
+void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s,
+ int32_t reason_code)
{
int bssid_changed;
@@ -121,7 +122,7 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
return;
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED, reason_code);
bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
os_memset(wpa_s->bssid, 0, ETH_ALEN);
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
@@ -672,7 +673,8 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
* we don't wait timeout seconds before transitioning
* to INACTIVE state.
*/
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
+ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE,
+ LOCAL_REASON_UNKNOWN);
return;
}
wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
@@ -931,7 +933,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
}
if (wpa_s->disconnected) {
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED,
+ LOCAL_REASON_UNKNOWN);
wpa_scan_results_free(scan_res);
return 0;
}
@@ -960,7 +963,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
*/
wpa_printf(MSG_INFO, "Fast reconnect failed");
wpa_scan_results_free(scan_res);
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_mark_disassoc(wpa_s, LOCAL_REASON_UNKNOWN);
} else {
wpa_scan_results_free(scan_res);
wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
@@ -1218,7 +1221,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
return;
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
+ wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED, LOCAL_REASON_UNKNOWN);
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
@@ -1293,7 +1296,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
(wpa_s->current_ssid &&
wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
} else if (!ft_completed) {
/* Timeout for receiving the first EAPOL packet */
wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
@@ -1307,7 +1311,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
* handshake.
*/
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
@@ -1324,7 +1329,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
* up in authenticated.
*/
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
}
@@ -1500,7 +1506,7 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "Fast reconnect: Failed to trigger scan");
wpa_supplicant_req_scan(wpa_s, 0, 100000);
}
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_mark_disassoc(wpa_s, reason_code);
if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
@@ -1648,7 +1654,7 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
case EVENT_INTERFACE_REMOVED:
wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
wpa_s->interface_removed = 1;
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_mark_disassoc(wpa_s, LOCAL_REASON_UNKNOWN);
l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = NULL;
#ifdef CONFIG_IBSS_RSN
@@ -2206,21 +2212,25 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#ifdef CONFIG_AP
if (!wpa_s->ap_iface) {
wpa_supplicant_set_state(wpa_s,
- WPA_DISCONNECTED);
+ WPA_DISCONNECTED,
+ LOCAL_REASON_UNKNOWN);
wpa_supplicant_req_scan(wpa_s, 0, 0);
} else
wpa_supplicant_set_state(wpa_s,
- WPA_COMPLETED);
+ WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
#else /* CONFIG_AP */
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED,
+ LOCAL_REASON_UNKNOWN);
wpa_supplicant_req_scan(wpa_s, 0, 0);
#endif /* CONFIG_AP */
}
break;
case EVENT_INTERFACE_DISABLED:
wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
- wpa_supplicant_mark_disassoc(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
+ wpa_supplicant_mark_disassoc(wpa_s, LOCAL_REASON_UNKNOWN);
+ wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED,
+ LOCAL_REASON_UNKNOWN);
break;
case EVENT_CHANNEL_LIST_CHANGED:
if (wpa_s->drv_priv == NULL)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 2053c3d..d3bb6b0 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -83,6 +83,8 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
/* notify the new DBus API */
wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
+ wpas_dbus_signal_prop_changed(wpa_s,
+ WPAS_DBUS_PROP_STATE_CHANGE_REASON);
#ifdef CONFIG_P2P
if (new_state == WPA_COMPLETED)
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 4fb9bef..e9e2bc0 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -260,14 +260,16 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
}
if (wpa_s->disconnected && !wpa_s->scan_req) {
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED,
+ LOCAL_REASON_UNKNOWN);
return;
}
if (!wpa_supplicant_enabled_networks(wpa_s->conf) &&
!wpa_s->scan_req) {
wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
+ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE,
+ LOCAL_REASON_UNKNOWN);
return;
}
@@ -305,7 +307,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
prev_state = wpa_s->wpa_state;
if (wpa_s->wpa_state == WPA_DISCONNECTED ||
wpa_s->wpa_state == WPA_INACTIVE)
- wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
+ wpa_supplicant_set_state(wpa_s, WPA_SCANNING,
+ LOCAL_REASON_UNKNOWN);
/* Find the starting point from which to continue scanning */
ssid = wpa_s->conf->ssid;
@@ -472,7 +475,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
if (ret) {
wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
if (prev_state != wpa_s->wpa_state)
- wpa_supplicant_set_state(wpa_s, prev_state);
+ wpa_supplicant_set_state(wpa_s, prev_state,
+ LOCAL_REASON_UNKNOWN);
wpa_supplicant_req_scan(wpa_s, 1, 0);
}
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 325ffc5..4393b29 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -244,7 +244,8 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
wpa_clear_keys(wpa_s, bss->bssid);
- wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
+ wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING,
+ LOCAL_REASON_UNKNOWN);
old_ssid = wpa_s->current_ssid;
wpa_s->current_ssid = ssid;
wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
@@ -384,7 +385,7 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
params.freq);
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
+ wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING, LOCAL_REASON_UNKNOWN);
if (params.wpa_ie == NULL ||
ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
@@ -446,7 +447,7 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
}
-static void sme_deauth(struct wpa_supplicant *wpa_s)
+static void sme_deauth(struct wpa_supplicant *wpa_s, int32_t reason_code)
{
int bssid_changed;
@@ -460,7 +461,7 @@ static void sme_deauth(struct wpa_supplicant *wpa_s)
wpa_s->sme.prev_bssid_set = 0;
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED, reason_code);
os_memset(wpa_s->bssid, 0, ETH_ALEN);
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
if (bssid_changed)
@@ -484,7 +485,7 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
* benefit from using the previous authentication, so this could be
* optimized in the future.
*/
- sme_deauth(wpa_s);
+ sme_deauth(wpa_s, data->assoc_reject.status_code);
}
@@ -501,7 +502,7 @@ void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
{
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_mark_disassoc(wpa_s, LOCAL_REASON_UNKNOWN);
}
@@ -530,7 +531,7 @@ static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
struct wpa_supplicant *wpa_s = eloop_ctx;
if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
- sme_deauth(wpa_s);
+ sme_deauth(wpa_s, LOCAL_REASON_UNKNOWN);
}
}
@@ -540,7 +541,7 @@ static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
struct wpa_supplicant *wpa_s = eloop_ctx;
if (wpa_s->wpa_state == WPA_ASSOCIATING) {
wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
- sme_deauth(wpa_s);
+ sme_deauth(wpa_s, LOCAL_REASON_UNKNOWN);
}
}
@@ -565,7 +566,8 @@ void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
*/
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication "
"to proceed after disconnection event");
- wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
+ wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING,
+ LOCAL_REASON_UNKNOWN);
os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
/*
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d8c2a2c..fc647fe 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -562,18 +562,29 @@ static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
* wpa_supplicant_set_state - Set current connection state
* @wpa_s: Pointer to wpa_supplicant data
* @state: The new connection state
+ * @reason_code: IEEE 802.11 reason code, or LOCAL_REASON_UNKNOWN
*
* This function is called whenever the connection state changes, e.g.,
* association is completed for WPA/WPA2 4-Way Handshake is started.
*/
void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
- enum wpa_states state)
+ enum wpa_states state,
+ int32_t reason_code)
{
enum wpa_states old_state = wpa_s->wpa_state;
- wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
+ wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s (reason %d)",
wpa_supplicant_state_txt(wpa_s->wpa_state),
- wpa_supplicant_state_txt(state));
+ wpa_supplicant_state_txt(state),
+ reason_code);
+
+ /*
+ * NB: only update state_change_reason on true state change, to
+ * avoid clobbering state_change_reason when we deauthenticate
+ * following a disassociate event. see sme_event_disassoc.
+ */
+ if (state != wpa_s->wpa_state)
+ wpa_s->state_change_reason = reason_code;
if (state != WPA_SCANNING)
wpa_supplicant_notify_scanning(wpa_s, 0);
@@ -1294,7 +1305,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
}
- wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
+ wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING, LOCAL_REASON_UNKNOWN);
if (bss) {
params.bssid = bss->bssid;
params.ssid = bss->ssid;
@@ -1387,7 +1398,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
/* No need to timeout authentication since there is no key
* management. */
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
#ifdef CONFIG_IBSS_RSN
} else if (ssid->mode == WPAS_MODE_IBSS &&
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
@@ -1436,12 +1448,13 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
- const u8 *addr)
+ const u8 *addr,
+ int32_t reason_code)
{
struct wpa_ssid *old_ssid;
wpa_clear_keys(wpa_s, addr);
- wpa_supplicant_mark_disassoc(wpa_s);
+ wpa_supplicant_mark_disassoc(wpa_s, reason_code);
old_ssid = wpa_s->current_ssid;
wpa_s->current_ssid = NULL;
wpa_s->current_bss = NULL;
@@ -1474,7 +1487,7 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
addr = wpa_s->bssid;
}
- wpa_supplicant_clear_connection(wpa_s, addr);
+ wpa_supplicant_clear_connection(wpa_s, addr, reason_code);
}
@@ -1500,7 +1513,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
addr = wpa_s->bssid;
}
- wpa_supplicant_clear_connection(wpa_s, addr);
+ wpa_supplicant_clear_connection(wpa_s, addr, reason_code);
}
@@ -2047,7 +2060,8 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
interface_count++;
} else
- wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
+ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE,
+ LOCAL_REASON_UNKNOWN);
return 0;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index eaabe0f..71a7d0a 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -546,6 +546,7 @@ struct wpa_supplicant {
unsigned int wps_freq;
int wps_fragment_size;
int auto_reconnect_disabled;
+ int32_t state_change_reason;
/* Channel preferences for AP/P2P GO use */
int best_24_freq;
@@ -555,6 +556,8 @@ struct wpa_supplicant {
/* wpa_supplicant.c */
+#define LOCAL_REASON_UNKNOWN (-1)
+
int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
@@ -574,7 +577,8 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr);
void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
int sec, int usec);
void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
- enum wpa_states state);
+ enum wpa_states state,
+ int32_t reason_code);
struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s);
const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s);
void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s);
@@ -625,7 +629,8 @@ void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
/* events.c */
-void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
+void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s,
+ int32_t reason_code);
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
struct wpa_bss *selected,
struct wpa_ssid *ssid);
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 2662eec..6eb5db1 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -295,7 +295,7 @@ static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
wpa_supplicant_cancel_scan(wpa_s);
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED, LOCAL_REASON_UNKNOWN);
}
@@ -305,10 +305,12 @@ static void wpa_supplicant_notify_eapol_done(void *ctx)
struct wpa_supplicant *wpa_s = ctx;
wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
- wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
+ wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE,
+ LOCAL_REASON_UNKNOWN);
} else {
wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED,
+ LOCAL_REASON_UNKNOWN);
}
}
@@ -391,7 +393,7 @@ static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state)
{
- wpa_supplicant_set_state(wpa_s, state);
+ wpa_supplicant_set_state(wpa_s, state, LOCAL_REASON_UNKNOWN);
}
--
1.7.3.1
More information about the Hostap
mailing list