aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-09-25 14:23:53 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-09-25 14:25:52 -0700
commit91c40cdce17424d9a4718876becf0b7811cf68f2 (patch)
tree6c5488e5b026cda1c3bc78227a6c39136fc6b89a
parentaa532510a7b8c4da2d7d6e2c11dda5db840894e4 (diff)
downloadexternal_wpa_supplicant_8-91c40cdce17424d9a4718876becf0b7811cf68f2.zip
external_wpa_supplicant_8-91c40cdce17424d9a4718876becf0b7811cf68f2.tar.gz
external_wpa_supplicant_8-91c40cdce17424d9a4718876becf0b7811cf68f2.tar.bz2
wpa_supplicant: P2P-related fixes
- P2P: Show own channel list in debug log - P2P: Allow peer to propose channel in invitation process - P2P: Clear sta_scan_pending on group removal - P2P: Fix ignoring of PD Response due to dialog token mismatch BUG: 7226065, 7231289 Change-Id: Iacb0f85d80f63bcdf311ccc0d29d0c282a0c0576 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--src/p2p/p2p_build.c3
-rw-r--r--src/p2p/p2p_go_neg.c4
-rw-r--r--src/p2p/p2p_i.h2
-rw-r--r--src/p2p/p2p_invitation.c81
-rw-r--r--src/p2p/p2p_pd.c10
-rw-r--r--wpa_supplicant/p2p_supplicant.c4
6 files changed, 88 insertions, 16 deletions
diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c
index bbe2002..7f4d295 100644
--- a/src/p2p/p2p_build.c
+++ b/src/p2p/p2p_build.c
@@ -132,7 +132,8 @@ void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
/* Update attribute length */
WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
- wpa_printf(MSG_DEBUG, "P2P: * Channel List");
+ wpa_hexdump(MSG_DEBUG, "P2P: * Channel List",
+ len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2);
}
#ifdef ANDROID_P2P
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index b0b53fe..9c287b6 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -368,8 +368,8 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
}
-static void p2p_reselect_channel(struct p2p_data *p2p,
- struct p2p_channels *intersection)
+void p2p_reselect_channel(struct p2p_data *p2p,
+ struct p2p_channels *intersection)
{
struct p2p_reg_class *cl;
int freq;
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index bf55015..673c4c1 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -655,6 +655,8 @@ void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa,
const u8 *data, size_t len);
int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev);
u16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method);
+void p2p_reselect_channel(struct p2p_data *p2p,
+ struct p2p_channels *intersection);
/* p2p_pd.c */
void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index 785200c..7d6dd11 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -253,6 +253,8 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
}
if (op_freq) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation "
+ "processing forced frequency %d MHz", op_freq);
if (p2p_freq_to_channel(p2p->cfg->country, op_freq,
&reg_class, &channel) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
@@ -276,24 +278,89 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
if (status == P2P_SC_SUCCESS)
channels = &intersection;
} else {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: No forced channel from invitation processing - "
+ "figure out best one to use");
+
+ p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
+ &intersection);
+ /* Default to own configuration as a starting point */
+ p2p->op_reg_class = p2p->cfg->op_reg_class;
+ p2p->op_channel = p2p->cfg->op_channel;
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own default "
+ "op_class %d channel %d",
+ p2p->op_reg_class, p2p->op_channel);
+
+ /* Use peer preference if specified and compatible */
+ if (msg.operating_channel) {
+ int req_freq;
+ req_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",
+ req_freq);
+ if (req_freq > 0 &&
+ p2p_channels_includes(&intersection,
+ msg.operating_channel[3],
+ msg.operating_channel[4])) {
+ p2p->op_reg_class = msg.operating_channel[3];
+ p2p->op_channel = msg.operating_channel[4];
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Use peer preference op_class %d "
+ "channel %d",
+ p2p->op_reg_class, p2p->op_channel);
+ } else {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Cannot use peer channel "
+ "preference");
+ }
+ }
+
+ if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
+ p2p->op_channel)) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Initially selected channel (op_class %d "
+ "channel %d) not in channel intersection - try "
+ "to reselect",
+ p2p->op_reg_class, p2p->op_channel);
+ p2p_reselect_channel(p2p, &intersection);
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Re-selection result: op_class %d "
+ "channel %d",
+ p2p->op_reg_class, p2p->op_channel);
+ if (!p2p_channels_includes(&intersection,
+ p2p->op_reg_class,
+ p2p->op_channel)) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Peer does not support selected "
+ "operating channel (reg_class=%u "
+ "channel=%u)",
+ p2p->op_reg_class, p2p->op_channel);
+ status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
+ goto fail;
+ }
+ }
+
op_freq = p2p_channel_to_freq(p2p->cfg->country,
- p2p->cfg->op_reg_class,
- p2p->cfg->op_channel);
+ p2p->op_reg_class,
+ p2p->op_channel);
if (op_freq < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Unknown operational channel "
"(country=%c%c reg_class=%u channel=%u)",
p2p->cfg->country[0], p2p->cfg->country[1],
- p2p->cfg->op_reg_class, p2p->cfg->op_channel);
+ p2p->op_reg_class, p2p->op_channel);
status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
goto fail;
}
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating "
+ "channel - %d MHz", op_freq);
- p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
- &intersection);
if (status == P2P_SC_SUCCESS) {
- reg_class = p2p->cfg->op_reg_class;
- channel = p2p->cfg->op_channel;
+ reg_class = p2p->op_reg_class;
+ channel = p2p->op_channel;
channels = &intersection;
}
}
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index a2d5aee..42447e5 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -278,11 +278,6 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
return;
}
- if (p2p->pending_action_state == P2P_PENDING_PD) {
- os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
- p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- }
-
if (dev->dialog_token != msg.dialog_token) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Ignore Provision Discovery Response with "
@@ -292,6 +287,11 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
return;
}
+ if (p2p->pending_action_state == P2P_PENDING_PD) {
+ os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
+ p2p->pending_action_state = P2P_NO_PENDING_ACTION;
+ }
+
/*
* If the response is from the peer to whom a user initiated request
* was sent earlier, we reset that state info here.
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index cf8f935..c721a29 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -377,6 +377,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
wpa_config_remove_network(wpa_s->conf, id);
wpa_supplicant_clear_status(wpa_s);
wpa_supplicant_cancel_sched_scan(wpa_s);
+ wpa_s->sta_scan_pending = 0;
} else {
wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
"found");
@@ -2322,8 +2323,9 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
" was accepted; op_freq=%d MHz",
MAC2STR(sa), op_freq);
if (s) {
+ int go = s->mode == WPAS_MODE_P2P_GO;
wpas_p2p_group_add_persistent(
- wpa_s, s, s->mode == WPAS_MODE_P2P_GO, 0, 0);
+ wpa_s, s, go, go ? op_freq : 0, 0);
} else if (bssid) {
wpas_p2p_join(wpa_s, bssid, go_dev_addr,
wpa_s->p2p_wps_method, 0);