Skip to content

Commit

Permalink
fix: assign random MAC address to PS5 joypad in order to support mult…
Browse files Browse the repository at this point in the history
…iple virtual joypads
  • Loading branch information
ABeltramo committed May 19, 2024
1 parent fb1a9fa commit 528bfed
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/uhid/include/uhid/protected_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
namespace inputtino {
struct PS5JoypadState {
std::shared_ptr<uhid::Device> dev;
/**
* This will be the MAC address of the device
*
* IMPORTANT: this needs to be unique for each virtual device,
* otherwise the kernel driver will return an error:
* "Duplicate device found for MAC address XX:XX:XX:XX"
*
* We also use this information internally to unique match a device with the
* /dev/input/devXX files; see get_nodes()
*/
unsigned char mac_address[6] = {
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};

uhid::dualsense_input_report_usb current_state;
uint8_t touch_points_ids[2] = {0};
Expand Down
19 changes: 18 additions & 1 deletion src/uhid/joypad_ps5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <uhid/protected_types.hpp>
#include <uhid/ps5.hpp>
#include <uhid/uhid.hpp>
#include <random>

namespace inputtino {

Expand Down Expand Up @@ -51,6 +52,12 @@ static void on_uhid_event(std::shared_ptr<PS5JoypadState> state, uhid_event ev,
std::copy(&uhid::ps5_pairing_info[0],
&uhid::ps5_pairing_info[0] + sizeof(uhid::ps5_pairing_info),
&answer.u.get_report_reply.data[0]);

// Copy MAC address data
std::reverse_copy(&state->mac_address[0],
&state->mac_address[0] + sizeof(state->mac_address),
&answer.u.get_report_reply.data[1]);

answer.u.get_report_reply.size = sizeof(uhid::ps5_pairing_info);
break;
}
Expand Down Expand Up @@ -100,7 +107,17 @@ static void on_uhid_event(std::shared_ptr<PS5JoypadState> state, uhid_event ev,
}
}

PS5Joypad::PS5Joypad() : _state(std::make_shared<PS5JoypadState>()) {}
void generate_mac_address(PS5JoypadState *state) {
std::default_random_engine generator;
std::uniform_int_distribution<unsigned char> distribution(0, 0xFF);
for (int i = 0; i < 6; i++) {
state->mac_address[i] = distribution(generator);
}
}

PS5Joypad::PS5Joypad() : _state(std::make_shared<PS5JoypadState>()) {
generate_mac_address(this->_state.get());
}

PS5Joypad::~PS5Joypad() {
if (this->_state && this->_state->dev) {
Expand Down

0 comments on commit 528bfed

Please sign in to comment.