]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Create P2P Device interface if supported
authorArend van Spriel <arend@broadcom.com>
Sun, 30 Jun 2013 07:17:47 +0000 (10:17 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 30 Jun 2013 07:50:14 +0000 (10:50 +0300)
If the capability flag of the driver indicates a dedicated P2P Device is
supported, a P2P Device interface is created.

Create the P2P Device in main interface creation loop when the added
interface flags support and P2P supplicant is not yet initialized
avoiding recursion of add_interface.

Do not register l2_packet for P2P Device interface (both for EAPOL and
for TDLS).

Signed-hostap: Arend van Spriel <arend@broadcom.com>

wpa_supplicant/main.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 1b3364cbe3a66377480b141746c73a74770cf376..d495ec167ecff935423614622454767d4a01e56f 100644 (file)
@@ -14,6 +14,7 @@
 #include "common.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
+#include "p2p_supplicant.h"
 
 extern struct wpa_driver_ops *wpa_drivers[];
 
@@ -289,6 +290,8 @@ int main(int argc, char *argv[])
        }
 
        for (i = 0; exitcode == 0 && i < iface_count; i++) {
+               struct wpa_supplicant *wpa_s;
+
                if ((ifaces[i].confname == NULL &&
                     ifaces[i].ctrl_interface == NULL) ||
                    ifaces[i].ifname == NULL) {
@@ -299,7 +302,15 @@ int main(int argc, char *argv[])
                        exitcode = -1;
                        break;
                }
-               if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL)
+               wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);
+               if (wpa_s == NULL) {
+                       exitcode = -1;
+                       break;
+               }
+               if (wpa_s->global->p2p == NULL &&
+                   (wpa_s->drv_flags &
+                    WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+                   wpas_p2p_add_p2pdev_interface(wpa_s) < 0)
                        exitcode = -1;
        }
 
index b0ebaaeb1e03233db33003b35dc771acf91b063c..abba791b5fed01c20a8a23d47c3874d62f019d0a 100644 (file)
@@ -2975,6 +2975,44 @@ static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
 }
 
 
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+{
+       struct wpa_interface iface;
+       struct wpa_supplicant *p2pdev_wpa_s;
+       char ifname[100];
+       char force_name[100];
+       int ret;
+
+       os_snprintf(ifname, sizeof(ifname), "p2p-dev-%s", wpa_s->ifname);
+       force_name[0] = '\0';
+       wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
+       ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
+                            force_name, wpa_s->pending_interface_addr, NULL);
+       if (ret < 0) {
+               wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
+               return ret;
+       }
+       os_strlcpy(wpa_s->pending_interface_name, ifname,
+                  sizeof(wpa_s->pending_interface_name));
+
+       os_memset(&iface, 0, sizeof(iface));
+       iface.p2p_mgmt = 1;
+       iface.ifname = wpa_s->pending_interface_name;
+       iface.driver = wpa_s->driver->name;
+       iface.ctrl_interface = wpa_s->conf->ctrl_interface;
+       iface.driver_param = wpa_s->conf->driver_param;
+       iface.confname = wpa_s->confname;
+       p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
+       if (!p2pdev_wpa_s) {
+               wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
+               return -1;
+       }
+
+       wpa_s->pending_interface_name[0] = '\0';
+       return 0;
+}
+
+
 /**
  * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
  * @global: Pointer to global data from wpa_supplicant_init()
index 0a7212ca45cc1fa5742502ea72641ee58ee008c2..a7fadc049105ec75b3c6270de39479c2e2d2d52f 100644 (file)
@@ -14,10 +14,12 @@ struct p2p_go_neg_results;
 enum p2p_send_action_result;
 struct p2p_peer_info;
 struct p2p_channels;
+struct wps_event_fail;
 
 int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit(struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit_global(struct wpa_global *global);
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s);
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                     const char *pin, enum p2p_wps_method wps_method,
                     int persistent_group, int auto_join, int join,
index 7363ef59e9fdbbe2f188336272a85f0694581cab..ff96668a5415be91c0d468191c15e9fbe41ab2ed 100644 (file)
@@ -2328,7 +2328,8 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
                const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
                if (addr)
                        os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
-       } else if (!(wpa_s->drv_flags &
+       } else if (!wpa_s->p2p_mgmt &&
+                  !(wpa_s->drv_flags &
                     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
                l2_packet_deinit(wpa_s->l2);
                wpa_s->l2 = l2_packet_init(wpa_s->ifname,
@@ -2348,10 +2349,6 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
                return -1;
        }
 
-       wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
-               MAC2STR(wpa_s->own_addr));
-       wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-
        return 0;
 }
 
@@ -2397,6 +2394,10 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
        if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
                return -1;
 
+       wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
+               MAC2STR(wpa_s->own_addr));
+       wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+
        if (wpa_s->bridge_ifname[0]) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
                        "interface '%s'", wpa_s->bridge_ifname);
@@ -2960,11 +2961,21 @@ next_driver:
        if (wpa_s->max_remain_on_chan == 0)
                wpa_s->max_remain_on_chan = 1000;
 
+       /*
+        * Only take p2p_mgmt parameters when P2P Device is supported.
+        * Doing it here as it determines whether l2_packet_init() will be done
+        * during wpa_supplicant_driver_init().
+        */
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
+               wpa_s->p2p_mgmt = iface->p2p_mgmt;
+       else
+               iface->p2p_mgmt = 1;
+
        if (wpa_supplicant_driver_init(wpa_s) < 0)
                return -1;
 
 #ifdef CONFIG_TDLS
-       if (wpa_tdls_init(wpa_s->wpa))
+       if (!iface->p2p_mgmt && wpa_tdls_init(wpa_s->wpa))
                return -1;
 #endif /* CONFIG_TDLS */
 
@@ -3002,7 +3013,7 @@ next_driver:
        }
 
 #ifdef CONFIG_P2P
-       if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
+       if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
                wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
                return -1;
        }
index cc1dc5e168957ed4a1878d920f86134f6c4ce5fc..9240863102fc881829ef2d50012f9cc3d892e501 100644 (file)
@@ -104,6 +104,15 @@ struct wpa_interface {
         * receiving of EAPOL frames from an additional interface.
         */
        const char *bridge_ifname;
+
+       /**
+        * p2p_mgmt - Interface used for P2P management (P2P Device operations)
+        *
+        * Indicates whether wpas_p2p_init() must be called for this interface.
+        * This is used only when the driver supports a dedicated P2P Device
+        * interface that is not a network interface.
+        */
+       int p2p_mgmt;
 };
 
 /**
@@ -566,6 +575,8 @@ struct wpa_supplicant {
        unsigned int roc_waiting_drv_freq;
        int action_tx_wait_time;
 
+       int p2p_mgmt;
+
 #ifdef CONFIG_P2P
        struct p2p_go_neg_results *go_params;
        int create_p2p_iface;