struct p2p_device *dev;
enum p2p_after_scan op;
+ if (p2p->after_scan_tx) {
+ int ret;
+ /* TODO: schedule p2p_run_after_scan to be called from TX
+ * status callback(?) */
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending "
+ "Action frame at p2p_scan completion");
+ ret = p2p->cfg->send_action(p2p->cfg->cb_ctx,
+ p2p->after_scan_tx->freq,
+ p2p->after_scan_tx->dst,
+ p2p->after_scan_tx->src,
+ p2p->after_scan_tx->bssid,
+ (u8 *) (p2p->after_scan_tx + 1),
+ p2p->after_scan_tx->len,
+ p2p->after_scan_tx->wait_time);
+ os_free(p2p->after_scan_tx);
+ p2p->after_scan_tx = NULL;
+ return 1;
+ }
+
op = p2p->start_after_scan;
p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
switch (op) {
os_free(p2p->cfg->dev_name);
os_free(p2p->groups);
wpabuf_free(p2p->sd_resp);
+ os_free(p2p->after_scan_tx);
os_free(p2p);
}
return -1;
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, go_interface_addr,
- own_interface_addr,
- go_interface_addr,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
- {
+ if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr,
+ go_interface_addr,
+ wpabuf_head(req), wpabuf_len(req), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
return;
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq, sa, da, da,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0) {
+ if (p2p_send_action(p2p, rx_freq, sa, da, da,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list");
os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels));
}
+
+
+int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid, const u8 *buf,
+ size_t len, unsigned int wait_time)
+{
+ if (p2p->p2p_scan_running) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action "
+ "frame TX until p2p_scan completes");
+ if (p2p->after_scan_tx) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
+ "previous pending Action frame TX");
+ os_free(p2p->after_scan_tx);
+ }
+ p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) +
+ len);
+ if (p2p->after_scan_tx == NULL)
+ return -1;
+ p2p->after_scan_tx->freq = freq;
+ os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN);
+ os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN);
+ os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN);
+ p2p->after_scan_tx->len = len;
+ p2p->after_scan_tx->wait_time = wait_time;
+ os_memcpy(p2p->after_scan_tx + 1, buf, len);
+ return 0;
+ }
+
+ return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
+ buf, len, wait_time);
+}
os_memcpy(p2p->pending_client_disc_addr, dev->p2p_device_addr,
ETH_ALEN);
p2p->pending_action_state = P2P_PENDING_DEV_DISC_REQUEST;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, dev->oper_freq,
- go->p2p_device_addr, p2p->cfg->dev_addr,
- go->p2p_device_addr,
- wpabuf_head(req), wpabuf_len(req), 1000) < 0)
- {
+ if (p2p_send_action(p2p, dev->oper_freq, go->p2p_device_addr,
+ p2p->cfg->dev_addr, go->p2p_device_addr,
+ wpabuf_head(req), wpabuf_len(req), 1000) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
wpabuf_free(req);
MAC2STR(addr), status, freq);
p2p->pending_action_state = P2P_PENDING_DEV_DISC_RESPONSE;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, addr,
- p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0) {
+ if (p2p_send_action(p2p, freq, addr, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST;
p2p->go_neg_peer = dev;
dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dev->p2p_device_addr, p2p->cfg->dev_addr,
- dev->p2p_device_addr,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
- {
+ if (p2p_send_action(p2p, freq, dev->p2p_device_addr,
+ p2p->cfg->dev_addr, dev->p2p_device_addr,
+ wpabuf_head(req), wpabuf_len(req), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
/* Use P2P find to recover and retry */
} else
p2p->pending_action_state =
P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
- p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0) {
+ if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
freq = rx_freq;
else
freq = dev->listen_freq;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
- p2p->cfg->dev_addr, sa,
- wpabuf_head(conf), wpabuf_len(conf), 200) <
- 0) {
+ if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
+ wpabuf_head(conf), wpabuf_len(conf), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
p2p_go_neg_failed(p2p, dev, -1);
struct wpabuf *tlvs;
};
+struct p2p_pending_action_tx {
+ unsigned int freq;
+ u8 dst[ETH_ALEN];
+ u8 src[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ size_t len;
+ unsigned int wait_time;
+ /* Followed by len octets of the frame */
+};
+
/**
* struct p2p_data - P2P module data (internal to P2P module)
*/
P2P_AFTER_SCAN_CONNECT
} start_after_scan;
u8 after_scan_peer[ETH_ALEN];
+ struct p2p_pending_action_tx *after_scan_tx;
struct p2p_group **groups;
size_t num_groups;
size_t num_req_dev_type);
struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p);
void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len);
+int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid, const u8 *buf,
+ size_t len, unsigned int wait_time);
#endif /* P2P_I_H */
p2p->inv_op_freq = op_freq;
p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
- p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0) {
+ if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST;
p2p->invite_peer = dev;
dev->invitation_reqs++;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dev->p2p_device_addr, p2p->cfg->dev_addr,
- dev->p2p_device_addr,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
- {
+ if (p2p_send_action(p2p, freq, dev->p2p_device_addr,
+ p2p->cfg->dev_addr, dev->p2p_device_addr,
+ wpabuf_head(req), wpabuf_len(req), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
/* Use P2P find to recover and retry */
return;
}
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
- p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0) {
+ if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
return -1;
p2p->pending_action_state = P2P_PENDING_PD;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dev->p2p_device_addr, p2p->cfg->dev_addr,
- dev->p2p_device_addr,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
- {
+ if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr,
+ p2p->cfg->dev_addr, dev->p2p_device_addr,
+ wpabuf_head(req), wpabuf_len(req), 200) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
wpabuf_free(req);
return;
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dst, p2p->cfg->dev_addr, dst,
- wpabuf_head(req), wpabuf_len(req), 200) < 0)
+ if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, dst,
+ wpabuf_head(req), wpabuf_len(req), 200) < 0)
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
p2p->sd_query = query;
p2p->pending_action_state = P2P_PENDING_SD;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dev->p2p_device_addr, p2p->cfg->dev_addr,
- dev->p2p_device_addr,
- wpabuf_head(req), wpabuf_len(req), 5000) < 0)
- {
+ if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr,
+ p2p->cfg->dev_addr, dev->p2p_device_addr,
+ wpabuf_head(req), wpabuf_len(req), 5000) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
ret = -1;
return;
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
- dst, p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0)
+ if (p2p_send_action(p2p->cfg->cb_ctx, freq, dst, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
- if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq,
- sa, p2p->cfg->dev_addr, p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) <
- 0)
+ if (p2p_send_action(p2p, rx_freq, sa, p2p->cfg->dev_addr,
+ p2p->cfg->dev_addr,
+ wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");