p2p->after_scan_tx->bssid,
(u8 *) (p2p->after_scan_tx + 1),
p2p->after_scan_tx->len,
- p2p->after_scan_tx->wait_time);
+ p2p->after_scan_tx->wait_time, NULL);
os_free(p2p->after_scan_tx);
p2p->after_scan_tx = NULL;
return 1;
const u8 *src, const u8 *bssid, const u8 *buf,
size_t len, unsigned int wait_time)
{
+ int res, scheduled;
+
if (p2p->p2p_scan_running) {
p2p_dbg(p2p, "Delay Action frame TX until p2p_scan completes");
if (p2p->after_scan_tx) {
return 0;
}
- return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
- buf, len, wait_time);
+ res = p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
+ buf, len, wait_time, &scheduled);
+ if (res == 0 && scheduled && p2p->in_listen && freq > 0 &&
+ (unsigned int) p2p->drv_in_listen != freq) {
+ p2p_dbg(p2p,
+ "Stop listen on %d MHz to allow a frame to be sent immediately on %d MHz",
+ p2p->drv_in_listen, freq);
+ p2p_stop_listen_for_freq(p2p, freq);
+ }
+ return res;
}
* @buf: Frame body (starting from Category field)
* @len: Length of buf in octets
* @wait_time: How many msec to wait for a response frame
+ * @scheduled: Return value indicating whether the transmissions was
+ * scheduled to happen once the radio is available
* Returns: 0 on success, -1 on failure
*
* The Action frame may not be transmitted immediately and the status
*/
int (*send_action)(void *ctx, unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time);
+ size_t len, unsigned int wait_time, int *scheduled);
/**
* send_action_done - Notify that Action frame sequence was completed
if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, m->addr,
group->cfg->interface_addr,
group->cfg->interface_addr,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
+ wpabuf_head(req), wpabuf_len(req), 200, NULL)
+ < 0)
{
p2p_dbg(p2p, "Failed to send Action frame");
}
static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
const u8 *src, const u8 *bssid, const u8 *buf,
- size_t len, unsigned int wait_time)
+ size_t len, unsigned int wait_time, int *scheduled)
{
struct wpa_supplicant *wpa_s = ctx;
int listen_freq = -1, send_freq = -1;
+ if (scheduled)
+ *scheduled = 0;
if (wpa_s->p2p_listen_work)
listen_freq = wpa_s->p2p_listen_work->freq;
if (wpa_s->p2p_send_action_work)
send_freq = wpa_s->p2p_send_action_work->freq;
if (listen_freq != (int) freq && send_freq != (int) freq) {
- wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)",
- listen_freq, send_freq);
- return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
- len, wait_time);
+ int res;
+
+ wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d freq=%u)",
+ listen_freq, send_freq, freq);
+ res = wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
+ len, wait_time);
+ if (res == 0 && scheduled)
+ *scheduled = 1;
+ return res;
}
wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");