OpenWrt Forum Archive

Topic: libiwinfo fails to scan

The content of this topic has been archived on 22 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I found out that the "iwinfo wlan0 scan" command displays "No scan results" when many AP's are around.

---
I am using the freescale mpc83xx with an atheros card. It is a recompilation of a freescale platform OpenWrt with extra patches for my platform (Acksys WLn-link-oem).

It seems that in the libiwinfo package, "iwinfo_nl80211.c" iwinfo is not processing correctly the log messages coming from the wpa_supplicant. When the supplicant cache is empty, triggering a scan will log many messages:
  <2>BSS: Add new id...
  <3>CTRL-EVENT-BSS-ADDED...

and these messages which are sent separately  will overflow the 5 tries allowed in nl80211_wpactl_info().

I understand that LuCI uses libiwinfo also; it has the same problem in "site survey".

I found out other inconsistencies about the log messages and I came up with a patch against SVN rev. 34505 of the trunk.


What should I do next? Here is the patch for revision:

Index: iwinfo_nl80211.c
===================================================================
--- iwinfo_nl80211.c    (revision 34505)
+++ iwinfo_nl80211.c    (working copy)
@@ -528,16 +528,19 @@
    {
        send(sock, "ATTACH", 6, 0);

-        if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0)
+        if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)-1) <= 0)
            goto out;
    }


    send(sock, cmd, strlen(cmd), 0);

-    while( numtry++ < 5 )
+    /* we might have to scan up to 72 channels / 256ms per channel */
+    /* this makes up to 18.5s hence 10 tries */
+    while( numtry++ < 10 )
    {
-        if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0)
+        /* make sure there is a terminating nul byte */
+        if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)-1) <= 0)
        {
            if (event)
                continue;
@@ -547,6 +550,11 @@

        if ((!event && buffer[0] != '<') || (event && strstr(buffer, event)))
            break;
+
+        /* there may be more than max(numtry) BSS-ADDED events */
+        /* ignore them similar to wpa_cli */
+        if (buffer[0] == '<' && strncmp(buffer+3,"CTRL-EVENT-BSS-ADDED",20) == 0)
+            numtry--;
    }

    rv = buffer;
@@ -1679,14 +1687,26 @@
        {
            nl80211_get_quality_max(ifname, &qmax);

-            /* skip header line */
-            while (*res++ != '\n');
+            count = -1;

-            count = 0;
-
-            while (sscanf(res, "%17s %d %d %255s%*[ \t]%127[^\n]\n",
-                          bssid, &freq, &rssi, cipher, ssid) > 0)
-            {
+            do {
+                if (res[0] == '<')
+                {
+                    /* skip log lines */
+                    goto nextline;
+                }
+                if (count < 0)
+                {
+                    /* skip header line */
+                    count++;
+                    goto nextline;
+                }
+                if (sscanf(res, "%17s %d %d %255s%*[ \t]%127[^\n]\n",
+                          bssid, &freq, &rssi, cipher, ssid) < 5)
+                {
+                    /* skip malformed lines */
+                    goto nextline;
+                }
                /* BSSID */
                e->mac[0] = strtol(&bssid[0],  NULL, 16);
                e->mac[1] = strtol(&bssid[3],  NULL, 16);
@@ -1731,17 +1751,19 @@
                /* Crypto */
                nl80211_get_scancrypto(cipher, &e->crypto);

-                /* advance to next line */
-                while (*res && *res++ != '\n');
-
                count++;
                e++;

                memset(ssid, 0, sizeof(ssid));
                memset(bssid, 0, sizeof(bssid));
                memset(cipher, 0, sizeof(cipher));
-            }

+            nextline:
+                /* advance to next line */
+                while( *res && *res++ != '\n' );
+             }
+            while( *res );
+
            *len = count * sizeof(struct iwinfo_scanlist_entry);
            return 0;
        }

Not opposed to the patch per se but a couple of notes:
- strncmp(buffer+3,"CTRL-EVENT-BSS-ADDED",20)  -> are you sure that the notification always start with single digits, e.g. no "<123>CTRL-EVENT-BSS-ADDED"
- do we actually need dedicated checking for header and notification lines, shouldn't relying on sscanf() returning 5 be enough?

In any case please re-send the patch in a more suitable format, either to the development list or directly to me with jow at openwrt.org

Thanks for considering the patch.

> - strncmp(buffer+3,"CTRL-EVENT-BSS-ADDED",20)  -> are you sure that the notification always start with single digits, e.g. no "<123>CTRL-EVENT-BSS-ADDED"

Agree, though wpa_supplicant currently uses only single digits it might change in the future, or if someone adds new values for his own use. I will locate the > dynamically.

> - do we actually need dedicated checking for header and notification lines, shouldn't relying on sscanf() returning 5 be enough?

For the header it's true, but for other notifications we cannot be sure every possible notification will result in sscanf returning less than 5.

Should I delete each and every <...> notifications in nl80211_wpactl_info() altogether ? it is not easy since
- they might be embedded in the middle of long responses
- they might become usuful to some other invocation of nl80211_wpactl_info()

(Last edited by jpt on 24 Jan 2013, 10:03)

The discussion might have continued from here.