[PATCH v2 05/14] P2P: Cleanup of provision discovery req and resp processing
Shivani Baranwal
quic_shivbara at quicinc.com
Thu Jul 18 21:39:57 PDT 2024
Parse the p2p ies in handle provision discovery req and response
functions and process the frames based on the ies received in the
pd frames.
Signed-off-by: Shivani Baranwal <quic_shivbara at quicinc.com>
---
src/p2p/p2p.c | 4 +-
src/p2p/p2p_i.h | 8 +-
src/p2p/p2p_pd.c | 355 ++++++++++++++++++++++++++++---------------------------
3 files changed, 187 insertions(+), 180 deletions(-)
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index aa6e8ed..0a5c35f 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1925,10 +1925,10 @@ static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa,
p2p_process_invitation_resp(p2p, sa, data + 1, len - 1);
break;
case P2P_PROV_DISC_REQ:
- p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
+ p2p_handle_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
break;
case P2P_PROV_DISC_RESP:
- p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1);
+ p2p_handle_prov_disc_resp(p2p, sa, data + 1, len - 1);
break;
case P2P_DEV_DISC_REQ:
p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 787e599..2b10877 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -884,10 +884,10 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go,
struct p2p_device *dev, struct p2p_message *msg);
/* p2p_pd.c */
-void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
- const u8 *data, size_t len, int rx_freq);
-void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
- const u8 *data, size_t len);
+void p2p_handle_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
+ const u8 *data, size_t len, int rx_freq);
+void p2p_handle_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
+ const u8 *data, size_t len);
int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
int join, int force_freq);
void p2p_reset_pending_pd(struct p2p_data *p2p);
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index 7f9ee08..23bba08 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -600,10 +600,10 @@ void p2p_process_pcea(struct p2p_data *p2p, struct p2p_message *msg,
}
-void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
- const u8 *data, size_t len, int rx_freq)
+static void p2p_process_prov_disc_req(struct p2p_data *p2p,
+ struct p2p_message *msg, const u8 *sa,
+ const u8 *data, size_t len, int rx_freq)
{
- struct p2p_message msg;
struct p2p_device *dev;
int freq;
enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
@@ -624,13 +624,10 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
u8 remote_conncap;
u16 method;
- if (p2p_parse(data, len, &msg))
- return;
-
p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
" with config methods 0x%x (freq=%d)",
- MAC2STR(sa), msg.wps_config_methods, rx_freq);
- group_mac = msg.intended_addr;
+ MAC2STR(sa), msg->wps_config_methods, rx_freq);
+ group_mac = msg->intended_addr;
dev = p2p_get_device(p2p, sa);
if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
@@ -651,29 +648,29 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
MACSTR, MAC2STR(sa));
goto out;
}
- } else if (msg.wfd_subelems) {
+ } else if (msg->wfd_subelems) {
wpabuf_free(dev->info.wfd_subelems);
- dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
+ dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems);
}
- p2p_update_peer_6ghz_capab(dev, &msg);
+ p2p_update_peer_6ghz_capab(dev, msg);
- if (!msg.adv_id) {
+ if (!msg->adv_id) {
allowed_config_methods |= WPS_CONFIG_PUSHBUTTON;
- if (!(msg.wps_config_methods & allowed_config_methods)) {
+ if (!(msg->wps_config_methods & allowed_config_methods)) {
p2p_dbg(p2p,
"Unsupported Config Methods in Provision Discovery Request");
goto out;
}
/* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
- if (msg.group_id) {
+ if (msg->group_id) {
size_t i;
for (i = 0; i < p2p->num_groups; i++) {
if (p2p_group_is_group_id_match(
p2p->groups[i],
- msg.group_id, msg.group_id_len))
+ msg->group_id, msg->group_id_len))
break;
}
if (i == p2p->num_groups) {
@@ -689,29 +686,29 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
* Set adv_id here, so in case of an error, a P2PS PD Response
* will be sent.
*/
- adv_id = WPA_GET_LE32(msg.adv_id);
- if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) {
+ adv_id = WPA_GET_LE32(msg->adv_id);
+ if (p2ps_validate_pd_req(p2p, msg, sa) < 0) {
reject = P2P_SC_FAIL_INVALID_PARAMS;
goto out;
}
- req_fcap = (struct p2ps_feature_capab *) msg.feature_cap;
+ req_fcap = (struct p2ps_feature_capab *) msg->feature_cap;
- os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
- os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
+ os_memcpy(session_mac, msg->session_mac, ETH_ALEN);
+ os_memcpy(adv_mac, msg->adv_mac, ETH_ALEN);
- session_id = WPA_GET_LE32(msg.session_id);
+ session_id = WPA_GET_LE32(msg->session_id);
- if (msg.conn_cap)
- conncap = *msg.conn_cap;
+ if (msg->conn_cap)
+ conncap = *msg->conn_cap;
/*
* We need to verify a P2PS config methog in an initial PD
* request or in a follow-on PD request with the status
* SUCCESS_DEFERRED.
*/
- if ((!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) &&
- !(msg.wps_config_methods & allowed_config_methods)) {
+ if ((!msg->status || *msg->status == P2P_SC_SUCCESS_DEFERRED) &&
+ !(msg->wps_config_methods & allowed_config_methods)) {
p2p_dbg(p2p,
"Unsupported Config Methods in Provision Discovery Request");
goto out;
@@ -727,18 +724,18 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
P2P_DEV_PD_PEER_KEYPAD |
P2P_DEV_PD_PEER_P2PS);
- if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
+ if (msg->wps_config_methods & WPS_CONFIG_DISPLAY) {
p2p_dbg(p2p, "Peer " MACSTR
" requested us to show a PIN on display", MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
passwd_id = DEV_PW_USER_SPECIFIED;
- } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
+ } else if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) {
p2p_dbg(p2p, "Peer " MACSTR
" requested us to write its PIN using keypad",
MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
- } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
+ } else if (msg->wps_config_methods & WPS_CONFIG_P2PS) {
p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_P2PS;
@@ -749,8 +746,8 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
if (p2p->cfg->remove_stale_groups) {
p2p->cfg->remove_stale_groups(
p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
- msg.persistent_dev,
- msg.persistent_ssid, msg.persistent_ssid_len);
+ msg->persistent_dev,
+ msg->persistent_ssid, msg->persistent_ssid_len);
}
reject = P2P_SC_SUCCESS;
@@ -759,15 +756,15 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
* End of a legacy P2P PD Request processing, from this point continue
* with P2PS one.
*/
- if (!msg.adv_id)
+ if (!msg->adv_id)
goto out;
remote_conncap = conncap;
- if (!msg.status) {
+ if (!msg->status) {
unsigned int forced_freq, pref_freq;
- if (!ether_addr_equal(p2p->cfg->dev_addr, msg.adv_mac)) {
+ if (!ether_addr_equal(p2p->cfg->dev_addr, msg->adv_mac)) {
p2p_dbg(p2p,
"P2PS PD adv mac does not match the local one");
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
@@ -804,12 +801,12 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
"Incompatible P2PS feature capability CPT bitmask");
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
} else if (p2ps_adv->config_methods &&
- !(msg.wps_config_methods &
+ !(msg->wps_config_methods &
p2ps_adv->config_methods)) {
p2p_dbg(p2p,
"Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
p2ps_adv->config_methods,
- msg.wps_config_methods);
+ msg->wps_config_methods);
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
} else if (!p2ps_adv->state) {
p2p_dbg(p2p, "P2PS state unavailable");
@@ -819,24 +816,24 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
}
- if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
+ if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) {
p2p_dbg(p2p, "Keypad - always defer");
auto_accept = 0;
}
if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
- msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
- msg.channel_list && msg.channel_list_len &&
+ msg->persistent_dev) && conncap != P2PS_SETUP_NEW &&
+ msg->channel_list && msg->channel_list_len &&
p2p_peer_channels_check(p2p, &p2p->channels, dev,
- msg.channel_list,
- msg.channel_list_len) < 0) {
+ msg->channel_list,
+ msg->channel_list_len) < 0) {
p2p_dbg(p2p,
"No common channels - force deferred flow");
auto_accept = 0;
}
if (((remote_conncap & P2PS_SETUP_GROUP_OWNER) ||
- msg.persistent_dev) && msg.operating_channel) {
+ msg->persistent_dev) && msg->operating_channel) {
struct p2p_channels intersect;
/*
@@ -847,15 +844,15 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
*/
if (dev->channels.reg_classes == 0 ||
!p2p_channels_includes(&dev->channels,
- msg.operating_channel[3],
- msg.operating_channel[4])) {
+ msg->operating_channel[3],
+ msg->operating_channel[4])) {
struct p2p_channels *ch = &dev->channels;
os_memset(ch, 0, sizeof(*ch));
ch->reg_class[0].reg_class =
- msg.operating_channel[3];
+ msg->operating_channel[3];
ch->reg_class[0].channel[0] =
- msg.operating_channel[4];
+ msg->operating_channel[4];
ch->reg_class[0].channels = 1;
ch->reg_classes = 1;
}
@@ -874,7 +871,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
struct p2ps_provision *tmp;
if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
- msg.wps_config_methods,
+ msg->wps_config_methods,
session_mac, adv_mac) < 0) {
reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
goto out;
@@ -896,7 +893,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
}
}
- if (!msg.status && !auto_accept &&
+ if (!msg->status && !auto_accept &&
(!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
struct p2ps_provision *tmp;
@@ -906,7 +903,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
}
if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
- msg.wps_config_methods,
+ msg->wps_config_methods,
session_mac, adv_mac) < 0) {
reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
goto out;
@@ -917,26 +914,26 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
}
/* Not a P2PS Follow-on PD */
- if (!msg.status)
+ if (!msg->status)
goto out;
- if (*msg.status && *msg.status != P2P_SC_SUCCESS_DEFERRED) {
- reject = *msg.status;
+ if (*msg->status && *msg->status != P2P_SC_SUCCESS_DEFERRED) {
+ reject = *msg->status;
goto out;
}
- if (*msg.status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov)
+ if (*msg->status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov)
goto out;
if (p2p->p2ps_prov->adv_id != adv_id ||
- !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg.adv_mac)) {
+ !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg->adv_mac)) {
p2p_dbg(p2p,
"P2PS Follow-on PD with mismatch Advertisement ID/MAC");
goto out;
}
if (p2p->p2ps_prov->session_id != session_id ||
- !ether_addr_equal(p2p->p2ps_prov->session_mac, msg.session_mac)) {
+ !ether_addr_equal(p2p->p2ps_prov->session_mac, msg->session_mac)) {
p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Session ID/MAC");
goto out;
}
@@ -967,7 +964,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
else if (method & WPS_CONFIG_KEYPAD)
method = WPS_CONFIG_DISPLAY;
- if (!conncap || !(msg.wps_config_methods & method)) {
+ if (!conncap || !(msg->wps_config_methods & method)) {
/*
* Reject this "Deferred Accept*
* if incompatible conncap or method
@@ -978,11 +975,11 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
"Incompatible P2PS feature capability CPT bitmask");
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
} else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
- msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
- msg.channel_list && msg.channel_list_len &&
+ msg->persistent_dev) && conncap != P2PS_SETUP_NEW &&
+ msg->channel_list && msg->channel_list_len &&
p2p_peer_channels_check(p2p, &p2p->channels, dev,
- msg.channel_list,
- msg.channel_list_len) < 0) {
+ msg->channel_list,
+ msg->channel_list_len) < 0) {
p2p_dbg(p2p,
"No common channels in Follow-On Provision Discovery Request");
reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
@@ -994,10 +991,10 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
if (reject == P2P_SC_SUCCESS || reject == P2P_SC_SUCCESS_DEFERRED) {
u8 tmp;
- if (msg.operating_channel)
+ if (msg->operating_channel)
dev->oper_freq =
- p2p_channel_to_freq(msg.operating_channel[3],
- msg.operating_channel[4]);
+ p2p_channel_to_freq(msg->operating_channel[3],
+ msg->operating_channel[4]);
if ((conncap & P2PS_SETUP_GROUP_OWNER) &&
p2p_go_select_channel(p2p, dev, &tmp) < 0)
@@ -1010,7 +1007,7 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
out:
if (reject == P2P_SC_SUCCESS ||
reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
- config_methods = msg.wps_config_methods;
+ config_methods = msg->wps_config_methods;
else
config_methods = 0;
@@ -1018,18 +1015,17 @@ out:
* Send PD Response for an initial PD Request or for follow-on
* PD Request with P2P_SC_SUCCESS_DEFERRED status.
*/
- if (!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) {
- resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token,
+ if (!msg->status || *msg->status == P2P_SC_SUCCESS_DEFERRED) {
+ resp = p2p_build_prov_disc_resp(p2p, dev, msg->dialog_token,
reject, config_methods, adv_id,
- msg.group_id, msg.group_id_len,
- msg.persistent_ssid,
- msg.persistent_ssid_len,
+ msg->group_id, msg->group_id_len,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len,
(const u8 *) &resp_fcap,
sizeof(resp_fcap));
- if (!resp) {
- p2p_parse_free(&msg);
+ if (!resp)
return;
- }
+
p2p_dbg(p2p, "Sending Provision Discovery Response");
if (rx_freq > 0)
freq = rx_freq;
@@ -1039,7 +1035,6 @@ out:
if (freq < 0) {
p2p_dbg(p2p, "Unknown regulatory class/channel");
wpabuf_free(resp);
- p2p_parse_free(&msg);
return;
}
p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
@@ -1054,10 +1049,8 @@ out:
wpabuf_free(resp);
}
- if (!dev) {
- p2p_parse_free(&msg);
+ if (!dev)
return;
- }
freq = 0;
if (reject == P2P_SC_SUCCESS && conncap == P2PS_SETUP_GROUP_OWNER) {
@@ -1069,17 +1062,17 @@ out:
if (!p2p->cfg->p2ps_prov_complete) {
/* Don't emit anything */
- } else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
- *msg.status != P2P_SC_SUCCESS_DEFERRED) {
- reject = *msg.status;
+ } else if (msg->status && *msg->status != P2P_SC_SUCCESS &&
+ *msg->status != P2P_SC_SUCCESS_DEFERRED) {
+ reject = *msg->status;
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
sa, adv_mac, session_mac,
NULL, adv_id, session_id,
- 0, 0, msg.persistent_ssid,
- msg.persistent_ssid_len,
+ 0, 0, msg->persistent_ssid,
+ msg->persistent_ssid_len,
0, 0, NULL, NULL, 0, freq,
NULL, 0);
- } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
+ } else if (msg->status && *msg->status == P2P_SC_SUCCESS_DEFERRED &&
p2p->p2ps_prov) {
p2p->p2ps_prov->status = reject;
p2p->p2ps_prov->conncap = conncap;
@@ -1089,77 +1082,77 @@ out:
sa, adv_mac, session_mac,
NULL, adv_id,
session_id, conncap, 0,
- msg.persistent_ssid,
- msg.persistent_ssid_len, 0,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len, 0,
0, NULL, NULL, 0, freq,
NULL, 0);
else
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
- *msg.status,
+ *msg->status,
sa, adv_mac, session_mac,
group_mac, adv_id,
session_id, conncap,
passwd_id,
- msg.persistent_ssid,
- msg.persistent_ssid_len, 0,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len, 0,
0, NULL,
(const u8 *) &resp_fcap,
sizeof(resp_fcap), freq,
NULL, 0);
- } else if (msg.status && p2p->p2ps_prov) {
+ } else if (msg->status && p2p->p2ps_prov) {
p2p->p2ps_prov->status = P2P_SC_SUCCESS;
- p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
+ p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg->status, sa,
adv_mac, session_mac, group_mac,
adv_id, session_id, conncap,
passwd_id,
- msg.persistent_ssid,
- msg.persistent_ssid_len,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len,
0, 0, NULL,
(const u8 *) &resp_fcap,
sizeof(resp_fcap), freq, NULL, 0);
- } else if (msg.status) {
+ } else if (msg->status) {
} else if (auto_accept && reject == P2P_SC_SUCCESS) {
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
sa, adv_mac, session_mac,
group_mac, adv_id, session_id,
conncap, passwd_id,
- msg.persistent_ssid,
- msg.persistent_ssid_len,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len,
0, 0, NULL,
(const u8 *) &resp_fcap,
sizeof(resp_fcap), freq,
- msg.group_id ?
- msg.group_id + ETH_ALEN : NULL,
- msg.group_id ?
- msg.group_id_len - ETH_ALEN : 0);
+ msg->group_id ?
+ msg->group_id + ETH_ALEN : NULL,
+ msg->group_id ?
+ msg->group_id_len - ETH_ALEN : 0);
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
- (!msg.session_info || !msg.session_info_len)) {
- p2p->p2ps_prov->method = msg.wps_config_methods;
+ (!msg->session_info || !msg->session_info_len)) {
+ p2p->p2ps_prov->method = msg->wps_config_methods;
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
sa, adv_mac, session_mac,
group_mac, adv_id, session_id,
conncap, passwd_id,
- msg.persistent_ssid,
- msg.persistent_ssid_len,
+ msg->persistent_ssid,
+ msg->persistent_ssid_len,
0, 1, NULL,
(const u8 *) &resp_fcap,
sizeof(resp_fcap), freq, NULL, 0);
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
- size_t buf_len = msg.session_info_len;
+ size_t buf_len = msg->session_info_len;
char *buf = os_malloc(2 * buf_len + 1);
if (buf) {
- p2p->p2ps_prov->method = msg.wps_config_methods;
+ p2p->p2ps_prov->method = msg->wps_config_methods;
- utf8_escape((char *) msg.session_info, buf_len,
+ utf8_escape((char *) msg->session_info, buf_len,
buf, 2 * buf_len + 1);
p2p->cfg->p2ps_prov_complete(
p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
adv_mac, session_mac, group_mac, adv_id,
session_id, conncap, passwd_id,
- msg.persistent_ssid, msg.persistent_ssid_len,
+ msg->persistent_ssid, msg->persistent_ssid_len,
0, 1, buf,
(const u8 *) &resp_fcap, sizeof(resp_fcap),
freq, NULL, 0);
@@ -1187,29 +1180,29 @@ out:
* seeker: KEYPAD, response status: SUCCESS
*/
if (p2p->cfg->prov_disc_req &&
- ((reject == P2P_SC_SUCCESS && !msg.adv_id) ||
- (!msg.status &&
+ ((reject == P2P_SC_SUCCESS && !msg->adv_id) ||
+ (!msg->status &&
(reject == P2P_SC_SUCCESS ||
reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) &&
passwd_id == DEV_PW_USER_SPECIFIED) ||
- (!msg.status &&
+ (!msg->status &&
reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
(reject == P2P_SC_SUCCESS &&
- msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
+ msg->status && *msg->status == P2P_SC_SUCCESS_DEFERRED &&
passwd_id == DEV_PW_REGISTRAR_SPECIFIED))) {
const u8 *dev_addr = sa;
- if (msg.p2p_device_addr)
- dev_addr = msg.p2p_device_addr;
+ if (msg->p2p_device_addr)
+ dev_addr = msg->p2p_device_addr;
p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
- msg.wps_config_methods,
- dev_addr, msg.pri_dev_type,
- msg.device_name, msg.config_methods,
- msg.capability ? msg.capability[0] : 0,
- msg.capability ? msg.capability[1] :
+ msg->wps_config_methods,
+ dev_addr, msg->pri_dev_type,
+ msg->device_name, msg->config_methods,
+ msg->capability ? msg->capability[0] : 0,
+ msg->capability ? msg->capability[1] :
0,
- msg.group_id, msg.group_id_len);
+ msg->group_id, msg->group_id_len);
}
if (reject != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
@@ -1234,10 +1227,22 @@ out:
break;
}
- if (msg.intended_addr)
- os_memcpy(dev->interface_addr, msg.intended_addr,
+ if (msg->intended_addr)
+ os_memcpy(dev->interface_addr, msg->intended_addr,
ETH_ALEN);
}
+}
+
+
+void p2p_handle_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
+ const u8 *data, size_t len, int rx_freq)
+{
+ struct p2p_message msg;
+
+ if (p2p_parse(data, len, &msg))
+ return;
+
+ p2p_process_prov_disc_req(p2p, &msg, sa, data + 1, len - 1, rx_freq);
p2p_parse_free(&msg);
}
@@ -1340,10 +1345,10 @@ static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p,
}
-void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
- const u8 *data, size_t len)
+static void p2p_process_prov_disc_resp(struct p2p_data *p2p,
+ struct p2p_message *msg, const u8 *sa,
+ const u8 *data, size_t len)
{
- struct p2p_message msg;
struct p2p_device *dev;
u16 report_config_methods = 0, req_config_methods;
u8 status = P2P_SC_SUCCESS;
@@ -1354,30 +1359,26 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
int passwd_id = DEV_PW_DEFAULT;
int p2ps_seeker;
- if (p2p_parse(data, len, &msg))
- return;
-
- if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
- p2p_parse_free(&msg);
+ if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, msg)) {
return;
}
/* Parse the P2PS members present */
- if (msg.status)
- status = *msg.status;
+ if (msg->status)
+ status = *msg->status;
- group_mac = msg.intended_addr;
+ group_mac = msg->intended_addr;
- if (msg.adv_mac)
- os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
+ if (msg->adv_mac)
+ os_memcpy(adv_mac, msg->adv_mac, ETH_ALEN);
else
os_memset(adv_mac, 0, ETH_ALEN);
- if (msg.adv_id)
- adv_id = WPA_GET_LE32(msg.adv_id);
+ if (msg->adv_id)
+ adv_id = WPA_GET_LE32(msg->adv_id);
- if (msg.conn_cap) {
- conncap = *msg.conn_cap;
+ if (msg->conn_cap) {
+ conncap = *msg->conn_cap;
/* Switch bits to local relative */
switch (conncap) {
@@ -1392,25 +1393,23 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
" with config methods 0x%x",
- MAC2STR(sa), msg.wps_config_methods);
+ MAC2STR(sa), msg->wps_config_methods);
dev = p2p_get_device(p2p, sa);
if (dev == NULL || !dev->req_config_methods) {
p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
" with no pending request", MAC2STR(sa));
- p2p_parse_free(&msg);
return;
- } else if (msg.wfd_subelems) {
+ } else if (msg->wfd_subelems) {
wpabuf_free(dev->info.wfd_subelems);
- dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
+ dev->info.wfd_subelems = wpabuf_dup(msg->wfd_subelems);
}
- p2p_update_peer_6ghz_capab(dev, &msg);
+ p2p_update_peer_6ghz_capab(dev, msg);
- if (dev->dialog_token != msg.dialog_token) {
+ if (dev->dialog_token != msg->dialog_token) {
p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
- msg.dialog_token, dev->dialog_token);
- p2p_parse_free(&msg);
+ msg->dialog_token, dev->dialog_token);
return;
}
@@ -1435,14 +1434,13 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
ether_addr_equal(p2p->pending_pd_devaddr, sa))
p2p_reset_pending_pd(p2p);
- if (msg.wps_config_methods != req_config_methods) {
+ if (msg->wps_config_methods != req_config_methods) {
p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
- msg.wps_config_methods, req_config_methods);
+ msg->wps_config_methods, req_config_methods);
if (p2p->cfg->prov_disc_fail)
p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
P2P_PROV_DISC_REJECTED,
adv_id, adv_mac, NULL);
- p2p_parse_free(&msg);
p2ps_prov_free(p2p);
goto out;
}
@@ -1456,13 +1454,13 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
" accepted to show a PIN on display", MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
- } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
+ } else if (msg->wps_config_methods & WPS_CONFIG_KEYPAD) {
p2p_dbg(p2p, "Peer " MACSTR
" accepted to write our PIN using keypad",
MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
passwd_id = DEV_PW_USER_SPECIFIED;
- } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
+ } else if (msg->wps_config_methods & WPS_CONFIG_P2PS) {
p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
MAC2STR(sa));
dev->flags |= P2P_DEV_PD_PEER_P2PS;
@@ -1481,23 +1479,23 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
* fails the flow would continue, although it would probably
* fail. Same is true for the operating channel.
*/
- if (msg.channel_list && msg.channel_list_len &&
+ if (msg->channel_list && msg->channel_list_len &&
p2p_peer_channels_check(p2p, &p2p->channels, dev,
- msg.channel_list,
- msg.channel_list_len) < 0)
+ msg->channel_list,
+ msg->channel_list_len) < 0)
p2p_dbg(p2p, "P2PS PD Response - no common channels");
- if (msg.operating_channel) {
+ if (msg->operating_channel) {
if (p2p_channels_includes(&p2p->channels,
- msg.operating_channel[3],
- msg.operating_channel[4]) &&
+ msg->operating_channel[3],
+ msg->operating_channel[4]) &&
p2p_channels_includes(&dev->channels,
- msg.operating_channel[3],
- msg.operating_channel[4])) {
+ msg->operating_channel[3],
+ msg->operating_channel[4])) {
dev->oper_freq =
p2p_channel_to_freq(
- msg.operating_channel[3],
- msg.operating_channel[4]);
+ msg->operating_channel[3],
+ msg->operating_channel[4]);
} else {
p2p_dbg(p2p,
"P2PS PD Response - invalid operating channel");
@@ -1529,11 +1527,11 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
p2p->cfg->cb_ctx, status, sa, adv_mac,
p2p->p2ps_prov->session_mac,
group_mac, adv_id, p2p->p2ps_prov->session_id,
- conncap, passwd_id, msg.persistent_ssid,
- msg.persistent_ssid_len, 1, 0, NULL,
- msg.feature_cap, msg.feature_cap_len, freq,
- msg.group_id ? msg.group_id + ETH_ALEN : NULL,
- msg.group_id ? msg.group_id_len - ETH_ALEN : 0);
+ conncap, passwd_id, msg->persistent_ssid,
+ msg->persistent_ssid_len, 1, 0, NULL,
+ msg->feature_cap, msg->feature_cap_len, freq,
+ msg->group_id ? msg->group_id + ETH_ALEN : NULL,
+ msg->group_id ? msg->group_id_len - ETH_ALEN : 0);
}
p2ps_prov_free(p2p);
} else if (status != P2P_SC_SUCCESS &&
@@ -1555,16 +1553,15 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
NULL, NULL, 0);
}
- if (msg.session_info && msg.session_info_len) {
- size_t info_len = msg.session_info_len;
+ if (msg->session_info && msg->session_info_len) {
+ size_t info_len = msg->session_info_len;
char *deferred_sess_resp = os_malloc(2 * info_len + 1);
if (!deferred_sess_resp) {
- p2p_parse_free(&msg);
p2ps_prov_free(p2p);
goto out;
}
- utf8_escape((char *) msg.session_info, info_len,
+ utf8_escape((char *) msg->session_info, info_len,
deferred_sess_resp, 2 * info_len + 1);
if (p2p->cfg->prov_disc_fail)
@@ -1586,17 +1583,14 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
P2P_PROV_DISC_REJECTED,
adv_id, adv_mac, NULL);
- p2p_parse_free(&msg);
p2ps_prov_free(p2p);
goto out;
}
/* Store the provisioning info */
- dev->wps_prov_info = msg.wps_config_methods;
- if (msg.intended_addr)
- os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN);
-
- p2p_parse_free(&msg);
+ dev->wps_prov_info = msg->wps_config_methods;
+ if (msg->intended_addr)
+ os_memcpy(dev->interface_addr, msg->intended_addr, ETH_ALEN);
out:
dev->req_config_methods = 0;
@@ -1640,6 +1634,19 @@ out:
}
+void p2p_handle_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
+ const u8 *data, size_t len)
+{
+ struct p2p_message msg;
+
+ if (p2p_parse(data, len, &msg))
+ return;
+
+ p2p_process_prov_disc_resp(p2p, &msg, sa, data + 1, len - 1);
+ p2p_parse_free(&msg);
+}
+
+
int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
int join, int force_freq)
{
--
2.7.4
More information about the Hostap
mailing list