blob: 7f3f5293d73d9e91b58fc9ca075522d357ecb632 [file] [log] [blame]
Paul Stewart3f43f432012-07-16 12:12:45 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/link_monitor.h"
6
Paul Stewartf1961f82012-09-11 20:45:39 -07007#include <string>
Paul Stewart3f43f432012-07-16 12:12:45 -07008
Paul Stewart6c72c972012-07-27 11:29:20 -07009#include <base/bind.h>
Paul Stewart6c72c972012-07-27 11:29:20 -070010
Peter Qiuffa56372015-01-22 14:25:23 -080011#include "shill/active_link_monitor.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070012#include "shill/connection.h"
Paul Stewart6c72c972012-07-27 11:29:20 -070013#include "shill/device_info.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070014#include "shill/event_dispatcher.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070015#include "shill/logging.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070016#include "shill/net/shill_time.h"
Peter Qiuffa56372015-01-22 14:25:23 -080017#include "shill/passive_link_monitor.h"
Paul Stewart6c72c972012-07-27 11:29:20 -070018
19using base::Bind;
20using base::Unretained;
21using std::string;
Paul Stewart3f43f432012-07-16 12:12:45 -070022
23namespace shill {
24
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070025namespace Logging {
26static auto kModuleLogScope = ScopeLogger::kLink;
Paul Stewart8ae18742015-06-16 13:13:10 -070027static string ObjectID(Connection* c) { return c->interface_name(); }
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070028}
29
Peter Qiuffa56372015-01-22 14:25:23 -080030const int LinkMonitor::kDefaultTestPeriodMilliseconds =
31 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds;
32const int LinkMonitor::kFailureThreshold =
33 ActiveLinkMonitor::kFailureThreshold;
Paul Stewart036dba02012-08-07 12:34:41 -070034const char LinkMonitor::kDefaultLinkMonitorTechnologies[] = "wifi";
Paul Stewart6c72c972012-07-27 11:29:20 -070035
Paul Stewart8ae18742015-06-16 13:13:10 -070036LinkMonitor::LinkMonitor(const ConnectionRefPtr& connection,
37 EventDispatcher* dispatcher,
38 Metrics* metrics,
39 DeviceInfo* device_info,
40 const FailureCallback& failure_callback,
41 const GatewayChangeCallback& gateway_change_callback)
Paul Stewart3f43f432012-07-16 12:12:45 -070042 : connection_(connection),
43 dispatcher_(dispatcher),
Paul Stewartff845fc2012-08-07 07:28:44 -070044 metrics_(metrics),
Paul Stewart3f43f432012-07-16 12:12:45 -070045 failure_callback_(failure_callback),
Peter Qiub5d124f2014-04-14 12:05:02 -070046 gateway_change_callback_(gateway_change_callback),
Peter Qiuffa56372015-01-22 14:25:23 -080047 active_link_monitor_(
48 new ActiveLinkMonitor(
49 connection,
50 dispatcher,
51 metrics,
52 device_info,
53 Bind(&LinkMonitor::OnActiveLinkMonitorFailure,
54 Unretained(this)),
55 Bind(&LinkMonitor::OnActiveLinkMonitorSuccess,
56 Unretained(this)))),
57 passive_link_monitor_(
58 new PassiveLinkMonitor(
59 connection,
60 dispatcher,
61 Bind(&LinkMonitor::OnPassiveLinkMonitorResultCallback,
62 Unretained(this)))),
Paul Stewartf1961f82012-09-11 20:45:39 -070063 time_(Time::GetInstance()) {
64}
Paul Stewart3f43f432012-07-16 12:12:45 -070065
Paul Stewart6c72c972012-07-27 11:29:20 -070066LinkMonitor::~LinkMonitor() {
67 Stop();
68}
Paul Stewart3f43f432012-07-16 12:12:45 -070069
70bool LinkMonitor::Start() {
Paul Stewart6c72c972012-07-27 11:29:20 -070071 Stop();
Paul Stewart0443aa52012-08-09 10:43:50 -070072 time_->GetTimeMonotonic(&started_monitoring_at_);
Peter Qiuffa56372015-01-22 14:25:23 -080073 // Start active link monitor.
74 return active_link_monitor_->Start(
75 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds);
Paul Stewart3f43f432012-07-16 12:12:45 -070076}
77
78void LinkMonitor::Stop() {
Alex Vakulenko0951ccb2014-12-10 12:52:31 -080079 SLOG(connection_.get(), 2) << "In " << __func__ << ".";
Paul Stewart0443aa52012-08-09 10:43:50 -070080 timerclear(&started_monitoring_at_);
Peter Qiuffa56372015-01-22 14:25:23 -080081 active_link_monitor_->Stop();
82 passive_link_monitor_->Stop();
83 gateway_mac_address_.Clear();
Paul Stewart6c72c972012-07-27 11:29:20 -070084}
85
mukesh agrawalbb2231c2013-07-17 16:32:24 -070086void LinkMonitor::OnAfterResume() {
Peter Qiuffa56372015-01-22 14:25:23 -080087 // Preserve gateway settings across resume.
mukesh agrawalbb2231c2013-07-17 16:32:24 -070088 ByteString prior_gateway_mac_address(gateway_mac_address_);
Peter Qiuffa56372015-01-22 14:25:23 -080089 bool gateway_supports_unicast_arp =
90 active_link_monitor_->gateway_supports_unicast_arp();
mukesh agrawalbb2231c2013-07-17 16:32:24 -070091 Stop();
92 gateway_mac_address_ = prior_gateway_mac_address;
Peter Qiuffa56372015-01-22 14:25:23 -080093 active_link_monitor_->set_gateway_mac_address(gateway_mac_address_);
94 active_link_monitor_->set_gateway_supports_unicast_arp(
95 gateway_supports_unicast_arp);
96
97 active_link_monitor_->Start(ActiveLinkMonitor::kFastTestPeriodMilliseconds);
mukesh agrawalbb2231c2013-07-17 16:32:24 -070098}
99
Paul Stewartf1961f82012-09-11 20:45:39 -0700100int LinkMonitor::GetResponseTimeMilliseconds() const {
Peter Qiuffa56372015-01-22 14:25:23 -0800101 return active_link_monitor_->GetResponseTimeMilliseconds();
Paul Stewart6c72c972012-07-27 11:29:20 -0700102}
103
Paul Stewart9f7823e2012-08-09 10:58:26 -0700104bool LinkMonitor::IsGatewayFound() const {
105 return !gateway_mac_address_.IsZero();
106}
107
Peter Qiuffa56372015-01-22 14:25:23 -0800108void LinkMonitor::OnActiveLinkMonitorFailure(
109 Metrics::LinkMonitorFailure failure,
110 int broadcast_failure_count,
111 int unicast_failure_count) {
112 failure_callback_.Run();
Paul Stewart6c72c972012-07-27 11:29:20 -0700113
114 struct timeval now, elapsed_time;
115 time_->GetTimeMonotonic(&now);
Peter Qiuffa56372015-01-22 14:25:23 -0800116 timersub(&now, &started_monitoring_at_, &elapsed_time);
Paul Stewart6c72c972012-07-27 11:29:20 -0700117
Peter Qiuffa56372015-01-22 14:25:23 -0800118 metrics_->NotifyLinkMonitorFailure(
119 connection_->technology(),
120 failure,
121 elapsed_time.tv_sec,
122 broadcast_failure_count,
123 unicast_failure_count);
Paul Stewart6c72c972012-07-27 11:29:20 -0700124
Peter Qiuffa56372015-01-22 14:25:23 -0800125 Stop();
126}
Paul Stewart6c72c972012-07-27 11:29:20 -0700127
Peter Qiuffa56372015-01-22 14:25:23 -0800128void LinkMonitor::OnActiveLinkMonitorSuccess() {
129 if (!gateway_mac_address_.Equals(
130 active_link_monitor_->gateway_mac_address())) {
131 gateway_mac_address_ = active_link_monitor_->gateway_mac_address();
Peter Qiub5d124f2014-04-14 12:05:02 -0700132 // Notify device of the new gateway mac address.
133 gateway_change_callback_.Run();
Paul Stewart6c72c972012-07-27 11:29:20 -0700134 }
135
Peter Qiuffa56372015-01-22 14:25:23 -0800136 // Start passive link monitoring.
137 passive_link_monitor_->Start(PassiveLinkMonitor::kDefaultMonitorCycles);
Paul Stewart6c72c972012-07-27 11:29:20 -0700138}
139
Peter Qiuffa56372015-01-22 14:25:23 -0800140void LinkMonitor::OnPassiveLinkMonitorResultCallback(bool status) {
141 // TODO(zqiu): Add metrics for tracking passive link monitor results.
Paul Stewart6c72c972012-07-27 11:29:20 -0700142
Peter Qiuffa56372015-01-22 14:25:23 -0800143 // Start active monitor
144 active_link_monitor_->Start(
145 ActiveLinkMonitor::kDefaultTestPeriodMilliseconds);
Paul Stewart6c72c972012-07-27 11:29:20 -0700146}
147
Paul Stewart3f43f432012-07-16 12:12:45 -0700148} // namespace shill