OSDN Git Service

Add ANDROID-related changes
[android-x86/external-wpa_supplicant_6.git] / wpa_supplicant / src / drivers / driver_wext.c
index 8c2daa8..57ed33f 100644 (file)
@@ -21,6 +21,7 @@
 #include "includes.h"
 #include <sys/ioctl.h>
 #include <net/if_arp.h>
+#include <net/if.h>
 
 #include "wireless_copy.h"
 #include "common.h"
@@ -30,6 +31,9 @@
 #include "driver_wext.h"
 #include "ieee802_11_defs.h"
 #include "wpa_common.h"
+#include "wpa_ctrl.h"
+#include "wpa_supplicant_i.h"
+#include "config_ssid.h"
 
 
 static int wpa_driver_wext_flush_pmkid(void *priv);
@@ -352,6 +356,12 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
                }
                wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
 #endif /* CONFIG_PEERKEY */
+#ifdef ANDROID
+       } else if (os_strncmp(custom, "STOP", 4) == 0) {
+               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");
+#endif /* ANDROID */
        }
 }
 
@@ -1073,6 +1083,10 @@ int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
        struct iwreq iwr;
        int ret = 0, timeout;
        struct iw_scan_req req;
+#ifdef ANDROID
+       struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+       int scan_probe_flag = 0;
+#endif
 
        if (ssid_len > IW_ESSID_MAX_SIZE) {
                wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
@@ -1083,7 +1097,14 @@ int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
        os_memset(&iwr, 0, sizeof(iwr));
        os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
 
+#ifdef ANDROID
+       if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
+               scan_probe_flag = wpa_s->prev_scan_ssid->scan_ssid;
+       }
+       if (scan_probe_flag && (ssid && ssid_len)) {
+#else
        if (ssid && ssid_len) {
+#endif
                os_memset(&req, 0, sizeof(req));
                req.essid_len = ssid_len;
                req.bssid.sa_family = ARPHRD_ETHER;
@@ -1467,6 +1488,14 @@ struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv)
        struct wpa_scan_results *res;
        struct wext_scan_data data;
 
+#ifdef ANDROID
+       /* To make sure correctly parse scan results which is impacted by wext
+        * version, first check range->we_version, if it is default value (0),
+        * update again here */
+       if (drv->we_version_compiled == 0)
+               wpa_driver_wext_get_range(drv);
+#endif
+
        res_buf = wpa_driver_wext_giwscan(drv, &len);
        if (res_buf == NULL)
                return NULL;
@@ -2046,10 +2075,16 @@ int wpa_driver_wext_associate(void *priv,
        struct wpa_driver_wext_data *drv = priv;
        int ret = 0;
        int allow_unencrypted_eapol;
-       int value;
+       int value, flags;
 
        wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
 
+       if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
+               if (!(flags & IFF_UP)) {
+                       wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+               }
+       }
+
        /*
         * If the driver did not support SIOCSIWAUTH, fallback to
         * SIOCSIWENCODE here.
@@ -2323,6 +2358,70 @@ int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
 }
 
 
+#ifdef ANDROID
+static char *wpa_driver_get_country_code(int channels)
+{
+       char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
+
+       if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI)
+               country = "EU";
+       else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1)
+               country = "JP";
+       return country;
+}
+
+static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
+{
+       struct wpa_driver_wext_data *drv = priv;
+       struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+       struct iwreq iwr;
+       int ret = 0;
+
+       wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
+
+       if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
+               os_strncpy(cmd, "RSSI", MAX_DRV_CMD_SIZE);
+       }
+       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));
+       }
+       os_memset(&iwr, 0, sizeof(iwr));
+       os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+       os_memcpy(buf, cmd, strlen(cmd) + 1);
+       iwr.u.data.pointer = buf;
+       iwr.u.data.length = buf_len;
+
+       if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
+               perror("ioctl[SIOCSIWPRIV]");
+       }
+
+       if (ret < 0)
+               wpa_printf(MSG_ERROR, "%s failed", __func__);
+       else {
+               ret = 0;
+               if ((os_strcasecmp(cmd, "RSSI") == 0) ||
+                   (os_strcasecmp(cmd, "LINKSPEED") == 0) ||
+                   (os_strcasecmp(cmd, "MACADDR") == 0)) {
+                       ret = strlen(buf);
+               }
+/*             else if (os_strcasecmp(cmd, "START") == 0) {
+                       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) {
+                       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));
+       }
+       return ret;
+}
+#endif
+
+
 const struct wpa_driver_ops wpa_driver_wext_ops = {
        .name = "wext",
        .desc = "Linux wireless extensions (generic)",
@@ -2346,4 +2445,7 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
        .flush_pmkid = wpa_driver_wext_flush_pmkid,
        .get_capa = wpa_driver_wext_get_capa,
        .set_operstate = wpa_driver_wext_set_operstate,
+#ifdef ANDROID
+       .driver_cmd = wpa_driver_priv_driver_cmd,
+#endif
 };