X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fp2p_supplicant.c;h=da90c28e046f81bf2833faed55678976cac1ea5c;hb=0e2e565a44ab7b073491cab00847f7bc62731483;hp=8b1d5c4bde7c7d7389e24196042199300c2e3998;hpb=c4ea4c5c90cb80ea28073a6c40609c3a76f2a118;p=libeap.git diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 8b1d5c4..da90c28 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -445,15 +445,17 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s, char psk[65]; wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED - "%s GO ssid=\"%s\" psk=%s go_dev_addr=" MACSTR "%s", - wpa_s->ifname, ssid_txt, psk, MAC2STR(go_dev_addr), + "%s GO ssid=\"%s\" freq=%d psk=%s go_dev_addr=" MACSTR + "%s", + wpa_s->ifname, ssid_txt, ssid->frequency, psk, + MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : ""); wpas_p2p_cross_connect_setup(wpa_s); } else { wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED - "%s GO ssid=\"%s\" passphrase=\"%s\" go_dev_addr=" - MACSTR "%s", - wpa_s->ifname, ssid_txt, + "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" " + "go_dev_addr=" MACSTR "%s", + wpa_s->ifname, ssid_txt, ssid->frequency, ssid && ssid->passphrase ? ssid->passphrase : "", MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : ""); @@ -475,6 +477,9 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx) without_roc = wpa_s->pending_action_without_roc; wpa_s->pending_action_without_roc = 0; + wpa_printf(MSG_DEBUG, "P2P: Send Action callback (without_roc=%d " + "pending_action_tx=%p)", + without_roc, wpa_s->pending_action_tx); if (wpa_s->pending_action_tx == NULL) return; @@ -609,8 +614,9 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, struct wpa_supplicant *wpa_s = ctx; wpa_printf(MSG_DEBUG, "P2P: Send action frame: freq=%d dst=" MACSTR - " src=" MACSTR " bssid=" MACSTR, - freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid)); + " src=" MACSTR " bssid=" MACSTR " len=%d", + freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), + (int) len); if (wpa_s->pending_action_tx) { wpa_printf(MSG_DEBUG, "P2P: Dropped pending Action frame TX " @@ -618,8 +624,11 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, wpabuf_free(wpa_s->pending_action_tx); } wpa_s->pending_action_tx = wpabuf_alloc(len); - if (wpa_s->pending_action_tx == NULL) + if (wpa_s->pending_action_tx == NULL) { + wpa_printf(MSG_DEBUG, "P2P: Failed to allocate Action frame " + "TX buffer (len=%llu)", (unsigned long long) len); return -1; + } wpabuf_put_data(wpa_s->pending_action_tx, buf, len); os_memcpy(wpa_s->pending_action_src, src, ETH_ALEN); os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN); @@ -627,7 +636,8 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst, wpa_s->pending_action_freq = freq; if (wpa_s->off_channel_freq == freq || freq == 0) { - /* Already on requested channel; send immediately */ + wpa_printf(MSG_DEBUG, "P2P: Already on requested channel; " + "send Action frame immediately"); /* TODO: Would there ever be need to extend the current * duration on the channel? */ wpa_s->pending_action_without_roc = 1; @@ -690,6 +700,8 @@ static int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s, static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, struct p2p_go_neg_results *res) { + wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID", + res->ssid, res->ssid_len); wpa_supplicant_ap_deinit(wpa_s); wpas_copy_go_neg_results(wpa_s, res); if (res->wps_method == WPS_PBC) @@ -715,10 +727,11 @@ static void p2p_go_configured(void *ctx, void *data) if (ssid && ssid->mode == WPAS_MODE_P2P_GO) { wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning"); wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED - "%s GO ssid=\"%s\" passphrase=\"%s\" go_dev_addr=" - MACSTR "%s", + "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" " + "go_dev_addr=" MACSTR "%s", wpa_s->ifname, wpa_ssid_txt(ssid->ssid, ssid->ssid_len), + ssid->frequency, params->passphrase ? params->passphrase : "", MAC2STR(wpa_s->parent->own_addr), params->persistent_group ? " [PERSISTENT]" : ""); @@ -972,9 +985,9 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL); eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); - /* TODO: add peer Config Timeout */ - eloop_register_timeout(15, 0, wpas_p2p_group_formation_timeout, wpa_s, - NULL); + eloop_register_timeout(15 + res->peer_config_timeout / 100, + (res->peer_config_timeout % 100) * 10000, + wpas_p2p_group_formation_timeout, wpa_s, NULL); } @@ -1008,7 +1021,7 @@ static int wpas_start_listen(void *ctx, unsigned int freq, { struct wpa_supplicant *wpa_s = ctx; - wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie); + wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie, NULL); if (wpa_drv_probe_req_report(wpa_s, 1) < 0) { wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to " @@ -1701,6 +1714,15 @@ void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods) else if (config_methods & WPS_CONFIG_PUSHBUTTON) wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP MACSTR, MAC2STR(peer)); + + if (wpa_s->pending_pd_before_join && + (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || + os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) { + wpa_s->pending_pd_before_join = 0; + wpa_printf(MSG_DEBUG, "P2P: Starting pending " + "join-existing-group operation"); + wpas_p2p_join_start(wpa_s); + } } @@ -1813,7 +1835,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, if (s) { wpas_p2p_group_add_persistent( wpa_s, s, s->mode == WPAS_MODE_P2P_GO, 0); - } else { + } else if (bssid) { wpas_p2p_join(wpa_s, bssid, go_dev_addr, wpa_s->p2p_wps_method); } @@ -1927,16 +1949,24 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, /* Operating class 81 - 2.4 GHz band channels 1..13 */ p2p->channels.reg_class[cla].reg_class = 81; +#if 0 p2p->channels.reg_class[cla].channels = 13; for (i = 0; i < 13; i++) p2p->channels.reg_class[cla].channel[i] = i + 1; +#else + p2p->channels.reg_class[cla].channels = 11; + for (i = 0; i < 11; i++) + p2p->channels.reg_class[cla].channel[i] = i + 1; +#endif cla++; +#if 0 /* Operating class 82 - 2.4 GHz band channel 14 */ p2p->channels.reg_class[cla].reg_class = 82; p2p->channels.reg_class[cla].channels = 1; p2p->channels.reg_class[cla].channel[0] = 14; cla++; +#endif #if 0 /* Operating class 83 - 2.4 GHz band channels 1..9; 40 MHz */ @@ -2171,6 +2201,8 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) p2p.ssid_postfix_len); } + p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss; + global->p2p = p2p_init(&p2p); if (global->p2p == NULL) return -1; @@ -2243,6 +2275,15 @@ void wpas_p2p_deinit_global(struct wpa_global *global) os_free(ifname); } + /* + * Deinit GO data on any possibly remaining interface (if main + * interface is used as GO). + */ + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->ap_iface) + wpas_p2p_group_deinit(wpa_s); + } + p2p_deinit(global->p2p); global->p2p = NULL; } @@ -2291,6 +2332,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) { struct wpa_bss *bss; + int freq; eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); @@ -2303,14 +2345,25 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, if (scan_res) wpas_p2p_scan_res_handler(wpa_s, scan_res); + freq = p2p_get_oper_freq(wpa_s->global->p2p, + wpa_s->pending_join_iface_addr); + if (freq >= 0) { + wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " + "from P2P peer table: %d MHz", freq); + } bss = wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr); if (bss) { + freq = bss->freq; + wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " + "from BSS table: %d MHz", freq); + } + if (freq > 0) { u16 method; wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request " "prior to joining an existing group (GO " MACSTR " freq=%u MHz)", - MAC2STR(wpa_s->pending_join_dev_addr), bss->freq); + MAC2STR(wpa_s->pending_join_dev_addr), freq); wpa_s->pending_pd_before_join = 1; switch (wpa_s->pending_join_wps_method) { @@ -2453,6 +2506,15 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s) res.wps_method = wpa_s->pending_join_wps_method; wpas_start_wps_enrollee(group, &res); + /* + * Allow a longer timeout for join-a-running-group than normal 15 + * second group formation timeout since the GO may not have authorized + * our connection yet. + */ + eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL); + eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout, + wpa_s, NULL); + return 0; } @@ -2633,6 +2695,9 @@ static int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, unsigned int freq) { + wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback " + "(p2p_long_listen=%d pending_action_tx=%p)", + wpa_s->p2p_long_listen, wpa_s->pending_action_tx); wpa_s->off_channel_freq = 0; if (p2p_listen_end(wpa_s->global->p2p, freq) > 0) return; /* P2P module started a new operation */ @@ -2955,9 +3020,22 @@ int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, } +static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s) +{ + if (!wpa_s->pending_action_tx) + return; + + wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new " + "operation request"); + wpabuf_free(wpa_s->pending_action_tx); + wpa_s->pending_action_tx = NULL; +} + + int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, enum p2p_discovery_type type) { + wpas_p2p_clear_pending_action_tx(wpa_s); wpa_s->p2p_long_listen = 0; return p2p_find(wpa_s->global->p2p, timeout, type); @@ -2966,6 +3044,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s) { + wpas_p2p_clear_pending_action_tx(wpa_s); wpa_s->p2p_long_listen = 0; eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL); @@ -2986,6 +3065,8 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout) { int res; + wpas_p2p_clear_pending_action_tx(wpa_s); + if (timeout == 0) { /* * This is a request for unlimited Listen state. However, at @@ -3019,6 +3100,8 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, return -1; if (wpa_s->global->p2p == NULL) return -1; + if (bss == NULL) + return -1; p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len, @@ -3191,15 +3274,16 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s) char psk[65]; wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32); wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED - "%s client ssid=\"%s\" psk=%s go_dev_addr=" MACSTR - "%s", - wpa_s->ifname, ssid_txt, psk, MAC2STR(go_dev_addr), + "%s client ssid=\"%s\" freq=%d psk=%s go_dev_addr=" + MACSTR "%s", + wpa_s->ifname, ssid_txt, ssid->frequency, psk, + MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : ""); } else { wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED - "%s client ssid=\"%s\" passphrase=\"%s\" go_dev_addr=" - MACSTR "%s", - wpa_s->ifname, ssid_txt, + "%s client ssid=\"%s\" freq=%d passphrase=\"%s\" " + "go_dev_addr=" MACSTR "%s", + wpa_s->ifname, ssid_txt, ssid->frequency, ssid->passphrase ? ssid->passphrase : "", MAC2STR(go_dev_addr), persistent ? " [PERSISTENT]" : ""); @@ -3259,6 +3343,9 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s) if (p2p == NULL) return; + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) + return; + if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME) p2p_set_dev_name(p2p, wpa_s->conf->device_name); @@ -3310,6 +3397,9 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s) os_strlen(wpa_s->conf->p2p_ssid_postfix) : 0); } + + if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS) + p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss); } @@ -3453,3 +3543,16 @@ static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s) break; } } + + +int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT && + !wpa_s->p2p_in_provisioning) + return 0; /* not P2P client operation */ + + wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC " + "session overlap"); + wpas_group_formation_completed(wpa_s, 0); + return 1; +}