Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: content/browser/geolocation/wifi_data_provider_linux.cc

Issue 7413004: Uploading for backup... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: backup Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/linux/system.gyp ('k') | net/dbus/dbus.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Provides wifi scan API binding for suitable for typical linux distributions. 5 // Provides wifi scan API binding for suitable for typical linux distributions.
6 // Currently, only the NetworkManager API is used, accessed via D-Bus (in turn 6 // Currently, only the NetworkManager API is used, accessed via D-Bus (in turn
7 // accessed via the GLib wrapper). 7 // accessed via the GLib wrapper).
8 8
9 #include "content/browser/geolocation/wifi_data_provider_linux.h" 9 #include "content/browser/geolocation/wifi_data_provider_linux.h"
10 10
11 #include <dbus/dbus-glib.h>
12 #include <dbus/dbus-glib-lowlevel.h>
13 #include <dbus/dbus.h>
14 #include <dlfcn.h>
15 #include <glib.h>
16
17 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
18 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
19 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "net/dbus/dbus.h"
20 15
21 namespace { 16 namespace {
22 // The time periods between successive polls of the wifi data. 17 // The time periods between successive polls of the wifi data.
23 const int kDefaultPollingIntervalMilliseconds = 10 * 1000; // 10s 18 const int kDefaultPollingIntervalMilliseconds = 10 * 1000; // 10s
24 const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000; // 2 mins 19 const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000; // 2 mins
25 const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000; // 10 mins 20 const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000; // 10 mins
26 const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s 21 const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s
27 22
28 const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager"; 23 const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager";
29 const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager"; 24 const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager";
30 const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager"; 25 const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager";
31 26
32 // From http://projects.gnome.org/NetworkManager/developers/spec.html 27 // From http://projects.gnome.org/NetworkManager/developers/spec.html
33 enum { NM_DEVICE_TYPE_WIFI = 2 }; 28 enum { NM_DEVICE_TYPE_WIFI = 2 };
34 29
35 // Function type matching dbus_g_bus_get_private so that we can
36 // dynamically determine the presence of this symbol (see
37 // NetworkManagerWlanApi::Init)
38 typedef DBusGConnection* DBusGBusGetPrivateFunc(
39 DBusBusType type, GMainContext* context, GError** error);
40
41 // Utility wrappers to make various GLib & DBus structs into scoped objects.
42 class ScopedGPtrArrayFree {
43 public:
44 void operator()(GPtrArray* x) const {
45 if (x)
46 g_ptr_array_free(x, TRUE);
47 }
48 };
49 // Use ScopedGPtrArrayPtr as if it were scoped_ptr<GPtrArray>
50 typedef scoped_ptr_malloc<GPtrArray, ScopedGPtrArrayFree> ScopedGPtrArrayPtr;
51
52 class ScopedGObjectFree {
53 public:
54 void operator()(void* x) const {
55 if (x)
56 g_object_unref(x);
57 }
58 };
59 // Use ScopedDBusGProxyPtr as if it were scoped_ptr<DBusGProxy>
60 typedef scoped_ptr_malloc<DBusGProxy, ScopedGObjectFree> ScopedDBusGProxyPtr;
61
62 // Use ScopedGValue::v as an instance of GValue with automatic cleanup.
63 class ScopedGValue {
64 public:
65 ScopedGValue()
66 : v(empty_gvalue()) {
67 }
68 ~ScopedGValue() {
69 g_value_unset(&v);
70 }
71 static GValue empty_gvalue() {
72 GValue value = {0};
73 return value;
74 }
75
76 GValue v;
77 };
78
79 // Use ScopedDLHandle to automatically clean up after dlopen.
80 class ScopedDLHandle {
81 public:
82 ScopedDLHandle(void* handle)
83 : handle_(handle) {
84 }
85 ~ScopedDLHandle() {
86 if (handle_)
87 dlclose(handle_);
88 }
89 void* get() {
90 return handle_;
91 }
92 private:
93 void *handle_;
94 };
95
96 // Wifi API binding to NetworkManager, to allow reuse of the polling behavior 30 // Wifi API binding to NetworkManager, to allow reuse of the polling behavior
97 // defined in WifiDataProviderCommon. 31 // defined in WifiDataProviderCommon.
98 // TODO(joth): NetworkManager also allows for notification based handling, 32 // TODO(joth): NetworkManager also allows for notification based handling,
99 // however this will require reworking of the threading code to run a GLib 33 // however this will require reworking of the threading code to run a GLib
100 // event loop (GMainLoop). 34 // event loop (GMainLoop).
101 class NetworkManagerWlanApi : public WifiDataProviderCommon::WlanApiInterface { 35 class NetworkManagerWlanApi : public WifiDataProviderCommon::WlanApiInterface {
102 public: 36 public:
103 NetworkManagerWlanApi(); 37 NetworkManagerWlanApi();
104 ~NetworkManagerWlanApi(); 38 ~NetworkManagerWlanApi();
105 39
106 // Must be called before any other interface method. Will return false if the 40 // Must be called before any other interface method. Will return false if the
107 // NetworkManager session cannot be created (e.g. not present on this distro), 41 // NetworkManager session cannot be created (e.g. not present on this distro),
108 // in which case no other method may be called. 42 // in which case no other method may be called.
109 bool Init(); 43 bool Init();
110 44
111 // WifiDataProviderCommon::WlanApiInterface 45 // WifiDataProviderCommon::WlanApiInterface
112 bool GetAccessPointData(WifiData::AccessPointDataSet* data); 46 bool GetAccessPointData(WifiData::AccessPointDataSet* data);
113 47
114 private: 48 private:
115 // Checks if the last dbus call returned an error. If it did, logs the error
116 // message, frees it and returns true.
117 // This must be called after every dbus call that accepts |&error_|
118 bool CheckError();
119
120 // Enumerates the list of available network adapter devices known to 49 // Enumerates the list of available network adapter devices known to
121 // NetworkManager. Ownership of the array (and contained objects) is returned 50 // NetworkManager. Return true on success.
122 // to the caller. 51 bool GetAdapterDeviceList(std::vector<std::string>* device_paths);
123 GPtrArray* GetAdapterDeviceList();
124 52
125 // Given the NetworkManager path to a wireless adapater, dumps the wifi scan 53 // Given the NetworkManager path to a wireless adapater, dumps the wifi scan
126 // results and appends them to |data|. Returns false if a fatal error is 54 // results and appends them to |data|. Returns false if a fatal error is
127 // encountered such that the data set could not be populated. 55 // encountered such that the data set could not be populated.
128 bool GetAccessPointsForAdapter(const gchar* adapter_path, 56 bool GetAccessPointsForAdapter(const std::string& adapter_path,
129 WifiData::AccessPointDataSet* data); 57 WifiData::AccessPointDataSet* data);
130 58
131 // Internal method used by |GetAccessPointsForAdapter|, given a wifi access 59 // Internal method used by |GetAccessPointsForAdapter|, given a wifi access
132 // point proxy retrieves the named property into |value_out|. Returns false if 60 // point proxy retrieves the named property into |response|. Returns false if
133 // the property could not be read, or is not of type |expected_gvalue_type|. 61 // the property could not be read.
134 bool GetAccessPointProperty(DBusGProxy* proxy, const char* property_name, 62 bool GetAccessPointProperty(net::dbus::ObjectProxy* proxy,
135 int expected_gvalue_type, GValue* value_out); 63 const std::string& property_name,
64 net::dbus::Response* response);
136 65
137 // Error from the last dbus call. NULL when there's no error. Freed and 66 scoped_ptr<net::dbus::Bus> system_bus_;
138 // cleared by CheckError(). 67 scoped_ptr<net::dbus::ObjectProxy> network_manager_proxy_;
139 GError* error_;
140 // Connection to the dbus system bus.
141 DBusGConnection* connection_;
142 // Main context
143 GMainContext* context_;
144 // Proxy to the network manager dbus service.
145 ScopedDBusGProxyPtr proxy_;
146 68
147 DISALLOW_COPY_AND_ASSIGN(NetworkManagerWlanApi); 69 DISALLOW_COPY_AND_ASSIGN(NetworkManagerWlanApi);
148 }; 70 };
149 71
150 // Convert a wifi frequency to the corresponding channel. Adapted from 72 // Convert a wifi frequency to the corresponding channel. Adapted from
151 // geolocaiton/wifilib.cc in googleclient (internal to google). 73 // geolocaiton/wifilib.cc in googleclient (internal to google).
152 int frquency_in_khz_to_channel(int frequency_khz) { 74 int frquency_in_khz_to_channel(int frequency_khz) {
153 if (frequency_khz >= 2412000 && frequency_khz <= 2472000) // Channels 1-13. 75 if (frequency_khz >= 2412000 && frequency_khz <= 2472000) // Channels 1-13.
154 return (frequency_khz - 2407000) / 5000; 76 return (frequency_khz - 2407000) / 5000;
155 if (frequency_khz == 2484000) 77 if (frequency_khz == 2484000)
156 return 14; 78 return 14;
157 if (frequency_khz > 5000000 && frequency_khz < 6000000) // .11a bands. 79 if (frequency_khz > 5000000 && frequency_khz < 6000000) // .11a bands.
158 return (frequency_khz - 5000000) / 5000; 80 return (frequency_khz - 5000000) / 5000;
159 // Ignore everything else. 81 // Ignore everything else.
160 return AccessPointData().channel; // invalid channel 82 return AccessPointData().channel; // invalid channel
161 } 83 }
162 84
163 NetworkManagerWlanApi::NetworkManagerWlanApi() 85 NetworkManagerWlanApi::NetworkManagerWlanApi() {
164 : error_(NULL),
165 connection_(NULL),
166 context_(NULL)
167 {
168 } 86 }
169 87
170 NetworkManagerWlanApi::~NetworkManagerWlanApi() { 88 NetworkManagerWlanApi::~NetworkManagerWlanApi() {
171 proxy_.reset();
172 if (connection_) {
173 dbus_connection_close(dbus_g_connection_get_connection(connection_));
174 dbus_g_connection_unref(connection_);
175 }
176 if (context_)
177 g_main_context_unref(context_);
178
179 DCHECK(!error_) << "Missing a call to CheckError() to clear |error_|";
180 } 89 }
181 90
182 bool NetworkManagerWlanApi::Init() { 91 bool NetworkManagerWlanApi::Init() {
183 // Chrome DLL init code handles initializing the thread system, so rather than 92 net::dbus::Bus::Options options;
184 // get caught up with that nonsense here, lets just assert our requirement. 93 options.bus_type = net::dbus::Bus::SYSTEM;
185 CHECK(g_thread_supported()); 94 system_bus_.reset(new net::dbus::Bus(options));
186 95 network_manager_proxy_.reset(
187 // We require a private bus to ensure that we don't interfere with the 96 system_bus_->GetObjectProxy(kNetworkManagerServiceName,
188 // default loop on the main thread. Unforunately this functionality is only 97 kNetworkManagerPath));
189 // available in dbus-glib-0.84 and later. We do a dynamic symbol lookup
190 // to determine if dbus_g_bus_get_private is available. See bug
191 // http://code.google.com/p/chromium/issues/detail?id=59913 for more
192 // information.
193 ScopedDLHandle handle(dlopen(NULL, RTLD_LAZY));
194 if (!handle.get())
195 return false;
196
197 DBusGBusGetPrivateFunc *my_dbus_g_bus_get_private =
198 (DBusGBusGetPrivateFunc *) dlsym(handle.get(), "dbus_g_bus_get_private");
199
200 if (!my_dbus_g_bus_get_private) {
201 LOG(ERROR) << "We need dbus-glib >= 0.84 for wifi geolocation.";
202 return false;
203 }
204 // Get a private connection to the session bus.
205 context_ = g_main_context_new();
206 DCHECK(context_);
207 connection_ = my_dbus_g_bus_get_private(DBUS_BUS_SYSTEM, context_, &error_);
208
209 if (CheckError())
210 return false;
211 DCHECK(connection_);
212
213 // Disable timers on the connection since we don't need them and
214 // we're not going to run them anyway as the connection is associated
215 // with a private context. See bug http://crbug.com/40803
216 dbus_bool_t ok = dbus_connection_set_timeout_functions(
217 dbus_g_connection_get_connection(connection_),
218 NULL, NULL, NULL, NULL, NULL);
219 DCHECK(ok);
220
221 proxy_.reset(dbus_g_proxy_new_for_name(connection_,
222 kNetworkManagerServiceName,
223 kNetworkManagerPath,
224 kNetworkManagerInterface));
225 DCHECK(proxy_.get());
226
227 // Validate the proxy object by checking we can enumerate devices. 98 // Validate the proxy object by checking we can enumerate devices.
228 ScopedGPtrArrayPtr device_list(GetAdapterDeviceList()); 99 std::vector<std::string> adapter_paths;
229 return !!device_list.get(); 100 return GetAdapterDeviceList(&adapter_paths);
230 } 101 }
231 102
232 bool NetworkManagerWlanApi::GetAccessPointData( 103 bool NetworkManagerWlanApi::GetAccessPointData(
233 WifiData::AccessPointDataSet* data) { 104 WifiData::AccessPointDataSet* data) {
234 ScopedGPtrArrayPtr device_list(GetAdapterDeviceList()); 105 std::vector<std::string> device_paths;
235 if (device_list == NULL) { 106 if (!GetAdapterDeviceList(&device_paths)) {
236 DLOG(WARNING) << "Could not enumerate access points"; 107 DLOG(WARNING) << "Could not enumerate access points";
237 return false; 108 return false;
238 } 109 }
239 int success_count = 0; 110 int success_count = 0;
240 int fail_count = 0; 111 int fail_count = 0;
241 112
242 // Iterate the devices, getting APs for each wireless adapter found 113 // Iterate the devices, getting APs for each wireless adapter found
243 for (guint i = 0; i < device_list->len; i++) { 114 for (size_t i = 0; i < device_paths.size(); ++i) {
244 const gchar* device_path = 115 const std::string& device_path = device_paths[i];
245 reinterpret_cast<const gchar*>(g_ptr_array_index(device_list, i)); 116 scoped_ptr<net::dbus::ObjectProxy> properties_proxy(
117 system_bus_->GetObjectProxy(kNetworkManagerServiceName,
118 device_path));
246 119
247 ScopedDBusGProxyPtr device_properties_proxy(dbus_g_proxy_new_from_proxy( 120 net::dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get");
248 proxy_.get(), DBUS_INTERFACE_PROPERTIES, device_path)); 121 net::dbus::MessageWriter builder(&method_call);
249 ScopedGValue device_type_g_value; 122 builder.AppendString("org.freedesktop.NetworkManager.Device");
250 dbus_g_proxy_call(device_properties_proxy.get(), "Get", &error_, 123 builder.AppendString("DeviceType");
251 G_TYPE_STRING, "org.freedesktop.NetworkManager.Device", 124 net::dbus::Response response;
252 G_TYPE_STRING, "DeviceType", 125 if (!properties_proxy->CallMethodSync(&method_call,
253 G_TYPE_INVALID, 126 &response)) {
254 G_TYPE_VALUE, &device_type_g_value.v, 127 // Let's see the next device.
255 G_TYPE_INVALID);
256 if (CheckError())
257 continue; 128 continue;
258 129 }
259 const guint device_type = g_value_get_uint(&device_type_g_value.v); 130 net::dbus::MessageReader reader(&response);
131 uint32 device_type = 0;
132 if (!reader.PopVariantOfUint32(&device_type))
133 return false;
134 VLOG(1) << "Device type: " << device_type;
260 135
261 if (device_type == NM_DEVICE_TYPE_WIFI) { // Found a wlan adapter 136 if (device_type == NM_DEVICE_TYPE_WIFI) { // Found a wlan adapter
262 if (GetAccessPointsForAdapter(device_path, data)) 137 if (GetAccessPointsForAdapter(device_path.c_str(), data))
263 ++success_count; 138 ++success_count;
264 else 139 else
265 ++fail_count; 140 ++fail_count;
266 } 141 }
267 } 142 }
268 // At least one successfull scan overrides any other adapter reporting error. 143 // At least one successfull scan overrides any other adapter reporting error.
269 return success_count || fail_count == 0; 144 return success_count || fail_count == 0;
270 } 145 }
271 146
272 bool NetworkManagerWlanApi::CheckError() { 147 bool NetworkManagerWlanApi::GetAdapterDeviceList(
273 if (error_) { 148 std::vector<std::string>* device_paths) {
274 LOG(ERROR) << "Failed to complete NetworkManager call: " << error_->message; 149 net::dbus::MethodCall method_call(kNetworkManagerInterface, "GetDevices");
275 g_error_free(error_); 150 net::dbus::Response response;
276 error_ = NULL; 151 if (!network_manager_proxy_->CallMethodSync(&method_call,
277 return true; 152 &response))
278 } 153 return false;
279 return false; 154
155 net::dbus::MessageReader reader(&response);
156 return reader.PopArrayOfObjectPaths(device_paths);
280 } 157 }
281 158
282 GPtrArray* NetworkManagerWlanApi::GetAdapterDeviceList() {
283 GPtrArray* device_list = NULL;
284 dbus_g_proxy_call(proxy_.get(), "GetDevices", &error_,
285 G_TYPE_INVALID,
286 dbus_g_type_get_collection("GPtrArray",
287 DBUS_TYPE_G_OBJECT_PATH),
288 &device_list,
289 G_TYPE_INVALID);
290 if (CheckError())
291 return NULL;
292 return device_list;
293 }
294 159
295 bool NetworkManagerWlanApi::GetAccessPointsForAdapter( 160 bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
296 const gchar* adapter_path, WifiData::AccessPointDataSet* data) { 161 const std::string& adapter_path, WifiData::AccessPointDataSet* data) {
297 DCHECK(proxy_.get());
298
299 // Create a proxy object for this wifi adapter, and ask it to do a scan 162 // Create a proxy object for this wifi adapter, and ask it to do a scan
300 // (or at least, dump its scan results). 163 // (or at least, dump its scan results).
301 ScopedDBusGProxyPtr wifi_adapter_proxy(dbus_g_proxy_new_from_proxy( 164 scoped_ptr<net::dbus::ObjectProxy> wireless_proxy(
302 proxy_.get(), "org.freedesktop.NetworkManager.Device.Wireless", 165 system_bus_->GetObjectProxy(kNetworkManagerServiceName,
303 adapter_path)); 166 adapter_path));
167 net::dbus::MethodCall method_call(
168 "org.freedesktop.NetworkManager.Device.Wireless",
169 "GetAccessPoints");
170 net::dbus::Response response;
171 if (!wireless_proxy->CallMethodSync(&method_call, &response)) {
172 return false;
173 }
174 net::dbus::MessageReader reader(&response);
175 std::vector<std::string> access_point_paths;
176 reader.PopArrayOfObjectPaths(&access_point_paths);
304 177
305 GPtrArray* ap_list_raw = NULL; 178 DVLOG(1) << "Wireless adapter " << adapter_path << " found "
306 // Enumerate the access points for this adapter. 179 << access_point_paths.size() << " access points.";
307 dbus_g_proxy_call(wifi_adapter_proxy.get(), "GetAccessPoints", &error_,
308 G_TYPE_INVALID,
309 dbus_g_type_get_collection("GPtrArray",
310 DBUS_TYPE_G_OBJECT_PATH),
311 &ap_list_raw,
312 G_TYPE_INVALID);
313 ScopedGPtrArrayPtr ap_list(ap_list_raw); // Takes ownership.
314 ap_list_raw = NULL;
315 180
316 if (CheckError()) 181 for (size_t i = 0; i < access_point_paths.size(); ++i) {
317 return false; 182 const std::string& access_point_path = access_point_paths[i];
318 183
319 DVLOG(1) << "Wireless adapter " << adapter_path << " found " << ap_list->len 184 scoped_ptr<net::dbus::ObjectProxy> access_point_proxy(
320 << " access points."; 185 system_bus_->GetObjectProxy(kNetworkManagerServiceName,
321 186 access_point_path));
322 for (guint i = 0; i < ap_list->len; i++) {
323 const gchar* ap_path =
324 reinterpret_cast<const gchar*>(g_ptr_array_index(ap_list, i));
325 ScopedDBusGProxyPtr access_point_proxy(dbus_g_proxy_new_from_proxy(
326 proxy_.get(), DBUS_INTERFACE_PROPERTIES, ap_path));
327 187
328 AccessPointData access_point_data; 188 AccessPointData access_point_data;
329 { // Read SSID. 189 {
330 ScopedGValue ssid_g_value; 190 net::dbus::Response response;
331 if (!GetAccessPointProperty(access_point_proxy.get(), "Ssid", 191 if (!GetAccessPointProperty(access_point_proxy.get(), "Ssid",
332 G_TYPE_BOXED, &ssid_g_value.v)) 192 &response))
333 continue; 193 continue;
334 const GArray* ssid = 194 // The response should contain a variant that contains an array of bytes.
335 reinterpret_cast<const GArray*>(g_value_get_boxed(&ssid_g_value.v)); 195 net::dbus::MessageReader reader(&response);
336 UTF8ToUTF16(ssid->data, ssid->len, &access_point_data.ssid); 196 net::dbus::MessageReader variant_reader(&response);
197 if (!reader.PopVariant(&variant_reader))
198 return false;
199 std::vector<uint8> ssid_bytes;
200 if (!variant_reader.PopArrayOfBytes(&ssid_bytes))
201 return false;
202 std::string ssid(ssid_bytes.begin(), ssid_bytes.end());
203 access_point_data.ssid = UTF8ToUTF16(ssid);
204 VLOG(1) << "SSID: " << access_point_data.ssid;
337 } 205 }
338 206
339 { // Read the mac address 207 { // Read the mac address
340 ScopedGValue mac_g_value; 208 net::dbus::Response response;
341 if (!GetAccessPointProperty(access_point_proxy.get(), "HwAddress", 209 if (!GetAccessPointProperty(access_point_proxy.get(), "HwAddress",
342 G_TYPE_STRING, &mac_g_value.v)) 210 &response))
343 continue; 211 continue;
344 std::string mac = g_value_get_string(&mac_g_value.v); 212 net::dbus::MessageReader reader(&response);
213 std::string mac;
214 reader.PopVariantOfString(&mac);
215
345 ReplaceSubstringsAfterOffset(&mac, 0U, ":", ""); 216 ReplaceSubstringsAfterOffset(&mac, 0U, ":", "");
346 std::vector<uint8> mac_bytes; 217 std::vector<uint8> mac_bytes;
347 if (!base::HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) { 218 if (!base::HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) {
348 DLOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size() 219 DLOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size()
349 << " bytes) so using raw string: " << mac; 220 << " bytes) so using raw string: " << mac;
350 access_point_data.mac_address = UTF8ToUTF16(mac); 221 access_point_data.mac_address = UTF8ToUTF16(mac);
351 } else { 222 } else {
352 access_point_data.mac_address = MacAddressAsString16(&mac_bytes[0]); 223 access_point_data.mac_address = MacAddressAsString16(&mac_bytes[0]);
353 } 224 }
225 VLOG(1) << "MAC: " << access_point_data.mac_address;
354 } 226 }
355 227
356 { // Read signal strength. 228 { // Read signal strength.
357 ScopedGValue signal_g_value; 229 net::dbus::Response response;
358 if (!GetAccessPointProperty(access_point_proxy.get(), "Strength", 230 if (!GetAccessPointProperty(access_point_proxy.get(), "Strength",
359 G_TYPE_UCHAR, &signal_g_value.v)) 231 &response))
360 continue; 232 continue;
233 net::dbus::MessageReader reader(&response);
234 uint8 strength = 0;
235 if (!reader.PopVariantOfByte(&strength))
236 return false;
361 // Convert strength as a percentage into dBs. 237 // Convert strength as a percentage into dBs.
362 access_point_data.radio_signal_strength = 238 access_point_data.radio_signal_strength = -100 + strength / 2;
363 -100 + g_value_get_uchar(&signal_g_value.v) / 2; 239 VLOG(1) << "Strength(new): " << access_point_data.radio_signal_strength;
364 } 240 }
365 241
366 { // Read the channel 242 { // Read the channel
367 ScopedGValue freq_g_value; 243 net::dbus::Response response;
368 if (!GetAccessPointProperty(access_point_proxy.get(), "Frequency", 244 if (!GetAccessPointProperty(access_point_proxy.get(), "Frequency",
369 G_TYPE_UINT, &freq_g_value.v)) 245 &response))
370 continue; 246 continue;
247 net::dbus::MessageReader reader(&response);
248 uint32 frequency = 0;
249 if (!reader.PopVariantOfUint32(&frequency))
250 return false;
251
371 // NetworkManager returns frequency in MHz. 252 // NetworkManager returns frequency in MHz.
372 access_point_data.channel = 253 access_point_data.channel =
373 frquency_in_khz_to_channel(g_value_get_uint(&freq_g_value.v) * 1000); 254 frquency_in_khz_to_channel(frequency * 1000);
255 VLOG(1) << "Channel: " << access_point_data.channel;
374 } 256 }
375 data->insert(access_point_data); 257 data->insert(access_point_data);
376 } 258 }
377 return true; 259 return true;
378 } 260 }
379 261
380 bool NetworkManagerWlanApi::GetAccessPointProperty(DBusGProxy* proxy, 262 bool NetworkManagerWlanApi::GetAccessPointProperty(
381 const char* property_name, 263 net::dbus::ObjectProxy* access_point_proxy,
382 int expected_gvalue_type, 264 const std::string& property_name,
383 GValue* value_out) { 265 net::dbus::Response* response) {
384 dbus_g_proxy_call(proxy, "Get", &error_, 266 net::dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get");
385 G_TYPE_STRING, "org.freedesktop.NetworkManager.AccessPoint", 267 net::dbus::MessageWriter builder(&method_call);
386 G_TYPE_STRING, property_name, 268 builder.AppendString("org.freedesktop.NetworkManager.AccessPoint");
387 G_TYPE_INVALID, 269 builder.AppendString(property_name);
388 G_TYPE_VALUE, value_out, 270 return access_point_proxy->CallMethodSync(&method_call,
389 G_TYPE_INVALID); 271 response);
390 if (CheckError())
391 return false;
392 if (!G_VALUE_HOLDS(value_out, expected_gvalue_type)) {
393 DLOG(WARNING) << "Property " << property_name << " unexptected type "
394 << G_VALUE_TYPE(value_out);
395 return false;
396 }
397 return true;
398 } 272 }
399 273
400 } // namespace 274 } // namespace
401 275
402 // static 276 // static
403 template<> 277 template<>
404 WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() { 278 WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
405 return new WifiDataProviderLinux(); 279 return new WifiDataProviderLinux();
406 } 280 }
407 281
(...skipping 10 matching lines...) Expand all
418 return wlan_api.release(); 292 return wlan_api.release();
419 return NULL; 293 return NULL;
420 } 294 }
421 295
422 PollingPolicyInterface* WifiDataProviderLinux::NewPollingPolicy() { 296 PollingPolicyInterface* WifiDataProviderLinux::NewPollingPolicy() {
423 return new GenericPollingPolicy<kDefaultPollingIntervalMilliseconds, 297 return new GenericPollingPolicy<kDefaultPollingIntervalMilliseconds,
424 kNoChangePollingIntervalMilliseconds, 298 kNoChangePollingIntervalMilliseconds,
425 kTwoNoChangePollingIntervalMilliseconds, 299 kTwoNoChangePollingIntervalMilliseconds,
426 kNoWifiPollingIntervalMilliseconds>; 300 kNoWifiPollingIntervalMilliseconds>;
427 } 301 }
OLDNEW
« no previous file with comments | « build/linux/system.gyp ('k') | net/dbus/dbus.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698