candle-usb/candleLight_fw

Udev rules to bind specific dongle's SN to specific interface name

iDoka opened this issue · 3 comments

iDoka commented

Hi and thanks for that great work (including awesome approach to getting uniq SN).

In my setup I have several CAN-to-USB dongles (500k, 125k), and AFAIK CAN bus environment very sensitive with CAN controller setting (esp. bus speed setting).

I need some approach to udev rules for binding dongles with specific Serial Numbers with specific interface's names.
I case for using dongles based on SLCAN it simple task with following solution /etc/udev/rules.d/cantact.rules:

KERNEL=="ttyUSB*",  ATTRS{serial}=="000500127746430120333937", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="606f", MODE:="0777", SYMLINK+="ttyCAN0_500k"

KERNEL=="ttyUSB*",  ATTRS{serial}=="000500127746430120333939", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="606f", MODE:="0777", SYMLINK+="ttyCAN0_125k"

For gs_usb dongles I would like to have something similar to:

ACTION=="add" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="606f", ATTRS{serial}=="000500127746430120333937", MODE="660", GROUP="users", TAG+="uaccess", RUN+="ip link set canX type can bitrate 500000 && ifconfig canX up"

ACTION=="add" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="606f", ATTRS{serial}=="000500127746430120333939", MODE="660", GROUP="users", TAG+="uaccess", RUN+="ip link set canY type can bitrate 125000 && ifconfig canY up"

But I don't know the way to define canX and canY.
How can I do binding SN=000500127746430120333937 to can0 (for example) and SN=000500127746430120333939 to can1?

Maybe some clues : ID_SERIAL_SHORT is our serial number; but I'm I'm not sure either how to specify the net interface name canX in a udev rule; this page may have some ideas https://packetpushers.net/udev/ .

$ udevadm info /sys/bus/usb/devices/1-3.2

P: /devices/pci0000:00/0000:00:01.3/0000:01:00.0/usb1/1-3/1-3.2
N: bus/usb/001/084
L: 0
E: DEVPATH=/devices/pci0000:00/0000:00:01.3/0000:01:00.0/usb1/1-3/1-3.2
E: DEVNAME=/dev/bus/usb/001/084
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d50/606f/0
E: TYPE=0/0/0
E: BUSNUM=001
E: DEVNUM=084
E: MAJOR=189
E: MINOR=83
E: SUBSYSTEM=usb
E: USEC_INITIALIZED=808990027399
E: ID_VENDOR=chacaltech
E: ID_VENDOR_ENC=chacaltech
E: ID_VENDOR_ID=1d50
E: ID_MODEL=cannette_gs_usb
E: ID_MODEL_ENC=cannette\x20gs_usb
E: ID_MODEL_ID=606f
E: ID_REVISION=0000
E: ID_SERIAL=chacaltech_cannette_gs_usb_003800254250431420363230
E: ID_SERIAL_SHORT=003800254250431420363230
E: ID_BUS=usb
E: ID_USB_INTERFACES=:ffffff:fe0101:
E: ID_VENDOR_FROM_DATABASE=OpenMoko, Inc.
E: ID_MODEL_FROM_DATABASE=Geschwister Schneider CAN adapter
E: ID_PATH=pci-0000:01:00.0-usb-0:3.2
E: ID_PATH_TAG=pci-0000_01_00_0-usb-0_3_2
E: ID_FOR_SEAT=usb-pci-0000_01_00_0-usb-0_3_2
E: TAGS=:uaccess:seat:
E: CURRENT_TAGS=:uaccess:seat:

Actually, udev manpages refer to systemd.link for exactly this kind of thing. And, what a surprise, I was able to get something working in a few minutes, with a new file in

# cat /etc/systemd/network/60-persistent-candev.link 
[Match]
Property=ID_MODEL=cannette_gs_usb ID_SERIAL_SHORT="003800254250431420363230"

[Link]
# from systemd.link manpage:
# Note that specifying a name that the kernel might use for another interface (for example "eth0") is dangerous because the name assignment done by udev will race with the assignment done by the kernel, and only one
#   interface may use the name. Depending on the order of operations, either udev or the kernel will win, making the naming unpredictable. It is best to use some different prefix

Name=cannette5

and after resetting this board :

 $ ip a
....
57: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP group default qlen 10
    link/can 
59: cannette5: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can 

So... success ? @iDoka , let me know if this can work for your application ; if so, I'll add a note about this in the README

Added info in README.