blob: 37fb889a25af0b667c9ffe71b7bae6f805e53b76 [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewart75897df2011-04-27 09:05:53 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masoneb2e326b2011-07-12 13:28:51 -07005#include "shill/service.h"
6
Paul Stewart75897df2011-04-27 09:05:53 -07007#include <time.h>
Paul Stewart75897df2011-04-27 09:05:53 -07008#include <stdio.h>
Chris Masoneee929b72011-05-10 10:02:18 -07009
Chris Masone8fe2c7e2011-06-09 15:51:19 -070010#include <map>
Paul Stewart75897df2011-04-27 09:05:53 -070011#include <string>
Chris Masone8fe2c7e2011-06-09 15:51:19 -070012#include <vector>
Paul Stewart75897df2011-04-27 09:05:53 -070013
Chris Masoneee929b72011-05-10 10:02:18 -070014#include <base/logging.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <base/memory/scoped_ptr.h>
mukesh agrawal51a7e932011-07-27 16:18:26 -070016#include <base/string_number_conversions.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <chromeos/dbus/service_constants.h>
Chris Masoneee929b72011-05-10 10:02:18 -070018
Paul Stewartbe5f5b32011-12-07 17:11:11 -080019#include "shill/connection.h"
Paul Stewart75897df2011-04-27 09:05:53 -070020#include "shill/control_interface.h"
Chris Masone8fe2c7e2011-06-09 15:51:19 -070021#include "shill/error.h"
Paul Stewartbe5f5b32011-12-07 17:11:11 -080022#include "shill/http_proxy.h"
Chris Masone6791a432011-07-12 13:23:19 -070023#include "shill/manager.h"
Thieu Le48e6d6d2011-12-06 00:40:27 +000024#include "shill/metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070025#include "shill/profile.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070026#include "shill/property_accessor.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070027#include "shill/refptr_types.h"
Chris Masoned7732e42011-05-20 11:08:56 -070028#include "shill/service_dbus_adaptor.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070029#include "shill/store_interface.h"
Paul Stewart75897df2011-04-27 09:05:53 -070030
Chris Masone8fe2c7e2011-06-09 15:51:19 -070031using std::map;
Paul Stewart75897df2011-04-27 09:05:53 -070032using std::string;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070033using std::vector;
Paul Stewart75897df2011-04-27 09:05:53 -070034
35namespace shill {
Darin Petkovba40dd32011-07-11 20:06:39 -070036
37const char Service::kCheckPortalAuto[] = "auto";
38const char Service::kCheckPortalFalse[] = "false";
39const char Service::kCheckPortalTrue[] = "true";
40
Paul Stewartac4ac002011-08-26 12:04:26 -070041const int Service::kPriorityNone = 0;
42
Darin Petkovba40dd32011-07-11 20:06:39 -070043const char Service::kStorageAutoConnect[] = "AutoConnect";
44const char Service::kStorageCheckPortal[] = "CheckPortal";
45const char Service::kStorageEapAnonymousIdentity[] = "EAP.AnonymousIdentity";
46const char Service::kStorageEapCACert[] = "EAP.CACert";
47const char Service::kStorageEapCACertID[] = "EAP.CACertID";
48const char Service::kStorageEapCertID[] = "EAP.CertID";
49const char Service::kStorageEapClientCert[] = "EAP.ClientCert";
50const char Service::kStorageEapEap[] = "EAP.EAP";
51const char Service::kStorageEapIdentity[] = "EAP.Identity";
52const char Service::kStorageEapInnerEap[] = "EAP.InnerEAP";
53const char Service::kStorageEapKeyID[] = "EAP.KeyID";
54const char Service::kStorageEapKeyManagement[] = "EAP.KeyMgmt";
55const char Service::kStorageEapPIN[] = "EAP.PIN";
56const char Service::kStorageEapPassword[] = "EAP.Password";
57const char Service::kStorageEapPrivateKey[] = "EAP.PrivateKey";
58const char Service::kStorageEapPrivateKeyPassword[] = "EAP.PrivateKeyPassword";
59const char Service::kStorageEapUseSystemCAs[] = "EAP.UseSystemCAs";
60const char Service::kStorageFavorite[] = "Favorite";
61const char Service::kStorageName[] = "Name";
62const char Service::kStoragePriority[] = "Priority";
63const char Service::kStorageProxyConfig[] = "ProxyConfig";
64const char Service::kStorageSaveCredentials[] = "SaveCredentials";
Paul Stewart2706aaf2011-12-14 16:44:04 -080065const char Service::kStorageType[] = "Type";
Paul Stewart987e71e2011-12-05 09:45:06 -080066const char Service::kStorageUIData[] = "UIData";
Darin Petkovba40dd32011-07-11 20:06:39 -070067
mukesh agrawal51a7e932011-07-27 16:18:26 -070068// static
69unsigned int Service::serial_number_ = 0;
70
Paul Stewart75897df2011-04-27 09:05:53 -070071Service::Service(ControlInterface *control_interface,
mukesh agrawalb54601c2011-06-07 17:39:22 -070072 EventDispatcher *dispatcher,
mukesh agrawal7a4e4002011-09-06 11:26:05 -070073 Manager *manager,
Gaurav Shah435de2c2011-11-17 19:01:07 -080074 Technology::Identifier technology)
Paul Stewart03dba0b2011-08-22 16:32:45 -070075 : state_(kStateUnknown),
76 failure_(kFailureUnknown),
77 auto_connect_(false),
Darin Petkovba40dd32011-07-11 20:06:39 -070078 check_portal_(kCheckPortalAuto),
Chris Masone3bd3c8c2011-06-13 08:20:26 -070079 connectable_(false),
80 favorite_(false),
Darin Petkovba40dd32011-07-11 20:06:39 -070081 priority_(kPriorityNone),
Paul Stewart1ca3e852011-11-04 07:50:49 -070082 security_level_(0),
Paul Stewart22aa71b2011-09-16 12:15:11 -070083 strength_(0),
Darin Petkovba40dd32011-07-11 20:06:39 -070084 save_credentials_(true),
Gaurav Shah435de2c2011-11-17 19:01:07 -080085 technology_(technology),
Chris Masone3bd3c8c2011-06-13 08:20:26 -070086 dispatcher_(dispatcher),
mukesh agrawald835b202011-10-07 15:26:47 -070087 unique_name_(base::UintToString(serial_number_++)),
88 friendly_name_(unique_name_),
Chris Masonea82b7112011-05-25 15:16:29 -070089 available_(false),
90 configured_(false),
Chris Masonea82b7112011-05-25 15:16:29 -070091 configuration_(NULL),
Chris Masone6791a432011-07-12 13:23:19 -070092 adaptor_(control_interface->CreateServiceAdaptor(this)),
Thieu Le48e6d6d2011-12-06 00:40:27 +000093 manager_(manager),
94 metrics_(Metrics::GetInstance()) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -070095
Chris Masone27c4aa52011-07-02 13:10:14 -070096 store_.RegisterBool(flimflam::kAutoConnectProperty, &auto_connect_);
Chris Masone4d42df82011-07-02 17:09:39 -070097
98 // flimflam::kActivationStateProperty: Registered in CellularService
99 // flimflam::kCellularApnProperty: Registered in CellularService
100 // flimflam::kCellularLastGoodApnProperty: Registered in CellularService
101 // flimflam::kNetworkTechnologyProperty: Registered in CellularService
Darin Petkov3335b372011-08-22 11:05:32 -0700102 // flimflam::kOperatorNameProperty: DEPRECATED
103 // flimflam::kOperatorCodeProperty: DEPRECATED
Chris Masone4d42df82011-07-02 17:09:39 -0700104 // flimflam::kRoamingStateProperty: Registered in CellularService
Darin Petkov3335b372011-08-22 11:05:32 -0700105 // flimflam::kServingOperatorProperty: Registered in CellularService
Chris Masone4d42df82011-07-02 17:09:39 -0700106 // flimflam::kPaymentURLProperty: Registered in CellularService
107
Chris Masone27c4aa52011-07-02 13:10:14 -0700108 store_.RegisterString(flimflam::kCheckPortalProperty, &check_portal_);
109 store_.RegisterConstBool(flimflam::kConnectableProperty, &connectable_);
110 HelpRegisterDerivedString(flimflam::kDeviceProperty,
111 &Service::GetDeviceRpcId,
112 NULL);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700113
Chris Masoneb2e326b2011-07-12 13:28:51 -0700114 store_.RegisterString(flimflam::kEapIdentityProperty, &eap_.identity);
115 store_.RegisterString(flimflam::kEAPEAPProperty, &eap_.eap);
116 store_.RegisterString(flimflam::kEapPhase2AuthProperty, &eap_.inner_eap);
Chris Masone27c4aa52011-07-02 13:10:14 -0700117 store_.RegisterString(flimflam::kEapAnonymousIdentityProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700118 &eap_.anonymous_identity);
119 store_.RegisterString(flimflam::kEAPClientCertProperty, &eap_.client_cert);
120 store_.RegisterString(flimflam::kEAPCertIDProperty, &eap_.cert_id);
121 store_.RegisterString(flimflam::kEapPrivateKeyProperty, &eap_.private_key);
Chris Masone27c4aa52011-07-02 13:10:14 -0700122 store_.RegisterString(flimflam::kEapPrivateKeyPasswordProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700123 &eap_.private_key_password);
124 store_.RegisterString(flimflam::kEAPKeyIDProperty, &eap_.key_id);
125 store_.RegisterString(flimflam::kEapCaCertProperty, &eap_.ca_cert);
126 store_.RegisterString(flimflam::kEapCaCertIDProperty, &eap_.ca_cert_id);
127 store_.RegisterString(flimflam::kEAPPINProperty, &eap_.pin);
128 store_.RegisterString(flimflam::kEapPasswordProperty, &eap_.password);
129 store_.RegisterString(flimflam::kEapKeyMgmtProperty, &eap_.key_management);
130 store_.RegisterBool(flimflam::kEapUseSystemCAsProperty, &eap_.use_system_cas);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700131
Chris Masone27c4aa52011-07-02 13:10:14 -0700132 store_.RegisterConstString(flimflam::kErrorProperty, &error_);
133 store_.RegisterConstBool(flimflam::kFavoriteProperty, &favorite_);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800134 HelpRegisterDerivedUint16(shill::kHTTPProxyPortProperty,
135 &Service::GetHTTPProxyPort,
136 NULL);
Chris Masone27c4aa52011-07-02 13:10:14 -0700137 HelpRegisterDerivedBool(flimflam::kIsActiveProperty,
Chris Masoneb2e326b2011-07-12 13:28:51 -0700138 &Service::IsActive,
139 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700140 // flimflam::kModeProperty: Registered in WiFiService
mukesh agrawald835b202011-10-07 15:26:47 -0700141 store_.RegisterConstString(flimflam::kNameProperty, &friendly_name_);
Chris Masone4d42df82011-07-02 17:09:39 -0700142 // flimflam::kPassphraseProperty: Registered in WiFiService
143 // flimflam::kPassphraseRequiredProperty: Registered in WiFiService
Chris Masone27c4aa52011-07-02 13:10:14 -0700144 store_.RegisterInt32(flimflam::kPriorityProperty, &priority_);
145 HelpRegisterDerivedString(flimflam::kProfileProperty,
146 &Service::GetProfileRpcId,
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800147 &Service::SetProfileRpcId);
Chris Masone4d42df82011-07-02 17:09:39 -0700148 store_.RegisterString(flimflam::kProxyConfigProperty, &proxy_config_);
Chris Masone43b48a12011-07-01 13:37:07 -0700149 // TODO(cmasone): Create VPN Service with this property
Chris Masone27c4aa52011-07-02 13:10:14 -0700150 // store_.RegisterConstStringmap(flimflam::kProviderProperty, &provider_);
Chris Masone4d42df82011-07-02 17:09:39 -0700151
Chris Masoneb2e326b2011-07-12 13:28:51 -0700152 store_.RegisterBool(flimflam::kSaveCredentialsProperty, &save_credentials_);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800153 HelpRegisterDerivedString(flimflam::kTypeProperty,
154 &Service::GetTechnologyString,
155 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700156 // flimflam::kSecurityProperty: Registered in WiFiService
Chris Masone27c4aa52011-07-02 13:10:14 -0700157 HelpRegisterDerivedString(flimflam::kStateProperty,
158 &Service::CalculateState,
159 NULL);
Chris Masone4d42df82011-07-02 17:09:39 -0700160 // flimflam::kSignalStrengthProperty: Registered in WiFi/CellularService
Paul Stewart987e71e2011-12-05 09:45:06 -0800161 store_.RegisterString(flimflam::kUIDataProperty, &ui_data_);
Chris Masone4d42df82011-07-02 17:09:39 -0700162 // flimflam::kWifiAuthMode: Registered in WiFiService
163 // flimflam::kWifiHiddenSsid: Registered in WiFiService
164 // flimflam::kWifiFrequency: Registered in WiFiService
165 // flimflam::kWifiPhyMode: Registered in WiFiService
166 // flimflam::kWifiHexSsid: Registered in WiFiService
Thieu Le48e6d6d2011-12-06 00:40:27 +0000167
168 metrics_->RegisterService(this);
169
Chris Masoneb07006b2011-05-14 16:10:04 -0700170 VLOG(2) << "Service initialized.";
Paul Stewart75897df2011-04-27 09:05:53 -0700171}
172
Thieu Le48e6d6d2011-12-06 00:40:27 +0000173Service::~Service() {
174 metrics_->DeregisterService(this);
175}
Paul Stewart75897df2011-04-27 09:05:53 -0700176
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000177void Service::AutoConnect() {
178 if (this->IsAutoConnectable()) {
179 Error error;
180 Connect(&error);
181 }
182}
183
Paul Stewarta41e38d2011-11-11 07:47:29 -0800184void Service::ActivateCellularModem(const string &/*carrier*/, Error *error) {
Darin Petkovb100ae72011-08-24 16:19:45 -0700185 const string kMessage = "Service doesn't support cellular modem activation.";
186 LOG(ERROR) << kMessage;
187 CHECK(error);
188 error->Populate(Error::kInvalidArguments, kMessage);
Darin Petkovc408e692011-08-17 13:47:15 -0700189}
190
mukesh agrawal1830fa12011-09-26 14:31:40 -0700191bool Service::TechnologyIs(const Technology::Identifier /*type*/) const {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700192 return false;
193}
194
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800195bool Service::IsActive(Error */*error*/) {
Paul Stewart03dba0b2011-08-22 16:32:45 -0700196 return state_ != kStateUnknown &&
197 state_ != kStateIdle &&
198 state_ != kStateFailure;
199}
200
201void Service::SetState(ConnectState state) {
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800202 LOG(INFO) << "In " << __func__ << "(): Service " << friendly_name_
203 << " state " << ConnectStateToString(state_) << " -> "
204 << ConnectStateToString(state);
mukesh agrawal7ec71312011-11-10 02:08:26 +0000205
Paul Stewart03dba0b2011-08-22 16:32:45 -0700206 if (state == state_) {
207 return;
208 }
209
210 state_ = state;
211 if (state != kStateFailure) {
212 failure_ = kFailureUnknown;
213 }
214 manager_->UpdateService(this);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000215 metrics_->NotifyServiceStateChanged(this, state);
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800216 Error error;
mukesh agrawalfa602f22011-11-29 02:00:46 +0000217 if (state == kStateConnected) {
218 // TODO(quiche): After we have portal detection in place, CalculateState
219 // should map kStateConnected to kStateReady. At that point, we should
220 // remove this. crosbug.com/23318.
221 adaptor_->EmitStringChanged(
222 flimflam::kStateProperty, flimflam::kStateReady);
223 }
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800224 adaptor_->EmitStringChanged(flimflam::kStateProperty, CalculateState(&error));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700225}
226
227void Service::SetFailure(ConnectFailure failure) {
228 failure_ = failure;
229 SetState(kStateFailure);
230}
231
Chris Masone6791a432011-07-12 13:23:19 -0700232string Service::GetRpcIdentifier() const {
Chris Masone3c3f6a12011-07-01 10:01:41 -0700233 return adaptor_->GetRpcIdentifier();
234}
235
Paul Stewartbba6a5b2011-11-02 18:45:59 -0700236bool Service::IsLoadableFrom(StoreInterface *storage) const {
237 return storage->ContainsGroup(GetStorageIdentifier());
238}
239
Chris Masone9d779932011-08-25 16:33:41 -0700240bool Service::Load(StoreInterface *storage) {
241 const string id = GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700242 if (!storage->ContainsGroup(id)) {
243 LOG(WARNING) << "Service is not available in the persistent store: " << id;
244 return false;
245 }
246 storage->GetBool(id, kStorageAutoConnect, &auto_connect_);
247 storage->GetString(id, kStorageCheckPortal, &check_portal_);
248 storage->GetBool(id, kStorageFavorite, &favorite_);
249 storage->GetInt(id, kStoragePriority, &priority_);
250 storage->GetString(id, kStorageProxyConfig, &proxy_config_);
251 storage->GetBool(id, kStorageSaveCredentials, &save_credentials_);
Paul Stewart987e71e2011-12-05 09:45:06 -0800252 storage->GetString(id, kStorageUIData, &ui_data_);
Chris Masone34af2182011-08-22 11:59:36 -0700253
254 LoadEapCredentials(storage, id);
255
256 // TODO(petkov): Load these:
257
Chris Masone34af2182011-08-22 11:59:36 -0700258 // "Failure"
259 // "Modified"
260 // "LastAttempt"
Chris Masone34af2182011-08-22 11:59:36 -0700261 // "APN"
262 // "LastGoodAPN"
263
Paul Stewarta41e38d2011-11-11 07:47:29 -0800264 favorite_ = true;
265
Chris Masone34af2182011-08-22 11:59:36 -0700266 return true;
Darin Petkovba40dd32011-07-11 20:06:39 -0700267}
268
Paul Stewarta41e38d2011-11-11 07:47:29 -0800269void Service::Unload() {
270 auto_connect_ = false;
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800271 check_portal_ = kCheckPortalAuto;
Paul Stewarta41e38d2011-11-11 07:47:29 -0800272 favorite_ = false;
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800273 priority_ = kPriorityNone;
274 proxy_config_ = "";
275 save_credentials_ = true;
276 ui_data_ = "";
277
278 UnloadEapCredentials();
Paul Stewarta41e38d2011-11-11 07:47:29 -0800279}
280
Chris Masone9d779932011-08-25 16:33:41 -0700281bool Service::Save(StoreInterface *storage) {
282 const string id = GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700283
Paul Stewart2706aaf2011-12-14 16:44:04 -0800284 storage->SetString(id, kStorageType, GetTechnologyString(NULL));
285
Chris Masone34af2182011-08-22 11:59:36 -0700286 // TODO(petkov): We could choose to simplify the saving code by removing most
287 // conditionals thus saving even default values.
288 if (favorite_) {
289 storage->SetBool(id, kStorageAutoConnect, auto_connect_);
290 }
291 if (check_portal_ == kCheckPortalAuto) {
292 storage->DeleteKey(id, kStorageCheckPortal);
293 } else {
294 storage->SetString(id, kStorageCheckPortal, check_portal_);
295 }
296 storage->SetBool(id, kStorageFavorite, favorite_);
mukesh agrawald835b202011-10-07 15:26:47 -0700297 storage->SetString(id, kStorageName, friendly_name_);
Chris Masone34af2182011-08-22 11:59:36 -0700298 if (priority_ != kPriorityNone) {
299 storage->SetInt(id, kStoragePriority, priority_);
300 } else {
301 storage->DeleteKey(id, kStoragePriority);
302 }
Paul Stewart987e71e2011-12-05 09:45:06 -0800303 SaveString(storage, id, kStorageProxyConfig, proxy_config_, false, true);
Chris Masone34af2182011-08-22 11:59:36 -0700304 if (save_credentials_) {
305 storage->DeleteKey(id, kStorageSaveCredentials);
306 } else {
307 storage->SetBool(id, kStorageSaveCredentials, false);
308 }
Paul Stewart987e71e2011-12-05 09:45:06 -0800309 SaveString(storage, id, kStorageUIData, ui_data_, false, true);
Chris Masone34af2182011-08-22 11:59:36 -0700310
311 SaveEapCredentials(storage, id);
312
313 // TODO(petkov): Save these:
314
315 // "WiFi.HiddenSSID"
316 // "SSID"
317 // "Failure"
318 // "Modified"
319 // "LastAttempt"
320 // WiFiService: "Passphrase"
321 // "APN"
322 // "LastGoodAPN"
323
324 return true;
325}
326
mukesh agrawal00917ce2011-11-22 23:56:55 +0000327void Service::MakeFavorite() {
328 if (favorite_) {
329 // We do not want to clobber the value of auto_connect_ (it may
330 // be user-set). So return early.
331 return;
332 }
333
334 auto_connect_ = true;
335 favorite_ = true;
336}
337
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800338void Service::SetConnection(ConnectionRefPtr connection) {
339 if (connection.get()) {
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800340 http_proxy_.reset(new HTTPProxy(connection));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800341 http_proxy_->Start(dispatcher_, &sockets_);
342 } else {
343 http_proxy_.reset();
344 }
345 connection_ = connection;
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800346}
347
mukesh agrawal00917ce2011-11-22 23:56:55 +0000348// static
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800349const char *Service::ConnectFailureToString(const ConnectFailure &state) {
350 switch (state) {
351 case kFailureUnknown:
352 return "Unknown";
353 case kFailureActivationFailure:
354 return "Activation Failure";
355 case kFailureOutOfRange:
356 return "Out of range";
357 case kFailurePinMissing:
358 return "PIN missing";
359 case kFailureConfigurationFailed:
360 return "Configuration Failed";
361 case kFailureBadCredentials:
362 return "Bad Credentials";
363 case kFailureNeedEVDO:
364 return "Need EVDO";
365 case kFailureNeedHomeNetwork:
366 return "Need Home Network";
367 case kFailureOTASPFailure:
368 return "OTASP Failure";
369 case kFailureAAAFailure:
370 return "AAA Failure";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000371 case kFailureMax:
372 return "Max failure error code";
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800373 }
374 return "Invalid";
375}
376
377// static
378const char *Service::ConnectStateToString(const ConnectState &state) {
379 switch (state) {
380 case kStateUnknown:
381 return "Unknown";
382 case kStateIdle:
383 return "Idle";
384 case kStateAssociating:
385 return "Associating";
386 case kStateConfiguring:
387 return "Configuring";
388 case kStateConnected:
389 return "Connected";
390 case kStateDisconnected:
391 return "Disconnected";
Thieu Le48e6d6d2011-12-06 00:40:27 +0000392 case kStateReady:
393 return "Ready";
394 case kStatePortal:
395 return "Portal";
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800396 case kStateFailure:
397 return "Failure";
398 case kStateOnline:
399 return "Online";
400 }
401 return "Invalid";
402}
403
404
405// static
Gaurav Shah435de2c2011-11-17 19:01:07 -0800406string Service::GetTechnologyString(Error */*error*/) {
407 return Technology::NameFromIdentifier(technology());
408}
409
Paul Stewart22aa71b2011-09-16 12:15:11 -0700410bool Service::DecideBetween(int a, int b, bool *decision) {
411 if (a == b)
412 return false;
413 *decision = (a > b);
414 return true;
415}
416
mukesh agrawal00917ce2011-11-22 23:56:55 +0000417// static
Paul Stewart22aa71b2011-09-16 12:15:11 -0700418bool Service::Compare(ServiceRefPtr a,
419 ServiceRefPtr b,
420 const vector<Technology::Identifier> &tech_order) {
421 bool ret;
422
423 if (a->state() != b->state()) {
424 if (DecideBetween(a->IsConnected(), b->IsConnected(), &ret)) {
425 return ret;
426 }
427
428 // TODO(pstew): Services don't know about portal state yet
429
430 if (DecideBetween(a->IsConnecting(), b->IsConnecting(), &ret)) {
431 return ret;
432 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000433
434 if (DecideBetween(!a->IsFailed(), !b->IsFailed(), &ret)) {
435 return ret;
436 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700437 }
438
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000439 if (DecideBetween(a->connectable(), b->connectable(), &ret) ||
440 DecideBetween(a->auto_connect(), b->auto_connect(), &ret) ||
441 DecideBetween(a->favorite(), b->favorite(), &ret) ||
Paul Stewart22aa71b2011-09-16 12:15:11 -0700442 DecideBetween(a->priority(), b->priority(), &ret)) {
443 return ret;
444 }
445
446 // TODO(pstew): Below this point we are making value judgements on
447 // services that are not related to anything intrinsic or
448 // user-specified. These heuristics should be richer (contain
449 // historical information, for example) and be subject to user
450 // customization.
451
452 for (vector<Technology::Identifier>::const_iterator it = tech_order.begin();
453 it != tech_order.end();
454 ++it) {
455 if (DecideBetween(a->TechnologyIs(*it), b->TechnologyIs(*it), &ret))
456 return ret;
457 }
458
Paul Stewart1ca3e852011-11-04 07:50:49 -0700459 if (DecideBetween(a->security_level(), b->security_level(), &ret) ||
Paul Stewart22aa71b2011-09-16 12:15:11 -0700460 DecideBetween(a->strength(), b->strength(), &ret)) {
461 return ret;
462 }
463
464 return a->UniqueName() < b->UniqueName();
465}
466
Chris Masone34af2182011-08-22 11:59:36 -0700467const ProfileRefPtr &Service::profile() const { return profile_; }
468
469void Service::set_profile(const ProfileRefPtr &p) { profile_ = p; }
470
mukesh agrawal29c13a12011-11-24 00:09:19 +0000471void Service::set_connectable(bool connectable) {
472 connectable_ = connectable;
473 adaptor_->EmitBoolChanged(flimflam::kConnectableProperty, connectable_);
474}
475
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800476string Service::CalculateState(Error */*error*/) {
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700477 switch (state_) {
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800478 case kStateIdle:
479 return flimflam::kStateIdle;
480 case kStateAssociating:
481 return flimflam::kStateAssociation;
482 case kStateConfiguring:
483 return flimflam::kStateConfiguration;
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700484 case kStateConnected:
Gaurav Shah435de2c2011-11-17 19:01:07 -0800485 // TODO(gauravsh): Until portal handling is implemented, go to "online"
486 // instead of "ready" state. crosbug.com/23318
487 return flimflam::kStateOnline;
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800488 case kStateDisconnected:
489 return flimflam::kStateDisconnect;
490 case kStateFailure:
491 return flimflam::kStateFailure;
492 case kStateOnline:
493 return flimflam::kStateOnline;
494 case kStateUnknown:
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700495 default:
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800496 return "";
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700497 }
498}
499
mukesh agrawalffa3d042011-10-06 15:26:10 -0700500void Service::HelpRegisterDerivedBool(
501 const string &name,
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800502 bool(Service::*get)(Error *),
mukesh agrawalffa3d042011-10-06 15:26:10 -0700503 void(Service::*set)(const bool&, Error *)) {
Chris Masone27c4aa52011-07-02 13:10:14 -0700504 store_.RegisterDerivedBool(
505 name,
506 BoolAccessor(new CustomAccessor<Service, bool>(this, get, set)));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700507}
508
mukesh agrawalffa3d042011-10-06 15:26:10 -0700509void Service::HelpRegisterDerivedString(
510 const string &name,
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800511 string(Service::*get)(Error *),
mukesh agrawalffa3d042011-10-06 15:26:10 -0700512 void(Service::*set)(const string&, Error *)) {
Chris Masone27c4aa52011-07-02 13:10:14 -0700513 store_.RegisterDerivedString(
514 name,
515 StringAccessor(new CustomAccessor<Service, string>(this, get, set)));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700516}
517
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800518void Service::HelpRegisterDerivedUint16(
519 const string &name,
520 uint16(Service::*get)(Error *),
521 void(Service::*set)(const uint16&, Error *)) {
522 store_.RegisterDerivedUint16(
523 name,
524 Uint16Accessor(new CustomAccessor<Service, uint16>(this, get, set)));
525}
526
Darin Petkovba40dd32011-07-11 20:06:39 -0700527void Service::SaveString(StoreInterface *storage,
Chris Masone34af2182011-08-22 11:59:36 -0700528 const string &id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700529 const string &key,
530 const string &value,
531 bool crypted,
532 bool save) {
533 if (value.empty() || !save) {
Chris Masone34af2182011-08-22 11:59:36 -0700534 storage->DeleteKey(id, key);
Darin Petkovba40dd32011-07-11 20:06:39 -0700535 return;
536 }
537 if (crypted) {
Chris Masone34af2182011-08-22 11:59:36 -0700538 storage->SetCryptedString(id, key, value);
Darin Petkovba40dd32011-07-11 20:06:39 -0700539 return;
540 }
Chris Masone34af2182011-08-22 11:59:36 -0700541 storage->SetString(id, key, value);
Darin Petkovba40dd32011-07-11 20:06:39 -0700542}
543
Chris Masone34af2182011-08-22 11:59:36 -0700544void Service::LoadEapCredentials(StoreInterface *storage, const string &id) {
Darin Petkovba40dd32011-07-11 20:06:39 -0700545 storage->GetCryptedString(id, kStorageEapIdentity, &eap_.identity);
546 storage->GetString(id, kStorageEapEap, &eap_.eap);
547 storage->GetString(id, kStorageEapInnerEap, &eap_.inner_eap);
548 storage->GetCryptedString(id,
549 kStorageEapAnonymousIdentity,
550 &eap_.anonymous_identity);
551 storage->GetString(id, kStorageEapClientCert, &eap_.client_cert);
552 storage->GetString(id, kStorageEapCertID, &eap_.cert_id);
553 storage->GetString(id, kStorageEapPrivateKey, &eap_.private_key);
554 storage->GetCryptedString(id,
555 kStorageEapPrivateKeyPassword,
556 &eap_.private_key_password);
557 storage->GetString(id, kStorageEapKeyID, &eap_.key_id);
558 storage->GetString(id, kStorageEapCACert, &eap_.ca_cert);
559 storage->GetString(id, kStorageEapCACertID, &eap_.ca_cert_id);
560 storage->GetBool(id, kStorageEapUseSystemCAs, &eap_.use_system_cas);
561 storage->GetString(id, kStorageEapPIN, &eap_.pin);
562 storage->GetCryptedString(id, kStorageEapPassword, &eap_.password);
563 storage->GetString(id, kStorageEapKeyManagement, &eap_.key_management);
mukesh agrawal29c13a12011-11-24 00:09:19 +0000564 // TODO(quiche): Update Connectable property. (crosbug.com/23466)
Darin Petkovba40dd32011-07-11 20:06:39 -0700565}
566
Chris Masone34af2182011-08-22 11:59:36 -0700567void Service::SaveEapCredentials(StoreInterface *storage, const string &id) {
Darin Petkovba40dd32011-07-11 20:06:39 -0700568 bool save = save_credentials_;
Chris Masone34af2182011-08-22 11:59:36 -0700569 SaveString(storage, id, kStorageEapIdentity, eap_.identity, true, save);
570 SaveString(storage, id, kStorageEapEap, eap_.eap, false, true);
571 SaveString(storage, id, kStorageEapInnerEap, eap_.inner_eap, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700572 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700573 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700574 kStorageEapAnonymousIdentity,
575 eap_.anonymous_identity,
576 true,
577 save);
Chris Masone34af2182011-08-22 11:59:36 -0700578 SaveString(storage, id, kStorageEapClientCert, eap_.client_cert, false, save);
579 SaveString(storage, id, kStorageEapCertID, eap_.cert_id, false, save);
580 SaveString(storage, id, kStorageEapPrivateKey, eap_.private_key, false, save);
Darin Petkovba40dd32011-07-11 20:06:39 -0700581 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700582 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700583 kStorageEapPrivateKeyPassword,
584 eap_.private_key_password,
585 true,
586 save);
Chris Masone34af2182011-08-22 11:59:36 -0700587 SaveString(storage, id, kStorageEapKeyID, eap_.key_id, false, save);
588 SaveString(storage, id, kStorageEapCACert, eap_.ca_cert, false, true);
589 SaveString(storage, id, kStorageEapCACertID, eap_.ca_cert_id, false, true);
590 storage->SetBool(id, kStorageEapUseSystemCAs, eap_.use_system_cas);
591 SaveString(storage, id, kStorageEapPIN, eap_.pin, false, save);
592 SaveString(storage, id, kStorageEapPassword, eap_.password, true, save);
Darin Petkovba40dd32011-07-11 20:06:39 -0700593 SaveString(storage,
Chris Masone34af2182011-08-22 11:59:36 -0700594 id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700595 kStorageEapKeyManagement,
596 eap_.key_management,
597 false,
598 true);
599}
600
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800601void Service::UnloadEapCredentials() {
602 eap_.identity = "";
603 eap_.eap = "";
604 eap_.inner_eap = "";
605 eap_.anonymous_identity = "";
606 eap_.client_cert = "";
607 eap_.cert_id = "";
608 eap_.private_key = "";
609 eap_.private_key_password = "";
610 eap_.key_id = "";
611 eap_.ca_cert = "";
612 eap_.ca_cert_id = "";
613 eap_.use_system_cas = false;
614 eap_.pin = "";
615 eap_.password = "";
616 eap_.key_management = "";
617}
618
Paul Stewartac4ac002011-08-26 12:04:26 -0700619const string &Service::GetEAPKeyManagement() const {
620 return eap_.key_management;
621}
622
623void Service::SetEAPKeyManagement(const string &key_management) {
624 eap_.key_management = key_management;
625}
626
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800627string Service::GetProfileRpcId(Error *error) {
628 if (!profile_) {
629 // This happens in some unit tests where profile_ is not set.
630 error->Populate(Error::kNotFound);
631 return "";
632 }
633 return profile_->GetRpcIdentifier();
634}
635
636void Service::SetProfileRpcId(const string &profile, Error *error) {
637 manager_->SetProfileForService(this, profile, error);
638}
639
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800640uint16 Service::GetHTTPProxyPort(Error */*error*/) {
641 if (http_proxy_.get()) {
642 return static_cast<uint16>(http_proxy_->proxy_port());
643 }
644 return 0;
645}
646
Paul Stewart75897df2011-04-27 09:05:53 -0700647} // namespace shill