SolarisWifiScanner.cpp (3452B)
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/. */ 4 5 #include "nsWifiMonitor.h" 6 #include "nsWifiAccessPoint.h" 7 8 #include "nsCRT.h" 9 #include "nsServiceManagerUtils.h" 10 #include "nsComponentManagerUtils.h" 11 12 #include "SolarisWifiScanner.h" 13 14 #include <glib.h> 15 16 #define DLADM_STRSIZE 256 17 #define DLADM_SECTIONS 3 18 19 using namespace mozilla; 20 21 struct val_strength_t { 22 const char* strength_name; 23 int signal_value; 24 }; 25 26 static val_strength_t strength_vals[] = {{"very weak", -112}, 27 {"weak", -88}, 28 {"good", -68}, 29 {"very good", -40}, 30 {"excellent", -16}}; 31 32 static nsWifiAccessPoint* do_parse_str(char* bssid_str, char* essid_str, 33 char* strength) { 34 unsigned char mac_as_int[6] = {0}; 35 sscanf(bssid_str, "%x:%x:%x:%x:%x:%x", &mac_as_int[0], &mac_as_int[1], 36 &mac_as_int[2], &mac_as_int[3], &mac_as_int[4], &mac_as_int[5]); 37 38 int signal = 0; 39 uint32_t strength_vals_count = sizeof(strength_vals) / sizeof(val_strength_t); 40 for (uint32_t i = 0; i < strength_vals_count; i++) { 41 if (!nsCRT::strncasecmp(strength, strength_vals[i].strength_name, 42 DLADM_STRSIZE)) { 43 signal = strength_vals[i].signal_value; 44 break; 45 } 46 } 47 48 nsWifiAccessPoint* ap = new nsWifiAccessPoint(); 49 if (ap) { 50 ap->setMac(mac_as_int); 51 ap->setSignal(signal); 52 size_t len = essid_str ? strnlen(essid_str, DLADM_STRSIZE) : 0; 53 ap->setSSID(essid_str, len); 54 } 55 return ap; 56 } 57 58 nsresult WifiScannerImpl::GetAccessPointsFromWLAN( 59 nsTArray<RefPtr<nsIWifiAccessPoint>>& accessPoints) { 60 GError* err = nullptr; 61 char* sout = nullptr; 62 char* serr = nullptr; 63 int exit_status = 0; 64 char* dladm_args[] = { 65 "/usr/bin/pfexec", "/usr/sbin/dladm", "scan-wifi", "-p", "-o", 66 "BSSID,ESSID,STRENGTH"}; 67 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 } 87 88 if (sout_char == '\\') { 89 escape = true; 90 continue; 91 } 92 93 if (sout_char == ':') { 94 wlan[section][wlan_put] = '\0'; 95 section++; 96 wlan_put = 0; 97 continue; 98 } 99 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.AppendElement(ap); 106 } 107 } 108 section = 0; 109 wlan_put = 0; 110 continue; 111 } 112 113 wlan[section][wlan_put++] = sout_char; 114 115 } while ((wlan_put <= DLADM_STRSIZE) && (section < DLADM_SECTIONS) && 116 (sout_char != '\0')); 117 } 118 119 g_free(sout); 120 g_free(serr); 121 }