I'm trying to reverse engineer the RGB controls for my SteelSeries Apex 3 TKL keyboard. My end goal is to control the RGB using Python, specifically the ctrl_transfer(bmRequestType, bmRequest, wValue, wIndex, data)
command.
I am using Wireshark to capture the data sent to the keyboard when demanding a colour using OpenRGB. However, I do not understand why I am missing certain information from the packet being sent. I've seen another post that contains additional information in their USB URB, such as Setup Data. How to correctly do a USB control transfer (libusb)?. I am missing this information, and only have Unused Setup Header (see extract from the USB URB below). I'd like to use this to extract the bmRequestType
, bRequest
, wValue
, wIndex
, wLength
, and Data Fragment
. Is there a way to view Setup Data?
From looking around, bmRequestType: 0x21
, bRequest: 9
, appear to be common for RGB controls, but wValue
and wIndex
can vary depending on the device.
These are the frames that I capture when I change the colour using OpenRGB: Initial frame:
Frame 219: 128 bytes on wire (1024 bits), 128 bytes captured (1024 bits) on interface usbmon1, id 0
Section number: 1
Interface id: 0 (usbmon1)
Interface name: usbmon1
Encapsulation type: USB packets with Linux header and padding (115)
Arrival Time: Sep 21, 2024 12:35:27.591740000 BST
UTC Arrival Time: Sep 21, 2024 11:35:27.591740000 UTC
Epoch Arrival Time: 1726918527.591740000
[Time shift for this packet: 0.000000000 seconds]
[Time delta from previous captured frame: 0.001744000 seconds]
[Time delta from previous displayed frame: 0.000000000 seconds]
[Time since reference or first frame: 1.540403000 seconds]
Frame Number: 219
Frame Length: 128 bytes (1024 bits)
Capture Length: 128 bytes (1024 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: usb:usbhid]
USB URB
[Source: 1.7.2]
[Destination: host]
URB id: 0xffff8b7f8e353d80
URB type: URB_COMPLETE ('C')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x82, Direction: IN
1... .... = Direction: IN (1)
.... 0010 = Endpoint number: 2
Device: 7
URB bus id: 1
Device setup request: not relevant ('-')
Data: present ('\0')
URB sec: 1726918527
URB usec: 591740
URB status: Success (0)
URB length [bytes]: 64
Data length [bytes]: 64
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 1
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
HID Data: 21000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Second frame:
Frame 220: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface usbmon1, id 0
Section number: 1
Interface id: 0 (usbmon1)
Interface name: usbmon1
Encapsulation type: USB packets with Linux header and padding (115)
Arrival Time: Sep 21, 2024 12:35:27.591762000 BST
UTC Arrival Time: Sep 21, 2024 11:35:27.591762000 UTC
Epoch Arrival Time: 1726918527.591762000
[Time shift for this packet: 0.000000000 seconds]
[Time delta from previous captured frame: 0.000022000 seconds]
[Time delta from previous displayed frame: 0.000022000 seconds]
[Time since reference or first frame: 1.540425000 seconds]
Frame Number: 220
Frame Length: 64 bytes (512 bits)
Capture Length: 64 bytes (512 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: usb]
USB URB
[Source: host]
[Destination: 1.7.2]
URB id: 0xffff8b7f8e353d80
URB type: URB_SUBMIT ('S')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x82, Direction: IN
1... .... = Direction: IN (1)
.... 0010 = Endpoint number: 2
Device: 7
URB bus id: 1
Device setup request: not relevant ('-')
Data: not present ('<')
URB sec: 1726918527
URB usec: 591762
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 64
Data length [bytes]: 0
[Response in: 223]
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 1
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
Third frame:
Frame 223: 128 bytes on wire (1024 bits), 128 bytes captured (1024 bits) on interface usbmon1, id 0
Section number: 1
Interface id: 0 (usbmon1)
Interface name: usbmon1
Encapsulation type: USB packets with Linux header and padding (115)
Arrival Time: Sep 21, 2024 12:35:27.594736000 BST
UTC Arrival Time: Sep 21, 2024 11:35:27.594736000 UTC
Epoch Arrival Time: 1726918527.594736000
[Time shift for this packet: 0.000000000 seconds]
[Time delta from previous captured frame: 0.002949000 seconds]
[Time delta from previous displayed frame: 0.002974000 seconds]
[Time since reference or first frame: 1.543399000 seconds]
Frame Number: 223
Frame Length: 128 bytes (1024 bits)
Capture Length: 128 bytes (1024 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: usb:usbhid]
USB URB
[Source: 1.7.2]
[Destination: host]
URB id: 0xffff8b7f8e353d80
URB type: URB_COMPLETE ('C')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x82, Direction: IN
1... .... = Direction: IN (1)
.... 0010 = Endpoint number: 2
Device: 7
URB bus id: 1
Device setup request: not relevant ('-')
Data: present ('\0')
URB sec: 1726918527
URB usec: 594736
URB status: Success (0)
URB length [bytes]: 64
Data length [bytes]: 64
[Request in: 220]
[Time from request: 0.002974000 seconds]
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 1
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
HID Data: 23000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Fourth frame:
Frame 224: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface usbmon1, id 0
Section number: 1
Interface id: 0 (usbmon1)
Interface name: usbmon1
Encapsulation type: USB packets with Linux header and padding (115)
Arrival Time: Sep 21, 2024 12:35:27.594743000 BST
UTC Arrival Time: Sep 21, 2024 11:35:27.594743000 UTC
Epoch Arrival Time: 1726918527.594743000
[Time shift for this packet: 0.000000000 seconds]
[Time delta from previous captured frame: 0.000007000 seconds]
[Time delta from previous displayed frame: 0.000007000 seconds]
[Time since reference or first frame: 1.543406000 seconds]
Frame Number: 224
Frame Length: 64 bytes (512 bits)
Capture Length: 64 bytes (512 bits)
[Frame is marked: False]
[Frame is ignored: False]
[Protocols in frame: usb]
USB URB
[Source: host]
[Destination: 1.7.2]
URB id: 0xffff8b7f8e353d80
URB type: URB_SUBMIT ('S')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x82, Direction: IN
1... .... = Direction: IN (1)
.... 0010 = Endpoint number: 2
Device: 7
URB bus id: 1
Device setup request: not relevant ('-')
Data: not present ('<')
URB sec: 1726918527
URB usec: 594743
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 64
Data length [bytes]: 0
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 1
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
I have tried various permutations of demands from OpenRGB to try and extract the Setup Data to no avail.
I solved this myself. I was monitoring the incorrect USB packets! All information such as bmRequestType = 0x21
, bRequest = 0x09
, wValue = 0x0200
, wIndex = 0x1
, wLength = 64
, and Data Fragment = varies by request...
were present in these packets.
My script is working now.