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"
15 #define DLADM_STRSIZE 256
16 #define DLADM_SECTIONS 3
18 using namespace mozilla
;
20 struct val_strength_t
{
21 const char *strength_name
;
25 static val_strength_t strength_vals
[] = {
26 { "very weak", -112 },
33 static nsWifiAccessPoint
*
34 do_parse_str(char *bssid_str
, char *essid_str
, char *strength
)
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]);
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
;
49 nsWifiAccessPoint
*ap
= new nsWifiAccessPoint();
51 ap
->setMac(mac_as_int
);
52 ap
->setSignal(signal
);
53 ap
->setSSID(essid_str
, PL_strnlen(essid_str
, DLADM_STRSIZE
));
59 do_dladm(nsCOMArray
<nsWifiAccessPoint
> &accessPoints
)
61 GError
*err
= nullptr;
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];
73 uint32_t sout_scan
= 0;
74 uint32_t wlan_put
= 0;
76 nsWifiAccessPoint
* ap
;
79 sout_char
= sout
[sout_scan
++];
82 if (sout_char
!= '\0') {
83 wlan
[section
][wlan_put
++] = sout_char
;
88 if (sout_char
=='\\') {
93 if (sout_char
== ':') {
94 wlan
[section
][wlan_put
] = '\0';
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]);
105 accessPoints
.AppendObject(ap
);
113 wlan
[section
][wlan_put
++] = sout_char
;
115 } while ((wlan_put
<= DLADM_STRSIZE
) && (section
< DLADM_SECTIONS
) &&
116 (sout_char
!= '\0'));
124 nsWifiMonitor::DoScan()
126 // Regularly get the access point data.
128 nsCOMArray
<nsWifiAccessPoint
> lastAccessPoints
;
129 nsCOMArray
<nsWifiAccessPoint
> accessPoints
;
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(kDefaultWifiScanInterval
));