networkupstools / nut-ddl

Network UPS Tools Devices Dumps Library
http://networkupstools.org/ddl/index.html#_supported_devices
4 stars 16 forks source link

Document the helper scripts tools/nut-ddl-dump.sh tools/nut-recorder.sh #3

Open aquette opened 9 years ago

aquette commented 9 years ago

The nut, repository and main distribution, provides 2 helper scripts to help in the generation of device dumps:

This should also be documented in the main DDL repository, and in the Developer (and probably also the User) documentations

luzfcb commented 8 months ago

I have a UPS that is not officially supported. I want to try to reverse engineer (although I have never done this in practice) the proprietary application that communicates via USB with the UPS. Would these scripts be helpful in any way to do this?

hwinfo --usb

#....
13: USB 00.1: 0000 Unclassified device
  [Created at usb.122]
  Unique ID: yLyY.+wqcmQaR_Y7
  Parent ID: W5SY.d7FDLX76qXB
  SysFS ID: /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-6/3-6.1/3-6.1:1.1
  SysFS BusID: 3-6.1:1.1
  Hardware Class: unknown
  Model: "Lakeview MCU VIRTUAL COM DEMO"
  Hotplug: USB
  Vendor: usb 0x0925 "Lakeview Research"
  Device: usb 0x1241 "MCU VIRTUAL COM DEMO"
  Revision: "1.01"
  Driver: "cdc_acm"
  Driver Modules: "cdc_acm"
  Speed: 12 Mbps
  Module Alias: "usb:v0925p1241d0101dc02dsc00dp00ic0Aisc00ip00in01"
  Config Status: cfg=new, avail=yes, need=no, active=unknown
  Attached to: #25 (Hub)

#....
Details of udevadm info -a /dev/ttyACM0

``` Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-6/3-6.1/3-6.1:1.0/tty/ttyACM0': KERNEL=="ttyACM0" SUBSYSTEM=="tty" DRIVER=="" ATTR{power/async}=="disabled" ATTR{power/control}=="auto" ATTR{power/runtime_active_kids}=="0" ATTR{power/runtime_active_time}=="0" ATTR{power/runtime_enabled}=="disabled" ATTR{power/runtime_status}=="unsupported" ATTR{power/runtime_suspended_time}=="0" ATTR{power/runtime_usage}=="0" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-6/3-6.1/3-6.1:1.0': KERNELS=="3-6.1:1.0" SUBSYSTEMS=="usb" DRIVERS=="cdc_acm" ATTRS{authorized}=="1" ATTRS{bAlternateSetting}==" 0" ATTRS{bInterfaceClass}=="02" ATTRS{bInterfaceNumber}=="00" ATTRS{bInterfaceProtocol}=="00" ATTRS{bInterfaceSubClass}=="02" ATTRS{bNumEndpoints}=="01" ATTRS{bmCapabilities}=="6" ATTRS{power/async}=="enabled" ATTRS{power/runtime_active_kids}=="0" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="suspended" ATTRS{power/runtime_usage}=="0" ATTRS{supports_autosuspend}=="1" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-6/3-6.1': KERNELS=="3-6.1" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="02" ATTRS{bDeviceProtocol}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="100mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 2" ATTRS{bcdDevice}=="0101" ATTRS{bmAttributes}=="c0" ATTRS{busnum}=="3" ATTRS{configuration}=="" ATTRS{devnum}=="6" ATTRS{devpath}=="6.1" ATTRS{idProduct}=="1241" ATTRS{idVendor}=="0925" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="NXP SEMICONDUCTORS" ATTRS{maxchild}=="0" ATTRS{power/active_duration}=="757724" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend}=="2" ATTRS{power/autosuspend_delay_ms}=="2000" ATTRS{power/connected_duration}=="757724" ATTRS{power/control}=="on" ATTRS{power/level}=="on" ATTRS{power/persist}=="1" ATTRS{power/runtime_active_kids}=="0" ATTRS{power/runtime_active_time}=="757540" ATTRS{power/runtime_enabled}=="forbidden" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="1" ATTRS{product}=="MCU VIRTUAL COM DEMO" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{rx_lanes}=="1" ATTRS{speed}=="12" ATTRS{tx_lanes}=="1" ATTRS{urbnum}=="10424" ATTRS{version}==" 2.00" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-6': KERNELS=="3-6" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="09" ATTRS{bDeviceProtocol}=="01" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="100mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="8536" ATTRS{bmAttributes}=="e0" ATTRS{busnum}=="3" ATTRS{configuration}=="" ATTRS{devnum}=="3" ATTRS{devpath}=="6" ATTRS{idProduct}=="0608" ATTRS{idVendor}=="05e3" ATTRS{ltm_capable}=="no" ATTRS{maxchild}=="4" ATTRS{physical_location/dock}=="no" ATTRS{physical_location/horizontal_position}=="left" ATTRS{physical_location/lid}=="no" ATTRS{physical_location/panel}=="front" ATTRS{physical_location/vertical_position}=="upper" ATTRS{power/active_duration}=="7712304" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend}=="0" ATTRS{power/autosuspend_delay_ms}=="0" ATTRS{power/connected_duration}=="7713292" ATTRS{power/control}=="auto" ATTRS{power/level}=="auto" ATTRS{power/runtime_active_kids}=="2" ATTRS{power/runtime_active_time}=="7712258" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{power/wakeup}=="disabled" ATTRS{power/wakeup_abort_count}=="" ATTRS{power/wakeup_active}=="" ATTRS{power/wakeup_active_count}=="" ATTRS{power/wakeup_count}=="" ATTRS{power/wakeup_expire_count}=="" ATTRS{power/wakeup_last_time_ms}=="" ATTRS{power/wakeup_max_time_ms}=="" ATTRS{power/wakeup_total_time_ms}=="" ATTRS{product}=="USB2.0 Hub" ATTRS{quirks}=="0x0" ATTRS{removable}=="removable" ATTRS{rx_lanes}=="1" ATTRS{speed}=="480" ATTRS{tx_lanes}=="1" ATTRS{urbnum}=="140" ATTRS{version}==" 2.00" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3': KERNELS=="usb3" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{authorized_default}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="09" ATTRS{bDeviceProtocol}=="01" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="0mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="0605" ATTRS{bmAttributes}=="e0" ATTRS{busnum}=="3" ATTRS{configuration}=="" ATTRS{devnum}=="1" ATTRS{devpath}=="0" ATTRS{idProduct}=="0002" ATTRS{idVendor}=="1d6b" ATTRS{interface_authorized_default}=="1" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="Linux 6.5.0-21-generic xhci-hcd" ATTRS{maxchild}=="6" ATTRS{power/active_duration}=="7712796" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend}=="0" ATTRS{power/autosuspend_delay_ms}=="0" ATTRS{power/connected_duration}=="7713744" ATTRS{power/control}=="auto" ATTRS{power/level}=="auto" ATTRS{power/runtime_active_kids}=="1" ATTRS{power/runtime_active_time}=="7712985" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{power/wakeup}=="disabled" ATTRS{power/wakeup_abort_count}=="" ATTRS{power/wakeup_active}=="" ATTRS{power/wakeup_active_count}=="" ATTRS{power/wakeup_count}=="" ATTRS{power/wakeup_expire_count}=="" ATTRS{power/wakeup_last_time_ms}=="" ATTRS{power/wakeup_max_time_ms}=="" ATTRS{power/wakeup_total_time_ms}=="" ATTRS{product}=="xHCI Host Controller" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{rx_lanes}=="1" ATTRS{serial}=="0000:08:00.3" ATTRS{speed}=="480" ATTRS{tx_lanes}=="1" ATTRS{urbnum}=="61" ATTRS{version}==" 2.00" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3': KERNELS=="0000:08:00.3" SUBSYSTEMS=="pci" DRIVERS=="xhci_hcd" ATTRS{ari_enabled}=="0" ATTRS{broken_parity_status}=="0" ATTRS{class}=="0x0c0330" ATTRS{consistent_dma_mask_bits}=="64" ATTRS{current_link_speed}=="16.0 GT/s PCIe" ATTRS{current_link_width}=="16" ATTRS{d3cold_allowed}=="1" ATTRS{dbc}=="disabled" ATTRS{dbc_bInterfaceProtocol}=="01" ATTRS{dbc_bcdDevice}=="0010" ATTRS{dbc_idProduct}=="0010" ATTRS{dbc_idVendor}=="1d6b" ATTRS{device}=="0x149c" ATTRS{dma_mask_bits}=="64" ATTRS{driver_override}=="(null)" ATTRS{enable}=="1" ATTRS{irq}=="40" ATTRS{link/l0s_aspm}=="0" ATTRS{link/l1_aspm}=="0" ATTRS{local_cpulist}=="0-23" ATTRS{local_cpus}=="00ffffff" ATTRS{max_link_speed}=="16.0 GT/s PCIe" ATTRS{max_link_width}=="16" ATTRS{msi_bus}=="1" ATTRS{msi_irqs/59}=="msix" ATTRS{msi_irqs/60}=="msix" ATTRS{msi_irqs/61}=="msix" ATTRS{msi_irqs/62}=="msix" ATTRS{msi_irqs/63}=="msix" ATTRS{msi_irqs/64}=="msix" ATTRS{msi_irqs/65}=="msix" ATTRS{msi_irqs/66}=="msix" ATTRS{numa_node}=="-1" ATTRS{power/async}=="enabled" ATTRS{power/control}=="on" ATTRS{power/runtime_active_kids}=="1" ATTRS{power/runtime_active_time}=="7714032" ATTRS{power/runtime_enabled}=="forbidden" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="1" ATTRS{power/wakeup}=="enabled" ATTRS{power/wakeup_abort_count}=="0" ATTRS{power/wakeup_active}=="0" ATTRS{power/wakeup_active_count}=="0" ATTRS{power/wakeup_count}=="0" ATTRS{power/wakeup_expire_count}=="0" ATTRS{power/wakeup_last_time_ms}=="0" ATTRS{power/wakeup_max_time_ms}=="0" ATTRS{power/wakeup_total_time_ms}=="0" ATTRS{power_state}=="D0" ATTRS{reset_method}=="pm" ATTRS{revision}=="0x00" ATTRS{subsystem_device}=="0x148c" ATTRS{subsystem_vendor}=="0x1022" ATTRS{vendor}=="0x1022" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0': KERNELS=="0000:03:08.0" SUBSYSTEMS=="pci" DRIVERS=="pcieport" ATTRS{ari_enabled}=="0" ATTRS{broken_parity_status}=="0" ATTRS{class}=="0x060400" ATTRS{consistent_dma_mask_bits}=="32" ATTRS{current_link_speed}=="16.0 GT/s PCIe" ATTRS{current_link_width}=="16" ATTRS{d3cold_allowed}=="1" ATTRS{device}=="0x57a4" ATTRS{dma_mask_bits}=="32" ATTRS{driver_override}=="(null)" ATTRS{enable}=="2" ATTRS{irq}=="37" ATTRS{local_cpulist}=="0-23" ATTRS{local_cpus}=="00ffffff" ATTRS{max_link_speed}=="16.0 GT/s PCIe" ATTRS{max_link_width}=="16" ATTRS{msi_bus}=="1" ATTRS{msi_irqs/37}=="msi" ATTRS{numa_node}=="-1" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend_delay_ms}=="100" ATTRS{power/control}=="auto" ATTRS{power/runtime_active_kids}=="3" ATTRS{power/runtime_active_time}=="7714038" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{power/wakeup}=="disabled" ATTRS{power/wakeup_abort_count}=="" ATTRS{power/wakeup_active}=="" ATTRS{power/wakeup_active_count}=="" ATTRS{power/wakeup_count}=="" ATTRS{power/wakeup_expire_count}=="" ATTRS{power/wakeup_last_time_ms}=="" ATTRS{power/wakeup_max_time_ms}=="" ATTRS{power/wakeup_total_time_ms}=="" ATTRS{power_state}=="D0" ATTRS{reset_method}=="pm" ATTRS{revision}=="0x00" ATTRS{secondary_bus_number}=="8" ATTRS{subordinate_bus_number}=="8" ATTRS{subsystem_device}=="0x1484" ATTRS{subsystem_vendor}=="0x1022" ATTRS{vendor}=="0x1022" looking at parent device '/devices/pci0000:00/0000:00:01.2/0000:02:00.0': KERNELS=="0000:02:00.0" SUBSYSTEMS=="pci" DRIVERS=="pcieport" ATTRS{ari_enabled}=="0" ATTRS{broken_parity_status}=="0" ATTRS{class}=="0x060400" ATTRS{consistent_dma_mask_bits}=="32" ATTRS{current_link_speed}=="16.0 GT/s PCIe" ATTRS{current_link_width}=="4" ATTRS{d3cold_allowed}=="1" ATTRS{device}=="0x57ad" ATTRS{dma_mask_bits}=="32" ATTRS{driver_override}=="(null)" ATTRS{enable}=="2" ATTRS{irq}=="24" ATTRS{link/l1_1_aspm}=="0" ATTRS{link/l1_1_pcipm}=="0" ATTRS{link/l1_aspm}=="0" ATTRS{local_cpulist}=="0-23" ATTRS{local_cpus}=="00ffffff" ATTRS{max_link_speed}=="16.0 GT/s PCIe" ATTRS{max_link_width}=="8" ATTRS{msi_bus}=="1" ATTRS{numa_node}=="-1" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend_delay_ms}=="100" ATTRS{power/control}=="auto" ATTRS{power/runtime_active_kids}=="7" ATTRS{power/runtime_active_time}=="7714049" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{power/wakeup}=="disabled" ATTRS{power/wakeup_abort_count}=="" ATTRS{power/wakeup_active}=="" ATTRS{power/wakeup_active_count}=="" ATTRS{power/wakeup_count}=="" ATTRS{power/wakeup_expire_count}=="" ATTRS{power/wakeup_last_time_ms}=="" ATTRS{power/wakeup_max_time_ms}=="" ATTRS{power/wakeup_total_time_ms}=="" ATTRS{power_state}=="D0" ATTRS{reset_method}=="pm bus" ATTRS{revision}=="0x00" ATTRS{secondary_bus_number}=="3" ATTRS{subordinate_bus_number}=="10" ATTRS{subsystem_device}=="0x0000" ATTRS{subsystem_vendor}=="0x0000" ATTRS{vendor}=="0x1022" looking at parent device '/devices/pci0000:00/0000:00:01.2': KERNELS=="0000:00:01.2" SUBSYSTEMS=="pci" DRIVERS=="pcieport" ATTRS{aer_rootport_total_err_cor}=="0" ATTRS{aer_rootport_total_err_fatal}=="0" ATTRS{aer_rootport_total_err_nonfatal}=="0" ATTRS{ari_enabled}=="0" ATTRS{broken_parity_status}=="0" ATTRS{class}=="0x060400" ATTRS{consistent_dma_mask_bits}=="32" ATTRS{current_link_speed}=="16.0 GT/s PCIe" ATTRS{current_link_width}=="4" ATTRS{d3cold_allowed}=="1" ATTRS{device}=="0x1483" ATTRS{dma_mask_bits}=="32" ATTRS{driver_override}=="(null)" ATTRS{enable}=="2" ATTRS{irq}=="28" ATTRS{local_cpulist}=="0-23" ATTRS{local_cpus}=="00ffffff" ATTRS{max_link_speed}=="16.0 GT/s PCIe" ATTRS{max_link_width}=="8" ATTRS{msi_bus}=="1" ATTRS{msi_irqs/28}=="msi" ATTRS{numa_node}=="-1" ATTRS{power/async}=="enabled" ATTRS{power/autosuspend_delay_ms}=="100" ATTRS{power/control}=="auto" ATTRS{power/runtime_active_kids}=="1" ATTRS{power/runtime_active_time}=="7714051" ATTRS{power/runtime_enabled}=="enabled" ATTRS{power/runtime_status}=="active" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{power/wakeup}=="enabled" ATTRS{power/wakeup_abort_count}=="0" ATTRS{power/wakeup_active}=="0" ATTRS{power/wakeup_active_count}=="0" ATTRS{power/wakeup_count}=="0" ATTRS{power/wakeup_expire_count}=="0" ATTRS{power/wakeup_last_time_ms}=="0" ATTRS{power/wakeup_max_time_ms}=="0" ATTRS{power/wakeup_total_time_ms}=="0" ATTRS{power_state}=="D0" ATTRS{reset_method}=="pm" ATTRS{revision}=="0x00" ATTRS{secondary_bus_number}=="2" ATTRS{subordinate_bus_number}=="10" ATTRS{subsystem_device}=="0x1453" ATTRS{subsystem_vendor}=="0x1022" ATTRS{vendor}=="0x1022" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" ATTRS{power/async}=="enabled" ATTRS{power/control}=="auto" ATTRS{power/runtime_active_kids}=="24" ATTRS{power/runtime_active_time}=="0" ATTRS{power/runtime_enabled}=="disabled" ATTRS{power/runtime_status}=="unsupported" ATTRS{power/runtime_suspended_time}=="0" ATTRS{power/runtime_usage}=="0" ATTRS{waiting_for_supplier}=="0" ```

jimklimov commented 8 months ago

@luzfcb : your question pertains more to the main NUT repository issue tracker, and probably bring it up (add a link) on the NUT mailing list. This repo is specifically about the DDL (device NUT data dumps library), and the scripts above help collect such data snapshots for comparisons or recordings of activity to simulate later.

I am not well versed in USB programming specifically, but generally I would guess a new driver would be more about determining the vendor protocol used than about the hardware link details the tools above reported in your post.

OTOH, current nutdrv_qx and usbhid_ups drivers support trying to use vendorid+productid+subdriver run-time parameters so as to try "lock-picking" devices whose IDs are not yet known and compiled into specific drivers. Earlier seemingly related 0925:1234 IDs are handled by nutdrv_qx (and older richcomm_usb).

My first step would be to set up a loop that would try starting the driver programs from command line to dump device information, until something is successful and reasonable, and only investigate vendor protocols or reverse engineering if your device looks like nothing we have coded for earlier.

luzfcb commented 8 months ago

@jimklimov Thanks for the explanations.

My first step would be to set up a loop that would try starting the driver programs from command line to dump device information, until something is successful and reasonable, and only investigate vendor protocols or reverse engineering if your device looks like nothing we have coded for earlier.

Is there any official or non-official step-by-step documentation on how I can do this process?

jimklimov commented 8 months ago

Not that I'm aware of, quickly...

Essentially it would be just a loop of shell scripting to iterate subdriver values (which you can find in the help of your NUT driver programs). Note that usbhid-ups with this feature is part of NUT v2.8.1 release or current master; most pre-packaged builds are older. But I'd guess that nutdrv_qx is a more likely fit, and it supports needed options for quite a while.

So the skeleton would be roughly like this, to run with debugging and exit after printing one upsc-like collection of data (if present):

:; for S in <divinated list of subdriver strings> ; do \
    echo "=== $S"; \
    nutdrv_qx -s test -x port=auto -x vendorid=0925 -x productid=1241 -x subdriver="$S" -DDDDDD -d1 ; \
   done 2>&1 | tee test.log

Which would leave you with a wall of text (and a test.log file) to review. Maybe you would need some more -x option(=val) clarifications.

The Megatec Qx family of protocols typically reply with text strings (USB/serial friendly) which start with a parenthesis and follow up with some voltages, temperatures, and a bit-mask of some states, depending on the query. They are quite recognizable and make sense "visually" if you see them in wire captures or NUT driver logs; but then there are many vendor-specific dialects.

USB HID is more formal and binary (and some vendors do botch the encoding). Here probably an explore mode of usbhid-ups driver can help better with the first step (to rule out non-HID devices), or possibly third-party tools like usbhid-dump. Note that sometimes useful data may be not on the default (number 0) "interface". Just recently the NUT master codebase got options to tune the numbers involved in USB low-level links, but it is an experimental gray area so far.