mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[hal] WS Simulation: Add message filtering capability (#5395)
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpinet/uv/util.h>
|
||||
|
||||
#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<std::string_view, 16> 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;
|
||||
}
|
||||
|
||||
@@ -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<const std::string&>();
|
||||
if (!m_client->CanSendMessage(type)) {
|
||||
return;
|
||||
}
|
||||
} catch (wpi::json::exception& e) {
|
||||
fmt::print(stderr, "Error with message: {}\n", e.what());
|
||||
}
|
||||
|
||||
wpi::SmallVector<uv::Buffer, 4> sendBufs;
|
||||
wpi::raw_uv_ostream os{sendBufs, [this]() -> uv::Buffer {
|
||||
std::lock_guard lock(m_buffers_mutex);
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <WSProviderContainer.h>
|
||||
#include <WSProvider_SimDevice.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpinet/uv/Async.h>
|
||||
#include <wpinet/uv/Loop.h>
|
||||
#include <wpinet/uv/Tcp.h>
|
||||
@@ -41,6 +43,8 @@ class HALSimWS : public std::enable_shared_from_this<HALSimWS> {
|
||||
|
||||
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<HALSimWS> {
|
||||
std::string m_host;
|
||||
std::string m_uri;
|
||||
int m_port;
|
||||
|
||||
bool m_useMsgFiltering;
|
||||
wpi::StringMap<bool> m_msgFilters;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
|
||||
@@ -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<const std::string&>();
|
||||
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<uv::Buffer, 4> sendBufs;
|
||||
wpi::raw_uv_ostream os{sendBufs, [this]() -> uv::Buffer {
|
||||
|
||||
@@ -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<std::string_view, 16> 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;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <WSBaseProvider.h>
|
||||
#include <WSProviderContainer.h>
|
||||
#include <WSProvider_SimDevice.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpinet/uv/Async.h>
|
||||
#include <wpinet/uv/Loop.h>
|
||||
#include <wpinet/uv/Tcp.h>
|
||||
@@ -41,6 +43,8 @@ class HALSimWeb : public std::enable_shared_from_this<HALSimWeb> {
|
||||
// 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<HALSimWeb> {
|
||||
|
||||
std::string m_uri;
|
||||
int m_port;
|
||||
|
||||
bool m_useMsgFiltering;
|
||||
wpi::StringMap<bool> m_msgFilters;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
|
||||
Reference in New Issue
Block a user