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

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

Issue 6597044: Revert 76228 - Move core pieces of geolocation from chrome to content.This is... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 9 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
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // For OSX 10.5 we use the system API function WirelessScanSplit. This function
6 // is not documented or included in the SDK, so we use a reverse-engineered
7 // header, osx_wifi_.h. This file is taken from the iStumbler project
8 // (http://www.istumbler.net).
9
10 #include "content/browser/geolocation/wifi_data_provider_mac.h"
11
12 #include <dlfcn.h>
13 #include <stdio.h>
14
15 #include "base/utf_string_conversions.h"
16 #include "content/browser/geolocation/osx_wifi.h"
17 #include "content/browser/geolocation/wifi_data_provider_common.h"
18
19 namespace {
20 // The time periods, in milliseconds, between successive polls of the wifi data.
21 const int kDefaultPollingInterval = 120000; // 2 mins
22 const int kNoChangePollingInterval = 300000; // 5 mins
23 const int kTwoNoChangePollingInterval = 600000; // 10 mins
24 const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s
25
26 // Provides the wifi API binding for use when running on OSX 10.5 machines using
27 // the Apple80211 framework.
28 class Apple80211Api : public WifiDataProviderCommon::WlanApiInterface {
29 public:
30 Apple80211Api();
31 virtual ~Apple80211Api();
32
33 // Must be called before any other interface method. Will return false if the
34 // Apple80211 framework cannot be initialized (e.g. running on post-10.5 OSX),
35 // in which case no other method may be called.
36 bool Init();
37
38 // WlanApiInterface
39 virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data);
40
41 private:
42 // Handle, context and function pointers for Apple80211 library.
43 void* apple_80211_library_;
44 WirelessContext* wifi_context_;
45 WirelessAttachFunction WirelessAttach_function_;
46 WirelessScanSplitFunction WirelessScanSplit_function_;
47 WirelessDetachFunction WirelessDetach_function_;
48
49 WifiData wifi_data_;
50
51 DISALLOW_COPY_AND_ASSIGN(Apple80211Api);
52 };
53
54 Apple80211Api::Apple80211Api()
55 : apple_80211_library_(NULL), wifi_context_(NULL),
56 WirelessAttach_function_(NULL), WirelessScanSplit_function_(NULL),
57 WirelessDetach_function_(NULL) {
58 }
59
60 Apple80211Api::~Apple80211Api() {
61 if (WirelessDetach_function_)
62 (*WirelessDetach_function_)(wifi_context_);
63 dlclose(apple_80211_library_);
64 }
65
66 bool Apple80211Api::Init() {
67 DVLOG(1) << "Apple80211Api::Init";
68 apple_80211_library_ = dlopen(
69 "/System/Library/PrivateFrameworks/Apple80211.framework/Apple80211",
70 RTLD_LAZY);
71 if (!apple_80211_library_) {
72 DLOG(WARNING) << "Could not open Apple80211 library";
73 return false;
74 }
75 WirelessAttach_function_ = reinterpret_cast<WirelessAttachFunction>(
76 dlsym(apple_80211_library_, "WirelessAttach"));
77 WirelessScanSplit_function_ = reinterpret_cast<WirelessScanSplitFunction>(
78 dlsym(apple_80211_library_, "WirelessScanSplit"));
79 WirelessDetach_function_ = reinterpret_cast<WirelessDetachFunction>(
80 dlsym(apple_80211_library_, "WirelessDetach"));
81 DCHECK(WirelessAttach_function_);
82 DCHECK(WirelessScanSplit_function_);
83 DCHECK(WirelessDetach_function_);
84
85 if (!WirelessAttach_function_ || !WirelessScanSplit_function_ ||
86 !WirelessDetach_function_) {
87 DLOG(WARNING) << "Symbol error. Attach: " << !!WirelessAttach_function_
88 << " Split: " << !!WirelessScanSplit_function_
89 << " Detach: " << !!WirelessDetach_function_;
90 return false;
91 }
92
93 WIErr err = (*WirelessAttach_function_)(&wifi_context_, 0);
94 if (err != noErr) {
95 DLOG(WARNING) << "Error attaching: " << err;
96 return false;
97 }
98 return true;
99 }
100
101 bool Apple80211Api::GetAccessPointData(WifiData::AccessPointDataSet* data) {
102 DVLOG(1) << "Apple80211Api::GetAccessPointData";
103 DCHECK(data);
104 DCHECK(WirelessScanSplit_function_);
105 CFArrayRef managed_access_points = NULL;
106 CFArrayRef adhoc_access_points = NULL;
107 // Arrays returned here are owned by the caller.
108 WIErr err = (*WirelessScanSplit_function_)(wifi_context_,
109 &managed_access_points,
110 &adhoc_access_points,
111 0);
112 if (err != noErr) {
113 DLOG(WARNING) << "Error spliting scan: " << err;
114 return false;
115 }
116
117 if (managed_access_points == NULL) {
118 DLOG(WARNING) << "managed_access_points == NULL";
119 return false;
120 }
121
122 int num_access_points = CFArrayGetCount(managed_access_points);
123 DVLOG(1) << "Found " << num_access_points << " managed access points";
124 for (int i = 0; i < num_access_points; ++i) {
125 const WirelessNetworkInfo* access_point_info =
126 reinterpret_cast<const WirelessNetworkInfo*>(
127 CFDataGetBytePtr(
128 reinterpret_cast<const CFDataRef>(
129 CFArrayGetValueAtIndex(managed_access_points, i))));
130
131 // Currently we get only MAC address, signal strength, channel
132 // signal-to-noise and SSID
133 AccessPointData access_point_data;
134 access_point_data.mac_address =
135 MacAddressAsString16(access_point_info->macAddress);
136 // WirelessNetworkInfo::signal appears to be signal strength in dBm.
137 access_point_data.radio_signal_strength = access_point_info->signal;
138 access_point_data.channel = access_point_info->channel;
139 // WirelessNetworkInfo::noise appears to be noise floor in dBm.
140 access_point_data.signal_to_noise = access_point_info->signal -
141 access_point_info->noise;
142 if (!UTF8ToUTF16(reinterpret_cast<const char*>(access_point_info->name),
143 access_point_info->nameLen,
144 &access_point_data.ssid)) {
145 access_point_data.ssid.clear();
146 }
147 data->insert(access_point_data);
148 }
149
150 if (managed_access_points)
151 CFRelease(managed_access_points);
152 if (adhoc_access_points)
153 CFRelease(adhoc_access_points);
154
155 return true;
156 }
157 } // namespace
158
159 // static
160 template<>
161 WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
162 return new MacWifiDataProvider();
163 }
164
165 MacWifiDataProvider::MacWifiDataProvider() {
166 }
167
168 MacWifiDataProvider::~MacWifiDataProvider() {
169 }
170
171 MacWifiDataProvider::WlanApiInterface* MacWifiDataProvider::NewWlanApi() {
172 // Try and find a API binding that works: first try the officially supported
173 // CoreWLAN API, and if this fails (e.g. on OSX 10.5) fall back to the reverse
174 // engineered Apple80211 API.
175 MacWifiDataProvider::WlanApiInterface* core_wlan_api = NewCoreWlanApi();
176 if (core_wlan_api)
177 return core_wlan_api;
178
179 scoped_ptr<Apple80211Api> wlan_api(new Apple80211Api);
180 if (wlan_api->Init())
181 return wlan_api.release();
182
183 DVLOG(1) << "MacWifiDataProvider : failed to initialize any wlan api";
184 return NULL;
185 }
186
187 PollingPolicyInterface* MacWifiDataProvider::NewPollingPolicy() {
188 return new GenericPollingPolicy<kDefaultPollingInterval,
189 kNoChangePollingInterval,
190 kTwoNoChangePollingInterval,
191 kNoWifiPollingIntervalMilliseconds>;
192 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698