blob: bbc37ad46c66d914e551023459c24d50ce756d32 [file] [log] [blame]
// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_SERVICE_
#define SHILL_SERVICE_
#include <string>
#include <map>
#include <vector>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "shill/accessor_interface.h"
#include "shill/property_store.h"
#include "shill/refptr_types.h"
#include "shill/technology.h"
namespace shill {
class Connection;
class Configuration;
class ControlInterface;
class Endpoint;
class Error;
class EventDispatcher;
class KeyValueStore;
class Manager;
class ServiceAdaptorInterface;
class StoreInterface;
// A Service is a uniquely named entity, which the system can
// connect in order to begin sending and receiving network traffic.
// All Services are bound to an Entry, which represents the persistable
// state of the Service. If the Entry is populated at the time of Service
// creation, that information is used to prime the Service. If not, the Entry
// becomes populated over time.
class Service : public base::RefCounted<Service> {
public:
static const char kCheckPortalAuto[];
static const char kCheckPortalFalse[];
static const char kCheckPortalTrue[];
enum ConnectFailure {
kFailureUnknown,
kFailureActivationFailure,
kFailureOutOfRange,
kFailurePinMissing,
kFailureConfigurationFailed,
kFailureBadCredentials,
kFailureNeedEVDO,
kFailureNeedHomeNetwork,
kFailureOTASPFailure,
kFailureAAAFailure
};
enum ConnectState {
kStateUnknown,
kStateIdle,
kStateAssociating,
kStateConfiguring,
kStateConnected,
kStateDisconnected,
kStateFailure
};
struct EapCredentials {
EapCredentials() : use_system_cas(false) {}
std::string identity;
std::string eap;
std::string inner_eap;
std::string anonymous_identity;
std::string client_cert;
std::string cert_id;
std::string private_key;
std::string private_key_password;
std::string key_id;
std::string ca_cert;
std::string ca_cert_id;
bool use_system_cas;
std::string pin;
std::string password;
std::string key_management;
};
static const int kPriorityNone;
// A constructor for the Service object
Service(ControlInterface *control_interface,
EventDispatcher *dispatcher,
Manager *manager,
const std::string &type);
virtual ~Service();
virtual void Connect(Error *error) = 0;
virtual void Disconnect() = 0;
// The default implementation sets |error| to kInvalidArguments.
virtual void ActivateCellularModem(const std::string &carrier, Error *error);
// Base method always returns false.
virtual bool TechnologyIs(const Technology::Identifier type) const;
virtual bool IsActive(Error *error);
virtual ConnectState state() const { return state_; }
// Updates the state of the Service and alerts the manager. Also
// clears |failure_| if the new state isn't a failure.
virtual void SetState(ConnectState state);
// State utility functions
bool IsConnected() const { return state() == kStateConnected; }
bool IsConnecting() const {
return state() == kStateAssociating || state() == kStateConfiguring;
}
virtual ConnectFailure failure() const { return failure_; }
// Records the failure mode, and sets the Service state to "Failure".
virtual void SetFailure(ConnectFailure failure);
// Returns a string that is guaranteed to uniquely identify this Service
// instance.
const std::string &UniqueName() const { return unique_name_; }
virtual std::string GetRpcIdentifier() const;
// Returns the unique persistent storage identifier for the service.
virtual std::string GetStorageIdentifier() const = 0;
// Returns whether the service configuration can be loaded from |storage|.
virtual bool IsLoadableFrom(StoreInterface *storage) const;
// Loads the service from persistent |storage|. Returns true on success.
virtual bool Load(StoreInterface *storage);
// Saves the service to persistent |storage|. Returns true on success.
virtual bool Save(StoreInterface *storage);
bool auto_connect() const { return auto_connect_; }
void set_auto_connect(bool connect) { auto_connect_ = connect; }
bool favorite() const { return favorite_; }
void set_favorite(bool favorite) { favorite_ = favorite; }
int32 priority() const { return priority_; }
void set_priority(int32 priority) { priority_ = priority; }
int32 security_level() const { return security_level_; }
void set_security_level(int32 security) { security_level_ = security; }
int32 strength() const { return strength_; }
void set_strength(int32 strength) { strength_ = strength; }
const std::string &error() const { return error_; }
void set_error(const std::string &error) { error_ = error; }
// Compare two services. Returns true if Service a should be displayed
// above Service b
static bool Compare(ServiceRefPtr a,
ServiceRefPtr b,
const std::vector<Technology::Identifier> &tech_order);
// These are defined in service.cc so that we don't have to include profile.h
// TODO(cmasone): right now, these are here only so that we can get the
// profile name as a property. Can we store just the name, and then handle
// setting the profile for this service via |manager_|?
const ProfileRefPtr &profile() const;
void set_profile(const ProfileRefPtr &p);
PropertyStore *mutable_store() { return &store_; }
const PropertyStore &store() const { return store_; }
protected:
// Returns true if a character is allowed to be in a service storage id.
static bool LegalChar(char a) { return isalnum(a) || a == '_'; }
const std::string &friendly_name() const { return friendly_name_; }
void set_friendly_name(const std::string &n) { friendly_name_ = n; }
virtual std::string CalculateState(Error *error);
void HelpRegisterDerivedBool(
const std::string &name,
bool(Service::*get)(Error *),
void(Service::*set)(const bool&, Error *));
void HelpRegisterDerivedString(
const std::string &name,
std::string(Service::*get)(Error *),
void(Service::*set)(const std::string&, Error *));
// Assigns |value| to |key| in |storage| if |value| is non-empty and |save| is
// true. Otherwise, removes |key| from |storage|. If |crypted| is true, the
// value is encrypted.
void SaveString(StoreInterface *storage,
const std::string &id,
const std::string &key,
const std::string &value,
bool crypted,
bool save);
void LoadEapCredentials(StoreInterface *storage, const std::string &id);
void SaveEapCredentials(StoreInterface *storage, const std::string &id);
// Property accessors reserved for subclasses
EventDispatcher *dispatcher() const { return dispatcher_; }
const std::string &GetEAPKeyManagement() const;
void SetEAPKeyManagement(const std::string &key_management);
private:
friend class ServiceAdaptorInterface;
FRIEND_TEST(DeviceTest, SelectedService);
FRIEND_TEST(ServiceTest, Constructor);
FRIEND_TEST(ServiceTest, Save);
FRIEND_TEST(ServiceTest, SaveString);
FRIEND_TEST(ServiceTest, SaveStringCrypted);
FRIEND_TEST(ServiceTest, SaveStringDontSave);
FRIEND_TEST(ServiceTest, SaveStringEmpty);
static const char kStorageAutoConnect[];
static const char kStorageCheckPortal[];
static const char kStorageEapAnonymousIdentity[];
static const char kStorageEapCACert[];
static const char kStorageEapCACertID[];
static const char kStorageEapCertID[];
static const char kStorageEapClientCert[];
static const char kStorageEapEap[];
static const char kStorageEapIdentity[];
static const char kStorageEapInnerEap[];
static const char kStorageEapKeyID[];
static const char kStorageEapKeyManagement[];
static const char kStorageEapPIN[];
static const char kStorageEapPassword[];
static const char kStorageEapPrivateKey[];
static const char kStorageEapPrivateKeyPassword[];
static const char kStorageEapUseSystemCAs[];
static const char kStorageFavorite[];
static const char kStorageName[];
static const char kStoragePriority[];
static const char kStorageProxyConfig[];
static const char kStorageSaveCredentials[];
virtual std::string GetDeviceRpcId(Error *error) = 0;
std::string GetProfileRpcId(Error */*error*/) {
return ""; // Will need to call Profile to get this.
}
// Utility function that returns true if a is different from b. When they
// are, "decision" is populated with the boolean value of "a > b".
static bool DecideBetween(int a, int b, bool *decision);
ConnectState state_;
ConnectFailure failure_;
bool auto_connect_;
std::string check_portal_;
bool connectable_;
std::string error_;
bool favorite_;
int32 priority_;
int32 security_level_;
int32 strength_;
std::string proxy_config_;
bool save_credentials_;
EapCredentials eap_; // Only saved if |save_credentials_| is true.
const std::string type_;
ProfileRefPtr profile_;
PropertyStore store_;
EventDispatcher *dispatcher_;
static unsigned int serial_number_;
std::string unique_name_; // MUST be unique amongst service instances
std::string friendly_name_; // MAY be same as |unique_name_|
bool available_;
bool configured_;
Configuration *configuration_;
Connection *connection_;
scoped_ptr<ServiceAdaptorInterface> adaptor_;
Manager *manager_;
DISALLOW_COPY_AND_ASSIGN(Service);
};
} // namespace shill
#endif // SHILL_SERVICE_