diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2011-02-18 16:29:31 -0800 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2011-02-22 16:40:49 -0800 |
commit | f09d4bb307a8a925c098942868c035b67d248e31 (patch) | |
tree | 777b9d36d8b75cfcb49796e01b66cd5df91ba313 | |
parent | a12fdfe7081a569335ae45c9c679ab144d85e3b3 (diff) | |
download | wpa_supplicant_6-f09d4bb307a8a925c098942868c035b67d248e31.tar.gz |
WEXT: Add background scan command support
Change-Id: Ie7d6b9570acbe798bba13b0d99e98e488c682340
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r-- | wpa_supplicant/src/drivers/driver_wext.c | 89 | ||||
-rw-r--r-- | wpa_supplicant/src/drivers/driver_wext.h | 32 |
2 files changed, 120 insertions, 1 deletions
diff --git a/wpa_supplicant/src/drivers/driver_wext.c b/wpa_supplicant/src/drivers/driver_wext.c index 97f1396..4982bff 100644 --- a/wpa_supplicant/src/drivers/driver_wext.c +++ b/wpa_supplicant/src/drivers/driver_wext.c @@ -33,7 +33,7 @@ #include "wpa_common.h" #include "wpa_ctrl.h" #include "wpa_supplicant_i.h" -#include "config_ssid.h" +#include "config.h" static int wpa_driver_wext_flush_pmkid(void *priv); @@ -2587,6 +2587,85 @@ static char *wpa_driver_get_country_code(int channels) return country; } +static int wpa_driver_set_backgroundscan_params(void *priv) +{ + struct wpa_driver_wext_data *drv = priv; + struct wpa_supplicant *wpa_s; + struct iwreq iwr; + 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++] = 'S'; + 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 + IW_ESSID_MAX_SIZE + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf)) + break; + if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= IW_ESSID_MAX_SIZE)){ + 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; + + os_memset(&iwr, 0, sizeof(iwr)); + os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); + iwr.u.data.pointer = buf; + iwr.u.data.length = bp; + + ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr); + + if (ret < 0) { + wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret); + drv->errors++; + if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) { + drv->errors = 0; + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); + } + } else { + drv->errors = 0; + } + return ret; + +} + static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len ) { struct wpa_driver_wext_data *drv = priv; @@ -2619,6 +2698,14 @@ static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t wpa_printf(MSG_DEBUG,"Reload command"); wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); return ret; + } else if( os_strcasecmp(cmd, "BGSCAN-START") == 0 ) { + ret = wpa_driver_set_backgroundscan_params(priv); + if (ret < 0) { + return ret; + } + os_strncpy(cmd, "PNOFORCE 1", MAX_DRV_CMD_SIZE); + } else if( os_strcasecmp(cmd, "BGSCAN-STOP") == 0 ) { + os_strncpy(cmd, "PNOFORCE 0", MAX_DRV_CMD_SIZE); } os_memset(&iwr, 0, sizeof(iwr)); diff --git a/wpa_supplicant/src/drivers/driver_wext.h b/wpa_supplicant/src/drivers/driver_wext.h index 29ef44b..7ba31e8 100644 --- a/wpa_supplicant/src/drivers/driver_wext.h +++ b/wpa_supplicant/src/drivers/driver_wext.h @@ -111,6 +111,38 @@ int wpa_driver_wext_keymgmt2wext(int keymgmt); #define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250 #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 #endif /* DRIVER_WEXT_H */ |