OSDN Git Service

wifi
[gb-231r1-is01/GB_2.3_IS01.git] / external / wpa_supplicant / driver_wext.c
index 3c50466..5cb3649 100644 (file)
@@ -21,7 +21,6 @@
 #include "includes.h"
 #include <sys/ioctl.h>
 #include <net/if_arp.h>
-#include <net/if.h>
 
 #include "wireless_copy.h"
 #include "common.h"
@@ -32,9 +31,9 @@
 #include "priv_netlink.h"
 #include "driver_wext.h"
 #include "wpa.h"
+/* [Sharp]20100313 In order to display Link Speed. start */
 #include "wpa_ctrl.h"
-#include "wpa_supplicant_i.h"
-#include "config_ssid.h"
+/* [Sharp]20100313 In order to display Link Speed. end */
 
 #ifdef CONFIG_CLIENT_MLME
 #include <netpacket/packet.h>
@@ -71,6 +70,8 @@ struct wpa_driver_wext_data {
        size_t assoc_req_ies_len;
        u8 *assoc_resp_ies;
        size_t assoc_resp_ies_len;
+       u8 *scan_gen_ies;
+       size_t scan_gen_ies_len;
        struct wpa_driver_capa capa;
        int has_capability;
        int we_version_compiled;
@@ -84,7 +85,12 @@ struct wpa_driver_wext_data {
        char mlmedev[IFNAMSIZ + 1];
 
        int scan_complete_events;
-       int errors;
+       
+       u8 ssid[32];
+       unsigned int ssid_len;
+    /* [Sharp]20100313 In order to display Link Speed. start */
+       unsigned int max_rate;
+    /* [Sharp]20100313 In order to display Link Speed. end */
 };
 
 
@@ -289,6 +295,11 @@ int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
        os_memset(buf, 0, sizeof(buf));
        os_memcpy(buf, ssid, ssid_len);
        iwr.u.essid.pointer = (caddr_t) buf;
+       
+       os_memset(drv->ssid, 0, 32);
+       os_memcpy(drv->ssid, ssid, ssid_len);
+       drv->ssid_len = ssid_len;
+
        if (drv->we_version_compiled < 21) {
                /* For historic reasons, set SSID length to include one extra
                 * character, C string nul termination, even though SSID is
@@ -406,12 +417,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 */
+       /* Android uses the "started" event to take wpa_supplicant out of "STOPPED" mode
+        * Without such a message, the supplicant will not reconnect to an AP following
+        * suspend/resume
+        */
+       } else if (os_strncmp(custom, "STARTED", 7) == 0) {
+               wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
        }
 }
 
@@ -495,6 +506,99 @@ static int wpa_driver_wext_event_wireless_assocrespie(
 
        wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev,
                    len);
+       /* [Sharp]20100313 In order to display Link Speed. start */
+       drv->max_rate = 0;
+    {
+        unsigned int i = 0;
+        unsigned int too_many = 0;
+        unsigned int max_rate = 0;
+        unsigned char ie_len;
+        unsigned char index;
+        
+        while( ( i<(len-2) ) &&  ( too_many < 100 ) )
+        {
+            index = ev[i];
+            ie_len = ev[i+1];
+            
+            if( index == 1 )
+            {
+                unsigned int j;
+                unsigned int end;
+                
+                end = i + ie_len + 2;
+                
+                if( end > len )
+                {
+                    end = len;
+                }
+              
+                /* supported rates */
+                for( j=i+2; j<end; j++ )
+                {
+                    unsigned int rate;
+                    
+                    rate = ev[j] & 0x7f;
+                    if( rate > drv->max_rate )
+                    {
+                        drv->max_rate = rate;
+                    }
+                }
+                
+                break;
+            }
+            
+            i = i + ie_len + 2;
+            
+            too_many++;
+        }
+    }
+    
+    {
+        unsigned int i = 0;
+        unsigned int too_many = 0;
+        unsigned int max_rate = 0;
+        unsigned char ie_len;
+        unsigned char index;
+    
+        while( ( i<(len-2) ) &&  ( too_many < 100 ) )
+        {
+            index = ev[i];
+            ie_len = ev[i+1];
+            
+            if( index == 50 )
+            {
+                unsigned int j;
+                unsigned int end;
+                
+                end = i + ie_len + 2;
+                
+                if( end > len )
+                {
+                    end = len;
+                }
+              
+                /* supported rates */
+                for( j=i+2; j<end; j++ )
+                {
+                    unsigned int rate;
+                    
+                    rate = ev[j] & 0x7f;
+                    if( rate > drv->max_rate )
+                    {
+                        drv->max_rate = rate;
+                    }
+                }
+                
+                break;
+            }
+            
+            i = i + ie_len + 2;
+            
+            too_many++;
+        }
+        wpa_printf(MSG_DEBUG,"Associated Rate %d\n", drv->max_rate );
+    }
+    /* [Sharp]20100313 In order to display Link Speed. end */
        os_free(drv->assoc_resp_ies);
        drv->assoc_resp_ies = os_malloc(len);
        if (drv->assoc_resp_ies == NULL) {
@@ -511,8 +615,11 @@ static int wpa_driver_wext_event_wireless_assocrespie(
 static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv)
 {
        union wpa_event_data data;
+       /* [Sharp]20100225 Measures to reconnect it when WPA/WPA2 security is set. start */
+       int flags = 0;
+       /* [Sharp]20100225 Measures to reconnect it when WPA/WPA2 security is set. end */
 
-       if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL)
+       if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL && drv->scan_gen_ies == NULL)
                return;
 
        os_memset(&data, 0, sizeof(data));
@@ -527,13 +634,72 @@ static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv)
                data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
        }
 
+       if (drv->scan_gen_ies) {
+               data.assoc_info.beacon_ies = drv->scan_gen_ies;
+               drv->scan_gen_ies = NULL;
+               data.assoc_info.beacon_ies_len = drv->scan_gen_ies_len;
+       }
+
+       /* [Sharp]20100225 Measures to reconnect it when WPA/WPA2 security is set. start */
+       if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
+               if (!(flags & IFF_UP))
+                       wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+       }
+       /* [Sharp]20100225 Measures to reconnect it when WPA/WPA2 security is set. end */
+
        wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
 
        os_free(data.assoc_info.req_ies);
        os_free(data.assoc_info.resp_ies);
+        os_free(data.assoc_info.beacon_ies);
+}
+
+static void wpa_driver_wext_update_beacon_ies(struct wpa_driver_wext_data *drv,
+                                              const u8 *bssid)
+{
+#define SCAN_AP_LIMIT 128
+    struct wpa_scan_result *scan_res;
+    struct wpa_scan_result *r;
+    int num;
+    int i;
+
+    scan_res = os_malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result));
+    if (scan_res == NULL) {
+        wpa_printf(MSG_WARNING, "Failed to allocate memory for scan "
+                "results");
+        return;
+    }
+
+    num = wpa_driver_wext_get_scan_results(drv, scan_res, SCAN_AP_LIMIT);
+    if (num < 0) {
+        wpa_printf(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies: failed to get scan results");
+        os_free(scan_res);
+        return;
+    }
+
+    /* Search for the current BSSID */
+    for (i = 0; i < num; i++) {
+        r = &scan_res[i];
+        if (os_memcmp(r->bssid, bssid, ETH_ALEN) != 0)
+            continue;
+
+        os_free(drv->scan_gen_ies);
+        drv->scan_gen_ies = os_malloc(r->wpa_ie_len + r->rsn_ie_len);
+        if (drv->scan_gen_ies == NULL) {
+            drv->scan_gen_ies_len = 0;
+            os_free(scan_res);
+            return;
+        }
+        os_memcpy(drv->scan_gen_ies, r->wpa_ie, r->wpa_ie_len);
+        os_memcpy(drv->scan_gen_ies + r->wpa_ie_len, r->rsn_ie, r->rsn_ie_len);
+        drv->scan_gen_ies_len = r->wpa_ie_len + r->rsn_ie_len;
+        wpa_hexdump(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies:",
+                    drv->scan_gen_ies, drv->scan_gen_ies_len);
+    }
+
+    os_free(scan_res);
 }
 
-
 static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
                                           void *ctx, char *data, int len)
 {
@@ -588,6 +754,7 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
                                                     NULL);
                        
                        } else {
+                               wpa_driver_wext_update_beacon_ies(drv, (const u8*)iwe->u.ap_addr.sa_data);
                                wpa_driver_wext_event_assoc_ies(drv);
                                wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
                        }
@@ -1002,7 +1169,6 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
 
        drv->mlme_sock = -1;
 
-       drv->errors = 0;
        wpa_driver_wext_finish_drv_init(drv);
 
        return drv;
@@ -1013,13 +1179,6 @@ static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
 {
        int flags;
 
-       if (wpa_driver_wext_get_ifflags(drv, &flags) != 0 ||
-           wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
-               printf("Could not set interface '%s' UP\n", drv->ifname);
-       }
-#ifdef ANDROID
-       os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
-#endif
        /*
         * Make sure that the driver does not have any obsolete PMKID entries.
         */
@@ -1029,6 +1188,11 @@ static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
                printf("Could not configure driver to use managed mode\n");
        }
 
+       if (wpa_driver_wext_get_ifflags(drv, &flags) != 0 ||
+           wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
+               printf("Could not set interface '%s' UP\n", drv->ifname);
+       }
+
        wpa_driver_wext_get_range(drv);
 
        drv->ifindex = if_nametoindex(drv->ifname);
@@ -1128,10 +1292,6 @@ 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)",
@@ -1142,14 +1302,7 @@ int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
        os_memset(&iwr, 0, sizeof(iwr));
        os_strncpy(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;
@@ -1251,13 +1404,7 @@ int wpa_driver_wext_get_scan_results(void *priv,
        size_t len, clen, res_buf_len;
 
        os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));
-#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_len = IW_SCAN_MAX_DATA;
        for (;;) {
                res_buf = os_malloc(res_buf_len);
@@ -1396,8 +1543,18 @@ int wpa_driver_wext_get_scan_results(void *priv,
                case IWEVQUAL:
                        if (ap_num < max_size) {
                                results[ap_num].qual = iwe->u.qual.qual;
-                               results[ap_num].noise = iwe->u.qual.noise;
-                               results[ap_num].level = iwe->u.qual.level;
+
+                               if( iwe->u.qual.updated & IW_QUAL_DBM )
+                               {
+                                       /* Values in dBm, stored in u8 with range 63 : -192 */
+                                       results[ap_num].noise = ( iwe->u.qual.noise > 63 ) ? iwe->u.qual.noise - 0x100 : iwe->u.qual.noise;
+                                       results[ap_num].level = ( iwe->u.qual.level > 63 ) ? iwe->u.qual.level - 0x100 : iwe->u.qual.level;
+                               }
+                               else
+                               {
+                                       results[ap_num].noise = iwe->u.qual.noise;
+                                       results[ap_num].level = iwe->u.qual.level;
+                               }
                        }
                        break;
                case SIOCGIWENCODE:
@@ -1943,16 +2100,10 @@ wpa_driver_wext_associate(void *priv,
        struct wpa_driver_wext_data *drv = priv;
        int ret = 0;
        int allow_unencrypted_eapol;
-       int value, flags;
+       int value;
 
        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.
@@ -2510,88 +2661,197 @@ int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
        return drv->we_version_compiled;
 }
 
-#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)
+/*-----------------------------------------------------------------------------
+Routine Name: wpa_driver_wext_driver_cmd
+Routine Description: executes driver-specific commands
+Arguments:
+priv - pointer to private data structure
+cmd - command
+buf - return buffer
+buf_len - buffer length
+Return Value: actual buffer length - success, -1 - failure
+Copied from TI driver
+-----------------------------------------------------------------------------*/
+int wpa_driver_wext_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, flags;
-
-       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));
-       }
-       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 ) {
-               wpa_printf(MSG_DEBUG,"Reload command");
-               wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
-               return ret;
-       }
-
-       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__);
-               drv->errors++;
-               if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) {
-                       drv->errors = 0;
-                       wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
+    int ret = -1;
+
+    wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);
+
+    if( os_strcasecmp(cmd, "start") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Start command");
+               
+        return( ret );
+    }
+
+    if( os_strcasecmp(cmd, "stop") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Stop command");
+    }
+    else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
+               struct ifreq ifr;
+               os_memset(&ifr, 0, sizeof(ifr));
+               os_strncpy(ifr.ifr_name, drv->ifname, IFNAMSIZ);
+
+               if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr) < 0) {
+                       perror("ioctl[SIOCGIFHWADDR]");
+                       ret = -1;
+               } else {
+                       u8 *macaddr = (u8 *)ifr.ifr_hwaddr.sa_data;
+                       ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
                }
        }
-       else {
-               drv->errors = 0;
-               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, "scan-passive") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Scan Passive command");
+    }
+    else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Scan Active command");
+    }
+    else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Link Speed command");
+        /* [Sharp]20100313 In order to display Link Speed. start */
+               ret = os_snprintf(buf, buf_len, "LinkSpeed %u\n", (drv->max_rate/2));
+        /* [Sharp]20100313 In order to display Link Speed. end */
+    }
+    else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
+    }
+    else if( os_strcasecmp(cmd, "rssi") == 0 ) {
+               struct iwreq wrq;
+               struct iw_statistics stats;
+               signed int rssi;
+               
+               wrq.u.data.pointer = (caddr_t) &stats;
+               wrq.u.data.length = sizeof(stats);
+               wrq.u.data.flags = 1; /* Clear updated flag */
+               strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);
+               
+               if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) {
+                       perror("ioctl[SIOCGIWSTATS]");
+                       ret = -1;
+               } else {
+                       if( stats.qual.updated & IW_QUAL_DBM ) {
+                               /* Values in dBm, stored in u8 with range 63 : -192 */
+                               rssi = ( stats.qual.level > 63 ) ? stats.qual.level - 0x100 :  stats.qual.level;
+                       } else {
+                               rssi = stats.qual.level;
+                       }
+                       
+                       if( drv->ssid_len != 0 && drv->ssid_len < buf_len) {
+                               os_memcpy( (void *)buf, (void *)(drv->ssid), drv->ssid_len );
+                               ret = drv->ssid_len;
+                               ret += snprintf(&buf[ret], buf_len-ret, " rssi %d\n", rssi);
+                               if (ret < (int)buf_len) {
+                                       return( ret );
+                               }
+                               ret = -1;
+                       }
                }
-/*             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_strncasecmp(cmd, "powermode", 9) == 0 ) {
+    }
+    else if( os_strncasecmp(cmd, "getpower", 8) == 0 ) {
+    }
+    else if( os_strncasecmp(cmd, "get-rts-threshold", 17) == 0 ) {
+               struct iwreq wrq;
+               unsigned int rtsThreshold;
+
+               strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);
+               
+               if (ioctl(drv->ioctl_sock, SIOCGIWRTS, &wrq) < 0) {
+                       perror("ioctl[SIOCGIWRTS]");
+                       ret = -1;
+               } else {
+                       rtsThreshold = wrq.u.rts.value;
+                       wpa_printf(MSG_DEBUG,"Get RTS Threshold command = %d", rtsThreshold);
+            ret = snprintf(buf, buf_len, "rts-threshold = %u\n", rtsThreshold);
+            if (ret < (int)buf_len) {
+                return( ret );
+            }
+        }
+    }
+    else if( os_strncasecmp(cmd, "set-rts-threshold", 17) == 0 ) {
+               struct iwreq wrq;
+               unsigned int rtsThreshold;
+        char *cp = cmd + 17;
+        char *endp;
+
+               strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);
+               
+        if (*cp != '\0') {
+            rtsThreshold = (unsigned int)strtol(cp, &endp, 0);
+            if (endp != cp) {
+                               wrq.u.rts.value = rtsThreshold;
+                               wrq.u.rts.fixed = 1;
+                               wrq.u.rts.disabled = 0;
+                               
+                               if (ioctl(drv->ioctl_sock, SIOCSIWRTS, &wrq) < 0) {
+                                       perror("ioctl[SIOCGIWRTS]");
+                                       ret = -1;
+                               } else {
+                                       rtsThreshold = wrq.u.rts.value;
+                                       wpa_printf(MSG_DEBUG,"Set RTS Threshold command = %d", rtsThreshold);
+                                       ret = 0;
+                               }
+            }
+        }
+    }
+    else if( os_strcasecmp(cmd, "btcoexscan-start") == 0 ) {
+    }
+    else if( os_strcasecmp(cmd, "btcoexscan-stop") == 0 ) {
+    }
+    else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
+    }
+    else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
+        wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
+    }
+    else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
+    }
+    else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
+    }
+    else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
+    }
+    else if( os_strcasecmp(cmd, "snr") == 0 ) {
+               struct iwreq wrq;
+               struct iw_statistics stats;
+               int snr, rssi, noise;
+               
+               wrq.u.data.pointer = (caddr_t) &stats;
+               wrq.u.data.length = sizeof(stats);
+               wrq.u.data.flags = 1; /* Clear updated flag */
+               strncpy(wrq.ifr_name, drv->ifname, IFNAMSIZ);
+               
+               if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &wrq) < 0) {
+                       perror("ioctl[SIOCGIWSTATS]");
+                       ret = -1;
+               } else {
+                       if( stats.qual.updated & IW_QUAL_DBM ) {
+                               /* Values in dBm, stored in u8 with range 63 : -192 */
+                               rssi = ( stats.qual.level > 63 ) ? stats.qual.level - 0x100 :  stats.qual.level;
+                               noise = ( stats.qual.noise > 63 ) ? stats.qual.noise - 0x100 :  stats.qual.noise;
+                       } else {
+                               rssi = stats.qual.level;
+                               noise = stats.qual.noise;
+                       }
+
+                       snr = rssi - noise;
+                       
+            ret = snprintf(buf, buf_len, "snr = %u\n", (unsigned int)snr);
+            if (ret < (int)buf_len) {
+                return( ret );
+            }
                }
-               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;
+    }
+    else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
+    }
+    else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
+    }
+    else {
+        wpa_printf(MSG_DEBUG,"Unsupported command");
+    }
+    return(ret);
 }
-#endif
+
 
 const struct wpa_driver_ops wpa_driver_wext_ops = {
        .name = "wext",
@@ -2625,7 +2885,5 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
        .mlme_add_sta = wpa_driver_wext_mlme_add_sta,
        .mlme_remove_sta = wpa_driver_wext_mlme_remove_sta,
 #endif /* CONFIG_CLIENT_MLME */
-#ifdef ANDROID
-       .driver_cmd = wpa_driver_priv_driver_cmd,
-#endif
+       .driver_cmd     = wpa_driver_wext_driver_cmd,
 };