X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fp2p_supplicant.c;h=79b769149367607e7e26963f0b3badb4dfe4abff;hb=ac8d1011b7eebc5de4129a3efccf1bdecc2b7236;hp=be6c3390a121e3d73aa16faa2990bdf8a7816775;hpb=b73bf0a74b9638b7164e7d3a61891d7d39088d84;p=libeap.git diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index be6c339..79b7691 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -700,13 +700,14 @@ 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_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR, + MAC2STR(res->peer_interface_addr)); 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) - wpas_wps_start_pbc(wpa_s, NULL /* res->peer_interface_addr */, - 1); + wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1); else { u16 dev_pw_id = DEV_PW_DEFAULT; if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) @@ -1021,7 +1022,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 " @@ -1048,7 +1049,7 @@ static int wpas_start_listen(void *ctx, unsigned int freq, static void wpas_stop_listen(void *ctx) { struct wpa_supplicant *wpa_s = ctx; - if (wpa_s->off_channel_freq) { + if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { wpa_drv_cancel_remain_on_channel(wpa_s); wpa_s->off_channel_freq = 0; wpa_s->roc_waiting_drv_freq = 0; @@ -1835,7 +1836,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); } @@ -1904,151 +1905,153 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid) } +static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s, + struct p2p_channels *chan) +{ + int i, cla = 0; + + wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz " + "band"); + + /* Operating class 81 - 2.4 GHz band channels 1..13 */ + chan->reg_class[cla].reg_class = 81; + chan->reg_class[cla].channels = 11; + for (i = 0; i < 11; i++) + chan->reg_class[cla].channel[i] = i + 1; + cla++; + + wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz " + "band"); + + /* Operating class 115 - 5 GHz, channels 36-48 */ + chan->reg_class[cla].reg_class = 115; + chan->reg_class[cla].channels = 4; + chan->reg_class[cla].channel[0] = 36; + chan->reg_class[cla].channel[1] = 40; + chan->reg_class[cla].channel[2] = 44; + chan->reg_class[cla].channel[3] = 48; + cla++; + + wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz " + "band"); + + /* Operating class 124 - 5 GHz, channels 149,153,157,161 */ + chan->reg_class[cla].reg_class = 124; + chan->reg_class[cla].channels = 4; + chan->reg_class[cla].channel[0] = 149; + chan->reg_class[cla].channel[1] = 153; + chan->reg_class[cla].channel[2] = 157; + chan->reg_class[cla].channel[3] = 161; + cla++; + + chan->reg_classes = cla; + return 0; +} + + +static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, + u16 num_modes, + enum hostapd_hw_mode mode) +{ + u16 i; + + for (i = 0; i < num_modes; i++) { + if (modes[i].mode == mode) + return &modes[i]; + } + + return NULL; +} + + +static int has_channel(struct hostapd_hw_modes *mode, u8 chan) +{ + int i; + + for (i = 0; i < mode->num_channels; i++) { + if (mode->channels[i].chan == chan) { + return !(mode->channels[i].flag & + (HOSTAPD_CHAN_DISABLED | + HOSTAPD_CHAN_PASSIVE_SCAN | + HOSTAPD_CHAN_NO_IBSS | + HOSTAPD_CHAN_RADAR)); + } + } + + return 0; +} + + +struct p2p_oper_class_map { + enum hostapd_hw_mode mode; + u8 op_class; + u8 min_chan; + u8 max_chan; + u8 inc; +}; + static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, - struct p2p_config *p2p) + struct p2p_channels *chan) { - struct hostapd_hw_modes *modes; + struct hostapd_hw_modes *modes, *mode; u16 num_modes, flags; - int i, cla; - int band24 = 0, band5_low = 0, band5_high = 0; - - /* TODO: more detailed selection of channels within reg_class based on - * driver capabilities */ + int cla, op; + struct p2p_oper_class_map op_class[] = { + { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1 }, + { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1 }, + { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4 }, + { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4 }, +#if 0 /* TODO: 40 MHz channels */ + { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1 }, + { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1 }, + { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8 }, + { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8 }, + { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8 }, + { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8 }, +#endif + { -1, 0, 0, 0, 0 } + }; modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags); if (modes == NULL) { wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching " "of all supported channels; assume dualband " "support"); - band24 = band5_low = band5_high = 1; - } else { - for (i = 0; i < num_modes; i++) { - struct hostapd_hw_modes *mode; - mode = &modes[i]; - if (mode->mode == HOSTAPD_MODE_IEEE80211G) { - band24 = 1; - } else if (mode->mode == HOSTAPD_MODE_IEEE80211A) { - int j; - for (j = 0; j < mode->num_channels; j++) { - struct hostapd_channel_data *ch; - ch = &mode->channels[j]; - if (ch->chan == 36) - band5_low = 1; - else if (ch->chan == 157) - band5_high = 1; - } - } - } + return wpas_p2p_default_channels(wpa_s, chan); } cla = 0; - if (band24) { - wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for " - "2.4 GHz band"); - - /* 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 + for (op = 0; op_class[op].op_class; op++) { + struct p2p_oper_class_map *o = &op_class[op]; + u8 ch; + struct p2p_reg_class *reg = NULL; -#if 0 - /* Operating class 83 - 2.4 GHz band channels 1..9; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 83; - p2p->channels.reg_class[cla].channels = 9; - for (i = 0; i < 9; i++) - p2p->channels.reg_class[cla].channel[i] = i + 1; - cla++; - - /* Operating class 84 - 2.4 GHz band channels 5..13; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 84; - p2p->channels.reg_class[cla].channels = 9; - for (i = 0; i < 9; i++) - p2p->channels.reg_class[cla].channel[i] = i + 5; - cla++; -#endif - } - - if (band5_low) { - wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for " - "lower 5 GHz band"); - - /* Operating class 115 - 5 GHz, channels 36-48 */ - p2p->channels.reg_class[cla].reg_class = 115; - p2p->channels.reg_class[cla].channels = 4; - p2p->channels.reg_class[cla].channel[0] = 36; - p2p->channels.reg_class[cla].channel[1] = 40; - p2p->channels.reg_class[cla].channel[2] = 44; - p2p->channels.reg_class[cla].channel[3] = 48; - cla++; - -#if 0 - /* Operating class 116 - 5 GHz, channels 36,44; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 116; - p2p->channels.reg_class[cla].channels = 2; - p2p->channels.reg_class[cla].channel[0] = 36; - p2p->channels.reg_class[cla].channel[1] = 44; - cla++; - - /* Operating class 117 - 5 GHz, channels 40,48; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 117; - p2p->channels.reg_class[cla].channels = 2; - p2p->channels.reg_class[cla].channel[0] = 40; - p2p->channels.reg_class[cla].channel[1] = 48; - cla++; -#endif - } - - if (band5_high) { - wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for " - "higher 5 GHz band"); - - /* Operating class 124 - 5 GHz, channels 149,153,157,161 */ - p2p->channels.reg_class[cla].reg_class = 124; - p2p->channels.reg_class[cla].channels = 4; - p2p->channels.reg_class[cla].channel[0] = 149; - p2p->channels.reg_class[cla].channel[1] = 153; - p2p->channels.reg_class[cla].channel[2] = 157; - p2p->channels.reg_class[cla].channel[3] = 161; - cla++; - -#if 0 - /* Operating class 126 - 5 GHz, channels 149,157; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 126; - p2p->channels.reg_class[cla].channels = 2; - p2p->channels.reg_class[cla].channel[0] = 149; - p2p->channels.reg_class[cla].channel[1] = 157; - cla++; - - /* Operating class 127 - 5 GHz, channels 153,161; 40 MHz */ - p2p->channels.reg_class[cla].reg_class = 127; - p2p->channels.reg_class[cla].channels = 2; - p2p->channels.reg_class[cla].channel[0] = 153; - p2p->channels.reg_class[cla].channel[1] = 161; - cla++; -#endif + mode = get_mode(modes, num_modes, o->mode); + if (mode == NULL) + continue; + for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { + if (!has_channel(mode, ch)) + continue; + if (reg == NULL) { + wpa_printf(MSG_DEBUG, "P2P: Add operating " + "class %u", o->op_class); + reg = &chan->reg_class[cla]; + cla++; + reg->reg_class = o->op_class; + } + reg->channel[reg->channels] = ch; + reg->channels++; + } + if (reg) { + wpa_hexdump(MSG_DEBUG, "P2P: Channels", + reg->channel, reg->channels); + } } - p2p->channels.reg_classes = cla; + chan->reg_classes = cla; - if (modes) - ieee80211_sta_free_hw_features(modes, num_modes); + ieee80211_sta_free_hw_features(modes, num_modes); return 0; } @@ -2160,7 +2163,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) } else os_memcpy(p2p.country, "US\x04", 3); - if (wpas_p2p_setup_channels(wpa_s, &p2p)) { + if (wpas_p2p_setup_channels(wpa_s, &p2p.channels)) { wpa_printf(MSG_ERROR, "P2P: Failed to configure supported " "channel list"); return -1; @@ -2201,6 +2204,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; @@ -2529,14 +2534,16 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s) * initiating Group Owner negotiation * @go_intent: GO Intent or -1 to use default * @freq: Frequency for the group or 0 for auto-selection - * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on failure + * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified + * failure, -2 on failure due to channel not currently available, + * -3 if forced channel is not supported */ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, const char *pin, enum p2p_wps_method wps_method, int persistent_group, int join, int auth, int go_intent, int freq) { - int force_freq = 0; + int force_freq = 0, oper_freq = 0; u8 bssid[ETH_ALEN]; int ret = 0; enum wpa_driver_if_type iftype; @@ -2582,21 +2589,52 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, return ret; } - if (freq > 0) - force_freq = freq; - else if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 && - wpa_s->assoc_freq) - force_freq = wpa_s->assoc_freq; + if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 && + wpa_s->assoc_freq) + oper_freq = wpa_s->assoc_freq; else { - force_freq = wpa_drv_shared_freq(wpa_s); - if (force_freq < 0) - force_freq = 0; + oper_freq = wpa_drv_shared_freq(wpa_s); + if (oper_freq < 0) + oper_freq = 0; } - if (force_freq > 0) { + if (freq > 0) { + if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { + wpa_printf(MSG_DEBUG, "P2P: The forced channel " + "(%u MHz) is not supported for P2P uses", + freq); + return -3; + } + + if (oper_freq > 0 && freq != oper_freq && + !(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " + "on %u MHz while connected on another " + "channel (%u MHz)", freq, oper_freq); + return -2; + } + wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " + "requested channel (%u MHz)", freq); + force_freq = freq; + } else if (oper_freq > 0 && + !p2p_supported_freq(wpa_s->global->p2p, oper_freq)) { + if (!(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " + "while connected on non-P2P supported " + "channel (%u MHz)", oper_freq); + return -2; + } + wpa_printf(MSG_DEBUG, "P2P: Current operating channel " + "(%u MHz) not available for P2P - try to use " + "another channel", oper_freq); + force_freq = 0; + } else if (oper_freq > 0) { wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " "channel we are already using (%u MHz) on another " - "interface", force_freq); + "interface", oper_freq); + force_freq = oper_freq; } wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); @@ -2824,6 +2862,13 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, { struct p2p_go_neg_results params; + if (freq > 0 && !p2p_supported_freq(wpa_s->global->p2p, freq)) { + wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO " + "(%u MHz) is not supported for P2P uses", + freq); + return -1; + } + wpas_p2p_init_go_params(wpa_s, ¶ms, freq); p2p_go_params(wpa_s->global->p2p, ¶ms); params.persistent_group = persistent_group; @@ -3341,6 +3386,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); @@ -3392,6 +3440,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); }