Skip to content

Instantly share code, notes, and snippets.

@Leo-PL
Last active April 6, 2024 11:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Leo-PL/b5ee737e49b34c1551dba6c182707c8e to your computer and use it in GitHub Desktop.
Save Leo-PL/b5ee737e49b34c1551dba6c182707c8e to your computer and use it in GitHub Desktop.
[DEPRECATED - see https://github.com/Leo-PL/my-openwrt-packages/tree/master/utils/persistent-serial} Persistent serial port names for USB-serial on OpenWrt hotplugd
[ "${ACTION}" = "add" -o "${ACTION}" = "remove" ] || exit 0
[ "${SUBSYSTEM}" = "tty" ] || exit 0
[ -n "${DEVNAME}" -a -n "${DEVPATH}" ] || exit 1
if [ "${ACTION}" = "add" ]; then
subsystem="$(basename $(readlink /sys${DEVPATH}/../../../subsystem))"
[ "$subsystem" = "usb" ] || exit 0
manufacturer="$(cat /sys${DEVPATH}/../../../../manufacturer)" || manufacturer="$(cat /sys${DEVPATH}/../../../../idVendor)"
product="$(cat /sys${DEVPATH}/../../../../product)" || product="$(cat /sys${DEVPATH}/../../../../idProduct)"
serial="$(cat /sys${DEVPATH}/../../../../serial)"
interface="$(cat /sys${DEVPATH}/../../../bInterfaceNumber)"
port="$(cat /sys${DEVPATH}/device/port_number)"
id_link=$(echo "${subsystem}"-"${manufacturer}"_"${product}${serial:+_}${serial}"-if"${interface}${port:+-port}${port}" | s/[^\.\:0-9A-Za-z-]/_/g)
path_link=$(echo "${DEVPATH}${port:+-port}${port}" | sed s%/devices/%% | sed s%/${DEVNAME}/tty/${DEVNAME}%%g | sed s/[^\.\:0-9A-Za-z-]/_/g)
mkdir -p /dev/serial/by-id /dev/serial/by-path
ln -sf "/dev/${DEVNAME}" "/dev/serial/by-id/${id_link}"
ln -sf "/dev/${DEVNAME}" "/dev/serial/by-path/${path_link}"
elif [ "${ACTION}" = "remove" ]; then
for link in $(find /dev/serial -type l); do
[ -L ${link} -a "$(readlink ${link})" = "/dev/$DEVNAME" ] && rm ${link}
done
fi
@Zerogiven
Copy link

This script is great, but do you have an idea if it is possible to make hardlinks instead of softlinks?
The problem is, if i map it into docker, the target from the symlink is missing or wrong :)

@Leo-PL
Copy link
Author

Leo-PL commented Mar 7, 2024

I haven't tried, really, but it could be enough to remove -s from calls to ln. Or even just cp them, because they are just character device nodes.

@Zerogiven
Copy link

Zerogiven commented Mar 8, 2024

i'll give it a try with cp, cause hardlink with ln does not work, but thanks 🙂

@galenseitz
Copy link

Hi,
On line 12, serial is set, but it is never used. Was this intentional? On two udev systems I have here (ubuntu 22.04, CentOS 7), the serial number appears after the product string. For example:
usb-FTDI_FT232R_USB_UART_B0009WPF-if00-port0
usb-FTDI_TTL232RG-VIP_FT3Z78MG-if00-port0

@Leo-PL
Copy link
Author

Leo-PL commented Mar 28, 2024

Huh, it looks like I forgot to include it for some reason :-D
I'll push updated version when I test it out.
Edit: done, please try it out. Should work even if serial attribute is missing from the device, like with cheap CH341 adapters. I'm thinking about submitting this script upstream.

@galenseitz
Copy link

Thanks. The serial number is now present.

Looking at this further, I noticed some other things.

  1. Is the intent to mimic udev behavior? If so, the sed command at the end of line 16 is problematic. For example, under udev, my FTDI FT230X-based device shows up like this: usb-ACME_coyote_serial-v1.0_FT50OA8O-if00-port0. Using your script with OpenWRT, it looks like this: usb-ACME_coyote_serial-v1_0_FT50OA8O-if00-port0. Perhaps '.' and ':', and possibly other characters should also be excluded from being mangled. I could try to track down the udev code that does this if that would be helpful.
  2. I wonder if the script should be using bind/unbind rather than add/remove. The only reason for saying this is because of reading this https://lwn.net/Articles/837033/ on lwn.net. For simple serial devices, waiting for the bind event is likely unnecessary, but in the future there may be devices where waiting for bind is needed. The script would need tweaking to use bind. If you're interested in this, I can modify the script to support it.
  3. This likely isn't your department, but the OpenWRT hotplug documentation doesn't even mention tty events. I took me a while to realize that I needed to create the /etc/hotplug.d/tty directory and place my script in there. This was before I discovered your script today. If you happen to know someone within the OpenWRT community that could edit the page to add the tty event, that would be helpful to others. https://openwrt.org/docs/guide-user/base-system/hotplug#how_it_works

@Leo-PL
Copy link
Author

Leo-PL commented Mar 28, 2024

@galenseitz
ad 1: I intended the names to be persistent to the device and to path, and close to udev - but not exact. I'm not that pedantic. Getting that done exactly as in udev would probably take more code and effort - I'd like to keep this as simple as possible. Perhaps this can be extended inside hotplugd as new environment variables. Aand then used in the script. An idea worth exploring. Variables inside usb subsystem seem to cover that already.
As for mangling characters, I already excluded . and : from by-path symlinks, now I see a point to not mangle them for by-id as well.

ad 2: yeah, that's possible, but I'm unsure if it worked back in the 19.07 days, when I implemented this initially. I'd be welcome if you could try it out. "bind" would be good for coldplug, but as we're dealing with USB anyway, this doesn't matter as much, handling "add" events should work just as fine - and platform serial ports should be deterministic without that anyway.

ad 3: Wiki is often outdated. I can't promise to clean that up, but if you'd like, you can request a wiki account on forum.openwrt.org and document that, since you're fresh on the topic.

@galenseitz
Copy link

I understand about wanting to keep it simple. That said, I decided to go ahead and make the changes for myself. I forked your code. Unfortunately it seems that github doesn't support pull requests for gists. Anyway, you can see my version here https://gist.github.com/galenseitz/f3b2c4a45557eebe992dc637a1db070b. I have comments on each commit, but I don't see a way to view them. It looks like you may have to clone my gist to see them.

@Leo-PL
Copy link
Author

Leo-PL commented Mar 30, 2024

Copying the URL manually worked. It isn't as complicated as I envisioned after all, I'll try it out. Looks cool!
I plan to package the script in https://github.com/Leo-PL/my-openwrt-packages soon-ish. I mean - I created the package, but I have yet to at least build-test it.

@Leo-PL
Copy link
Author

Leo-PL commented Apr 6, 2024

@galenseitz I updated the wiki for TTY events as well, and hell - even put the script above as an example, already in your improved form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment