Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asus ROG Strix LC III 360 #685

Open
sdns575 opened this issue Mar 21, 2024 · 18 comments
Open

Asus ROG Strix LC III 360 #685

sdns575 opened this issue Mar 21, 2024 · 18 comments
Labels
new device Support for a new device

Comments

@sdns575
Copy link

sdns575 commented Mar 21, 2024

Device type

AIO Liquid Cooler

Product page

https://rog.asus.com/cooling/cpu-liquid-coolers/rog-strix-lc/rog-strix-lc-iii-360/

First-party software

Armoury Crate

What monitoring functionality does the device support?

No response

What configuration functionality does the device support?

lighting of embedded LEDs

Physical connection

USB Header

Connection protocol

USB/HID

Additional information about the device

Bus 001 Device 004: ID 0b05:1b29 ASUSTek Computer, Inc. AURA LED Controller
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0b05 ASUSTek Computer, Inc.
idProduct 0x1b29
bcdDevice 1.00
iManufacturer 1 AsusTek Computer Inc.
iProduct 2 AURA LED Controller
iSerial 3 9876543210
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x002b
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 16mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 36
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 4
Device Status: 0x0001
Self Powered

Can you help with implementing or testing the changes needed for liquidctl to support this device?

testing changes on Linux, attempting to capture USB/HID traffic

@sdns575 sdns575 added the new device Support for a new device label Mar 21, 2024
@sdns575
Copy link
Author

sdns575 commented Apr 4, 2024

How can I help to integrate this device into liquidctl?

I tried reading CONTRIBUTING.md but I don't know how to decode captured data (lack of experiences).

Any help will be appreciated.

@aleksamagicka
Copy link
Member

Capturing USB traffic is a good tutorial for that.

@jonasmalacofilho
Copy link
Member

And as a complement, there's also Techniques for analyzing USB protocols.

@sdns575
Copy link
Author

sdns575 commented Apr 4, 2024

Hi and thank you for your answer. I read all the two guide and I reached the tshark step where I obtain data like this:

ec40800004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec408000044cff004cff004cff004cff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

but I don't know how to interpret them.

@jonasmalacofilho
Copy link
Member

It generally also helps to correlate the captured transfers with what was going on with the cooler (e.g. initialization, reporting increasing temperatures or speeds, setting different fan/pump speeds, etc.).

@sdns575
Copy link
Author

sdns575 commented Apr 5, 2024

Hi,
The lines I reported are only related to waterblock logo color change. The pump is controlled by BIOS, Fans (no RGB) by BIOS. The only thing configurable by Armoury Crate is the ROG logo on wb for this AIO.

@jonasmalacofilho
Copy link
Member

Oh, sorry, I've been away from the project for a few weeks and missed the context.

In that case, my first though is that 4cff00 is some 24-bit color in R, G, and B channels, but not necessarily in that order. And what we're seeing is Aura sending periodic commands to set all LEDs, as in what we normally call "software mode", where effect and animation is done by Aura in software.

Many devices also support hardware modes, that is, lighting effects that once set, work independently of software. Figuring them out requires finding a way to make the first-party application set them: some tools, like iCue, have explicit "hardware" modes; others set them automatically when you close the application; and there are some that simply don't support them (even when the actual device firmware does), in which case we can sometimes still find the hardware modes by experimenting with changing arbitrary bytes in the packets (note: this type of experiment carries some risk).

@sdns575
Copy link
Author

sdns575 commented Apr 6, 2024

Hi, and thank you for your answer.

I done another test with capture and tried to set color to red (#ff0000). On of the lines is:

ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

where:
ec40800004 could be the command

ff0000ff0000ff0000ff0000 is the color setting

and the rest:
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

is null, maybe it is space for other features (if I'm not wrong, for this cooler I can change the top and add an LCD screen top, maybe the remaining 000... could be used for that.)

I made another test changing the effect (the previous effect was "static"), in this test I set "breath" effect and the code is equal except for color, but I noticed that it appears as (continous) stream of command where in each command there is a different color to make the effect.

At this point. how can I try to write on the USB device using dev /dev/bus/usb/001/004 ? There is another way?

Thank you in advance.

@sdns575
Copy link
Author

sdns575 commented Apr 6, 2024

I would add I found another command when I change the color:

ec40800004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

ec40800004 the first command
000000000000000000000000 black color (maybe reset for the effect)

and the remaining 0.

@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Apr 6, 2024

At this point. how can I try to write on the USB device using dev /dev/bus/usb/001/004 ? There is another way?

That seems reasonable.


Since this is a bInterfaceClass 255 (Vendor Specific) device, I also advise you to look at all read, write, and control transfers from/to this device with Wireshark. Specifically, you need to look for any additional transfers that are required either during Windows/Armory crate boot or shutdown, as well as before & after any "useful" writes (e.g. change color commands).

It's possible that something like _configure_flow_control/_begin_transaction from our asetek driver will be necessary. Those devices also describe themselves as vendor-specific class, and I think I read somewhere that this Strix LC III is made by Asetek as well.

EDIT: you probably also want to take a look at some basics of the USB protocol, like transfer/endpoint types. PyUSB abstracts some of that stuff way (like interrupt vs bulk reads/writes), but since it's an extra layer, it can sometimes also make things more confusing if the device does weird/unusual things.

@sdns575
Copy link
Author

sdns575 commented Apr 6, 2024

Hi,
During VM startup I got this:

This could be initialization of the device?
ec35000000ff00fe010000000000000000000064646400000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec35000000ff00fe010000000000000000000064646400000000000000000000000000000000000000000000000000000000000000000000000000000000000000

This should be the reset before setting any color/effect
ec40800004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

This is the color/effect settings (from the system when booting)
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ec40800004ff0000ff0000ff0000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Then I left wireshark capturing and I noticed some request (don't know if sent by the VM kernel or Armoury Crate) with this data:
ec82000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

(the previous was sent many times example: 20s after capture starts, 102s, 204s, 326s, 471s.......)

During shutdown the VM I don't get any request as the reported but something like this:

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x00
bDescriptorType: CONFIGURATION (0x02)
Language Id: no language specified (0x0000)
wLength: 43

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x03
bDescriptorType: STRING (0x03)
Language Id: English (United States) (0x0409)
wLength: 255

Setup Data
bmRequestType: 0x00
bRequest: SET CONFIGURATION (9)
bConfigurationValue: 1
wIndex: 0 (0x0000)
wLength: 0

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x03
bDescriptorType: STRING (0x03)
Language Id: English (United States) (0x0409)
wLength: 255

Setup Data
bmRequestType: 0x21
bRequest: SET_IDLE (0x0a)
wValue: 0x0000
wIndex: 2
wLength: 0

Setup Data
bmRequestType: 0x81
bDescriptorIndex: 0x00
bDescriptorType: HID Report (0x22)
wInterfaceNumber: 2
wDescriptorLength: 36

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x00
bDescriptorType: DEVICE (0x01)
Language Id: no language specified (0x0000)
wLength: 18

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x00
bDescriptorType: CONFIGURATION (0x02)
Language Id: no language specified (0x0000)
wLength: 9

Setup Data
bmRequestType: 0x80
bRequest: GET DESCRIPTOR (6)
Descriptor Index: 0x00
bDescriptorType: CONFIGURATION (0x02)
Language Id: no language specified (0x0000)
wLength: 43

@jonasmalacofilho
Copy link
Member

On second thought, the protocol used for the logo doesn't look anything like Asetek's. And from the latter data it seems that only the HID interface is used.

In fact, we actually have some code supporting HID-based Aura devices, and looking at it now (admittedly only superficially) it looks quite close to what you've reported.


P.S. I appreciate the summarized data, but please also attach the raw Wireshark files in case we need to look at the data in more detail.

@sdns575
Copy link
Author

sdns575 commented Apr 6, 2024

Hi,
as required I attached raw Wireshark file:

  1. asus_rog_lc3_startup - VM startup and first Armoury Crate setting (red color static)
  2. asus_rog_lc3_static_from_red_to_white - color change from red to white for static effect
  3. asus_rog_lc3_stroboscopic_effect - strobo effect using Armoury Crate
  4. asus_rog_lc3_rainbow_effect - rainbow effect using Armoury Crate
  5. asus_rog_lc3_breath_effect - breath effect using Armoury Crate
  6. asus_rog_lc3_shutdown - VM shutdown from static effect (red color)

asus_rog_lc3_raw.tar.gz

@sdns575
Copy link
Author

sdns575 commented May 2, 2024

Hi,
there are news on this? There is something I can test?

Best regards

@sdns575
Copy link
Author

sdns575 commented May 27, 2024

@jonasmalacofilho

Hi, I tried something like this:

import usb.core
import usb.util
dev = usb.core.find(idVendor=0x0b05, idProduct=0x1b29)

if dev is None:
    raise ValueError('Device not found')

data = b'\xEC\x40\x80\x00\x04\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

dev.set_configuration()

cfg = dev.get_active_configuration()
intf = cfg[(0,0)]

ep = usb.util.find_descriptor(
    intf,
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_OUT)

assert ep is not None

ep.write(data)

but I get Resource Busy and can't find a solution. Any help will be appreciated.

@Mardoxx
Copy link

Mardoxx commented Jul 10, 2024

@sdns575

dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)

# Ensure the device is found
if dev is None:
    raise ValueError('Device not found')

# https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/devio.c#L1558
# the usbfs driver in Linux has a limitation that if any interface of the device is claimed by a kernel
# driver no interface can be claimed by a libusb process. So you have to iterate through all of the
# interfaces and detach the kernel driver on all of them
for cfg in dev:
    for intf in cfg:
        if dev.is_kernel_driver_active(intf.bInterfaceNumber):
            print(f"Detaching kernel driver from interface {intf.bInterfaceNumber}")
            try:
                dev.detach_kernel_driver(intf.bInterfaceNumber)
            except usb.core.USBError as e:
                print(f"Could not detach kernel driver from interface {intf.bInterfaceNumber}: {str(e)}")

try that

the commands will be similar to this #677 (comment)
there will be different ones for the orientation which will be sent in degrees rather than horizontal/vertical.

If you use wireshark/fiddler and look for http://127.0.0.1:1042/api/X/type/Y/model/Z/display it contains a json object with parameters you can change to tighten your development loop

If you attach a debugger to armoury crate, in the console output of aaHMLib.dll spews out the commands for fan/pump duty.

@sdns575
Copy link
Author

sdns575 commented Jul 11, 2024

No luck, I get:

assert ep is not None

@Mardoxx
Copy link

Mardoxx commented Jul 11, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new device Support for a new device
Projects
None yet
Development

No branches or pull requests

4 participants