P2P: Create P2P Device interface if supported

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>
This commit is contained in:
Arend van Spriel 2013-06-30 10:17:47 +03:00 committed by Jouni Malinen
parent 851b0c5581
commit c68f6200a7
5 changed files with 81 additions and 8 deletions

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

View 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()

View 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,

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

View 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;