From aa532510a7b8c4da2d7d6e2c11dda5db840894e4 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Mon, 24 Sep 2012 10:35:31 -0700 Subject: [PATCH] wpa_supplicant: P2P-related fixes - Remove unused function warning in WPS-NFC case - P2P: Fix p2p_ctrl_invite_persistent to parse peer parameter - hostapd: Fix CONFIG_INTERWORKING=y build without CONFIG_HS20=y - hostapd: Fix WDS VLAN bridge handling - hostapd: Send EAPOL frames from the VO queue if WMM is active - P2P: Remove channel 14 from supported P2P channels - hostapd: Clear WLAN_STA_ASSOC_REQ_OK if sending the assoc response failed - hostapd: Add check for the wds sta flag before creating 4addr VLANs - nl80211: Use the monitor interface if socket tx status is not supported - wpa_supplicant: Set state to DISCONNECTED on AP creation errors - P2P: Fix p2p_group_idle in no-group-interface P2P client case - P2P: Fix PSK configuration for GO network - Print control interface commands in easier format - Add debug print for no enabled networks case - P2P: Add more debug prints for GO start routines - P2P: Fix pending sta scan processing for concurrent operation cases BUG: 6940646 Change-Id: I1b1c54a08c61ec4af2bfd2274afc93501004eea2 Signed-off-by: Dmitry Shmidt --- src/ap/gas_serv.c | 16 ++++++++++++++++ src/ap/ieee802_11.c | 28 ++++++++++++++++------------ src/drivers/driver_nl80211.c | 26 ++++++++++++++------------ wpa_supplicant/ctrl_iface.c | 20 ++++++++++---------- wpa_supplicant/events.c | 8 +++++++- wpa_supplicant/p2p_supplicant.c | 40 +++++++++++++++++++++++++++++++--------- wpa_supplicant/scan.c | 12 +++++++++++- wpa_supplicant/wpa_supplicant.c | 5 ++++- wpa_supplicant/wps_supplicant.c | 2 ++ 9 files changed, 111 insertions(+), 46 deletions(-) diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index 53e6cbb..851c183 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -128,6 +128,7 @@ static void gas_serv_free_dialogs(struct hostapd_data *hapd, } +#ifdef CONFIG_HS20 static void anqp_add_hs_capab_list(struct hostapd_data *hapd, struct wpabuf *buf) { @@ -151,6 +152,7 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd, wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS); gas_anqp_set_element_len(buf, len); } +#endif /* CONFIG_HS20 */ static void anqp_add_capab_list(struct hostapd_data *hapd, @@ -174,7 +176,9 @@ static void anqp_add_capab_list(struct hostapd_data *hapd, wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK); if (hapd->conf->domain_name) wpabuf_put_le16(buf, ANQP_DOMAIN_NAME); +#ifdef CONFIG_HS20 anqp_add_hs_capab_list(hapd, buf); +#endif /* CONFIG_HS20 */ gas_anqp_set_element_len(buf, len); } @@ -429,6 +433,8 @@ static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf) } +#ifdef CONFIG_HS20 + static void anqp_add_operator_friendly_name(struct hostapd_data *hapd, struct wpabuf *buf) { @@ -499,6 +505,8 @@ static void anqp_add_operating_class(struct hostapd_data *hapd, } } +#endif /* CONFIG_HS20 */ + static struct wpabuf * gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, @@ -531,6 +539,7 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, if (request & ANQP_REQ_DOMAIN_NAME) anqp_add_domain_name(hapd, buf); +#ifdef CONFIG_HS20 if (request & ANQP_REQ_HS_CAPABILITY_LIST) anqp_add_hs_capab_list(hapd, buf); if (request & ANQP_REQ_OPERATOR_FRIENDLY_NAME) @@ -541,6 +550,7 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, anqp_add_connection_capability(hapd, buf); if (request & ANQP_REQ_OPERATING_CLASS) anqp_add_operating_class(hapd, buf); +#endif /* CONFIG_HS20 */ return buf; } @@ -649,6 +659,8 @@ static void rx_anqp_query_list(struct hostapd_data *hapd, } +#ifdef CONFIG_HS20 + static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype, struct anqp_query_info *qi) { @@ -755,6 +767,8 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd, } } +#endif /* CONFIG_HS20 */ + static void gas_serv_req_local_processing(struct hostapd_data *hapd, const u8 *sa, u8 dialog_token, @@ -899,9 +913,11 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, case ANQP_QUERY_LIST: rx_anqp_query_list(hapd, pos, pos + elen, &qi); break; +#ifdef CONFIG_HS20 case ANQP_VENDOR_SPECIFIC: rx_anqp_vendor_specific(hapd, pos, pos + elen, &qi); break; +#endif /* CONFIG_HS20 */ default: wpa_printf(MSG_DEBUG, "ANQP: Unsupported Query " "Request element %u", info_id); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 211ee1b..ce20e5f 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1506,13 +1506,6 @@ static void handle_assoc_cb(struct hostapd_data *hapd, int new_assoc = 1; struct ieee80211_ht_capabilities ht_cap; - if (!ok) { - hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_DEBUG, - "did not acknowledge association response"); - return; - } - if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) : sizeof(mgmt->u.assoc_resp))) { printf("handle_assoc_cb(reassoc=%d) - too short payload " @@ -1520,11 +1513,6 @@ static void handle_assoc_cb(struct hostapd_data *hapd, return; } - if (reassoc) - status = le_to_host16(mgmt->u.reassoc_resp.status_code); - else - status = le_to_host16(mgmt->u.assoc_resp.status_code); - sta = ap_get_sta(hapd, mgmt->da); if (!sta) { printf("handle_assoc_cb: STA " MACSTR " not found\n", @@ -1532,6 +1520,19 @@ static void handle_assoc_cb(struct hostapd_data *hapd, return; } + if (!ok) { + hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_DEBUG, + "did not acknowledge association response"); + sta->flags &= ~WLAN_STA_ASSOC_REQ_OK; + return; + } + + if (reassoc) + status = le_to_host16(mgmt->u.reassoc_resp.status_code); + else + status = le_to_host16(mgmt->u.assoc_resp.status_code); + if (status != WLAN_STATUS_SUCCESS) goto fail; @@ -1830,6 +1831,9 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, sta = ap_get_sta(hapd, src); if (sta && (sta->flags & WLAN_STA_ASSOC)) { + if (!hapd->conf->wds_sta) + return; + if (wds && !(sta->flags & WLAN_STA_WDS)) { wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for " "STA " MACSTR " (aid %u)", diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index a9e6139..4574938 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2678,10 +2678,10 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv) } #else /* - * If poll command is supported mac80211 is new enough to - * have everything we need to not need monitor interfaces. + * If poll command and tx status are supported, mac80211 is new enough + * to have everything we need to not need monitor interfaces. */ - drv->use_monitor = !info.poll_command_supported; + drv->use_monitor = !info.poll_command_supported || !info.data_tx_status; #endif if (drv->device_ap_sme && drv->use_monitor) { @@ -6423,8 +6423,8 @@ static int wpa_driver_nl80211_hapd_send_eapol( pos = (u8 *) (hdr + 1); if (qos) { - /* add an empty QoS header if needed */ - pos[0] = 0; + /* Set highest priority in QoS header */ + pos[0] = 7; pos[1] = 0; pos += 2; } @@ -7729,6 +7729,10 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val, } return i802_set_sta_vlan(priv, addr, name, 0); } else { + if (bridge_ifname) + linux_br_del_if(drv->global->ioctl_sock, bridge_ifname, + name); + i802_set_sta_vlan(priv, addr, bss->ifname, 0); return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN, name); @@ -8096,7 +8100,12 @@ static int wpa_driver_nl80211_if_remove(void *priv, if (ifindex <= 0) return -1; + nl80211_remove_iface(drv, ifindex); + #ifdef HOSTAPD + if (type != WPA_IF_AP_BSS) + return 0; + if (bss->added_if_into_bridge) { if (linux_br_del_if(drv->global->ioctl_sock, bss->brname, bss->ifname) < 0) @@ -8110,13 +8119,6 @@ static int wpa_driver_nl80211_if_remove(void *priv, "bridge %s: %s", bss->brname, strerror(errno)); } -#endif /* HOSTAPD */ - - nl80211_remove_iface(drv, ifindex); - -#ifdef HOSTAPD - if (type != WPA_IF_AP_BSS) - return 0; if (bss != &drv->first_bss) { struct i802_bss *tbss; diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 0d8821b..bcf27be 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -3547,11 +3547,18 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) char *pos; int id; struct wpa_ssid *ssid; - u8 peer[ETH_ALEN]; + u8 *_peer = NULL, peer[ETH_ALEN]; int freq = 0; int ht40; id = atoi(cmd); + pos = os_strstr(cmd, " peer="); + if (pos) { + pos += 6; + if (hwaddr_aton(pos, peer)) + return -1; + _peer = peer; + } ssid = wpa_config_get_network(wpa_s->conf, id); if (ssid == NULL || ssid->disabled != 2) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d " @@ -3568,17 +3575,9 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) return -1; } - pos = os_strstr(cmd, " peer="); - if (pos) { - pos += 6; - if (hwaddr_aton(pos, peer)) - return -1; - } - ht40 = os_strstr(cmd, " ht40") != NULL; - return wpas_p2p_invite(wpa_s, pos ? peer : NULL, ssid, NULL, freq, - ht40); + return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40); } @@ -4402,6 +4401,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, level = MSG_EXCESSIVE; wpa_hexdump_ascii(level, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); + wpa_dbg(wpa_s, level, "Control interface command '%s'", buf); } reply = os_malloc(reply_size); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fdcbcc2..6e9d7ba 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -854,7 +854,12 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, * we don't wait timeout seconds before transitioning * to INACTIVE state. */ + wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request " + "since there are no enabled networks"); wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); +#ifdef CONFIG_P2P + wpa_s->sta_scan_pending = 0; +#endif /* CONFIG_P2P */ return; } wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec); @@ -1059,7 +1064,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, #ifdef CONFIG_P2P if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled && - wpa_s->global->p2p != NULL && !wpa_s->sta_scan_pending) { + wpa_s->global->p2p != NULL && !wpa_s->sta_scan_pending && + !wpa_s->scan_res_handler) { wpa_s->global->p2p_cb_on_scan_complete = 0; if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) { wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation " diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 903c94f..cf8f935 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -267,13 +267,12 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, if (ssid == NULL) { /* * The current SSID was not known, but there may still be a - * pending P2P group interface waiting for provisioning. + * pending P2P group interface waiting for provisioning or a + * P2P group that is trying to reconnect. */ ssid = wpa_s->conf->ssid; while (ssid) { - if (ssid->p2p_group && - (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION || - (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) + if (ssid->p2p_group) break; ssid = ssid->next; } @@ -873,12 +872,18 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, { struct wpa_ssid *ssid; - if (wpas_copy_go_neg_results(wpa_s, params) < 0) + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO"); + if (wpas_copy_go_neg_results(wpa_s, params) < 0) { + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation " + "results"); return; + } ssid = wpa_config_add_network(wpa_s->conf); - if (ssid == NULL) + if (ssid == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO"); return; + } wpa_s->show_group_started = 0; @@ -900,6 +905,13 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, ssid->proto = WPA_PROTO_RSN; ssid->pairwise_cipher = WPA_CIPHER_CCMP; ssid->passphrase = os_strdup(params->passphrase); + if (ssid->passphrase == NULL) { + wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to copy passphrase for " + "GO"); + wpa_config_remove_network(wpa_s->conf, ssid->id); + return; + } + wpa_config_update_psk(ssid); ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity; wpa_s->ap_configured_cb = p2p_go_configured; @@ -908,6 +920,8 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, wpa_s->connect_without_scan = ssid; wpa_s->reassociate = 1; wpa_s->disconnected = 0; + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to " + "start GO)"); wpa_supplicant_req_scan(wpa_s, 0, 0); } @@ -2517,7 +2531,6 @@ struct p2p_oper_class_map { static struct p2p_oper_class_map op_class[] = { { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 }, - { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20 }, #if 0 /* Do not enable HT40 on 2 GHz for now */ { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS }, { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS }, @@ -3820,18 +3833,27 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, { struct wpa_supplicant *group_wpa_s; - if (!wpas_p2p_create_iface(wpa_s)) + if (!wpas_p2p_create_iface(wpa_s)) { + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group " + "operations"); return wpa_s; + } if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO : - WPA_IF_P2P_CLIENT) < 0) + WPA_IF_P2P_CLIENT) < 0) { + wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to add group interface"); return NULL; + } group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go); if (group_wpa_s == NULL) { + wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to initialize group " + "interface"); wpas_p2p_remove_pending_group_interface(wpa_s); return NULL; } + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s", + group_wpa_s->ifname); return group_wpa_s; } diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index bf55f5e..0f6433b 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -83,15 +83,21 @@ static int wpas_wps_in_use(struct wpa_supplicant *wpa_s, int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s) { struct wpa_ssid *ssid = wpa_s->conf->ssid; - int count = 0; + int count = 0, disabled = 0; while (ssid) { if (!wpas_network_disabled(wpa_s, ssid)) count++; + else + disabled++; ssid = ssid->next; } if (wpa_s->conf->cred && wpa_s->conf->interworking && wpa_s->conf->auto_interworking) count++; + if (count == 0 && disabled > 0) { + wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled " + "networks)", disabled); + } return count; } @@ -450,6 +456,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) } if (wpa_s->disconnected && !wpa_s->scan_req) { + wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan"); wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); return; } @@ -464,6 +471,9 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) !wpa_s->scan_req) { wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan"); wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); +#ifdef CONFIG_P2P + wpa_s->sta_scan_pending = 0; +#endif /* CONFIG_P2P */ return; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 49830d6..d8f3c44 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1255,7 +1255,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, "mode"); return; } - wpa_supplicant_create_ap(wpa_s, ssid); + if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) { + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + return; + } wpa_s->current_bss = bss; #else /* CONFIG_AP */ wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in " diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 130f3ab..915ca57 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -1869,6 +1869,7 @@ static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s, } +#ifdef CONFIG_WPS_ER static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s, struct wps_parse_attr *attr) { @@ -1876,6 +1877,7 @@ static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s, wpa_s->wps->registrar, attr->oob_dev_password, attr->oob_dev_password_len); } +#endif /* CONFIG_WPS_ER */ static int wpas_wps_nfc_tag_process(struct wpa_supplicant *wpa_s, -- 2.11.0