diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2010-08-16 14:50:17 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2010-08-16 14:50:17 -0700 |
commit | 6a7e5896c58217e6cac00218e9dcca199f9e7907 (patch) | |
tree | edcd95efcf9aa62ca48280117233ffc9b145bba1 | |
parent | 34c53d409e7b538d90037d0048f6a1828d2dcbb8 (diff) | |
download | wpa_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.c | 2 | ||||
-rw-r--r-- | wpa_supplicant/scan.c | 24 | ||||
-rw-r--r-- | wpa_supplicant/src/drivers/driver.h | 18 | ||||
-rw-r--r-- | wpa_supplicant/src/drivers/driver_wext.c | 226 | ||||
-rw-r--r-- | wpa_supplicant/src/drivers/driver_wext.h | 21 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.c | 24 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant_i.h | 10 |
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) |