iwinfo: nl80211: use new path lookup function for nl80211_phy_idx_from_uci_path
[project/iwinfo.git] / iwinfo_cli.c
index aab6ae6598b9f828ddc02512dded5173045ac56e..456c67a2a5812015636b35b589385f4fa2219cb3 100644 (file)
@@ -58,7 +58,7 @@ static char * format_channel(int ch)
 
 static char * format_frequency(int freq)
 {
-       static char buf[10];
+       static char buf[11];
 
        if (freq <= 0)
                snprintf(buf, sizeof(buf), "unknown");
@@ -130,7 +130,7 @@ static char * format_noise(int noise)
 
 static char * format_rate(int rate)
 {
-       static char buf[14];
+       static char buf[18];
 
        if (rate <= 0)
                snprintf(buf, sizeof(buf), "unknown");
@@ -158,6 +158,9 @@ static char * format_enc_ciphers(int ciphers)
        if (ciphers & IWINFO_CIPHER_CCMP)
                pos += sprintf(pos, "CCMP, ");
 
+       if (ciphers & IWINFO_CIPHER_GCMP)
+               pos += sprintf(pos, "GCMP, ");
+
        if (ciphers & IWINFO_CIPHER_WRAP)
                pos += sprintf(pos, "WRAP, ");
 
@@ -186,6 +189,12 @@ static char * format_enc_suites(int suites)
        if (suites & IWINFO_KMGMT_8021x)
                pos += sprintf(pos, "802.1X/");
 
+       if (suites & IWINFO_KMGMT_SAE)
+               pos += sprintf(pos, "SAE/");
+
+       if (suites & IWINFO_KMGMT_OWE)
+               pos += sprintf(pos, "OWE/");
+
        if (!suites || (suites & IWINFO_KMGMT_NONE))
                pos += sprintf(pos, "NONE/");
 
@@ -197,6 +206,8 @@ static char * format_enc_suites(int suites)
 static char * format_encryption(struct iwinfo_crypto_entry *c)
 {
        static char buf[512];
+       char *pos = buf;
+       int i, n;
 
        if (!c)
        {
@@ -228,25 +239,25 @@ static char * format_encryption(struct iwinfo_crypto_entry *c)
                /* WPA */
                else if (c->wpa_version)
                {
-                       switch (c->wpa_version) {
-                               case 3:
-                                       snprintf(buf, sizeof(buf), "mixed WPA/WPA2 %s (%s)",
-                                               format_enc_suites(c->auth_suites),
-                                               format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
-                                       break;
+                       for (i = 0, n = 0; i < 3; i++)
+                               if (c->wpa_version & (1 << i))
+                                       n++;
 
-                               case 2:
-                                       snprintf(buf, sizeof(buf), "WPA2 %s (%s)",
-                                               format_enc_suites(c->auth_suites),
-                                               format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
-                                       break;
+                       if (n > 1)
+                               pos += sprintf(pos, "mixed ");
 
-                               case 1:
-                                       snprintf(buf, sizeof(buf), "WPA %s (%s)",
-                                               format_enc_suites(c->auth_suites),
-                                               format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
-                                       break;
-                       }
+                       for (i = 0; i < 3; i++)
+                               if (c->wpa_version & (1 << i))
+                                       if (i)
+                                               pos += sprintf(pos, "WPA%d/", i + 1);
+                                       else
+                                               pos += sprintf(pos, "WPA/");
+
+                       pos--;
+
+                       sprintf(pos, " %s (%s)",
+                               format_enc_suites(c->auth_suites),
+                               format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
                }
                else
                {
@@ -263,17 +274,19 @@ static char * format_encryption(struct iwinfo_crypto_entry *c)
 
 static char * format_hwmodes(int modes)
 {
-       static char buf[12];
+       static char buf[17];
 
        if (modes <= 0)
                snprintf(buf, sizeof(buf), "unknown");
        else
-               snprintf(buf, sizeof(buf), "802.11%s%s%s%s%s",
+               snprintf(buf, sizeof(buf), "802.11%s%s%s%s%s%s%s",
                        (modes & IWINFO_80211_A) ? "a" : "",
                        (modes & IWINFO_80211_B) ? "b" : "",
                        (modes & IWINFO_80211_G) ? "g" : "",
                        (modes & IWINFO_80211_N) ? "n" : "",
-                       (modes & IWINFO_80211_AC) ? "ac" : "");
+                       (modes & IWINFO_80211_AC) ? "ac" : "",
+                       (modes & IWINFO_80211_AD) ? "ad" : "",
+                       (modes & IWINFO_80211_AX) ? "ax" : "");
 
        return buf;
 }
@@ -309,11 +322,39 @@ static char * format_assocrate(struct iwinfo_rate_entry *r)
                                l = sizeof(buf) - (p - buf);
                        }
                }
+               else if (r->is_he)
+               {
+                       p += snprintf(p, l, ", HE-MCS %d, %dMHz", r->mcs, r->mhz);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-NSS %d", r->nss);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-GI %d", r->he_gi);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-DCM %d", r->he_dcm);
+                       l = sizeof(buf) - (p - buf);
+               }
        }
 
        return buf;
 }
 
+static const char* format_chan_width(uint16_t width)
+{
+       switch (width) {
+               case 20: return "20 MHz";
+               case 2040: return "40 MHz and upper or 20 MHz with intolerant bit";
+               case 40: return "40 MHz or lower";
+               case 80: return "80 MHz";
+               case 8080: return "80+80 MHz";
+               case 160: return "160 MHz";
+       }
+
+       return "unknown";
+}
+
 
 static const char * print_type(const struct iwinfo_ops *iw, const char *ifname)
 {
@@ -422,6 +463,24 @@ static char * print_channel(const struct iwinfo_ops *iw, const char *ifname)
        return format_channel(ch);
 }
 
+static char * print_center_chan1(const struct iwinfo_ops *iw, const char *ifname)
+{
+       int ch;
+       if (iw->center_chan1(ifname, &ch))
+               ch = -1;
+
+       return format_channel(ch);
+}
+
+static char * print_center_chan2(const struct iwinfo_ops *iw, const char *ifname)
+{
+       int ch;
+       if (iw->center_chan2(ifname, &ch))
+               ch = -1;
+
+       return format_channel(ch);
+}
+
 static char * print_frequency(const struct iwinfo_ops *iw, const char *ifname)
 {
        int freq;
@@ -543,6 +602,11 @@ static void print_info(const struct iwinfo_ops *iw, const char *ifname)
                print_mode(iw, ifname),
                print_channel(iw, ifname),
                print_frequency(iw, ifname));
+       if (iw->center_chan1 != NULL) {
+               printf("          Center Channel 1: %s",
+                       print_center_chan1(iw, ifname));
+               printf(" 2: %s\n", print_center_chan2(iw, ifname));
+       }
        printf("          Tx-Power: %s  Link Quality: %s/%s\n",
                print_txpower(iw, ifname),
                print_quality(iw, ifname),
@@ -603,8 +667,27 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
                        format_signal(e->signal - 0x100),
                        format_quality(e->quality),
                        format_quality_max(e->quality_max));
-               printf("          Encryption: %s\n\n",
+               printf("          Encryption: %s\n",
                        format_encryption(&e->crypto));
+               printf("          HT Operation:\n");
+               printf("                    Primary Channel: %d\n",
+                       e->ht_chan_info.primary_chan);
+               printf("                    Secondary Channel Offset: %s\n",
+                       ht_secondary_offset[e->ht_chan_info.secondary_chan_off]);
+               printf("                    Channel Width: %s\n",
+                       format_chan_width(e->ht_chan_info.chan_width));
+
+               if (e->vht_chan_info.center_chan_1) {
+                       printf("          VHT Operation:\n");
+                       printf("                    Channel Width: %s\n",
+                               format_chan_width(e->vht_chan_info.chan_width));
+                       printf("                    Center Frequency 1: %d\n",
+                                e->vht_chan_info.center_chan_1);
+                       printf("                    Center Frequency 2: %d\n",
+                                e->vht_chan_info.center_chan_2);
+               }
+
+               printf("\n");
        }
 }
 
@@ -700,10 +783,13 @@ static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
                        e->rx_packets
                );
 
-               printf("        TX: %-38s  %8d Pkts.\n\n",
+               printf("        TX: %-38s  %8d Pkts.\n",
                        format_assocrate(&e->tx_rate),
                        e->tx_packets
                );
+
+               printf("        expected throughput: %s\n\n",
+                       format_rate(e->thr));
        }
 }
 
@@ -789,6 +875,16 @@ static void lookup_phy(const struct iwinfo_ops *iw, const char *section)
 }
 
 
+static void lookup_path(const struct iwinfo_ops *iw, const char *phy)
+{
+       const char *path;
+
+       if (!iw->phy_path || iw->phy_path(phy, &path) || !path)
+               return;
+
+       printf("%s\n", path);
+}
+
 int main(int argc, char **argv)
 {
        int i, rv = 0;
@@ -848,6 +944,10 @@ int main(int argc, char **argv)
                }
                else
                {
+                       if (!strcmp(argv[2], "path")) {
+                               lookup_path(iw, argv[3]);
+                               return 0;
+                       }
                        switch (argv[2][0])
                        {
                        case 'p':