diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 3e6fba5bd..56d38a5fd 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -157,6 +157,11 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, elems->rsn_selection = pos + 4; elems->rsn_selection_len = elen - 4; break; + case P2P2_OUI_TYPE: + /* Wi-Fi Alliance - P2P2 IE */ + elems->p2p2_ie = pos; + elems->p2p2_ie_len = elen; + break; default: wpa_printf(MSG_MSGDUMP, "Unknown WFA " "information element ignored " diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index d4c691e1b..e4321b5c5 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -65,6 +65,7 @@ struct ieee802_11_elems { const u8 *vendor_ht_cap; const u8 *vendor_vht; const u8 *p2p; + const u8 *p2p2_ie; const u8 *wfd; const u8 *link_id; const u8 *interworking; @@ -139,6 +140,7 @@ struct ieee802_11_elems { u8 vendor_ht_cap_len; u8 vendor_vht_len; u8 p2p_len; + u8 p2p2_ie_len; u8 wfd_len; u8 interworking_len; u8 qos_map_set_len; diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 3da75582f..7c155a05e 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -596,6 +596,7 @@ struct p2p_data { */ struct p2p_message { struct wpabuf *p2p_attributes; + struct wpabuf *p2p2_attributes; struct wpabuf *wps_attributes; struct wpabuf *wfd_subelems; @@ -694,6 +695,12 @@ struct p2p_message { const u8 *pref_freq_list; size_t pref_freq_list_len; + + const u8 *pcea_info; + size_t pcea_info_len; + + const u8 *pbma_info; + size_t pbma_info_len; }; diff --git a/src/p2p/p2p_parse.c b/src/p2p/p2p_parse.c index 07d6ca022..a70e18079 100644 --- a/src/p2p/p2p_parse.c +++ b/src/p2p/p2p_parse.c @@ -417,6 +417,26 @@ static int p2p_parse_attribute(u8 id, const u8 *data, u16 len, msg->persistent_ssid_len)); break; } + case P2P_ATTR_CAPABILITY_EXTENSION: + if (len < 2) { + wpa_printf(MSG_DEBUG, "P2P: Too short PCEA (length %d)", + len); + return -1; + } + msg->pcea_info = data; + msg->pcea_info_len = len; + wpa_printf(MSG_DEBUG, "P2P: * PCEA (length=%u)", len); + break; + case P2P_ATTR_PAIRING_AND_BOOTSTRAPPING: + if (len < 1) { + wpa_printf(MSG_DEBUG, "P2P: Too short PBMA (length %d)", + len); + return -1; + } + msg->pbma_info = data; + msg->pbma_info_len = len; + wpa_printf(MSG_DEBUG, "P2P: * PBMA (length=%u)", len); + break; default: wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " "(length %d)", id, len); @@ -573,6 +593,18 @@ int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) return -1; } + msg->p2p2_attributes = ieee802_11_vendor_ie_concat(data, len, + P2P2_IE_VENDOR_TYPE); + if (msg->p2p2_attributes && + p2p_parse_p2p_ie(msg->p2p2_attributes, msg)) { + wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P2 IE data"); + if (msg->p2p2_attributes) + wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P2 IE data", + msg->p2p2_attributes); + p2p_parse_free(msg); + return -1; + } + #ifdef CONFIG_WIFI_DISPLAY if (elems.wfd) { msg->wfd_subelems = ieee802_11_vendor_ie_concat( @@ -647,6 +679,8 @@ void p2p_parse_free(struct p2p_message *msg) { wpabuf_free(msg->p2p_attributes); msg->p2p_attributes = NULL; + wpabuf_free(msg->p2p2_attributes); + msg->p2p2_attributes = NULL; wpabuf_free(msg->wps_attributes); msg->wps_attributes = NULL; #ifdef CONFIG_WIFI_DISPLAY