1c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt/* 2c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * Driver interaction with extended Linux Wireless Extensions 3c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * 4c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * This program is free software; you can redistribute it and/or modify 5c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 6c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * published by the Free Software Foundation. 7c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * 8c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 9c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * license. 10c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * 11c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt */ 12c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 13c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "includes.h" 14c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include <sys/ioctl.h> 15c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include <net/if_arp.h> 16c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include <net/if.h> 17c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 18c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "wireless_copy.h" 19c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "common.h" 20c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "driver.h" 21c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "eloop.h" 22c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "priv_netlink.h" 23c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "driver_wext.h" 24c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "ieee802_11_defs.h" 25c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "wpa_common.h" 26c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "wpa_ctrl.h" 27c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "wpa_supplicant_i.h" 28c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "config.h" 29c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "linux_ioctl.h" 30c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "scan.h" 31c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 32c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt#include "driver_cmd_wext.h" 33c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 34c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt/** 35c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion 36c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * @priv: Pointer to private wext data from wpa_driver_wext_init() 37c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * 38c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * This function can be used to set registered timeout when starting a scan to 39c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * generate a scan completed event if the driver does not report this. 40c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt */ 41c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtstatic void wpa_driver_wext_set_scan_timeout(void *priv) 42c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 43c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_driver_wext_data *drv = priv; 44c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int timeout = 10; /* In case scan A and B bands it can be long */ 45c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 46c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Not all drivers generate "scan completed" wireless event, so try to 47c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * read results after a timeout. */ 48c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (drv->scan_complete_events) { 49c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* 50c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * The driver seems to deliver SIOCGIWSCAN events to notify 51c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * when scan is complete, so use longer timeout to avoid race 52c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * conditions with scanning and following association request. 53c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt */ 54c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt timeout = 30; 55c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 56c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds", 57c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt timeout); 58c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); 59c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv, 60c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->ctx); 61c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 62c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 63c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt/** 64c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * wpa_driver_wext_combo_scan - Request the driver to initiate combo scan 65c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * @priv: Pointer to private wext data from wpa_driver_wext_init() 66c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * @params: Scan parameters 67c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt * Returns: 0 on success, -1 on failure 68c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt */ 69c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtint wpa_driver_wext_combo_scan(void *priv, struct wpa_driver_scan_params *params) 70c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 71c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt char buf[WEXT_CSCAN_BUF_LEN]; 72c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_driver_wext_data *drv = priv; 73c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct iwreq iwr; 74c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int ret, bp; 75c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt unsigned i; 76c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx); 77c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 78c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (!drv->driver_is_started) { 79c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Driver stopped", __func__); 80c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return 0; 81c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 82c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 83c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Start", __func__); 84c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 85c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set list of SSIDs */ 86c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp = WEXT_CSCAN_HEADER_SIZE; 87c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(buf, WEXT_CSCAN_HEADER, bp); 88c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt for(i=0; i < params->num_ssids; i++) { 89c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if ((bp + IW_ESSID_MAX_SIZE + 10) >= (int)sizeof(buf)) 90c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt break; 91c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "For Scan: %s", params->ssids[i].ssid); 92c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_SSID_SECTION; 93c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = params->ssids[i].ssid_len; 94c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(&buf[bp], params->ssids[i].ssid, params->ssids[i].ssid_len); 95c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp += params->ssids[i].ssid_len; 96c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 97c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 98c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set list of channels */ 99c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION; 100c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = 0; 101c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 102c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set passive dwell time (default is 250) */ 103c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION; 104c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME; 105c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME >> 8); 106c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 107c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set home dwell time (default is 40) */ 108c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION; 109c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME; 110c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8); 111c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 112c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 113c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 114c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.pointer = buf; 115c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.length = bp; 116c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 117c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) { 118d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt if (!drv->bgscan_enabled) 119d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (cscan): %d", ret); 120d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt else 121d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt ret = 0; /* Hide error in case of bg scan */ 122c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 123c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 124c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 125c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 126c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtstatic int wpa_driver_wext_set_cscan_params(char *buf, size_t buf_len, char *cmd) 127c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 128c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt char *pasv_ptr; 129c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int bp, i; 130c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt u16 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF; 131c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt u8 channel; 132c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 133c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd); 134c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 135c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Get command parameters */ 136c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt pasv_ptr = os_strstr(cmd, ",TIME="); 137c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (pasv_ptr) { 138c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt *pasv_ptr = '\0'; 139c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt pasv_ptr += 6; 140c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt pasv_dwell = (u16)atoi(pasv_ptr); 141c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (pasv_dwell == 0) 142c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF; 143c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 144c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt channel = (u8)atoi(cmd + 5); 145c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 146c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp = WEXT_CSCAN_HEADER_SIZE; 147c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(buf, WEXT_CSCAN_HEADER, bp); 148c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 149c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set list of channels */ 150c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION; 151c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = channel; 152c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (channel != 0) { 153c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt i = (pasv_dwell - 1) / WEXT_CSCAN_PASV_DWELL_TIME_DEF; 154c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt for (; i > 0; i--) { 155c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if ((size_t)(bp + 12) >= buf_len) 156c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt break; 157c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION; 158c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = channel; 159c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 160c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else { 161c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (pasv_dwell > WEXT_CSCAN_PASV_DWELL_TIME_MAX) 162c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_MAX; 163c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 164c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 165c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set passive dwell time (default is 250) */ 166c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION; 167c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (channel != 0) { 168c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME_DEF; 169c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME_DEF >> 8); 170c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else { 171c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)pasv_dwell; 172c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)(pasv_dwell >> 8); 173c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 174c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 175c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set home dwell time (default is 40) */ 176c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION; 177c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME; 178c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8); 179c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 180c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Set cscan type */ 181c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_TYPE_SECTION; 182c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_CSCAN_TYPE_PASSIVE; 183c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return bp; 184c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 185c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 186c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtstatic char *wpa_driver_get_country_code(int channels) 187c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 188c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */ 189c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 190c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI) 191c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt country = "EU"; 192c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1) 193c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt country = "JP"; 194c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return country; 195c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 196c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 197c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtstatic int wpa_driver_set_backgroundscan_params(void *priv) 198c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 199c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_driver_wext_data *drv = priv; 200c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_supplicant *wpa_s; 201c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct iwreq iwr; 202c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int ret = 0, i = 0, bp; 203c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt char buf[WEXT_PNO_MAX_COMMAND_SIZE]; 204c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_ssid *ssid_conf; 205c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 206c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (drv == NULL) { 207c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__); 208c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return -1; 209c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 210c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (drv->ctx == NULL) { 211c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__); 212c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return -1; 213c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 214c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_s = (struct wpa_supplicant *)(drv->ctx); 215c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (wpa_s->conf == NULL) { 216c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__); 217c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return -1; 218c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 219c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ssid_conf = wpa_s->conf->ssid; 220c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 221c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp = WEXT_PNOSETUP_HEADER_SIZE; 222c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp); 223d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt buf[bp++] = WEXT_PNO_TLV_PREFIX; 224c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_TLV_VERSION; 225c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_TLV_SUBVERSION; 226c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_TLV_RESERVED; 227c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 228c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt while ((i < WEXT_PNO_AMOUNT) && (ssid_conf != NULL)) { 229c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* Check that there is enough space needed for 1 more SSID, the other sections and null termination */ 230c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf)) 231c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt break; 232c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= IW_ESSID_MAX_SIZE)){ 233c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "For PNO Scan: %s", ssid_conf->ssid); 234c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_SSID_SECTION; 235c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = ssid_conf->ssid_len; 236c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(&buf[bp], ssid_conf->ssid, ssid_conf->ssid_len); 237c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp += ssid_conf->ssid_len; 238c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt i++; 239c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 240c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ssid_conf = ssid_conf->next; 241c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 242c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 243c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION; 244c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", WEXT_PNO_SCAN_INTERVAL); 245c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp += WEXT_PNO_SCAN_INTERVAL_LENGTH; 246c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 247c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_REPEAT_SECTION; 248c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", WEXT_PNO_REPEAT); 249c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp += WEXT_PNO_REPEAT_LENGTH; 250c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 251c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION; 252c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", WEXT_PNO_MAX_REPEAT); 253c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1; 254c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 255c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 256c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 257c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.pointer = buf; 258c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.length = bp; 259c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 260c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr); 261c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 262c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (ret < 0) { 263c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret); 264c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors++; 265c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) { 266c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors = 0; 267c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); 268c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 269c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else { 270c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors = 0; 271c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 272c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 273c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 274c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 275c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 276c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidtint wpa_driver_wext_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len ) 277c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt{ 278c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_driver_wext_data *drv = priv; 279c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx); 280c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt struct iwreq iwr; 281c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int ret = 0, flags; 282c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 283c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len); 284c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 285c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (!drv->driver_is_started && (os_strcasecmp(cmd, "START") != 0)) { 286c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet"); 287c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return -1; 288c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 289c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 290c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) { 291d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt os_strncpy(cmd, RSSI_CMD, MAX_DRV_CMD_SIZE); 292c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) { 293c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt int no_of_chan; 294c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 295c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt no_of_chan = atoi(cmd + 13); 296c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s", 297c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_driver_get_country_code(no_of_chan)); 298c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if (os_strcasecmp(cmd, "STOP") == 0) { 299f9694904d6ea5c37db1cd48ba0afa16f4bfc9f9aDmitry Shmidt linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); 300c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if( os_strcasecmp(cmd, "RELOAD") == 0 ) { 301c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG,"Reload command"); 302c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); 303c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 304c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if( os_strcasecmp(cmd, "BGSCAN-START") == 0 ) { 305c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ret = wpa_driver_set_backgroundscan_params(priv); 306c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (ret < 0) { 307c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 308c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 309c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_strncpy(cmd, "PNOFORCE 1", MAX_DRV_CMD_SIZE); 310c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->bgscan_enabled = 1; 311c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if( os_strcasecmp(cmd, "BGSCAN-STOP") == 0 ) { 312c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_strncpy(cmd, "PNOFORCE 0", MAX_DRV_CMD_SIZE); 313c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->bgscan_enabled = 0; 314c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 315c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 316c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 317c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 318c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt os_memcpy(buf, cmd, strlen(cmd) + 1); 319c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.pointer = buf; 320c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.length = buf_len; 321c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 322c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if( os_strncasecmp(cmd, "CSCAN", 5) == 0 ) { 323c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (!wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) || 324c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt (wpa_s->wpa_state >= WPA_COMPLETED))) { 325c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt iwr.u.data.length = wpa_driver_wext_set_cscan_params(buf, buf_len, cmd); 326c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else { 327c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "Ongoing Scan action..."); 328c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 329c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 330c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 331c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 332c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr); 333c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt 334c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (ret < 0) { 335c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd); 336c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors++; 337c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) { 338c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors = 0; 339c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); 340c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 341c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else { 342c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->errors = 0; 343c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ret = 0; 344d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt if ((os_strcasecmp(cmd, RSSI_CMD) == 0) || 345d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt (os_strcasecmp(cmd, LINKSPEED_CMD) == 0) || 346c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt (os_strcasecmp(cmd, "MACADDR") == 0) || 347c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt (os_strcasecmp(cmd, "GETPOWER") == 0) || 348c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt (os_strcasecmp(cmd, "GETBAND") == 0)) { 349c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt ret = strlen(buf); 350c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if (os_strcasecmp(cmd, "START") == 0) { 351c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->driver_is_started = TRUE; 352f9694904d6ea5c37db1cd48ba0afa16f4bfc9f9aDmitry Shmidt linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1); 353c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US); 354c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */ 355c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if (os_strcasecmp(cmd, "STOP") == 0) { 356c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt drv->driver_is_started = FALSE; 357c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt /* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */ 358c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } else if (os_strncasecmp(cmd, "CSCAN", 5) == 0) { 359c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_driver_wext_set_scan_timeout(priv); 360c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 361c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 362c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf)); 363c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt } 364c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt return ret; 365c208ac5eb62bad8f6346aaa98c69462dff0337feDmitry Shmidt} 366d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt 367d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidtint wpa_driver_signal_poll(void *priv, struct wpa_signal_info *si) 368d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt{ 369d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt char buf[MAX_DRV_CMD_SIZE]; 370d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt struct wpa_driver_wext_data *drv = priv; 371d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt char *prssi; 372d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt int res; 373d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt 374d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt os_memset(si, 0, sizeof(*si)); 375d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt res = wpa_driver_wext_driver_cmd(priv, RSSI_CMD, buf, sizeof(buf)); 376d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt /* Answer: SSID rssi -Val */ 377d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt if (res < 0) 378d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt return res; 379d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt prssi = strcasestr(buf, RSSI_CMD); 380d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt if (!prssi) 381d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt return -1; 382d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt si->current_signal = atoi(prssi + strlen(RSSI_CMD) + 1); 383d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt 384d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt res = wpa_driver_wext_driver_cmd(priv, LINKSPEED_CMD, buf, sizeof(buf)); 385d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt /* Answer: LinkSpeed Val */ 386d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt if (res < 0) 387d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt return res; 388d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt si->current_txrate = atoi(buf + strlen(LINKSPEED_CMD) + 1) * 1000; 389d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt 390d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt return 0; 391d7edab78ddecd5492c22006c1b1e23c6c6b2a479Dmitry Shmidt} 392