The max cable length for USB 2.0 standard is 5 meters. The USB 3.0 standard does not specify a max length, but practically consider it 3 meters. Lengths can be exceeded by passive hubs between cable lengths tor reconditioning the signal and for still longer lengths, active powered hubs. USB over IP consists of a USB server that translates USB signals to network signals and communicates with a client up to 100 meters away which translates network signals back to USB signals. Gigabit network adapters and cables can support 4 USB 2.0 devices at full capacity.
Quoting Chia Huang of Elite Silicon Technology: “Atrust m220 comes with DisplayLink DL125. We know DisplayLink do release Linux driver for Ubuntu system (16.04 and 18.04). However, Atrust has discontinued their m220 box. Almost all network zero clients (with our chip) out there on the market today all come with SMSC’s (now Microchip) UFX6000 chip: HP t200 (discontinued), Atrust m320/m321, Centerm C75 v3, ThinGlobal MiniPoint Ethernet and Phistek ZE6000. The only exception is Phistek’s ZE7000 (https://www.phistek.com/p080.php?id=45) which comes with DL165 chip. But that’s the only DisplayLink chip model and the availability is not as high as the other models.“
The Phisteck ZE7000 sells for $170 direct from manufacturer. The Display Link DL-165 is supported by Linux, but the Eiite Silicon Technology USB over IP chip driver is only available for CentOS and perhaps other rpm based distros. What about an external USB over IP gigabit network hub for multiple Displaylink based USB zeroclients? These also are expensive and I have none to test. The mechanism in Manjaro for auto seat creation requires that the hierarchy of USB devices is maintained. The displaylink device must be seen virtually as a child of the usb zeroclient internal hub, otherwise no new seat is created and it will be treated as a desktop display extention or mirror of the seat0 primary display.
USBIP already exists in both Raspberry Pi and Manjaro software repositories so only an app for non technical people is needed to configure USBIP at both the server and client ends.
Use Add/Remove Software GUI utility and search for USBIP and install on Raspberry Pi (I am using 3B plus model).
The Raspberry Pi will be the USBIP server (package contains both server and client). Googling USBIP returns a lot of out of date documentation. The following currently works in December 2019. In a terminal on the Pi:
pi@raspberrypi:~ $ sudo modprobe usbip_host
pi@raspberrypi:~ $ lsmod |grep usbip_host
usbip_host 28672 0
usbip_core 16384 1 usbip_host
pi@raspberrypi:~ $ sudo usbipd -D
pi@raspberrypi:~ $ usbip list -l
busid 1-1.4 (046d:c52b)
Logitech, Inc. : Unifying Receiver (046d:c52b)
Now plug in my Plugable 3 port USB 3.0 hub and look for usb zero client plugged into this hub which also has its own Logitech, Inc. Unifying Receiver:
pi@raspberrypi:~ $ usbip list -lbusid 1-1.2.1 (0b95:1790)
ASIX Electronics Corp. : AX88179 Gigabit Ethernet (0b95:1790) DisplayLink : unknown product (17e9:410e)busid 1-18.104.22.168 (0d8c:013a)
C-Media Electronics, Inc. : unknown product (0d8c:013a)busid 1-22.214.171.124 (046d:c52b)
Logitech, Inc. : Unifying Receiver (046d:c52b)busid 1-1.4 (046d:c52b)
Logitech, Inc. : Unifying Receiver (046d:c52b)
pi@raspberrypi:~ $ sudo usbip bind -b 1-126.96.36.199 <--- c-media
usbip: info: bind device on busid 1-188.8.131.52: complete
pi@raspberrypi:~ $ sudo usbip bind -b 1-184.108.40.206 <--- HP T150 with unifying receiver
usbip: info: bind device on busid 1-220.127.116.11: complete
pi@raspberrypi:~ $ sudo usbip bind -b 1-18.104.22.168 <--- displaylink
usbip: info: bind device on busid 1-22.214.171.124: complete
This is encouraging. It would be desirable for usbipd to be a service started at boot and for it to bind all usb devices so that they become available to the client on the Manjaro desktop. It would be desirable not to have to configure each device you want to be found. Enlisting google again with this additional criterion, I found this link:
He shows how to export one specific usb device by code that searches for its idVendor:idProduct value. What if you want to export more than one device, or you don’t know in advance what devices will be plugged in? This suggests an alternative approach – instead of specifying for what you want to export, instead search for what you don’t want and avoid exporting that while exporting everything else. You will discover one thing that you must exclude. The Rasberry Pi 3x gigabit LAN port is the child of a usb bus. On the PI 3B, its idVendor:idProduct is 0424:ec00, but on the Pi 3Bplus, it is 0424:7800. If you were to export this usb LAN device you have broken the LAN pipe that you are exporting other usb devices over. The Pi 4B gigabit LAN is not USB based so not an issue.
If you are using docking stations as zero clients, then you have no use for the docking stations LAN port, so that is also good to avoid exporting. Implementing these changes to his code results in the following content which you need to create with an editor and root privileges and save as /lib/systemd/system/usbipd.service
[Unit] Description=usbip host daemon After=network.target [Service] Type=forking ExecStart=/usr/sbin/usbipd -D # ExecStartPost=/bin/sh -c "/usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep -v '0424:7800#'| grep -v '0b95:772a#' | cut '-d#' -f1)" # ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep -v '0424:7800#' | grep -v '0b95:772a#' | cut '-d#' -f1`); killall usbipd" [Install] WantedBy=multi-user.target pi@raspberrypi-3B:~ $
One very interesting aspect of launching a shell with the -c “….” option is that it can read multiple lines of text from standard input until all sti has been consumed. The code within (…) writes a line of text for every usb device found except for devices excluded by grep’s -v option. ‘0424:7800’ is the raspberry pi’s usb gigabit LAN device that must be excluded. ‘0b95:772a’ is the ASIX Electronics Corp. : AX88772A Fast Ethernet usb device on a Plugable UD-160-A docking station which is not relevant to its use as a zero client.
Following Derusha’s model results in his (…) writing multiple lines to sto, but the first part of his “ExecStartPost=” only consumes the first line of its sti, so only the first local usb device will be found. It will be easier to get a user pace solution working first, so I have commented out two lines.
!/bin/bash sudo modprobe usbip_host lsmod |grep usbip_host sudo usbipd -D usbip list -l read -p "Press any key to bind all" sudo usbip list -p -l | grep -v '0424:7800#'| grep -v '0b95:772a#' | cut '-d=' -f2 | cut '-d#' -f1 | xargs -L 1 -r sudo bash -c 'usbip bind -b"$0" ' read -p "Press any key to exit"
We will also need an unbind version:
!/bin/bash sudo modprobe usbip_host lsmod |grep usbip_host sudo usbipd -D usbip list -l read -p "Press any key to unbind all" sudo usbip list -p -l | grep -v '0424:7800#'| grep -v '0b95:772a#' | cut '-d=' -f2 | cut '-d#' -f1 | xargs -L 1 -r sudo bash -c 'usbip unbind -b"$0" ' read -p "Press any key to exit"
I have chosen to export all devices connected to the Raspberry Pi 3B+’s 4 usb ports, and to communicate with it with either Putty for CLI or with x2go for a full desktop GUI experience, rather than input devices using up one or two of its 4 usb ports. Both use port 22 for remote access. If you want to use the Pi for both a usb server of network attached usb zero clients and a desktop in its own right, then you would want to choose a different model of input device than will be used with any of the zero client workstations. For Logitech wireless keyboards and mice, there is one model of nano receiver (046d:c525) and 5 models of unifying receiver (046d:c52b, c52f, c531, c532, and c534). The one you choose to stay local to the Pi, should be added to my grep -v filters in the code above so that it is not found and exported.
Having created and saved /lib/systemd/system/usbipd.service, do the following steps as detailed by https://derushadigital.com/other%20projects/2019/02/19/RPi-USBIP-ZWave.html
# reload systemd, enable, then start the service
sudo systemctl --system daemon-reload
sudo systemctl enable usbipd.service
sudo systemctl start usbipd.service
Note that if no usb devices are plugged into the Pi, none will be found when usbipd.service is started and the result is that this service will terminate since it has nothing to do.
Now for the client side on the Manjaro desktop that we want to recognize all potential remote usb over IP zero clients. Ideally when they are found, a new named seat will be created for each with a new login window.
This turns out to be more challenging. Most of the documentation you find on Google for USBIP is obsolete, or only applies to certain Linux distributions. My server side instructions may not work on other distributions than Raspbian for the Raspberry Pi I am using. USBIP started out as a user space project and then later parts were incorporated into the kernel. Add typos in various documentation and you have a lot to try and I am still working on it.
Raspbian does not support USB multi-seat, so that is not the end goal, but since it does have the USBIP package in its repository, it is handy for testing client code. The client needs to be able to attach and detach remote usb devices. Some usb devices have internal ports, so detaching is based on ports not usb bus IDs. 192.168.10.113 is the IP of my Raspberry Pi 3B+, you will need to edit this IP for your server.
!/bin/bash sudo modprobe vhci_hcd lsmod |grep vhci_hcd sudo usbipd -D usbip list -r 192.168.10.113 |cut '-d:' -f1 |grep 1-1 |tr -d ' ' read -p "Press any key to attach all" usbip list -r 192.168.10.113 |cut '-d:' -f1 |grep 1-1 |tr -d ' ' | xargs -L 1 -r sudo bash -c 'sudo usbip attach -r 192.168.10.113 -b"$0" ' read -p "Press any key to exit"
The command, usbip port, will list the imported remote USB devices and their ports. Not all USB ports are necessarily occupied, so the following code removes error messages from trying to read empty USB ports.
!/bin/bash usbip port 2>/dev/null
Before can unbind USB on the server, the client has to detach any imported ports.
sudo modprobe vhci-hcd lsmod |grep vhci-hcd sudo usbipd -D usbip port 2>/dev/null | grep '' | sed -E 's/^Port ([0-9][0-9])./\1/' read -p "Press any key to detach all ports" usbip port 2>/dev/null | grep '' | sed -E 's/^Port ([0-9][0-9])./\1/'| xargs -L 1 -r sudo bash -c 'sudo usbip detach -p"$0" ' read -p "Press any key to exit"
WordPress is removing some of my program characters. I need to figure out how to make it display correctly as well as produce the correct result when you copy and paste this code. Before I fix it, you are welcome to request the proper code as an email attachment using my contact form.
Raspberry Pi 3B + model binding all its USB ports for export; Raspberry Pi 4B+ model attached (imported) usb devices: Kingston flashdrive, USB DVD player with media, as well as a Plugable UD-160-A Docking Station/zeroclient with its own Logitech unifying receiver.
With only the Mediatek, Inc. USB drive connected, the Raspberry Pi 3B+ idles at 2.9 watts and uses 4.6-4.9 watts while serving a DVD movie to some other computer that has imported this USB drive. VLC will pop up when drive is imported with attach command.