-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ACM MVP Behavior changes #2738
base: develop
Are you sure you want to change the base?
ACM MVP Behavior changes #2738
Changes from all commits
e1845f2
3d1a413
692d33d
d3401bb
f61d755
e4ef3ca
f3850b7
ddf5e29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,13 @@ ConnectionManager* ConnectionManager::instance() { | |
void ConnectionManager::setPreferredNetwork(network_handle_t network, bool preferred) { | ||
if (preferred) { | ||
if (network != NETWORK_INTERFACE_ALL) { | ||
preferredNetwork_ = network; | ||
preferredNetwork_ = network; | ||
|
||
// If cloud is already connected, and a preferred network is set, and it is up, move cloud connection to it immediately | ||
if (spark_cloud_flag_connected() && network_ready(spark::Network.from(preferredNetwork_), 0, nullptr)) { | ||
auto options = CloudDisconnectOptions().graceful(true).reconnect(true).toSystemOptions(); | ||
eberseth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
spark_cloud_disconnect(&options, nullptr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same concern here about executing this on the system task as from network manager context |
||
} | ||
} | ||
} else { | ||
if (network == preferredNetwork_ || network == NETWORK_INTERFACE_ALL) { | ||
|
@@ -124,25 +130,14 @@ network_handle_t ConnectionManager::getCloudConnectionNetwork() { | |
network_handle_t ConnectionManager::selectCloudConnectionNetwork() { | ||
network_handle_t bestNetwork = NETWORK_INTERFACE_ALL; | ||
|
||
// 1: If there is a bound network connection. Do not use anything else, regardless of network state | ||
network_handle_t boundNetwork = NETWORK_INTERFACE_ALL; | ||
size_t n = sizeof(boundNetwork); | ||
spark_get_connection_property(SPARK_CLOUD_BIND_NETWORK_INTERFACE, &boundNetwork, &n, nullptr); | ||
|
||
if (boundNetwork != NETWORK_INTERFACE_ALL) { | ||
LOG_DEBUG(TRACE, "Using bound network: %lu", boundNetwork); | ||
return boundNetwork; | ||
} | ||
|
||
// 2: If no bound network, use preferred network | ||
if (preferredNetwork_ != NETWORK_INTERFACE_ALL && network_ready(spark::Network.from(preferredNetwork_), 0, nullptr)) { | ||
LOG_DEBUG(TRACE, "Using preferred network: %lu", preferredNetwork_); | ||
return preferredNetwork_; | ||
} | ||
|
||
// 3: If no preferred network, use the 'best' network based on criteria | ||
// 3.1: Network is ready: ie configured + connected (see ipv4 routable hook) | ||
// 3.2: Network has best criteria based on network tester results | ||
// If no preferred network, use the 'best' network based on criteria | ||
// Network is ready: ie configured + connected (see ipv4 routable hook) | ||
// Network has best criteria based on network tester results | ||
for (auto& i: bestNetworks_) { | ||
if (network_ready(spark::Network.from(i), 0, nullptr)) { | ||
LOG_DEBUG(TRACE, "Using best network: %lu", i); | ||
|
@@ -236,7 +231,7 @@ int ConnectionTester::sendTestPacket(ConnectionMetrics* metrics) { | |
if (metrics->txPacketCount == metrics->rxPacketCount || | ||
(millis() > metrics->txPacketStartMillis + REACHABILITY_TEST_PACKET_TIMEOUT_MS)) { | ||
|
||
CHECK(generateTestPacket(metrics)); | ||
generateTestPacket(metrics); | ||
|
||
int r = sock_send(metrics->socketDescriptor, metrics->txBuffer, metrics->testPacketSize, 0); | ||
if (r > 0) { | ||
|
@@ -278,12 +273,6 @@ int ConnectionTester::receiveTestPacket(ConnectionMetrics* metrics) { | |
}; | ||
|
||
int ConnectionTester::generateTestPacket(ConnectionMetrics* metrics) { | ||
auto network = spark::Network.from(metrics->interface); | ||
if (!network) { | ||
LOG(ERROR, "No Network associated with interface %d", metrics->interface); | ||
return SYSTEM_ERROR_BAD_DATA; | ||
} | ||
|
||
unsigned packetDataLength = random(1, REACHABILITY_MAX_PAYLOAD_SIZE); | ||
|
||
DTLSPlaintext_t msg = { | ||
|
@@ -331,7 +320,7 @@ int ConnectionTester::pollSockets(struct pollfd* pfds, int socketCount) { | |
receiveTestPacket(connection); | ||
} | ||
if (pfds[i].revents & POLLOUT) { | ||
sendTestPacket(connection); | ||
CHECK(sendTestPacket(connection)); | ||
} | ||
} | ||
return 0; | ||
|
@@ -380,7 +369,12 @@ int ConnectionTester::testConnections() { | |
// For each network interface to test, create + open a socket with the retrieved server address | ||
// If any of the sockets fail to be created + opened with this server address, return an error | ||
for (auto& connectionMetrics: metrics_) { | ||
if (!network_ready(spark::Network.from(connectionMetrics.interface),0,nullptr)) { | ||
auto network = spark::Network.from(connectionMetrics.interface); | ||
if (network == spark::Network) { | ||
LOG(ERROR, "No Network associated with interface %d", connectionMetrics.interface); | ||
return SYSTEM_ERROR_BAD_DATA; | ||
} | ||
if (!network_ready(network, 0, nullptr)) { | ||
LOG_DEBUG(TRACE,"%s not ready, skipping test", netifToName(connectionMetrics.interface)); | ||
continue; | ||
} | ||
|
@@ -487,13 +481,13 @@ const Vector<ConnectionMetrics> ConnectionTester::getConnectionMetrics(){ | |
const Vector<network_interface_t> ConnectionTester::getSupportedInterfaces() { | ||
const Vector<network_interface_t> interfaceList = { | ||
#if HAL_PLATFORM_ETHERNET | ||
static_cast<network_interface_t>(NetworkDiagnosticsInterface::ETHERNET), | ||
NETWORK_INTERFACE_ETHERNET, | ||
#endif | ||
#if HAL_PLATFORM_WIFI | ||
static_cast<network_interface_t>(NetworkDiagnosticsInterface::WIFI_STA), | ||
NETWORK_INTERFACE_WIFI_STA, | ||
#endif | ||
#if HAL_PLATFORM_CELLULAR | ||
static_cast<network_interface_t>(NetworkDiagnosticsInterface::CELLULAR) | ||
NETWORK_INTERFACE_CELLULAR | ||
#endif | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,8 @@ LOG_SOURCE_CATEGORY("system.nm") | |
#include "control/common.h" | ||
#include "control/network.h" | ||
#include <unistd.h> | ||
#include "system_connection_manager.h" | ||
#include "spark_wiring_cloud.h" | ||
|
||
#define CHECKV(_expr) \ | ||
({ \ | ||
|
@@ -536,6 +538,11 @@ void NetworkManager::handleIfState(if_t iface, const struct if_event* ev) { | |
} | ||
|
||
void NetworkManager::handleIfLink(if_t iface, const struct if_event* ev) { | ||
uint8_t netIfIndex = 0; | ||
if_get_index(iface, &netIfIndex); | ||
bool disconnectCloud = false; | ||
auto options = CloudDisconnectOptions().reconnect(true); | ||
|
||
if (ev->ev_if_link->state) { | ||
/* Interface link state changed to UP */ | ||
NetworkInterfaceConfig conf; | ||
|
@@ -609,11 +616,25 @@ void NetworkManager::handleIfLink(if_t iface, const struct if_event* ev) { | |
} else if (state_ == State::IP_CONFIGURED || state_ == State::IFACE_LINK_UP) { | ||
refreshIpState(); | ||
} | ||
|
||
// If the preferred network becomes available, close the cloud connection to force migration to this network | ||
if (ConnectionManager::instance()->getPreferredNetwork() == netIfIndex) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works, but technically is not the correct spot to check if a network is ready (ie IP configured). I think to be strictly correct, the transition from link up -> ip configured is detected in |
||
LOG(INFO, "Preferred network %u available, moving cloud connection", netIfIndex); | ||
options.graceful(true); | ||
disconnectCloud = true; | ||
} | ||
|
||
} else { | ||
// Disable by default | ||
if_clear_xflags(iface, IFXF_DHCP); | ||
resetInterfaceProtocolState(iface); | ||
|
||
// If this is the current cloud connection, disconnect the cloud, but reconnect immediately on any other available interface | ||
if (ConnectionManager::instance()->getCloudConnectionNetwork() == netIfIndex) { | ||
LOG(WARN, "Cloud connection interface %d link state down, disconnecting", netIfIndex); | ||
disconnectCloud = true; | ||
} | ||
|
||
clearDnsConfiguration(iface); | ||
/* Interface link state changed to DOWN */ | ||
if (state_ == State::IP_CONFIGURED || state_ == State::IFACE_LINK_UP) { | ||
|
@@ -624,6 +645,12 @@ void NetworkManager::handleIfLink(if_t iface, const struct if_event* ev) { | |
} | ||
} | ||
} | ||
|
||
if (spark_cloud_flag_connected() && disconnectCloud) { | ||
auto systemOptions = options.toSystemOptions(); | ||
spark_cloud_disconnect(&systemOptions, nullptr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we defer the actual disabling of the |
||
} | ||
|
||
forceCloudPingIfConnected(); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear if this approach detects underlying network state faster, the netif flags did not seem to change before the wifi client realized the AP had been disconnected: