From patchwork Sun Mar 17 20:57:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: dvdspndl@gmail.com X-Patchwork-Id: 228327 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 DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "maxx.shmoo.com", Issuer "CA Cert Signing Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 14FFC2C00B4 for ; Mon, 18 Mar 2013 07:59:25 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id A62A99D21F; Sun, 17 Mar 2013 16:59:20 -0400 (EDT) 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 MBDKR3JzFrJN; Sun, 17 Mar 2013 16:59:20 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id B8E7A9C1BA; Sun, 17 Mar 2013 16:58:13 -0400 (EDT) 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 9CD269C191 for ; Sun, 17 Mar 2013 16:58:11 -0400 (EDT) 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 RV5sVXqjDC70 for ; Sun, 17 Mar 2013 16:58:07 -0400 (EDT) Received: from mail-ee0-f50.google.com (mail-ee0-f50.google.com [74.125.83.50]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id 874F09C16B for ; Sun, 17 Mar 2013 16:57:44 -0400 (EDT) Received: by mail-ee0-f50.google.com with SMTP id e51so2365031eek.37 for ; Sun, 17 Mar 2013 13:57:43 -0700 (PDT) X-Received: by 10.14.3.133 with SMTP id 5mr11344055eeh.43.1363553863631; Sun, 17 Mar 2013 13:57:43 -0700 (PDT) Received: from localhost (46-116-160-72.bb.netvision.net.il. [46.116.160.72]) by mx.google.com with ESMTPS id d47sm23391606eem.9.2013.03.17.13.57.42 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 17 Mar 2013 13:57:42 -0700 (PDT) From: David Spinadel To: hostap@lists.shmoo.com Subject: [PATCH v2 08/10] nl80211_driver: implement init and deinit P2P device functions Date: Sun, 17 Mar 2013 22:57:18 +0200 Message-Id: <1363553840-7844-9-git-send-email-dvdspndl@gmail.com> X-Mailer: git-send-email 1.7.10.msysgit.1 In-Reply-To: <1363553840-7844-1-git-send-email-dvdspndl@gmail.com> References: <1363553840-7844-1-git-send-email-dvdspndl@gmail.com> X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 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: David Spinadel Signed-off-by: David Spinadel --- src/drivers/driver_nl80211.c | 152 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7e2ede8..00e56c8 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9631,6 +9631,154 @@ static int android_pno_stop(struct i802_bss *bss) #endif /* ANDROID */ +#ifdef CONFIG_P2P +static int nl80211_create_p2p_dev_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct i802_bss *p2p_dev = arg; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + if (tb[NL80211_ATTR_WDEV]) + p2p_dev->wdev_id = + nla_get_u64(tb[NL80211_ATTR_WDEV]); + + if (tb[NL80211_ATTR_MAC]) + os_memcpy(p2p_dev->addr, + nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN); + + return NL_SKIP; +} + +static int nl80211_p2p_device_exec_cmd(struct wpa_driver_nl80211_data *drv, + const char *ifname, + enum nl80211_commands cmd, + int64_t wdev_id) +{ + struct nl_msg *msg; + int ret = -1; + + if (wdev_id < 0) { + wpa_printf(MSG_DEBUG, "nl80211: Cannot execute p2p device" + "cmd %d without wdev_id", cmd); + return -1; + } + wpa_printf(MSG_DEBUG, "Executing p2p device cmd %d", cmd); + msg = nlmsg_alloc(); + if (!msg) + return -1; + + nl80211_cmd(drv, msg, 0, cmd); + NLA_PUT_U64(msg, NL80211_ATTR_WDEV, wdev_id); + + ret = send_and_recv_msgs(drv, msg, NULL, NULL); + msg = NULL; + if (ret) { +nla_put_failure: + nlmsg_free(msg); + wpa_printf(MSG_ERROR, "nl80211: Failed to execute CMD %d on " + "%s: error =%d:%s", cmd, ifname, ret, + strerror(-ret)); + } + return ret; +} + +static void nl80211_deinit_p2p_dev(void *priv) +{ + struct i802_bss *p2p_dev = priv; + struct wpa_driver_nl80211_data *drv = p2p_dev->drv; + struct i802_bss *last; + + if (p2p_dev->wdev_id == -1) + return; + + /* + * Not stopping the P2P device here as the kernel does that when + * deinit is called. Need to execute STOP here if that changes. + */ + nl80211_p2p_device_exec_cmd(drv, p2p_dev->ifname, + NL80211_CMD_DEL_INTERFACE, + p2p_dev->wdev_id); + + for (last = &drv->first_bss; last->next && last->next != p2p_dev; + last = last->next) + ; + if (last->next && last->next == p2p_dev) + last->next = p2p_dev->next; + + os_free(p2p_dev); +} + +static void *nl80211_init_p2p_dev(void *priv, const char *ifname, u8 *addr) +{ + struct i802_bss *bss = priv; + struct i802_bss *last; + struct wpa_driver_nl80211_data *drv = bss->drv; + int ret; + int type; + struct i802_bss *p2p_dev = os_zalloc(sizeof(struct i802_bss)); + if (!p2p_dev) + return NULL; + + *p2p_dev = *bss; + os_strncpy(p2p_dev->ifname, ifname, IFNAMSIZ); + + p2p_dev->ifindex = nl80211_create_iface(drv, ifname, + NL80211_IFTYPE_P2P_DEVICE, + NULL, 0, + nl80211_create_p2p_dev_handler, + p2p_dev); + if (p2p_dev->wdev_id == -1 || p2p_dev->ifindex != 0 || + is_zero_ether_addr((const u8 *)&p2p_dev->addr)) { + wpa_printf(MSG_ERROR, "nl80211: Failed to create a p2p device" + " interface %s", ifname); + os_free(p2p_dev); + return NULL; + } + + ret = nl80211_p2p_device_exec_cmd(drv, ifname, + NL80211_CMD_START_P2P_DEVICE, + p2p_dev->wdev_id); + + if (ret < 0) { + wpa_printf(MSG_ERROR, "nl80211: Failed to start p2p device" + " interface %s", ifname); + nl80211_deinit_p2p_dev(p2p_dev); + return NULL; + } + + for (last = bss; last->next; last = last->next) + ; + last->next = p2p_dev; + + os_memcpy(addr, p2p_dev->addr, ETH_ALEN); + + /* Register P2P Public Action frame on the device interface */ + type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4); + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x04\x09\x50\x6f\x9a\x09", 6); + /* Register P2P Action frame on the device interface */ + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x7f\x50\x6f\x9a\x09", 5); + /* GAS Initial Request */ + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x04\x0a", 2); + /* GAS Initial Response */ + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x04\x0b", 2); + + /* GAS Comeback Request */ + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x04\x0c", 2); + + /* GAS Comeback Response */ + nl80211_register_frame(p2p_dev, bss->nl_mgmt, type, + (u8 *) "\x04\x0d", 2); + + return p2p_dev; +} +#endif /* CONFIG_P2P */ static int driver_nl80211_set_key(const char *ifname, void *priv, enum wpa_alg alg, const u8 *addr, @@ -9847,4 +9995,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .tdls_oper = nl80211_tdls_oper, #endif /* CONFIG_TDLS */ .update_ft_ies = wpa_driver_nl80211_update_ft_ies, +#ifdef CONFIG_P2P + .init_p2p_dev = nl80211_init_p2p_dev, + .deinit_p2p_dev = nl80211_deinit_p2p_dev, +#endif /* CONFIG_P2P */ };