lua: fix WPA cipher reporting
[project/iwinfo.git] / iwinfo_nl80211.c
index 55bfd0f..63b70d5 100644 (file)
@@ -218,9 +218,6 @@ static struct nl80211_msg_conveyor * nl80211_new(struct genl_family *family,
        return &cv;
 
 err:
-       if (cb)
-               nl_cb_put(cb);
-
        if (req)
                nlmsg_free(req);
 
@@ -248,6 +245,9 @@ static int nl80211_phy_idx_from_uci_path(struct uci_section *s)
 
        snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt);  /**/
        if (glob(buf, 0, NULL, &gl))
+               snprintf(buf, sizeof(buf), "/sys/devices/platform/%s/ieee80211/*/index", opt);  /**/
+
+       if (glob(buf, 0, NULL, &gl))
                return -1;
 
        if (gl.gl_pathc > 0)
@@ -604,7 +604,7 @@ static char * nl80211_phy2ifname(const char *ifname)
                                            ((ifidx < 0) || (cifidx < ifidx)))
                                        {
                                                ifidx = cifidx;
-                                               strncpy(nif, e->d_name, sizeof(nif));
+                                               strncpy(nif, e->d_name, sizeof(nif) - 1);
                                        }
                                }
                        }
@@ -951,7 +951,7 @@ static void nl80211_hostapd_hup(const char *ifname)
        if (phy)
        {
                snprintf(buf, sizeof(buf), "/var/run/wifi-%s.pid", phy);
-               if ((fd = open(buf, O_RDONLY)) > 0)
+               if ((fd = open(buf, O_RDONLY)) >= 0)
                {
                        if (read(fd, buf, sizeof(buf)) > 0)
                                pid = atoi(buf);
@@ -1188,22 +1188,35 @@ static int nl80211_get_channel(const char *ifname, int *buf)
        return -1;
 }
 
+static int nl80211_get_txpower_cb(struct nl_msg *msg, void *arg)
+{
+       int *buf = arg;
+       struct nlattr **tb = nl80211_parse(msg);
+
+       if (tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL])
+               *buf = iwinfo_mbm2dbm(nla_get_u32(tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]));
+
+       return NL_SKIP;
+}
 
 static int nl80211_get_txpower(const char *ifname, int *buf)
 {
-#if 0
        char *res;
-       char path[PATH_MAX];
+       struct nl80211_msg_conveyor *req;
 
-       res = nl80211_ifname2phy(ifname);
-       snprintf(path, sizeof(path), "/sys/kernel/debug/ieee80211/%s/power",
-                res ? res : ifname);
+       res = nl80211_phy2ifname(ifname);
+       req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0);
 
-       if ((*buf = nl80211_readint(path)) > -1)
-               return 0;
-#endif
+       if (req)
+       {
+               *buf = 0;
+               nl80211_send(req, nl80211_get_txpower_cb, buf);
+               nl80211_free(req);
+               if (*buf)
+                       return 0;
+       }
 
-       return wext_ops.txpower(ifname, buf);
+       return -1;
 }
 
 
@@ -1615,6 +1628,48 @@ static int nl80211_get_phyname(const char *ifname, char *buf)
 }
 
 
+static void nl80211_parse_rateinfo(struct nlattr **ri,
+                                   struct iwinfo_rate_entry *re)
+{
+       if (ri[NL80211_RATE_INFO_BITRATE32])
+               re->rate = nla_get_u32(ri[NL80211_RATE_INFO_BITRATE32]) * 100;
+       else if (ri[NL80211_RATE_INFO_BITRATE])
+               re->rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]) * 100;
+
+       if (ri[NL80211_RATE_INFO_VHT_MCS])
+       {
+               re->is_vht = 1;
+               re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_VHT_MCS]);
+
+               if (ri[NL80211_RATE_INFO_VHT_NSS])
+                       re->nss = nla_get_u8(ri[NL80211_RATE_INFO_VHT_NSS]);
+       }
+       else if (ri[NL80211_RATE_INFO_MCS])
+       {
+               re->is_ht = 1;
+               re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_MCS]);
+       }
+
+       if (ri[NL80211_RATE_INFO_5_MHZ_WIDTH])
+               re->mhz = 5;
+       else if (ri[NL80211_RATE_INFO_10_MHZ_WIDTH])
+               re->mhz = 10;
+       else if (ri[NL80211_RATE_INFO_40_MHZ_WIDTH])
+               re->mhz = 40;
+       else if (ri[NL80211_RATE_INFO_80_MHZ_WIDTH])
+               re->mhz = 80;
+       else if (ri[NL80211_RATE_INFO_80P80_MHZ_WIDTH] ||
+                ri[NL80211_RATE_INFO_160_MHZ_WIDTH])
+               re->mhz = 160;
+       else
+               re->mhz = 20;
+
+       if (ri[NL80211_RATE_INFO_SHORT_GI])
+               re->is_short_gi = 1;
+
+       re->is_40mhz = (re->mhz == 40);
+}
+
 static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
 {
        struct nl80211_array_buf *arr = arg;
@@ -1673,38 +1728,12 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
                if (sinfo[NL80211_STA_INFO_RX_BITRATE] &&
                    !nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
                                      sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy))
-               {
-                       if (rinfo[NL80211_RATE_INFO_BITRATE])
-                               e->rx_rate.rate =
-                                       nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]) * 100;
-
-                       if (rinfo[NL80211_RATE_INFO_MCS])
-                               e->rx_rate.mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
-
-                       if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
-                               e->rx_rate.is_40mhz = 1;
-
-                       if (rinfo[NL80211_RATE_INFO_SHORT_GI])
-                               e->rx_rate.is_short_gi = 1;
-               }
+                       nl80211_parse_rateinfo(rinfo, &e->rx_rate);
 
                if (sinfo[NL80211_STA_INFO_TX_BITRATE] &&
                    !nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
                                      sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy))
-               {
-                       if (rinfo[NL80211_RATE_INFO_BITRATE])
-                               e->tx_rate.rate =
-                                       nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]) * 100;
-
-                       if (rinfo[NL80211_RATE_INFO_MCS])
-                               e->tx_rate.mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
-
-                       if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
-                               e->tx_rate.is_40mhz = 1;
-
-                       if (rinfo[NL80211_RATE_INFO_SHORT_GI])
-                               e->tx_rate.is_short_gi = 1;
-               }
+                       nl80211_parse_rateinfo(rinfo, &e->tx_rate);
 
                if (sinfo[NL80211_STA_INFO_RX_BYTES])
                        e->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
@@ -2480,6 +2509,7 @@ static int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
                e->iso3166 = l->iso3166;
                e->ccode[0] = (l->iso3166 / 256);
                e->ccode[1] = (l->iso3166 % 256);
+               e->ccode[2] = 0;
        }
 
        *len = (count * sizeof(struct iwinfo_country_entry));
@@ -2684,7 +2714,7 @@ static int nl80211_get_mbssid_support(const char *ifname, int *buf)
 
 static int nl80211_get_hardware_id(const char *ifname, char *buf)
 {
-       int rv;
+       int rv = -1;
        char *res;
 
        /* Got a radioX pseudo interface, find some interface on it or create one */