aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2010-08-16 14:50:17 -0700
committerDmitry Shmidt <dimitrysh@google.com>2010-08-16 14:50:17 -0700
commit6a7e5896c58217e6cac00218e9dcca199f9e7907 (patch)
treeedcd95efcf9aa62ca48280117233ffc9b145bba1
parent34c53d409e7b538d90037d0048f6a1828d2dcbb8 (diff)
downloadwpa_supplicant_6-6a7e5896c58217e6cac00218e9dcca199f9e7907.tar.gz
WEXT: Add combo scan support (DO NOT MERGE)
Change-Id: Ibedff7e8f75556ba8df7094b7cfa6de1d1eab2a8 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--wpa_supplicant/ctrl_iface.c2
-rw-r--r--wpa_supplicant/scan.c24
-rw-r--r--wpa_supplicant/src/drivers/driver.h18
-rw-r--r--wpa_supplicant/src/drivers/driver_wext.c226
-rw-r--r--wpa_supplicant/src/drivers/driver_wext.h21
-rw-r--r--wpa_supplicant/wpa_supplicant.c24
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h10
7 files changed, 241 insertions, 84 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 2d22e08..a5c256b 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -1633,6 +1633,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
int ctrl_rsp = 0;
int reply_len;
+ wpa_printf(MSG_ERROR, "CMD: %s", buf);
+
if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 624e628..4b15d22 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -92,6 +92,9 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
#endif /* CONFIG_WPS */
+ wpa_printf(MSG_ERROR, "%s: scan_req = %d, ap_scan = %d", __func__,
+ wpa_s->scan_req, wpa_s->conf->ap_scan);
+
if (wpa_s->disconnected && !wpa_s->scan_req) {
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
return;
@@ -162,15 +165,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
return;
}
- wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)",
- ssid ? "specific": "broadcast");
- if (ssid) {
- wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
- ssid->ssid, ssid->ssid_len);
- wpa_s->prev_scan_ssid = ssid;
- } else
- wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
-
#ifdef CONFIG_WPS
wps = wpas_wps_in_use(wpa_s->conf, &req_type);
#endif /* CONFIG_WPS */
@@ -199,14 +193,22 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
wpa_supplicant_notify_scanning(wpa_s, 1);
+ wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)",
+ ssid ? "specific": "broadcast");
+ if (ssid) {
+ wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
+ ssid->ssid, ssid->ssid_len);
+ wpa_s->prev_scan_ssid = ssid;
+ } else
+ wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+
if (wpa_s->use_client_mlme) {
ieee80211_sta_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len);
ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
ssid ? ssid->ssid_len : 0);
} else {
wpa_drv_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len);
- ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0);
+ ret = wpa_drv_scan(wpa_s, &ssid);
}
wpabuf_free(wps_ie);
diff --git a/wpa_supplicant/src/drivers/driver.h b/wpa_supplicant/src/drivers/driver.h
index bb5f5b0..8c9db27 100644
--- a/wpa_supplicant/src/drivers/driver.h
+++ b/wpa_supplicant/src/drivers/driver.h
@@ -369,6 +369,7 @@ struct ieee80211_rx_status {
int ssi;
};
+struct wpa_ssid;
/**
* struct wpa_driver_ops - Driver interface API definition
@@ -572,6 +573,23 @@ struct wpa_driver_ops {
int (*scan)(void *priv, const u8 *ssid, size_t ssid_len);
/**
+ * combo_scan - Request the driver to initiate combo scan
+ * @priv: private driver interface data
+ * @ssid_ptr: specific SSID to scan for (ProbeReq) or %NULL to scan for
+ * all SSIDs (either active scan with broadcast SSID or passive
+ * scan
+ * @ssid_conf: SSID list from configuration
+ *
+ * Returns: 0 on success, -1 on failure
+ *
+ * Once the scan results are ready, the driver should report scan
+ * results event for wpa_supplicant which will eventually request the
+ * results with wpa_driver_get_scan_results().
+ */
+ int (*combo_scan)(void *priv, struct wpa_ssid **ssid_prt,
+ struct wpa_ssid *ssid_conf);
+
+ /**
* get_scan_results - Fetch the latest scan results (old version)
* @priv: private driver interface data
* @results: pointer to buffer for scan results
diff --git a/wpa_supplicant/src/drivers/driver_wext.c b/wpa_supplicant/src/drivers/driver_wext.c
index 2f0771d..1185af9 100644
--- a/wpa_supplicant/src/drivers/driver_wext.c
+++ b/wpa_supplicant/src/drivers/driver_wext.c
@@ -142,7 +142,7 @@ int wpa_driver_wext_get_bssid(void *priv, u8 *bssid)
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
- perror("ioctl[SIOCGIWAP]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIWAP]");
ret = -1;
}
os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
@@ -172,7 +172,7 @@ int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid)
os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN);
if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) {
- perror("ioctl[SIOCSIWAP]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWAP]");
ret = -1;
}
@@ -198,7 +198,7 @@ int wpa_driver_wext_get_ssid(void *priv, u8 *ssid)
iwr.u.essid.length = 32;
if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
- perror("ioctl[SIOCGIWESSID]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIWESSID]");
ret = -1;
} else {
ret = iwr.u.essid.length;
@@ -256,7 +256,7 @@ int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
iwr.u.essid.length = ssid_len;
if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
- perror("ioctl[SIOCSIWESSID]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWESSID]");
ret = -1;
}
@@ -282,7 +282,7 @@ int wpa_driver_wext_set_freq(void *priv, int freq)
iwr.u.freq.e = 1;
if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) {
- perror("ioctl[SIOCSIWFREQ]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWFREQ]");
ret = -1;
}
@@ -363,6 +363,8 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
} else if (os_strncmp(custom, "START", 5) == 0) {
wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+ } else if (os_strncmp(custom, "HANG", 4) == 0) {
+ wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
#endif /* ANDROID */
}
}
@@ -806,7 +808,7 @@ try_again:
(struct sockaddr *) &from, &fromlen);
if (left < 0) {
if (errno != EINTR && errno != EAGAIN)
- perror("recvfrom(netlink)");
+ wpa_printf(MSG_ERROR, "%s: recvfrom(netlink): %d", __func__, errno);
return;
}
@@ -865,7 +867,7 @@ static int wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data *drv,
os_memset(&ifr, 0, sizeof(ifr));
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
- perror("ioctl[SIOCGIFFLAGS]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]");
return -1;
}
*flags = ifr.ifr_flags & 0xffff;
@@ -894,7 +896,7 @@ static int wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data *drv,
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_flags = flags & 0xffff;
if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
- perror("SIOCSIFFLAGS");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]");
return -1;
}
return 0;
@@ -934,14 +936,14 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (drv->ioctl_sock < 0) {
- perror("socket(PF_INET,SOCK_DGRAM)");
+ wpa_printf(MSG_ERROR, "%s: socket(PF_INET,SOCK_DGRAM)", __func__);
os_free(drv);
return NULL;
}
s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (s < 0) {
- perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
+ wpa_printf(MSG_ERROR, "%s: socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)", __func__);
close(drv->ioctl_sock);
os_free(drv);
return NULL;
@@ -951,7 +953,7 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
local.nl_family = AF_NETLINK;
local.nl_groups = RTMGRP_LINK;
if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
- perror("bind(netlink)");
+ wpa_printf(MSG_ERROR, "bind(netlink)");
close(s);
close(drv->ioctl_sock);
os_free(drv);
@@ -964,7 +966,7 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
drv->mlme_sock = -1;
#ifdef ANDROID
drv->errors = 0;
- drv->driver_is_loaded = TRUE;
+ drv->driver_is_started = TRUE;
drv->skip_disconnect = 0;
#endif
wpa_driver_wext_finish_drv_init(drv);
@@ -1074,7 +1076,6 @@ void wpa_driver_wext_deinit(void *priv)
os_free(drv);
}
-
/**
* wpa_driver_wext_scan_timeout - Scan timeout to report scan completion
* @eloop_ctx: Unused
@@ -1089,6 +1090,34 @@ void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx)
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
}
+/**
+ * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ *
+ * This function can be used to set registered timeout when starting a scan to
+ * generate a scan completed event if the driver does not report this.
+ */
+static void wpa_driver_wext_set_scan_timeout(void *priv)
+{
+ struct wpa_driver_wext_data *drv = priv;
+ int timeout = 10; /* In case scan A and B bands it can be long */
+
+ /* Not all drivers generate "scan completed" wireless event, so try to
+ * read results after a timeout. */
+ if (drv->scan_complete_events) {
+ /*
+ * The driver seems to deliver SIOCGIWSCAN events to notify
+ * when scan is complete, so use longer timeout to avoid race
+ * conditions with scanning and following association request.
+ */
+ timeout = 30;
+ }
+ wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds",
+ timeout);
+ eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
+ eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
+ drv->ctx);
+}
/**
* wpa_driver_wext_scan - Request the driver to initiate scan
@@ -1103,7 +1132,7 @@ int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
{
struct wpa_driver_wext_data *drv = priv;
struct iwreq iwr;
- int ret = 0, timeout;
+ int ret = 0;
struct iw_scan_req req;
#ifdef ANDROID
struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
@@ -1140,28 +1169,104 @@ int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
}
if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
- perror("ioctl[SIOCSIWSCAN]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWSCAN]");
ret = -1;
}
- /* Not all drivers generate "scan completed" wireless event, so try to
- * read results after a timeout. */
- timeout = 5;
- if (drv->scan_complete_events) {
- /*
- * The driver seems to deliver SIOCGIWSCAN events to notify
- * when scan is complete, so use longer timeout to avoid race
- * conditions with scanning and following association request.
- */
- timeout = 30;
+ wpa_driver_wext_set_scan_timeout(priv);
+
+ return ret;
+}
+
+/**
+ * wpa_driver_wext_combo_scan - Request the driver to initiate combo scan
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ * @ssid_ptr: Pointer to current SSID from configuration list or %NULL to
+ * scan for all SSIDs (either active scan with broadcast SSID or passive
+ * scan)
+ * @ssid_conf: SSID list from the configuration
+ * Returns: 0 on success, -1 on failure
+ * Also updates @ssid_ptr to next specific scan item
+ */
+int wpa_driver_wext_combo_scan(void *priv, struct wpa_ssid **ssid_ptr,
+ struct wpa_ssid *ssid_conf)
+{
+ char buf[WEXT_CSCAN_BUF_LEN];
+ struct wpa_driver_wext_data *drv = priv;
+ struct iwreq iwr;
+ int ret = 0, timeout, i = 0, bp;
+ struct wpa_ssid *ssid, *ssid_orig;
+ u8 *ssid_nm = NULL;
+ size_t ssid_len = 0;
+
+ struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+ int scan_probe_flag = 0;
+
+ if (!drv->driver_is_started) {
+ wpa_printf(MSG_DEBUG, "%s: Driver stopped", __func__);
+ return -1;
}
- wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
- "seconds", ret, timeout);
- eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
- eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
- drv->ctx);
+
+ wpa_printf(MSG_DEBUG, "%s: Start", __func__);
+
+ /* Set list of SSIDs */
+ ssid_orig = (*ssid_ptr);
+ ssid = (*ssid_ptr) ? (*ssid_ptr) : ssid_conf;
+ bp = WEXT_CSCAN_HEADER_SIZE;
+ os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
+ while (i < WEXT_CSCAN_AMOUNT) {
+ if ((bp + IW_ESSID_MAX_SIZE + 10) >= (int)sizeof(buf))
+ break;
+ *ssid_ptr = ssid;
+ if (ssid == NULL)
+ break;
+ if (!ssid->disabled && ssid->scan_ssid) {
+ wpa_printf(MSG_DEBUG, "For Scan: %s", ssid->ssid);
+ buf[bp++] = WEXT_CSCAN_SSID_SECTION;
+ buf[bp++] = ssid->ssid_len;
+ os_memcpy(&buf[bp], ssid->ssid, ssid->ssid_len);
+ bp += ssid->ssid_len;
+ i++;
+ }
+ ssid = ssid->next;
+ }
+
+ /* Set list of channels */
+ buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
+ buf[bp++] = 0;
+
+ /* Set passive dwell time (default is 250) */
+ buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
+ buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME;
+ buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME >> 8);
+
+ /* Set home dwell time (default is 40) */
+ buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
+ buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
+ buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
+
+ os_memset(&iwr, 0, sizeof(iwr));
+ os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ iwr.u.data.pointer = buf;
+ iwr.u.data.length = bp;
+
+ if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (cscan): %d", ret);
+ *ssid_ptr = ssid_orig;
+ goto old_scan;
+ }
+
+ wpa_driver_wext_set_scan_timeout(priv);
return ret;
+
+old_scan:
+ if (*ssid_ptr) {
+ ssid_nm = (*ssid_ptr)->ssid;
+ ssid_len = (*ssid_ptr)->ssid_len;
+ }
+
+ return wpa_driver_wext_scan(priv, ssid_nm, ssid_len);
}
@@ -1195,7 +1300,7 @@ static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
"trying larger buffer (%lu bytes)",
(unsigned long) res_buf_len);
} else {
- perror("ioctl[SIOCGIWSCAN]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIWSCAN]: %d", errno);
os_free(res_buf);
return NULL;
}
@@ -1633,7 +1738,7 @@ static int wpa_driver_wext_get_range(void *priv)
sizeof(range->enc_capa);
if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
- perror("ioctl[SIOCGIWRANGE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIRANGE]");
os_free(range);
return -1;
} else if (iwr.u.data.length >= minlen &&
@@ -1718,7 +1823,7 @@ static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
if (ret < 0)
- perror("ioctl[SIOCSIWENCODEEXT] PMK");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT] PMK");
os_free(ext);
return ret;
@@ -1811,7 +1916,7 @@ static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg,
ret = -2;
}
- perror("ioctl[SIOCSIWENCODEEXT]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT]");
}
os_free(ext);
@@ -1885,7 +1990,7 @@ int wpa_driver_wext_set_key(void *priv, wpa_alg alg,
iwr.u.encoding.length = key_len;
if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
- perror("ioctl[SIOCSIWENCODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]");
ret = -1;
}
@@ -1897,7 +2002,7 @@ int wpa_driver_wext_set_key(void *priv, wpa_alg alg,
iwr.u.encoding.pointer = (caddr_t) NULL;
iwr.u.encoding.length = 0;
if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
- perror("ioctl[SIOCSIWENCODE] (set_tx)");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE] (set_tx)");
ret = -1;
}
}
@@ -1946,7 +2051,7 @@ static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,
iwr.u.data.length = sizeof(mlme);
if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
- perror("ioctl[SIOCSIWMLME]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMLME]");
ret = -1;
}
@@ -1971,7 +2076,7 @@ static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
os_memset(&iwr, 0, sizeof(iwr));
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
- perror("ioctl[SIOCGIWMODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIWMODE]");
iwr.u.mode = IW_MODE_INFRA;
}
@@ -2029,7 +2134,7 @@ static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
iwr.u.data.length = ie_len;
if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
- perror("ioctl[SIOCSIWGENIE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWGENIE]");
ret = -1;
}
@@ -2106,7 +2211,7 @@ wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv,
}
if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
- perror("ioctl[SIOCSIWENCODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]");
ret = -1;
}
@@ -2268,7 +2373,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
}
if (errno != EBUSY) {
- perror("ioctl[SIOCSIWMODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMODE]");
goto done;
}
@@ -2277,7 +2382,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
* down, try to set the mode again, and bring it back up.
*/
if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
- perror("ioctl[SIOCGIWMODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCGIWMODE]");
goto done;
}
@@ -2292,7 +2397,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
/* Try to set the mode again while the interface is down */
iwr.u.mode = new_mode;
if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
- perror("ioctl[SIOCSIWMODE]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMODE]");
else
ret = 0;
@@ -2329,7 +2434,7 @@ static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
if (errno != EOPNOTSUPP)
- perror("ioctl[SIOCSIWPMKSA]");
+ wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPMKSA]");
ret = -1;
}
@@ -2428,29 +2533,26 @@ static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t
wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
- if (!drv->driver_is_loaded && (os_strcasecmp(cmd, "START") != 0)) {
+ if (!drv->driver_is_started && (os_strcasecmp(cmd, "START") != 0)) {
wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet");
return -1;
}
if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
os_strncpy(cmd, "RSSI", MAX_DRV_CMD_SIZE);
- }
- else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
+ } else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
int no_of_chan;
no_of_chan = atoi(cmd + 13);
os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s",
wpa_driver_get_country_code(no_of_chan));
- }
- else if (os_strcasecmp(cmd, "STOP") == 0) {
+ } else if (os_strcasecmp(cmd, "STOP") == 0) {
if ((wpa_driver_wext_get_ifflags(drv, &flags) == 0) &&
(flags & IFF_UP)) {
wpa_printf(MSG_ERROR, "WEXT: %s when iface is UP", cmd);
wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
}
- }
- else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
+ } else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
wpa_printf(MSG_DEBUG,"Reload command");
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
return ret;
@@ -2462,9 +2564,7 @@ static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t
iwr.u.data.pointer = buf;
iwr.u.data.length = buf_len;
- if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
- perror("ioctl[SIOCSIWPRIV]");
- }
+ ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
if (ret < 0) {
wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd);
@@ -2473,22 +2573,21 @@ static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t
drv->errors = 0;
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
}
- }
- else {
+ } else {
drv->errors = 0;
ret = 0;
if ((os_strcasecmp(cmd, "RSSI") == 0) ||
(os_strcasecmp(cmd, "LINKSPEED") == 0) ||
- (os_strcasecmp(cmd, "MACADDR") == 0)) {
+ (os_strcasecmp(cmd, "MACADDR") == 0) ||
+ (os_strcasecmp(cmd, "GETPOWER") == 0) ||
+ (os_strcasecmp(cmd, "GETBAND") == 0)) {
ret = strlen(buf);
- }
- else if (os_strcasecmp(cmd, "START") == 0) {
- drv->driver_is_loaded = TRUE;
+ } else if (os_strcasecmp(cmd, "START") == 0) {
+ drv->driver_is_started = TRUE;
/* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */
- }
- else if (os_strcasecmp(cmd, "STOP") == 0) {
- drv->driver_is_loaded = FALSE;
+ } else if (os_strcasecmp(cmd, "STOP") == 0) {
+ drv->driver_is_started = FALSE;
/* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */
}
wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
@@ -2508,6 +2607,7 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
.set_countermeasures = wpa_driver_wext_set_countermeasures,
.set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted,
.scan = wpa_driver_wext_scan,
+ .combo_scan = wpa_driver_wext_combo_scan,
.get_scan_results2 = wpa_driver_wext_get_scan_results,
.deauthenticate = wpa_driver_wext_deauthenticate,
.disassociate = wpa_driver_wext_disassociate,
diff --git a/wpa_supplicant/src/drivers/driver_wext.h b/wpa_supplicant/src/drivers/driver_wext.h
index f6b76a9..29ef44b 100644
--- a/wpa_supplicant/src/drivers/driver_wext.h
+++ b/wpa_supplicant/src/drivers/driver_wext.h
@@ -45,7 +45,7 @@ struct wpa_driver_wext_data {
int scan_complete_events;
#ifdef ANDROID
int errors;
- int driver_is_loaded;
+ int driver_is_started;
int skip_disconnect;
#endif
};
@@ -63,6 +63,8 @@ int wpa_driver_wext_set_key(void *priv, wpa_alg alg,
int set_tx, const u8 *seq, size_t seq_len,
const u8 *key, size_t key_len);
int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len);
+int wpa_driver_wext_combo_scan(void *priv, struct wpa_ssid **ssid_ptr,
+ struct wpa_ssid *ssid_conf);
struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv);
void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx);
@@ -92,6 +94,23 @@ int wpa_driver_wext_keymgmt2wext(int keymgmt);
#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"
+#define WEXT_CSCAN_HEADER_SIZE 12
+#define WEXT_CSCAN_SSID_SECTION 'S'
+#define WEXT_CSCAN_CHANNEL_SECTION 'C'
+#define WEXT_CSCAN_NPROBE_SECTION 'N'
+#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
+#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
+#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
+#define WEXT_CSCAN_TYPE_SECTION 'T'
+#define WEXT_CSCAN_TYPE_DEFAULT 0
+#define WEXT_CSCAN_TYPE_PASSIVE 1
+#define WEXT_CSCAN_PASV_DWELL_TIME 130
+#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
+#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
+#define WEXT_CSCAN_HOME_DWELL_TIME 130
#endif
#endif /* DRIVER_WEXT_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index b66061e..beec16e 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1484,6 +1484,30 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
return NULL;
}
+int wpa_drv_scan(struct wpa_supplicant *wpa_s, struct wpa_ssid **ssid_ptr)
+{
+ u8 *ssid_nm = NULL;
+ size_t ssid_len = 0;
+ int ret = -1;
+
+ if (wpa_s->driver->combo_scan) {
+ ret = wpa_s->driver->combo_scan(wpa_s->drv_priv, ssid_ptr,
+ wpa_s->conf->ssid);
+ if (!ret) {
+ wpa_s->prev_scan_ssid = (*ssid_ptr) ?
+ (*ssid_ptr) : BROADCAST_SSID_SCAN;
+ }
+ }
+ else if (wpa_s->driver->scan) {
+ if (*ssid_ptr) {
+ ssid_nm = (*ssid_ptr)->ssid;
+ ssid_len = (*ssid_ptr)->ssid_len;
+ }
+
+ ret = wpa_s->driver->scan(wpa_s->drv_priv, ssid_nm, ssid_len);
+ }
+ return ret;
+}
static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
const char *name)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 188d9a6..0771077 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -421,6 +421,7 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
int scanning);
+int wpa_drv_scan(struct wpa_supplicant *wpa_s, struct wpa_ssid **ssid_prt);
/* events.c */
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
@@ -507,15 +508,6 @@ static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,
return -1;
}
-static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s, const u8 *ssid,
- size_t ssid_len)
-{
- if (wpa_s->driver->scan) {
- return wpa_s->driver->scan(wpa_s->drv_priv, ssid, ssid_len);
- }
- return -1;
-}
-
static inline int wpa_drv_get_scan_results(struct wpa_supplicant *wpa_s,
struct wpa_scan_result *results,
size_t max_size)