From patchwork Mon Mar 3 12:53:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peer, Ilan" X-Patchwork-Id: 325810 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B1C812C00D5 for ; Mon, 3 Mar 2014 23:58:08 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id BE1D19D2F9; Mon, 3 Mar 2014 07:57:26 -0500 (EST) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id K5hKj+UqfBb8; Mon, 3 Mar 2014 07:57:26 -0500 (EST) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 936A89D2F6; Mon, 3 Mar 2014 07:56:23 -0500 (EST) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id C684117C02E for ; Mon, 3 Mar 2014 07:56:21 -0500 (EST) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id E4ZnYIwRHn83 for ; Mon, 3 Mar 2014 07:56:16 -0500 (EST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B05CB9C19B for ; Mon, 3 Mar 2014 07:56:00 -0500 (EST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 03 Mar 2014 04:55:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,577,1389772800"; d="scan'208";a="491246672" Received: from unknown (HELO ipeer-e6430-1.jer.intel.com) ([10.12.217.169]) by fmsmga002.fm.intel.com with ESMTP; 03 Mar 2014 04:55:25 -0800 From: Ilan Peer To: hostap@lists.shmoo.com Subject: [PATCH] P2P: fix P2P device handling with RF-Kill Date: Mon, 3 Mar 2014 14:53:22 +0200 Message-Id: <1393851204-964-6-git-send-email-ilan.peer@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1393851204-964-1-git-send-email-ilan.peer@intel.com> References: <1393851204-964-1-git-send-email-ilan.peer@intel.com> Cc: Moshe Benji X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com From: Moshe Benji When RF-kill blocked becomes unblocked and vice versa, we should enable or properly disable the P2P device respectively. Additionally, when we start with RF-kill blocked, we should disable the P2P interface. This is needed in cases where there is no netdev associated with the P2P device. Signed-off-by: Moshe Benji --- src/common/defs.h | 6 +++++ src/drivers/driver_nl80211.c | 46 ++++++++++++++++++++++++--------------- src/p2p/p2p.c | 15 +++++++++++++ src/p2p/p2p.h | 6 +++++ wpa_supplicant/config.c | 2 +- wpa_supplicant/ctrl_iface.c | 11 +++++++++- wpa_supplicant/events.c | 10 +++++++++ wpa_supplicant/p2p_supplicant.c | 9 ++++++++ wpa_supplicant/p2p_supplicant.h | 1 + 9 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/common/defs.h b/src/common/defs.h index d4091e3..2f56b27 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -300,4 +300,10 @@ enum wpa_ctrl_req_type { /* Maximum number of EAP methods to store for EAP server user information */ #define EAP_MAX_METHODS 8 +/* P2P Mgmt interface disabled by config or control interface */ +#define WPA_P2P_MGMT_CTRL_DISABLED BIT(0) + +/* P2P Mgmt interface disabled since the underlying interface is disabled*/ +#define WPA_P2P_MGMT_IF_DISABLED BIT(1) + #endif /* DEFS_H */ diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 6df0a84..6790d2c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3997,11 +3997,15 @@ static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv) static void wpa_driver_nl80211_rfkill_blocked(void *ctx) { + struct wpa_driver_nl80211_data *drv = ctx; wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked"); + /* - * This may be for any interface; use ifdown event to disable - * interface. + * rtnetlink ifdown handler will report interfaces other than the P2P + * Device interface as disabled. */ + if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) + wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); } @@ -4014,7 +4018,13 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx) "after rfkill unblock"); return; } - /* rtnetlink ifup handler will report interface as enabled */ + + /* + * rtnetlink ifup handler will report interfaces other than the P2P + * Device interface as enabled. + */ + if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) + wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); } @@ -4600,7 +4610,14 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv, wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s", bss->ifname, drv->phyname); - if (set_addr && + if (drv->hostapd) + nlmode = NL80211_IFTYPE_AP; + else if (bss->if_dynamic) + nlmode = nl80211_get_ifmode(bss); + else + nlmode = NL80211_IFTYPE_STATION; + + if (set_addr && (nlmode != NL80211_IFTYPE_P2P_DEVICE) && (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) || linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, set_addr))) @@ -4609,13 +4626,6 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv, if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP) drv->start_mode_ap = 1; - if (drv->hostapd) - nlmode = NL80211_IFTYPE_AP; - else if (bss->if_dynamic) - nlmode = nl80211_get_ifmode(bss); - else - nlmode = NL80211_IFTYPE_STATION; - if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) { wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode"); return -1; @@ -4636,19 +4646,19 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv, } else { wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable " "interface '%s' due to rfkill", bss->ifname); - if (nlmode == NL80211_IFTYPE_P2P_DEVICE) - return 0; - drv->if_disabled = 1; + if (nlmode != NL80211_IFTYPE_P2P_DEVICE) + drv->if_disabled = 1; send_rfkill_event = 1; } - if (!drv->hostapd) + if (!drv->hostapd && (nlmode != NL80211_IFTYPE_P2P_DEVICE)) netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 1, IF_OPER_DORMANT); - if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, - bss->addr)) - return -1; + if (nlmode != NL80211_IFTYPE_P2P_DEVICE) + if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, + bss->addr)) + return -1; if (send_rfkill_event) { eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill, diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 4b90989..7740fb0 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -2452,6 +2452,21 @@ void p2p_deinit(struct p2p_data *p2p) } +void p2p_reset(struct p2p_data *p2p) +{ + if (p2p == NULL) + return; + + eloop_cancel_timeout(p2p_expiration_timeout, p2p, NULL); + eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL); + eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); + eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL); + + p2p_flush(p2p); + wpabuf_free(p2p->sd_resp); +} + + void p2p_flush(struct p2p_data *p2p) { struct p2p_device *dev, *prev; diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 08e7176..7a4717a 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1196,6 +1196,12 @@ u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr); */ void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr); +/** + * p2p_reset - cancel timeouts and reset P2P data, state will be set to + * P2P_IDLE by p2p_flush() + * @p2p: P2P module context from p2p_init() + */ +void p2p_reset(struct p2p_data *p2p); /* Event notifications from lower layer driver operations */ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 23aab4b..378d0b9 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3551,7 +3551,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(p2p_add_cli_chan, 0, 1), 0 }, { INT(p2p_go_ht40), 0 }, { INT(p2p_go_vht), 0 }, - { INT(p2p_disabled), 0 }, + { INT_RANGE(p2p_disabled, 0, WPA_P2P_MGMT_CTRL_DISABLED), 0 }, { INT(p2p_no_group_iface), 0 }, { INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 }, { IPV4(ip_addr_go), 0 }, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 793faec..16e98e8 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4643,10 +4643,19 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd) return wpa_drv_set_p2p_powersave(wpa_s, -1, -1, atoi(param)); if (os_strcmp(cmd, "disabled") == 0) { - wpa_s->global->p2p_disabled = atoi(param); + int disabled = atoi(param); + + if (disabled) + wpa_s->global->p2p_disabled |= + WPA_P2P_MGMT_CTRL_DISABLED; + else + wpa_s->global->p2p_disabled &= + ~WPA_P2P_MGMT_CTRL_DISABLED; + wpa_printf(MSG_DEBUG, "P2P functionality %s", wpa_s->global->p2p_disabled ? "disabled" : "enabled"); + if (wpa_s->global->p2p_disabled) { wpas_p2p_stop_find(wpa_s); os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 059ffcb..d98e4a4 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3260,6 +3260,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled"); if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { wpa_supplicant_update_mac_addr(wpa_s); + if (wpa_s->p2p_mgmt) + wpa_s->global->p2p_disabled &= + ~WPA_P2P_MGMT_IF_DISABLED; + #ifdef CONFIG_AP if (!wpa_s->ap_iface) { wpa_supplicant_set_state(wpa_s, @@ -3288,6 +3292,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpas_p2p_disconnect(wpa_s); break; } + + if (wpa_s->p2p_mgmt) { + wpas_p2p_reset(wpa_s); + wpa_s->global->p2p_disabled |= WPA_P2P_MGMT_IF_DISABLED; + } + #endif /* CONFIG_P2P */ wpa_supplicant_mark_disassoc(wpa_s); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b878198..8c7bf4b 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -6881,6 +6881,15 @@ static void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s, } +void wpas_p2p_reset(struct wpa_supplicant *wpa_s) +{ + if (!wpa_s || wpa_s->global->p2p_disabled || !wpa_s->global->p2p) + return; + + p2p_reset(wpa_s->global->p2p); +} + + void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer, int iface_addr) { diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index d3d36b1..0403e3e 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -158,6 +158,7 @@ int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init, const struct wpabuf *req, const struct wpabuf *sel, int forced_freq); int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled); +void wpas_p2p_reset(struct wpa_supplicant *wpa_s); #ifdef CONFIG_P2P int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);