aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/p2p/p2p.c26
-rw-r--r--src/p2p/p2p.h9
-rw-r--r--wpa_supplicant/bss.c17
-rw-r--r--wpa_supplicant/bss.h2
-rw-r--r--wpa_supplicant/ctrl_iface.c7
5 files changed, 61 insertions, 0 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 2f4c114..e7ce230 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -2096,6 +2096,32 @@ int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end)
}
+int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr)
+{
+ struct wpabuf *p2p_ie;
+ struct p2p_message msg;
+
+ p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
+ P2P_IE_VENDOR_TYPE);
+ if (p2p_ie == NULL)
+ return -1;
+ os_memset(&msg, 0, sizeof(msg));
+ if (p2p_parse_p2p_ie(p2p_ie, &msg)) {
+ wpabuf_free(p2p_ie);
+ return -1;
+ }
+
+ if (msg.p2p_device_addr == NULL) {
+ wpabuf_free(p2p_ie);
+ return -1;
+ }
+
+ os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);
+ wpabuf_free(p2p_ie);
+ return 0;
+}
+
+
static void p2p_clear_go_neg(struct p2p_data *p2p)
{
p2p->go_neg_peer = NULL;
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 0924db5..9c4070c 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -1377,6 +1377,15 @@ int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end);
int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end);
/**
+ * p2p_parse_dev_addr - Parse P2P Device Address from P2P IE(s)
+ * @ies: Information elements from scan results
+ * @ies_len: ies buffer length in octets
+ * @dev_addr: Buffer for returning P2P Device Address
+ * Returns: 0 on success or -1 if P2P Device Address could not be parsed
+ */
+int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr);
+
+/**
* p2p_assoc_req_ie - Build P2P IE for (Re)Association Request frame
* @p2p: P2P module context from p2p_init()
* @bssid: BSSID
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 078e22d..1e79658 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -540,6 +540,23 @@ struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
}
+#ifdef CONFIG_P2P
+struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
+ const u8 *dev_addr)
+{
+ struct wpa_bss *bss;
+ dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
+ u8 addr[ETH_ALEN];
+ if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len,
+ addr) == 0 &&
+ os_memcmp(addr, dev_addr, ETH_ALEN) == 0)
+ return bss;
+ }
+ return NULL;
+}
+#endif /* CONFIG_P2P */
+
+
struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
{
struct wpa_bss *bss;
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index bb19f49..9f13298 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -94,6 +94,8 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
const u8 *ssid, size_t ssid_len);
struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
const u8 *bssid);
+struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
+ const u8 *dev_addr);
struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id);
const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie);
const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 6a3223e..7f4fb09 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2210,6 +2210,13 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
bss = dl_list_entry(next, struct wpa_bss,
list_id);
}
+#ifdef CONFIG_P2P
+ } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
+ if (hwaddr_aton(cmd + 13, bssid) == 0)
+ bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
+ else
+ bss = NULL;
+#endif /* CONFIG_P2P */
} else if (hwaddr_aton(cmd, bssid) == 0)
bss = wpa_bss_get_bssid(wpa_s, bssid);
else {