| mukesh agrawal | 8a3188d | 2011-12-01 20:56:44 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be | 
 | 3 | // found in the LICENSE file. | 
 | 4 |  | 
| Chris Masone | 2b10554 | 2011-06-22 10:58:09 -0700 | [diff] [blame] | 5 | #include "shill/device.h" | 
 | 6 |  | 
| mukesh agrawal | 5c4dd0b | 2011-09-14 13:53:14 -0700 | [diff] [blame] | 7 | #include <netinet/in.h> | 
 | 8 | #include <linux/if.h>  // Needs definitions from netinet/in.h | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 9 | #include <stdio.h> | 
| mukesh agrawal | 5c4dd0b | 2011-09-14 13:53:14 -0700 | [diff] [blame] | 10 | #include <time.h> | 
| Chris Masone | ee929b7 | 2011-05-10 10:02:18 -0700 | [diff] [blame] | 11 |  | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 12 | #include <string> | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 13 | #include <vector> | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 14 |  | 
| Eric Shienbrood | 3e20a23 | 2012-02-16 11:35:56 -0500 | [diff] [blame] | 15 | #include <base/bind.h> | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 16 | #include <base/file_util.h> | 
| Chris Masone | 487b8bf | 2011-05-13 16:27:57 -0700 | [diff] [blame] | 17 | #include <base/memory/ref_counted.h> | 
| Ben Chan | a0ddf46 | 2014-02-06 11:32:42 -0800 | [diff] [blame] | 18 | #include <base/strings/stringprintf.h> | 
| Chris Masone | 3bd3c8c | 2011-06-13 08:20:26 -0700 | [diff] [blame] | 19 | #include <chromeos/dbus/service_constants.h> | 
| Chris Masone | ee929b7 | 2011-05-10 10:02:18 -0700 | [diff] [blame] | 20 |  | 
| Arman Uguray | f84a424 | 2013-04-09 20:01:07 -0700 | [diff] [blame] | 21 | #include "shill/async_connection.h" | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 22 | #include "shill/connection.h" | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 23 | #include "shill/control_interface.h" | 
| Chris Masone | d7732e4 | 2011-05-20 11:08:56 -0700 | [diff] [blame] | 24 | #include "shill/device_dbus_adaptor.h" | 
| Chris Masone | 2b10554 | 2011-06-22 10:58:09 -0700 | [diff] [blame] | 25 | #include "shill/dhcp_config.h" | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 26 | #include "shill/dhcp_provider.h" | 
| Arman Uguray | f84a424 | 2013-04-09 20:01:07 -0700 | [diff] [blame] | 27 | #include "shill/dns_client.h" | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 28 | #include "shill/dns_client_factory.h" | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 29 | #include "shill/error.h" | 
| Paul Stewart | 26b327e | 2011-10-19 11:38:09 -0700 | [diff] [blame] | 30 | #include "shill/event_dispatcher.h" | 
| Gaurav Shah | 6d2c72d | 2012-10-16 16:30:44 -0700 | [diff] [blame] | 31 | #include "shill/geolocation_info.h" | 
| Paul Stewart | f65320c | 2011-10-13 14:34:52 -0700 | [diff] [blame] | 32 | #include "shill/http_proxy.h" | 
| Arman Uguray | f84a424 | 2013-04-09 20:01:07 -0700 | [diff] [blame] | 33 | #include "shill/ip_address.h" | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 34 | #include "shill/link_monitor.h" | 
| Christopher Wiley | b691efd | 2012-08-09 13:51:51 -0700 | [diff] [blame] | 35 | #include "shill/logging.h" | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 36 | #include "shill/manager.h" | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 37 | #include "shill/metrics.h" | 
| Chris Masone | 95207da | 2011-06-29 16:50:49 -0700 | [diff] [blame] | 38 | #include "shill/property_accessor.h" | 
| Chris Masone | 2b10554 | 2011-06-22 10:58:09 -0700 | [diff] [blame] | 39 | #include "shill/refptr_types.h" | 
| Paul Stewart | c39f113 | 2011-06-22 12:02:28 -0700 | [diff] [blame] | 40 | #include "shill/rtnl_handler.h" | 
| Chris Masone | 2b10554 | 2011-06-22 10:58:09 -0700 | [diff] [blame] | 41 | #include "shill/service.h" | 
| Arman Uguray | f84a424 | 2013-04-09 20:01:07 -0700 | [diff] [blame] | 42 | #include "shill/socket_info_reader.h" | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 43 | #include "shill/store_interface.h" | 
| Gaurav Shah | 435de2c | 2011-11-17 19:01:07 -0800 | [diff] [blame] | 44 | #include "shill/technology.h" | 
| Paul Stewart | fa11e28 | 2013-12-02 22:04:25 -0800 | [diff] [blame] | 45 | #include "shill/tethering.h" | 
| Peter Qiu | dc335f8 | 2014-05-15 10:33:17 -0700 | [diff] [blame] | 46 | #include "shill/traffic_monitor.h" | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 47 |  | 
| Eric Shienbrood | 3e20a23 | 2012-02-16 11:35:56 -0500 | [diff] [blame] | 48 | using base::Bind; | 
| Albert Chaulk | 0e1cdea | 2013-02-27 15:32:55 -0800 | [diff] [blame] | 49 | using base::FilePath; | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 50 | using base::StringPrintf; | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 51 | using std::string; | 
 | 52 | using std::vector; | 
 | 53 |  | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 54 | namespace shill { | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 55 |  | 
 | 56 | // static | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 57 | const char Device::kIPFlagTemplate[] = "/proc/sys/net/%s/conf/%s/%s"; | 
 | 58 | // static | 
 | 59 | const char Device::kIPFlagVersion4[] = "ipv4"; | 
 | 60 | // static | 
 | 61 | const char Device::kIPFlagVersion6[] = "ipv6"; | 
 | 62 | // static | 
 | 63 | const char Device::kIPFlagDisableIPv6[] = "disable_ipv6"; | 
 | 64 | // static | 
 | 65 | const char Device::kIPFlagUseTempAddr[] = "use_tempaddr"; | 
 | 66 | // static | 
 | 67 | const char Device::kIPFlagUseTempAddrUsedAndDefault[] = "2"; | 
| Paul Stewart | c8f4bef | 2011-12-13 09:45:51 -0800 | [diff] [blame] | 68 | // static | 
 | 69 | const char Device::kIPFlagReversePathFilter[] = "rp_filter"; | 
 | 70 | // static | 
 | 71 | const char Device::kIPFlagReversePathFilterEnabled[] = "1"; | 
 | 72 | // static | 
 | 73 | const char Device::kIPFlagReversePathFilterLooseMode[] = "2"; | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 74 | // static | 
| Prathmesh Prabhu | ba99b59 | 2013-04-17 15:13:14 -0700 | [diff] [blame] | 75 | const char Device::kStoragePowered[] = "Powered"; | 
 | 76 | // static | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 77 | const char Device::kStorageReceiveByteCount[] = "ReceiveByteCount"; | 
 | 78 | // static | 
 | 79 | const char Device::kStorageTransmitByteCount[] = "TransmitByteCount"; | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 80 | // static | 
 | 81 | const char Device::kFallbackDnsTestHostname[] = "www.gstatic.com"; | 
 | 82 | // static | 
 | 83 | const char* Device::kFallbackDnsServers[] = { | 
 | 84 |     "8.8.8.8", | 
 | 85 |     "8.8.8.4" | 
 | 86 | }; | 
 | 87 |  | 
 | 88 | // static | 
 | 89 | const int Device::kDNSTimeoutMilliseconds = 5000; | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 90 |  | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 91 | Device::Device(ControlInterface *control_interface, | 
| Paul Stewart | b50f0b9 | 2011-05-16 16:31:42 -0700 | [diff] [blame] | 92 |                EventDispatcher *dispatcher, | 
| Thieu Le | 3426c8f | 2012-01-11 17:35:11 -0800 | [diff] [blame] | 93 |                Metrics *metrics, | 
| Paul Stewart | f1ce5d2 | 2011-05-19 13:10:20 -0700 | [diff] [blame] | 94 |                Manager *manager, | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 95 |                const string &link_name, | 
| Chris Masone | 626719f | 2011-08-18 16:58:48 -0700 | [diff] [blame] | 96 |                const string &address, | 
| Gaurav Shah | 435de2c | 2011-11-17 19:01:07 -0800 | [diff] [blame] | 97 |                int interface_index, | 
 | 98 |                Technology::Identifier technology) | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 99 |     : enabled_(false), | 
 | 100 |       enabled_persistent_(true), | 
 | 101 |       enabled_pending_(enabled_), | 
| Chris Masone | b925cc8 | 2011-06-22 15:39:57 -0700 | [diff] [blame] | 102 |       reconnect_(true), | 
| Chris Masone | 626719f | 2011-08-18 16:58:48 -0700 | [diff] [blame] | 103 |       hardware_address_(address), | 
| mukesh agrawal | f60e406 | 2011-05-27 13:13:41 -0700 | [diff] [blame] | 104 |       interface_index_(interface_index), | 
 | 105 |       running_(false), | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 106 |       link_name_(link_name), | 
| Chris Masone | 19e3040 | 2011-07-19 15:48:47 -0700 | [diff] [blame] | 107 |       unique_id_(link_name), | 
| Darin Petkov | d966195 | 2011-08-03 16:25:42 -0700 | [diff] [blame] | 108 |       control_interface_(control_interface), | 
 | 109 |       dispatcher_(dispatcher), | 
| Thieu Le | 3426c8f | 2012-01-11 17:35:11 -0800 | [diff] [blame] | 110 |       metrics_(metrics), | 
| Chris Masone | 7df0c67 | 2011-07-15 10:24:54 -0700 | [diff] [blame] | 111 |       manager_(manager), | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 112 |       weak_ptr_factory_(this), | 
| Darin Petkov | 77cb681 | 2011-08-15 16:19:41 -0700 | [diff] [blame] | 113 |       adaptor_(control_interface->CreateDeviceAdaptor(this)), | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 114 |       dns_client_factory_(DNSClientFactory::GetInstance()), | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 115 |       portal_detector_callback_(Bind(&Device::PortalDetectorCallback, | 
 | 116 |                                      weak_ptr_factory_.GetWeakPtr())), | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 117 |       dns_client_callback_(Bind(&Device::DNSClientCallback, | 
 | 118 |                                 weak_ptr_factory_.GetWeakPtr())), | 
| Gaurav Shah | 435de2c | 2011-11-17 19:01:07 -0800 | [diff] [blame] | 119 |       technology_(technology), | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 120 |       portal_attempts_to_online_(0), | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 121 |       receive_byte_offset_(0), | 
 | 122 |       transmit_byte_offset_(0), | 
| mukesh agrawal | 5c4dd0b | 2011-09-14 13:53:14 -0700 | [diff] [blame] | 123 |       dhcp_provider_(DHCPProvider::GetInstance()), | 
 | 124 |       rtnl_handler_(RTNLHandler::GetInstance()) { | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 125 |   store_.RegisterConstString(kAddressProperty, &hardware_address_); | 
| Chris Masone | 4d42df8 | 2011-07-02 17:09:39 -0700 | [diff] [blame] | 126 |  | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 127 |   // kBgscanMethodProperty: Registered in WiFi | 
 | 128 |   // kBgscanShortIntervalProperty: Registered in WiFi | 
 | 129 |   // kBgscanSignalThresholdProperty: Registered in WiFi | 
| Chris Masone | 4d42df8 | 2011-07-02 17:09:39 -0700 | [diff] [blame] | 130 |  | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 131 |   // kCellularAllowRoamingProperty: Registered in Cellular | 
 | 132 |   // kCarrierProperty: Registered in Cellular | 
 | 133 |   // kEsnProperty: Registered in Cellular | 
 | 134 |   // kHomeProviderProperty: Registered in Cellular | 
 | 135 |   // kImeiProperty: Registered in Cellular | 
 | 136 |   // kIccidProperty: Registered in Cellular | 
 | 137 |   // kImsiProperty: Registered in Cellular | 
 | 138 |   // kManufacturerProperty: Registered in Cellular | 
 | 139 |   // kMdnProperty: Registered in Cellular | 
 | 140 |   // kMeidProperty: Registered in Cellular | 
 | 141 |   // kMinProperty: Registered in Cellular | 
 | 142 |   // kModelIDProperty: Registered in Cellular | 
 | 143 |   // kFirmwareRevisionProperty: Registered in Cellular | 
 | 144 |   // kHardwareRevisionProperty: Registered in Cellular | 
 | 145 |   // kPRLVersionProperty: Registered in Cellular | 
 | 146 |   // kSIMLockStatusProperty: Registered in Cellular | 
 | 147 |   // kFoundNetworksProperty: Registered in Cellular | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 148 |   // kDBusObjectProperty: Register in Cellular | 
| Chris Masone | 4d42df8 | 2011-07-02 17:09:39 -0700 | [diff] [blame] | 149 |  | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 150 |   store_.RegisterConstString(kInterfaceProperty, &link_name_); | 
 | 151 |   HelpRegisterConstDerivedRpcIdentifiers(kIPConfigsProperty, | 
| Jason Glasgow | 08afdff | 2012-04-03 10:22:26 -0400 | [diff] [blame] | 152 |                                          &Device::AvailableIPConfigs); | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 153 |   store_.RegisterConstString(kNameProperty, &link_name_); | 
 | 154 |   store_.RegisterConstBool(kPoweredProperty, &enabled_); | 
 | 155 |   HelpRegisterConstDerivedString(kTypeProperty, | 
| mukesh agrawal | bebf1b8 | 2013-04-23 15:06:33 -0700 | [diff] [blame] | 156 |                                  &Device::GetTechnologyString); | 
| Ben Chan | 39a7beb | 2013-09-21 11:28:00 -0700 | [diff] [blame] | 157 |   HelpRegisterConstDerivedUint64(kLinkMonitorResponseTimeProperty, | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 158 |                                  &Device::GetLinkMonitorResponseTime); | 
| Jason Glasgow | b579005 | 2012-01-27 01:03:52 -0500 | [diff] [blame] | 159 |  | 
| Chris Masone | b925cc8 | 2011-06-22 15:39:57 -0700 | [diff] [blame] | 160 |   // TODO(cmasone): Chrome doesn't use this...does anyone? | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 161 |   // store_.RegisterConstBool(kReconnectProperty, &reconnect_); | 
| Chris Masone | b925cc8 | 2011-06-22 15:39:57 -0700 | [diff] [blame] | 162 |  | 
| Chris Masone | 4e85161 | 2011-07-01 10:46:53 -0700 | [diff] [blame] | 163 |   // TODO(cmasone): Figure out what shill concept maps to flimflam's "Network". | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 164 |   // known_properties_.push_back(kNetworksProperty); | 
| Chris Masone | b925cc8 | 2011-06-22 15:39:57 -0700 | [diff] [blame] | 165 |  | 
| Wade Guthrie | 227c774 | 2013-10-10 11:06:33 -0700 | [diff] [blame] | 166 |   // kRoamThresholdProperty: Registered in WiFi | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 167 |   // kScanningProperty: Registered in WiFi, Cellular | 
 | 168 |   // kScanIntervalProperty: Registered in WiFi, Cellular | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 169 |  | 
 | 170 |   if (manager_ && manager_->device_info()) {  // Unit tests may not have these. | 
 | 171 |     manager_->device_info()->GetByteCounts( | 
 | 172 |         interface_index_, &receive_byte_offset_, &transmit_byte_offset_); | 
| Ben Chan | 39a7beb | 2013-09-21 11:28:00 -0700 | [diff] [blame] | 173 |     HelpRegisterConstDerivedUint64(kReceiveByteCountProperty, | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 174 |                                    &Device::GetReceiveByteCountProperty); | 
| Ben Chan | 39a7beb | 2013-09-21 11:28:00 -0700 | [diff] [blame] | 175 |     HelpRegisterConstDerivedUint64(kTransmitByteCountProperty, | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 176 |                                    &Device::GetTransmitByteCountProperty); | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 177 |   } | 
 | 178 |  | 
| Darin Petkov | a0a0efe | 2012-06-27 12:50:01 +0200 | [diff] [blame] | 179 |   LOG(INFO) << "Device created: " << link_name_ | 
 | 180 |             << " index " << interface_index_; | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 181 | } | 
 | 182 |  | 
 | 183 | Device::~Device() { | 
| Darin Petkov | a0a0efe | 2012-06-27 12:50:01 +0200 | [diff] [blame] | 184 |   LOG(INFO) << "Device destructed: " << link_name_ | 
 | 185 |             << " index " << interface_index_; | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 186 | } | 
 | 187 |  | 
| Paul Stewart | f1ce5d2 | 2011-05-19 13:10:20 -0700 | [diff] [blame] | 188 | void Device::LinkEvent(unsigned flags, unsigned change) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 189 |   SLOG(Device, 2) << "Device " << link_name_ | 
 | 190 |                   << std::showbase << std::hex | 
 | 191 |                   << " flags " << flags << " changed " << change | 
 | 192 |                   << std::dec << std::noshowbase; | 
| Paul Stewart | f1ce5d2 | 2011-05-19 13:10:20 -0700 | [diff] [blame] | 193 | } | 
 | 194 |  | 
| Wade Guthrie | 4823f4f | 2013-07-25 10:03:03 -0700 | [diff] [blame] | 195 | void Device::Scan(ScanType scan_type, Error *error, const string &reason) { | 
 | 196 |   SLOG(Device, 2) << __func__ << " [Device] on " << link_name() << " from " | 
 | 197 |                   << reason; | 
| Paul Stewart | be00517 | 2011-11-02 18:10:29 -0700 | [diff] [blame] | 198 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 199 |                         "Device doesn't support scan."); | 
| Paul Stewart | f1ce5d2 | 2011-05-19 13:10:20 -0700 | [diff] [blame] | 200 | } | 
 | 201 |  | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 202 | void Device::RegisterOnNetwork(const std::string &/*network_id*/, Error *error, | 
 | 203 |                                  const ResultCallback &/*callback*/) { | 
 | 204 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
| Paul Stewart | be00517 | 2011-11-02 18:10:29 -0700 | [diff] [blame] | 205 |                         "Device doesn't support network registration."); | 
| Darin Petkov | 9ae310f | 2011-08-30 15:41:13 -0700 | [diff] [blame] | 206 | } | 
 | 207 |  | 
| Darin Petkov | c64fe5e | 2012-01-11 12:46:13 +0100 | [diff] [blame] | 208 | void Device::RequirePIN( | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 209 |     const string &/*pin*/, bool /*require*/, | 
 | 210 |     Error *error, const ResultCallback &/*callback*/) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 211 |   SLOG(Device, 2) << __func__; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 212 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 213 |                         "Device doesn't support RequirePIN."); | 
| Darin Petkov | e42e101 | 2011-08-31 12:35:04 -0700 | [diff] [blame] | 214 | } | 
 | 215 |  | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 216 | void Device::EnterPIN(const string &/*pin*/, | 
 | 217 |                       Error *error, const ResultCallback &/*callback*/) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 218 |   SLOG(Device, 2) << __func__; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 219 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 220 |                         "Device doesn't support EnterPIN."); | 
| Darin Petkov | e42e101 | 2011-08-31 12:35:04 -0700 | [diff] [blame] | 221 | } | 
 | 222 |  | 
| mukesh agrawal | 1830fa1 | 2011-09-26 14:31:40 -0700 | [diff] [blame] | 223 | void Device::UnblockPIN(const string &/*unblock_code*/, | 
 | 224 |                         const string &/*pin*/, | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 225 |                         Error *error, const ResultCallback &/*callback*/) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 226 |   SLOG(Device, 2) << __func__; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 227 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 228 |                         "Device doesn't support UnblockPIN."); | 
| Darin Petkov | e42e101 | 2011-08-31 12:35:04 -0700 | [diff] [blame] | 229 | } | 
 | 230 |  | 
| mukesh agrawal | 1830fa1 | 2011-09-26 14:31:40 -0700 | [diff] [blame] | 231 | void Device::ChangePIN(const string &/*old_pin*/, | 
 | 232 |                        const string &/*new_pin*/, | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 233 |                        Error *error, const ResultCallback &/*callback*/) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 234 |   SLOG(Device, 2) << __func__; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 235 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 236 |                         "Device doesn't support ChangePIN."); | 
| Darin Petkov | e42e101 | 2011-08-31 12:35:04 -0700 | [diff] [blame] | 237 | } | 
 | 238 |  | 
| Ben Chan | ad663e1 | 2013-01-08 01:58:47 -0800 | [diff] [blame] | 239 | void Device::Reset(Error *error, const ResultCallback &/*callback*/) { | 
 | 240 |   SLOG(Device, 2) << __func__; | 
 | 241 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 242 |                         "Device doesn't support Reset."); | 
 | 243 | } | 
 | 244 |  | 
| Darin Petkov | c37a9c4 | 2012-09-06 15:28:22 +0200 | [diff] [blame] | 245 | void Device::SetCarrier(const string &/*carrier*/, | 
 | 246 |                         Error *error, const ResultCallback &/*callback*/) { | 
 | 247 |   SLOG(Device, 2) << __func__; | 
 | 248 |   Error::PopulateAndLog(error, Error::kNotSupported, | 
 | 249 |                         "Device doesn't support SetCarrier."); | 
 | 250 | } | 
 | 251 |  | 
| Ben Chan | bcc6e01 | 2013-11-04 14:28:37 -0800 | [diff] [blame] | 252 | bool Device::IsIPv6Allowed() const { | 
 | 253 |   return true; | 
 | 254 | } | 
 | 255 |  | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 256 | void Device::DisableIPv6() { | 
| Ben Chan | bcc6e01 | 2013-11-04 14:28:37 -0800 | [diff] [blame] | 257 |   SLOG(Device, 2) << __func__; | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 258 |   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "1"); | 
 | 259 | } | 
 | 260 |  | 
 | 261 | void Device::EnableIPv6() { | 
| Ben Chan | bcc6e01 | 2013-11-04 14:28:37 -0800 | [diff] [blame] | 262 |   SLOG(Device, 2) << __func__; | 
 | 263 |   if (!IsIPv6Allowed()) { | 
 | 264 |     LOG(INFO) << "Skip enabling IPv6 on " << link_name_ | 
 | 265 |               << " as it is not allowed."; | 
 | 266 |     return; | 
 | 267 |   } | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 268 |   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagDisableIPv6, "0"); | 
 | 269 | } | 
 | 270 |  | 
 | 271 | void Device::EnableIPv6Privacy() { | 
 | 272 |   SetIPFlag(IPAddress::kFamilyIPv6, kIPFlagUseTempAddr, | 
 | 273 |             kIPFlagUseTempAddrUsedAndDefault); | 
 | 274 | } | 
 | 275 |  | 
| Paul Stewart | c8f4bef | 2011-12-13 09:45:51 -0800 | [diff] [blame] | 276 | void Device::DisableReversePathFilter() { | 
 | 277 |   // TODO(pstew): Current kernel doesn't offer reverse-path filtering flag | 
| Paul Stewart | ee6b3d7 | 2013-07-12 16:07:51 -0700 | [diff] [blame] | 278 |   // for IPv6.  crbug.com/207193 | 
| Paul Stewart | c8f4bef | 2011-12-13 09:45:51 -0800 | [diff] [blame] | 279 |   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter, | 
 | 280 |             kIPFlagReversePathFilterLooseMode); | 
 | 281 | } | 
 | 282 |  | 
 | 283 | void Device::EnableReversePathFilter() { | 
 | 284 |   SetIPFlag(IPAddress::kFamilyIPv4, kIPFlagReversePathFilter, | 
 | 285 |             kIPFlagReversePathFilterEnabled); | 
 | 286 | } | 
 | 287 |  | 
| Gaurav Shah | 435de2c | 2011-11-17 19:01:07 -0800 | [diff] [blame] | 288 | bool Device::IsConnected() const { | 
 | 289 |   if (selected_service_) | 
 | 290 |     return selected_service_->IsConnected(); | 
 | 291 |   return false; | 
 | 292 | } | 
 | 293 |  | 
| Paul Stewart | d215af6 | 2012-04-24 23:25:50 -0700 | [diff] [blame] | 294 | bool Device::IsConnectedToService(const ServiceRefPtr &service) const { | 
 | 295 |   return service == selected_service_ && IsConnected(); | 
 | 296 | } | 
 | 297 |  | 
| Paul Stewart | fa11e28 | 2013-12-02 22:04:25 -0800 | [diff] [blame] | 298 | bool Device::IsConnectedViaTether() const { | 
 | 299 |   return | 
 | 300 |       ipconfig_.get() && | 
 | 301 |       ipconfig_->properties().vendor_encapsulated_options == | 
 | 302 |           Tethering::kAndroidVendorEncapsulatedOptions; | 
 | 303 | } | 
 | 304 |  | 
| mukesh agrawal | f6b3209 | 2013-04-10 15:49:55 -0700 | [diff] [blame] | 305 | string Device::GetRpcIdentifier() const { | 
| Chris Masone | 27c4aa5 | 2011-07-02 13:10:14 -0700 | [diff] [blame] | 306 |   return adaptor_->GetRpcIdentifier(); | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 307 | } | 
 | 308 |  | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 309 | string Device::GetStorageIdentifier() { | 
 | 310 |   string id = GetRpcIdentifier(); | 
 | 311 |   ControlInterface::RpcIdToStorageId(&id); | 
| Chris Masone | 626719f | 2011-08-18 16:58:48 -0700 | [diff] [blame] | 312 |   size_t needle = id.find('_'); | 
| Chris Masone | 34af218 | 2011-08-22 11:59:36 -0700 | [diff] [blame] | 313 |   DLOG_IF(ERROR, needle == string::npos) << "No _ in storage id?!?!"; | 
| Chris Masone | 626719f | 2011-08-18 16:58:48 -0700 | [diff] [blame] | 314 |   id.replace(id.begin() + needle + 1, id.end(), hardware_address_); | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 315 |   return id; | 
 | 316 | } | 
 | 317 |  | 
| Gaurav Shah | 6d2c72d | 2012-10-16 16:30:44 -0700 | [diff] [blame] | 318 | vector<GeolocationInfo> Device::GetGeolocationObjects() const { | 
 | 319 |   return vector<GeolocationInfo>(); | 
| Wade Guthrie | 227c774 | 2013-10-10 11:06:33 -0700 | [diff] [blame] | 320 | } | 
| Gaurav Shah | 6d2c72d | 2012-10-16 16:30:44 -0700 | [diff] [blame] | 321 |  | 
| Jason Glasgow | b579005 | 2012-01-27 01:03:52 -0500 | [diff] [blame] | 322 | string Device::GetTechnologyString(Error */*error*/) { | 
 | 323 |   return Technology::NameFromIdentifier(technology()); | 
 | 324 | } | 
 | 325 |  | 
| Chris Masone | 19e3040 | 2011-07-19 15:48:47 -0700 | [diff] [blame] | 326 | const string& Device::FriendlyName() const { | 
| Chris Masone | 7df0c67 | 2011-07-15 10:24:54 -0700 | [diff] [blame] | 327 |   return link_name_; | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 328 | } | 
 | 329 |  | 
| Chris Masone | 19e3040 | 2011-07-19 15:48:47 -0700 | [diff] [blame] | 330 | const string& Device::UniqueName() const { | 
 | 331 |   return unique_id_; | 
 | 332 | } | 
 | 333 |  | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 334 | bool Device::Load(StoreInterface *storage) { | 
 | 335 |   const string id = GetStorageIdentifier(); | 
 | 336 |   if (!storage->ContainsGroup(id)) { | 
 | 337 |     LOG(WARNING) << "Device is not available in the persistent store: " << id; | 
 | 338 |     return false; | 
 | 339 |   } | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 340 |   enabled_persistent_ = true; | 
 | 341 |   storage->GetBool(id, kStoragePowered, &enabled_persistent_); | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 342 |   uint64 rx_byte_count = 0, tx_byte_count = 0; | 
 | 343 |  | 
 | 344 |   manager_->device_info()->GetByteCounts( | 
 | 345 |       interface_index_, &rx_byte_count, &tx_byte_count); | 
 | 346 |   // If there is a byte-count present in the profile, the return value | 
 | 347 |   // of Device::Get*ByteCount() should be the this stored value plus | 
 | 348 |   // whatever additional bytes we receive since time-of-load.  We | 
 | 349 |   // accomplish this by the subtractions below, which can validly | 
 | 350 |   // roll over "negative" in the subtractions below and in Get*ByteCount. | 
 | 351 |   uint64 profile_byte_count; | 
 | 352 |   if (storage->GetUint64(id, kStorageReceiveByteCount, &profile_byte_count)) { | 
 | 353 |     receive_byte_offset_ = rx_byte_count - profile_byte_count; | 
 | 354 |   } | 
 | 355 |   if (storage->GetUint64(id, kStorageTransmitByteCount, &profile_byte_count)) { | 
 | 356 |     transmit_byte_offset_ = tx_byte_count - profile_byte_count; | 
 | 357 |   } | 
 | 358 |  | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 359 |   return true; | 
 | 360 | } | 
 | 361 |  | 
 | 362 | bool Device::Save(StoreInterface *storage) { | 
 | 363 |   const string id = GetStorageIdentifier(); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 364 |   storage->SetBool(id, kStoragePowered, enabled_persistent_); | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 365 |   storage->SetUint64(id, kStorageReceiveByteCount, GetReceiveByteCount()); | 
 | 366 |   storage->SetUint64(id, kStorageTransmitByteCount, GetTransmitByteCount()); | 
| Chris Masone | 5dec5f4 | 2011-07-22 14:07:55 -0700 | [diff] [blame] | 367 |   return true; | 
 | 368 | } | 
 | 369 |  | 
| mukesh agrawal | 784566d | 2012-08-08 18:32:58 -0700 | [diff] [blame] | 370 | void Device::OnBeforeSuspend() { | 
 | 371 |   // Nothing to be done in the general case. | 
 | 372 | } | 
 | 373 |  | 
 | 374 | void Device::OnAfterResume() { | 
 | 375 |   if (ipconfig_) { | 
 | 376 |     SLOG(Device, 3) << "Renewing IP address on resume."; | 
 | 377 |     ipconfig_->RenewIP(); | 
 | 378 |   } | 
| mukesh agrawal | bb2231c | 2013-07-17 16:32:24 -0700 | [diff] [blame] | 379 |   if (link_monitor_) { | 
 | 380 |     SLOG(Device, 3) << "Informing Link Monitor of resume."; | 
 | 381 |     link_monitor_->OnAfterResume(); | 
 | 382 |   } | 
| mukesh agrawal | 784566d | 2012-08-08 18:32:58 -0700 | [diff] [blame] | 383 | } | 
 | 384 |  | 
| Darin Petkov | 2b8e44e | 2012-06-25 15:13:26 +0200 | [diff] [blame] | 385 | void Device::DropConnection() { | 
 | 386 |   SLOG(Device, 2) << __func__; | 
 | 387 |   DestroyIPConfig(); | 
 | 388 |   SelectService(NULL); | 
 | 389 | } | 
 | 390 |  | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 391 | void Device::DestroyIPConfig() { | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 392 |   DisableIPv6(); | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 393 |   if (ipconfig_.get()) { | 
| Paul Stewart | 217c61d | 2013-06-13 15:12:02 -0700 | [diff] [blame] | 394 |     ipconfig_->ReleaseIP(IPConfig::kReleaseReasonDisconnect); | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 395 |     ipconfig_ = NULL; | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 396 |     UpdateIPConfigsProperty(); | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 397 |   } | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 398 |   DestroyConnection(); | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 399 | } | 
 | 400 |  | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 401 | void Device::OnIPv6AddressChanged() { | 
 | 402 |   IPAddress address(IPAddress::kFamilyIPv6); | 
 | 403 |   if (!manager_->device_info()->GetPrimaryIPv6Address( | 
 | 404 |           interface_index_, &address)) { | 
 | 405 |     if (ip6config_) { | 
 | 406 |       ip6config_ = NULL; | 
 | 407 |       UpdateIPConfigsProperty(); | 
 | 408 |     } | 
 | 409 |     return; | 
 | 410 |   } | 
 | 411 |  | 
 | 412 |   IPConfig::Properties properties; | 
 | 413 |   if (!address.IntoString(&properties.address)) { | 
 | 414 |     LOG(ERROR) << "Unable to convert IPv6 address into a string!"; | 
 | 415 |     return; | 
 | 416 |   } | 
 | 417 |   properties.subnet_prefix = address.prefix(); | 
 | 418 |  | 
 | 419 |   if (!ip6config_) { | 
 | 420 |     ip6config_ = new IPConfig(control_interface_, link_name_); | 
 | 421 |   } else if (properties.address == ip6config_->properties().address && | 
 | 422 |              properties.subnet_prefix == | 
 | 423 |                  ip6config_->properties().subnet_prefix) { | 
 | 424 |     SLOG(Device, 2) << __func__ << " primary address for " | 
 | 425 |                     << link_name_ << " is unchanged."; | 
 | 426 |     return; | 
 | 427 |   } | 
 | 428 |  | 
 | 429 |   properties.address_family = IPAddress::kFamilyIPv6; | 
 | 430 |   properties.method = kTypeIPv6; | 
 | 431 |   ip6config_->set_properties(properties); | 
 | 432 |   UpdateIPConfigsProperty(); | 
 | 433 | } | 
 | 434 |  | 
| Arman Uguray | ed8e610 | 2012-11-29 14:47:20 -0800 | [diff] [blame] | 435 | bool Device::ShouldUseArpGateway() const { | 
 | 436 |   return false; | 
 | 437 | } | 
 | 438 |  | 
| Paul Stewart | 75a68b9 | 2013-10-24 10:50:27 -0700 | [diff] [blame] | 439 | bool Device::ShouldUseMinimalDHCPConfig() const { | 
| Paul Stewart | dded007 | 2013-10-24 12:38:54 -0700 | [diff] [blame] | 440 |   return selected_service_ && selected_service_->ShouldUseMinimalDHCPConfig(); | 
| Paul Stewart | 75a68b9 | 2013-10-24 10:50:27 -0700 | [diff] [blame] | 441 | } | 
 | 442 |  | 
| Paul Stewart | 316acef | 2014-05-29 18:40:48 -0700 | [diff] [blame] | 443 | bool Device::IsUsingStaticIP() const { | 
 | 444 |   if (!selected_service_) { | 
 | 445 |     return false; | 
 | 446 |   } | 
 | 447 |   return selected_service_->HasStaticIPAddress(); | 
 | 448 | } | 
 | 449 |  | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 450 | bool Device::AcquireIPConfig() { | 
| Paul Stewart | d408fdf | 2012-05-07 17:15:57 -0700 | [diff] [blame] | 451 |   return AcquireIPConfigWithLeaseName(string()); | 
 | 452 | } | 
 | 453 |  | 
 | 454 | bool Device::AcquireIPConfigWithLeaseName(const string &lease_name) { | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 455 |   DestroyIPConfig(); | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 456 |   EnableIPv6(); | 
| Arman Uguray | ed8e610 | 2012-11-29 14:47:20 -0800 | [diff] [blame] | 457 |   bool arp_gateway = manager_->GetArpGateway() && ShouldUseArpGateway(); | 
| Paul Stewart | d408fdf | 2012-05-07 17:15:57 -0700 | [diff] [blame] | 458 |   ipconfig_ = dhcp_provider_->CreateConfig(link_name_, | 
 | 459 |                                            manager_->GetHostName(), | 
 | 460 |                                            lease_name, | 
| Paul Stewart | 75a68b9 | 2013-10-24 10:50:27 -0700 | [diff] [blame] | 461 |                                            arp_gateway, | 
 | 462 |                                            ShouldUseMinimalDHCPConfig()); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 463 |   ipconfig_->RegisterUpdateCallback(Bind(&Device::OnIPConfigUpdated, | 
 | 464 |                                          weak_ptr_factory_.GetWeakPtr())); | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 465 |   ipconfig_->RegisterFailureCallback(Bind(&Device::OnIPConfigFailed, | 
 | 466 |                                           weak_ptr_factory_.GetWeakPtr())); | 
| Paul Stewart | 8223653 | 2013-12-10 15:33:11 -0800 | [diff] [blame] | 467 |   ipconfig_->RegisterRefreshCallback(Bind(&Device::OnIPConfigRefreshed, | 
 | 468 |                                           weak_ptr_factory_.GetWeakPtr())); | 
| Paul Stewart | 1f916e4 | 2013-12-23 09:52:54 -0800 | [diff] [blame] | 469 |   ipconfig_->RegisterExpireCallback(Bind(&Device::OnIPConfigExpired, | 
 | 470 |                                          weak_ptr_factory_.GetWeakPtr())); | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 471 |   dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask, | 
 | 472 |                              weak_ptr_factory_.GetWeakPtr())); | 
| Darin Petkov | afa6fc4 | 2011-06-21 16:21:08 -0700 | [diff] [blame] | 473 |   return ipconfig_->RequestIP(); | 
 | 474 | } | 
 | 475 |  | 
| Ben Chan | 539ab02 | 2014-02-03 16:34:57 -0800 | [diff] [blame] | 476 | void Device::AssignIPConfig(const IPConfig::Properties &properties) { | 
 | 477 |   DestroyIPConfig(); | 
 | 478 |   EnableIPv6(); | 
 | 479 |   ipconfig_ = new IPConfig(control_interface_, link_name_); | 
 | 480 |   ipconfig_->set_properties(properties); | 
 | 481 |   dispatcher_->PostTask(Bind(&Device::OnIPConfigUpdated, | 
 | 482 |                              weak_ptr_factory_.GetWeakPtr(), ipconfig_)); | 
 | 483 | } | 
 | 484 |  | 
| Albert Chaulk | 0e1cdea | 2013-02-27 15:32:55 -0800 | [diff] [blame] | 485 | void Device::DestroyIPConfigLease(const string &name) { | 
 | 486 |   dhcp_provider_->DestroyLease(name); | 
 | 487 | } | 
 | 488 |  | 
| mukesh agrawal | bebf1b8 | 2013-04-23 15:06:33 -0700 | [diff] [blame] | 489 | void Device::HelpRegisterConstDerivedString( | 
| Jason Glasgow | b579005 | 2012-01-27 01:03:52 -0500 | [diff] [blame] | 490 |     const string &name, | 
| mukesh agrawal | bebf1b8 | 2013-04-23 15:06:33 -0700 | [diff] [blame] | 491 |     string(Device::*get)(Error *error)) { | 
| Jason Glasgow | b579005 | 2012-01-27 01:03:52 -0500 | [diff] [blame] | 492 |   store_.RegisterDerivedString( | 
 | 493 |       name, | 
| mukesh agrawal | bebf1b8 | 2013-04-23 15:06:33 -0700 | [diff] [blame] | 494 |       StringAccessor(new CustomAccessor<Device, string>(this, get, NULL))); | 
| Chris Masone | 4e85161 | 2011-07-01 10:46:53 -0700 | [diff] [blame] | 495 | } | 
 | 496 |  | 
| Jason Glasgow | 08afdff | 2012-04-03 10:22:26 -0400 | [diff] [blame] | 497 | void Device::HelpRegisterConstDerivedRpcIdentifiers( | 
 | 498 |     const string &name, | 
 | 499 |     RpcIdentifiers(Device::*get)(Error *)) { | 
 | 500 |   store_.RegisterDerivedRpcIdentifiers( | 
 | 501 |       name, | 
 | 502 |       RpcIdentifiersAccessor( | 
 | 503 |           new CustomAccessor<Device, RpcIdentifiers>(this, get, NULL))); | 
 | 504 | } | 
 | 505 |  | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 506 | void Device::HelpRegisterConstDerivedUint64( | 
 | 507 |     const string &name, | 
 | 508 |     uint64(Device::*get)(Error *)) { | 
 | 509 |   store_.RegisterDerivedUint64( | 
 | 510 |       name, | 
 | 511 |       Uint64Accessor( | 
 | 512 |           new CustomAccessor<Device, uint64>(this, get, NULL))); | 
 | 513 | } | 
 | 514 |  | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 515 | void Device::ConfigureStaticIPTask() { | 
 | 516 |   SLOG(Device, 2) << __func__ << " selected_service " << selected_service_.get() | 
 | 517 |                   << " ipconfig " << ipconfig_.get(); | 
 | 518 |  | 
 | 519 |   if (!selected_service_ || !ipconfig_) { | 
 | 520 |     return; | 
 | 521 |   } | 
 | 522 |  | 
| Paul Stewart | 316acef | 2014-05-29 18:40:48 -0700 | [diff] [blame] | 523 |   if (IsUsingStaticIP()) { | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 524 |     SLOG(Device, 2) << __func__ << " " << " configuring static IP parameters."; | 
 | 525 |     // If the parameters contain an IP address, apply them now and bring | 
 | 526 |     // the interface up.  When DHCP information arrives, it will supplement | 
 | 527 |     // the static information. | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 528 |     OnIPConfigUpdated(ipconfig_); | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 529 |   } else { | 
| Paul Stewart | 8223653 | 2013-12-10 15:33:11 -0800 | [diff] [blame] | 530 |     // Either |ipconfig_| has just been created in AcquireIPConfig() or | 
 | 531 |     // we're being called by OnIPConfigRefreshed().  In either case a | 
 | 532 |     // DHCP client has been started, and will take care of calling | 
 | 533 |     // OnIPConfigUpdated() when it completes. | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 534 |     SLOG(Device, 2) << __func__ << " " << " no static IP address."; | 
 | 535 |   } | 
 | 536 | } | 
 | 537 |  | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 538 | void Device::OnIPConfigUpdated(const IPConfigRefPtr &ipconfig) { | 
 | 539 |   SLOG(Device, 2) << __func__; | 
 | 540 |   CreateConnection(); | 
 | 541 |   if (selected_service_) { | 
 | 542 |     ipconfig->ApplyStaticIPParameters( | 
 | 543 |         selected_service_->mutable_static_ip_parameters()); | 
| Paul Stewart | 316acef | 2014-05-29 18:40:48 -0700 | [diff] [blame] | 544 |     if (IsUsingStaticIP()) { | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 545 |       // If we are using a statically configured IP address instead | 
 | 546 |       // of a leased IP address, release any acquired lease so it may | 
 | 547 |       // be used by others.  This allows us to merge other non-leased | 
 | 548 |       // parameters (like DNS) when they're available from a DHCP server | 
 | 549 |       // and not overridden by static parameters, but at the same time | 
 | 550 |       // we avoid taking up a dynamic IP address the DHCP server could | 
 | 551 |       // assign to someone else who might actually use it. | 
 | 552 |       ipconfig->ReleaseIP(IPConfig::kReleaseReasonStaticIP); | 
| Paul Stewart | 1062d9d | 2012-04-27 10:42:27 -0700 | [diff] [blame] | 553 |     } | 
| Paul Stewart | c39f113 | 2011-06-22 12:02:28 -0700 | [diff] [blame] | 554 |   } | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 555 |   connection_->UpdateFromIPConfig(ipconfig); | 
 | 556 |   // SetConnection must occur after the UpdateFromIPConfig so the | 
 | 557 |   // service can use the values derived from the connection. | 
 | 558 |   if (selected_service_) { | 
 | 559 |     selected_service_->OnDHCPSuccess(); | 
 | 560 |     selected_service_->SetConnection(connection_); | 
 | 561 |   } | 
 | 562 |   // The service state change needs to happen last, so that at the | 
 | 563 |   // time we report the state change to the manager, the service | 
 | 564 |   // has its connection. | 
 | 565 |   SetServiceState(Service::kStateConnected); | 
 | 566 |   OnConnected(); | 
 | 567 |   portal_attempts_to_online_ = 0; | 
 | 568 |   // Subtle: Start portal detection after transitioning the service | 
 | 569 |   // to the Connected state because this call may immediately transition | 
 | 570 |   // to the Online state. | 
 | 571 |   if (selected_service_) { | 
 | 572 |     StartPortalDetection(); | 
 | 573 |   } | 
 | 574 |   StartLinkMonitor(); | 
| Peter Qiu | dc335f8 | 2014-05-15 10:33:17 -0700 | [diff] [blame] | 575 |   StartTrafficMonitor(); | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 576 |   UpdateIPConfigsProperty(); | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 577 | } | 
 | 578 |  | 
 | 579 | void Device::OnIPConfigFailed(const IPConfigRefPtr &ipconfig) { | 
 | 580 |   SLOG(Device, 2) << __func__; | 
 | 581 |   // TODO(pstew): This logic gets yet more complex when multiple | 
 | 582 |   // IPConfig types are run in parallel (e.g. DHCP and DHCP6) | 
 | 583 |   if (selected_service_) { | 
 | 584 |     selected_service_->OnDHCPFailure(); | 
 | 585 |  | 
| Paul Stewart | 316acef | 2014-05-29 18:40:48 -0700 | [diff] [blame] | 586 |     if (IsUsingStaticIP()) { | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 587 |       // Consider three cases: | 
 | 588 |       // | 
 | 589 |       // 1. We're here because DHCP failed while starting up. There | 
 | 590 |       //    are two subcases: | 
 | 591 |       //    a. DHCP has failed, and Static IP config has _not yet_ | 
 | 592 |       //       completed. It's fine to do nothing, because we'll | 
 | 593 |       //       apply the static config shortly. | 
 | 594 |       //    b. DHCP has failed, and Static IP config has _already_ | 
 | 595 |       //       completed. It's fine to do nothing, because we can | 
 | 596 |       //       continue to use the static config that's already | 
 | 597 |       //       been applied. | 
 | 598 |       // | 
 | 599 |       // 2. We're here because a previously valid DHCP configuration | 
 | 600 |       //    is no longer valid. There's still a static IP config, | 
 | 601 |       //    because the condition in the if clause evaluated to true. | 
 | 602 |       //    Furthermore, the static config includes an IP address for | 
 | 603 |       //    us to use. | 
 | 604 |       // | 
 | 605 |       //    The current configuration may include some DHCP | 
 | 606 |       //    parameters, overriden by any static parameters | 
 | 607 |       //    provided. We continue to use this configuration, because | 
 | 608 |       //    the only configuration element that is leased to us (IP | 
 | 609 |       //    address) will be overriden by a static parameter. | 
 | 610 |       return; | 
 | 611 |     } | 
 | 612 |   } | 
 | 613 |  | 
 | 614 |   ipconfig->ResetProperties(); | 
 | 615 |   OnIPConfigFailure(); | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 616 |   UpdateIPConfigsProperty(); | 
| Paul Stewart | c509953 | 2013-12-12 07:53:15 -0800 | [diff] [blame] | 617 |   DestroyConnection(); | 
| Chris Masone | 8fe2c7e | 2011-06-09 15:51:19 -0700 | [diff] [blame] | 618 | } | 
 | 619 |  | 
| Paul Stewart | 8223653 | 2013-12-10 15:33:11 -0800 | [diff] [blame] | 620 | void Device::OnIPConfigRefreshed(const IPConfigRefPtr &ipconfig) { | 
 | 621 |   // Clear the previously applied static IP parameters. | 
 | 622 |   ipconfig->RestoreSavedIPParameters( | 
 | 623 |       selected_service_->mutable_static_ip_parameters()); | 
 | 624 |  | 
 | 625 |   dispatcher_->PostTask(Bind(&Device::ConfigureStaticIPTask, | 
 | 626 |                              weak_ptr_factory_.GetWeakPtr())); | 
 | 627 | } | 
 | 628 |  | 
| Paul Stewart | f6f9648 | 2013-07-12 12:49:15 -0700 | [diff] [blame] | 629 | void Device::OnIPConfigFailure() { | 
 | 630 |   if (selected_service_) { | 
 | 631 |     Error error; | 
 | 632 |     selected_service_->DisconnectWithFailure(Service::kFailureDHCP, &error); | 
 | 633 |   } | 
 | 634 | } | 
 | 635 |  | 
| Paul Stewart | 1f916e4 | 2013-12-23 09:52:54 -0800 | [diff] [blame] | 636 | void Device::OnIPConfigExpired(const IPConfigRefPtr &ipconfig) { | 
 | 637 |   metrics()->SendToUMA( | 
 | 638 |       metrics()->GetFullMetricName( | 
| mukesh agrawal | 132e96f | 2014-04-24 11:49:42 -0700 | [diff] [blame] | 639 |           Metrics::kMetricExpiredLeaseLengthSecondsSuffix, technology()), | 
| Paul Stewart | 1f916e4 | 2013-12-23 09:52:54 -0800 | [diff] [blame] | 640 |       ipconfig->properties().lease_duration_seconds, | 
 | 641 |       Metrics::kMetricExpiredLeaseLengthSecondsMin, | 
 | 642 |       Metrics::kMetricExpiredLeaseLengthSecondsMax, | 
 | 643 |       Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets); | 
 | 644 | } | 
 | 645 |  | 
| Christopher Wiley | 5519e9e | 2013-01-08 16:55:56 -0800 | [diff] [blame] | 646 | void Device::OnConnected() {} | 
 | 647 |  | 
| Paul Stewart | 8596f9f | 2013-03-14 07:58:26 -0700 | [diff] [blame] | 648 | void Device::OnConnectionUpdated() { | 
 | 649 |   if (selected_service_) { | 
 | 650 |     manager_->UpdateService(selected_service_); | 
 | 651 |   } | 
 | 652 | } | 
 | 653 |  | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 654 | void Device::CreateConnection() { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 655 |   SLOG(Device, 2) << __func__; | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 656 |   if (!connection_.get()) { | 
| mukesh agrawal | 23ac6b7 | 2013-01-31 18:52:37 -0800 | [diff] [blame] | 657 |     connection_ = new Connection(interface_index_, | 
 | 658 |                                  link_name_, | 
 | 659 |                                  technology_, | 
 | 660 |                                  manager_->device_info()); | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 661 |   } | 
 | 662 | } | 
 | 663 |  | 
 | 664 | void Device::DestroyConnection() { | 
| mukesh agrawal | 6813e76 | 2013-07-10 19:05:08 -0700 | [diff] [blame] | 665 |   SLOG(Device, 2) << __func__ << " on " << link_name_; | 
| Peter Qiu | dc335f8 | 2014-05-15 10:33:17 -0700 | [diff] [blame] | 666 |   StopTrafficMonitor(); | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 667 |   StopPortalDetection(); | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 668 |   StopLinkMonitor(); | 
| Paul Stewart | be5f5b3 | 2011-12-07 17:11:11 -0800 | [diff] [blame] | 669 |   if (selected_service_.get()) { | 
| mukesh agrawal | 6813e76 | 2013-07-10 19:05:08 -0700 | [diff] [blame] | 670 |     SLOG(Device, 3) << "Clearing connection of service " | 
 | 671 |                     << selected_service_->unique_name(); | 
| Paul Stewart | c1dec4d | 2011-12-08 15:25:28 -0800 | [diff] [blame] | 672 |     selected_service_->SetConnection(NULL); | 
| Paul Stewart | be5f5b3 | 2011-12-07 17:11:11 -0800 | [diff] [blame] | 673 |   } | 
| Paul Stewart | c8f4bef | 2011-12-13 09:45:51 -0800 | [diff] [blame] | 674 |   connection_ = NULL; | 
| Paul Stewart | e613202 | 2011-08-16 09:11:02 -0700 | [diff] [blame] | 675 | } | 
 | 676 |  | 
| Paul Stewart | 03dba0b | 2011-08-22 16:32:45 -0700 | [diff] [blame] | 677 | void Device::SelectService(const ServiceRefPtr &service) { | 
| Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 678 |   SLOG(Device, 2) << __func__ << ": service " | 
| mukesh agrawal | 6813e76 | 2013-07-10 19:05:08 -0700 | [diff] [blame] | 679 |                   << (service ? service->unique_name() : "*reset*") | 
 | 680 |                   << " on " << link_name_; | 
| mukesh agrawal | 8a3188d | 2011-12-01 20:56:44 +0000 | [diff] [blame] | 681 |  | 
 | 682 |   if (selected_service_.get() == service.get()) { | 
 | 683 |     // No change to |selected_service_|. Return early to avoid | 
 | 684 |     // changing its state. | 
 | 685 |     return; | 
 | 686 |   } | 
 | 687 |  | 
| Paul Stewart | be5f5b3 | 2011-12-07 17:11:11 -0800 | [diff] [blame] | 688 |   if (selected_service_.get()) { | 
 | 689 |     if (selected_service_->state() != Service::kStateFailure) { | 
 | 690 |       selected_service_->SetState(Service::kStateIdle); | 
 | 691 |     } | 
| Paul Stewart | 20b0a09 | 2012-05-22 20:39:57 -0700 | [diff] [blame] | 692 |     // Just in case the Device subclass has not already done so, make | 
 | 693 |     // sure the previously selected service has its connection removed. | 
| Paul Stewart | c1dec4d | 2011-12-08 15:25:28 -0800 | [diff] [blame] | 694 |     selected_service_->SetConnection(NULL); | 
| Peter Qiu | dc335f8 | 2014-05-15 10:33:17 -0700 | [diff] [blame] | 695 |     StopTrafficMonitor(); | 
| Paul Stewart | c886061 | 2012-09-28 07:36:21 -0700 | [diff] [blame] | 696 |     StopLinkMonitor(); | 
 | 697 |     StopPortalDetection(); | 
| Paul Stewart | 03dba0b | 2011-08-22 16:32:45 -0700 | [diff] [blame] | 698 |   } | 
 | 699 |   selected_service_ = service; | 
 | 700 | } | 
 | 701 |  | 
 | 702 | void Device::SetServiceState(Service::ConnectState state) { | 
 | 703 |   if (selected_service_.get()) { | 
 | 704 |     selected_service_->SetState(state); | 
 | 705 |   } | 
 | 706 | } | 
 | 707 |  | 
 | 708 | void Device::SetServiceFailure(Service::ConnectFailure failure_state) { | 
 | 709 |   if (selected_service_.get()) { | 
 | 710 |     selected_service_->SetFailure(failure_state); | 
 | 711 |   } | 
 | 712 | } | 
 | 713 |  | 
| Eric Shienbrood | cc95c5d | 2012-03-30 15:25:49 -0400 | [diff] [blame] | 714 | void Device::SetServiceFailureSilent(Service::ConnectFailure failure_state) { | 
 | 715 |   if (selected_service_.get()) { | 
 | 716 |     selected_service_->SetFailureSilent(failure_state); | 
 | 717 |   } | 
 | 718 | } | 
 | 719 |  | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 720 | bool Device::SetIPFlag(IPAddress::Family family, const string &flag, | 
 | 721 |                        const string &value) { | 
 | 722 |   string ip_version; | 
 | 723 |   if (family == IPAddress::kFamilyIPv4) { | 
 | 724 |     ip_version = kIPFlagVersion4; | 
 | 725 |   } else if (family == IPAddress::kFamilyIPv6) { | 
 | 726 |     ip_version = kIPFlagVersion6; | 
 | 727 |   } else { | 
 | 728 |     NOTIMPLEMENTED(); | 
 | 729 |   } | 
 | 730 |   FilePath flag_file(StringPrintf(kIPFlagTemplate, ip_version.c_str(), | 
 | 731 |                                   link_name_.c_str(), flag.c_str())); | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 732 |   SLOG(Device, 2) << "Writing " << value << " to flag file " | 
 | 733 |                   << flag_file.value(); | 
| Ben Chan | 6fbf64f | 2014-05-21 18:07:01 -0700 | [diff] [blame] | 734 |   if (base::WriteFile(flag_file, value.c_str(), value.length()) != 1) { | 
| Paul Stewart | 2bf1d35 | 2011-12-06 15:02:55 -0800 | [diff] [blame] | 735 |     LOG(ERROR) << StringPrintf("IP flag write failed: %s to %s", | 
 | 736 |                                value.c_str(), flag_file.value().c_str()); | 
 | 737 |     return false; | 
 | 738 |   } | 
 | 739 |   return true; | 
 | 740 | } | 
 | 741 |  | 
| Paul Stewart | c6fbad9 | 2013-11-13 14:50:52 -0800 | [diff] [blame] | 742 | string Device::PerformTDLSOperation(const string &/* operation */, | 
 | 743 |                                     const string &/* peer */, | 
 | 744 |                                     Error */* error */) { | 
 | 745 |   return ""; | 
 | 746 | } | 
 | 747 |  | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 748 | void Device::ResetByteCounters() { | 
 | 749 |   manager_->device_info()->GetByteCounts( | 
 | 750 |       interface_index_, &receive_byte_offset_, &transmit_byte_offset_); | 
 | 751 |   manager_->UpdateDevice(this); | 
 | 752 | } | 
 | 753 |  | 
| Paul Stewart | d215af6 | 2012-04-24 23:25:50 -0700 | [diff] [blame] | 754 | bool Device::RestartPortalDetection() { | 
 | 755 |   StopPortalDetection(); | 
 | 756 |   return StartPortalDetection(); | 
 | 757 | } | 
 | 758 |  | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 759 | bool Device::RequestPortalDetection() { | 
 | 760 |   if (!selected_service_) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 761 |     SLOG(Device, 2) << FriendlyName() | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 762 |             << ": No selected service, so no need for portal check."; | 
 | 763 |     return false; | 
 | 764 |   } | 
 | 765 |  | 
 | 766 |   if (!connection_.get()) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 767 |     SLOG(Device, 2) << FriendlyName() | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 768 |             << ": No connection, so no need for portal check."; | 
 | 769 |     return false; | 
 | 770 |   } | 
 | 771 |  | 
 | 772 |   if (selected_service_->state() != Service::kStatePortal) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 773 |     SLOG(Device, 2) << FriendlyName() | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 774 |             << ": Service is not in portal state.  No need to start check."; | 
 | 775 |     return false; | 
 | 776 |   } | 
 | 777 |  | 
 | 778 |   if (!connection_->is_default()) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 779 |     SLOG(Device, 2) << FriendlyName() | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 780 |             << ": Service is not the default connection.  Don't start check."; | 
 | 781 |     return false; | 
 | 782 |   } | 
 | 783 |  | 
 | 784 |   if (portal_detector_.get() && portal_detector_->IsInProgress()) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 785 |     SLOG(Device, 2) << FriendlyName() | 
 | 786 |                     << ": Portal detection is already running."; | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 787 |     return true; | 
 | 788 |   } | 
 | 789 |  | 
 | 790 |   return StartPortalDetection(); | 
 | 791 | } | 
 | 792 |  | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 793 | bool Device::StartPortalDetection() { | 
| Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 794 |   DCHECK(selected_service_); | 
| Paul Stewart | d215af6 | 2012-04-24 23:25:50 -0700 | [diff] [blame] | 795 |   if (selected_service_->IsPortalDetectionDisabled()) { | 
| Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 796 |     SLOG(Device, 2) << "Service " << selected_service_->unique_name() | 
| Paul Stewart | d215af6 | 2012-04-24 23:25:50 -0700 | [diff] [blame] | 797 |                     << ": Portal detection is disabled; " | 
 | 798 |                     << "marking service online."; | 
 | 799 |     SetServiceConnectedState(Service::kStateOnline); | 
 | 800 |     return false; | 
 | 801 |   } | 
 | 802 |  | 
 | 803 |   if (selected_service_->IsPortalDetectionAuto() && | 
 | 804 |       !manager_->IsPortalDetectionEnabled(technology())) { | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 805 |     // If portal detection is disabled for this technology, immediately set | 
 | 806 |     // the service state to "Online". | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 807 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 808 |                     << ": Portal detection is disabled; " | 
 | 809 |                     << "marking service online."; | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 810 |     SetServiceConnectedState(Service::kStateOnline); | 
 | 811 |     return false; | 
 | 812 |   } | 
 | 813 |  | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 814 |   if (selected_service_->HasProxyConfig()) { | 
 | 815 |     // Services with HTTP proxy configurations should not be checked by the | 
 | 816 |     // connection manager, since we don't have the ability to evaluate | 
 | 817 |     // arbitrary proxy configs and their possible credentials. | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 818 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 819 |                     << ": Service has proxy config; marking it online."; | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 820 |     SetServiceConnectedState(Service::kStateOnline); | 
 | 821 |     return false; | 
 | 822 |   } | 
 | 823 |  | 
 | 824 |   portal_detector_.reset(new PortalDetector(connection_, | 
 | 825 |                                             dispatcher_, | 
| Eric Shienbrood | 3e20a23 | 2012-02-16 11:35:56 -0500 | [diff] [blame] | 826 |                                             portal_detector_callback_)); | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 827 |   if (!portal_detector_->Start(manager_->GetPortalCheckURL())) { | 
 | 828 |     LOG(ERROR) << "Device " << FriendlyName() | 
 | 829 |                << ": Portal detection failed to start: likely bad URL: " | 
 | 830 |                << manager_->GetPortalCheckURL(); | 
 | 831 |     SetServiceConnectedState(Service::kStateOnline); | 
 | 832 |     return false; | 
 | 833 |   } | 
 | 834 |  | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 835 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 836 |                   << ": Portal detection has started."; | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 837 |   return true; | 
 | 838 | } | 
 | 839 |  | 
 | 840 | void Device::StopPortalDetection() { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 841 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
| mukesh agrawal | bb2231c | 2013-07-17 16:32:24 -0700 | [diff] [blame] | 842 |                   << ": Portal detection stopping."; | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 843 |   portal_detector_.reset(); | 
 | 844 | } | 
 | 845 |  | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 846 | void Device::set_link_monitor(LinkMonitor *link_monitor) { | 
 | 847 |   link_monitor_.reset(link_monitor); | 
 | 848 | } | 
 | 849 |  | 
 | 850 | bool Device::StartLinkMonitor() { | 
 | 851 |   if (!manager_->IsTechnologyLinkMonitorEnabled(technology())) { | 
 | 852 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 853 |                     << ": Link Monitoring is disabled."; | 
 | 854 |     return false; | 
 | 855 |   } | 
 | 856 |  | 
 | 857 |   if (!link_monitor()) { | 
 | 858 |     set_link_monitor( | 
 | 859 |       new LinkMonitor( | 
 | 860 |           connection_, dispatcher_, metrics(), manager_->device_info(), | 
| Peter Qiu | b5d124f | 2014-04-14 12:05:02 -0700 | [diff] [blame] | 861 |           Bind(&Device::OnLinkMonitorFailure, weak_ptr_factory_.GetWeakPtr()), | 
 | 862 |           Bind(&Device::OnLinkMonitorGatewayChange, | 
 | 863 |                weak_ptr_factory_.GetWeakPtr()))); | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 864 |   } | 
 | 865 |  | 
 | 866 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 867 |                   << ": Link Monitor starting."; | 
 | 868 |   return link_monitor_->Start(); | 
 | 869 | } | 
 | 870 |  | 
 | 871 | void Device::StopLinkMonitor() { | 
 | 872 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 873 |                   << ": Link Monitor stopping."; | 
 | 874 |   link_monitor_.reset(); | 
 | 875 | } | 
 | 876 |  | 
 | 877 | void Device::OnLinkMonitorFailure() { | 
 | 878 |   LOG(ERROR) << "Device " << FriendlyName() | 
 | 879 |              << ": Link Monitor indicates failure."; | 
 | 880 | } | 
 | 881 |  | 
| Peter Qiu | 9d58193 | 2014-04-14 16:37:37 -0700 | [diff] [blame] | 882 | void Device::OnLinkMonitorGatewayChange() { | 
 | 883 |   string gateway_mac = link_monitor()->gateway_mac_address().HexEncode(); | 
 | 884 |   int connection_id = manager_->CalcConnectionId( | 
 | 885 |       ipconfig_->properties().gateway, gateway_mac); | 
 | 886 |  | 
 | 887 |   CHECK(selected_service_); | 
 | 888 |   selected_service_->set_connection_id(connection_id); | 
 | 889 |  | 
 | 890 |   manager_->ReportServicesOnSameNetwork(connection_id); | 
 | 891 | } | 
 | 892 |  | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 893 | void Device::PerformFallbackDNSTest() { | 
 | 894 |   // Return if DNS client already running. | 
| Alex Vakulenko | 8a53229 | 2014-06-16 17:18:44 -0700 | [diff] [blame] | 895 |   if (fallback_dns_test_client_.get()) { | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 896 |     return; | 
 | 897 |   } | 
 | 898 |  | 
 | 899 |   // Send DNS request to Google's DNS server. | 
 | 900 |   vector<string> dns_servers(std::begin(kFallbackDnsServers), | 
 | 901 |                              std::end(kFallbackDnsServers)); | 
 | 902 |   fallback_dns_test_client_.reset( | 
 | 903 |       dns_client_factory_->CreateDNSClient(IPAddress::kFamilyIPv4, | 
 | 904 |                                            connection_->interface_name(), | 
 | 905 |                                            dns_servers, | 
 | 906 |                                            kDNSTimeoutMilliseconds, | 
 | 907 |                                            dispatcher_, | 
 | 908 |                                            dns_client_callback_)); | 
 | 909 |   Error error; | 
 | 910 |   if (!fallback_dns_test_client_->Start(kFallbackDnsTestHostname, &error)) { | 
 | 911 |     LOG(ERROR) << __func__ << ": Failed to start DNS client " | 
 | 912 |                                 << error.message(); | 
 | 913 |     fallback_dns_test_client_.reset(); | 
 | 914 |   } | 
 | 915 | } | 
 | 916 |  | 
 | 917 | void Device::DNSClientCallback(const Error &error, const IPAddress& ip) { | 
| Peter Qiu | f18e771 | 2014-05-20 09:59:46 -0700 | [diff] [blame] | 918 |   int result = Metrics::kFallbackDNSTestResultFailure; | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 919 |   if (error.IsSuccess()) { | 
| Peter Qiu | f18e771 | 2014-05-20 09:59:46 -0700 | [diff] [blame] | 920 |     result = Metrics::kFallbackDNSTestResultSuccess; | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 921 |   } | 
| Peter Qiu | f18e771 | 2014-05-20 09:59:46 -0700 | [diff] [blame] | 922 |   metrics()->NotifyFallbackDNSTestResult(technology_, result); | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 923 |   fallback_dns_test_client_.reset(); | 
 | 924 | } | 
 | 925 |  | 
| Peter Qiu | dc335f8 | 2014-05-15 10:33:17 -0700 | [diff] [blame] | 926 | void Device::set_traffic_monitor(TrafficMonitor *traffic_monitor) { | 
 | 927 |   traffic_monitor_.reset(traffic_monitor); | 
 | 928 | } | 
 | 929 |  | 
 | 930 | bool Device::IsTrafficMonitorEnabled() const { | 
 | 931 |   return false; | 
 | 932 | } | 
 | 933 |  | 
 | 934 | void Device::StartTrafficMonitor() { | 
 | 935 |   // Return if traffic monitor is not enabled for this device. | 
 | 936 |   if (!IsTrafficMonitorEnabled()) { | 
 | 937 |     return; | 
 | 938 |   } | 
 | 939 |  | 
 | 940 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 941 |                   << ": Traffic Monitor starting."; | 
 | 942 |   if (!traffic_monitor_.get()) { | 
 | 943 |     traffic_monitor_.reset(new TrafficMonitor(this, dispatcher_)); | 
 | 944 |     traffic_monitor_->set_network_problem_detected_callback( | 
 | 945 |         Bind(&Device::OnEncounterNetworkProblem, | 
 | 946 |              weak_ptr_factory_.GetWeakPtr())); | 
 | 947 |   } | 
 | 948 |   traffic_monitor_->Start(); | 
 | 949 | } | 
 | 950 |  | 
 | 951 | void Device::StopTrafficMonitor() { | 
 | 952 |   // Return if traffic monitor is not enabled for this device. | 
 | 953 |   if (!IsTrafficMonitorEnabled()) { | 
 | 954 |     return; | 
 | 955 |   } | 
 | 956 |  | 
 | 957 |   if (traffic_monitor_.get()) { | 
 | 958 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 959 |                     << ": Traffic Monitor stopping."; | 
 | 960 |     traffic_monitor_->Stop(); | 
 | 961 |   } | 
 | 962 |   traffic_monitor_.reset(); | 
 | 963 | } | 
 | 964 |  | 
 | 965 | void Device::OnEncounterNetworkProblem(int reason) { | 
 | 966 |   int metric_code; | 
 | 967 |   switch (reason) { | 
 | 968 |     case TrafficMonitor::kNetworkProblemCongestedTxQueue: | 
 | 969 |       metric_code = Metrics::kNetworkProblemCongestedTCPTxQueue; | 
 | 970 |       break; | 
 | 971 |     case TrafficMonitor::kNetworkProblemDNSFailure: | 
 | 972 |       metric_code = Metrics::kNetworkProblemDNSFailure; | 
 | 973 |       break; | 
 | 974 |     default: | 
 | 975 |       LOG(ERROR) << "Invalid network problem code: " << reason; | 
 | 976 |       return; | 
 | 977 |   } | 
 | 978 |  | 
 | 979 |   metrics()->NotifyNetworkProblemDetected(technology_, metric_code); | 
 | 980 |   // Stop the traffic monitor, only report the first network problem detected | 
 | 981 |   // on the connection for now. | 
 | 982 |   StopTrafficMonitor(); | 
 | 983 | } | 
 | 984 |  | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 985 | void Device::SetServiceConnectedState(Service::ConnectState state) { | 
 | 986 |   DCHECK(selected_service_.get()); | 
 | 987 |  | 
 | 988 |   if (!selected_service_.get()) { | 
 | 989 |     LOG(ERROR) << FriendlyName() << ": " | 
 | 990 |                << "Portal detection completed but no selected service exists!"; | 
 | 991 |     return; | 
 | 992 |   } | 
 | 993 |  | 
 | 994 |   if (!selected_service_->IsConnected()) { | 
 | 995 |     LOG(ERROR) << FriendlyName() << ": " | 
 | 996 |                << "Portal detection completed but selected service " | 
| Darin Petkov | 457728b | 2013-01-09 09:49:08 +0100 | [diff] [blame] | 997 |                << selected_service_->unique_name() | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 998 |                << " is in non-connected state."; | 
 | 999 |     return; | 
 | 1000 |   } | 
 | 1001 |  | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 1002 |   if (state == Service::kStatePortal && connection_->is_default() && | 
 | 1003 |       manager_->GetPortalCheckInterval() != 0) { | 
 | 1004 |     CHECK(portal_detector_.get()); | 
 | 1005 |     if (!portal_detector_->StartAfterDelay( | 
 | 1006 |             manager_->GetPortalCheckURL(), | 
 | 1007 |             manager_->GetPortalCheckInterval())) { | 
 | 1008 |       LOG(ERROR) << "Device " << FriendlyName() | 
 | 1009 |                  << ": Portal detection failed to restart: likely bad URL: " | 
 | 1010 |                  << manager_->GetPortalCheckURL(); | 
 | 1011 |       SetServiceState(Service::kStateOnline); | 
 | 1012 |       portal_detector_.reset(); | 
 | 1013 |       return; | 
 | 1014 |     } | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1015 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 1016 |                     << ": Portal detection retrying."; | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 1017 |   } else { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1018 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 1019 |                     << ": Portal will not retry."; | 
| Paul Stewart | c681fa0 | 2012-03-02 19:40:04 -0800 | [diff] [blame] | 1020 |     portal_detector_.reset(); | 
 | 1021 |   } | 
 | 1022 |  | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1023 |   SetServiceState(state); | 
 | 1024 | } | 
 | 1025 |  | 
 | 1026 | void Device::PortalDetectorCallback(const PortalDetector::Result &result) { | 
 | 1027 |   if (!result.final) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1028 |     SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 1029 |                     << ": Received non-final status: " | 
 | 1030 |                     << PortalDetector::StatusToString(result.status); | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1031 |     return; | 
 | 1032 |   } | 
 | 1033 |  | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1034 |   SLOG(Device, 2) << "Device " << FriendlyName() | 
 | 1035 |                   << ": Received final status: " | 
 | 1036 |                   << PortalDetector::StatusToString(result.status); | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1037 |  | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1038 |   portal_attempts_to_online_ += result.num_attempts; | 
 | 1039 |  | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 1040 |   int portal_status = Metrics::PortalDetectionResultToEnum(result); | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1041 |   metrics()->SendEnumToUMA( | 
| mukesh agrawal | 132e96f | 2014-04-24 11:49:42 -0700 | [diff] [blame] | 1042 |       metrics()->GetFullMetricName(Metrics::kMetricPortalResultSuffix, | 
 | 1043 |                                    technology()), | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 1044 |       portal_status, | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1045 |       Metrics::kPortalResultMax); | 
 | 1046 |  | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1047 |   if (result.status == PortalDetector::kStatusSuccess) { | 
 | 1048 |     SetServiceConnectedState(Service::kStateOnline); | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1049 |  | 
 | 1050 |     metrics()->SendToUMA( | 
 | 1051 |         metrics()->GetFullMetricName( | 
| mukesh agrawal | 132e96f | 2014-04-24 11:49:42 -0700 | [diff] [blame] | 1052 |             Metrics::kMetricPortalAttemptsToOnlineSuffix, technology()), | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1053 |         portal_attempts_to_online_, | 
 | 1054 |         Metrics::kMetricPortalAttemptsToOnlineMin, | 
 | 1055 |         Metrics::kMetricPortalAttemptsToOnlineMax, | 
 | 1056 |         Metrics::kMetricPortalAttemptsToOnlineNumBuckets); | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1057 |   } else { | 
 | 1058 |     SetServiceConnectedState(Service::kStatePortal); | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1059 |  | 
 | 1060 |     metrics()->SendToUMA( | 
 | 1061 |         metrics()->GetFullMetricName( | 
| mukesh agrawal | 132e96f | 2014-04-24 11:49:42 -0700 | [diff] [blame] | 1062 |             Metrics::kMetricPortalAttemptsSuffix, technology()), | 
| Thieu Le | 85e050b | 2012-03-13 15:04:38 -0700 | [diff] [blame] | 1063 |         result.num_attempts, | 
 | 1064 |         Metrics::kMetricPortalAttemptsMin, | 
 | 1065 |         Metrics::kMetricPortalAttemptsMax, | 
 | 1066 |         Metrics::kMetricPortalAttemptsNumBuckets); | 
| Peter Qiu | b9256f3 | 2014-05-09 15:27:29 -0700 | [diff] [blame] | 1067 |  | 
 | 1068 |     // Perform fallback DNS test if the portal failure is DNS related. | 
 | 1069 |     // The test will send a  DNS request to Google's DNS server to determine | 
 | 1070 |     // if the DNS failure is due to bad DNS server settings. | 
 | 1071 |     if ((portal_status == Metrics::kPortalResultDNSFailure) || | 
 | 1072 |         (portal_status == Metrics::kPortalResultDNSTimeout)) { | 
 | 1073 |       PerformFallbackDNSTest(); | 
 | 1074 |     } | 
| Paul Stewart | 20088d8 | 2012-02-16 06:58:55 -0800 | [diff] [blame] | 1075 |   } | 
 | 1076 | } | 
 | 1077 |  | 
| Gaurav Shah | 1b7a616 | 2011-11-09 11:41:01 -0800 | [diff] [blame] | 1078 | vector<string> Device::AvailableIPConfigs(Error */*error*/) { | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 1079 |   vector<string> ipconfigs; | 
 | 1080 |   if (ipconfig_) { | 
 | 1081 |     ipconfigs.push_back(ipconfig_->GetRpcIdentifier()); | 
| Jason Glasgow | 08afdff | 2012-04-03 10:22:26 -0400 | [diff] [blame] | 1082 |   } | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 1083 |   if (ip6config_) { | 
 | 1084 |     ipconfigs.push_back(ip6config_->GetRpcIdentifier()); | 
 | 1085 |   } | 
 | 1086 |   return ipconfigs; | 
| Chris Masone | 4e85161 | 2011-07-01 10:46:53 -0700 | [diff] [blame] | 1087 | } | 
 | 1088 |  | 
 | 1089 | string Device::GetRpcConnectionIdentifier() { | 
 | 1090 |   return adaptor_->GetRpcConnectionIdentifier(); | 
 | 1091 | } | 
 | 1092 |  | 
| Paul Stewart | 036dba0 | 2012-08-07 12:34:41 -0700 | [diff] [blame] | 1093 | uint64 Device::GetLinkMonitorResponseTime(Error *error) { | 
 | 1094 |   if (!link_monitor_.get()) { | 
 | 1095 |     // It is not strictly an error that the link monitor does not | 
 | 1096 |     // exist, but returning an error here allows the GetProperties | 
 | 1097 |     // call in our Adaptor to omit this parameter. | 
 | 1098 |     error->Populate(Error::kNotFound, "Device is not running LinkMonitor"); | 
 | 1099 |     return 0; | 
 | 1100 |   } | 
 | 1101 |   return link_monitor_->GetResponseTimeMilliseconds(); | 
 | 1102 | } | 
 | 1103 |  | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 1104 | uint64 Device::GetReceiveByteCount() { | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 1105 |   uint64 rx_byte_count = 0, tx_byte_count = 0; | 
 | 1106 |   manager_->device_info()->GetByteCounts( | 
 | 1107 |       interface_index_, &rx_byte_count, &tx_byte_count); | 
 | 1108 |   return rx_byte_count - receive_byte_offset_; | 
 | 1109 | } | 
 | 1110 |  | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 1111 | uint64 Device::GetTransmitByteCount() { | 
| Paul Stewart | 6ff27f5 | 2012-07-11 06:51:41 -0700 | [diff] [blame] | 1112 |   uint64 rx_byte_count = 0, tx_byte_count = 0; | 
 | 1113 |   manager_->device_info()->GetByteCounts( | 
 | 1114 |       interface_index_, &rx_byte_count, &tx_byte_count); | 
 | 1115 |   return tx_byte_count - transmit_byte_offset_; | 
 | 1116 | } | 
 | 1117 |  | 
| Ben Chan | b061f89 | 2013-02-27 17:46:55 -0800 | [diff] [blame] | 1118 | uint64 Device::GetReceiveByteCountProperty(Error */*error*/) { | 
 | 1119 |   return GetReceiveByteCount(); | 
 | 1120 | } | 
 | 1121 |  | 
 | 1122 | uint64 Device::GetTransmitByteCountProperty(Error */*error*/) { | 
 | 1123 |   return GetTransmitByteCount(); | 
 | 1124 | } | 
 | 1125 |  | 
| Eric Shienbrood | 7fce52c | 2012-04-13 19:11:02 -0400 | [diff] [blame] | 1126 | bool Device::IsUnderlyingDeviceEnabled() const { | 
 | 1127 |   return false; | 
 | 1128 | } | 
 | 1129 |  | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1130 | // callback | 
 | 1131 | void Device::OnEnabledStateChanged(const ResultCallback &callback, | 
 | 1132 |                                    const Error &error) { | 
| mukesh agrawal | 46c27cc | 2013-07-10 16:39:10 -0700 | [diff] [blame] | 1133 |   SLOG(Device, 2) << __func__ | 
 | 1134 |                   << " (target: " << enabled_pending_ << "," | 
 | 1135 |                   << " success: " << error.IsSuccess() << ")" | 
 | 1136 |                   << " on " << link_name_; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1137 |   if (error.IsSuccess()) { | 
 | 1138 |     enabled_ = enabled_pending_; | 
 | 1139 |     manager_->UpdateEnabledTechnologies(); | 
| Ben Chan | 923a502 | 2013-09-20 11:23:23 -0700 | [diff] [blame] | 1140 |     adaptor_->EmitBoolChanged(kPoweredProperty, enabled_); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1141 |   } | 
| Gary Morain | baeefdf | 2012-04-30 14:53:35 -0700 | [diff] [blame] | 1142 |   enabled_pending_ = enabled_; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1143 |   if (!callback.is_null()) | 
 | 1144 |     callback.Run(error); | 
 | 1145 | } | 
 | 1146 |  | 
 | 1147 | void Device::SetEnabled(bool enable) { | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1148 |   SLOG(Device, 2) << __func__ << "(" << enable << ")"; | 
| Jason Glasgow | 4a49079 | 2012-04-10 15:02:05 -0400 | [diff] [blame] | 1149 |   Error error; | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1150 |   SetEnabledChecked(enable, false, &error, ResultCallback()); | 
| Arman Uguray | 8bf6a5c | 2013-08-12 14:18:03 -0700 | [diff] [blame] | 1151 |  | 
 | 1152 |   // SetEnabledInternal might fail here if there is an unfinished enable or | 
 | 1153 |   // disable operation. Don't log error in this case, as this method is only | 
 | 1154 |   // called when the underlying device is already in the target state and the | 
 | 1155 |   // pending operation should eventually bring the device to the expected | 
 | 1156 |   // state. | 
 | 1157 |   LOG_IF(ERROR, | 
 | 1158 |          error.IsFailure() && | 
 | 1159 |          !error.IsOngoing() && | 
 | 1160 |          error.type() != Error::kInProgress) | 
| Jason Glasgow | 4a49079 | 2012-04-10 15:02:05 -0400 | [diff] [blame] | 1161 |       << "Enabled failed, but no way to report the failure."; | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1162 | } | 
 | 1163 |  | 
| Ben Chan | 9f3dcf8 | 2013-09-25 18:04:58 -0700 | [diff] [blame] | 1164 | void Device::SetEnabledNonPersistent(bool enable, | 
 | 1165 |                                      Error *error, | 
 | 1166 |                                      const ResultCallback &callback) { | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1167 |   SetEnabledChecked(enable, false, error, callback); | 
| Ben Chan | 9f3dcf8 | 2013-09-25 18:04:58 -0700 | [diff] [blame] | 1168 | } | 
 | 1169 |  | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1170 | void Device::SetEnabledPersistent(bool enable, | 
 | 1171 |                                   Error *error, | 
 | 1172 |                                   const ResultCallback &callback) { | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1173 |   SetEnabledChecked(enable, true, error, callback); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1174 | } | 
 | 1175 |  | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1176 | void Device::SetEnabledChecked(bool enable, | 
 | 1177 |                                bool persist, | 
 | 1178 |                                Error *error, | 
 | 1179 |                                const ResultCallback &callback) { | 
| Jason Glasgow | 4a49079 | 2012-04-10 15:02:05 -0400 | [diff] [blame] | 1180 |   DCHECK(error); | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1181 |   SLOG(Device, 2) << "Device " << link_name_ << " " | 
 | 1182 |                   << (enable ? "starting" : "stopping"); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1183 |   if (enable == enabled_) { | 
| Arman Uguray | 2f352e6 | 2013-08-28 19:12:53 -0700 | [diff] [blame] | 1184 |     if (enable != enabled_pending_ && persist) { | 
 | 1185 |       // Return an error, as there is an ongoing operation to achieve the | 
 | 1186 |       // opposite. | 
 | 1187 |       Error::PopulateAndLog( | 
 | 1188 |           error, Error::kOperationFailed, | 
 | 1189 |           enable ? "Cannot enable while the device is disabling." : | 
 | 1190 |                    "Cannot disable while the device is enabling."); | 
 | 1191 |       return; | 
 | 1192 |     } | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1193 |     LOG(INFO) << "Already in desired enable state."; | 
| Jason Glasgow | 4a49079 | 2012-04-10 15:02:05 -0400 | [diff] [blame] | 1194 |     error->Reset(); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1195 |     return; | 
 | 1196 |   } | 
 | 1197 |  | 
 | 1198 |   if (enabled_pending_ == enable) { | 
| Jason Glasgow | 4a49079 | 2012-04-10 15:02:05 -0400 | [diff] [blame] | 1199 |     Error::PopulateAndLog(error, Error::kInProgress, | 
 | 1200 |                           "Enable operation already in progress"); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1201 |     return; | 
 | 1202 |   } | 
 | 1203 |  | 
 | 1204 |   if (persist) { | 
 | 1205 |     enabled_persistent_ = enable; | 
| Darin Petkov | e7c6ad3 | 2012-06-29 10:22:09 +0200 | [diff] [blame] | 1206 |     manager_->UpdateDevice(this); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1207 |   } | 
 | 1208 |  | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1209 |   SetEnabledUnchecked(enable, error, callback); | 
 | 1210 | } | 
 | 1211 |  | 
 | 1212 | void Device::SetEnabledUnchecked(bool enable, Error *error, | 
 | 1213 |                                  const ResultCallback &on_enable_complete) { | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1214 |   enabled_pending_ = enable; | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1215 |   EnabledStateChangedCallback chained_callback = | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1216 |       Bind(&Device::OnEnabledStateChanged, | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1217 |            weak_ptr_factory_.GetWeakPtr(), on_enable_complete); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1218 |   if (enable) { | 
 | 1219 |     running_ = true; | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1220 |     Start(error, chained_callback); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1221 |   } else { | 
 | 1222 |     running_ = false; | 
 | 1223 |     DestroyIPConfig();         // breaks a reference cycle | 
 | 1224 |     SelectService(NULL);       // breaks a reference cycle | 
 | 1225 |     rtnl_handler_->SetInterfaceFlags(interface_index(), 0, IFF_UP); | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1226 |     SLOG(Device, 3) << "Device " << link_name_ << " ipconfig_ " | 
 | 1227 |                     << (ipconfig_ ? "is set." : "is not set."); | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 1228 |     SLOG(Device, 3) << "Device " << link_name_ << " ip6config_ " | 
 | 1229 |                     << (ip6config_ ? "is set." : "is not set."); | 
| Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1230 |     SLOG(Device, 3) << "Device " << link_name_ << " connection_ " | 
 | 1231 |                     << (connection_ ? "is set." : "is not set."); | 
 | 1232 |     SLOG(Device, 3) << "Device " << link_name_ << " selected_service_ " | 
 | 1233 |                     << (selected_service_ ? "is set." : "is not set."); | 
| mukesh agrawal | 2818551 | 2013-10-18 16:57:09 -0700 | [diff] [blame] | 1234 |     Stop(error, chained_callback); | 
| Eric Shienbrood | 9a24553 | 2012-03-07 14:20:39 -0500 | [diff] [blame] | 1235 |   } | 
 | 1236 | } | 
 | 1237 |  | 
| Paul Stewart | d4f2648 | 2014-04-25 19:12:03 -0700 | [diff] [blame] | 1238 | void Device::UpdateIPConfigsProperty() { | 
 | 1239 |   adaptor_->EmitRpcIdentifierArrayChanged( | 
 | 1240 |       kIPConfigsProperty, AvailableIPConfigs(NULL)); | 
 | 1241 | } | 
 | 1242 |  | 
| Paul Stewart | 75897df | 2011-04-27 09:05:53 -0700 | [diff] [blame] | 1243 | }  // namespace shill |