// Copyright (c) 2010 The Chromium 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 CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_ #define CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_ #include <string> #include <vector> #include "base/observer_list.h" #include "base/platform_thread.h" #include "base/singleton.h" #include "base/string16.h" #include "base/timer.h" #include "net/url_request/url_request_job_tracker.h" #include "third_party/cros/chromeos_network.h" namespace chromeos { class Network { public: const std::string& service_path() const { return service_path_; } const std::string& device_path() const { return device_path_; } const std::string& ip_address() const { return ip_address_; } ConnectionType type() const { return type_; } bool connecting() const { return state_ == STATE_ASSOCIATION || state_ == STATE_CONFIGURATION || state_ == STATE_CARRIER; } bool connected() const { return state_ == STATE_READY; } bool connecting_or_connected() const { return connecting() || connected(); } bool failed() const { return state_ == STATE_FAILURE; } ConnectionError error() const { return error_; } void set_connecting(bool connecting) { state_ = (connecting ? STATE_ASSOCIATION : STATE_IDLE); } void set_connected(bool connected) { state_ = (connected ? STATE_READY : STATE_IDLE); } // Clear the fields. virtual void Clear(); // Configure the Network from a ServiceInfo object. virtual void ConfigureFromService(const ServiceInfo& service); // Return a string representation of the state code. // This not translated and should be only used for debugging purposes. std::string GetStateString(); // Return a string representation of the error code. // This not translated and should be only used for debugging purposes. std::string GetErrorString(); protected: Network() : type_(TYPE_UNKNOWN), state_(STATE_UNKNOWN), error_(ERROR_UNKNOWN) {} virtual ~Network() {} std::string service_path_; std::string device_path_; std::string ip_address_; ConnectionType type_; int state_; ConnectionError error_; }; class EthernetNetwork : public Network { public: EthernetNetwork() : Network() {} }; class WirelessNetwork : public Network { public: // WirelessNetwork are sorted by name. bool operator< (const WirelessNetwork& other) const { return name_ < other.name(); } // We frequently want to compare networks by service path. struct ServicePathEq { explicit ServicePathEq(const std::string& path_in) : path(path_in) {} bool operator()(const WirelessNetwork& a) { return a.service_path().compare(path) == 0; } const std::string& path; }; const std::string& name() const { return name_; } int strength() const { return strength_; } bool auto_connect() const { return auto_connect_; } void set_name(const std::string& name) { name_ = name; } void set_auto_connect(bool auto_connect) { auto_connect_ = auto_connect; } // Network overrides. virtual void Clear(); virtual void ConfigureFromService(const ServiceInfo& service); protected: WirelessNetwork() : Network(), strength_(0), auto_connect_(false) {} std::string name_; int strength_; bool auto_connect_; }; class CellularNetwork : public WirelessNetwork { public: CellularNetwork() : WirelessNetwork() {} explicit CellularNetwork(const ServiceInfo& service) : WirelessNetwork() { ConfigureFromService(service); } // WirelessNetwork overrides. virtual void Clear(); virtual void ConfigureFromService(const ServiceInfo& service); }; class WifiNetwork : public WirelessNetwork { public: WifiNetwork() : WirelessNetwork(), encryption_(SECURITY_NONE) {} explicit WifiNetwork(const ServiceInfo& service) : WirelessNetwork() { ConfigureFromService(service); } bool encrypted() const { return encryption_ != SECURITY_NONE; } ConnectionSecurity encryption() const { return encryption_; } const std::string& passphrase() const { return passphrase_; } const std::string& identity() const { return identity_; } const std::string& cert_path() const { return cert_path_; } void set_encryption(ConnectionSecurity encryption) { encryption_ = encryption; } void set_passphrase(const std::string& passphrase) { passphrase_ = passphrase; } void set_identity(const std::string& identity) { identity_ = identity; } void set_cert_path(const std::string& cert_path) { cert_path_ = cert_path; } // WirelessNetwork overrides. virtual void Clear(); virtual void ConfigureFromService(const ServiceInfo& service); // Return a string representation of the encryption code. // This not translated and should be only used for debugging purposes. std::string GetEncryptionString(); protected: ConnectionSecurity encryption_; std::string passphrase_; std::string identity_; std::string cert_path_; }; typedef std::vector<WifiNetwork> WifiNetworkVector; typedef std::vector<CellularNetwork> CellularNetworkVector; struct CellTower { enum RadioType { RADIOTYPE_GSM, RADIOTYPE_CDMA, RADIOTYPE_WCDMA, } radio_type; // GSM/WCDMA CDMA int mobile_country_code; // MCC MCC int mobile_network_code; // MNC SID int location_area_code; // LAC NID int cell_id; // CID BID base::Time timestamp; // Timestamp when this cell was primary int signal_strength; // Radio signal strength measured in dBm. int timing_advance; // Represents the distance from the cell tower. Each // unit is roughly 550 meters. }; struct WifiAccessPoint { std::string mac_address; // The mac address of the WiFi node. std::string name; // The SSID of the WiFi node. base::Time timestamp; // Timestamp when this AP was detected. int signal_strength; // Radio signal strength measured in dBm. int signal_to_noise; // Current signal to noise ratio measured in dB. int channel; // Wifi channel number. }; typedef std::vector<CellTower> CellTowerVector; typedef std::vector<WifiAccessPoint> WifiAccessPointVector; struct NetworkIPConfig { NetworkIPConfig(const std::string& device_path, IPConfigType type, const std::string& address, const std::string& netmask, const std::string& gateway, const std::string& name_servers) : device_path(device_path), type(type), address(address), netmask(netmask), gateway(gateway), name_servers(name_servers) {} // NetworkIPConfigs are sorted by tyoe. bool operator< (const NetworkIPConfig& other) const { return type < other.type; } std::string device_path; IPConfigType type; std::string address; std::string netmask; std::string gateway; std::string name_servers; }; typedef std::vector<NetworkIPConfig> NetworkIPConfigVector; class NetworkLibrary { public: class Observer { public: // A bitfield mask for traffic types. enum TrafficTypes { TRAFFIC_DOWNLOAD = 0x1, TRAFFIC_UPLOAD = 0x2, } TrafficTypeMasks; // Called when the network has changed. (wifi networks, and ethernet) virtual void NetworkChanged(NetworkLibrary* obj) = 0; // Called when network traffic has been detected. // Takes a bitfield of TrafficTypeMasks. virtual void NetworkTraffic(NetworkLibrary* obj, int traffic_type) = 0; }; virtual ~NetworkLibrary() {} virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; virtual const EthernetNetwork& ethernet_network() const = 0; virtual bool ethernet_connecting() const = 0; virtual bool ethernet_connected() const = 0; virtual const std::string& wifi_name() const = 0; virtual bool wifi_connecting() const = 0; virtual bool wifi_connected() const = 0; virtual int wifi_strength() const = 0; virtual const std::string& cellular_name() const = 0; virtual bool cellular_connecting() const = 0; virtual bool cellular_connected() const = 0; virtual int cellular_strength() const = 0; // Return true if any network is currently connected. virtual bool Connected() const = 0; // Return true if any network is currently connecting. virtual bool Connecting() const = 0; // Returns the current IP address if connected. If not, returns empty string. virtual const std::string& IPAddress() const = 0; // Returns the current list of wifi networks. virtual const WifiNetworkVector& wifi_networks() const = 0; // Returns the list of remembered wifi networks. virtual const WifiNetworkVector& remembered_wifi_networks() const = 0; // Returns the current list of cellular networks. virtual const CellularNetworkVector& cellular_networks() const = 0; // Returns the list of remembered cellular networks. virtual const CellularNetworkVector& remembered_cellular_networks() const = 0; // Search the current list of networks by path and if the network // is available, copy the result and return true. virtual bool FindWifiNetworkByPath(const std::string& path, WifiNetwork* result) const = 0; virtual bool FindCellularNetworkByPath(const std::string& path, CellularNetwork* result) const = 0; // Request a scan for new wifi networks. virtual void RequestWifiScan() = 0; // Reads out the results of the last wifi scan. These results are not // pre-cached in the library, so the call may block whilst the results are // read over IPC. // Returns false if an error occurred in reading the results. Note that // a true return code only indicates the result set was successfully read, // it does not imply a scan has successfully completed yet. virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) = 0; // TODO(joth): Add GetCellTowers to retrieve a CellTowerVector. // Force an update of the system info. virtual void UpdateSystemInfo() = 0; // Attempt to connect to the preferred network if available and it is set up. // This call will return true if connection is started. // If the preferred network is not available or not setup, returns false. // Note: For dogfood purposes, we hardcode the preferred network to Google-A. virtual bool ConnectToPreferredNetworkIfAvailable() = 0; // Returns true if we are currently connected to the preferred network. virtual bool PreferredNetworkConnected() = 0; // Returns true if we failed to connect to the preferred network. virtual bool PreferredNetworkFailed() = 0; // Connect to the specified wireless network with password. virtual void ConnectToWifiNetwork(WifiNetwork network, const std::string& password, const std::string& identity, const std::string& certpath) = 0; // Connect to the specified wifi ssid with password. virtual void ConnectToWifiNetwork(const std::string& ssid, const std::string& password, const std::string& identity, const std::string& certpath, bool auto_connect) = 0; // Connect to the specified cellular network. virtual void ConnectToCellularNetwork(CellularNetwork network) = 0; // Disconnect from the specified wireless (either cellular or wifi) network. virtual void DisconnectFromWirelessNetwork( const WirelessNetwork& network) = 0; // Save network information including passwords (wifi) and auto-connect. virtual void SaveCellularNetwork(const CellularNetwork& network) = 0; virtual void SaveWifiNetwork(const WifiNetwork& network) = 0; // Forget the passed in wireless (either cellular or wifi) network. virtual void ForgetWirelessNetwork(const WirelessNetwork& network) = 0; virtual bool ethernet_available() const = 0; virtual bool wifi_available() const = 0; virtual bool cellular_available() const = 0; virtual bool ethernet_enabled() const = 0; virtual bool wifi_enabled() const = 0; virtual bool cellular_enabled() const = 0; virtual bool offline_mode() const = 0; // Enables/disables the ethernet network device. virtual void EnableEthernetNetworkDevice(bool enable) = 0; // Enables/disables the wifi network device. virtual void EnableWifiNetworkDevice(bool enable) = 0; // Enables/disables the cellular network device. virtual void EnableCellularNetworkDevice(bool enable) = 0; // Enables/disables offline mode. virtual void EnableOfflineMode(bool enable) = 0; // Fetches IP configs for a given device_path virtual NetworkIPConfigVector GetIPConfigs( const std::string& device_path) = 0; // Fetches debug network info for display in about:network. // The page will have a meta refresh of |refresh| seconds if |refresh| > 0. virtual std::string GetHtmlInfo(int refresh) = 0; }; // This class handles the interaction with the ChromeOS network library APIs. // Classes can add themselves as observers. Users can get an instance of this // library class like this: NetworkLibrary::Get() class NetworkLibraryImpl : public NetworkLibrary, public URLRequestJobTracker::JobObserver { public: NetworkLibraryImpl(); virtual ~NetworkLibraryImpl(); // URLRequestJobTracker::JobObserver methods (called on the IO thread): virtual void OnJobAdded(URLRequestJob* job); virtual void OnJobRemoved(URLRequestJob* job); virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status); virtual void OnJobRedirect(URLRequestJob* job, const GURL& location, int status_code); virtual void OnBytesRead(URLRequestJob* job, const char* buf, int byte_count); // NetworkLibrary overrides. virtual void AddObserver(Observer* observer); virtual void RemoveObserver(Observer* observer); virtual const EthernetNetwork& ethernet_network() const { return ethernet_; } virtual bool ethernet_connecting() const { return ethernet_.connecting(); } virtual bool ethernet_connected() const { return ethernet_.connected(); } virtual const std::string& wifi_name() const { return wifi_.name(); } virtual bool wifi_connecting() const { return wifi_.connecting(); } virtual bool wifi_connected() const { return wifi_.connected(); } virtual int wifi_strength() const { return wifi_.strength(); } virtual const std::string& cellular_name() const { return cellular_.name(); } virtual bool cellular_connecting() const { return cellular_.connecting(); } virtual bool cellular_connected() const { return cellular_.connected(); } virtual int cellular_strength() const { return cellular_.strength(); } virtual bool Connected() const; virtual bool Connecting() const; virtual const std::string& IPAddress() const; virtual const WifiNetworkVector& wifi_networks() const { return wifi_networks_; } virtual const WifiNetworkVector& remembered_wifi_networks() const { return remembered_wifi_networks_; } virtual const CellularNetworkVector& cellular_networks() const { return cellular_networks_; } virtual const CellularNetworkVector& remembered_cellular_networks() const { return remembered_cellular_networks_; } virtual bool FindWifiNetworkByPath(const std::string& path, WifiNetwork* network) const; virtual bool FindCellularNetworkByPath(const std::string& path, CellularNetwork* network) const; virtual void RequestWifiScan(); virtual bool GetWifiAccessPoints(WifiAccessPointVector* result); virtual bool ConnectToPreferredNetworkIfAvailable(); virtual bool PreferredNetworkConnected(); virtual bool PreferredNetworkFailed(); virtual void ConnectToWifiNetwork(WifiNetwork network, const std::string& password, const std::string& identity, const std::string& certpath); virtual void ConnectToWifiNetwork(const std::string& ssid, const std::string& password, const std::string& identity, const std::string& certpath, bool auto_connect); virtual void ConnectToCellularNetwork(CellularNetwork network); virtual void DisconnectFromWirelessNetwork(const WirelessNetwork& network); virtual void SaveCellularNetwork(const CellularNetwork& network); virtual void SaveWifiNetwork(const WifiNetwork& network); virtual void ForgetWirelessNetwork(const WirelessNetwork& network); virtual bool ethernet_available() const { return available_devices_ & (1 << TYPE_ETHERNET); } virtual bool wifi_available() const { return available_devices_ & (1 << TYPE_WIFI); } virtual bool cellular_available() const { return available_devices_ & (1 << TYPE_CELLULAR); } virtual bool ethernet_enabled() const { return enabled_devices_ & (1 << TYPE_ETHERNET); } virtual bool wifi_enabled() const { return enabled_devices_ & (1 << TYPE_WIFI); } virtual bool cellular_enabled() const { return enabled_devices_ & (1 << TYPE_CELLULAR); } virtual bool offline_mode() const { return offline_mode_; } virtual void EnableEthernetNetworkDevice(bool enable); virtual void EnableWifiNetworkDevice(bool enable); virtual void EnableCellularNetworkDevice(bool enable); virtual void EnableOfflineMode(bool enable); virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path); virtual std::string GetHtmlInfo(int refresh); virtual void UpdateSystemInfo(); private: // This method is called when there's a change in network status. // This method is called on a background thread. static void NetworkStatusChangedHandler(void* object); // This parses SystemInfo into: // - an EthernetNetwork // - a WifiNetworkVector of wifi networks // - a CellularNetworkVector of cellular networks. // - a WifiNetworkVector of remembered wifi networks // - a CellularNetworkVector of remembered cellular networks. static void ParseSystem(SystemInfo* system, EthernetNetwork* ethernet, WifiNetworkVector* wifi_networks, CellularNetworkVector* ceullular_networks, WifiNetworkVector* remembered_wifi_networks, CellularNetworkVector* remembered_ceullular_networks); // This methods loads the initial list of networks on startup and starts the // monitoring of network changes. void Init(); // Returns the preferred wifi network. WifiNetwork* GetPreferredNetwork(); // Gets the WifiNetwork with the given name. Returns NULL if not found. // Only used by GetPreferredNetwork() to lookup "Google" and "GoogleA" (hack) WifiNetwork* GetWifiNetworkByName(const std::string& name); // Gets the WirelessNetwork (WifiNetwork or CellularNetwork) by path template<typename T> T* GetWirelessNetworkByPath(std::vector<T>& networks, const std::string& path); template<typename T> const T* GetWirelessNetworkByPath(const std::vector<T>& networks, const std::string& path) const; // Enables/disables the specified network device. void EnableNetworkDeviceType(ConnectionType device, bool enable); // Update the cached network status. // This will notify all the Observers. void UpdateNetworkStatus(); // Checks network traffic to see if there is any uploading. // If there is download traffic, then true is passed in for download. // If there is network traffic then start timer that invokes // NetworkTrafficTimerFired. void CheckNetworkTraffic(bool download); // Called when the timer fires and we need to send out NetworkTraffic // notifications. void NetworkTrafficTimerFired(); // This is a helper method to notify the observers on the UI thread. void NotifyNetworkTraffic(int traffic_type); // This will notify all obeservers on the UI thread. void NotifyObservers(); ObserverList<Observer> observers_; // The amount of time to wait between each NetworkTraffic notifications. static const int kNetworkTrafficeTimerSecs; // Timer for sending NetworkTraffic notification every // kNetworkTrafficeTimerSecs seconds. base::OneShotTimer<NetworkLibraryImpl> timer_; // The current traffic type that will be sent out for the next NetworkTraffic // notification. This is a bitfield of TrafficTypeMasks. int traffic_type_; // The network status connection for monitoring network status changes. MonitorNetworkConnection network_status_connection_; // The ethernet network. EthernetNetwork ethernet_; // The list of available wifi networks. WifiNetworkVector wifi_networks_; // The current connected (or connecting) wifi network. WifiNetwork wifi_; // The remembered wifi networks. WifiNetworkVector remembered_wifi_networks_; // The list of available cellular networks. CellularNetworkVector cellular_networks_; // The current connected (or connecting) cellular network. CellularNetwork cellular_; // The remembered cellular networks. CellularNetworkVector remembered_cellular_networks_; // The current available network devices. Bitwise flag of ConnectionTypes. int available_devices_; // The current enabled network devices. Bitwise flag of ConnectionTypes. int enabled_devices_; // The current connected network devices. Bitwise flag of ConnectionTypes. int connected_devices_; bool offline_mode_; DISALLOW_COPY_AND_ASSIGN(NetworkLibraryImpl); }; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_