diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index 1b3364cbe..d495ec167 100644 --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -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; } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b0ebaaeb1..abba791b5 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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() diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 0a7212ca4..a7fadc049 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -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, diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 7363ef59e..ff96668a5 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index cc1dc5e16..924086310 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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;