aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2012-09-22 16:59:30 -0700
committerIrfan Sheriff <isheriff@google.com>2012-09-23 17:28:47 -0700
commitaf84a575044f6556994fcc124a955fc0ac0a6736 (patch)
tree2fc48bbddb8ef135f997561f8d3beb951341a640 /src
parent89ca702e8ed3247d7007dbdebe531036671c34af (diff)
downloadexternal_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.c21
-rw-r--r--src/p2p/p2p_go_neg.c56
-rw-r--r--src/p2p/p2p_invitation.c18
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