diff options
| author | Santosh Sajjan <ssajjan@codeaurora.org> | 2011-11-18 13:27:21 +0530 |
|---|---|---|
| committer | Ethan Chen <intervigil@gmail.com> | 2012-05-21 22:33:08 -0700 |
| commit | 38715b525e1d98620deabe9299060762be0380b9 (patch) | |
| tree | 1c56ba333f7a58bfab0c8221b39ca256f8cf9bfd | |
| parent | 6c70d496d0eae3ee18e496baf0e3e561c450d34c (diff) | |
| download | android_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/.config | 2 | ||||
| -rw-r--r-- | hostapd/Android.mk | 6 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.c | 131 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.h | 157 | ||||
| -rw-r--r-- | src/drivers/driver_qcom_cmd_nl80211.c | 137 | ||||
| -rw-r--r-- | src/drivers/drivers.mk | 3 | ||||
| -rw-r--r-- | wpa_supplicant/.config | 2 | ||||
| -rw-r--r-- | wpa_supplicant/Android.mk | 8 | ||||
| -rwxr-xr-x[-rw-r--r--] | wpa_supplicant/wpa_supplicant.c | 8 |
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); |
