netwerk/wifi/nsWifiScannerSolaris.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/wifi/nsWifiScannerSolaris.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,149 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "nsWifiMonitor.h"
     1.9 +#include "nsWifiAccessPoint.h"
    1.10 +
    1.11 +#include "nsServiceManagerUtils.h"
    1.12 +#include "nsComponentManagerUtils.h"
    1.13 +#include "nsIMutableArray.h"
    1.14 +
    1.15 +#include "plstr.h"
    1.16 +#include <glib.h>
    1.17 +
    1.18 +#define DLADM_STRSIZE 256
    1.19 +#define DLADM_SECTIONS 3
    1.20 +
    1.21 +using namespace mozilla;
    1.22 +
    1.23 +struct val_strength_t {
    1.24 +  const char *strength_name;
    1.25 +  int         signal_value;
    1.26 +};
    1.27 +
    1.28 +static val_strength_t strength_vals[] = {
    1.29 +  { "very weak", -112 },
    1.30 +  { "weak",      -88 },
    1.31 +  { "good",      -68 },
    1.32 +  { "very good", -40 },
    1.33 +  { "excellent", -16 }
    1.34 +};
    1.35 +
    1.36 +static nsWifiAccessPoint *
    1.37 +do_parse_str(char *bssid_str, char *essid_str, char *strength)
    1.38 +{
    1.39 +  unsigned char mac_as_int[6] = { 0 };
    1.40 +  sscanf(bssid_str, "%x:%x:%x:%x:%x:%x", &mac_as_int[0], &mac_as_int[1],
    1.41 +         &mac_as_int[2], &mac_as_int[3], &mac_as_int[4], &mac_as_int[5]);
    1.42 +
    1.43 +  int signal = 0;
    1.44 +  uint32_t strength_vals_count = sizeof(strength_vals) / sizeof (val_strength_t);
    1.45 +  for (uint32_t i = 0; i < strength_vals_count; i++) {
    1.46 +    if (!strncasecmp(strength, strength_vals[i].strength_name, DLADM_STRSIZE)) {
    1.47 +      signal = strength_vals[i].signal_value;
    1.48 +      break;
    1.49 +    }
    1.50 +  }
    1.51 +
    1.52 +  nsWifiAccessPoint *ap = new nsWifiAccessPoint();
    1.53 +  if (ap) {
    1.54 +    ap->setMac(mac_as_int);
    1.55 +    ap->setSignal(signal);
    1.56 +    ap->setSSID(essid_str, PL_strnlen(essid_str, DLADM_STRSIZE));
    1.57 +  }
    1.58 +  return ap;
    1.59 +}
    1.60 +
    1.61 +static void
    1.62 +do_dladm(nsCOMArray<nsWifiAccessPoint> &accessPoints)
    1.63 +{
    1.64 +  GError *err = nullptr;
    1.65 +  char *sout = nullptr;
    1.66 +  char *serr = nullptr;
    1.67 +  int exit_status = 0;
    1.68 +  char * dladm_args[] = { "/usr/bin/pfexec", "/usr/sbin/dladm",
    1.69 +                          "scan-wifi", "-p", "-o", "BSSID,ESSID,STRENGTH" };
    1.70 +
    1.71 +  gboolean rv = g_spawn_sync("/", dladm_args, nullptr, (GSpawnFlags)0, nullptr,
    1.72 +                             nullptr, &sout, &serr, &exit_status, &err);
    1.73 +  if (rv && !exit_status) {
    1.74 +    char wlan[DLADM_SECTIONS][DLADM_STRSIZE+1];
    1.75 +    uint32_t section = 0;
    1.76 +    uint32_t sout_scan = 0;
    1.77 +    uint32_t wlan_put = 0;
    1.78 +    bool escape = false;
    1.79 +    nsWifiAccessPoint* ap;
    1.80 +    char sout_char;
    1.81 +    do {
    1.82 +      sout_char = sout[sout_scan++];
    1.83 +      if (escape) {
    1.84 +        escape = false;
    1.85 +        if (sout_char != '\0') {
    1.86 +          wlan[section][wlan_put++] = sout_char;
    1.87 +          continue;
    1.88 +        }
    1.89 +      }
    1.90 +
    1.91 +      if (sout_char =='\\') {
    1.92 +        escape = true;
    1.93 +        continue;
    1.94 +      }
    1.95 +
    1.96 +      if (sout_char == ':') {
    1.97 +        wlan[section][wlan_put] = '\0';
    1.98 +        section++;
    1.99 +        wlan_put = 0;
   1.100 +        continue;
   1.101 +      }
   1.102 +
   1.103 +      if ((sout_char == '\0') || (sout_char == '\n')) {
   1.104 +        wlan[section][wlan_put] = '\0';
   1.105 +        if (section == DLADM_SECTIONS - 1) {
   1.106 +          ap = do_parse_str(wlan[0], wlan[1], wlan[2]);
   1.107 +          if (ap) {
   1.108 +            accessPoints.AppendObject(ap);
   1.109 +          }
   1.110 +        }
   1.111 +        section = 0;
   1.112 +        wlan_put = 0;
   1.113 +        continue;
   1.114 +      }
   1.115 +
   1.116 +      wlan[section][wlan_put++] = sout_char;
   1.117 +
   1.118 +    } while ((wlan_put <= DLADM_STRSIZE) && (section < DLADM_SECTIONS) &&
   1.119 +             (sout_char != '\0'));
   1.120 +  }
   1.121 +
   1.122 +  g_free(sout);
   1.123 +  g_free(serr);
   1.124 +}
   1.125 +
   1.126 +nsresult
   1.127 +nsWifiMonitor::DoScan()
   1.128 +{
   1.129 +  // Regularly get the access point data.
   1.130 +
   1.131 +  nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
   1.132 +  nsCOMArray<nsWifiAccessPoint> accessPoints;
   1.133 +
   1.134 +  while (mKeepGoing) {
   1.135 +
   1.136 +    accessPoints.Clear();
   1.137 +    do_dladm(accessPoints);
   1.138 +
   1.139 +    bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
   1.140 +    ReplaceArray(lastAccessPoints, accessPoints);
   1.141 +
   1.142 +    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
   1.143 +    NS_ENSURE_SUCCESS(rv, rv);
   1.144 +
   1.145 +    LOG(("waiting on monitor\n"));
   1.146 +
   1.147 +    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   1.148 +    mon.Wait(PR_SecondsToInterval(60));
   1.149 +  }
   1.150 +
   1.151 +  return NS_OK;
   1.152 +}

mercurial