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/. */
6 #include "DbusWifiScanner.h"
7 #include "nsWifiAccessPoint.h"
8 #include "mozilla/GUniquePtr.h"
9 #include "mozilla/RefPtr.h"
10 #include "mozilla/GRefPtr.h"
14 WifiScannerImpl::WifiScannerImpl() { MOZ_COUNT_CTOR(WifiScannerImpl
); }
16 WifiScannerImpl::~WifiScannerImpl() { MOZ_COUNT_DTOR(WifiScannerImpl
); }
18 nsresult
WifiScannerImpl::GetAccessPointsFromWLAN(
19 AccessPointArray
& aAccessPoints
) {
20 RefPtr
<GDBusProxy
> proxy
= dont_AddRef(g_dbus_proxy_new_for_bus_sync(
21 G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
, nullptr,
22 "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager",
23 "org.freedesktop.NetworkManager", nullptr, nullptr));
25 return NS_ERROR_FAILURE
;
28 RefPtr
<GVariant
> result
=
29 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "Devices"));
31 !g_variant_is_of_type(result
, G_VARIANT_TYPE_OBJECT_PATH_ARRAY
)) {
32 return NS_ERROR_FAILURE
;
35 gsize num
= g_variant_n_children(result
);
36 for (gsize i
= 0; i
< num
; i
++) {
37 const char* devicePath
=
38 g_variant_get_string(g_variant_get_child_value(result
, i
), nullptr);
39 if (!devicePath
|| !AddDevice(devicePath
, aAccessPoints
)) {
40 return NS_ERROR_FAILURE
;
47 bool WifiScannerImpl::AddDevice(const char* aDevicePath
,
48 AccessPointArray
& aAccessPoints
) {
49 RefPtr
<GDBusProxy
> proxy
= dont_AddRef(g_dbus_proxy_new_for_bus_sync(
50 G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
, nullptr,
51 "org.freedesktop.NetworkManager", aDevicePath
,
52 "org.freedesktop.NetworkManager.Device", nullptr, nullptr));
57 RefPtr
<GVariant
> deviceType
=
58 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "DeviceType"));
59 if (!deviceType
|| !g_variant_is_of_type(deviceType
, G_VARIANT_TYPE_UINT32
)) {
63 // http://projects.gnome.org/NetworkManager/developers/api/07/spec-07.html
64 // Refer to NM_DEVICE_TYPE_WIFI under NM_DEVICE_TYPE.
65 const uint32_t NM_DEVICE_TYPE_WIFI
= 2;
66 if (g_variant_get_uint32(deviceType
) != NM_DEVICE_TYPE_WIFI
) {
67 // Don't probe non-wifi devices
71 proxy
= dont_AddRef(g_dbus_proxy_new_for_bus_sync(
72 G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
, nullptr,
73 "org.freedesktop.NetworkManager", aDevicePath
,
74 "org.freedesktop.NetworkManager.Device.Wireless", nullptr, nullptr));
79 RefPtr
<GVariant
> points
=
80 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "AccessPoints"));
82 !g_variant_is_of_type(points
, G_VARIANT_TYPE_OBJECT_PATH_ARRAY
)) {
86 gsize num
= g_variant_n_children(points
);
87 for (gsize i
= 0; i
< num
; i
++) {
89 g_variant_get_string(g_variant_get_child_value(points
, i
), nullptr);
90 if (!ap
|| !AddAPProperties(ap
, aAccessPoints
)) {
97 bool WifiScannerImpl::AddAPProperties(const char* aApPath
,
98 AccessPointArray
& aAccessPoints
) {
99 RefPtr
<GDBusProxy
> proxy
= dont_AddRef(g_dbus_proxy_new_for_bus_sync(
100 G_BUS_TYPE_SYSTEM
, G_DBUS_PROXY_FLAGS_NONE
, nullptr,
101 "org.freedesktop.NetworkManager", aApPath
,
102 "org.freedesktop.NetworkManager.AccessPoint", nullptr, nullptr));
107 RefPtr
<nsWifiAccessPoint
> ap
= new nsWifiAccessPoint();
109 RefPtr
<GVariant
> ssid
=
110 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "Ssid"));
111 if (!ssid
|| !g_variant_is_of_type(ssid
, G_VARIANT_TYPE_BYTESTRING
)) {
114 const uint32_t MAX_SSID_LEN
= 32;
116 const char* ssidString
= static_cast<const char*>(
117 g_variant_get_fixed_array(ssid
, &len
, sizeof(guint8
)));
118 if (ssidString
&& len
&& len
<= MAX_SSID_LEN
) {
119 ap
->setSSID(ssidString
, len
);
122 RefPtr
<GVariant
> hwAddress
=
123 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "HwAddress"));
124 if (!hwAddress
|| !g_variant_is_of_type(hwAddress
, G_VARIANT_TYPE_STRING
)) {
127 GUniquePtr
<gchar
> address(g_variant_dup_string(hwAddress
, nullptr));
128 SetMac(address
.get(), ap
);
130 RefPtr
<GVariant
> st
=
131 dont_AddRef(g_dbus_proxy_get_cached_property(proxy
, "Strength"));
132 if (!st
|| !g_variant_is_of_type(st
, G_VARIANT_TYPE_BYTE
)) {
136 uint8_t strength
= g_variant_get_byte(st
); // in %
137 int signal_strength
= (strength
/ 2) - 100; // strength to dB
138 ap
->setSignal(signal_strength
);
140 aAccessPoints
.AppendElement(ap
);
144 bool WifiScannerImpl::SetMac(char* aHwAddress
, nsWifiAccessPoint
* aAp
) {
145 // hwAddress format is XX:XX:XX:XX:XX:XX. Need to convert to XXXXXX format.
146 const uint32_t MAC_LEN
= 6;
147 uint8_t macAddress
[MAC_LEN
];
148 char* savedPtr
= nullptr;
149 char* token
= strtok_r(aHwAddress
, ":", &savedPtr
);
150 for (unsigned char& macAddres
: macAddress
) {
154 macAddres
= strtoul(token
, nullptr, 16);
155 token
= strtok_r(nullptr, ":", &savedPtr
);
157 aAp
->setMac(macAddress
);
161 } // namespace mozilla