Skip to content

Commit

Permalink
[system] network diagnostics for Gen 3 platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
avtolstoy committed Oct 29, 2020
1 parent 76c7523 commit 986b726
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 93 deletions.
13 changes: 13 additions & 0 deletions system/src/system_network_diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "spark_wiring_fixed_point.h"
#include "spark_wiring_platform.h"
#include "spark_wiring_ticks.h"
#include "system_network_diagnostics.h"

#if Wiring_WiFi
#include "spark_wiring_wifi.h"
Expand All @@ -42,6 +43,18 @@
#define Wiring_Network 0
#else

namespace {

using namespace particle;

NetworkDiagnostics g_networkDiagnostics;

} // namespace

particle::NetworkDiagnostics* particle::NetworkDiagnostics::instance() {
return &g_networkDiagnostics;
}

namespace
{

Expand Down
18 changes: 0 additions & 18 deletions system/src/system_network_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,3 @@ void resetNetworkInterfaces() {
}

} // namespace particle

/* FIXME: there should be a define that tells whether there is NetworkManager available
* or not */
#if !HAL_PLATFORM_IFAPI

namespace {

using namespace particle;

NetworkDiagnostics g_networkDiagnostics;

} // namespace

particle::NetworkDiagnostics* particle::NetworkDiagnostics::instance() {
return &g_networkDiagnostics;
}

#endif /* !HAL_PLATFORM_IFAPI */
69 changes: 1 addition & 68 deletions system/src/system_network_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void resetNetworkInterfaces();
#include "rgbled.h"
#include "spark_wiring_led.h"
#include "spark_wiring_ticks.h"
#include "spark_wiring_diagnostics.h"
#include "system_network_diagnostics.h"
#include "system_event.h"
#include "system_cloud_internal.h"
#include "system_network.h"
Expand Down Expand Up @@ -131,73 +131,6 @@ class NetworkStateLogger {
#define LOG_NETWORK_STATE()
#endif

namespace particle {

class NetworkDiagnostics {
public:
// Note: Use odd numbers to encode transitional states
enum Status {
TURNED_OFF = 0,
TURNING_ON = 1,
DISCONNECTED = 2,
CONNECTING = 3,
CONNECTED = 4,
DISCONNECTING = 5,
TURNING_OFF = 7
};

NetworkDiagnostics() :
status_(DIAG_ID_NETWORK_CONNECTION_STATUS, DIAG_NAME_NETWORK_CONNECTION_STATUS, TURNED_OFF),
disconnReason_(DIAG_ID_NETWORK_DISCONNECTION_REASON, DIAG_NAME_NETWORK_DISCONNECTION_REASON, NETWORK_DISCONNECT_REASON_NONE),
disconnCount_(DIAG_ID_NETWORK_DISCONNECTS, DIAG_NAME_NETWORK_DISCONNECTS),
connCount_(DIAG_ID_NETWORK_CONNECTION_ATTEMPTS, DIAG_NAME_NETWORK_CONNECTION_ATTEMPTS),
lastError_(DIAG_ID_NETWORK_CONNECTION_ERROR_CODE, DIAG_NAME_NETWORK_CONNECTION_ERROR_CODE) {
}

NetworkDiagnostics& status(Status status) {
status_ = status;
return *this;
}

NetworkDiagnostics& connectionAttempt() {
++connCount_;
return *this;
}

NetworkDiagnostics& resetConnectionAttempts() {
connCount_ = 0;
return *this;
}

NetworkDiagnostics& disconnectionReason(network_disconnect_reason reason) {
disconnReason_ = reason;
return *this;
}

NetworkDiagnostics& disconnectedUnexpectedly() {
++disconnCount_;
return *this;
}

NetworkDiagnostics& lastError(int error) {
lastError_ = error;
return *this;
}

static NetworkDiagnostics* instance();

private:
// Some of the diagnostic data sources use the synchronization since they can be updated from
// the networking service thread
AtomicEnumDiagnosticData<Status> status_;
AtomicEnumDiagnosticData<network_disconnect_reason> disconnReason_;
AtomicUnsignedIntegerDiagnosticData disconnCount_;
SimpleUnsignedIntegerDiagnosticData connCount_;
SimpleIntegerDiagnosticData lastError_;
};

} // namespace particle

/**
* Internal network interface class to provide polymorphic behavior for each
* network type. This is not part of the dynalib so functions can freely evolve.
Expand Down
28 changes: 25 additions & 3 deletions system/src/system_network_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ LOG_SOURCE_CATEGORY("system.nm")
#include "system_event.h"
#include "timer_hal.h"
#include "delay_hal.h"
#include "system_network_diagnostics.h"

#define CHECKV(_expr) \
({ \
Expand Down Expand Up @@ -212,7 +213,7 @@ int NetworkManager::activateConnections() {
return 0;
}

int NetworkManager::deactivateConnections() {
int NetworkManager::deactivateConnections(network_disconnect_reason reason) {
switch (state_) {
case State::DISABLED:
case State::IFACE_DOWN: {
Expand All @@ -223,6 +224,15 @@ int NetworkManager::deactivateConnections() {
}
}

if (isConnectivityAvailable()) {
const auto diag = NetworkDiagnostics::instance();
if (reason != NETWORK_DISCONNECT_REASON_NONE) {
diag->disconnectionReason(reason);
if (reason == NETWORK_DISCONNECT_REASON_ERROR || reason == NETWORK_DISCONNECT_REASON_RESET) {
diag->disconnectedUnexpectedly();
}
}
}
transition(State::IFACE_REQUEST_DOWN);

int waitingFor = 0;
Expand Down Expand Up @@ -365,13 +375,16 @@ void NetworkManager::transition(State state) {
switch (state) {
case State::DISABLED: {
LED_SIGNAL_START(NETWORK_OFF, BACKGROUND);
// FIXME:
// FIXME: turning-off events/diagnostics
system_notify_event(network_status, network_status_powering_off);
system_notify_event(network_status, network_status_off);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::TURNED_OFF);
break;
}
case State::IFACE_DOWN: {
LED_SIGNAL_START(NETWORK_ON, BACKGROUND);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::DISCONNECTED);
NetworkDiagnostics::instance()->resetConnectionAttempts();
if (state_ == State::IFACE_REQUEST_DOWN) {
system_notify_event(network_status, network_status_disconnected);
} else if (state_ == State::DISABLED) {
Expand All @@ -383,15 +396,23 @@ void NetworkManager::transition(State state) {
}
case State::IFACE_REQUEST_DOWN: {
system_notify_event(network_status, network_status_disconnecting);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::DISCONNECTING);
break;
}
case State::IFACE_REQUEST_UP: {
LED_SIGNAL_START(NETWORK_CONNECTING, BACKGROUND);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::CONNECTING);
break;
}
case State::IFACE_UP: {
if (state_ == State::IP_CONFIGURED) {
NetworkDiagnostics::instance()->disconnectionReason(NETWORK_DISCONNECT_REASON_ERROR);
NetworkDiagnostics::instance()->disconnectedUnexpectedly();
}
LED_SIGNAL_START(NETWORK_CONNECTING, BACKGROUND);
system_notify_event(network_status, network_status_connecting);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::CONNECTING);
NetworkDiagnostics::instance()->connectionAttempt();
break;
}
case State::IFACE_LINK_UP: {
Expand All @@ -400,6 +421,7 @@ void NetworkManager::transition(State state) {
}
case State::IP_CONFIGURED: {
LED_SIGNAL_START(NETWORK_CONNECTED, BACKGROUND);
NetworkDiagnostics::instance()->status(NetworkDiagnostics::CONNECTED);
if (state_ != State::IP_CONFIGURED) {
system_notify_event(network_status, network_status_connected);
}
Expand Down Expand Up @@ -757,7 +779,7 @@ int NetworkManager::enableInterface(if_t iface) {
return 0;
}

int NetworkManager::disableInterface(if_t iface) {
int NetworkManager::disableInterface(if_t iface, network_disconnect_reason reason) {
// Special case - disable all
if (iface == nullptr) {
populateInterfaceRuntimeState(false);
Expand Down
5 changes: 3 additions & 2 deletions system/src/system_network_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "resolvapi.h"
#include <atomic>
#include "intrusive_list.h"
#include "system_defs.h"

namespace particle { namespace system {

Expand All @@ -43,7 +44,7 @@ class NetworkManager {
bool isNetworkingEnabled() const;

int activateConnections();
int deactivateConnections();
int deactivateConnections(network_disconnect_reason reason = NETWORK_DISCONNECT_REASON_UNKNOWN);
bool isEstablishingConnections() const;

bool isConnectivityAvailable() const;
Expand All @@ -65,7 +66,7 @@ class NetworkManager {
int clearConfiguration(if_t iface = nullptr);

int enableInterface(if_t iface = nullptr);
int disableInterface(if_t iface = nullptr);
int disableInterface(if_t iface = nullptr, network_disconnect_reason reason = NETWORK_DISCONNECT_REASON_UNKNOWN);
bool isInterfaceEnabled(if_t iface) const;
int countEnabledInterfaces();
int syncInterfaceStates();
Expand Down
4 changes: 2 additions & 2 deletions system/src/system_network_manager_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void networkDisconnectImpl(network_handle_t network, network_disconnect_reason r
if (network != NETWORK_INTERFACE_ALL) {
if_t iface;
if (!if_get_by_index(network, &iface)) {
NetworkManager::instance()->disableInterface(iface);
NetworkManager::instance()->disableInterface(iface, reason);
NetworkManager::instance()->syncInterfaceStates();
}
} else {
Expand All @@ -77,7 +77,7 @@ void networkDisconnectImpl(network_handle_t network, network_disconnect_reason r

if ((network == NETWORK_INTERFACE_ALL ||
NetworkManager::instance()->countEnabledInterfaces() == 0) &&
!NetworkManager::instance()->deactivateConnections()) {
!NetworkManager::instance()->deactivateConnections(reason)) {
/* FIXME: should not loop in here */
while (NetworkManager::instance()->getState() != NetworkManager::State::IFACE_DOWN) {
HAL_Delay_Milliseconds(1);
Expand Down

0 comments on commit 986b726

Please sign in to comment.