void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int bssid_changed; int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); /* * For now, unconditionally terminate the previous authentication. In * theory, this should not be needed, but mac80211 gets quite confused * if the authentication is left pending.. Some roaming cases might * benefit from using the previous authentication, so this could be * optimized in the future. */ if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING) < 0) { wpa_msg(wpa_s, MSG_INFO, "Deauth request to the driver failed"); } wpa_s->sme.prev_bssid_set = 0; if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); /* * TODO: if more than one possible AP is available in scan results, * could try the other ones before requesting a new scan. */ ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Association rejected"); //wpa_supplicant_req_scan(wpa_s, timeout / 1000, // 1000 * (timeout % 1000)); }
void sme_event_disassoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received"); if (wpa_s->sme.prev_bssid_set) { /* * cfg80211/mac80211 can get into somewhat confused state if * the AP only disassociates us and leaves us in authenticated * state. For now, force the state to be cleared to avoid * confusing errors if we try to associate with the AP again. */ wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear " "driver state"); wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, WLAN_REASON_DEAUTH_LEAVING); } }
void sme_event_disassoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { wpa_printf(MSG_DEBUG, "SME: Disassociation event received"); if (!is_zero_ether_addr(wpa_s->bssid) && !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) { /* * cfg80211/mac80211 can get into somewhat confused state if * the AP only disassociates us and leaves us in authenticated * state. For now, force the state to be cleared to avoid * confusing errors if we try to associate with the AP again. */ wpa_printf(MSG_DEBUG, "SME: Deauthenticate to clear driver " "state"); wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, WLAN_REASON_DEAUTH_LEAVING); } }
static void sme_deauth(struct wpa_supplicant *wpa_s) { int bssid_changed; bssid_changed = !is_zero_ether_addr(wpa_s->bssid); if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING) < 0) { wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver " "failed"); } wpa_s->sme.prev_bssid_set = 0; wpas_connection_failed(wpa_s, wpa_s->pending_bssid); wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); }
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: " "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); #ifdef CONFIG_SAE if (wpa_s->sme.sae_pmksa_caching && wpa_s->current_ssid && wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) { wpa_dbg(wpa_s, MSG_DEBUG, "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication"); wpa_sm_aborted_cached(wpa_s->wpa); wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid); if (wpa_s->current_bss) { struct wpa_bss *bss = wpa_s->current_bss; struct wpa_ssid *ssid = wpa_s->current_ssid; wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING); wpas_connect_work_done(wpa_s); wpa_supplicant_mark_disassoc(wpa_s); wpa_supplicant_connect(wpa_s, bss, ssid); return; } } #endif /* CONFIG_SAE */ /* * For now, unconditionally terminate the previous authentication. In * theory, this should not be needed, but mac80211 gets quite confused * if the authentication is left pending.. Some roaming cases might * benefit from using the previous authentication, so this could be * optimized in the future. */ sme_deauth(wpa_s); }
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, size_t buf_len ) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct ifreq ifr; struct wpa_supplicant *wpa_s; struct hostapd_data *hapd; int handled = 0; int cmd_len = 0; union wpa_event_data event; static int user_force_band = 0; int ret = -1; if (drv == NULL) { wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__); return -1; } if (drv->ctx == NULL) { wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__); return -1; } if (os_strcmp(bss->ifname, "ap0") == 0) { hapd = (struct hostapd_data *)(drv->ctx); } else { wpa_s = (struct wpa_supplicant *)(drv->ctx); if (wpa_s->conf == NULL) { wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__); return -1; } } wpa_printf(MSG_DEBUG, "iface %s recv cmd %s", bss->ifname, cmd); handled = 1; if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) { int state; state = atoi(cmd + 10); wpa_printf(MSG_DEBUG, "POWERMODE=%d", state); } else if (os_strncmp(cmd, "MACADDR", os_strlen("MACADDR")) == 0) { u8 macaddr[ETH_ALEN] = {}; os_memcpy(&macaddr, wpa_s->own_addr, ETH_ALEN); ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr)); wpa_printf(MSG_DEBUG, "%s", buf); } else if(os_strncasecmp(cmd, "COUNTRY", os_strlen("COUNTRY"))==0) { if (os_strlen(cmd) != os_strlen("COUNTRY") + 3) { wpa_printf(MSG_DEBUG, "Ignore COUNTRY cmd %s", cmd); ret = 0; } else { wpa_printf(MSG_INFO, "set country: %s", cmd+8); // ret = wpa_drv_set_country(wpa_s, cmd+8); ret = wpa_driver_mediatek_set_country(priv, cmd+8); if (ret == 0) { wpa_printf(MSG_DEBUG, "Update channel list after country code changed"); wpa_driver_notify_country_change(wpa_s, cmd); } } } else if (os_strcasecmp(cmd, "start") == 0) { if (ret = linux_set_iface_flags(drv->global->ioctl_sock, drv->first_bss->ifname, 1)) { wpa_printf(MSG_INFO, "nl80211: Could not set interface UP, ret=%d \n", ret); } else { wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STARTED"); } } else if (os_strcasecmp(cmd, "stop") == 0) { if (drv->associated) { ret = wpa_drv_deauthenticate(wpa_s, drv->bssid, WLAN_REASON_DEAUTH_LEAVING); if (ret != 0) wpa_printf(MSG_DEBUG, "DRIVER-STOP error, ret=%d", ret); } else { wpa_printf(MSG_INFO, "nl80211: not associated, no need to deauthenticate \n"); } if (ret = linux_set_iface_flags(drv->global->ioctl_sock, drv->first_bss->ifname, 0)) { wpa_printf(MSG_INFO, "nl80211: Could not set interface Down, ret=%d \n", ret); } else { wpa_msg(drv->ctx, MSG_INFO, "CTRL-EVENT-DRIVER-STATE STOPPED"); } } else if (os_strncasecmp(cmd, "getpower", 8) == 0) { u32 mode; // ret = wpa_driver_wext_driver_get_power(drv, &mode); if (ret == 0) { ret = snprintf(buf, buf_len, "powermode = %u\n", mode); wpa_printf(MSG_DEBUG, "%s", buf); if (ret < (int)buf_len) return ret; } } else if (os_strncasecmp(cmd, "get-rts-threshold", 17) == 0) { u32 thd; // ret = wpa_driver_wext_driver_get_rts(drv, &thd); if (ret == 0) { ret = snprintf(buf, buf_len, "rts-threshold = %u\n", thd); wpa_printf(MSG_DEBUG, "%s", buf); if (ret < (int)buf_len) return ret; } } else if (os_strncasecmp(cmd, "set-rts-threshold", 17) == 0) { u32 thd = 0; char *cp = cmd + 17; char *endp; if (*cp != '\0') { thd = (u32)strtol(cp, &endp, 0); // if (endp != cp) // ret = wpa_driver_wext_driver_set_rts(drv, thd); } } else if (os_strcasecmp(cmd, "btcoexscan-start") == 0) { ret = 0; /* mt5921 linux driver not implement yet */ } else if (os_strcasecmp(cmd, "btcoexscan-stop") == 0) { ret = 0; /* mt5921 linux driver not implement yet */ } else if (os_strncasecmp(cmd, "btcoexmode", 10) == 0) { ret = 0; /* mt5921 linux driver not implement yet */ } else { handled = 0; wpa_printf(MSG_INFO, "Unsupported command"); } return ret; }