Serial-port for device with two interfaces

I am working on an Ubuntu Core project that needs serial-port paths for a single USB FTDI device that exposes two interfaces. There needs to be two exposed paths, one for each of the device’s two interfaces.

It has been suggested that snapd may need to support a third (as-yet-identified) attribute since the vendorID and the productID are the same for the two interfaces/paths. Perhaps snapd already creates two paths in such a case, differentiated by the trailing digit? (Customer has the USB device now, so I cannot test, but they are looking for clear understanding to determine whether they need to file a snapd feature request bug.)

Suppose this slot for a two-interface device:

slots:
  serial-port:
    path: /dev/serial-port-BE0
    usb-vendor: 0xTHEVENDOR
    usb-product: 0xTHEPRODUCT

Would snapd deterministically provide these paths?

  • device’s first interface: /dev/serial-port-BE0
  • device’s second interface: /dev/serial-port-BE1

Or, is this required (with a snapd enhancement for the third attribute, of course):

slots:
  serial-port:
    path: /dev/serial-port-BE0
    usb-vendor: 0xTHEVENDOR
    usb-product: 0xTHEPRODUCT
    THIRD-ATTRIBUTE: X

  serial-port:
    path: /dev/serial-port-BE1
    usb-vendor: 0xTHEVENDOR
    usb-product: 0xTHEPRODUCT
    THIRD-ATTRIBUTRE: Y

Thanks

So snapd is not the one providing the path and it will not write anything referencing /dev/serial-port-BE0. What will happen is that snapd will take the slot definition and write out a udev rule on the system which then is processed by udev. For your first slot definition, snapd will write out this udev rule:

# serial-port
IMPORT{builtin}="usb_id"
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="THEVENDOR", ATTRS{idProduct}=="THEPRODUCT", SYMLINK+="/dev/serial-port-BE0"

which then upon boot will be used by udev when considering new devices the kernel provides to udev. If as you say this device has multiple devices which match this rule, this rule will be applied for both devices, but since you can only ever have one symlink with one target, the rule that runs last will win and the device that udev sees last will be the target of the symlink /dev/serial-port-BE0, and the previous symlink target will be lost.

The TLDR is that the rule will run for multiple devices connected at the same time, but it’s not-deterministic which actual device will be the target of the symlink, but it will only be one of them and there will not be a /dev/serial-port-BE1 anywhere.

Yes a third attribute in snapd is needed to support this situation. I note that after consulting the code a little bit more, snapd also supports a usb-interface-number attribute as well which corresponds to the udev variable ENV{ID_USB_INTERFACE_NUM}=="SOME_HEX_NUMBER". If this is specified it is added in addition to the vendor ID and product ID already specified in the slot definition, so perhaps this variable is enough for this device.

I tested this, and it appears to work. Thanks.

@degville: usb-interface-number attribute should probably be documented.

1 Like

Thanks for letting me know Kyle. I’ll do this.