mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-03 03:01:44 +00:00
Add functionality for getting the current network mode (#202)
Use bit flags to indicate a combination of network mode and status.
This commit is contained in:
committed by
Peter Johnson
parent
417cf33f90
commit
f43675e2bd
@@ -57,6 +57,15 @@ enum NT_NotifyKind {
|
|||||||
NT_NOTIFY_FLAGS = 0x20 /* flags changed */
|
NT_NOTIFY_FLAGS = 0x20 /* flags changed */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Client/server modes */
|
||||||
|
enum NT_NetworkMode {
|
||||||
|
NT_NET_MODE_NONE = 0x00, /* not running */
|
||||||
|
NT_NET_MODE_SERVER = 0x01, /* running in server mode */
|
||||||
|
NT_NET_MODE_CLIENT = 0x02, /* running in client mode */
|
||||||
|
NT_NET_MODE_STARTING = 0x04, /* flag for starting (either client or server) */
|
||||||
|
NT_NET_MODE_FAILURE = 0x08, /* flag for failure (either client or server) */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structures
|
* Structures
|
||||||
*/
|
*/
|
||||||
@@ -345,6 +354,11 @@ struct NT_Value** NT_UnpackRpcValues(const char* packed, size_t packed_len,
|
|||||||
*/
|
*/
|
||||||
void NT_SetNetworkIdentity(const char* name, size_t name_len);
|
void NT_SetNetworkIdentity(const char* name, size_t name_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current network mode.
|
||||||
|
*/
|
||||||
|
unsigned int NT_GetNetworkMode();
|
||||||
|
|
||||||
/** Start Server
|
/** Start Server
|
||||||
* Starts a server using the specified filename, listening address, and port.
|
* Starts a server using the specified filename, listening address, and port.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ std::vector<std::shared_ptr<Value>> UnpackRpcValues(StringRef packed,
|
|||||||
* Client/Server Functions
|
* Client/Server Functions
|
||||||
*/
|
*/
|
||||||
void SetNetworkIdentity(StringRef name);
|
void SetNetworkIdentity(StringRef name);
|
||||||
|
unsigned int GetNetworkMode();
|
||||||
void StartServer(StringRef persist_filename, const char* listen_address,
|
void StartServer(StringRef persist_filename, const char* listen_address,
|
||||||
unsigned int port);
|
unsigned int port);
|
||||||
void StopServer();
|
void StopServer();
|
||||||
|
|||||||
@@ -1502,6 +1502,17 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
|||||||
nt::StopClient();
|
nt::StopClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||||
|
* Method: getNetworkMode
|
||||||
|
* Signature: ()
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getNetworkMode
|
||||||
|
(JNIEnv *, jclass)
|
||||||
|
{
|
||||||
|
return nt::GetNetworkMode();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
* Class: edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||||
* Method: setServer
|
* Method: setServer
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ public class NetworkTablesJNI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final int NT_NET_MODE_NONE = 0x00;
|
||||||
|
public static final int NT_NET_MODE_SERVER = 0x01;
|
||||||
|
public static final int NT_NET_MODE_CLIENT = 0x02;
|
||||||
|
public static final int NT_NET_MODE_STARTING = 0x04;
|
||||||
|
public static final int NT_NET_MODE_FAILURE = 0x08;
|
||||||
|
|
||||||
public static native boolean containsKey(String key);
|
public static native boolean containsKey(String key);
|
||||||
public static native int getType(String key);
|
public static native int getType(String key);
|
||||||
|
|
||||||
@@ -148,6 +154,7 @@ public class NetworkTablesJNI {
|
|||||||
// public static native byte[] getRpcResultNonblocking(int callUid) throws RpcNoResponseException;
|
// public static native byte[] getRpcResultNonblocking(int callUid) throws RpcNoResponseException;
|
||||||
|
|
||||||
public static native void setNetworkIdentity(String name);
|
public static native void setNetworkIdentity(String name);
|
||||||
|
public static native int getNetworkMode();
|
||||||
public static native void startServer(String persistFilename, String listenAddress, int port);
|
public static native void startServer(String persistFilename, String listenAddress, int port);
|
||||||
public static native void stopServer();
|
public static native void stopServer();
|
||||||
public static native void startClient();
|
public static native void startClient();
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ NT_StartDSClient @119
|
|||||||
NT_StopDSClient @120
|
NT_StopDSClient @120
|
||||||
NT_StartClientNone @121
|
NT_StartClientNone @121
|
||||||
|
|
||||||
|
NT_GetNetworkMode @122
|
||||||
|
|
||||||
; JNI functions
|
; JNI functions
|
||||||
JNI_OnLoad
|
JNI_OnLoad
|
||||||
JNI_OnUnload
|
JNI_OnUnload
|
||||||
@@ -194,3 +196,4 @@ Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultRaw
|
|||||||
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultBooleanArray
|
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultBooleanArray
|
||||||
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultDoubleArray
|
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultDoubleArray
|
||||||
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultStringArray
|
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultStringArray
|
||||||
|
Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getNetworkMode
|
||||||
|
|||||||
@@ -118,3 +118,5 @@ NT_SetServerMulti @118
|
|||||||
NT_StartDSClient @119
|
NT_StartDSClient @119
|
||||||
NT_StopDSClient @120
|
NT_StopDSClient @120
|
||||||
NT_StartClientNone @121
|
NT_StartClientNone @121
|
||||||
|
|
||||||
|
NT_GetNetworkMode @122
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ DispatcherBase::~DispatcherBase() {
|
|||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int DispatcherBase::GetNetworkMode() const {
|
||||||
|
return m_networkMode;
|
||||||
|
}
|
||||||
|
|
||||||
void DispatcherBase::StartServer(
|
void DispatcherBase::StartServer(
|
||||||
StringRef persist_filename,
|
StringRef persist_filename,
|
||||||
std::unique_ptr<wpi::NetworkAcceptor> acceptor) {
|
std::unique_ptr<wpi::NetworkAcceptor> acceptor) {
|
||||||
@@ -83,7 +87,7 @@ void DispatcherBase::StartServer(
|
|||||||
if (m_active) return;
|
if (m_active) return;
|
||||||
m_active = true;
|
m_active = true;
|
||||||
}
|
}
|
||||||
m_server = true;
|
m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
|
||||||
m_persist_filename = persist_filename;
|
m_persist_filename = persist_filename;
|
||||||
m_server_acceptor = std::move(acceptor);
|
m_server_acceptor = std::move(acceptor);
|
||||||
|
|
||||||
@@ -103,7 +107,7 @@ void DispatcherBase::StartServer(
|
|||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
m_storage.SetOutgoing(std::bind(&Dispatcher::QueueOutgoing, this, _1, _2, _3),
|
m_storage.SetOutgoing(std::bind(&Dispatcher::QueueOutgoing, this, _1, _2, _3),
|
||||||
m_server);
|
(m_networkMode & NT_NET_MODE_SERVER) != 0);
|
||||||
|
|
||||||
m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
|
m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
|
||||||
m_clientserver_thread = std::thread(&Dispatcher::ServerThreadMain, this);
|
m_clientserver_thread = std::thread(&Dispatcher::ServerThreadMain, this);
|
||||||
@@ -115,10 +119,10 @@ void DispatcherBase::StartClient() {
|
|||||||
if (m_active) return;
|
if (m_active) return;
|
||||||
m_active = true;
|
m_active = true;
|
||||||
}
|
}
|
||||||
m_server = false;
|
m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_STARTING;
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
m_storage.SetOutgoing(std::bind(&Dispatcher::QueueOutgoing, this, _1, _2, _3),
|
m_storage.SetOutgoing(std::bind(&Dispatcher::QueueOutgoing, this, _1, _2, _3),
|
||||||
m_server);
|
(m_networkMode & NT_NET_MODE_SERVER) != 0);
|
||||||
|
|
||||||
m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
|
m_dispatch_thread = std::thread(&Dispatcher::DispatchThreadMain, this);
|
||||||
m_clientserver_thread = std::thread(&Dispatcher::ClientThreadMain, this);
|
m_clientserver_thread = std::thread(&Dispatcher::ClientThreadMain, this);
|
||||||
@@ -243,7 +247,7 @@ void DispatcherBase::DispatchThreadMain() {
|
|||||||
if (!m_active) break; // in case we were woken up to terminate
|
if (!m_active) break; // in case we were woken up to terminate
|
||||||
|
|
||||||
// perform periodic persistent save
|
// perform periodic persistent save
|
||||||
if (m_server && !m_persist_filename.empty() && start > next_save_time) {
|
if ((m_networkMode & NT_NET_MODE_SERVER) != 0 && !m_persist_filename.empty() && start > next_save_time) {
|
||||||
next_save_time += save_delta_time;
|
next_save_time += save_delta_time;
|
||||||
// handle loop taking too long
|
// handle loop taking too long
|
||||||
if (start > next_save_time) next_save_time = start + save_delta_time;
|
if (start > next_save_time) next_save_time = start + save_delta_time;
|
||||||
@@ -264,10 +268,10 @@ void DispatcherBase::DispatchThreadMain() {
|
|||||||
// post outgoing messages if connection is active
|
// post outgoing messages if connection is active
|
||||||
// only send keep-alives on client
|
// only send keep-alives on client
|
||||||
if (conn->state() == NetworkConnection::kActive)
|
if (conn->state() == NetworkConnection::kActive)
|
||||||
conn->PostOutgoing(!m_server);
|
conn->PostOutgoing((m_networkMode & NT_NET_MODE_CLIENT) != 0);
|
||||||
|
|
||||||
// if client, reconnect if connection died
|
// if client, reconnect if connection died
|
||||||
if (!m_server && conn->state() == NetworkConnection::kDead)
|
if ((m_networkMode & NT_NET_MODE_CLIENT) != 0 && conn->state() == NetworkConnection::kDead)
|
||||||
reconnect = true;
|
reconnect = true;
|
||||||
}
|
}
|
||||||
// reconnect if we disconnected (and a reconnect is not in progress)
|
// reconnect if we disconnected (and a reconnect is not in progress)
|
||||||
@@ -297,15 +301,20 @@ void DispatcherBase::QueueOutgoing(std::shared_ptr<Message> msg,
|
|||||||
void DispatcherBase::ServerThreadMain() {
|
void DispatcherBase::ServerThreadMain() {
|
||||||
if (m_server_acceptor->start() != 0) {
|
if (m_server_acceptor->start() != 0) {
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_FAILURE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_networkMode = NT_NET_MODE_SERVER;
|
||||||
while (m_active) {
|
while (m_active) {
|
||||||
auto stream = m_server_acceptor->accept();
|
auto stream = m_server_acceptor->accept();
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
m_active = false;
|
m_active = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_active) return;
|
if (!m_active) {
|
||||||
|
m_networkMode = NT_NET_MODE_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
DEBUG("server: client connection from " << stream->getPeerIP() << " port "
|
DEBUG("server: client connection from " << stream->getPeerIP() << " port "
|
||||||
<< stream->getPeerPort());
|
<< stream->getPeerPort());
|
||||||
|
|
||||||
@@ -333,6 +342,7 @@ void DispatcherBase::ServerThreadMain() {
|
|||||||
conn->Start();
|
conn->Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_networkMode = NT_NET_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispatcherBase::ClientThreadMain() {
|
void DispatcherBase::ClientThreadMain() {
|
||||||
@@ -348,7 +358,10 @@ void DispatcherBase::ClientThreadMain() {
|
|||||||
if (m_client_connector_override) {
|
if (m_client_connector_override) {
|
||||||
connect = m_client_connector_override;
|
connect = m_client_connector_override;
|
||||||
} else {
|
} else {
|
||||||
if (m_client_connectors.empty()) continue;
|
if (m_client_connectors.empty()) {
|
||||||
|
m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_FAILURE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (i >= m_client_connectors.size()) i = 0;
|
if (i >= m_client_connectors.size()) i = 0;
|
||||||
connect = m_client_connectors[i++];
|
connect = m_client_connectors[i++];
|
||||||
}
|
}
|
||||||
@@ -357,8 +370,12 @@ void DispatcherBase::ClientThreadMain() {
|
|||||||
// try to connect (with timeout)
|
// try to connect (with timeout)
|
||||||
DEBUG("client trying to connect");
|
DEBUG("client trying to connect");
|
||||||
auto stream = connect();
|
auto stream = connect();
|
||||||
if (!stream) continue; // keep retrying
|
if (!stream) {
|
||||||
|
m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_FAILURE;
|
||||||
|
continue; // keep retrying
|
||||||
|
}
|
||||||
DEBUG("client connected");
|
DEBUG("client connected");
|
||||||
|
m_networkMode = NT_NET_MODE_CLIENT;
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(m_user_mutex);
|
std::unique_lock<std::mutex> lock(m_user_mutex);
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
@@ -381,6 +398,7 @@ void DispatcherBase::ClientThreadMain() {
|
|||||||
m_do_reconnect = false;
|
m_do_reconnect = false;
|
||||||
m_reconnect_cv.wait(lock, [&] { return !m_active || m_do_reconnect; });
|
m_reconnect_cv.wait(lock, [&] { return !m_active || m_do_reconnect; });
|
||||||
}
|
}
|
||||||
|
m_networkMode = NT_NET_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DispatcherBase::ClientHandshake(
|
bool DispatcherBase::ClientHandshake(
|
||||||
@@ -551,7 +569,7 @@ bool DispatcherBase::ServerHandshake(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DispatcherBase::ClientReconnect(unsigned int proto_rev) {
|
void DispatcherBase::ClientReconnect(unsigned int proto_rev) {
|
||||||
if (m_server) return;
|
if ((m_networkMode & NT_NET_MODE_SERVER) != 0) return;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_user_mutex);
|
std::lock_guard<std::mutex> lock(m_user_mutex);
|
||||||
m_reconnect_proto_rev = proto_rev;
|
m_reconnect_proto_rev = proto_rev;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class DispatcherBase {
|
|||||||
|
|
||||||
virtual ~DispatcherBase();
|
virtual ~DispatcherBase();
|
||||||
|
|
||||||
|
unsigned int GetNetworkMode() const;
|
||||||
void StartServer(llvm::StringRef persist_filename,
|
void StartServer(llvm::StringRef persist_filename,
|
||||||
std::unique_ptr<wpi::NetworkAcceptor> acceptor);
|
std::unique_ptr<wpi::NetworkAcceptor> acceptor);
|
||||||
void StartClient();
|
void StartClient();
|
||||||
@@ -84,7 +85,7 @@ class DispatcherBase {
|
|||||||
|
|
||||||
Storage& m_storage;
|
Storage& m_storage;
|
||||||
Notifier& m_notifier;
|
Notifier& m_notifier;
|
||||||
bool m_server = false;
|
unsigned int m_networkMode = NT_NET_MODE_NONE;
|
||||||
std::string m_persist_filename;
|
std::string m_persist_filename;
|
||||||
std::thread m_dispatch_thread;
|
std::thread m_dispatch_thread;
|
||||||
std::thread m_clientserver_thread;
|
std::thread m_clientserver_thread;
|
||||||
|
|||||||
@@ -365,6 +365,10 @@ void NT_SetNetworkIdentity(const char* name, size_t name_len) {
|
|||||||
nt::SetNetworkIdentity(StringRef(name, name_len));
|
nt::SetNetworkIdentity(StringRef(name, name_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int NT_GetNetworkMode() {
|
||||||
|
return nt::GetNetworkMode();
|
||||||
|
}
|
||||||
|
|
||||||
void NT_StartServer(const char* persist_filename, const char* listen_address,
|
void NT_StartServer(const char* persist_filename, const char* listen_address,
|
||||||
unsigned int port) {
|
unsigned int port) {
|
||||||
nt::StartServer(persist_filename, listen_address, port);
|
nt::StartServer(persist_filename, listen_address, port);
|
||||||
|
|||||||
@@ -240,6 +240,11 @@ void SetNetworkIdentity(StringRef name) {
|
|||||||
Dispatcher::GetInstance().SetIdentity(name);
|
Dispatcher::GetInstance().SetIdentity(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int GetNetworkMode() {
|
||||||
|
auto& d = Dispatcher::GetInstance();
|
||||||
|
return d.GetNetworkMode();
|
||||||
|
}
|
||||||
|
|
||||||
void StartServer(StringRef persist_filename, const char* listen_address,
|
void StartServer(StringRef persist_filename, const char* listen_address,
|
||||||
unsigned int port) {
|
unsigned int port) {
|
||||||
Dispatcher::GetInstance().StartServer(persist_filename, listen_address, port);
|
Dispatcher::GetInstance().StartServer(persist_filename, listen_address, port);
|
||||||
|
|||||||
Reference in New Issue
Block a user