Skip to content

Commit

Permalink
Define UHID vendorId and productId from the client
Browse files Browse the repository at this point in the history
Let the client choose the USB ids, that it transmits in UHID_CREATE
requests.

PR #5623 <Genymobile/scrcpy#5623>
  • Loading branch information
rom1v committed Dec 7, 2024
1 parent b69438d commit e492b17
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 13 deletions.
14 changes: 10 additions & 4 deletions app/src/control_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, uint8_t *buf) {
return 2;
case SC_CONTROL_MSG_TYPE_UHID_CREATE:
sc_write16be(&buf[1], msg->uhid_create.id);
sc_write16be(&buf[3], msg->uhid_create.vendor_id);
sc_write16be(&buf[5], msg->uhid_create.product_id);

size_t index = 3;
size_t index = 7;
index += write_string_tiny(&buf[index], msg->uhid_create.name, 127);

sc_write16be(&buf[index], msg->uhid_create.report_desc_size);
Expand Down Expand Up @@ -278,9 +280,13 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
// Quote only if name is not null
const char *name = msg->uhid_create.name;
const char *quote = name ? "\"" : "";
LOG_CMSG("UHID create [%" PRIu16 "] name=%s%s%s "
"report_desc_size=%" PRIu16, msg->uhid_create.id,
quote, name, quote, msg->uhid_create.report_desc_size);
LOG_CMSG("UHID create [%" PRIu16 "] %04" PRIx16 ":%04" PRIx16
" name=%s%s%s report_desc_size=%" PRIu16,
msg->uhid_create.id,
msg->uhid_create.vendor_id,
msg->uhid_create.product_id,
quote, name, quote,
msg->uhid_create.report_desc_size);
break;
}
case SC_CONTROL_MSG_TYPE_UHID_INPUT: {
Expand Down
2 changes: 2 additions & 0 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ struct sc_control_msg {
} set_display_power;
struct {
uint16_t id;
uint16_t vendor_id;
uint16_t product_id;
const char *name; // pointer to static data
uint16_t report_desc_size;
const uint8_t *report_desc; // pointer to static data
Expand Down
5 changes: 5 additions & 0 deletions app/src/uhid/gamepad_uhid.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
/** Downcast gamepad processor to sc_gamepad_uhid */
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_uhid, gamepad_processor)

#define SC_GAMEPAD_UHID_VENDOR_ID 0
#define SC_GAMEPAD_UHID_PRODUCT_ID 0

static void
sc_gamepad_uhid_send_input(struct sc_gamepad_uhid *gamepad,
const struct sc_hid_input *hid_input,
Expand All @@ -30,6 +33,8 @@ sc_gamepad_uhid_send_open(struct sc_gamepad_uhid *gamepad,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = hid_open->hid_id;
msg.uhid_create.vendor_id = SC_GAMEPAD_UHID_VENDOR_ID;
msg.uhid_create.product_id = SC_GAMEPAD_UHID_PRODUCT_ID;
msg.uhid_create.name = hid_open->name;
msg.uhid_create.report_desc = hid_open->report_desc;
msg.uhid_create.report_desc_size = hid_open->report_desc_size;
Expand Down
2 changes: 2 additions & 0 deletions app/src/uhid/keyboard_uhid.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = SC_HID_ID_KEYBOARD;
msg.uhid_create.vendor_id = 0;
msg.uhid_create.product_id = 0;
msg.uhid_create.name = hid_open.name;
msg.uhid_create.report_desc = hid_open.report_desc;
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
Expand Down
2 changes: 2 additions & 0 deletions app/src/uhid/mouse_uhid.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = SC_HID_ID_MOUSE;
msg.uhid_create.vendor_id = 0;
msg.uhid_create.product_id = 0;
msg.uhid_create.name = hid_open.name;
msg.uhid_create.report_desc = hid_open.report_desc;
msg.uhid_create.report_desc_size = hid_open.report_desc_size;
Expand Down
6 changes: 5 additions & 1 deletion app/tests/test_control_msg_serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ static void test_serialize_uhid_create(void) {
.type = SC_CONTROL_MSG_TYPE_UHID_CREATE,
.uhid_create = {
.id = 42,
.vendor_id = 0x1234,
.product_id = 0x5678,
.name = "ABC",
.report_desc_size = sizeof(report_desc),
.report_desc = report_desc,
Expand All @@ -337,11 +339,13 @@ static void test_serialize_uhid_create(void) {

uint8_t buf[SC_CONTROL_MSG_MAX_SIZE];
size_t size = sc_control_msg_serialize(&msg, buf);
assert(size == 20);
assert(size == 24);

const uint8_t expected[] = {
SC_CONTROL_MSG_TYPE_UHID_CREATE,
0, 42, // id
0x12, 0x34, // vendor id
0x56, 0x78, // product id
3, // name size
65, 66, 67, // "ABC"
0, 11, // report desc size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public final class ControlMessage {
private int id;
private byte[] data;
private boolean on;
private int vendorId;
private int productId;

private ControlMessage() {
}
Expand Down Expand Up @@ -131,10 +133,12 @@ public static ControlMessage createEmpty(int type) {
return msg;
}

public static ControlMessage createUhidCreate(int id, String name, byte[] reportDesc) {
public static ControlMessage createUhidCreate(int id, int vendorId, int productId, String name, byte[] reportDesc) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_UHID_CREATE;
msg.id = id;
msg.vendorId = vendorId;
msg.productId = productId;
msg.text = name;
msg.data = reportDesc;
return msg;
Expand Down Expand Up @@ -237,4 +241,12 @@ public byte[] getData() {
public boolean getOn() {
return on;
}

public int getVendorId() {
return vendorId;
}

public int getProductId() {
return productId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,11 @@ private ControlMessage parseSetDisplayPower() throws IOException {

private ControlMessage parseUhidCreate() throws IOException {
int id = dis.readUnsignedShort();
int vendorId = dis.readUnsignedShort();
int productId = dis.readUnsignedShort();
String name = parseString(1);
byte[] data = parseByteArray(2);
return ControlMessage.createUhidCreate(id, name, data);
return ControlMessage.createUhidCreate(id, vendorId, productId, name, data);
}

private ControlMessage parseUhidInput() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ private boolean handleEvent() throws IOException {
Device.rotateDevice(getActionDisplayId());
break;
case ControlMessage.TYPE_UHID_CREATE:
getUhidManager().open(msg.getId(), msg.getText(), msg.getData());
getUhidManager().open(msg.getId(), msg.getVendorId(), msg.getProductId(), msg.getText(), msg.getData());
break;
case ControlMessage.TYPE_UHID_INPUT:
getUhidManager().writeInput(msg.getId(), msg.getData());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public UhidManager(DeviceMessageSender sender) {
}
}

public void open(int id, String name, byte[] reportDesc) throws IOException {
public void open(int id, int vendorId, int productId, String name, byte[] reportDesc) throws IOException {
try {
FileDescriptor fd = Os.open("/dev/uhid", OsConstants.O_RDWR, 0);
try {
Expand All @@ -58,7 +58,7 @@ public void open(int id, String name, byte[] reportDesc) throws IOException {
close(old);
}

byte[] req = buildUhidCreate2Req(name, reportDesc);
byte[] req = buildUhidCreate2Req(vendorId, productId, name, reportDesc);
Os.write(fd, req, 0, req.length);

registerUhidListener(id, fd);
Expand Down Expand Up @@ -148,7 +148,7 @@ public void writeInput(int id, byte[] data) throws IOException {
}
}

private static byte[] buildUhidCreate2Req(String name, byte[] reportDesc) {
private static byte[] buildUhidCreate2Req(int vendorId, int productId, String name, byte[] reportDesc) {
/*
* struct uhid_event {
* uint32_t type;
Expand Down Expand Up @@ -183,8 +183,8 @@ private static byte[] buildUhidCreate2Req(String name, byte[] reportDesc) {

buf.putShort((short) reportDesc.length);
buf.putShort(BUS_VIRTUAL);
buf.putInt(0); // vendor id
buf.putInt(0); // product id
buf.putInt(vendorId);
buf.putInt(productId);
buf.putInt(0); // version
buf.putInt(0); // country;
buf.put(reportDesc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ public void testParseUhidCreate() throws IOException {
DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(ControlMessage.TYPE_UHID_CREATE);
dos.writeShort(42); // id
dos.writeShort(0x1234); // vendorId
dos.writeShort(0x5678); // productId
dos.writeByte(3); // name size
dos.write("ABC".getBytes(StandardCharsets.US_ASCII));
byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
Expand All @@ -335,6 +337,8 @@ public void testParseUhidCreate() throws IOException {
ControlMessage event = reader.read();
Assert.assertEquals(ControlMessage.TYPE_UHID_CREATE, event.getType());
Assert.assertEquals(42, event.getId());
Assert.assertEquals(0x1234, event.getVendorId());
Assert.assertEquals(0x5678, event.getProductId());
Assert.assertEquals("ABC", event.getText());
Assert.assertArrayEquals(data, event.getData());

Expand Down

0 comments on commit e492b17

Please sign in to comment.