summaryrefslogtreecommitdiffstats
path: root/bcmdhd/wpa_supplicant_8_lib
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-07-18 10:39:22 -0700
committerDmitry Shmidt <dimitrysh@google.com>2011-07-19 16:51:17 -0700
commit991c6863090c21e49229be18a6859d0ec5eaac17 (patch)
treedb5faab09886e9395c759b2048cc0e769f1d7821 /bcmdhd/wpa_supplicant_8_lib
parentab02c0b81a08e4a36ea8ebf3b4fc713c4808ec56 (diff)
downloadhardware_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.h53
-rw-r--r--bcmdhd/wpa_supplicant_8_lib/driver_cmd_nl80211.c127
-rw-r--r--bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.c7
-rw-r--r--bcmdhd/wpa_supplicant_8_lib/driver_cmd_wext.h34
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 */