netwerk/wifi/nsWifiScannerSolaris.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsWifiMonitor.h"
     6 #include "nsWifiAccessPoint.h"
     8 #include "nsServiceManagerUtils.h"
     9 #include "nsComponentManagerUtils.h"
    10 #include "nsIMutableArray.h"
    12 #include "plstr.h"
    13 #include <glib.h>
    15 #define DLADM_STRSIZE 256
    16 #define DLADM_SECTIONS 3
    18 using namespace mozilla;
    20 struct val_strength_t {
    21   const char *strength_name;
    22   int         signal_value;
    23 };
    25 static val_strength_t strength_vals[] = {
    26   { "very weak", -112 },
    27   { "weak",      -88 },
    28   { "good",      -68 },
    29   { "very good", -40 },
    30   { "excellent", -16 }
    31 };
    33 static nsWifiAccessPoint *
    34 do_parse_str(char *bssid_str, char *essid_str, char *strength)
    35 {
    36   unsigned char mac_as_int[6] = { 0 };
    37   sscanf(bssid_str, "%x:%x:%x:%x:%x:%x", &mac_as_int[0], &mac_as_int[1],
    38          &mac_as_int[2], &mac_as_int[3], &mac_as_int[4], &mac_as_int[5]);
    40   int signal = 0;
    41   uint32_t strength_vals_count = sizeof(strength_vals) / sizeof (val_strength_t);
    42   for (uint32_t i = 0; i < strength_vals_count; i++) {
    43     if (!strncasecmp(strength, strength_vals[i].strength_name, DLADM_STRSIZE)) {
    44       signal = strength_vals[i].signal_value;
    45       break;
    46     }
    47   }
    49   nsWifiAccessPoint *ap = new nsWifiAccessPoint();
    50   if (ap) {
    51     ap->setMac(mac_as_int);
    52     ap->setSignal(signal);
    53     ap->setSSID(essid_str, PL_strnlen(essid_str, DLADM_STRSIZE));
    54   }
    55   return ap;
    56 }
    58 static void
    59 do_dladm(nsCOMArray<nsWifiAccessPoint> &accessPoints)
    60 {
    61   GError *err = nullptr;
    62   char *sout = nullptr;
    63   char *serr = nullptr;
    64   int exit_status = 0;
    65   char * dladm_args[] = { "/usr/bin/pfexec", "/usr/sbin/dladm",
    66                           "scan-wifi", "-p", "-o", "BSSID,ESSID,STRENGTH" };
    68   gboolean rv = g_spawn_sync("/", dladm_args, nullptr, (GSpawnFlags)0, nullptr,
    69                              nullptr, &sout, &serr, &exit_status, &err);
    70   if (rv && !exit_status) {
    71     char wlan[DLADM_SECTIONS][DLADM_STRSIZE+1];
    72     uint32_t section = 0;
    73     uint32_t sout_scan = 0;
    74     uint32_t wlan_put = 0;
    75     bool escape = false;
    76     nsWifiAccessPoint* ap;
    77     char sout_char;
    78     do {
    79       sout_char = sout[sout_scan++];
    80       if (escape) {
    81         escape = false;
    82         if (sout_char != '\0') {
    83           wlan[section][wlan_put++] = sout_char;
    84           continue;
    85         }
    86       }
    88       if (sout_char =='\\') {
    89         escape = true;
    90         continue;
    91       }
    93       if (sout_char == ':') {
    94         wlan[section][wlan_put] = '\0';
    95         section++;
    96         wlan_put = 0;
    97         continue;
    98       }
   100       if ((sout_char == '\0') || (sout_char == '\n')) {
   101         wlan[section][wlan_put] = '\0';
   102         if (section == DLADM_SECTIONS - 1) {
   103           ap = do_parse_str(wlan[0], wlan[1], wlan[2]);
   104           if (ap) {
   105             accessPoints.AppendObject(ap);
   106           }
   107         }
   108         section = 0;
   109         wlan_put = 0;
   110         continue;
   111       }
   113       wlan[section][wlan_put++] = sout_char;
   115     } while ((wlan_put <= DLADM_STRSIZE) && (section < DLADM_SECTIONS) &&
   116              (sout_char != '\0'));
   117   }
   119   g_free(sout);
   120   g_free(serr);
   121 }
   123 nsresult
   124 nsWifiMonitor::DoScan()
   125 {
   126   // Regularly get the access point data.
   128   nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
   129   nsCOMArray<nsWifiAccessPoint> accessPoints;
   131   while (mKeepGoing) {
   133     accessPoints.Clear();
   134     do_dladm(accessPoints);
   136     bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
   137     ReplaceArray(lastAccessPoints, accessPoints);
   139     nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
   140     NS_ENSURE_SUCCESS(rv, rv);
   142     LOG(("waiting on monitor\n"));
   144     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   145     mon.Wait(PR_SecondsToInterval(60));
   146   }
   148   return NS_OK;
   149 }

mercurial