Merge pull request #6004 from german77/udprandom

InputCommon: Use an unique client id for each udp socket instance
This commit is contained in:
bunnei 2021-03-03 15:45:32 -08:00 committed by GitHub
commit 394475c4e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 19 deletions

View file

@ -5,6 +5,7 @@
#include <chrono> #include <chrono>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <random>
#include <thread> #include <thread>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "common/logging/log.h" #include "common/logging/log.h"
@ -26,10 +27,10 @@ class Socket {
public: public:
using clock = std::chrono::system_clock; using clock = std::chrono::system_clock;
explicit Socket(const std::string& host, u16 port, std::size_t pad_index_, u32 client_id_, explicit Socket(const std::string& host, u16 port, std::size_t pad_index_,
SocketCallback callback_) SocketCallback callback_)
: callback(std::move(callback_)), timer(io_service), : callback(std::move(callback_)), timer(io_service),
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id_), socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()),
pad_index(pad_index_) { pad_index(pad_index_) {
boost::system::error_code ec{}; boost::system::error_code ec{};
auto ipv4 = boost::asio::ip::make_address_v4(host, ec); auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
@ -63,6 +64,11 @@ public:
} }
private: private:
u32 GenerateRandomClientId() const {
std::random_device device;
return device();
}
void HandleReceive(const boost::system::error_code&, std::size_t bytes_transferred) { void HandleReceive(const boost::system::error_code&, std::size_t bytes_transferred) {
if (auto type = Response::Validate(receive_buffer.data(), bytes_transferred)) { if (auto type = Response::Validate(receive_buffer.data(), bytes_transferred)) {
switch (*type) { switch (*type) {
@ -115,7 +121,7 @@ private:
boost::asio::basic_waitable_timer<clock> timer; boost::asio::basic_waitable_timer<clock> timer;
udp::socket socket; udp::socket socket;
u32 client_id{}; const u32 client_id;
std::size_t pad_index{}; std::size_t pad_index{};
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>); static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
@ -203,7 +209,7 @@ void Client::ReloadSockets() {
LOG_ERROR(Input, "Duplicated UDP servers found"); LOG_ERROR(Input, "Duplicated UDP servers found");
continue; continue;
} }
StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872); StartCommunication(client++, udp_input_address, udp_input_port, pad);
} }
} }
} }
@ -277,7 +283,7 @@ void Client::OnPadData(Response::PadData data, std::size_t client) {
} }
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port, void Client::StartCommunication(std::size_t client, const std::string& host, u16 port,
std::size_t pad_index, u32 client_id) { std::size_t pad_index) {
SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
[this](Response::PortInfo info) { OnPortInfo(info); }, [this](Response::PortInfo info) { OnPortInfo(info); },
[this, client](Response::PadData data) { OnPadData(data, client); }}; [this, client](Response::PadData data) { OnPadData(data, client); }};
@ -287,7 +293,7 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
clients[client].port = port; clients[client].port = port;
clients[client].pad_index = pad_index; clients[client].pad_index = pad_index;
clients[client].active = 0; clients[client].active = 0;
clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); clients[client].socket = std::make_unique<Socket>(host, port, pad_index, callback);
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()}; clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
// Set motion parameters // Set motion parameters
// SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
@ -416,7 +422,7 @@ const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
return pad_queue; return pad_queue;
} }
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id, void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
const std::function<void()>& success_callback, const std::function<void()>& success_callback,
const std::function<void()>& failure_callback) { const std::function<void()>& failure_callback) {
std::thread([=] { std::thread([=] {
@ -426,7 +432,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
.port_info = [](Response::PortInfo) {}, .port_info = [](Response::PortInfo) {},
.pad_data = [&](Response::PadData) { success_event.Set(); }, .pad_data = [&](Response::PadData) { success_event.Set(); },
}; };
Socket socket{host, port, pad_index, client_id, std::move(callback)}; Socket socket{host, port, pad_index, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket}; std::thread worker_thread{SocketLoop, &socket};
const bool result = success_event.WaitFor(std::chrono::seconds(5)); const bool result = success_event.WaitFor(std::chrono::seconds(5));
socket.Stop(); socket.Stop();
@ -440,7 +446,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
} }
CalibrationConfigurationJob::CalibrationConfigurationJob( CalibrationConfigurationJob::CalibrationConfigurationJob(
const std::string& host, u16 port, std::size_t pad_index, u32 client_id, const std::string& host, u16 port, std::size_t pad_index,
std::function<void(Status)> status_callback, std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback) { std::function<void(u16, u16, u16, u16)> data_callback) {
@ -485,7 +491,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
complete_event.Set(); complete_event.Set();
} }
}}; }};
Socket socket{host, port, pad_index, client_id, std::move(callback)}; Socket socket{host, port, pad_index, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket}; std::thread worker_thread{SocketLoop, &socket};
complete_event.Wait(); complete_event.Wait();
socket.Stop(); socket.Stop();

View file

@ -126,7 +126,7 @@ private:
void OnPortInfo(Response::PortInfo); void OnPortInfo(Response::PortInfo);
void OnPadData(Response::PadData, std::size_t client); void OnPadData(Response::PadData, std::size_t client);
void StartCommunication(std::size_t client, const std::string& host, u16 port, void StartCommunication(std::size_t client, const std::string& host, u16 port,
std::size_t pad_index, u32 client_id); std::size_t pad_index);
void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc, void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
const Common::Vec3<float>& gyro); const Common::Vec3<float>& gyro);
@ -165,7 +165,7 @@ public:
* @param data_callback Called when calibration data is ready * @param data_callback Called when calibration data is ready
*/ */
explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index, explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index,
u32 client_id, std::function<void(Status)> status_callback, std::function<void(Status)> status_callback,
std::function<void(u16, u16, u16, u16)> data_callback); std::function<void(u16, u16, u16, u16)> data_callback);
~CalibrationConfigurationJob(); ~CalibrationConfigurationJob();
void Stop(); void Stop();
@ -174,7 +174,7 @@ private:
Common::Event complete_event; Common::Event complete_event;
}; };
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id, void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
const std::function<void()>& success_callback, const std::function<void()>& success_callback,
const std::function<void()>& failure_callback); const std::function<void()>& failure_callback);

View file

@ -24,7 +24,7 @@
CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent, CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
const std::string& host, u16 port, const std::string& host, u16 port,
u8 pad_index, u16 client_id) u8 pad_index)
: QDialog(parent) { : QDialog(parent) {
layout = new QVBoxLayout; layout = new QVBoxLayout;
status_label = new QLabel(tr("Communicating with the server...")); status_label = new QLabel(tr("Communicating with the server..."));
@ -41,7 +41,7 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
using namespace InputCommon::CemuhookUDP; using namespace InputCommon::CemuhookUDP;
job = std::make_unique<CalibrationConfigurationJob>( job = std::make_unique<CalibrationConfigurationJob>(
host, port, pad_index, client_id, host, port, pad_index,
[this](CalibrationConfigurationJob::Status status) { [this](CalibrationConfigurationJob::Status status) {
QString text; QString text;
switch (status) { switch (status) {
@ -218,7 +218,6 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
udp_test_in_progress = true; udp_test_in_progress = true;
InputCommon::CemuhookUDP::TestCommunication( InputCommon::CemuhookUDP::TestCommunication(
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0,
24872,
[this] { [this] {
LOG_INFO(Frontend, "UDP input test success"); LOG_INFO(Frontend, "UDP input test success");
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
@ -233,8 +232,7 @@ void ConfigureMotionTouch::OnConfigureTouchCalibration() {
ui->touch_calibration_config->setEnabled(false); ui->touch_calibration_config->setEnabled(false);
ui->touch_calibration_config->setText(tr("Configuring")); ui->touch_calibration_config->setText(tr("Configuring"));
CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(), CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(),
static_cast<u16>(ui->udp_port->text().toUInt()), 0, static_cast<u16>(ui->udp_port->text().toUInt()), 0);
24872);
dialog.exec(); dialog.exec();
if (dialog.completed) { if (dialog.completed) {
min_x = dialog.min_x; min_x = dialog.min_x;

View file

@ -30,7 +30,7 @@ class CalibrationConfigurationDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port, explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port,
u8 pad_index, u16 client_id); u8 pad_index);
~CalibrationConfigurationDialog() override; ~CalibrationConfigurationDialog() override;
private: private: