Re: Как надежно различать два одинаковых USB-устройства в Window
От: velkin Удмуртия https://kisa.biz
Дата: 08.01.25 20:32
Оценка: 14 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>P.S. Уточню: требуется не способ адресации заранее неизвестного устройства в заранее неизвестной системе, а постоянный адрес уже известного устройства. То есть, в первый раз устройство будет найдено любым из доступных в системе способов (по имени или другим свойствам), а уже затем нужно определить его "физический адрес", чтобы при следующем запуске (в том числе после выключения/перезагрузки) уверенно и предсказуемо найти его уже по адресу — разумеется, при условии, что оно подключено к тому же самому разъему.


У меня к примеру была задача поставить на Raspberry Pi 2 проброс портов в интернет. Я скомпилировал драйвера для USB устройств CH34X. И началось, каждый раз при перезагрузке компьютера получались разные ttyUSB или в терминологии виндузятников COM порты.

Я считал командной информацию для каждого из USB портов. Сами устройства CH34X как клоны.

  udev_info_port1.txt
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/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"
SUBSYSTEM=="tty"
DRIVER==""
ATTR{power/control}=="auto"
ATTR{power/runtime_active_time}=="0"
ATTR{power/runtime_status}=="unsupported"
ATTR{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0':
KERNELS=="ttyUSB0"
SUBSYSTEMS=="usb-serial"
DRIVERS=="ch341-uart"
ATTRS{port_number}=="0"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0':
KERNELS=="1-1.2:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="ch341"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="ff"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceProtocol}=="02"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bNumEndpoints}=="03"
ATTRS{supports_autosuspend}=="1"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2':
KERNELS=="1-1.2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="ff"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{bMaxPower}=="96mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0254"
ATTRS{bmAttributes}=="80"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="10"
ATTRS{devpath}=="1.2"
ATTRS{devspec}=="(null)"
ATTRS{idProduct}=="7523"
ATTRS{idVendor}=="1a86"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="0"
ATTRS{power/active_duration}=="3100"
ATTRS{power/autosuspend}=="2"
ATTRS{power/autosuspend_delay_ms}=="2000"
ATTRS{power/connected_duration}=="3100"
ATTRS{power/control}=="on"
ATTRS{power/level}=="on"
ATTRS{power/persist}=="1"
ATTRS{power/runtime_active_time}=="2870"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{product}=="USB2.0-Ser!"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="removable"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="12"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="16"
ATTRS{version}==" 1.10"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="2mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0200"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="2"
ATTRS{devpath}=="1"
ATTRS{idProduct}=="9514"
ATTRS{idVendor}=="0424"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="5"
ATTRS{power/active_duration}=="256670"
ATTRS{power/autosuspend}=="0"
ATTRS{power/autosuspend_delay_ms}=="0"
ATTRS{power/connected_duration}=="256670"
ATTRS{power/control}=="auto"
ATTRS{power/level}=="auto"
ATTRS{power/runtime_active_time}=="256219"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="480"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="161"
ATTRS{version}==" 2.00"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
KERNELS=="usb1"
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}=="0606"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
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.6.51+rpt-rpi-v7 dwc_otg_hcd"
ATTRS{maxchild}=="1"
ATTRS{power/active_duration}=="256800"
ATTRS{power/autosuspend}=="0"
ATTRS{power/autosuspend_delay_ms}=="0"
ATTRS{power/connected_duration}=="256810"
ATTRS{power/control}=="auto"
ATTRS{power/level}=="auto"
ATTRS{power/runtime_active_time}=="256813"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{product}=="DWC OTG Controller"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{serial}=="3f980000.usb"
ATTRS{speed}=="480"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="26"
ATTRS{version}==" 2.00"

looking at parent device '/devices/platform/soc/3f980000.usb':
KERNELS=="3f980000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="dwc_otg"
ATTRS{busconnected}=="Bus Connected = 0x1"
ATTRS{buspower}=="Bus Power = 0x1"
ATTRS{bussuspend}=="Bus Suspend = 0x0"
ATTRS{devspeed}=="Device Speed = 0x0"
ATTRS{disconnect_us}=="(not readable)"
ATTRS{driver_override}=="(null)"
ATTRS{enumspeed}=="Device Enumeration Speed = 0x1"
ATTRS{fr_interval}=="Frame Interval = 0x1d4b"
ATTRS{ggpio}=="GGPIO = 0x00000000"
ATTRS{gnptxfsiz}=="GNPTXFSIZ = 0x01000306"
ATTRS{gotgctl}=="GOTGCTL = 0x001c0001"
ATTRS{gpvndctl}=="GPVNDCTL = 0x00000000"
ATTRS{grxfsiz}=="GRXFSIZ = 0x00000306"
ATTRS{gsnpsid}=="GSNPSID = 0x4f54280a"
ATTRS{guid}=="GUID = 0x2708a000"
ATTRS{gusbcfg}=="GUSBCFG = 0x20001700"
ATTRS{hcd_frrem}=="HCD Dump Frame Remaining"
ATTRS{hcddump}=="HCD Dump"
ATTRS{hnp}=="HstNegScs = 0x0"
ATTRS{hnpcapable}=="HNPCapable = 0x1"
ATTRS{hprt0}=="HPRT0 = 0x00001005"
ATTRS{hptxfsiz}=="HPTXFSIZ = 0x02000406"
ATTRS{hsic_connect}=="HSIC Connect = 0x1"
ATTRS{inv_sel_hsic}=="Invert Select HSIC = 0x0"
ATTRS{mode}=="Mode = 0x1"
ATTRS{mode_ch_tim_en}=="Mode Change Ready Timer Enable = 0x0"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{rd_reg_test}=="Time to read GNPTXFSIZ reg 10000000 times: 1480 msecs (148 jiffies)"
ATTRS{regdump}=="Register Dump"
ATTRS{regoffset}=="0xffffffff"
ATTRS{regvalue}=="invalid offset"
ATTRS{rem_wakeup_pwrdn}==""
ATTRS{remote_wakeup}=="Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0"
ATTRS{spramdump}=="SPRAM Dump"
ATTRS{srp}=="SesReqScs = 0x1"
ATTRS{srpcapable}=="SRPCapable = 0x1"
ATTRS{wr_reg_test}=="Time to write GNPTXFSIZ reg 10000000 times: 370 msecs (37 jiffies)"

looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS=="simple-pm-bus"
ATTRS{driver_override}=="(null)"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

  udev_info_port2.txt
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/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"
SUBSYSTEM=="tty"
DRIVER==""
ATTR{power/control}=="auto"
ATTR{power/runtime_active_time}=="0"
ATTR{power/runtime_status}=="unsupported"
ATTR{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/ttyUSB0':
KERNELS=="ttyUSB0"
SUBSYSTEMS=="usb-serial"
DRIVERS=="ch341-uart"
ATTRS{port_number}=="0"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0':
KERNELS=="1-1.4:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="ch341"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="ff"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceProtocol}=="02"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bNumEndpoints}=="03"
ATTRS{supports_autosuspend}=="1"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4':
KERNELS=="1-1.4"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="ff"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{bMaxPower}=="96mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0254"
ATTRS{bmAttributes}=="80"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="9"
ATTRS{devpath}=="1.4"
ATTRS{devspec}=="(null)"
ATTRS{idProduct}=="7523"
ATTRS{idVendor}=="1a86"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="0"
ATTRS{power/active_duration}=="15960"
ATTRS{power/autosuspend}=="2"
ATTRS{power/autosuspend_delay_ms}=="2000"
ATTRS{power/connected_duration}=="15960"
ATTRS{power/control}=="on"
ATTRS{power/level}=="on"
ATTRS{power/persist}=="1"
ATTRS{power/runtime_active_time}=="15735"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{product}=="USB2.0-Ser!"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="removable"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="12"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="16"
ATTRS{version}==" 1.10"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bMaxPower}=="2mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0200"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="2"
ATTRS{devpath}=="1"
ATTRS{idProduct}=="9514"
ATTRS{idVendor}=="0424"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="5"
ATTRS{power/active_duration}=="248790"
ATTRS{power/autosuspend}=="0"
ATTRS{power/autosuspend_delay_ms}=="0"
ATTRS{power/connected_duration}=="248790"
ATTRS{power/control}=="auto"
ATTRS{power/level}=="auto"
ATTRS{power/runtime_active_time}=="248343"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="480"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="139"
ATTRS{version}==" 2.00"

looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
KERNELS=="usb1"
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}=="0606"
ATTRS{bmAttributes}=="e0"
ATTRS{busnum}=="1"
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.6.51+rpt-rpi-v7 dwc_otg_hcd"
ATTRS{maxchild}=="1"
ATTRS{power/active_duration}=="248930"
ATTRS{power/autosuspend}=="0"
ATTRS{power/autosuspend_delay_ms}=="0"
ATTRS{power/connected_duration}=="248930"
ATTRS{power/control}=="auto"
ATTRS{power/level}=="auto"
ATTRS{power/runtime_active_time}=="248934"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{product}=="DWC OTG Controller"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="unknown"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{serial}=="3f980000.usb"
ATTRS{speed}=="480"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="26"
ATTRS{version}==" 2.00"

looking at parent device '/devices/platform/soc/3f980000.usb':
KERNELS=="3f980000.usb"
SUBSYSTEMS=="platform"
DRIVERS=="dwc_otg"
ATTRS{busconnected}=="Bus Connected = 0x1"
ATTRS{buspower}=="Bus Power = 0x1"
ATTRS{bussuspend}=="Bus Suspend = 0x0"
ATTRS{devspeed}=="Device Speed = 0x0"
ATTRS{disconnect_us}=="(not readable)"
ATTRS{driver_override}=="(null)"
ATTRS{enumspeed}=="Device Enumeration Speed = 0x1"
ATTRS{fr_interval}=="Frame Interval = 0x1d4b"
ATTRS{ggpio}=="GGPIO = 0x00000000"
ATTRS{gnptxfsiz}=="GNPTXFSIZ = 0x01000306"
ATTRS{gotgctl}=="GOTGCTL = 0x001c0001"
ATTRS{gpvndctl}=="GPVNDCTL = 0x00000000"
ATTRS{grxfsiz}=="GRXFSIZ = 0x00000306"
ATTRS{gsnpsid}=="GSNPSID = 0x4f54280a"
ATTRS{guid}=="GUID = 0x2708a000"
ATTRS{gusbcfg}=="GUSBCFG = 0x20001700"
ATTRS{hcd_frrem}=="HCD Dump Frame Remaining"
ATTRS{hcddump}=="HCD Dump"
ATTRS{hnp}=="HstNegScs = 0x0"
ATTRS{hnpcapable}=="HNPCapable = 0x1"
ATTRS{hprt0}=="HPRT0 = 0x00001005"
ATTRS{hptxfsiz}=="HPTXFSIZ = 0x02000406"
ATTRS{hsic_connect}=="HSIC Connect = 0x1"
ATTRS{inv_sel_hsic}=="Invert Select HSIC = 0x0"
ATTRS{mode}=="Mode = 0x1"
ATTRS{mode_ch_tim_en}=="Mode Change Ready Timer Enable = 0x0"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{rd_reg_test}=="Time to read GNPTXFSIZ reg 10000000 times: 1210 msecs (121 jiffies)"
ATTRS{regdump}=="Register Dump"
ATTRS{regoffset}=="0xffffffff"
ATTRS{regvalue}=="invalid offset"
ATTRS{rem_wakeup_pwrdn}==""
ATTRS{remote_wakeup}=="Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0"
ATTRS{spramdump}=="SPRAM Dump"
ATTRS{srp}=="SesReqScs = 0x1"
ATTRS{srpcapable}=="SRPCapable = 0x1"
ATTRS{wr_reg_test}=="Time to write GNPTXFSIZ reg 10000000 times: 370 msecs (37 jiffies)"

looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS=="simple-pm-bus"
ATTRS{driver_override}=="(null)"
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
ATTRS{power/control}=="auto"
ATTRS{power/runtime_active_time}=="0"
ATTRS{power/runtime_status}=="unsupported"
ATTRS{power/runtime_suspended_time}=="0"

После сравнения kdiff3 я обнаружил, что у них различается devpath или ещё devnum.

ATTRS{devpath}=="1.2"
ATTRS{devpath}=="1.4"

И так далее. Путь скорее всего является срезом от полного пути.

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2':
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0':
looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0':
looking at _____ device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0':


Я взял devpath и создал ссылку на конкретный физический USB порт.
/etc/udev/rules.d/10-local.rules

SUBSYSTEM=="tty", ATTRS{devpath}=="1.2", SYMLINK+="ttyUSB_1_2", OWNER="velkin", GROUP="dialout", MODE="0666"
SUBSYSTEM=="tty", ATTRS{devpath}=="1.4", SYMLINK+="ttyUSB_1_4", OWNER="velkin", GROUP="dialout", MODE="0666"
SUBSYSTEM=="tty", ATTRS{devpath}=="1.3", SYMLINK+="ttyUSB_1_3", OWNER="velkin", GROUP="dialout", MODE="0666"
SUBSYSTEM=="tty", ATTRS{devpath}=="1.5", SYMLINK+="ttyUSB_1_5", OWNER="velkin", GROUP="dialout", MODE="0666"

И потом сделал примерно так.

ser2net.yaml

connection: &object_30
accepter: tcp,7001
enable: on
options:
banner: *banner
kickolduser: true
telnet-brk-on-sync: true
connector: serialdev,
/dev/ttyUSB_1_2,
9600n81,local

А до этого была попытка определить устройство по его параметрам, а не путь к нему, то есть не по разъёму USB на материнке.

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{product}=="USB2.0-Ser!", SYMLINK+="usb2com_ch340"

Я могу вырезать ещё раз часть кода, ту что под катом.

looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2':
KERNELS=="1-1.2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{authorized}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bConfigurationValue}=="1"
ATTRS{bDeviceClass}=="ff"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{bMaxPower}=="96mA"
ATTRS{bNumConfigurations}=="1"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bcdDevice}=="0254"
ATTRS{bmAttributes}=="80"
ATTRS{busnum}=="1"
ATTRS{configuration}==""
ATTRS{devnum}=="10"
ATTRS{devpath}=="1.2"
ATTRS{devspec}=="(null)"
ATTRS{idProduct}=="7523"
ATTRS{idVendor}=="1a86"
ATTRS{ltm_capable}=="no"
ATTRS{maxchild}=="0"
ATTRS{power/active_duration}=="3100"
ATTRS{power/autosuspend}=="2"
ATTRS{power/autosuspend_delay_ms}=="2000"
ATTRS{power/connected_duration}=="3100"
ATTRS{power/control}=="on"
ATTRS{power/level}=="on"
ATTRS{power/persist}=="1"
ATTRS{power/runtime_active_time}=="2870"
ATTRS{power/runtime_status}=="active"
ATTRS{power/runtime_suspended_time}=="0"
ATTRS{product}=="USB2.0-Ser!"
ATTRS{quirks}=="0x0"
ATTRS{removable}=="removable"
ATTRS{remove}=="(not readable)"
ATTRS{rx_lanes}=="1"
ATTRS{speed}=="12"
ATTRS{tx_lanes}=="1"
ATTRS{urbnum}=="16"
ATTRS{version}==" 1.10"

Если отбросить параметры power, то kdiff3 показывает различие только.

ATTRS{devnum}=="9" ATTRS{devnum}=="10"
ATTRS{devpath}=="1.4" ATTRS{devpath}=="1.2"

То есть команды udevadm info --name=/dev/ttyUSB0 и прочие больше ничего не покажут.

Может тебе это никак и не поможет, но я, например, не нашёл решение своей проблемы в лоб в веб-поиске, но косвенно догадался как решить. А это в свою очередь даёт мне возможность направлять более точные запросы в веб-поиск по тому же devpath. Здесь скорее вопрос можешь ли ты считывать параметры USB устройств в Windows.

Ну то есть, когда устройство втыкается в порт.
1. Можно определить куда воткнули новое устройство, то есть в какой разъём.
devpath (под вопросом devnum)
2. Определить какое устройство было воткнуто.
idVendor, idProduct (под вопросом product) и так далее

А устройство так же может быть USB хабом. И вопрос опять в том, что те же два USB хаба могут ничем и не отличаться. Если бы у меня были конкретные устройства, особенно одинаковые, я бы их воткнул и посмотрел, что будет, если взять два одинаковых хаба, воткнуть их в два USB разъёма на материнке, и потом попытаться отличить один от другого. А если их переткнуть между разъёмами на материнке наоборот.

Вот почему я просто прибил устройство к разъёму USB на материнке, а не к параметрам самого устройства. У меня есть скачанная книжка по программированию USB портов, но я её не читал. Так что я всё это понимаю на примитивном уровне команд утилит в гнулинуксе. Но по сути вызов библиотек включая системные не слишком от них отличается. Что они могут, то и ты сможешь, главное знать, что вызывать.

Опять если набрать в веб-поиске то, что ты сам написал SPDRP_LOCATION_INFORMATION.
https://learn.microsoft.com/ru-ru/windows-hardware/drivers/install/accessing-device-instance-spdrp-xxx-properties
https://www.cyberforum.ru/win-api/thread1176871.html
И так далее. Читаешь, разбираешься, может пишешь код, чтобы посмотреть, что выдаёт система. Или давай дождёмся экспертов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.