1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/link_monitor.h" 18 19 #include <string> 20 21 #include <base/bind.h> 22 23 #include "shill/active_link_monitor.h" 24 #include "shill/connection.h" 25 #include "shill/device_info.h" 26 #include "shill/event_dispatcher.h" 27 #include "shill/logging.h" 28 #include "shill/net/shill_time.h" 29 #include "shill/passive_link_monitor.h" 30 31 using base::Bind; 32 using base::Unretained; 33 using std::string; 34 35 namespace shill { 36 37 namespace Logging { 38 static auto kModuleLogScope = ScopeLogger::kLink; 39 static string ObjectID(Connection* c) { return c->interface_name(); } 40 } 41 42 const int LinkMonitor::kDefaultTestPeriodMilliseconds = 43 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds; 44 const int LinkMonitor::kFailureThreshold = 45 ActiveLinkMonitor::kFailureThreshold; 46 const char LinkMonitor::kDefaultLinkMonitorTechnologies[] = "wifi"; 47 48 LinkMonitor::LinkMonitor(const ConnectionRefPtr& connection, 49 EventDispatcher* dispatcher, 50 Metrics* metrics, 51 DeviceInfo* device_info, 52 const FailureCallback& failure_callback, 53 const GatewayChangeCallback& gateway_change_callback) 54 : connection_(connection), 55 dispatcher_(dispatcher), 56 metrics_(metrics), 57 failure_callback_(failure_callback), 58 gateway_change_callback_(gateway_change_callback), 59 active_link_monitor_( 60 new ActiveLinkMonitor( 61 connection, 62 dispatcher, 63 metrics, 64 device_info, 65 Bind(&LinkMonitor::OnActiveLinkMonitorFailure, 66 Unretained(this)), 67 Bind(&LinkMonitor::OnActiveLinkMonitorSuccess, 68 Unretained(this)))), 69 passive_link_monitor_( 70 new PassiveLinkMonitor( 71 connection, 72 dispatcher, 73 Bind(&LinkMonitor::OnPassiveLinkMonitorResultCallback, 74 Unretained(this)))), 75 time_(Time::GetInstance()) { 76 } 77 78 LinkMonitor::~LinkMonitor() { 79 Stop(); 80 } 81 82 bool LinkMonitor::Start() { 83 Stop(); 84 time_->GetTimeMonotonic(&started_monitoring_at_); 85 // Start active link monitor. 86 return active_link_monitor_->Start( 87 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds); 88 } 89 90 void LinkMonitor::Stop() { 91 SLOG(connection_.get(), 2) << "In " << __func__ << "."; 92 timerclear(&started_monitoring_at_); 93 active_link_monitor_->Stop(); 94 passive_link_monitor_->Stop(); 95 gateway_mac_address_.Clear(); 96 } 97 98 void LinkMonitor::OnAfterResume() { 99 // Preserve gateway settings across resume. 100 ByteString prior_gateway_mac_address(gateway_mac_address_); 101 bool gateway_supports_unicast_arp = 102 active_link_monitor_->gateway_supports_unicast_arp(); 103 Stop(); 104 gateway_mac_address_ = prior_gateway_mac_address; 105 active_link_monitor_->set_gateway_mac_address(gateway_mac_address_); 106 active_link_monitor_->set_gateway_supports_unicast_arp( 107 gateway_supports_unicast_arp); 108 109 active_link_monitor_->Start(ActiveLinkMonitor::kFastTestPeriodMilliseconds); 110 } 111 112 int LinkMonitor::GetResponseTimeMilliseconds() const { 113 return active_link_monitor_->GetResponseTimeMilliseconds(); 114 } 115 116 bool LinkMonitor::IsGatewayFound() const { 117 return !gateway_mac_address_.IsZero(); 118 } 119 120 void LinkMonitor::OnActiveLinkMonitorFailure( 121 Metrics::LinkMonitorFailure failure, 122 int broadcast_failure_count, 123 int unicast_failure_count) { 124 failure_callback_.Run(); 125 126 struct timeval now, elapsed_time; 127 time_->GetTimeMonotonic(&now); 128 timersub(&now, &started_monitoring_at_, &elapsed_time); 129 130 metrics_->NotifyLinkMonitorFailure( 131 connection_->technology(), 132 failure, 133 elapsed_time.tv_sec, 134 broadcast_failure_count, 135 unicast_failure_count); 136 137 Stop(); 138 } 139 140 void LinkMonitor::OnActiveLinkMonitorSuccess() { 141 if (!gateway_mac_address_.Equals( 142 active_link_monitor_->gateway_mac_address())) { 143 gateway_mac_address_ = active_link_monitor_->gateway_mac_address(); 144 // Notify device of the new gateway mac address. 145 gateway_change_callback_.Run(); 146 } 147 148 // Start passive link monitoring. 149 passive_link_monitor_->Start(PassiveLinkMonitor::kDefaultMonitorCycles); 150 } 151 152 void LinkMonitor::OnPassiveLinkMonitorResultCallback(bool status) { 153 // TODO(zqiu): Add metrics for tracking passive link monitor results. 154 155 // Start active monitor 156 active_link_monitor_->Start( 157 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds); 158 } 159 160 } // namespace shill 161