blob: 6404f32c9c6e5e8fd05bf0d53a981f3fee3c9fa1 [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 Masone9be4a9d2011-05-16 15:44:09 -07005#ifndef SHILL_SERVICE_
6#define SHILL_SERVICE_
Paul Stewart75897df2011-04-27 09:05:53 -07007
Chris Masone9be4a9d2011-05-16 15:44:09 -07008#include <string>
Chris Masone8fe2c7e2011-06-09 15:51:19 -07009#include <map>
10#include <vector>
Chris Masone9be4a9d2011-05-16 15:44:09 -070011
12#include <base/memory/ref_counted.h>
Paul Stewartba41b992011-05-26 07:02:46 -070013#include <base/memory/scoped_ptr.h>
Darin Petkovba40dd32011-07-11 20:06:39 -070014#include <gtest/gtest_prod.h> // for FRIEND_TEST
Paul Stewart75897df2011-04-27 09:05:53 -070015
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include "shill/accessor_interface.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070017#include "shill/property_store.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070018#include "shill/refptr_types.h"
Paul Stewartbe5f5b32011-12-07 17:11:11 -080019#include "shill/sockets.h"
Paul Stewart22aa71b2011-09-16 12:15:11 -070020#include "shill/technology.h"
Chris Masonec1e50412011-06-07 13:04:53 -070021
Paul Stewart75897df2011-04-27 09:05:53 -070022namespace shill {
23
Paul Stewart75897df2011-04-27 09:05:53 -070024class Configuration;
Chris Masone9be4a9d2011-05-16 15:44:09 -070025class ControlInterface;
Paul Stewart75897df2011-04-27 09:05:53 -070026class Endpoint;
Chris Masone8fe2c7e2011-06-09 15:51:19 -070027class Error;
Chris Masone9be4a9d2011-05-16 15:44:09 -070028class EventDispatcher;
Paul Stewartbe5f5b32011-12-07 17:11:11 -080029class HTTPProxy;
mukesh agrawal7a4e4002011-09-06 11:26:05 -070030class KeyValueStore;
Chris Masone6791a432011-07-12 13:23:19 -070031class Manager;
Thieu Le48e6d6d2011-12-06 00:40:27 +000032class Metrics;
Chris Masone9be4a9d2011-05-16 15:44:09 -070033class ServiceAdaptorInterface;
Darin Petkovba40dd32011-07-11 20:06:39 -070034class StoreInterface;
Paul Stewart75897df2011-04-27 09:05:53 -070035
Chris Masone7aa5f902011-07-11 11:13:35 -070036// A Service is a uniquely named entity, which the system can
37// connect in order to begin sending and receiving network traffic.
38// All Services are bound to an Entry, which represents the persistable
39// state of the Service. If the Entry is populated at the time of Service
40// creation, that information is used to prime the Service. If not, the Entry
41// becomes populated over time.
Chris Masone27c4aa52011-07-02 13:10:14 -070042class Service : public base::RefCounted<Service> {
Paul Stewart75897df2011-04-27 09:05:53 -070043 public:
Darin Petkovba40dd32011-07-11 20:06:39 -070044 static const char kCheckPortalAuto[];
45 static const char kCheckPortalFalse[];
46 static const char kCheckPortalTrue[];
47
Paul Stewart75897df2011-04-27 09:05:53 -070048 enum ConnectFailure {
Paul Stewart03dba0b2011-08-22 16:32:45 -070049 kFailureUnknown,
50 kFailureActivationFailure,
51 kFailureOutOfRange,
52 kFailurePinMissing,
53 kFailureConfigurationFailed,
54 kFailureBadCredentials,
55 kFailureNeedEVDO,
56 kFailureNeedHomeNetwork,
57 kFailureOTASPFailure,
Thieu Le48e6d6d2011-12-06 00:40:27 +000058 kFailureAAAFailure,
59 kFailureMax
Paul Stewart75897df2011-04-27 09:05:53 -070060 };
Chris Masone9be4a9d2011-05-16 15:44:09 -070061 enum ConnectState {
Paul Stewart03dba0b2011-08-22 16:32:45 -070062 kStateUnknown,
63 kStateIdle,
64 kStateAssociating,
65 kStateConfiguring,
66 kStateConnected,
67 kStateDisconnected,
Thieu Le48e6d6d2011-12-06 00:40:27 +000068 kStateReady,
69 kStatePortal,
Gaurav Shahc6d6c722011-11-17 18:59:39 -080070 kStateFailure,
71 kStateOnline
Chris Masone9be4a9d2011-05-16 15:44:09 -070072 };
Chris Masoneb2e326b2011-07-12 13:28:51 -070073 struct EapCredentials {
74 EapCredentials() : use_system_cas(false) {}
75 std::string identity;
76 std::string eap;
77 std::string inner_eap;
78 std::string anonymous_identity;
79 std::string client_cert;
80 std::string cert_id;
81 std::string private_key;
82 std::string private_key_password;
83 std::string key_id;
84 std::string ca_cert;
85 std::string ca_cert_id;
86 bool use_system_cas;
87 std::string pin;
88 std::string password;
89 std::string key_management;
90 };
Chris Masone9be4a9d2011-05-16 15:44:09 -070091
Paul Stewartac4ac002011-08-26 12:04:26 -070092 static const int kPriorityNone;
93
Chris Masone9be4a9d2011-05-16 15:44:09 -070094 // A constructor for the Service object
95 Service(ControlInterface *control_interface,
96 EventDispatcher *dispatcher,
mukesh agrawal7a4e4002011-09-06 11:26:05 -070097 Manager *manager,
Gaurav Shah435de2c2011-11-17 19:01:07 -080098 Technology::Identifier technology);
Chris Masone9be4a9d2011-05-16 15:44:09 -070099 virtual ~Service();
Darin Petkovba40dd32011-07-11 20:06:39 -0700100
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000101 // AutoConnect MAY choose to ignore the connection request in some
102 // cases. For example, if the corresponding Device only supports one
103 // concurrent connection, and another Service is already connected
104 // or connecting.
105 //
106 // AutoConnect MAY issue RPCs immediately. So AutoConnect MUST NOT
107 // be called from a D-Bus signal handler context.
108 virtual void AutoConnect();
109 // Queue up a connection attempt.
Darin Petkov4d6d9412011-08-24 13:19:54 -0700110 virtual void Connect(Error *error) = 0;
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +0000111 virtual void Disconnect(Error *error) = 0;
Chris Masonea82b7112011-05-25 15:16:29 -0700112
Darin Petkovb100ae72011-08-24 16:19:45 -0700113 // The default implementation sets |error| to kInvalidArguments.
114 virtual void ActivateCellularModem(const std::string &carrier, Error *error);
Darin Petkovc408e692011-08-17 13:47:15 -0700115
Paul Stewart22aa71b2011-09-16 12:15:11 -0700116 // Base method always returns false.
117 virtual bool TechnologyIs(const Technology::Identifier type) const;
118
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800119 virtual bool IsActive(Error *error);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700120
121 virtual ConnectState state() const { return state_; }
122 // Updates the state of the Service and alerts the manager. Also
123 // clears |failure_| if the new state isn't a failure.
124 virtual void SetState(ConnectState state);
125
Paul Stewart22aa71b2011-09-16 12:15:11 -0700126 // State utility functions
Gaurav Shah435de2c2011-11-17 19:01:07 -0800127 virtual bool IsConnected() const { return state() == kStateConnected; }
128 virtual bool IsConnecting() const {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700129 return state() == kStateAssociating || state() == kStateConfiguring;
130 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000131 virtual bool IsFailed() const {
132 return state() == kStateFailure;
133 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700134
Paul Stewart03dba0b2011-08-22 16:32:45 -0700135 virtual ConnectFailure failure() const { return failure_; }
136 // Records the failure mode, and sets the Service state to "Failure".
137 virtual void SetFailure(ConnectFailure failure);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700138
Darin Petkovba40dd32011-07-11 20:06:39 -0700139 // Returns a string that is guaranteed to uniquely identify this Service
140 // instance.
mukesh agrawald835b202011-10-07 15:26:47 -0700141 const std::string &UniqueName() const { return unique_name_; }
Darin Petkovafa6fc42011-06-21 16:21:08 -0700142
Chris Masone6791a432011-07-12 13:23:19 -0700143 virtual std::string GetRpcIdentifier() const;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700144
Darin Petkovba40dd32011-07-11 20:06:39 -0700145 // Returns the unique persistent storage identifier for the service.
Chris Masone6515aab2011-10-12 16:19:09 -0700146 virtual std::string GetStorageIdentifier() const = 0;
Darin Petkovba40dd32011-07-11 20:06:39 -0700147
Paul Stewartbba6a5b2011-11-02 18:45:59 -0700148 // Returns whether the service configuration can be loaded from |storage|.
149 virtual bool IsLoadableFrom(StoreInterface *storage) const;
150
Darin Petkovba40dd32011-07-11 20:06:39 -0700151 // Loads the service from persistent |storage|. Returns true on success.
Chris Masone9d779932011-08-25 16:33:41 -0700152 virtual bool Load(StoreInterface *storage);
Darin Petkovba40dd32011-07-11 20:06:39 -0700153
Paul Stewarta41e38d2011-11-11 07:47:29 -0800154 // Indicate to service that it is no longer persisted to storage. It
155 // should purge any stored profile state (e.g., credentials).
156 virtual void Unload();
157
Darin Petkovba40dd32011-07-11 20:06:39 -0700158 // Saves the service to persistent |storage|. Returns true on success.
Chris Masone9d779932011-08-25 16:33:41 -0700159 virtual bool Save(StoreInterface *storage);
Darin Petkovba40dd32011-07-11 20:06:39 -0700160
Paul Stewarta41e38d2011-11-11 07:47:29 -0800161 // Returns true if the service RPC identifier should be part of the
162 // manager's advertised services list, false otherwise.
163 virtual bool IsVisible() const { return true; }
164
mukesh agrawal00917ce2011-11-22 23:56:55 +0000165 virtual void MakeFavorite();
166
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800167 // Set the connection for this service. If the connection is
168 // non-NULL, create an HTTP Proxy that will utilize this service's
169 // connection to serve requests.
170 virtual void SetConnection(ConnectionRefPtr connection);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800171
Thieu Le48e6d6d2011-12-06 00:40:27 +0000172 // The inherited class should register any custom metrics in this method.
173 virtual void InitializeCustomMetrics() const {}
174
175 // The inherited class that needs to send metrics after the service has
176 // transitioned to the ready state.
177 virtual void SendPostReadyStateMetrics() const {}
178
Darin Petkovafa6fc42011-06-21 16:21:08 -0700179 bool auto_connect() const { return auto_connect_; }
180 void set_auto_connect(bool connect) { auto_connect_ = connect; }
Paul Stewart75897df2011-04-27 09:05:53 -0700181
Gaurav Shah435de2c2011-11-17 19:01:07 -0800182 bool connectable() const { return connectable_; }
mukesh agrawal29c13a12011-11-24 00:09:19 +0000183 void set_connectable(bool connectable);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800184
Paul Stewart22aa71b2011-09-16 12:15:11 -0700185 bool favorite() const { return favorite_; }
mukesh agrawal00917ce2011-11-22 23:56:55 +0000186 // Setter is deliberately omitted; use MakeFavorite.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700187
mukesh agrawal15908392011-11-16 18:29:25 +0000188 const std::string &friendly_name() const { return friendly_name_; }
189
Paul Stewart22aa71b2011-09-16 12:15:11 -0700190 int32 priority() const { return priority_; }
191 void set_priority(int32 priority) { priority_ = priority; }
192
Paul Stewart1ca3e852011-11-04 07:50:49 -0700193 int32 security_level() const { return security_level_; }
194 void set_security_level(int32 security) { security_level_ = security; }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700195
196 int32 strength() const { return strength_; }
197 void set_strength(int32 strength) { strength_ = strength; }
198
Gaurav Shah435de2c2011-11-17 19:01:07 -0800199 virtual Technology::Identifier technology() const { return technology_; }
200 std::string GetTechnologyString(Error *error);
201
Darin Petkov51489002011-08-18 13:13:20 -0700202 const std::string &error() const { return error_; }
203 void set_error(const std::string &error) { error_ = error; }
204
Gaurav Shahc6d6c722011-11-17 18:59:39 -0800205 static const char *ConnectFailureToString(const ConnectFailure &state);
206 static const char *ConnectStateToString(const ConnectState &state);
207
Paul Stewart22aa71b2011-09-16 12:15:11 -0700208 // Compare two services. Returns true if Service a should be displayed
209 // above Service b
210 static bool Compare(ServiceRefPtr a,
211 ServiceRefPtr b,
212 const std::vector<Technology::Identifier> &tech_order);
213
Chris Masone34af2182011-08-22 11:59:36 -0700214 // These are defined in service.cc so that we don't have to include profile.h
Chris Masone9d779932011-08-25 16:33:41 -0700215 // TODO(cmasone): right now, these are here only so that we can get the
216 // profile name as a property. Can we store just the name, and then handle
217 // setting the profile for this service via |manager_|?
Chris Masone6791a432011-07-12 13:23:19 -0700218 const ProfileRefPtr &profile() const;
219 void set_profile(const ProfileRefPtr &p);
220
mukesh agrawalde29fa82011-09-16 16:16:36 -0700221 PropertyStore *mutable_store() { return &store_; }
222 const PropertyStore &store() const { return store_; }
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800223 const ConnectionRefPtr &connection() const { return connection_; }
Chris Masone27c4aa52011-07-02 13:10:14 -0700224
mukesh agrawalb54601c2011-06-07 17:39:22 -0700225 protected:
Chris Masone34af2182011-08-22 11:59:36 -0700226 // Returns true if a character is allowed to be in a service storage id.
227 static bool LegalChar(char a) { return isalnum(a) || a == '_'; }
228
mukesh agrawald835b202011-10-07 15:26:47 -0700229 void set_friendly_name(const std::string &n) { friendly_name_ = n; }
Chris Masone9d779932011-08-25 16:33:41 -0700230
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800231 virtual std::string CalculateState(Error *error);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700232
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000233 // Returns whether this service is in a state conducive to auto-connect.
234 // This should include any tests used for computing connectable(),
235 // as well as other critera such as whether the device associated with
236 // this service is busy with another connection.
237 virtual bool IsAutoConnectable() const { return connectable(); }
238
mukesh agrawalffa3d042011-10-06 15:26:10 -0700239 void HelpRegisterDerivedBool(
240 const std::string &name,
Hristo Stefanoved2c28c2011-11-29 15:37:30 -0800241 bool(Service::*get)(Error *error),
242 void(Service::*set)(const bool &value, Error *error));
mukesh agrawalffa3d042011-10-06 15:26:10 -0700243 void HelpRegisterDerivedString(
244 const std::string &name,
Hristo Stefanoved2c28c2011-11-29 15:37:30 -0800245 std::string(Service::*get)(Error *error),
246 void(Service::*set)(const std::string &value, Error *error));
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800247 void HelpRegisterDerivedUint16(
248 const std::string &name,
249 uint16(Service::*get)(Error *error),
250 void(Service::*set)(const uint16 &value, Error *error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700251
Darin Petkovb72cf402011-11-22 14:51:39 +0100252 ServiceAdaptorInterface *adaptor() const { return adaptor_.get(); }
253
Darin Petkovba40dd32011-07-11 20:06:39 -0700254 // Assigns |value| to |key| in |storage| if |value| is non-empty and |save| is
255 // true. Otherwise, removes |key| from |storage|. If |crypted| is true, the
256 // value is encrypted.
257 void SaveString(StoreInterface *storage,
Chris Masone34af2182011-08-22 11:59:36 -0700258 const std::string &id,
Darin Petkovba40dd32011-07-11 20:06:39 -0700259 const std::string &key,
260 const std::string &value,
261 bool crypted,
262 bool save);
263
Chris Masone34af2182011-08-22 11:59:36 -0700264 void LoadEapCredentials(StoreInterface *storage, const std::string &id);
265 void SaveEapCredentials(StoreInterface *storage, const std::string &id);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800266 void UnloadEapCredentials();
Darin Petkovba40dd32011-07-11 20:06:39 -0700267
Paul Stewartac4ac002011-08-26 12:04:26 -0700268 // Property accessors reserved for subclasses
269 EventDispatcher *dispatcher() const { return dispatcher_; }
270 const std::string &GetEAPKeyManagement() const;
271 void SetEAPKeyManagement(const std::string &key_management);
Thieu Le48e6d6d2011-12-06 00:40:27 +0000272 Metrics *metrics() const { return metrics_; }
mukesh agrawalb54601c2011-06-07 17:39:22 -0700273
Paul Stewart75897df2011-04-27 09:05:53 -0700274 private:
Darin Petkovba40dd32011-07-11 20:06:39 -0700275 friend class ServiceAdaptorInterface;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000276 friend class MetricsTest;
Paul Stewart03dba0b2011-08-22 16:32:45 -0700277 FRIEND_TEST(DeviceTest, SelectedService);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800278 FRIEND_TEST(ManagerTest, SortServicesWithConnection);
Darin Petkovba40dd32011-07-11 20:06:39 -0700279 FRIEND_TEST(ServiceTest, Constructor);
280 FRIEND_TEST(ServiceTest, Save);
281 FRIEND_TEST(ServiceTest, SaveString);
282 FRIEND_TEST(ServiceTest, SaveStringCrypted);
283 FRIEND_TEST(ServiceTest, SaveStringDontSave);
284 FRIEND_TEST(ServiceTest, SaveStringEmpty);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800285 FRIEND_TEST(ServiceTest, Unload);
Darin Petkovba40dd32011-07-11 20:06:39 -0700286
287 static const char kStorageAutoConnect[];
288 static const char kStorageCheckPortal[];
289 static const char kStorageEapAnonymousIdentity[];
290 static const char kStorageEapCACert[];
291 static const char kStorageEapCACertID[];
292 static const char kStorageEapCertID[];
293 static const char kStorageEapClientCert[];
294 static const char kStorageEapEap[];
295 static const char kStorageEapIdentity[];
296 static const char kStorageEapInnerEap[];
297 static const char kStorageEapKeyID[];
298 static const char kStorageEapKeyManagement[];
299 static const char kStorageEapPIN[];
300 static const char kStorageEapPassword[];
301 static const char kStorageEapPrivateKey[];
302 static const char kStorageEapPrivateKeyPassword[];
303 static const char kStorageEapUseSystemCAs[];
304 static const char kStorageFavorite[];
305 static const char kStorageName[];
306 static const char kStoragePriority[];
307 static const char kStorageProxyConfig[];
308 static const char kStorageSaveCredentials[];
Paul Stewart2706aaf2011-12-14 16:44:04 -0800309 static const char kStorageType[];
Paul Stewart987e71e2011-12-05 09:45:06 -0800310 static const char kStorageUIData[];
Darin Petkovba40dd32011-07-11 20:06:39 -0700311
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800312 virtual std::string GetDeviceRpcId(Error *error) = 0;
Chris Masone95207da2011-06-29 16:50:49 -0700313
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800314 std::string GetProfileRpcId(Error *error);
315 void SetProfileRpcId(const std::string &profile, Error *error);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700316
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800317 // Returns TCP port of service's HTTP proxy in host order.
318 uint16 GetHTTPProxyPort(Error *error);
319
Paul Stewart22aa71b2011-09-16 12:15:11 -0700320 // Utility function that returns true if a is different from b. When they
321 // are, "decision" is populated with the boolean value of "a > b".
322 static bool DecideBetween(int a, int b, bool *decision);
323
Thieu Le48e6d6d2011-12-06 00:40:27 +0000324 // For unit testing.
325 void set_metrics(Metrics *metrics) { metrics_ = metrics; }
326
Paul Stewartac4ac002011-08-26 12:04:26 -0700327 ConnectState state_;
328 ConnectFailure failure_;
329 bool auto_connect_;
330 std::string check_portal_;
331 bool connectable_;
332 std::string error_;
333 bool favorite_;
334 int32 priority_;
Paul Stewart1ca3e852011-11-04 07:50:49 -0700335 int32 security_level_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700336 int32 strength_;
Paul Stewartac4ac002011-08-26 12:04:26 -0700337 std::string proxy_config_;
Paul Stewart987e71e2011-12-05 09:45:06 -0800338 std::string ui_data_;
Paul Stewartac4ac002011-08-26 12:04:26 -0700339 bool save_credentials_;
340 EapCredentials eap_; // Only saved if |save_credentials_| is true.
Gaurav Shah435de2c2011-11-17 19:01:07 -0800341 Technology::Identifier technology_;
Paul Stewartac4ac002011-08-26 12:04:26 -0700342
343 ProfileRefPtr profile_;
344 PropertyStore store_;
345
346 EventDispatcher *dispatcher_;
mukesh agrawal51a7e932011-07-27 16:18:26 -0700347 static unsigned int serial_number_;
mukesh agrawald835b202011-10-07 15:26:47 -0700348 std::string unique_name_; // MUST be unique amongst service instances
349 std::string friendly_name_; // MAY be same as |unique_name_|
Paul Stewart75897df2011-04-27 09:05:53 -0700350 bool available_;
351 bool configured_;
Paul Stewart75897df2011-04-27 09:05:53 -0700352 Configuration *configuration_;
Paul Stewartba41b992011-05-26 07:02:46 -0700353 scoped_ptr<ServiceAdaptorInterface> adaptor_;
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800354 scoped_ptr<HTTPProxy> http_proxy_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800355 ConnectionRefPtr connection_;
Chris Masone6791a432011-07-12 13:23:19 -0700356 Manager *manager_;
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800357 Sockets sockets_;
Thieu Le48e6d6d2011-12-06 00:40:27 +0000358 Metrics *metrics_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700359
mukesh agrawalb54601c2011-06-07 17:39:22 -0700360 DISALLOW_COPY_AND_ASSIGN(Service);
Paul Stewart75897df2011-04-27 09:05:53 -0700361};
362
363} // namespace shill
364
365#endif // SHILL_SERVICE_