Skip to content

Commit 14027a8

Browse files
committed
feat: properly control MAC address generation
1 parent 1f3dd23 commit 14027a8

File tree

4 files changed

+44
-16
lines changed

4 files changed

+44
-16
lines changed

include/inputtino/input.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <map>
77
#include <memory>
88
#include <optional>
9+
#include <random>
910
#include <string>
1011
#include <thread>
1112
#include <vector>
@@ -453,6 +454,13 @@ class PS5Joypad : public Joypad {
453454

454455
private:
455456
std::thread _send_input_thread;
456-
PS5Joypad(uint16_t vendor_id);
457+
458+
static std::array<unsigned char, 6> generate_mac_address() {
459+
auto rand = std::bind(std::uniform_int_distribution<unsigned char>{0, 0xFF},
460+
std::default_random_engine{std::random_device()()});
461+
return {rand(), rand(), rand(), rand(), rand(), rand()};
462+
};
463+
464+
PS5Joypad(uint16_t vendor_id, std::array<unsigned char, 6> mac_address = generate_mac_address());
457465
};
458466
} // namespace inputtino

src/uhid/joypad_ps5.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,9 @@ static void on_uhid_event(std::shared_ptr<PS5JoypadState> state, uhid_event ev,
216216
}
217217
}
218218

219-
void generate_mac_address(PS5JoypadState *state) {
220-
auto rand = std::bind(std::uniform_int_distribution<unsigned char>{0, 0xFF},
221-
std::default_random_engine{std::random_device()()});
222-
for (int i = 0; i < 6; i++) {
223-
state->mac_address[i] = rand();
224-
}
225-
}
226-
227-
PS5Joypad::PS5Joypad(uint16_t vendor_id) : _state(std::make_shared<PS5JoypadState>()) {
228-
generate_mac_address(this->_state.get());
219+
PS5Joypad::PS5Joypad(uint16_t vendor_id, std::array<unsigned char, 6> mac_address)
220+
: _state(std::make_shared<PS5JoypadState>()) {
221+
std::copy(mac_address.begin(), mac_address.end(), this->_state->mac_address);
229222
this->_state->vendor_id = vendor_id;
230223
// Set touchpad as not pressed
231224
this->_state->current_state.points[0].contact = 1;
@@ -265,10 +258,24 @@ Result<PS5Joypad> PS5Joypad::create(const DeviceDefinition &device) {
265258
def.report_description = {&uhid::ps5_rdesc[0], &uhid::ps5_rdesc[0] + sizeof(uhid::ps5_rdesc)};
266259
}
267260

268-
auto joypad = PS5Joypad(device.vendor_id);
261+
std::array<unsigned char, 6> mac_address = {};
262+
if (def.uniq.empty()) {
263+
mac_address = generate_mac_address();
264+
} else {
265+
// Assuming we have in input a MAC address in the format of xx:xx:xx:xx:xx:xx
266+
std::stringstream ss(def.uniq);
267+
for (int i = 0; i < 6; ++i) {
268+
unsigned int value;
269+
ss >> std::hex >> value;
270+
mac_address[i] = static_cast<unsigned char>(value);
271+
if (i < 5)
272+
ss.ignore(1, ':');
273+
}
274+
}
275+
auto joypad = PS5Joypad(device.vendor_id, mac_address);
269276

270277
if (def.phys.empty()) {
271-
def.phys = joypad.get_mac_address();
278+
def.phys = "INPUTTINO_BT_LINK";
272279
}
273280
if (def.uniq.empty()) {
274281
def.uniq = joypad.get_mac_address();

src/uinput/joypad_ps.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ Result<libevdev_uinput_ptr> create_ps_controller(const DeviceDefinition &device)
7979
return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
8080
}
8181

82-
PS5Joypad::PS5Joypad(uint16_t vendor_id) : _state(std::make_shared<PS5JoypadState>()) {}
82+
PS5Joypad::PS5Joypad(uint16_t vendor_id, std::array<unsigned char, 6> mac_address) : _state(std::make_shared<PS5JoypadState>()) {
83+
}
8384

8485
PS5Joypad::~PS5Joypad() {
8586
if (_state) {

tests/testUHID.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class SDLTestsFixture {
5757
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR | SDL_INIT_EVENTS) <
5858
0) {
5959
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
60-
}
60+
}
6161
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
6262
SDL_GameControllerEventState(SDL_ENABLE);
6363
}
@@ -67,7 +67,6 @@ class SDLTestsFixture {
6767
}
6868
};
6969

70-
7170
#define SDL_TEST_BUTTON(JOYPAD_BTN, SDL_BTN) \
7271
REQUIRE(SDL_GameControllerGetButton(gc, SDL_BTN) == 0); \
7372
joypad.set_pressed_buttons(JOYPAD_BTN); \
@@ -467,4 +466,17 @@ TEST_CASE("Bluetooth CRC32", "[PS]") {
467466
auto crc2 = CRC32(&PS_INPUT_CRC32_SEED, 1, 0xFFFFFFFF);
468467
crc2 = CRC32(reinterpret_cast<unsigned char *>(buffer.data()), buffer.length(), crc2);
469468
REQUIRE(crc2 == 0x9498b398);
469+
}
470+
471+
TEST_CASE("Test MAC address", "[PS]") {
472+
DeviceDefinition def = {.name = "Wolf DualSense (virtual) pad",
473+
.vendor_id = 0x054C,
474+
.product_id = 0x0CE6,
475+
.version = 0x8111,
476+
.device_uniq = "AA:00:CC:11:EE:22"};
477+
478+
auto joypad = std::move(*PS5Joypad::create(def));
479+
480+
std::this_thread::sleep_for(50ms);
481+
REQUIRE_THAT(joypad.get_mac_address(), Equals("aa:00:cc:11:ee:22"));
470482
}

0 commit comments

Comments
 (0)