diff --git a/simulation/halsim_ws_client/src/main/native/cpp/HALSimWS.cpp b/simulation/halsim_ws_client/src/main/native/cpp/HALSimWS.cpp index f4c5926f96..bc38c3cc50 100644 --- a/simulation/halsim_ws_client/src/main/native/cpp/HALSimWS.cpp +++ b/simulation/halsim_ws_client/src/main/native/cpp/HALSimWS.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include "HALSimWSClientConnection.h" @@ -66,6 +68,22 @@ bool HALSimWS::Initialize() { m_uri = "/wpilibws"; } + const char* msgFilters = std::getenv("HALSIMWS_FILTERS"); + if (msgFilters != nullptr) { + m_useMsgFiltering = true; + + std::string_view filters(msgFilters); + filters = wpi::trim(filters); + wpi::SmallVector filtersSplit; + + wpi::split(filters, filtersSplit, ',', -1, false); + for (auto val : filtersSplit) { + m_msgFilters[wpi::trim(val)] = true; + } + } else { + m_useMsgFiltering = false; + } + return true; } @@ -87,8 +105,19 @@ void HALSimWS::Start() { m_tcp_client->closed.connect([]() { std::puts("TCP connection closed"); }); - // Set up the connection timer std::puts("HALSimWS Initialized"); + + // Print any filters we are using + if (m_useMsgFiltering) { + fmt::print("WS Message Filters:"); + for (auto filter : m_msgFilters.keys()) { + fmt::print("* \"{}\"\n", filter); + } + } else { + fmt::print("No WS Message Filters specified"); + } + + // Set up the connection timer fmt::print("Will attempt to connect to ws://{}:{}{}\n", m_host, m_port, m_uri); @@ -171,3 +200,10 @@ void HALSimWS::OnNetValueChanged(const wpi::json& msg) { fmt::print(stderr, "Error with incoming message: {}\n", e.what()); } } + +bool HALSimWS::CanSendMessage(std::string_view type) { + if (!m_useMsgFiltering) { + return true; + } + return m_msgFilters.count(type) > 0; +} diff --git a/simulation/halsim_ws_client/src/main/native/cpp/HALSimWSClientConnection.cpp b/simulation/halsim_ws_client/src/main/native/cpp/HALSimWSClientConnection.cpp index 10ea8af2e3..cba94c8df4 100644 --- a/simulation/halsim_ws_client/src/main/native/cpp/HALSimWSClientConnection.cpp +++ b/simulation/halsim_ws_client/src/main/native/cpp/HALSimWSClientConnection.cpp @@ -74,6 +74,17 @@ void HALSimWSClientConnection::OnSimValueChanged(const wpi::json& msg) { if (msg.empty()) { return; } + + // Skip sending if this message is not in the allowed filter list + try { + auto& type = msg.at("type").get_ref(); + if (!m_client->CanSendMessage(type)) { + return; + } + } catch (wpi::json::exception& e) { + fmt::print(stderr, "Error with message: {}\n", e.what()); + } + wpi::SmallVector sendBufs; wpi::raw_uv_ostream os{sendBufs, [this]() -> uv::Buffer { std::lock_guard lock(m_buffers_mutex); diff --git a/simulation/halsim_ws_client/src/main/native/include/HALSimWS.h b/simulation/halsim_ws_client/src/main/native/include/HALSimWS.h index 5bec17cdbb..9be891967f 100644 --- a/simulation/halsim_ws_client/src/main/native/include/HALSimWS.h +++ b/simulation/halsim_ws_client/src/main/native/include/HALSimWS.h @@ -7,9 +7,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -41,6 +43,8 @@ class HALSimWS : public std::enable_shared_from_this { void OnNetValueChanged(const wpi::json& msg); + bool CanSendMessage(std::string_view type); + const std::string& GetTargetHost() const { return m_host; } const std::string& GetTargetUri() const { return m_uri; } int GetTargetPort() const { return m_port; } @@ -67,6 +71,9 @@ class HALSimWS : public std::enable_shared_from_this { std::string m_host; std::string m_uri; int m_port; + + bool m_useMsgFiltering; + wpi::StringMap m_msgFilters; }; } // namespace wpilibws diff --git a/simulation/halsim_ws_server/src/main/native/cpp/HALSimHttpConnection.cpp b/simulation/halsim_ws_server/src/main/native/cpp/HALSimHttpConnection.cpp index 77dec08f0c..ba4212171c 100644 --- a/simulation/halsim_ws_server/src/main/native/cpp/HALSimHttpConnection.cpp +++ b/simulation/halsim_ws_server/src/main/native/cpp/HALSimHttpConnection.cpp @@ -76,6 +76,16 @@ void HALSimHttpConnection::ProcessWsUpgrade() { } void HALSimHttpConnection::OnSimValueChanged(const wpi::json& msg) { + // Skip sending if this message is not in the allowed filter list + try { + auto& type = msg.at("type").get_ref(); + if (!m_server->CanSendMessage(type)) { + return; + } + } catch (wpi::json::exception& e) { + fmt::print(stderr, "Error with message: {}\n", e.what()); + } + // render json to buffers wpi::SmallVector sendBufs; wpi::raw_uv_ostream os{sendBufs, [this]() -> uv::Buffer { diff --git a/simulation/halsim_ws_server/src/main/native/cpp/HALSimWeb.cpp b/simulation/halsim_ws_server/src/main/native/cpp/HALSimWeb.cpp index 8a6df97810..790d0b5790 100644 --- a/simulation/halsim_ws_server/src/main/native/cpp/HALSimWeb.cpp +++ b/simulation/halsim_ws_server/src/main/native/cpp/HALSimWeb.cpp @@ -77,6 +77,22 @@ bool HALSimWeb::Initialize() { m_port = 3300; } + const char* msgFilters = std::getenv("HALSIMWS_FILTERS"); + if (msgFilters != nullptr) { + m_useMsgFiltering = true; + + std::string_view filters(msgFilters); + filters = wpi::trim(filters); + wpi::SmallVector filtersSplit; + + wpi::split(filters, filtersSplit, ',', -1, false); + for (auto val : filtersSplit) { + m_msgFilters[wpi::trim(val)] = true; + } + } else { + m_useMsgFiltering = false; + } + return true; } @@ -100,6 +116,16 @@ void HALSimWeb::Start() { m_server->Listen(); fmt::print("Listening at http://localhost:{}\n", m_port); fmt::print("WebSocket URI: {}\n", m_uri); + + // Print any filters we are using + if (m_useMsgFiltering) { + fmt::print("WS Message Filters:"); + for (auto filter : m_msgFilters.keys()) { + fmt::print("* \"{}\"\n", filter); + } + } else { + fmt::print("No WS Message Filters specified"); + } } bool HALSimWeb::RegisterWebsocket( @@ -157,3 +183,10 @@ void HALSimWeb::OnNetValueChanged(const wpi::json& msg) { fmt::print(stderr, "Error with incoming message: {}\n", e.what()); } } + +bool HALSimWeb::CanSendMessage(std::string_view type) { + if (!m_useMsgFiltering) { + return true; + } + return m_msgFilters.count(type) > 0; +} diff --git a/simulation/halsim_ws_server/src/main/native/include/HALSimWeb.h b/simulation/halsim_ws_server/src/main/native/include/HALSimWeb.h index de5d1f227a..6f0efaf632 100644 --- a/simulation/halsim_ws_server/src/main/native/include/HALSimWeb.h +++ b/simulation/halsim_ws_server/src/main/native/include/HALSimWeb.h @@ -7,10 +7,12 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -41,6 +43,8 @@ class HALSimWeb : public std::enable_shared_from_this { // network -> sim void OnNetValueChanged(const wpi::json& msg); + bool CanSendMessage(std::string_view type); + const std::string& GetWebrootSys() const { return m_webroot_sys; } const std::string& GetWebrootUser() const { return m_webroot_user; } const std::string& GetServerUri() const { return m_uri; } @@ -69,6 +73,9 @@ class HALSimWeb : public std::enable_shared_from_this { std::string m_uri; int m_port; + + bool m_useMsgFiltering; + wpi::StringMap m_msgFilters; }; } // namespace wpilibws