From patchwork Mon Feb 11 11:15:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [RFC,10/10] wpa_supplicant: init a dedicated P2P device interface Date: Mon, 11 Feb 2013 01:15:47 -0000 From: Arend van Spriel X-Patchwork-Id: 219583 Message-Id: <1360581347-26766-11-git-send-email-arend@broadcom.com> To: hostap@lists.shmoo.com Cc: Jouni Malinen , Johannes Berg From: David Spinadel Try to init a dedicated P2P device if supported in wpas_init_p2p and deinit it in wpas_deinit_p2p. Signed-hostap: David Spinadel --- src/p2p/p2p.c | 15 +++++++++ src/p2p/p2p.h | 8 +++++ src/p2p/p2p_i.h | 5 +++ wpa_supplicant/p2p_supplicant.c | 65 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 55a95b5..973fcf1 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -4330,3 +4330,18 @@ int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, return 0; } + +void p2p_set_dev_addr(struct p2p_data *p2p, u8 *addr) +{ + os_memcpy(p2p->cfg->dev_addr, addr, ETH_ALEN); +} + +void p2p_set_dev_priv(struct p2p_data *p2p, void *priv) +{ + p2p->dev_drv_priv = priv; +} + +void *p2p_get_dev_priv(struct p2p_data *p2p) +{ + return p2p->dev_drv_priv; +} diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 2d8b2c2..980ae78 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1779,5 +1779,13 @@ struct wpabuf * wifi_display_encaps(struct wpabuf *subelems); */ int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int, int max_disc_tu); +/** + * p2p_set_dev_addr - Set P2P device address + * @p2p: P2P nodule context from p2p_init() + * @addr: P2P device address to assign to p2p device. + */ +void p2p_set_dev_addr(struct p2p_data *p2p, u8 *addr); +void p2p_set_dev_priv(struct p2p_data *p2p, void *priv); +void *p2p_get_dev_priv(struct p2p_data *p2p); #endif /* P2P_H */ diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 27fef01..57a0238 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -216,6 +216,11 @@ struct p2p_data { } state; /** + * dev_drv_priv - Driver context of P2P device + */ + void *dev_drv_priv; + + /** * min_disc_int - minDiscoverableInterval */ int min_disc_int; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 87dae65..f01da9c 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2807,6 +2807,58 @@ static int wpas_go_connected(void *ctx, const u8 *dev_addr) return 0; } +/** + * wpas_p2p_dev_interface_init - Initialize P2P device interface to be used + * for all device related operations + * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() + * @p2p: P2P module context from p2p_init() + * Returns: 0 on success, -1 on failure + */ +static int wpas_p2p_dev_interface_init(struct wpa_supplicant *wpa_s, + struct p2p_data *p2p) +{ + char *ifname = NULL; + char p2p_dev_ifname[IFNAMSIZ]; + int ifname_len = 0; + u8 addr[ETH_ALEN]; + + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) + return 0; + + if (!p2p) + return -1; + + wpa_printf(MSG_DEBUG, "P2P: Initialize P2P device Interface"); + + ifname = wpa_s->ifname; + /** + * If the name p2p-dev-$(wpa_s->ifname) is greater than IFNAMESIZ + * Assume the last 4 char of the wpa_s->ifname as unique + */ + ifname_len = os_strlen(ifname); + if (ifname_len > (IFNAMSIZ - 9)) + ifname += (ifname_len - 5); + + os_snprintf(p2p_dev_ifname, IFNAMSIZ, "p2p-dev-%s", ifname); + wpa_printf(MSG_DEBUG, "Creating a P2P device interface %s for %s", + p2p_dev_ifname, wpa_s->ifname); + + wpa_s->p2p_drv_priv = wpa_drv_init_p2p_dev(wpa_s, p2p_dev_ifname, addr); + if (!wpa_s->p2p_drv_priv) { + wpa_printf(MSG_ERROR, "P2P: Failed to create a new P2P " + "device interface"); + return -1; + } + + /* override p2p device address. */ + os_memcpy(wpa_s->global->p2p_dev_addr, addr, ETH_ALEN); + p2p_set_dev_addr(p2p, addr); + p2p_set_dev_priv(p2p, wpa_s->p2p_drv_priv); + + wpa_printf(MSG_INFO, "P2P: Device initialization success"); + + return 0; +} /** * wpas_p2p_init - Initialize P2P module for %wpa_supplicant @@ -2823,8 +2875,10 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)) return 0; - if (global->p2p) + if (global->p2p) { + wpa_s->p2p_drv_priv = p2p_get_dev_priv(global->p2p); return 0; + } if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) { struct p2p_params params; @@ -2965,6 +3019,12 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) global->p2p, wpa_s->conf->wps_vendor_ext[i]); } + /* Try to initialize P2P device interface */ + if (wpas_p2p_dev_interface_init(wpa_s, global->p2p)) { + p2p_deinit(global->p2p); + return -1; + } + return 0; } @@ -2998,6 +3058,9 @@ void wpas_p2p_deinit(struct wpa_supplicant *wpa_s) /* TODO: remove group interface from the driver if this wpa_s instance * is on top of a P2P group interface */ + + if (wpa_s->p2p_drv_priv) + wpa_drv_deinit_p2p_dev(wpa_s); }