diff options
author | Irfan Sheriff <isheriff@google.com> | 2012-09-22 16:59:30 -0700 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2012-09-23 17:28:47 -0700 |
commit | af84a575044f6556994fcc124a955fc0ac0a6736 (patch) | |
tree | 2fc48bbddb8ef135f997561f8d3beb951341a640 /src | |
parent | 89ca702e8ed3247d7007dbdebe531036671c34af (diff) | |
download | external_wpa_supplicant_8-af84a575044f6556994fcc124a955fc0ac0a6736.zip external_wpa_supplicant_8-af84a575044f6556994fcc124a955fc0ac0a6736.tar.gz external_wpa_supplicant_8-af84a575044f6556994fcc124a955fc0ac0a6736.tar.bz2 |
GC channel fixes for better interop with SCC
- Force operating channel as the only channel in channel list attribute for go negotiation
and persistence
- Force an operating channel in go negotiation response even if the GO indicates a different
in negotiation request
- Fix a bug with updating peer operating channel based on GO negotiation confirm
Bug: 7217600
Change-Id: I6da0dc1a49c1d99ae97dcab8ee9899e07a80a6cb
Diffstat (limited to 'src')
-rw-r--r-- | src/p2p/p2p_build.c | 21 | ||||
-rw-r--r-- | src/p2p/p2p_go_neg.c | 56 | ||||
-rw-r--r-- | src/p2p/p2p_invitation.c | 18 |
3 files changed, 79 insertions, 16 deletions
diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index def422d..66e8456 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -135,6 +135,27 @@ void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country, wpa_printf(MSG_DEBUG, "P2P: * Channel List"); } +/* Adds a given channel as the only channel in channel list attribute */ +void p2p_buf_add_oper_as_channel_list(struct wpabuf *buf, const char *country, + u8 reg_class, u8 channel) +{ + u8 *len; + u8 channel_list[1]; + channel_list[0] = channel; + + /* Channel List */ + wpabuf_put_u8(buf, P2P_ATTR_CHANNEL_LIST); + len = wpabuf_put(buf, 2); /* IE length to be filled */ + wpabuf_put_data(buf, country, 3); /* Country String */ + + wpabuf_put_u8(buf, reg_class); + wpabuf_put_u8(buf, 1); + wpabuf_put_data(buf, channel_list, 1); + + /* Update attribute length */ + WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2); + wpa_printf(MSG_DEBUG, "P2P: * Oper as Channel List %u", channel); +} void p2p_buf_add_status(struct wpabuf *buf, u8 status) { diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 031b3a1..0324fe5 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -174,7 +174,13 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period, p2p->ext_listen_interval); p2p_buf_add_intended_addr(buf, p2p->intended_addr); - p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); + if (p2p->cfg->p2p_concurrency == P2P_SINGLE_CHANNEL_CONCURRENT && p2p->op_channel) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Force channel list %d", p2p->op_channel); + p2p_buf_add_oper_as_channel_list(buf, p2p->cfg->country, p2p->op_reg_class, + p2p->op_channel); + } else { + p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); + } p2p_buf_add_device_info(buf, p2p, peer); p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); @@ -294,26 +300,40 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker); p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); if (peer && peer->go_state == REMOTE_GO) { - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Omit Operating " - "Channel attribute"); + if (p2p->cfg->p2p_concurrency == P2P_SINGLE_CHANNEL_CONCURRENT && p2p->op_channel) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Forcing a channel "); + p2p_buf_add_operating_channel(buf, p2p->cfg->country, + p2p->op_reg_class, p2p->op_channel); + } else { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Omit Operating " + "Channel attribute"); + } } else { p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); } p2p_buf_add_intended_addr(buf, p2p->intended_addr); - if (status || peer == NULL) { - p2p_buf_add_channel_list(buf, p2p->cfg->country, - &p2p->channels); - } else if (peer->go_state == REMOTE_GO) { - p2p_buf_add_channel_list(buf, p2p->cfg->country, - &p2p->channels); + + if (p2p->cfg->p2p_concurrency == P2P_SINGLE_CHANNEL_CONCURRENT && p2p->op_channel) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Force channel list %d", p2p->op_channel); + p2p_buf_add_oper_as_channel_list(buf, p2p->cfg->country, p2p->op_reg_class, + p2p->op_channel); } else { - struct p2p_channels res; - p2p_channels_intersect(&p2p->channels, &peer->channels, - &res); - p2p_buf_add_channel_list(buf, p2p->cfg->country, &res); + if (status || peer == NULL) { + p2p_buf_add_channel_list(buf, p2p->cfg->country, + &p2p->channels); + } else if (peer->go_state == REMOTE_GO) { + p2p_buf_add_channel_list(buf, p2p->cfg->country, + &p2p->channels); + } else { + struct p2p_channels res; + p2p_channels_intersect(&p2p->channels, &peer->channels, + &res); + p2p_buf_add_channel_list(buf, p2p->cfg->country, &res); + } } + p2p_buf_add_device_info(buf, p2p, peer); if (peer && peer->go_state == LOCAL_GO) { p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid, @@ -1168,6 +1188,16 @@ void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa, #endif /* CONFIG_P2P_STRICT */ } + if (msg.operating_channel) { + dev->oper_freq = p2p_channel_to_freq((const char *) + msg.operating_channel, + msg.operating_channel[3], + msg.operating_channel[4]); + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer operating " + "channel preference: %d MHz", dev->oper_freq); + } else + dev->oper_freq = 0; + if (!msg.channel_list) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Mandatory Operating Channel attribute missing " diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index d26654b..b237cf8 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -66,7 +66,13 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, p2p->op_reg_class, p2p->op_channel); if (p2p->inv_bssid_set) p2p_buf_add_group_bssid(buf, p2p->inv_bssid); - p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); + if (p2p->cfg->p2p_concurrency == P2P_SINGLE_CHANNEL_CONCURRENT && p2p->op_channel) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Forcing channel list %d", p2p->op_channel); + p2p_buf_add_oper_as_channel_list(buf, p2p->cfg->country, p2p->op_reg_class, + p2p->op_channel); + } else { + p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); + } if (go_dev_addr) dev_addr = go_dev_addr; else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT) @@ -133,8 +139,14 @@ static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p, reg_class, channel); if (group_bssid) p2p_buf_add_group_bssid(buf, group_bssid); - if (channels) - p2p_buf_add_channel_list(buf, p2p->cfg->country, channels); + if (p2p->cfg->p2p_concurrency == P2P_SINGLE_CHANNEL_CONCURRENT && channel) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Forcing channel list %d", channel); + p2p_buf_add_oper_as_channel_list(buf, p2p->cfg->country, + reg_class, channel); + } else { + if (channels) + p2p_buf_add_channel_list(buf, p2p->cfg->country, channels); + } p2p_buf_update_ie_hdr(buf, len); #ifdef CONFIG_WIFI_DISPLAY |