Turning a USB printer into a network accessible device

Raspberry Pis are fun. You can do a lot of cool things with them. For that matter, there are some really lame educational albeit non-utilitarian projects out there. To be fair, this project doesn't really require a Raspberry Pi, but the small form factor of the Raspberry Pi makes it ideal. I chose to use a Raspberry Pi Zero W.

So what's the project? Turn an all-in-one printer/scanner into a network accessible device. I should make it clear that I run Linux OSs. As such part of what I have written here probably won't apply directly to the Windows crowd.

How does it work?
The approach here is twofold. The printer can be shared with CUPS from the PiZeroW, so that part is rather trival. Sharing the scanner over the network is the less trivial part, though not horribly complicated. To accomplish this, I used usbip which provides a way to share a USB device over an IP network.
Hosting a USB devices with the usbip server introduces a new problem. When usbip is hosting the device, the local computer (PiZeroW) can't use the device, and thus network printing cannot be provided with CUPS. The solution? Let the PiZeroW have full control of the device unless someone asks to use the scanner. Using knockd, we can listen for requests to use the scanner. When someone knocks, all we have to do is pass the USB printer/scanner over to usbip and make it available for network access. The client script that makes this request must also clean up after it is finished (knock https://howtoraspberrypi.com/how-to-raspberry-pi-headless-setup/to let the PiZeroW know it's done) so that the printer/scanner can be handed back to the PiZeroW.


Supplies
  • One Raspberry Pi Zero W (though any Linux box or Raspberry Pi with networking would suffice).
  • All of the stuff needed to run the Raspberry Pi (SD card, power, micro-USB to full size USB adapter)
  • An all-in-one HP Deskjet F2100 series printer/scanner. Note the brand and model are not important. What is important is that the devices has Linux drivers.
  • A second computer running Ubuntu 18.04 from which I want to use my network printer/scanner (the distribution and version are not of great importance, but as noted later, this system must have a version of usbip compatible with that on the PiZeroW).

Making it happen
I'm not going to walk through every step here, because much of what I will describe can be accomplished by following other readily available tutorials.

  1. Set up the PiZeroW:
    • Download Raspbian Stretch Lite, Stretch being the current version as of writing. This will eventually change with future releases. I'm using the June 2018 version.
    • Follow the steps for a headless setup to get SSH and WiFi up and running on your PiZeroW before booting for the first time.
    • Once you have your PiZeroW set up, connect the printer and SSH into the PiZeroW. Update the package lists and install usbip, cups, and hplip (that last package provides the drivers for HP printers)
      sudo apt update && sudo apt install usbip cups hplip knockd
    • Configure cups and make sure it's running
      sudo usermod -a -G lpadmin pi && sudo service cups restart
    • SSH into the PiZeroW with the option, -L 6310:localhost:631. This will allow you to browse to https://localhost:6310 on the Ubuntu machine and manage the available printers on the PiZeroW. Ignore the certificate errors and add the USB printer to the PiZeroW as a shared printer.
    • Pull the knockd.conf file from my Github and change the ports as you like or just leave them as they are. Save this file as /etc/knockd.conf. If you're not using wireless on the PiZeroW, also be sure the change the interface!
    • Copy the host-printer.sh and stop-hosting-printer.sh files from my Github and save them in /usr/local/bin
    • There is a bug in a knockd service file. Fix that.
      echo -e '[Install]\nWantedBy=multi-user.target\nAlias=knockd.service' | sudo tee -a /lib/systemd/system/knockd.service && echo FIXED
    • Set knockd to start on system boot
      sudo systemctl enable knockd.service
    • Please note that the configuration used for usbip assumes that you are using a PiZeroW without a USB hub. If you're using a hub or a different pi with multiple USB ports, you will need to find out what the correct busid is for your attached printer and updated this in the host-printer.sh and stop-hosting-printer.sh files.
    • Reboot the PiZeroW, and you should be ready to move on to the clients
  2. Setup your Ubuntu 18.04 client: Before I get started here, I should mention that the Ubuntu 18.04 usbip executable (provided by linux-tools-*generic) is not compatible with the Raspbian usbip executable. I worked this one over for a while and finally asked about it. A very helpful commentator noted that the usbip packages for Raspbian and Debian Buster had no problem getting along. My solution was to pull the usbip package from the Debian Buster repos and install it in Ubuntu 18.04. No more problem!
    • Get the usbip package for Debian Buster and install it in Ubuntu 18.04 machine
      wget -O /tmp/usbip.deb "http://http.us.debian.org/debian/pool/main/l/linux/usbip_2.0+4.18.6-1_amd64.deb" && sudo dpkg -i /tmp/usbip.deb
    • Install knockd
      sudo apt update && sudo apt install knockd
    • Pull the attach-scanner.sh script from my Github and drop it on the client.
    • Run the attach-scanner.sh script and enter your account password. The first time you run this, it will ask you for the IP address of the PiZeroW. Ideally this should be configured as a static lease on your router. If you changed the ports in /etc/knockd.conf on the PiZeroW, then you need to change the ports in this script to match those. Also, if you had to change the busid on the server side hosting scripts, you'll have to change it in this file as well.
Usage
At this point, you're ready to roll! On the client machine, you simply run the attach-scanner.sh script. This will perform a knock sequence on the PiZeroW which will respond by making the USB printer/scanner available over the network. The script will then automatically connect to the printer. After connecting, it will simply wait. If you close the window or press <kbd>Enter</kbd>, the script running on the client will take that to mean that you're finished, and the client will disconnect the remote USB device and then send a knock sequence to the PiZeroW signifying that the PiZeroW can do what it needs to do to take back local control of the device for network printing.

Comments

Popular posts from this blog

Encrypted Ubuntu Installation with "Manual" Partitioning

Router Firmware -- Dumping and Flashing

DIY lefty USB hub with fingerprint reader for about $5