OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 #include "chromeos/components/tether/tether_connector.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "chromeos/components/tether/active_host.h" |
| 9 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" |
| 10 #include "chromeos/components/tether/tether_host_fetcher.h" |
| 11 #include "chromeos/components/tether/wifi_hotspot_connector.h" |
| 12 #include "chromeos/network/network_handler.h" |
| 13 #include "chromeos/network/network_state_handler.h" |
| 14 #include "components/proximity_auth/logging/logging.h" |
| 15 |
| 16 namespace chromeos { |
| 17 |
| 18 namespace tether { |
| 19 |
| 20 TetherConnector::TetherConnector( |
| 21 WifiHotspotConnector* wifi_hotspot_connector, |
| 22 ActiveHost* active_host, |
| 23 TetherHostFetcher* tether_host_fetcher, |
| 24 BleConnectionManager* connection_manager, |
| 25 HostScanDevicePrioritizer* host_scan_device_prioritizer, |
| 26 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map) |
| 27 : TetherConnector(NetworkConnect::Get(), |
| 28 NetworkHandler::Get()->network_state_handler(), |
| 29 wifi_hotspot_connector, |
| 30 active_host, |
| 31 tether_host_fetcher, |
| 32 connection_manager, |
| 33 host_scan_device_prioritizer, |
| 34 device_id_tether_network_guid_map) {} |
| 35 |
| 36 TetherConnector::TetherConnector( |
| 37 NetworkConnect* network_connect, |
| 38 NetworkStateHandler* network_state_handler, |
| 39 WifiHotspotConnector* wifi_hotspot_connector, |
| 40 ActiveHost* active_host, |
| 41 TetherHostFetcher* tether_host_fetcher, |
| 42 BleConnectionManager* connection_manager, |
| 43 HostScanDevicePrioritizer* host_scan_device_prioritizer, |
| 44 DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map) |
| 45 : network_connect_(network_connect), |
| 46 network_state_handler_(network_state_handler), |
| 47 wifi_hotspot_connector_(wifi_hotspot_connector), |
| 48 active_host_(active_host), |
| 49 tether_host_fetcher_(tether_host_fetcher), |
| 50 connection_manager_(connection_manager), |
| 51 host_scan_device_prioritizer_(host_scan_device_prioritizer), |
| 52 device_id_tether_network_guid_map_(device_id_tether_network_guid_map), |
| 53 weak_ptr_factory_(this) { |
| 54 network_connect_->SetTetherDelegate(this); |
| 55 } |
| 56 |
| 57 TetherConnector::~TetherConnector() { |
| 58 network_connect_->SetTetherDelegate(nullptr); |
| 59 if (connect_tethering_operation_) { |
| 60 connect_tethering_operation_->RemoveObserver(this); |
| 61 } |
| 62 } |
| 63 |
| 64 void TetherConnector::ConnectToNetwork(const std::string& guid) { |
| 65 PA_LOG(INFO) << "Attempting to connect to network with GUID " << guid << "."; |
| 66 |
| 67 std::string device_id = |
| 68 device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(guid); |
| 69 |
| 70 if (device_id_pending_connection_ == device_id) { |
| 71 PA_LOG(INFO) << "Connection attempt requested for network with GUID " |
| 72 << guid << ", but a connection attempt is already in " |
| 73 << "progress. Continuing with the existing attempt."; |
| 74 return; |
| 75 } |
| 76 |
| 77 if (connect_tethering_operation_) { |
| 78 DCHECK(!device_id_pending_connection_.empty()); |
| 79 |
| 80 PA_LOG(INFO) << "A connection attempt was already in progress to device " |
| 81 << "with ID " << device_id_pending_connection_ << ". " |
| 82 << "Canceling that connection attempt before continuing."; |
| 83 |
| 84 // If a connection to a *different* device is pending, stop the connection |
| 85 // attempt. |
| 86 connect_tethering_operation_->RemoveObserver(this); |
| 87 connect_tethering_operation_.reset(); |
| 88 } |
| 89 |
| 90 device_id_pending_connection_ = device_id; |
| 91 |
| 92 tether_host_fetcher_->FetchTetherHost( |
| 93 device_id_pending_connection_, |
| 94 base::Bind(&TetherConnector::OnTetherHostToConnectFetched, |
| 95 weak_ptr_factory_.GetWeakPtr(), |
| 96 device_id_pending_connection_)); |
| 97 } |
| 98 |
| 99 void TetherConnector::OnSuccessfulConnectTetheringResponse( |
| 100 const cryptauth::RemoteDevice& remote_device, |
| 101 const std::string& ssid, |
| 102 const std::string& password) { |
| 103 if (device_id_pending_connection_ != remote_device.GetDeviceId()) { |
| 104 // If the success was part of a previous attempt for a different device, |
| 105 // ignore it. |
| 106 PA_LOG(INFO) << "Received successful ConnectTetheringResponse from " |
| 107 << "device with ID " |
| 108 << remote_device.GetTruncatedDeviceIdForLogs() |
| 109 << ", but a connection to another device was started while " |
| 110 << "the response was being received."; |
| 111 return; |
| 112 } |
| 113 |
| 114 PA_LOG(INFO) << "Received successful ConnectTetheringResponse from device " |
| 115 << "with ID " << remote_device.GetTruncatedDeviceIdForLogs() |
| 116 << ". SSID: \"" << ssid << "\", Password: \"" << password |
| 117 << "\""; |
| 118 |
| 119 // Make a copy of the device ID, SSID, and password to pass below before |
| 120 // destroying |connect_tethering_operation_|. |
| 121 std::string remote_device_id = remote_device.GetDeviceId(); |
| 122 std::string ssid_copy = ssid; |
| 123 std::string password_copy = password; |
| 124 |
| 125 connect_tethering_operation_->RemoveObserver(this); |
| 126 connect_tethering_operation_.reset(); |
| 127 |
| 128 wifi_hotspot_connector_->ConnectToWifiHotspot( |
| 129 ssid_copy, password_copy, |
| 130 base::Bind(&TetherConnector::OnWifiConnection, |
| 131 weak_ptr_factory_.GetWeakPtr(), remote_device_id)); |
| 132 } |
| 133 |
| 134 void TetherConnector::OnConnectTetheringFailure( |
| 135 const cryptauth::RemoteDevice& remote_device, |
| 136 ConnectTetheringResponse_ResponseCode error_code) { |
| 137 if (device_id_pending_connection_ != remote_device.GetDeviceId()) { |
| 138 // If the failure was part of a previous attempt for a different device, |
| 139 // ignore it. |
| 140 PA_LOG(INFO) << "Received failed ConnectTetheringResponse from device with " |
| 141 << "ID " << remote_device.GetTruncatedDeviceIdForLogs() |
| 142 << ", but a connection to another device has already started."; |
| 143 return; |
| 144 } |
| 145 |
| 146 PA_LOG(WARNING) << "Connection to device with ID " |
| 147 << remote_device.GetTruncatedDeviceIdForLogs() |
| 148 << " could not connect. Error code: " << error_code; |
| 149 |
| 150 connect_tethering_operation_->RemoveObserver(this); |
| 151 connect_tethering_operation_.reset(); |
| 152 SetDisconnected(); |
| 153 } |
| 154 |
| 155 void TetherConnector::OnTetherHostToConnectFetched( |
| 156 const std::string& device_id, |
| 157 std::unique_ptr<cryptauth::RemoteDevice> tether_host_to_connect) { |
| 158 if (!tether_host_to_connect) { |
| 159 PA_LOG(ERROR) << "Could not fetch tether host with device ID " |
| 160 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
| 161 << ". Cannot connect."; |
| 162 return; |
| 163 } |
| 164 |
| 165 if (device_id_pending_connection_ != tether_host_to_connect->GetDeviceId()) { |
| 166 PA_LOG(INFO) << "Device to connect to has changed while device with ID " |
| 167 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
| 168 << " was being fetched."; |
| 169 return; |
| 170 } |
| 171 |
| 172 active_host_->SetActiveHostConnecting( |
| 173 device_id_pending_connection_, |
| 174 device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( |
| 175 device_id_pending_connection_)); |
| 176 |
| 177 connect_tethering_operation_ = |
| 178 ConnectTetheringOperation::Factory::NewInstance( |
| 179 *tether_host_to_connect, connection_manager_, |
| 180 host_scan_device_prioritizer_); |
| 181 connect_tethering_operation_->AddObserver(this); |
| 182 connect_tethering_operation_->Initialize(); |
| 183 } |
| 184 |
| 185 void TetherConnector::SetDisconnected() { |
| 186 device_id_pending_connection_ = ""; |
| 187 active_host_->SetActiveHostDisconnected(); |
| 188 } |
| 189 |
| 190 void TetherConnector::SetConnected(const std::string& device_id, |
| 191 const std::string& wifi_network_guid) { |
| 192 device_id_pending_connection_ = ""; |
| 193 active_host_->SetActiveHostConnected( |
| 194 device_id, |
| 195 device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( |
| 196 device_id), |
| 197 wifi_network_guid); |
| 198 } |
| 199 |
| 200 void TetherConnector::OnWifiConnection(const std::string& device_id, |
| 201 const std::string& wifi_network_guid) { |
| 202 if (device_id != device_id_pending_connection_) { |
| 203 // If the device ID does not match the ID of the device pending connection, |
| 204 // this is a stale attempt. |
| 205 PA_LOG(ERROR) << "Cannot connect to device with ID " |
| 206 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
| 207 << " because another connection attempt has been started to " |
| 208 << "a different device."; |
| 209 |
| 210 // TODO(khorimoto): Disconnect from the network. |
| 211 return; |
| 212 } |
| 213 |
| 214 if (wifi_network_guid.empty()) { |
| 215 // If the Wi-Fi network ID is empty, then the connection did not succeed. |
| 216 PA_LOG(ERROR) << "Failed to connect to the hotspot belonging to the device " |
| 217 << "with ID " |
| 218 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
| 219 << "."; |
| 220 |
| 221 SetDisconnected(); |
| 222 return; |
| 223 } |
| 224 |
| 225 bool successful_association = |
| 226 network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork( |
| 227 device_id, wifi_network_guid); |
| 228 if (successful_association) { |
| 229 PA_LOG(INFO) << "Successfully connected to host device with ID " |
| 230 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) |
| 231 << ". Tether network ID: \"" << device_id |
| 232 << "\", Wi-Fi network ID: \"" << wifi_network_guid << "\""; |
| 233 } else { |
| 234 PA_LOG(WARNING) << "Successfully connected to host device with ID " |
| 235 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( |
| 236 device_id) |
| 237 << ", but failed to associate tether network with ID \"" |
| 238 << device_id << "\" to Wi-Fi network with ID \"" |
| 239 << wifi_network_guid << "\"."; |
| 240 } |
| 241 |
| 242 SetConnected(device_id, wifi_network_guid); |
| 243 } |
| 244 |
| 245 } // namespace tether |
| 246 |
| 247 } // namespace chromeos |
OLD | NEW |