Sigh! This got bounced because of HTML parts. Another question that arises, though: What sort of performance can I expect writing to and reading from a RAW HID gadget, configured using that descriptor? My understanding is that I should be able to get 64kBps, based on a 64-byte packet, and a 1000 packet per second limit. With my current code, and a Windows host, I am only able to get approximately 1kBps :-( Here is the code I am using on the Linux side to "pipe" a socket over the raw HID device, chunked up into 63-byte packets: #!/usr/bin/env python3 import selectors import socket import os import fcntl def set_blocking(fd, blocking): flag = fcntl.fcntl(fd, fcntl.F_GETFL) if blocking == False: fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK) else: fcntl.fcntl(fd, fcntl.F_SETFL, flag & ~os.O_NONBLOCK) def accept(sock, mask): conn, addr = sock.accept() # Should be ready print('accepted', conn, 'from', addr) global connection connection = conn conn.setblocking(False) sel.register(conn, selectors.EVENT_READ, read_socket) def read_socket(conn, mask): global connection data = conn.recv(63) # Should be ready if data: print('< ', repr(data)) set_blocking(hidg.fileno(), True) hidg.write(bytes([len(data)])+data+bytes(64-len(data)-1)) hidg.flush() set_blocking(hidg.fileno(), False) else: print('closing', conn) sel.unregister(conn) conn.close() connection = None def read_hid(conn, mask): data = hidg.read(64) # Should be ready if data: if data[0:1] != b'\0': print('> ', repr(data[1:])) data = data[1:data[0]] if connection != None: connection.send(data) # Hope it won't block else: print('closing', connection) sel.unregister(connection) connection.close() sel.unregister(hidg) hidg.close() sel = selectors.DefaultSelector() connection = None hidg = open('/dev/hidg1', 'r+b') set_blocking(hidg.fileno(), False) sel.register(hidg, selectors.EVENT_READ, read_hid) sock = socket.socket() sock.bind(('localhost', 8089)) sock.listen(1) sock.setblocking(False) sel.register(sock, selectors.EVENT_READ, accept) while True: events = sel.select() for key, mask in events: callback = key.data callback(key.fileobj, mask) The Windows side code is at https://github.com/SensePost/USaBUSe/powershell/, most notably read_exec.ps1 which is normally "typed out" via the gadget keyboard, followed by spawn.ps1 which is normally sent over the raw hid interface. Any insight you can offer will be much appreciated! Regards, Rogan ---------- Forwarded message ---------- From: Rogan Dawes <rogan@xxxxxxxxxxxx> Date: Mon, Jan 9, 2017 at 7:51 AM Subject: Re: Raw hid gadget To: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Cc: linux-usb@xxxxxxxxxxxxxxx Hi Alan, My responses are inline. On Sun, Jan 8, 2017 at 12:15 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > On Sat, 7 Jan 2017, Rogan Dawes wrote: > >> Hi Alan, >> >> Thanks for the response. I have not read hiddev.txt, so that explains >> the incorrect expectations. If I may ask, why is the value a 4-byte >> field? Is that just to round it to 8 bytes? > > Probably because the original programmers needed to accomodate the data > that could appear in any report. Since data fields can be as large as > 32 bits, that means the field has to be 4 bytes long. > Makes sense, I guess ;-) >> The "English" version of the descriptor is as follows, from the >> original LUFA source: >> >> HID_DESCRIPTOR_VENDOR(0x00, 0x01, 0x02, 0x03, GENERIC_REPORT_SIZE) /* >> GENERIC_REPORT_SIZE == 64 */ >> >> And parsed using http://eleccelerator.com/usbdescreqparser/, translates to: >> >> 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) >> 0x09, 0x01, // Usage (0x01) > > Hmmm. Is there any reason for this item? Not specifically, it is just copy and paste from the sample code ;-) > So your device produces (and consumes) reports containing 64 8-bit > values. Presumably in a 64-byte data packet. Yes, it is my understanding that this is the largest packet size allowed for a generic hid interface. >> So I apparently need to extract just the 5th byte from the packet, and >> discard the rest. Excellent! > > (Not from the _packet_, but from the data you receive over the rawhid > interface.) > > Well, that's if you want to read just the first value. If you want to > read the second value, you have to extract the 13th byte, if you want > to read the third value, you have to extract the 21st byte, and so on. Gotcha! > This raises the question of how many of the values in the report are > real. In your first example, for instance, there must have been 64 > values but only 4 of them were real. How are you going to tell where > the real data ends in each report? I use the first byte as a length indicator, and the remaining 63 bytes as data. Rogan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html