Message ID | e651dd84e545275d28cdab6d94c2e7d5c5876dfa.1400741305.git.jithu@broadcom.com |
---|---|
State | Accepted |
Headers | show |
On Thu, May 22, 2014 at 12:25:53PM +0530, Jithu Jance wrote: > I re-organised the code to take care of this case. Hope this is > fine now. While this can pass all the hwsim test cases one-by-one separately, there are still some errors being triggered with "P2P: p2p_listen command pending already" dropping a P2P_LISTEN command and wpa_supplicant ending up in state where it is not doing anything after the previous started operation (e.g., remain-on-channel) completes. > diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c > @@ -284,16 +290,21 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout) > > p2p_dbg(p2p, "Going to listen(only) state"); > > + p2p->pending_listen_sec = timeout / 1000; > + p2p->pending_listen_usec = (timeout % 1000) * 1000; > + > + if (p2p->pending_listen_freq) { > + /* We have a pending p2p_listen request */ > + p2p_dbg(p2p, "p2p_listen command pending already"); > + return -1; > + } > + > freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); > if (freq < 0) { > p2p_dbg(p2p, "Unknown regulatory class/channel"); > return -1; > } This looks a bit odd. Why would either of those return cases update pending_listen_{sec,usec}? I moved those two back here: > - p2p->pending_listen_freq = freq; > - p2p->pending_listen_sec = timeout / 1000; > - p2p->pending_listen_usec = (timeout % 1000) * 1000; In other words, only pending_listen_freq moves down to here: > @@ -308,6 +319,8 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout) > if (ies == NULL) > return -1; > > + p2p->pending_listen_freq = freq; > + > if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { > p2p_dbg(p2p, "Failed to start listen mode"); > p2p->pending_listen_freq = 0; That said, something is clearly still leaving p2p->pending_listen_freq set to non-zero value while allowing the previous operation to terminate. One example that I'm looking at is from grpform_no_5ghz_add_cli failure case where P2P_FIND is first started and P2P_LISTEN is then used to move listen-only state. This results in the previously started p2p_find getting stopped, but p2p_listen execution is still skipping scheduling of a new operation due to pending_listen_freq (which is likely left set by an earlier test case). Maybe p2p_stop_find() would need to clear pending_listen_freq to avoid this? In this particular error case, the previous find operation is indeed stopped by wpa_p2p_listen() calling p2p_stop_find just before calling p2p_listen().
On Thu, May 22, 2014 at 03:54:30PM +0300, Jouni Malinen wrote: > Maybe p2p_stop_find() would need to clear pending_listen_freq to avoid > this? In this particular error case, the previous find operation is > indeed stopped by wpa_p2p_listen() calling p2p_stop_find just before > calling p2p_listen(). That seems to have done the trick - two full test runs completed without any failures. I have this in the pending branch now: http://w1.fi/cgit/hostap/commit/?h=pending&id=5661bd0f706b542bdc3b35df5b2b391f277e1275
Hi Jouni, > On Thu, May 22, 2014 at 03:54:30PM +0300, Jouni Malinen wrote: >> Maybe p2p_stop_find() would need to clear pending_listen_freq to avoid >> this? In this particular error case, the previous find operation is >> indeed stopped by wpa_p2p_listen() calling p2p_stop_find just before >> calling p2p_listen(). > > That seems to have done the trick - two full test runs completed without > any failures. I have this in the pending branch now: > http://w1.fi/cgit/hostap/commit/?h=pending&id=5661bd0f706b542bdc3b35df5b2b391f277e1275 > Thanks a lot for nailing this down!!
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index c2f8d9b..08aecc1 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -238,6 +238,12 @@ static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) p2p_dbg(p2p, "Starting short listen state (state=%s)", p2p_state_txt(p2p->state)); + if (p2p->pending_listen_freq) { + /* We have a pending p2p_listen request */ + p2p_dbg(p2p, "p2p_listen command pending already"); + return; + } + freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); if (freq < 0) { p2p_dbg(p2p, "Unknown regulatory class/channel"); @@ -260,14 +266,14 @@ static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc) return; } - p2p->pending_listen_freq = freq; - p2p->pending_listen_sec = 0; - p2p->pending_listen_usec = 1024 * tu; - ies = p2p_build_probe_resp_ies(p2p); if (ies == NULL) return; + p2p->pending_listen_freq = freq; + p2p->pending_listen_sec = 0; + p2p->pending_listen_usec = 1024 * tu; + if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000, ies) < 0) { p2p_dbg(p2p, "Failed to start listen mode"); @@ -284,16 +290,21 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout) p2p_dbg(p2p, "Going to listen(only) state"); + p2p->pending_listen_sec = timeout / 1000; + p2p->pending_listen_usec = (timeout % 1000) * 1000; + + if (p2p->pending_listen_freq) { + /* We have a pending p2p_listen request */ + p2p_dbg(p2p, "p2p_listen command pending already"); + return -1; + } + freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel); if (freq < 0) { p2p_dbg(p2p, "Unknown regulatory class/channel"); return -1; } - p2p->pending_listen_freq = freq; - p2p->pending_listen_sec = timeout / 1000; - p2p->pending_listen_usec = (timeout % 1000) * 1000; - if (p2p->p2p_scan_running) { if (p2p->start_after_scan == P2P_AFTER_SCAN_CONNECT) { p2p_dbg(p2p, "p2p_scan running - connect is already pending - skip listen"); @@ -308,6 +319,8 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout) if (ies == NULL) return -1; + p2p->pending_listen_freq = freq; + if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, timeout, ies) < 0) { p2p_dbg(p2p, "Failed to start listen mode"); p2p->pending_listen_freq = 0;