Patchwork [RFC,10/10] wpa_supplicant: init a dedicated P2P device interface

login
register
mail settings
Submitter Arend van Spriel
Date Feb. 11, 2013, 11:15 a.m.
Message ID <1360581347-26766-11-git-send-email-arend@broadcom.com>
Download mbox | patch
Permalink /patch/219583/
State Superseded
Headers show

Comments

Arend van Spriel - Feb. 11, 2013, 11:15 a.m.
From: David Spinadel <david.spinadel@intel.com>

Try to init a dedicated P2P device if supported in wpas_init_p2p
and deinit it in wpas_deinit_p2p.

Signed-hostap: David Spinadel <david.spinadel@intel.com>
---
 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(-)

Patch

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);
 }