Home | History | Annotate | Download | only in shill
      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