Add wrapper functions to process and prepare response for go negotiation and invitation frames. Send the response action frames in handle_ functions. Signed-off-by: Shivani Baranwal <quic_shivbara@xxxxxxxxxxx> --- src/p2p/p2p.c | 9 ++- src/p2p/p2p_go_neg.c | 152 ++++++++++++++++++++++++++++++++--------------- src/p2p/p2p_i.h | 45 +++++++++++--- src/p2p/p2p_invitation.c | 61 +++++++++++-------- 4 files changed, 180 insertions(+), 87 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index a66f0c4..d61f769 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1927,17 +1927,16 @@ static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa, switch (data[0]) { case P2P_GO_NEG_REQ: - p2p_process_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); + p2p_handle_go_neg_req(p2p, sa, data + 1, len - 1, rx_freq); break; case P2P_GO_NEG_RESP: - p2p_process_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); + p2p_handle_go_neg_resp(p2p, sa, data + 1, len - 1, rx_freq); break; case P2P_GO_NEG_CONF: - p2p_process_go_neg_conf(p2p, sa, data + 1, len - 1); + p2p_handle_go_neg_conf(p2p, sa, data + 1, len - 1); break; case P2P_INVITATION_REQ: - p2p_process_invitation_req(p2p, sa, data + 1, len - 1, - rx_freq); + p2p_handle_invitation_req(p2p, sa, data + 1, len - 1, rx_freq); break; case P2P_INVITATION_RESP: p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 04e5139..0308216 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -801,21 +801,19 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go, } -void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq) +int p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq) { struct p2p_device *dev = NULL; - struct wpabuf *resp; struct p2p_message msg; u8 status = P2P_SC_FAIL_INVALID_PARAMS; int tie_breaker = 0; - int freq; p2p_dbg(p2p, "Received GO Negotiation Request from " MACSTR "(freq=%d)", MAC2STR(sa), rx_freq); if (p2p_parse(data, len, &msg)) - return; + return -1; if (!msg.capability) { p2p_dbg(p2p, "Mandatory Capability attribute missing from GO Negotiation Request"); @@ -890,7 +888,7 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, p2p->cfg->send_action_done(p2p->cfg->cb_ctx); p2p_go_neg_failed(p2p, *msg.status); p2p_parse_free(&msg); - return; + return -1; } goto fail; } @@ -968,7 +966,7 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) > 0) { p2p_dbg(p2p, "Do not reply since peer has higher address and GO Neg Request already sent"); p2p_parse_free(&msg); - return; + return -1; } if (dev->go_neg_req_sent && @@ -976,7 +974,7 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, p2p_dbg(p2p, "Do not reply since peer is waiting for us to start a new GO Negotiation and GO Neg Request already sent"); p2p_parse_free(&msg); - return; + return -1; } go = p2p_go_det(p2p->go_intent, *msg.go_intent); @@ -1086,7 +1084,10 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, p2p_set_state(p2p, P2P_GO_NEG); p2p_clear_timeout(p2p); dev->dialog_token = msg.dialog_token; - os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN); + if (!is_zero_ether_addr(msg.intended_addr)) { + p2p_dbg(p2p, "msg.intended_addr" MACSTR, MAC2STR(msg.intended_addr)); + os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN); + } p2p->go_neg_peer = dev; eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL); status = P2P_SC_SUCCESS; @@ -1095,22 +1096,13 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, fail: if (dev) dev->status = status; - resp = p2p_build_go_neg_resp(p2p, dev, msg.dialog_token, status, - !tie_breaker); + p2p->go_neg_resp = p2p_build_go_neg_resp(p2p, dev, msg.dialog_token, + status, !tie_breaker); + p2p_parse_free(&msg); - if (resp == NULL) - return; - p2p_dbg(p2p, "Sending GO Negotiation Response"); - if (rx_freq > 0) - freq = rx_freq; - else - freq = p2p_channel_to_freq(p2p->cfg->reg_class, - p2p->cfg->channel); - if (freq < 0) { - p2p_dbg(p2p, "Unknown regulatory class/channel"); - wpabuf_free(resp); - return; - } + if (!p2p->go_neg_resp) + return -1; + if (status == P2P_SC_SUCCESS) { p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE; dev->flags |= P2P_DEV_WAIT_GO_NEG_CONFIRM; @@ -1128,13 +1120,38 @@ fail: } else p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE_FAILURE; - if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, - p2p->cfg->dev_addr, - wpabuf_head(resp), wpabuf_len(resp), 100) < 0) { - p2p_dbg(p2p, "Failed to send Action frame"); + return 0; +} + +void p2p_handle_go_neg_req(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq) +{ + int freq; + + if (p2p_process_go_neg_req(p2p, sa, data, len, rx_freq)) + return; + + p2p_dbg(p2p, "Sending GO Negotiation Response"); + + if (rx_freq > 0) + freq = rx_freq; + else + freq = p2p_channel_to_freq(p2p->cfg->reg_class, + p2p->cfg->channel); + if (freq < 0) { + p2p_dbg(p2p, "Unknown regulatory class/channel"); + return; } - wpabuf_free(resp); + if (p2p->go_neg_resp && + p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, + p2p->cfg->dev_addr, wpabuf_head(p2p->go_neg_resp), + wpabuf_len(p2p->go_neg_resp), 100) < 0) { + p2p_dbg(p2p, "Failed to send Action frame"); + } + wpabuf_free(p2p->go_neg_resp); + p2p->go_neg_resp = NULL; + return; } @@ -1213,8 +1230,8 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, } -void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq) +int p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq) { struct p2p_device *dev; int go = -1; @@ -1229,16 +1246,16 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, dev != p2p->go_neg_peer) { p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR, MAC2STR(sa)); - return; + return -1; } if (p2p_parse(data, len, &msg)) - return; + return -1; if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_RESPONSE)) { p2p_dbg(p2p, "Was not expecting GO Negotiation Response - ignore"); p2p_parse_free(&msg); - return; + return -1; } dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; p2p_update_peer_6ghz_capab(dev, &msg); @@ -1247,7 +1264,7 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)", msg.dialog_token, dev->dialog_token); p2p_parse_free(&msg); - return; + return -1; } if (!msg.status) { @@ -1276,7 +1293,7 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, } p2p->cfg->send_action_done(p2p->cfg->cb_ctx); p2p_parse_free(&msg); - return; + return -1; } if (!msg.capability) { @@ -1446,7 +1463,10 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, p2p_clear_timeout(p2p); p2p_dbg(p2p, "GO Negotiation with " MACSTR, MAC2STR(sa)); - os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN); + if (!is_zero_ether_addr(msg.intended_addr)) { + p2p_dbg(p2p, "msg.intended_addr" MACSTR, MAC2STR(msg.intended_addr)); + os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN); + } fail: /* Store GO Negotiation Confirmation to allow retransmission */ @@ -1454,15 +1474,18 @@ fail: dev->go_neg_conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token, status, msg.operating_channel, go); - p2p_parse_free(&msg); if (dev->go_neg_conf == NULL) - return; - p2p_dbg(p2p, "Sending GO Negotiation Confirm"); + return -1; + + p2p->go_neg_conf = wpabuf_dup(dev->go_neg_conf); + p2p_parse_free(&msg); + if (status == P2P_SC_SUCCESS) { p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM; dev->go_state = go ? LOCAL_GO : REMOTE_GO; } else p2p->pending_action_state = P2P_NO_PENDING_ACTION; + if (rx_freq > 0) freq = rx_freq; else @@ -1471,7 +1494,39 @@ fail: dev->go_neg_conf_freq = freq; dev->go_neg_conf_sent = 0; - if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa, + if (status != P2P_SC_SUCCESS) { + p2p_dbg(p2p, "GO Negotiation failed"); + dev->status = status; + } + + return 0; +} + +void p2p_handle_go_neg_resp(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq) +{ + int freq; + struct p2p_device *dev; + + dev = p2p_get_device(p2p, sa); + if (dev == NULL || dev->wps_method == WPS_NOT_READY || + dev != p2p->go_neg_peer) { + p2p_dbg(p2p, "Not ready for GO negotiation with " MACSTR, + MAC2STR(sa)); + return; + } + + if (p2p_process_go_neg_resp(p2p, sa, data, len, rx_freq)) + return; + + p2p_dbg(p2p, "Sending GO Negotiation Confirm"); + if (rx_freq > 0) + freq = rx_freq; + else + freq = dev->listen_freq; + + if (dev->go_neg_conf && + p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa, wpabuf_head(dev->go_neg_conf), wpabuf_len(dev->go_neg_conf), 50) < 0) { p2p_dbg(p2p, "Failed to send Action frame"); @@ -1479,15 +1534,18 @@ fail: p2p->cfg->send_action_done(p2p->cfg->cb_ctx); } else dev->go_neg_conf_sent++; - if (status != P2P_SC_SUCCESS) { - p2p_dbg(p2p, "GO Negotiation failed"); - p2p_go_neg_failed(p2p, status); - } + + if (dev->status != P2P_SC_SUCCESS) + p2p_go_neg_failed(p2p, dev->status); + + wpabuf_free(p2p->go_neg_conf); + p2p->go_neg_conf = NULL; + return; } -void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len) +void p2p_handle_go_neg_conf(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len) { struct p2p_device *dev; struct p2p_message msg; diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index ef2bb9d..95bdd19 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -630,6 +630,25 @@ struct p2p_data { bool allow_6ghz; struct p2p_pairing_info *pairing_info; + /** + * go_neg_resp - GO Negotiation Response frame + */ + struct wpabuf *go_neg_resp; + + /** + * go_neg_conf - GO Negotiation Confirmation frame + */ + struct wpabuf *go_neg_conf; + + /** + * invitation_req - Invitation request frame + */ + struct wpabuf *invitation_req; + + /** + * invitation_resp - Invitation Response frame + */ + struct wpabuf *invitation_resp; }; /** @@ -901,12 +920,16 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev); int p2p_peer_channels_check(struct p2p_data *p2p, struct p2p_channels *own, struct p2p_device *dev, const u8 *channel_list, size_t channel_list_len); -void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq); -void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq); -void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len); +void p2p_handle_go_neg_req(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq); +void p2p_handle_go_neg_resp(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq); +void p2p_handle_go_neg_conf(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len); +int p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq); +int p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, const u8 *data, + size_t len, int rx_freq); 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, @@ -927,10 +950,14 @@ void p2p_process_pcea(struct p2p_data *p2p, struct p2p_message *msg, struct p2p_device *dev); /* p2p_invitation.c */ -void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq); +void p2p_handle_invitation_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq); +void p2p_handle_invitation_resp(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len); +int p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq); void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len); + const u8 *data, size_t len); int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev, const u8 *go_dev_addr, int dev_pw_id); void p2p_invitation_req_cb(struct p2p_data *p2p, int success); diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index 70a7f6f..8ade838 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -181,14 +181,12 @@ static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p, } -void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, - const u8 *data, size_t len, int rx_freq) +int p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq) { struct p2p_device *dev; struct p2p_message msg; - struct wpabuf *resp = NULL; u8 status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; - int freq; int go = 0; u8 group_bssid[ETH_ALEN], *bssid; int op_freq = 0; @@ -202,7 +200,7 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, MAC2STR(sa), rx_freq); if (p2p_parse(data, len, &msg)) - return; + return -1; dev = p2p_get_device(p2p, sa); if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { @@ -385,21 +383,11 @@ fail: bssid = group_bssid; else bssid = NULL; - resp = p2p_build_invitation_resp(p2p, dev, msg.dialog_token, status, - bssid, reg_class, channel, channels); - - if (resp == NULL) - goto out; - - if (rx_freq > 0) - freq = rx_freq; - else - freq = p2p_channel_to_freq(p2p->cfg->reg_class, - p2p->cfg->channel); - if (freq < 0) { - p2p_dbg(p2p, "Unknown regulatory class/channel"); - goto out; - } + p2p->invitation_resp = p2p_build_invitation_resp(p2p, dev, + msg.dialog_token, + status, bssid, + reg_class, channel, + channels); /* * Store copy of invitation data to be used when processing TX status @@ -424,17 +412,38 @@ fail: } p2p->inv_status = status; p2p->inv_op_freq = op_freq; + p2p_parse_free(&msg); + return 0; +} + + +void p2p_handle_invitation_req(struct p2p_data *p2p, const u8 *sa, + const u8 *data, size_t len, int rx_freq) +{ + int freq; + + if (p2p_process_invitation_req(p2p, sa, data, len, rx_freq)) + return; + + if (rx_freq > 0) + freq = rx_freq; + else + freq = p2p_channel_to_freq(p2p->cfg->reg_class, + p2p->cfg->channel); + if (freq < 0) + p2p_dbg(p2p, "Unknown regulatory class/channel"); p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE; - if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, + if (p2p->invitation_resp && + p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, p2p->cfg->dev_addr, - wpabuf_head(resp), wpabuf_len(resp), 50) < 0) { + wpabuf_head(p2p->invitation_resp), + wpabuf_len(p2p->invitation_resp), 50) < 0) p2p_dbg(p2p, "Failed to send Action frame"); - } -out: - wpabuf_free(resp); - p2p_parse_free(&msg); + wpabuf_free(p2p->invitation_resp); + p2p->invitation_resp = NULL; + return; } -- 2.7.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap