Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / netwerk / wifi / dbus / DbusWifiScanner.cpp
blob43a6cc49dced2c06916396203f9862059e92e917
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 <gio/gio.h>
6 #include "DbusWifiScanner.h"
7 #include "nsWifiAccessPoint.h"
8 #include "mozilla/GUniquePtr.h"
9 #include "mozilla/RefPtr.h"
10 #include "mozilla/GRefPtr.h"
12 namespace mozilla {
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));
24 if (!proxy) {
25 return NS_ERROR_FAILURE;
28 RefPtr<GVariant> result =
29 dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "Devices"));
30 if (!result ||
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;
44 return NS_OK;
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));
53 if (!proxy) {
54 return false;
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)) {
60 return false;
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
68 return true;
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));
75 if (!proxy) {
76 return false;
79 RefPtr<GVariant> points =
80 dont_AddRef(g_dbus_proxy_get_cached_property(proxy, "AccessPoints"));
81 if (!points ||
82 !g_variant_is_of_type(points, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
83 return false;
86 gsize num = g_variant_n_children(points);
87 for (gsize i = 0; i < num; i++) {
88 const char* ap =
89 g_variant_get_string(g_variant_get_child_value(points, i), nullptr);
90 if (!ap || !AddAPProperties(ap, aAccessPoints)) {
91 return false;
94 return true;
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));
103 if (!proxy) {
104 return false;
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)) {
112 return false;
114 const uint32_t MAX_SSID_LEN = 32;
115 gsize len = 0;
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)) {
125 return false;
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)) {
133 return false;
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);
141 return true;
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) {
151 if (!token) {
152 return false;
154 macAddres = strtoul(token, nullptr, 16);
155 token = strtok_r(nullptr, ":", &savedPtr);
157 aAp->setMac(macAddress);
158 return true;
161 } // namespace mozilla