From 1f1a08b4cc8101cf77eceb530ddd28c842675d94 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Thu, 2 Jul 2015 10:45:05 +0300 Subject: [PATCH] P2PS: Add intended iface address during PD for persistent group When persistent group is used and the peer is GO in this group, intended interface attribute should be added to PD request/response. Not doing so violates the spec. Signed-off-by: Andrei Otcheretianski Reviewed-by: Max Stepanov Reviewed-by: Ilan Peer --- src/p2p/p2p.h | 7 +++++-- src/p2p/p2p_pd.c | 20 ++++++++++++++++---- wpa_supplicant/p2p_supplicant.c | 16 +++++++++++++++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 67b8bdb..20c6429 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -955,18 +955,21 @@ struct p2p_config { /** * Determine if we have a persistent group we share with remote peer + * and allocate interface for this group if needed * @ctx: Callback context from cb_ctx * @addr: Peer device address to search for * @ssid: Persistent group SSID or %NULL if any * @ssid_len: Length of @ssid - * @go_dev_addr: Buffer for returning intended GO P2P Device Address + * @go_dev_addr: Buffer for returning GO P2P Device Address * @ret_ssid: Buffer for returning group SSID * @ret_ssid_len: Buffer for returning length of @ssid + * @intended_iface_addr: Buffer for returning intended iface address * Returns: 1 if a matching persistent group was found, 0 otherwise */ int (*get_persistent_group)(void *ctx, const u8 *addr, const u8 *ssid, size_t ssid_len, u8 *go_dev_addr, - u8 *ret_ssid, size_t *ret_ssid_len); + u8 *ret_ssid, size_t *ret_ssid_len, + u8 *intended_iface_addr); /** * Get information about a possible local GO role diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index d17921c..33c65dc 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -87,6 +87,7 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev, u8 ssid[SSID_MAX_LEN]; size_t ssid_len; u8 go_dev_addr[ETH_ALEN]; + u8 intended_addr[ETH_ALEN]; /* If we might be explicite group owner, add GO details */ if (prov->conncap & (P2PS_SETUP_GROUP_OWNER | @@ -101,7 +102,7 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev, if (p2p->cfg->get_persistent_group) { shared_group = p2p->cfg->get_persistent_group( p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0, - go_dev_addr, ssid, &ssid_len); + go_dev_addr, ssid, &ssid_len, intended_addr); } /* Add Operating Channel if conncap includes GO */ @@ -149,9 +150,15 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev, p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask), feat_cap_mask); - if (shared_group) + if (shared_group) { p2p_buf_add_persistent_group_info(buf, go_dev_addr, ssid, ssid_len); + /* Add intended interface address if it is not added yet */ + if ((prov->conncap == P2PS_SETUP_NONE || + prov->conncap == P2PS_SETUP_CLIENT) && + !is_zero_ether_addr(intended_addr)) + p2p_buf_add_intended_addr(buf, intended_addr); + } } @@ -296,15 +303,20 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, u8 ssid[SSID_MAX_LEN]; size_t ssid_len; u8 go_dev_addr[ETH_ALEN]; + u8 intended_addr[ETH_ALEN]; persist = p2p->cfg->get_persistent_group( p2p->cfg->cb_ctx, dev->info.p2p_device_addr, persist_ssid, persist_ssid_len, go_dev_addr, - ssid, &ssid_len); - if (persist) + ssid, &ssid_len, intended_addr); + if (persist) { p2p_buf_add_persistent_group_info( buf, go_dev_addr, ssid, ssid_len); + if (!is_zero_ether_addr(intended_addr)) + p2p_buf_add_intended_addr( + buf, intended_addr); + } } if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER)) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index c44ebfe..220f2d7 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3508,7 +3508,8 @@ static void wpas_presence_resp(void *ctx, const u8 *src, u8 status, static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid, size_t ssid_len, u8 *go_dev_addr, - u8 *ret_ssid, size_t *ret_ssid_len) + u8 *ret_ssid, size_t *ret_ssid_len, + u8 *intended_iface_addr) { struct wpa_supplicant *wpa_s = ctx; struct wpa_ssid *s; @@ -3518,6 +3519,19 @@ static int wpas_get_persistent_group(void *ctx, const u8 *addr, const u8 *ssid, os_memcpy(ret_ssid, s->ssid, s->ssid_len); *ret_ssid_len = s->ssid_len; os_memcpy(go_dev_addr, s->bssid, ETH_ALEN); + + if (s->mode != WPAS_MODE_P2P_GO) { + os_memset(intended_iface_addr, 0, ETH_ALEN); + } else if (wpas_p2p_create_iface(wpa_s)) { + if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO)) + return 0; + + os_memcpy(intended_iface_addr, + wpa_s->pending_interface_addr, ETH_ALEN); + } else { + os_memcpy(intended_iface_addr, wpa_s->own_addr, + ETH_ALEN); + } return 1; } -- 2.1.4