int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
const u8 *bssid, const u8 *ssid, size_t ssid_len,
unsigned int force_freq, const u8 *go_dev_addr,
- int persistent_group)
+ int persistent_group, unsigned int pref_freq)
{
struct p2p_device *dev;
return -1;
}
+ if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0)
+ return -1;
+
if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
if (!(dev->info.dev_capab &
P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
dev->invitation_reqs = 0;
- if (force_freq) {
- if (p2p_freq_to_channel(p2p->cfg->country, force_freq,
- &p2p->op_reg_class, &p2p->op_channel) <
- 0) {
- wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
- "P2P: Unsupported frequency %u MHz",
- force_freq);
- return -1;
- }
- p2p->channels.reg_classes = 1;
- p2p->channels.reg_class[0].channels = 1;
- p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
- p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
- } else {
- p2p->op_reg_class = p2p->cfg->op_reg_class;
- p2p->op_channel = p2p->cfg->op_channel;
- os_memcpy(&p2p->channels, &p2p->cfg->channels,
- sizeof(struct p2p_channels));
- }
-
if (p2p->state != P2P_IDLE)
p2p_stop_find(p2p);
int ht40)
{
enum p2p_invite_role role;
- u8 *bssid = NULL;
+ u8 *bssid = NULL, bssid_buf[ETH_ALEN];
+ int force_freq = 0, pref_freq = 0, oper_freq = 0;
wpa_s->p2p_persistent_go_freq = freq;
wpa_s->p2p_go_ht40 = !!ht40;
}
wpa_s->pending_invite_ssid_id = ssid->id;
+ if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 &&
+ wpa_s->assoc_freq) {
+ oper_freq = wpa_s->assoc_freq;
+ if (bssid == NULL)
+ bssid = bssid_buf;
+ } else {
+ oper_freq = wpa_drv_shared_freq(wpa_s);
+ if (oper_freq < 0)
+ oper_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_s->drv_flags &
+ WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+ wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we "
+ "are already using (%u MHz) on another interface",
+ oper_freq);
+ pref_freq = oper_freq;
+ } 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", oper_freq);
+ force_freq = oper_freq;
+ }
+
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid,
ssid->ssid, ssid->ssid_len,
return -1;
return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
- ssid->ssid, ssid->ssid_len, freq, go_dev_addr, 1);
+ ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
+ 1, pref_freq);
}
{
struct wpa_global *global = wpa_s->global;
enum p2p_invite_role role;
- u8 *bssid = NULL;
+ u8 *bssid = NULL, bssid_buf[ETH_ALEN];
struct wpa_ssid *ssid;
int persistent;
+ int force_freq = 0, oper_freq = 0, pref_freq = 0;
wpa_s->p2p_persistent_go_freq = 0;
wpa_s->p2p_go_ht40 = 0;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
+ if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 &&
+ wpa_s->assoc_freq) {
+ oper_freq = wpa_s->assoc_freq;
+ if (bssid == NULL)
+ bssid = bssid_buf;
+ } else {
+ oper_freq = wpa_drv_shared_freq(wpa_s);
+ if (oper_freq < 0)
+ oper_freq = 0;
+ }
+
+ 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_s->drv_flags &
+ WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+ wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we "
+ "are already using (%u MHz) on another interface",
+ oper_freq);
+ pref_freq = oper_freq;
+ } 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", oper_freq);
+ force_freq = oper_freq;
+ }
+
return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
- ssid->ssid, ssid->ssid_len, wpa_s->assoc_freq,
- go_dev_addr, persistent);
+ ssid->ssid, ssid->ssid_len, force_freq,
+ go_dev_addr, persistent, pref_freq);
}