aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantosh Sajjan <ssajjan@codeaurora.org>2011-11-18 13:27:21 +0530
committerEthan Chen <intervigil@gmail.com>2012-05-21 22:33:08 -0700
commit38715b525e1d98620deabe9299060762be0380b9 (patch)
tree1c56ba333f7a58bfab0c8221b39ca256f8cf9bfd
parent6c70d496d0eae3ee18e496baf0e3e561c450d34c (diff)
downloadandroid_external_wpa_supplicant_8-38715b525e1d98620deabe9299060762be0380b9.tar.gz
android_external_wpa_supplicant_8-38715b525e1d98620deabe9299060762be0380b9.tar.bz2
android_external_wpa_supplicant_8-38715b525e1d98620deabe9299060762be0380b9.zip
Added support for MSM driver CMD.
Driver specific commands (STOP/START/SETPOWER/GETPOWER) support is added. Also enable NL80211 support in wpa_supplicant and hostapd. Change-Id: I4ecca395e547f3e3f5141a524b2414e9103faebb
-rw-r--r--hostapd/.config2
-rw-r--r--hostapd/Android.mk6
-rw-r--r--src/drivers/driver_nl80211.c131
-rw-r--r--src/drivers/driver_nl80211.h157
-rw-r--r--src/drivers/driver_qcom_cmd_nl80211.c137
-rw-r--r--src/drivers/drivers.mk3
-rw-r--r--wpa_supplicant/.config2
-rw-r--r--wpa_supplicant/Android.mk8
-rwxr-xr-x[-rw-r--r--]wpa_supplicant/wpa_supplicant.c8
9 files changed, 320 insertions, 134 deletions
diff --git a/hostapd/.config b/hostapd/.config
index 8341d4b0..7b6c5f42 100644
--- a/hostapd/.config
+++ b/hostapd/.config
@@ -20,7 +20,7 @@
#CFLAGS += -I../../madwifi # change to the madwifi source directory
# Driver interface for drivers using the nl80211 kernel interface
-#CONFIG_DRIVER_NL80211=y
+CONFIG_DRIVER_NL80211=y
# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
# shipped with your distribution yet. If that is the case, you need to build
# newer libnl version and point the hostapd build to use it.
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 2ffe826a..5da94ea3 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -17,10 +17,14 @@ L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
L_CFLAGS += -DANDROID_LOG_NAME=\"hostapd\"
ifdef CONFIG_DRIVER_NL80211
+ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
+ L_CFLAGS += -DANDROID_QCOM_P2P_PATCH
+else
ifneq ($(BOARD_WLAN_DEVICE), wl12xx_mac80211)
L_CFLAGS += -DANDROID_BRCM_P2P_PATCH
endif
-endif
+endif # QCWCN
+endif # CONFIG_DRIVER_NL80211
# Use Android specific directory for control interface sockets
L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index ba37bac6..7fb51fc8 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -16,36 +16,8 @@
* See README and COPYING for more details.
*/
-#include "includes.h"
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include "nl80211_copy.h"
-
-#include "common.h"
-#include "eloop.h"
-#include "utils/list.h"
-#include "common/ieee802_11_defs.h"
-#include "netlink.h"
-#include "linux_ioctl.h"
-#include "radiotap.h"
-#include "radiotap_iter.h"
-#include "rfkill.h"
-#include "driver.h"
-#if defined(ANDROID_BRCM_P2P_PATCH) && !defined(HOSTAPD)
-#include "wpa_supplicant_i.h"
-#endif
-#ifdef ANDROID
-#define WPA_EVENT_DRIVER_STATE "CTRL-EVENT-DRIVER-STATE "
-#endif
+#include "driver_nl80211.h"
+
#ifdef CONFIG_LIBNL20
/* libnl 2.0 compatibility code */
#define nl_handle nl_sock
@@ -93,105 +65,6 @@ static void nl80211_handle_destroy(struct nl_handle *handle)
}
#endif /* CONFIG_LIBNL20 */
-
-#ifndef IFF_LOWER_UP
-#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
-#endif
-#ifndef IFF_DORMANT
-#define IFF_DORMANT 0x20000 /* driver signals dormant */
-#endif
-
-#ifndef IF_OPER_DORMANT
-#define IF_OPER_DORMANT 5
-#endif
-#ifndef IF_OPER_UP
-#define IF_OPER_UP 6
-#endif
-
-struct nl80211_global {
- struct dl_list interfaces;
- int if_add_ifindex;
-};
-
-struct i802_bss {
- struct wpa_driver_nl80211_data *drv;
- struct i802_bss *next;
- int ifindex;
- char ifname[IFNAMSIZ + 1];
- char brname[IFNAMSIZ];
- unsigned int beacon_set:1;
- unsigned int added_if_into_bridge:1;
- unsigned int added_bridge:1;
-};
-
-struct wpa_driver_nl80211_data {
- struct nl80211_global *global;
- struct dl_list list;
- u8 addr[ETH_ALEN];
- char phyname[32];
- void *ctx;
- struct netlink_data *netlink;
- int ioctl_sock; /* socket for ioctl() use */
- int ifindex;
- int if_removed;
- int if_disabled;
- int ignore_if_down_event;
- struct rfkill_data *rfkill;
- struct wpa_driver_capa capa;
- int has_capability;
-
- int operstate;
-
- int scan_complete_events;
-
- struct nl_handle *nl_handle;
- struct nl_handle *nl_handle_event;
- struct nl_handle *nl_handle_preq;
- struct nl_cache *nl_cache;
- struct nl_cache *nl_cache_event;
- struct nl_cache *nl_cache_preq;
- struct nl_cb *nl_cb;
- struct genl_family *nl80211;
-
- u8 auth_bssid[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- int associated;
- u8 ssid[32];
- size_t ssid_len;
- enum nl80211_iftype nlmode;
- enum nl80211_iftype ap_scan_as_station;
- unsigned int assoc_freq;
-
- int monitor_sock;
- int monitor_ifidx;
- int no_monitor_iface_capab;
-
- unsigned int pending_remain_on_chan:1;
-
- u64 remain_on_chan_cookie;
- u64 send_action_cookie;
-
- unsigned int last_mgmt_freq;
- unsigned int ap_oper_freq;
-
- struct wpa_driver_scan_filter *filter_ssids;
- size_t num_filter_ssids;
-
- struct i802_bss first_bss;
-
-#ifdef HOSTAPD
- int eapol_sock; /* socket for EAPOL frames */
-
- int default_if_indices[16];
- int *if_indices;
- int num_if_indices;
-
- int last_freq;
- int last_freq_ht;
-#endif /* HOSTAPD */
-};
-
-
static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
void *timeout_ctx);
static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
new file mode 100644
index 00000000..9ee88f9d
--- /dev/null
+++ b/src/drivers/driver_nl80211.h
@@ -0,0 +1,157 @@
+/*
+ * Driver interaction with Linux nl80211/cfg80211
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (c) 2009-2010, Atheros Communications
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef _DRIVER_NL80211_H_
+#define _DRIVER_NL80211_H_
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include "nl80211_copy.h"
+
+#include "common.h"
+#include "eloop.h"
+#include "utils/list.h"
+#include "common/ieee802_11_defs.h"
+#include "netlink.h"
+#include "linux_ioctl.h"
+#include "radiotap.h"
+#include "radiotap_iter.h"
+#include "rfkill.h"
+#include "driver.h"
+#if defined(ANDROID_BRCM_P2P_PATCH) && !defined(HOSTAPD)
+#include "wpa_supplicant_i.h"
+#endif
+#ifdef ANDROID
+#define WPA_EVENT_DRIVER_STATE "CTRL-EVENT-DRIVER-STATE "
+#endif
+
+#ifdef CONFIG_LIBNL20
+/* libnl 2.0 compatibility code */
+#define nl_handle nl_sock
+#define nl80211_handle_alloc nl_socket_alloc_cb
+#define nl80211_handle_destroy nl_socket_free
+#endif /* CONFIG_LIBNL20 */
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
+#endif
+#ifndef IFF_DORMANT
+#define IFF_DORMANT 0x20000 /* driver signals dormant */
+#endif
+
+#ifndef IF_OPER_DORMANT
+#define IF_OPER_DORMANT 5
+#endif
+#ifndef IF_OPER_UP
+#define IF_OPER_UP 6
+#endif
+
+struct nl80211_global {
+ struct dl_list interfaces;
+ int if_add_ifindex;
+};
+
+struct i802_bss {
+ struct wpa_driver_nl80211_data *drv;
+ struct i802_bss *next;
+ int ifindex;
+ char ifname[IFNAMSIZ + 1];
+ char brname[IFNAMSIZ];
+ unsigned int beacon_set:1;
+ unsigned int added_if_into_bridge:1;
+ unsigned int added_bridge:1;
+};
+
+struct wpa_driver_nl80211_data {
+ struct nl80211_global *global;
+ struct dl_list list;
+ u8 addr[ETH_ALEN];
+ char phyname[32];
+ void *ctx;
+ struct netlink_data *netlink;
+ int ioctl_sock; /* socket for ioctl() use */
+ int ifindex;
+ int if_removed;
+ int if_disabled;
+ int ignore_if_down_event;
+ struct rfkill_data *rfkill;
+ struct wpa_driver_capa capa;
+ int has_capability;
+
+ int operstate;
+
+ int scan_complete_events;
+
+ struct nl_handle *nl_handle;
+ struct nl_handle *nl_handle_event;
+ struct nl_handle *nl_handle_preq;
+ struct nl_cache *nl_cache;
+ struct nl_cache *nl_cache_event;
+ struct nl_cache *nl_cache_preq;
+ struct nl_cb *nl_cb;
+ struct genl_family *nl80211;
+
+ u8 auth_bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ int associated;
+ u8 ssid[32];
+ size_t ssid_len;
+ enum nl80211_iftype nlmode;
+ enum nl80211_iftype ap_scan_as_station;
+ unsigned int assoc_freq;
+
+ int monitor_sock;
+ int monitor_ifidx;
+ int no_monitor_iface_capab;
+
+ unsigned int pending_remain_on_chan:1;
+
+ u64 remain_on_chan_cookie;
+ u64 send_action_cookie;
+
+ unsigned int last_mgmt_freq;
+ unsigned int ap_oper_freq;
+
+ struct wpa_driver_scan_filter *filter_ssids;
+ size_t num_filter_ssids;
+
+ struct i802_bss first_bss;
+
+#ifdef HOSTAPD
+ int eapol_sock; /* socket for EAPOL frames */
+
+ int default_if_indices[16];
+ int *if_indices;
+ int num_if_indices;
+
+ int last_freq;
+ int last_freq_ht;
+#endif /* HOSTAPD */
+};
+
+#endif
diff --git a/src/drivers/driver_qcom_cmd_nl80211.c b/src/drivers/driver_qcom_cmd_nl80211.c
new file mode 100644
index 00000000..4e754129
--- /dev/null
+++ b/src/drivers/driver_qcom_cmd_nl80211.c
@@ -0,0 +1,137 @@
+/*
+ * Driver interaction with extended Linux CFG8021
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ */
+
+#ifdef ANDROID_QCOM_P2P_PATCH
+#include "driver_nl80211.h"
+
+#define WPA_PS_ENABLED 0
+#define WPA_PS_DISABLED 1
+
+static int wpa_driver_set_power_save(void *priv, int state)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int ret = -1;
+ enum nl80211_ps_state ps_state;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
+ NL80211_CMD_SET_POWER_SAVE, 0);
+
+ if (state == WPA_PS_ENABLED)
+ ps_state = NL80211_PS_ENABLED;
+ else
+ ps_state = NL80211_PS_DISABLED;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ msg = NULL;
+ if (ret < 0)
+ wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret);
+nla_put_failure:
+ nlmsg_free(msg);
+ return ret;
+}
+
+static int get_power_mode_handler(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ int *state = (int *)arg;
+
+ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+
+ if (!tb[NL80211_ATTR_PS_STATE])
+ return NL_SKIP;
+
+ if (state) {
+ *state = (int)nla_get_u32(tb[NL80211_ATTR_PS_STATE]);
+ wpa_printf(MSG_DEBUG, "nl80211: Get power mode = %d", *state);
+ *state = (*state == NL80211_PS_ENABLED) ?
+ WPA_PS_ENABLED : WPA_PS_DISABLED;
+ }
+
+ return NL_SKIP;
+}
+
+static int wpa_driver_get_power_save(void *priv, int *state)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int ret = -1;
+ enum nl80211_ps_state ps_state;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
+ NL80211_CMD_GET_POWER_SAVE, 0);
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+
+ ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state);
+ msg = NULL;
+ if (ret < 0)
+ wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret);
+nla_put_failure:
+ nlmsg_free(msg);
+ return ret;
+}
+
+int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
+ size_t buf_len )
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct ifreq ifr;
+ int ret = 0;
+
+ if (os_strcasecmp(cmd, "STOP") == 0) {
+ linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+ } else if (os_strcasecmp(cmd, "START") == 0) {
+ linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1);
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+ } else if (os_strcasecmp(cmd, "MACADDR") == 0) {
+ u8 macaddr[ETH_ALEN] = {};
+
+ ret = linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, macaddr);
+ if (!ret)
+ ret = os_snprintf(buf, buf_len,
+ "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
+ } else if (os_strcasecmp(cmd, "RELOAD") == 0) {
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+ } else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) {
+ int state;
+
+ state = atoi(cmd + 10);
+ ret = wpa_driver_set_power_save(priv, state);
+ } else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) {
+ int state = -1;
+
+ ret = wpa_driver_get_power_save(priv, &state);
+ if (!ret && (state != -1)) {
+ ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", state);
+ }
+ }
+ return ret;
+}
+#endif
diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk
index c690e1cc..6dc28c01 100644
--- a/src/drivers/drivers.mk
+++ b/src/drivers/drivers.mk
@@ -38,6 +38,9 @@ endif
ifdef CONFIG_DRIVER_NL80211
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211
DRV_OBJS += src/drivers/driver_nl80211.c
+ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
+DRV_OBJS += src/drivers/driver_qcom_cmd_nl80211.c
+endif
DRV_OBJS += src/utils/radiotap.c
NEED_SME=y
NEED_AP_MLME=y
diff --git a/wpa_supplicant/.config b/wpa_supplicant/.config
index c1fd141a..a1d99919 100644
--- a/wpa_supplicant/.config
+++ b/wpa_supplicant/.config
@@ -86,7 +86,7 @@
#CONFIG_DRIVER_WEXT=y
# Driver interface for Linux drivers using the nl80211 kernel interface
-#CONFIG_DRIVER_NL80211=y
+CONFIG_DRIVER_NL80211=y
CONFIG_LIBNL20=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index acb5cd47..339fa9c3 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -35,10 +35,14 @@ L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
L_CFLAGS += -DANDROID_LOG_NAME=\"wpa_supplicant\"
ifdef CONFIG_DRIVER_NL80211
-ifneq ($(BOARD_WLAN_DEVICE), wl12xx_mac80211)
+ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
+ L_CFLAGS += -DANDROID_QCOM_P2P_PATCH
+else
+ifneq ($(BOARD_WLAN_DEVICE),wl12xx_mac80211)
L_CFLAGS += -DANDROID_BRCM_P2P_PATCH
endif
-endif
+endif # QCWCN
+endif # CONFIG_DRIVER_NL80211
ifdef CONFIG_ROAMING
L_CFLAGS += -DCONFIG_ROAMING
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index a1e54565..99e82749 100644..100755
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -50,6 +50,10 @@
#include "bss.h"
#include "scan.h"
+#ifdef ANDROID
+#include <cutils/properties.h>
+#endif
+
const char *wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
"Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi> and contributors";
@@ -2404,6 +2408,8 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
+ property_set("wifi.wpa_supp_ready", "1");
+
return wpa_s;
}
@@ -2439,6 +2445,8 @@ int wpa_supplicant_remove_iface(struct wpa_global *global,
wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
+ property_set("wifi.wpa_supp_ready", "0");
+
if (global->p2p_group_formation == wpa_s)
global->p2p_group_formation = NULL;
wpa_supplicant_deinit_iface(wpa_s, 1, terminate);