diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2011-07-18 10:39:22 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2011-07-19 16:51:17 -0700 |
commit | 991c6863090c21e49229be18a6859d0ec5eaac17 (patch) | |
tree | db5faab09886e9395c759b2048cc0e769f1d7821 /bcmdhd/wpa_supplicant_8_lib | |
parent | ab02c0b81a08e4a36ea8ebf3b4fc713c4808ec56 (diff) | |
download | hardware_broadcom_wlan-991c6863090c21e49229be18a6859d0ec5eaac17.zip hardware_broadcom_wlan-991c6863090c21e49229be18a6859d0ec5eaac17.tar.gz hardware_broadcom_wlan-991c6863090c21e49229be18a6859d0ec5eaac17.tar.bz2 |
bcmdhd: wpa_supplicant: Add BGSCAN-START/STOP support
Change-Id: Iaedc340f84650af422bd2ea57d2a8b0a9d4a5330
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'bcmdhd/wpa_supplicant_8_lib')
-rw-r--r-- | bcmdhd/wpa_supplicant_8_lib/driver_cmd_common.h | 53 | ||||
-rw-r--r-- | bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c | 127 | ||||
-rw-r--r-- | bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c | 7 | ||||
-rw-r--r-- | bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h | 34 |
4 files changed, 177 insertions, 44 deletions
diff --git a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_common.h b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_common.h new file mode 100644 index 0000000..5469e99 --- /dev/null +++ b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_common.h @@ -0,0 +1,53 @@ +/* + * Driver interaction for private interface + * + * 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. + * + */ +#ifndef DRIVER_CMD_COMMON_H +#define DRIVER_CMD_COMMON_H + +#include "config_ssid.h" + +#define MAX_DRV_CMD_SIZE 248 +#define DRV_NUMBER_SEQUENTIAL_ERRORS 4 + +#define WEXT_PNOSETUP_HEADER "PNOSETUP " +#define WEXT_PNOSETUP_HEADER_SIZE 9 +#define WEXT_PNO_TLV_PREFIX 'S' +#define WEXT_PNO_TLV_VERSION '1' +#define WEXT_PNO_TLV_SUBVERSION '2' +#define WEXT_PNO_TLV_RESERVED '0' +#define WEXT_PNO_VERSION_SIZE 4 +#define WEXT_PNO_AMOUNT 16 +#define WEXT_PNO_SSID_SECTION 'S' +/* SSID header size is SSID section type above + SSID length */ +#define WEXT_PNO_SSID_HEADER_SIZE 2 +#define WEXT_PNO_SCAN_INTERVAL_SECTION 'T' +#define WEXT_PNO_SCAN_INTERVAL_LENGTH 2 +#define WEXT_PNO_SCAN_INTERVAL 30 +/* Scan interval size is scan interval section type + scan interval length above*/ +#define WEXT_PNO_SCAN_INTERVAL_SIZE (1 + WEXT_PNO_SCAN_INTERVAL_LENGTH) +#define WEXT_PNO_REPEAT_SECTION 'R' +#define WEXT_PNO_REPEAT_LENGTH 1 +#define WEXT_PNO_REPEAT 4 +/* Repeat section size is Repeat section type + Repeat value length above*/ +#define WEXT_PNO_REPEAT_SIZE (1 + WEXT_PNO_REPEAT_LENGTH) +#define WEXT_PNO_MAX_REPEAT_SECTION 'M' +#define WEXT_PNO_MAX_REPEAT_LENGTH 1 +#define WEXT_PNO_MAX_REPEAT 3 +/* Max Repeat section size is Max Repeat section type + Max Repeat value length above*/ +#define WEXT_PNO_MAX_REPEAT_SIZE (1 + WEXT_PNO_MAX_REPEAT_LENGTH) +/* This corresponds to the size of all sections expect SSIDs */ +#define WEXT_PNO_NONSSID_SECTIONS_SIZE (WEXT_PNO_SCAN_INTERVAL_SIZE + WEXT_PNO_REPEAT_SIZE + WEXT_PNO_MAX_REPEAT_SIZE) +/* PNO Max command size is total of header, version, ssid and other sections + Null termination */ +#define WEXT_PNO_MAX_COMMAND_SIZE (WEXT_PNOSETUP_HEADER_SIZE + WEXT_PNO_VERSION_SIZE \ + + WEXT_PNO_AMOUNT * (WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN) \ + + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) + +#endif /* DRIVER_CMD_COMMON_H */ diff --git a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c index ce5b6bb..95b5f26 100644 --- a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c +++ b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c @@ -11,8 +11,12 @@ */ #include "driver_nl80211.h" +#include "driver_cmd_common.h" -#define WPA_EVENT_DRIVER_STATE "CTRL-EVENT-DRIVER-STATE " +#include "wpa_supplicant_i.h" +#include "config.h" + +#define WPA_EVENT_DRIVER_STATE "CTRL-EVENT-DRIVER-STATE " #define WPA_PS_ENABLED 0 #define WPA_PS_DISABLED 1 @@ -27,6 +31,17 @@ int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg, int (*valid_handler)(struct nl_msg *, void *), void *valid_data); +static int drv_errors = 0; + +static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv) +{ + drv_errors++; + if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) { + drv_errors = 0; + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); + } +} + static int wpa_driver_set_btcoex_state(char state) { int ret; @@ -124,6 +139,86 @@ nla_put_failure: return ret; } +static int wpa_driver_set_backgroundscan_params(void *priv) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct wpa_supplicant *wpa_s; + struct ifreq ifr; + android_wifi_priv_cmd priv_cmd; + int ret = 0, i = 0, bp; + char buf[WEXT_PNO_MAX_COMMAND_SIZE]; + struct wpa_ssid *ssid_conf; + + if (drv == NULL) { + wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__); + return -1; + } + if (drv->ctx == NULL) { + wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__); + return -1; + } + wpa_s = (struct wpa_supplicant *)(drv->ctx); + if (wpa_s->conf == NULL) { + wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__); + return -1; + } + ssid_conf = wpa_s->conf->ssid; + + bp = WEXT_PNOSETUP_HEADER_SIZE; + os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp); + buf[bp++] = WEXT_PNO_TLV_PREFIX; + buf[bp++] = WEXT_PNO_TLV_VERSION; + buf[bp++] = WEXT_PNO_TLV_SUBVERSION; + buf[bp++] = WEXT_PNO_TLV_RESERVED; + + while ((i < WEXT_PNO_AMOUNT) && (ssid_conf != NULL)) { + /* Check that there is enough space needed for 1 more SSID, the other sections and null termination */ + if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf)) + break; + if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= MAX_SSID_LEN)){ + wpa_printf(MSG_DEBUG, "For PNO Scan: %s", ssid_conf->ssid); + buf[bp++] = WEXT_PNO_SSID_SECTION; + buf[bp++] = ssid_conf->ssid_len; + os_memcpy(&buf[bp], ssid_conf->ssid, ssid_conf->ssid_len); + bp += ssid_conf->ssid_len; + i++; + } + ssid_conf = ssid_conf->next; + } + + buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION; + os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", WEXT_PNO_SCAN_INTERVAL); + bp += WEXT_PNO_SCAN_INTERVAL_LENGTH; + + buf[bp++] = WEXT_PNO_REPEAT_SECTION; + os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", WEXT_PNO_REPEAT); + bp += WEXT_PNO_REPEAT_LENGTH; + + buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION; + os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", WEXT_PNO_MAX_REPEAT); + bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1; + + memset(&ifr, 0, sizeof(ifr)); + memset(&priv_cmd, 0, sizeof(priv_cmd)); + os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ); + + priv_cmd.buf = buf; + priv_cmd.used_len = bp; + priv_cmd.total_len = bp; + ifr.ifr_data = &priv_cmd; + + ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr); + + if (ret < 0) { + wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret); + wpa_driver_send_hang_msg(drv); + } else { + drv_errors = 0; + } + return ret; +} + int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, size_t buf_len ) { @@ -155,20 +250,38 @@ int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, state = atoi(cmd + 10); ret = wpa_driver_set_power_save(priv, state); + if (ret < 0) + wpa_driver_send_hang_msg(drv); + else + drv_errors = 0; } else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) { int state = -1; ret = wpa_driver_get_power_save(priv, &state); - if (!ret && (state != -1)) + if (!ret && (state != -1)) { ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", state); + drv_errors = 0; + } else { + wpa_driver_send_hang_msg(drv); + } } else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) { char state = cmd[11]; ret = wpa_driver_set_btcoex_state(state); } else { /* Use private command */ + if (os_strcasecmp(cmd, "BGSCAN-START") == 0) { + ret = wpa_driver_set_backgroundscan_params(priv); + if (ret < 0) { + return ret; + } + os_memcpy(buf, "PNOFORCE 1", 11); + } else if (os_strcasecmp(cmd, "BGSCAN-STOP") == 0) { + os_memcpy(buf, "PNOFORCE 0", 11); + } else { + os_memcpy(buf, cmd, strlen(cmd) + 1); + } memset(&ifr, 0, sizeof(ifr)); memset(&priv_cmd, 0, sizeof(priv_cmd)); - os_memcpy(buf, cmd, strlen(cmd) + 1); os_strncpy(ifr.ifr_name, bss->ifname, IFNAMSIZ); priv_cmd.buf = buf; @@ -176,19 +289,19 @@ int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, priv_cmd.total_len = buf_len; ifr.ifr_data = &priv_cmd; - if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) + if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) { wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__); - else { + wpa_driver_send_hang_msg(drv); + } else { + drv_errors = 0; ret = 0; if ((os_strcasecmp(cmd, "LINKSPEED") == 0) || (os_strcasecmp(cmd, "RSSI") == 0) || - (os_strcasecmp(cmd, "GETPOWER") == 0) || (os_strcasecmp(cmd, "GETBAND") == 0)) ret = strlen(buf); wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf)); } } - return ret; } diff --git a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c index c528308..aa2fb4a 100644 --- a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c +++ b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c @@ -30,6 +30,7 @@ #include "scan.h" #include "driver_cmd_wext.h" +#include "driver_cmd_common.h" /** * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion @@ -220,7 +221,7 @@ static int wpa_driver_set_backgroundscan_params(void *priv) bp = WEXT_PNOSETUP_HEADER_SIZE; os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp); - buf[bp++] = 'S'; + buf[bp++] = WEXT_PNO_TLV_PREFIX; buf[bp++] = WEXT_PNO_TLV_VERSION; buf[bp++] = WEXT_PNO_TLV_SUBVERSION; buf[bp++] = WEXT_PNO_TLV_RESERVED; @@ -262,7 +263,7 @@ static int wpa_driver_set_backgroundscan_params(void *priv) if (ret < 0) { wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret); drv->errors++; - if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) { + if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) { drv->errors = 0; wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); } @@ -334,7 +335,7 @@ int wpa_driver_wext_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len if (ret < 0) { wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd); drv->errors++; - if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) { + if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) { drv->errors = 0; wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); } diff --git a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h index a952d7e..1c6e8a1 100644 --- a/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h +++ b/bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h @@ -17,8 +17,6 @@ #define WEXT_NUMBER_SCAN_CHANNELS_MKK1 14 #define WPA_DRIVER_WEXT_WAIT_US 400000 -#define MAX_DRV_CMD_SIZE 248 -#define WEXT_NUMBER_SEQUENTIAL_ERRORS 4 #define WEXT_CSCAN_AMOUNT 9 #define WEXT_CSCAN_BUF_LEN 360 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" @@ -37,36 +35,4 @@ #define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000 #define WEXT_CSCAN_HOME_DWELL_TIME 130 -#define WEXT_PNOSETUP_HEADER "PNOSETUP " -#define WEXT_PNOSETUP_HEADER_SIZE 9 -#define WEXT_PNO_TLV_VERSION '1' -#define WEXT_PNO_TLV_SUBVERSION '2' -#define WEXT_PNO_TLV_RESERVED '0' -#define WEXT_PNO_VERSION_SIZE 4 -#define WEXT_PNO_AMOUNT 16 -#define WEXT_PNO_SSID_SECTION 'S' -/* SSID header size is SSID section type above + SSID length */ -#define WEXT_PNO_SSID_HEADER_SIZE 2 -#define WEXT_PNO_SCAN_INTERVAL_SECTION 'T' -#define WEXT_PNO_SCAN_INTERVAL_LENGTH 2 -#define WEXT_PNO_SCAN_INTERVAL 30 -/* Scan interval size is scan interval section type + scan interval length above*/ -#define WEXT_PNO_SCAN_INTERVAL_SIZE (1 + WEXT_PNO_SCAN_INTERVAL_LENGTH) -#define WEXT_PNO_REPEAT_SECTION 'R' -#define WEXT_PNO_REPEAT_LENGTH 1 -#define WEXT_PNO_REPEAT 4 -/* Repeat section size is Repeat section type + Repeat value length above*/ -#define WEXT_PNO_REPEAT_SIZE (1 + WEXT_PNO_REPEAT_LENGTH) -#define WEXT_PNO_MAX_REPEAT_SECTION 'M' -#define WEXT_PNO_MAX_REPEAT_LENGTH 1 -#define WEXT_PNO_MAX_REPEAT 3 -/* Max Repeat section size is Max Repeat section type + Max Repeat value length above*/ -#define WEXT_PNO_MAX_REPEAT_SIZE (1 + WEXT_PNO_MAX_REPEAT_LENGTH) -/* This corresponds to the size of all sections expect SSIDs */ -#define WEXT_PNO_NONSSID_SECTIONS_SIZE (WEXT_PNO_SCAN_INTERVAL_SIZE + WEXT_PNO_REPEAT_SIZE + WEXT_PNO_MAX_REPEAT_SIZE) -/* PNO Max command size is total of header, version, ssid and other sections + Null termination */ -#define WEXT_PNO_MAX_COMMAND_SIZE (WEXT_PNOSETUP_HEADER_SIZE + WEXT_PNO_VERSION_SIZE \ - + WEXT_PNO_AMOUNT * (WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE) \ - + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) - #endif /* DRIVER_CMD_WEXT_H */ |