Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS 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 "shill/wimax.h" |
| 6 | |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 7 | #include <base/bind.h> |
Darin Petkov | d1cd797 | 2012-05-22 15:26:15 +0200 | [diff] [blame] | 8 | #include <base/string_util.h> |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 9 | #include <base/stringprintf.h> |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 10 | |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 11 | #include "shill/key_value_store.h" |
Christopher Wiley | b691efd | 2012-08-09 13:51:51 -0700 | [diff] [blame] | 12 | #include "shill/logging.h" |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 13 | #include "shill/manager.h" |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 14 | #include "shill/proxy_factory.h" |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 15 | #include "shill/wimax_device_proxy_interface.h" |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 16 | #include "shill/wimax_service.h" |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 17 | |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 18 | using base::Bind; |
Darin Petkov | d1cd797 | 2012-05-22 15:26:15 +0200 | [diff] [blame] | 19 | using std::set; |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 20 | using std::string; |
| 21 | |
| 22 | namespace shill { |
| 23 | |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 24 | const int WiMax::kDefaultConnectTimeoutSeconds = 60; |
| 25 | const int WiMax::kDefaultRPCTimeoutSeconds = 30; |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 26 | |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 27 | WiMax::WiMax(ControlInterface *control, |
| 28 | EventDispatcher *dispatcher, |
| 29 | Metrics *metrics, |
| 30 | Manager *manager, |
| 31 | const string &link_name, |
Ben Chan | 4e64d2d | 2012-05-16 00:02:25 -0700 | [diff] [blame] | 32 | const string &address, |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 33 | int interface_index, |
| 34 | const RpcIdentifier &path) |
Ben Chan | 4e64d2d | 2012-05-16 00:02:25 -0700 | [diff] [blame] | 35 | : Device(control, dispatcher, metrics, manager, link_name, address, |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 36 | interface_index, Technology::kWiMax), |
| 37 | path_(path), |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 38 | weak_ptr_factory_(this), |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 39 | scanning_(false), |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 40 | status_(wimax_manager::kDeviceStatusUninitialized), |
| 41 | proxy_factory_(ProxyFactory::GetInstance()), |
| 42 | connect_timeout_seconds_(kDefaultConnectTimeoutSeconds) { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 43 | LOG(INFO) << "WiMAX device created: " << link_name << " @ " << path; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 44 | PropertyStore *store = mutable_store(); |
| 45 | store->RegisterConstBool(flimflam::kScanningProperty, &scanning_); |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 46 | } |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 47 | |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 48 | WiMax::~WiMax() { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 49 | LOG(INFO) << "WiMAX device destroyed: " << link_name(); |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 50 | } |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 51 | |
| 52 | void WiMax::Start(Error *error, const EnabledStateChangedCallback &callback) { |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 53 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 54 | scanning_ = false; |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 55 | proxy_.reset(proxy_factory_->CreateWiMaxDeviceProxy(path_)); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 56 | proxy_->set_networks_changed_callback( |
| 57 | Bind(&WiMax::OnNetworksChanged, Unretained(this))); |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 58 | proxy_->set_status_changed_callback( |
| 59 | Bind(&WiMax::OnStatusChanged, Unretained(this))); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 60 | proxy_->Enable( |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 61 | error, Bind(&WiMax::OnEnableComplete, this, callback), |
| 62 | kDefaultRPCTimeoutSeconds * 1000); |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | void WiMax::Stop(Error *error, const EnabledStateChangedCallback &callback) { |
Darin Petkov | b72b62e | 2012-05-15 16:55:36 +0200 | [diff] [blame] | 66 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 67 | StopConnectTimeout(); |
| 68 | if (pending_service_) { |
| 69 | pending_service_->SetState(Service::kStateIdle); |
| 70 | pending_service_ = NULL; |
| 71 | } |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 72 | if (selected_service()) { |
| 73 | Error error; |
| 74 | DisconnectFrom(selected_service(), &error); |
| 75 | } |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 76 | scanning_ = false; |
Darin Petkov | d1cd797 | 2012-05-22 15:26:15 +0200 | [diff] [blame] | 77 | networks_.clear(); |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 78 | manager()->wimax_provider()->OnNetworksChanged(); |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 79 | if (proxy_.get()) { |
| 80 | proxy_->Disable( |
| 81 | error, Bind(&WiMax::OnDisableComplete, this, callback), |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 82 | kDefaultRPCTimeoutSeconds * 1000); |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 83 | } else { |
| 84 | OnDisableComplete(callback, Error()); |
| 85 | } |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 86 | } |
| 87 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 88 | void WiMax::Scan(Error *error) { |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 89 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 90 | if (scanning_) { |
| 91 | Error::PopulateAndLog( |
| 92 | error, Error::kInProgress, "Scan already in progress."); |
| 93 | return; |
| 94 | } |
| 95 | scanning_ = true; |
| 96 | proxy_->ScanNetworks( |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 97 | error, Bind(&WiMax::OnScanNetworksComplete, this), |
| 98 | kDefaultRPCTimeoutSeconds * 1000); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 99 | if (error->IsFailure()) { |
| 100 | OnScanNetworksComplete(*error); |
| 101 | } |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 102 | } |
| 103 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 104 | void WiMax::ConnectTo(const WiMaxServiceRefPtr &service, Error *error) { |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 105 | SLOG(WiMax, 2) << __func__ << "(" << service->GetStorageIdentifier() << ")"; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 106 | if (pending_service_) { |
| 107 | Error::PopulateAndLog( |
| 108 | error, Error::kInProgress, |
| 109 | base::StringPrintf( |
Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 110 | "Pending connect to service %s, ignoring connect request to %s.", |
| 111 | pending_service_->unique_name().c_str(), |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 112 | service->GetStorageIdentifier().c_str())); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 113 | return; |
| 114 | } |
| 115 | service->SetState(Service::kStateAssociating); |
| 116 | pending_service_ = service; |
Ben Chan | 4e5c131 | 2012-05-18 18:45:38 -0700 | [diff] [blame] | 117 | |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 118 | // We use the RPC device status to determine the outcome of the connect |
| 119 | // operation by listening for status updates in OnStatusChanged. A transition |
| 120 | // to Connected means success. A transition to Connecting and then to a status |
| 121 | // different than Connected means failure. Also, schedule a connect timeout to |
| 122 | // guard against the RPC device never transitioning to a Connecting or a |
| 123 | // Connected state. |
| 124 | status_ = wimax_manager::kDeviceStatusUninitialized; |
| 125 | StartConnectTimeout(); |
| 126 | |
Darin Petkov | 25665aa | 2012-05-21 14:08:12 +0200 | [diff] [blame] | 127 | KeyValueStore parameters; |
Ben Chan | 4e5c131 | 2012-05-18 18:45:38 -0700 | [diff] [blame] | 128 | service->GetConnectParameters(¶meters); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 129 | proxy_->Connect( |
Ben Chan | 4e5c131 | 2012-05-18 18:45:38 -0700 | [diff] [blame] | 130 | service->GetNetworkObjectPath(), parameters, |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 131 | error, Bind(&WiMax::OnConnectComplete, this), |
| 132 | kDefaultRPCTimeoutSeconds * 1000); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 133 | if (error->IsFailure()) { |
| 134 | OnConnectComplete(*error); |
| 135 | } |
| 136 | } |
| 137 | |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 138 | void WiMax::DisconnectFrom(const ServiceRefPtr &service, Error *error) { |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 139 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 140 | if (pending_service_) { |
| 141 | Error::PopulateAndLog( |
| 142 | error, Error::kInProgress, |
| 143 | base::StringPrintf( |
Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 144 | "Pending connect to service %s, " |
| 145 | "ignoring disconnect request from %s.", |
| 146 | pending_service_->unique_name().c_str(), |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 147 | service->GetStorageIdentifier().c_str())); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 148 | return; |
| 149 | } |
| 150 | if (selected_service() && service != selected_service()) { |
| 151 | Error::PopulateAndLog( |
| 152 | error, Error::kNotConnected, |
| 153 | base::StringPrintf( |
Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 154 | "Current service is %s, ignoring disconnect request from %s.", |
| 155 | selected_service()->unique_name().c_str(), |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 156 | service->GetStorageIdentifier().c_str())); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 157 | return; |
| 158 | } |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 159 | DropConnection(); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 160 | proxy_->Disconnect( |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 161 | error, Bind(&WiMax::OnDisconnectComplete, this), |
| 162 | kDefaultRPCTimeoutSeconds * 1000); |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 163 | if (error->IsFailure()) { |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 164 | OnDisconnectComplete(*error); |
| 165 | } |
| 166 | } |
| 167 | |
Darin Petkov | 6b9b2e1 | 2012-07-10 15:51:42 +0200 | [diff] [blame] | 168 | bool WiMax::IsIdle() const { |
| 169 | return !pending_service_ && !selected_service(); |
| 170 | } |
| 171 | |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 172 | void WiMax::OnServiceStopped(const WiMaxServiceRefPtr &service) { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 173 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 174 | if (service == selected_service()) { |
| 175 | DropConnection(); |
| 176 | } |
Darin Petkov | c1e5273 | 2012-05-25 15:23:45 +0200 | [diff] [blame] | 177 | if (service == pending_service_) { |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 178 | pending_service_ = NULL; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 179 | } |
| 180 | } |
| 181 | |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 182 | void WiMax::OnDeviceVanished() { |
| 183 | LOG(INFO) << "WiMAX device vanished: " << link_name(); |
| 184 | proxy_.reset(); |
| 185 | DropService(Service::kStateIdle); |
| 186 | // Disable the device. This will also clear any relevant properties such as |
| 187 | // the live network set. |
| 188 | SetEnabled(false); |
| 189 | } |
| 190 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 191 | void WiMax::OnScanNetworksComplete(const Error &/*error*/) { |
| 192 | SLOG(WiMax, 2) << __func__; |
| 193 | scanning_ = false; |
| 194 | // The networks are updated when the NetworksChanged signal is received. |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | void WiMax::OnConnectComplete(const Error &error) { |
| 198 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 199 | if (error.IsSuccess()) { |
| 200 | // Nothing to do -- the connection process is resumed on the StatusChanged |
| 201 | // signal. |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 202 | return; |
| 203 | } |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 204 | DropService(Service::kStateFailure); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 205 | } |
| 206 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 207 | void WiMax::OnDisconnectComplete(const Error &/*error*/) { |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 208 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | void WiMax::OnEnableComplete(const EnabledStateChangedCallback &callback, |
| 212 | const Error &error) { |
| 213 | SLOG(WiMax, 2) << __func__; |
| 214 | if (error.IsFailure()) { |
| 215 | proxy_.reset(); |
| 216 | } else { |
Darin Petkov | 59f2d69 | 2012-06-07 15:57:46 +0200 | [diff] [blame] | 217 | LOG(INFO) << "WiMAX device " << link_name() << " enabled."; |
| 218 | // Updates the live networks based on the current WiMaxManager.Device |
| 219 | // networks. The RPC device will signal when the network set changes. |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 220 | Error e; |
Darin Petkov | 59f2d69 | 2012-06-07 15:57:46 +0200 | [diff] [blame] | 221 | OnNetworksChanged(proxy_->Networks(&e)); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 222 | } |
| 223 | callback.Run(error); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 224 | } |
| 225 | |
| 226 | void WiMax::OnDisableComplete(const EnabledStateChangedCallback &callback, |
| 227 | const Error &error) { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 228 | LOG(INFO) << "WiMAX device " << link_name() << " disabled."; |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 229 | proxy_.reset(); |
Darin Petkov | 912f0de | 2012-05-16 14:12:14 +0200 | [diff] [blame] | 230 | callback.Run(error); |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 231 | } |
| 232 | |
Darin Petkov | 9893d9c | 2012-05-17 15:27:31 -0700 | [diff] [blame] | 233 | void WiMax::OnNetworksChanged(const RpcIdentifiers &networks) { |
| 234 | SLOG(WiMax, 2) << __func__; |
Darin Petkov | c63dcf0 | 2012-05-24 11:51:43 +0200 | [diff] [blame] | 235 | networks_.clear(); |
| 236 | networks_.insert(networks.begin(), networks.end()); |
| 237 | manager()->wimax_provider()->OnNetworksChanged(); |
Darin Petkov | d1cd797 | 2012-05-22 15:26:15 +0200 | [diff] [blame] | 238 | } |
| 239 | |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 240 | void WiMax::OnStatusChanged(wimax_manager::DeviceStatus status) { |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 241 | SLOG(WiMax, 2) << "WiMAX device " << link_name() << " status: " << status; |
| 242 | wimax_manager::DeviceStatus old_status = status_; |
| 243 | status_ = status; |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 244 | switch (status) { |
| 245 | case wimax_manager::kDeviceStatusConnected: |
| 246 | if (!pending_service_) { |
| 247 | LOG(WARNING) << "Unexpected status change; ignored."; |
| 248 | return; |
| 249 | } |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 250 | // Stops the connect timeout -- the DHCP provider has a separate timeout. |
| 251 | StopConnectTimeout(); |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 252 | if (AcquireIPConfig()) { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 253 | LOG(INFO) << "WiMAX device " << link_name() << " connected to " |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 254 | << pending_service_->GetStorageIdentifier(); |
| 255 | SelectService(pending_service_); |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 256 | pending_service_ = NULL; |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 257 | SetServiceState(Service::kStateConfiguring); |
| 258 | } else { |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 259 | DropService(Service::kStateFailure); |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 260 | } |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 261 | break; |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 262 | case wimax_manager::kDeviceStatusConnecting: |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 263 | LOG(INFO) << "WiMAX device " << link_name() << " connecting..."; |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 264 | // Nothing to do. |
| 265 | break; |
| 266 | default: |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 267 | // We may receive a queued up status update (e.g., to Scanning) before |
| 268 | // receiving the status update to Connecting, so be careful to fail the |
| 269 | // service only on the right status transition. |
| 270 | if (old_status == wimax_manager::kDeviceStatusConnecting || |
| 271 | old_status == wimax_manager::kDeviceStatusConnected) { |
| 272 | LOG(INFO) << "WiMAX device " << link_name() |
| 273 | << " status: " << old_status << " -> " << status; |
| 274 | if (pending_service_) { |
| 275 | // For now, assume that failing to connect to a live network indicates |
| 276 | // bad user credentials. Reset the password to trigger the |
| 277 | // user/password dialog in the UI. |
| 278 | pending_service_->ClearPassphrase(); |
| 279 | } |
| 280 | DropService(Service::kStateFailure); |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 281 | } |
Darin Petkov | 8ea0eaf | 2012-05-29 11:21:33 +0200 | [diff] [blame] | 282 | break; |
| 283 | } |
| 284 | } |
| 285 | |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 286 | void WiMax::DropService(Service::ConnectState state) { |
| 287 | SLOG(WiMax, 2) << __func__ |
| 288 | << "(" << Service::ConnectStateToString(state) << ")"; |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 289 | StopConnectTimeout(); |
Darin Petkov | b96a451 | 2012-06-04 11:02:49 +0200 | [diff] [blame] | 290 | if (pending_service_) { |
| 291 | LOG(WARNING) << "Unable to initiate connection to: " |
| 292 | << pending_service_->GetStorageIdentifier(); |
| 293 | pending_service_->SetState(state); |
| 294 | pending_service_ = NULL; |
| 295 | } |
| 296 | if (selected_service()) { |
| 297 | LOG(WARNING) << "Service disconnected: " |
| 298 | << selected_service()->GetStorageIdentifier(); |
| 299 | selected_service()->SetState(state); |
| 300 | DropConnection(); |
| 301 | } |
| 302 | } |
| 303 | |
Darin Petkov | 3a4100c | 2012-06-14 11:36:59 +0200 | [diff] [blame] | 304 | void WiMax::StartConnectTimeout() { |
| 305 | SLOG(WiMax, 2) << __func__; |
| 306 | if (IsConnectTimeoutStarted()) { |
| 307 | return; |
| 308 | } |
| 309 | connect_timeout_callback_.Reset( |
| 310 | Bind(&WiMax::OnConnectTimeout, weak_ptr_factory_.GetWeakPtr())); |
| 311 | dispatcher()->PostDelayedTask( |
| 312 | connect_timeout_callback_.callback(), connect_timeout_seconds_ * 1000); |
| 313 | } |
| 314 | |
| 315 | void WiMax::StopConnectTimeout() { |
| 316 | SLOG(WiMax, 2) << __func__; |
| 317 | connect_timeout_callback_.Cancel(); |
| 318 | } |
| 319 | |
| 320 | bool WiMax::IsConnectTimeoutStarted() const { |
| 321 | return !connect_timeout_callback_.IsCancelled(); |
| 322 | } |
| 323 | |
| 324 | void WiMax::OnConnectTimeout() { |
| 325 | LOG(ERROR) << "WiMAX device " << link_name() << ": connect timeout."; |
| 326 | StopConnectTimeout(); |
| 327 | DropService(Service::kStateFailure); |
| 328 | } |
| 329 | |
Ben Chan | 99c8a4d | 2012-05-01 08:11:53 -0700 | [diff] [blame] | 330 | } // namespace shill |