libs/iwinfo: return bitrate in kilobits to properly handle .5 rates
[project/luci.git] / libs / iwinfo / src / iwinfo_wext_scan.c
index 63231b8..2023623 100644 (file)
@@ -43,7 +43,7 @@ static double wext_freq2float(const struct iw_freq *in)
        return res;
 }
 
-static int wext_extract_event(struct stream_descr *stream, struct iw_event *iwe)
+static int wext_extract_event(struct stream_descr *stream, struct iw_event *iwe, int wev)
 {
        const struct iw_ioctl_description *descr = NULL;
        int event_type = 0;
@@ -83,6 +83,10 @@ static int wext_extract_event(struct stream_descr *stream, struct iw_event *iwe)
        /* Unknown events -> event_type=0 => IW_EV_LCP_PK_LEN */
        event_len = event_type_size[event_type];
 
+       /* Fixup for earlier version of WE */
+       if((wev <= 18) && (event_type == IW_HEADER_TYPE_POINT))
+               event_len += IW_EV_POINT_OFF;
+
        /* Check if we know about this event */
        if(event_len <= IW_EV_LCP_PK_LEN)
        {
@@ -109,7 +113,7 @@ static int wext_extract_event(struct stream_descr *stream, struct iw_event *iwe)
 
        /* Fixup for WE-19 and later : pointer no longer in the stream */
        /* Beware of alignement. Dest has local alignement, not packed */
-       if( event_type == IW_HEADER_TYPE_POINT )
+       if( (wev > 18) && (event_type == IW_HEADER_TYPE_POINT) )
                memcpy((char *) iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pointer, event_len);
        else
                memcpy((char *) iwe + IW_EV_LCP_LEN, pointer, event_len);
@@ -230,11 +234,6 @@ static inline void wext_fill_wpa(unsigned char *iebuf, int buflen, struct iwinfo
 
        struct iwinfo_crypto_entry *ce = &e->crypto;
 
-       if( !ce->enabled )
-               return;
-
-       //memset(&e->crypto, 0, sizeof(struct iwinfo_crypto_entry));
-
        if(ielen > buflen)
                ielen = buflen;
 
@@ -284,20 +283,23 @@ static inline void wext_fill_wpa(unsigned char *iebuf, int buflen, struct iwinfo
 
        if(ielen < (offset + 4))
        {
-               ce->group_ciphers[2] = 1; /* TKIP */
+               ce->group_ciphers |= (1<<2); /* TKIP */
+               ce->pair_ciphers  |= (1<<2); /* TKIP */
+               ce->auth_suites   |= (1<<2); /* PSK */
                return;
        }
 
        if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
-               ce->group_ciphers[7] = 1; /* Proprietary */
+               ce->group_ciphers |= (1<<7); /* Proprietary */
        else
-               ce->group_ciphers[iebuf[offset+3]] = 1;
+               ce->group_ciphers |= (1<<iebuf[offset+3]);
 
        offset += 4;
 
        if(ielen < (offset + 2))
        {
-               ce->pair_ciphers[2] = 1; /* TKIP */
+               ce->pair_ciphers |= (1<<2); /* TKIP */
+               ce->auth_suites  |= (1<<2); /* PSK */
                return;
        }
 
@@ -312,9 +314,9 @@ static inline void wext_fill_wpa(unsigned char *iebuf, int buflen, struct iwinfo
        for(i = 0; i < cnt; i++)
        {
                if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
-                       ce->pair_ciphers[7] = 1; /* Proprietary */
+                       ce->pair_ciphers |= (1<<7); /* Proprietary */
                else if(iebuf[offset+3] <= IW_IE_CYPHER_NUM)
-                       ce->pair_ciphers[iebuf[offset+3]] = 1;
+                       ce->pair_ciphers |= (1<<iebuf[offset+3]);
                //else
                //      ce->pair_ciphers[ce->pair_cipher_num++] = 255; /* Unknown */
 
@@ -336,9 +338,9 @@ static inline void wext_fill_wpa(unsigned char *iebuf, int buflen, struct iwinfo
        for(i = 0; i < cnt; i++)
        {
                if(memcmp(&iebuf[offset], wpa_oui, 3) != 0)
-                       ce->auth_suites[7] = 1; /* Proprietary */
+                       ce->auth_suites |= (1<<7); /* Proprietary */
                else if(iebuf[offset+3] <= IW_IE_KEY_MGMT_NUM)
-                       ce->auth_suites[iebuf[offset+3]] = 1;
+                       ce->auth_suites |= (1<<iebuf[offset+3]);
                //else
                //      ce->auth_suites[ce->auth_suite_num++] = 255; /* Unknown */
 
@@ -347,7 +349,7 @@ static inline void wext_fill_wpa(unsigned char *iebuf, int buflen, struct iwinfo
 }
 
 
-static inline int wext_fill_entry(struct stream_descr *stream, struct iw_event *event,
+static inline void wext_fill_entry(struct stream_descr *stream, struct iw_event *event,
        struct iw_range *iw_range, int has_range, struct iwinfo_scanlist_entry *e)
 {
        int i;
@@ -388,6 +390,7 @@ static inline int wext_fill_entry(struct stream_descr *stream, struct iw_event *
                                        sprintf((char *) e->mode, "Ad-Hoc");
                                        break;
 
+                               case 2:
                                case 3:
                                        sprintf((char *) e->mode, "Master");
                                        break;
@@ -408,6 +411,11 @@ static inline int wext_fill_entry(struct stream_descr *stream, struct iw_event *
                        e->crypto.enabled = !(event->u.data.flags & IW_ENCODE_DISABLED);
                        break;
 
+               case IWEVQUAL:
+                       e->signal = event->u.qual.level;
+                       e->quality = event->u.qual.qual;
+                       e->quality_max = iw_range->max_qual.qual;
+                       break;
 #if 0
                case SIOCGIWRATE:
                        if(state->val_index == 0)
@@ -450,8 +458,6 @@ static inline int wext_fill_entry(struct stream_descr *stream, struct iw_event *
 
                        break;
        }
-
-       return 0;
 }
 
 
@@ -459,7 +465,6 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
 {
        struct iwreq wrq;
        struct iw_scan_req scanopt;        /* Options for 'set' */
-       //int scanflags = 0;      /* Flags for scan */
        unsigned char *buffer = NULL;      /* Results */
        int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
        struct iw_range range;
@@ -467,10 +472,9 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
        struct timeval tv;             /* Select timeout */
        int timeout = 15000000;     /* 15s */
 
-       int _len = 0;
+       int entrylen = 0;
        struct iwinfo_scanlist_entry e;
 
-       //IWINFO_BUFSIZE
        wrq.u.data.pointer = (caddr_t) &range;
        wrq.u.data.length  = sizeof(struct iw_range);
        wrq.u.data.flags   = 0; 
@@ -600,7 +604,7 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
                                do
                                {
                                        /* Extract an event and print it */
-                                       ret = wext_extract_event(&stream, &iwe);
+                                       ret = wext_extract_event(&stream, &iwe, range.we_version_compiled);
 
                                        if(ret >= 0)
                                        {
@@ -610,10 +614,14 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
                                                        {
                                                                first = 0;
                                                        }
-                                                       else if( (_len + sizeof(struct iwinfo_scanlist_entry)) <= IWINFO_BUFSIZE )
+                                                       else if( (entrylen + sizeof(struct iwinfo_scanlist_entry)) <= IWINFO_BUFSIZE )
                                                        {
-                                                               memcpy(&buf[_len], &e, sizeof(struct iwinfo_scanlist_entry));
-                                                               _len += sizeof(struct iwinfo_scanlist_entry);
+                                                               /* if encryption is off, clear the crypto strunct */
+                                                               if( !e.crypto.enabled )
+                                                                       memset(&e.crypto, 0, sizeof(struct iwinfo_crypto_entry));
+
+                                                               memcpy(&buf[entrylen], &e, sizeof(struct iwinfo_scanlist_entry));
+                                                               entrylen += sizeof(struct iwinfo_scanlist_entry);
                                                        }
                                                        else
                                                        {
@@ -630,7 +638,7 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
                                } while(ret > 0);
 
                                free(buffer);
-                               *len = _len;
+                               *len = entrylen;
                                return 0;
                        }