diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 19bcecebd..180827367 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1321,6 +1321,52 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data, #ifdef CONFIG_P2P +static int wpa_config_parse_go_p2p_dev_addr(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 || + os_strcmp(value, "any") == 0) { + os_memset(ssid->go_p2p_dev_addr, 0, ETH_ALEN); + wpa_printf(MSG_MSGDUMP, "GO P2P Device Address any"); + return 0; + } + if (hwaddr_aton(value, ssid->go_p2p_dev_addr)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid GO P2P Device Address '%s'.", + line, value); + return -1; + } + ssid->bssid_set = 1; + wpa_printf(MSG_MSGDUMP, "GO P2P Device Address " MACSTR, + MAC2STR(ssid->go_p2p_dev_addr)); + return 0; +} + + +#ifndef NO_CONFIG_WRITE +static char * wpa_config_write_go_p2p_dev_addr(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + char *value; + int res; + + if (is_zero_ether_addr(ssid->go_p2p_dev_addr)) + return NULL; + + value = os_malloc(20); + if (value == NULL) + return NULL; + res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->go_p2p_dev_addr)); + if (res < 0 || res >= 20) { + os_free(value); + return NULL; + } + value[20 - 1] = '\0'; + return value; +} +#endif /* NO_CONFIG_WRITE */ + + static int wpa_config_parse_p2p_client_list(const struct parse_data *data, struct wpa_ssid *ssid, int line, const char *value) @@ -1632,6 +1678,7 @@ static const struct parse_data ssid_fields[] = { { STR(bgscan) }, { INT_RANGE(ignore_broadcast_ssid, 0, 2) }, #ifdef CONFIG_P2P + { FUNC(go_p2p_dev_addr) }, { FUNC(p2p_client_list) }, { FUNC(psk_list) }, #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index cb2dde8e2..ed5cdfffc 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -606,6 +606,15 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) #ifdef CONFIG_P2P +static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid) +{ + char *value = wpa_config_get(ssid, "go_p2p_dev_addr"); + if (value == NULL) + return; + fprintf(f, "\tgo_p2p_dev_addr=%s\n", value); + os_free(value); +} + static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) { char *value = wpa_config_get(ssid, "p2p_client_list"); @@ -714,6 +723,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) #endif /* CONFIG_IEEE80211W */ STR(id_str); #ifdef CONFIG_P2P + write_go_p2p_dev_addr(f, ssid); write_p2p_client_list(f, ssid); write_psk_list(f, ssid); #endif /* CONFIG_P2P */ diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 2a8be6bd4..0102da94c 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -130,6 +130,11 @@ struct wpa_ssid { */ int bssid_set; + /** + * go_p2p_dev_addr - GO's P2P Device Address or all zeros if not set + */ + u8 go_p2p_dev_addr[ETH_ALEN]; + /** * psk - WPA pre-shared key (256 bits) */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fc66225b1..44937723f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -866,6 +866,32 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, continue; } + if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) { + struct wpabuf *p2p_ie; + u8 dev_addr[ETH_ALEN]; + + ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); + if (ie == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - no P2P element"); + continue; + } + p2p_ie = wpa_bss_get_vendor_ie_multi( + bss, P2P_IE_VENDOR_TYPE); + if (p2p_ie == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - could not fetch P2P element"); + continue; + } + + if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0 + || os_memcmp(dev_addr, ssid->go_p2p_dev_addr, + ETH_ALEN) != 0) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - no matching GO P2P Device Address in P2P element"); + wpabuf_free(p2p_ie); + continue; + } + wpabuf_free(p2p_ie); + } + /* * TODO: skip the AP if its P2P IE has Group Formation * bit set in the P2P Group Capability Bitmap and we