shill: Device: Add LinkMonitor
Start link monitoring for technologies for which it is enabled.
Add facilities in the manager and default profile to determine
and persist a list of technologies for which link monitoring
is enabled. Provide a means for the Device to report the current
rolling average LinkMonitor response time.
BUG=chromium-os:32600
TEST=Unit tests
Change-Id: I39dcc8ce2332d7be3c95d9953b4ae7d7172d7df1
Reviewed-on: https://gerrit.chromium.org/gerrit/29731
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
diff --git a/device.cc b/device.cc
index 9bfd3c8..6086045 100644
--- a/device.cc
+++ b/device.cc
@@ -26,6 +26,7 @@
#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/http_proxy.h"
+#include "shill/link_monitor.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/metrics.h"
@@ -135,6 +136,8 @@
HelpRegisterDerivedString(flimflam::kTypeProperty,
&Device::GetTechnologyString,
NULL);
+ HelpRegisterConstDerivedUint64(shill::kLinkMonitorResponseTimeProperty,
+ &Device::GetLinkMonitorResponseTime);
// TODO(cmasone): Chrome doesn't use this...does anyone?
// store_.RegisterConstBool(flimflam::kReconnectProperty, &reconnect_);
@@ -442,6 +445,7 @@
// to the Connected state because this call may immediately transition
// to the Online state.
StartPortalDetection();
+ StartLinkMonitor();
} else {
// TODO(pstew): This logic gets yet more complex when multiple
// IPConfig types are run in parallel (e.g. DHCP and DHCP6)
@@ -493,6 +497,7 @@
void Device::DestroyConnection() {
SLOG(Device, 2) << __func__;
StopPortalDetection();
+ StopLinkMonitor();
if (selected_service_.get()) {
selected_service_->SetConnection(NULL);
}
@@ -666,6 +671,40 @@
portal_detector_.reset();
}
+void Device::set_link_monitor(LinkMonitor *link_monitor) {
+ link_monitor_.reset(link_monitor);
+}
+
+bool Device::StartLinkMonitor() {
+ if (!manager_->IsTechnologyLinkMonitorEnabled(technology())) {
+ SLOG(Device, 2) << "Device " << FriendlyName()
+ << ": Link Monitoring is disabled.";
+ return false;
+ }
+
+ if (!link_monitor()) {
+ set_link_monitor(
+ new LinkMonitor(
+ connection_, dispatcher_, metrics(), manager_->device_info(),
+ Bind(&Device::OnLinkMonitorFailure, weak_ptr_factory_.GetWeakPtr())));
+ }
+
+ SLOG(Device, 2) << "Device " << FriendlyName()
+ << ": Link Monitor starting.";
+ return link_monitor_->Start();
+}
+
+void Device::StopLinkMonitor() {
+ SLOG(Device, 2) << "Device " << FriendlyName()
+ << ": Link Monitor stopping.";
+ link_monitor_.reset();
+}
+
+void Device::OnLinkMonitorFailure() {
+ LOG(ERROR) << "Device " << FriendlyName()
+ << ": Link Monitor indicates failure.";
+}
+
void Device::SetServiceConnectedState(Service::ConnectState state) {
DCHECK(selected_service_.get());
@@ -761,6 +800,17 @@
return adaptor_->GetRpcConnectionIdentifier();
}
+uint64 Device::GetLinkMonitorResponseTime(Error *error) {
+ if (!link_monitor_.get()) {
+ // It is not strictly an error that the link monitor does not
+ // exist, but returning an error here allows the GetProperties
+ // call in our Adaptor to omit this parameter.
+ error->Populate(Error::kNotFound, "Device is not running LinkMonitor");
+ return 0;
+ }
+ return link_monitor_->GetResponseTimeMilliseconds();
+}
+
uint64 Device::GetReceiveByteCount(Error */*error*/) {
uint64 rx_byte_count = 0, tx_byte_count = 0;
manager_->device_info()->GetByteCounts(