| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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 // We use the OSX system API function WirelessScanSplit. This function is not | 5 // For OSX 10.5 we use the system API function WirelessScanSplit. This function |
| 6 // documented or included in the SDK, so we use a reverse-engineered header, | 6 // is not documented or included in the SDK, so we use a reverse-engineered |
| 7 // osx_wifi_.h. This file is taken from the iStumbler project | 7 // header, osx_wifi_.h. This file is taken from the iStumbler project |
| 8 // (http://www.istumbler.net). | 8 // (http://www.istumbler.net). |
| 9 | 9 |
| 10 #include "chrome/browser/geolocation/wifi_data_provider_mac.h" | 10 #include "chrome/browser/geolocation/wifi_data_provider_mac.h" |
| 11 | 11 |
| 12 #include <dlfcn.h> | 12 #include <dlfcn.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "chrome/browser/geolocation/osx_wifi.h" | 15 #include "chrome/browser/geolocation/osx_wifi.h" |
| 16 #include "chrome/browser/geolocation/wifi_data_provider_common.h" | 16 #include "chrome/browser/geolocation/wifi_data_provider_common.h" |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 // The time periods, in milliseconds, between successive polls of the wifi data. | 19 // The time periods, in milliseconds, between successive polls of the wifi data. |
| 20 const int kDefaultPollingInterval = 120000; // 2 mins | 20 const int kDefaultPollingInterval = 120000; // 2 mins |
| 21 const int kNoChangePollingInterval = 300000; // 5 mins | 21 const int kNoChangePollingInterval = 300000; // 5 mins |
| 22 const int kTwoNoChangePollingInterval = 600000; // 10 mins | 22 const int kTwoNoChangePollingInterval = 600000; // 10 mins |
| 23 | 23 |
| 24 class OsxWlanApi : public WifiDataProviderCommon::WlanApiInterface { | 24 // Provides the wifi API binding for use when running on OSX 10.5 machines using |
| 25 // the Apple80211 framework. |
| 26 class Apple80211Api : public WifiDataProviderCommon::WlanApiInterface { |
| 25 public: | 27 public: |
| 26 OsxWlanApi(); | 28 Apple80211Api(); |
| 27 virtual ~OsxWlanApi(); | 29 virtual ~Apple80211Api(); |
| 28 | 30 |
| 29 bool Init(); | 31 bool Init(); |
| 30 | 32 |
| 31 // WlanApiInterface | 33 // WlanApiInterface |
| 32 virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data); | 34 virtual bool GetAccessPointData(WifiData::AccessPointDataSet* data); |
| 33 | 35 |
| 34 private: | 36 private: |
| 35 // Handle, context and function pointers for Apple80211 library. | 37 // Handle, context and function pointers for Apple80211 library. |
| 36 void* apple_80211_library_; | 38 void* apple_80211_library_; |
| 37 WirelessContext* wifi_context_; | 39 WirelessContext* wifi_context_; |
| 38 WirelessAttachFunction WirelessAttach_function_; | 40 WirelessAttachFunction WirelessAttach_function_; |
| 39 WirelessScanSplitFunction WirelessScanSplit_function_; | 41 WirelessScanSplitFunction WirelessScanSplit_function_; |
| 40 WirelessDetachFunction WirelessDetach_function_; | 42 WirelessDetachFunction WirelessDetach_function_; |
| 41 | 43 |
| 42 WifiData wifi_data_; | 44 WifiData wifi_data_; |
| 43 }; | 45 }; |
| 44 | 46 |
| 45 OsxWlanApi::OsxWlanApi() | 47 Apple80211Api::Apple80211Api() |
| 46 : apple_80211_library_(NULL), wifi_context_(NULL), | 48 : apple_80211_library_(NULL), wifi_context_(NULL), |
| 47 WirelessAttach_function_(NULL), WirelessScanSplit_function_(NULL), | 49 WirelessAttach_function_(NULL), WirelessScanSplit_function_(NULL), |
| 48 WirelessDetach_function_(NULL) { | 50 WirelessDetach_function_(NULL) { |
| 49 } | 51 } |
| 50 | 52 |
| 51 OsxWlanApi::~OsxWlanApi() { | 53 Apple80211Api::~Apple80211Api() { |
| 52 if (WirelessDetach_function_) | 54 if (WirelessDetach_function_) |
| 53 (*WirelessDetach_function_)(wifi_context_); | 55 (*WirelessDetach_function_)(wifi_context_); |
| 54 dlclose(apple_80211_library_); | 56 dlclose(apple_80211_library_); |
| 55 } | 57 } |
| 56 | 58 |
| 57 bool OsxWlanApi::Init() { | 59 bool Apple80211Api::Init() { |
| 58 DLOG(INFO) << "OsxWlanApi::Init"; | 60 DLOG(INFO) << "Apple80211Api::Init"; |
| 59 apple_80211_library_ = dlopen( | 61 apple_80211_library_ = dlopen( |
| 60 "/System/Library/PrivateFrameworks/Apple80211.framework/Apple80211", | 62 "/System/Library/PrivateFrameworks/Apple80211.framework/Apple80211", |
| 61 RTLD_LAZY); | 63 RTLD_LAZY); |
| 62 if (!apple_80211_library_) { | 64 if (!apple_80211_library_) { |
| 63 DLOG(WARNING) << "Could not open Apple80211 library"; | 65 DLOG(WARNING) << "Could not open Apple80211 library"; |
| 64 return false; | 66 return false; |
| 65 } | 67 } |
| 66 WirelessAttach_function_ = reinterpret_cast<WirelessAttachFunction>( | 68 WirelessAttach_function_ = reinterpret_cast<WirelessAttachFunction>( |
| 67 dlsym(apple_80211_library_, "WirelessAttach")); | 69 dlsym(apple_80211_library_, "WirelessAttach")); |
| 68 WirelessScanSplit_function_ = reinterpret_cast<WirelessScanSplitFunction>( | 70 WirelessScanSplit_function_ = reinterpret_cast<WirelessScanSplitFunction>( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 82 } | 84 } |
| 83 | 85 |
| 84 WIErr err = (*WirelessAttach_function_)(&wifi_context_, 0); | 86 WIErr err = (*WirelessAttach_function_)(&wifi_context_, 0); |
| 85 if (err != noErr) { | 87 if (err != noErr) { |
| 86 DLOG(WARNING) << "Error attaching: " << err; | 88 DLOG(WARNING) << "Error attaching: " << err; |
| 87 return false; | 89 return false; |
| 88 } | 90 } |
| 89 return true; | 91 return true; |
| 90 } | 92 } |
| 91 | 93 |
| 92 bool OsxWlanApi::GetAccessPointData(WifiData::AccessPointDataSet* data) { | 94 bool Apple80211Api::GetAccessPointData(WifiData::AccessPointDataSet* data) { |
| 93 DLOG(INFO) << "OsxWlanApi::GetAccessPointData"; | 95 DLOG(INFO) << "Apple80211Api::GetAccessPointData"; |
| 94 DCHECK(data); | 96 DCHECK(data); |
| 95 DCHECK(WirelessScanSplit_function_); | 97 DCHECK(WirelessScanSplit_function_); |
| 96 CFArrayRef managed_access_points = NULL; | 98 CFArrayRef managed_access_points = NULL; |
| 97 CFArrayRef adhoc_access_points = NULL; | 99 CFArrayRef adhoc_access_points = NULL; |
| 98 WIErr err = (*WirelessScanSplit_function_)(wifi_context_, | 100 WIErr err = (*WirelessScanSplit_function_)(wifi_context_, |
| 99 &managed_access_points, | 101 &managed_access_points, |
| 100 &adhoc_access_points, | 102 &adhoc_access_points, |
| 101 0); | 103 0); |
| 102 if (err != noErr) { | 104 if (err != noErr) { |
| 103 DLOG(WARNING) << "Error spliting scan: " << err; | 105 DLOG(WARNING) << "Error spliting scan: " << err; |
| 104 return false; | 106 return false; |
| 105 } | 107 } |
| 106 | 108 |
| 107 if (managed_access_points == NULL) { | 109 if (managed_access_points == NULL) { |
| 108 DLOG(WARNING) << "managed_access_points == NULL"; | 110 DLOG(WARNING) << "managed_access_points == NULL"; |
| 109 return false; | 111 return false; |
| 110 } | 112 } |
| 111 | 113 |
| 112 int num_access_points = CFArrayGetCount(managed_access_points); | 114 int num_access_points = CFArrayGetCount(managed_access_points); |
| 113 DLOG(INFO) << "Found " << num_access_points << " managed access points:-"; | 115 DLOG(INFO) << "Found " << num_access_points << " managed access points"; |
| 114 for (int i = 0; i < num_access_points; ++i) { | 116 for (int i = 0; i < num_access_points; ++i) { |
| 115 const WirelessNetworkInfo* access_point_info = | 117 const WirelessNetworkInfo* access_point_info = |
| 116 reinterpret_cast<const WirelessNetworkInfo*>( | 118 reinterpret_cast<const WirelessNetworkInfo*>( |
| 117 CFDataGetBytePtr( | 119 CFDataGetBytePtr( |
| 118 reinterpret_cast<const CFDataRef>( | 120 reinterpret_cast<const CFDataRef>( |
| 119 CFArrayGetValueAtIndex(managed_access_points, i)))); | 121 CFArrayGetValueAtIndex(managed_access_points, i)))); |
| 120 | 122 |
| 121 // Currently we get only MAC address, signal strength, channel | 123 // Currently we get only MAC address, signal strength, channel |
| 122 // signal-to-noise and SSID | 124 // signal-to-noise and SSID |
| 123 // TODO(steveblock): Work out how to get age. | |
| 124 AccessPointData access_point_data; | 125 AccessPointData access_point_data; |
| 125 access_point_data.mac_address = | 126 access_point_data.mac_address = |
| 126 MacAddressAsString16(access_point_info->macAddress); | 127 MacAddressAsString16(access_point_info->macAddress); |
| 127 // WirelessNetworkInfo::signal appears to be signal strength in dBm. | 128 // WirelessNetworkInfo::signal appears to be signal strength in dBm. |
| 128 access_point_data.radio_signal_strength = access_point_info->signal; | 129 access_point_data.radio_signal_strength = access_point_info->signal; |
| 129 access_point_data.channel = access_point_info->channel; | 130 access_point_data.channel = access_point_info->channel; |
| 130 // WirelessNetworkInfo::noise appears to be noise floor in dBm. | 131 // WirelessNetworkInfo::noise appears to be noise floor in dBm. |
| 131 access_point_data.signal_to_noise = access_point_info->signal - | 132 access_point_data.signal_to_noise = access_point_info->signal - |
| 132 access_point_info->noise; | 133 access_point_info->noise; |
| 133 if (!UTF8ToUTF16(reinterpret_cast<const char*>(access_point_info->name), | 134 if (!UTF8ToUTF16(reinterpret_cast<const char*>(access_point_info->name), |
| 134 access_point_info->nameLen, | 135 access_point_info->nameLen, |
| 135 &access_point_data.ssid)) { | 136 &access_point_data.ssid)) { |
| 136 access_point_data.ssid.clear(); | 137 access_point_data.ssid.clear(); |
| 137 } | 138 } |
| 138 | |
| 139 DLOG(INFO) << " AP " << i | |
| 140 << " mac: " << access_point_data.mac_address | |
| 141 << " ssid: " << access_point_data.ssid; | |
| 142 data->insert(access_point_data); | 139 data->insert(access_point_data); |
| 143 } | 140 } |
| 144 return true; | 141 return true; |
| 145 } | 142 } |
| 146 } // namespace | 143 } // namespace |
| 147 | 144 |
| 148 // static | 145 // static |
| 149 template<> | 146 template<> |
| 150 WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() { | 147 WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() { |
| 151 return new OsxWifiDataProvider(); | 148 return new MacWifiDataProvider(); |
| 152 } | 149 } |
| 153 | 150 |
| 154 OsxWifiDataProvider::OsxWifiDataProvider() { | 151 MacWifiDataProvider::MacWifiDataProvider() { |
| 155 } | 152 } |
| 156 | 153 |
| 157 OsxWifiDataProvider::~OsxWifiDataProvider() { | 154 MacWifiDataProvider::~MacWifiDataProvider() { |
| 158 } | 155 } |
| 159 | 156 |
| 160 OsxWifiDataProvider::WlanApiInterface* OsxWifiDataProvider::NewWlanApi() { | 157 MacWifiDataProvider::WlanApiInterface* MacWifiDataProvider::NewWlanApi() { |
| 161 scoped_ptr<OsxWlanApi> wlan_api(new OsxWlanApi); | 158 // Try and find a API binding that works: first try the officially supported |
| 162 if (!wlan_api->Init()) { | 159 // CoreWLAN API, and if this fails (e.g. on OSX 10.5) fall back to the reverse |
| 163 DLOG(INFO) << "OsxWifiDataProvider : failed to initialize wlan api"; | 160 // engineered Apple80211 API. |
| 164 return NULL; | 161 MacWifiDataProvider::WlanApiInterface* core_wlan_api = NewCoreWlanApi(); |
| 165 } | 162 if (core_wlan_api) |
| 166 return wlan_api.release(); | 163 return core_wlan_api; |
| 164 |
| 165 scoped_ptr<Apple80211Api> wlan_api(new Apple80211Api); |
| 166 if (wlan_api->Init()) |
| 167 return wlan_api.release(); |
| 168 |
| 169 DLOG(INFO) << "MacWifiDataProvider : failed to initialize any wlan api"; |
| 170 return NULL; |
| 167 } | 171 } |
| 168 | 172 |
| 169 PollingPolicyInterface* OsxWifiDataProvider::NewPollingPolicy() { | 173 PollingPolicyInterface* MacWifiDataProvider::NewPollingPolicy() { |
| 170 return new GenericPollingPolicy<kDefaultPollingInterval, | 174 return new GenericPollingPolicy<kDefaultPollingInterval, |
| 171 kNoChangePollingInterval, | 175 kNoChangePollingInterval, |
| 172 kTwoNoChangePollingInterval>; | 176 kTwoNoChangePollingInterval>; |
| 173 } | 177 } |
| OLD | NEW |