mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +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 */
|
||||
};
|
||||
|
||||
/** 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
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
* Get the current network mode.
|
||||
*/
|
||||
unsigned int NT_GetNetworkMode();
|
||||
|
||||
/** Start Server
|
||||
* 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
|
||||
*/
|
||||
void SetNetworkIdentity(StringRef name);
|
||||
unsigned int GetNetworkMode();
|
||||
void StartServer(StringRef persist_filename, const char* listen_address,
|
||||
unsigned int port);
|
||||
void StopServer();
|
||||
|
||||
@@ -1502,6 +1502,17 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||
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
|
||||
* 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 int getType(String key);
|
||||
|
||||
@@ -148,6 +154,7 @@ public class NetworkTablesJNI {
|
||||
// public static native byte[] getRpcResultNonblocking(int callUid) throws RpcNoResponseException;
|
||||
|
||||
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 stopServer();
|
||||
public static native void startClient();
|
||||
|
||||
@@ -119,6 +119,8 @@ NT_StartDSClient @119
|
||||
NT_StopDSClient @120
|
||||
NT_StartClientNone @121
|
||||
|
||||
NT_GetNetworkMode @122
|
||||
|
||||
; JNI functions
|
||||
JNI_OnLoad
|
||||
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_setDefaultDoubleArray
|
||||
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_StopDSClient @120
|
||||
NT_StartClientNone @121
|
||||
|
||||
NT_GetNetworkMode @122
|
||||
|
||||
@@ -75,6 +75,10 @@ DispatcherBase::~DispatcherBase() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
unsigned int DispatcherBase::GetNetworkMode() const {
|
||||
return m_networkMode;
|
||||
}
|
||||
|
||||
void DispatcherBase::StartServer(
|
||||
StringRef persist_filename,
|
||||
std::unique_ptr<wpi::NetworkAcceptor> acceptor) {
|
||||
@@ -83,7 +87,7 @@ void DispatcherBase::StartServer(
|
||||
if (m_active) return;
|
||||
m_active = true;
|
||||
}
|
||||
m_server = true;
|
||||
m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
|
||||
m_persist_filename = persist_filename;
|
||||
m_server_acceptor = std::move(acceptor);
|
||||
|
||||
@@ -103,7 +107,7 @@ void DispatcherBase::StartServer(
|
||||
|
||||
using namespace std::placeholders;
|
||||
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_clientserver_thread = std::thread(&Dispatcher::ServerThreadMain, this);
|
||||
@@ -115,10 +119,10 @@ void DispatcherBase::StartClient() {
|
||||
if (m_active) return;
|
||||
m_active = true;
|
||||
}
|
||||
m_server = false;
|
||||
m_networkMode = NT_NET_MODE_CLIENT | NT_NET_MODE_STARTING;
|
||||
using namespace std::placeholders;
|
||||
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_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
|
||||
|
||||
// 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;
|
||||
// handle loop taking too long
|
||||
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
|
||||
// only send keep-alives on client
|
||||
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 (!m_server && conn->state() == NetworkConnection::kDead)
|
||||
if ((m_networkMode & NT_NET_MODE_CLIENT) != 0 && conn->state() == NetworkConnection::kDead)
|
||||
reconnect = true;
|
||||
}
|
||||
// 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() {
|
||||
if (m_server_acceptor->start() != 0) {
|
||||
m_active = false;
|
||||
m_networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_FAILURE;
|
||||
return;
|
||||
}
|
||||
m_networkMode = NT_NET_MODE_SERVER;
|
||||
while (m_active) {
|
||||
auto stream = m_server_acceptor->accept();
|
||||
if (!stream) {
|
||||
m_active = false;
|
||||
return;
|
||||
}
|
||||
if (!m_active) return;
|
||||
if (!m_active) {
|
||||
m_networkMode = NT_NET_MODE_NONE;
|
||||
return;
|
||||
}
|
||||
DEBUG("server: client connection from " << stream->getPeerIP() << " port "
|
||||
<< stream->getPeerPort());
|
||||
|
||||
@@ -333,6 +342,7 @@ void DispatcherBase::ServerThreadMain() {
|
||||
conn->Start();
|
||||
}
|
||||
}
|
||||
m_networkMode = NT_NET_MODE_NONE;
|
||||
}
|
||||
|
||||
void DispatcherBase::ClientThreadMain() {
|
||||
@@ -348,7 +358,10 @@ void DispatcherBase::ClientThreadMain() {
|
||||
if (m_client_connector_override) {
|
||||
connect = m_client_connector_override;
|
||||
} 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;
|
||||
connect = m_client_connectors[i++];
|
||||
}
|
||||
@@ -357,8 +370,12 @@ void DispatcherBase::ClientThreadMain() {
|
||||
// try to connect (with timeout)
|
||||
DEBUG("client trying to 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");
|
||||
m_networkMode = NT_NET_MODE_CLIENT;
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_user_mutex);
|
||||
using namespace std::placeholders;
|
||||
@@ -381,6 +398,7 @@ void DispatcherBase::ClientThreadMain() {
|
||||
m_do_reconnect = false;
|
||||
m_reconnect_cv.wait(lock, [&] { return !m_active || m_do_reconnect; });
|
||||
}
|
||||
m_networkMode = NT_NET_MODE_NONE;
|
||||
}
|
||||
|
||||
bool DispatcherBase::ClientHandshake(
|
||||
@@ -551,7 +569,7 @@ bool DispatcherBase::ServerHandshake(
|
||||
}
|
||||
|
||||
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);
|
||||
m_reconnect_proto_rev = proto_rev;
|
||||
|
||||
@@ -39,6 +39,7 @@ class DispatcherBase {
|
||||
|
||||
virtual ~DispatcherBase();
|
||||
|
||||
unsigned int GetNetworkMode() const;
|
||||
void StartServer(llvm::StringRef persist_filename,
|
||||
std::unique_ptr<wpi::NetworkAcceptor> acceptor);
|
||||
void StartClient();
|
||||
@@ -84,7 +85,7 @@ class DispatcherBase {
|
||||
|
||||
Storage& m_storage;
|
||||
Notifier& m_notifier;
|
||||
bool m_server = false;
|
||||
unsigned int m_networkMode = NT_NET_MODE_NONE;
|
||||
std::string m_persist_filename;
|
||||
std::thread m_dispatch_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));
|
||||
}
|
||||
|
||||
unsigned int NT_GetNetworkMode() {
|
||||
return nt::GetNetworkMode();
|
||||
}
|
||||
|
||||
void NT_StartServer(const char* persist_filename, const char* listen_address,
|
||||
unsigned int port) {
|
||||
nt::StartServer(persist_filename, listen_address, port);
|
||||
|
||||
@@ -240,6 +240,11 @@ void SetNetworkIdentity(StringRef name) {
|
||||
Dispatcher::GetInstance().SetIdentity(name);
|
||||
}
|
||||
|
||||
unsigned int GetNetworkMode() {
|
||||
auto& d = Dispatcher::GetInstance();
|
||||
return d.GetNetworkMode();
|
||||
}
|
||||
|
||||
void StartServer(StringRef persist_filename, const char* listen_address,
|
||||
unsigned int port) {
|
||||
Dispatcher::GetInstance().StartServer(persist_filename, listen_address, port);
|
||||
|
||||
Reference in New Issue
Block a user