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

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

mercurial