devices: add device id for Realtek RTL8188CU and RTL8188FTV
[project/iwinfo.git] / iwinfo_utils.c
index d071997b4bebd1d1139262988b5f449f24a6797e..d96cbb345e68fb9b9a4d6edcc3067b5a192afd23 100644 (file)
@@ -77,6 +77,145 @@ int iwinfo_mw2dbm(int in)
        return (int)res;
 }
 
+static int iwinfo_bit(int value, int max)
+{
+       int i;
+
+       if (max > 31 || !(value & ((1 << max) - 1)))
+               return -1;
+
+       for (i = 0; i < max; i++)
+       {
+               if (value & 1)
+                       break;
+
+               value >>= 1;
+       }
+
+       return i;
+}
+
+static const char * const iwinfo_name(int mask, int max, const char * const names[])
+{
+       int index = iwinfo_bit(mask, max);
+
+       if (index < 0)
+               return NULL;
+
+       return names[index];
+}
+
+const char * const iwinfo_band_name(int mask)
+{
+       return iwinfo_name(mask, IWINFO_BAND_COUNT, IWINFO_BAND_NAMES);
+}
+
+const char * const iwinfo_htmode_name(int mask)
+{
+       return iwinfo_name(mask, IWINFO_HTMODE_COUNT, IWINFO_HTMODE_NAMES);
+}
+
+uint32_t iwinfo_band2ghz(uint8_t band)
+{
+       switch (band)
+       {
+       case IWINFO_BAND_24:
+               return 2;
+       case IWINFO_BAND_5:
+               return 5;
+       case IWINFO_BAND_6:
+               return 6;
+       case IWINFO_BAND_60:
+               return 60;
+       }
+
+       return 0;
+}
+
+uint8_t iwinfo_ghz2band(uint32_t ghz)
+{
+       switch (ghz)
+       {
+       case 2:
+               return IWINFO_BAND_24;
+       case 5:
+               return IWINFO_BAND_5;
+       case 6:
+               return IWINFO_BAND_6;
+       case 60:
+               return IWINFO_BAND_60;
+       }
+
+       return 0;
+}
+
+size_t iwinfo_format_hwmodes(int modes, char *buf, size_t len)
+{
+       // bit numbers as per IWINFO_80211_*:  ad ac ax  a  b  g  n
+       const int order[IWINFO_80211_COUNT] = { 5, 4, 6, 0, 1, 2, 3 };
+       size_t res = 0;
+       int i;
+
+       *buf = 0;
+
+       if (!(modes & ((1 << IWINFO_80211_COUNT) - 1)))
+               return 0;
+
+       for (i = 0; i < IWINFO_80211_COUNT; i++)
+               if (modes & 1 << order[i])
+                       res += snprintf(buf + res, len - res, "%s/", IWINFO_80211_NAMES[order[i]]);
+
+       if (res > 0)
+       {
+               res--;
+               buf[res] = 0;
+       }
+
+       return res;
+}
+
+int iwinfo_htmode_is_ht(int htmode)
+{
+       switch (htmode)
+       {
+       case IWINFO_HTMODE_HT20:
+       case IWINFO_HTMODE_HT40:
+               return 1;
+       }
+
+       return 0;
+}
+
+int iwinfo_htmode_is_vht(int htmode)
+{
+       switch (htmode)
+       {
+       case IWINFO_HTMODE_VHT20:
+       case IWINFO_HTMODE_VHT40:
+       case IWINFO_HTMODE_VHT80:
+       case IWINFO_HTMODE_VHT80_80:
+       case IWINFO_HTMODE_VHT160:
+               return 1;
+       }
+
+       return 0;
+}
+
+int iwinfo_htmode_is_he(int htmode)
+{
+       switch (htmode)
+       {
+       case IWINFO_HTMODE_HE20:
+       case IWINFO_HTMODE_HE40:
+       case IWINFO_HTMODE_HE80:
+       case IWINFO_HTMODE_HE80_80:
+       case IWINFO_HTMODE_HE160:
+               return 1;
+       }
+
+       return 0;
+}
+
 int iwinfo_ifup(const char *ifname)
 {
        struct ifreq ifr;
@@ -141,13 +280,19 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
 
        while (fgets(buf, sizeof(buf) - 1, db) != NULL)
        {
+               if (buf[0] == '#')
+                       continue;
+
                memset(&e, 0, sizeof(e));
 
                if (sscanf(buf, "%hx %hx %hx %hx %hd %hd \"%63[^\"]\" \"%63[^\"]\"",
                               &e.vendor_id, &e.device_id,
                               &e.subsystem_vendor_id, &e.subsystem_device_id,
                               &e.txpower_offset, &e.frequency_offset,
-                              e.vendor_name, e.device_name) < 8)
+                              e.vendor_name, e.device_name) != 8 &&
+                       sscanf(buf, "\"%127[^\"]\" %hd %hd \"%63[^\"]\" \"%63[^\"]\"",
+                              e.compatible, &e.txpower_offset, &e.frequency_offset,
+                              e.vendor_name, e.device_name) != 5)
                        continue;
 
                if ((e.vendor_id != 0xffff) && (e.vendor_id != id->vendor_id))
@@ -164,6 +309,9 @@ struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
                        (e.subsystem_device_id != id->subsystem_device_id))
                        continue;
 
+               if (strcmp(e.compatible, id->compatible))
+                       continue;
+
                rv = &e;
                break;
        }
@@ -316,10 +464,16 @@ static void iwinfo_parse_rsn_cipher(uint8_t idx, uint16_t *ciphers)
                        *ciphers |= IWINFO_CIPHER_GCMP;
                        break;
 
+               case 9:
+                       *ciphers |= IWINFO_CIPHER_GCMP256;
+                       break;
+
+               case 10:
+                       *ciphers |= IWINFO_CIPHER_CCMP256;
+                       break;
+
                case 6:  /* AES-128-CMAC */
                case 7:  /* No group addressed */
-               case 9:  /* GCMP-256 */
-               case 10: /* CCMP-256 */
                case 11: /* BIP-GMAC-128 */
                case 12: /* BIP-GMAC-256 */
                case 13: /* BIP-CMAC-256 */
@@ -422,11 +576,11 @@ void iwinfo_parse_rsn(struct iwinfo_crypto_entry *c, uint8_t *data, uint8_t len,
 
                                case 11: /* 802.1x Suite-B */
                                case 12: /* 802.1x Suite-B-192 */
+                               case 13: /* FT/802.1x SHA-384 */
                                        c->wpa_version |= 4;
                                        c->auth_suites |= IWINFO_KMGMT_8021x;
                                        break;
 
-                               case 13: /* FT/802.1x SHA-384 */
                                case 14: /* FILS SHA-256 */
                                case 15: /* FILS SHA-384 */
                                case 16: /* FT/FILS SHA-256 */