p910nd Print Server
p910nd is a small printer daemon intended for diskless platforms that does not spool to disk but passes the job directly to the printer. Normally a lpr daemon on a spooling host connects to it with a TCP connection on port 910n (where n=0, 1, or 2 for lp0, 1 and 2 respectively). p910nd is particularly useful for diskless platforms. Common Unix Printing System (CUPS) supports this protocol, it's called the AppSocket protocol and has the scheme
socket://remotehost:PORT
Windows and Mac Os X (via CUPS) also support this protocol. In mac OS Printer settings, the protocol is called HP Jetdirect - Socket
. Before starting, ensure you do not also have node_exporter scrape endpoints running on port 9100. If you do, adjust this guide to start with port 9101.
In this guide I show you how to enable printing support for HP M1120 and Canon MP480 printer.
Install software on LEDE device
- SSH into device, e.g.
ssh 192.168.1.1
- Enter
root
as username and supply with password - Update OpenWrt software packages:
opkg update
- Install Kernel modules for USB Printer support:
opkg install kmod-usb-printer
- Install printer server:
opkg install p910nd luci-app-p910nd
Configure print server p910nd
- Check if your printer is recognized:
root@OpenWrt:~# ls /dev/usb/lp* /dev/usb/lp0
- We can continue with configuring in Services → p910nd - Printer server:
The screenshot speaks for itself: Check enable, set Device address and check/uncheck Bidirectional mode. Bidirectional mode depends on your router. On my HP printer I leave it enabled, on my Canon I must disable, else printing is not working. - Consider leaving the interface unspecified so it listens on all IPv4 interfaces (on 0.0.0.0, alas no IPv6 support).
You should also open a port in the firewall for each printer configured. Once the above is done, it might be necessary to restart the print server with:
/etc/init.d/p910nd restart
Configure clients
Windows
First, install drivers for your printer.
- You may try to print a test page to the printer.
Mac OS X Sierra
First, try configure your printer via System Preferences:
- Done. Try with a test print.
This method has worked for me with a HP M1120 printer, but it failed with my Canon MP480 (Error: unable to communicate with printer). So I added manually.
Manual method
- You are done, try it with a test print.
For LEDE 17.01.x, p910nd printing should work straight away after completing above steps. For OpenWRT 18.06.x, you may need to power cycle the router after installing the p910nd packages. For 21.02.x, things should work straight away.
Debugging
Okay, your printer is connected to the router, lsusb -v
shows the device connected, and you have a /dev/usb/lp0
also. You send data to the printer, but nothing happens. Connecting your computer directly to the printer works fine. Some forum posts note that you may need to send the printer firmware to the printer after power-on. In my printer's case, an HP LaserJet 1018, it was necessary. GitHub might also have The dl file for LaserJet 1018
My printer wakes up with: cat sihp1018.dl > /dev/usb/lp0
Some users opted to run a script to automate this. On 21.02 - make a script /etc/hotplug.d/usb/30-hplj1018
, chmod +x /etc/hotplug.d/usb/30-hplj1018
and enjoy. See hotplug for info to verify subsystems, and variables below.
- /etc/hotplug.d/usb/30-hplj1018
#!/bin/sh set -e # change this to the location where you put the .dl file: FIRMWARE="/root/hplj1018.dl" DEVICE=$(uci get p910nd.@p910nd[0].device) LOGFILE=/var/log/hp PROD_ID="3f0/4117/100" DEV_TYPE="usb_device" daemon_restart() { echo "$(date) : (Re)Starting print daemon" >> $LOGFILE /etc/init.d/p910nd restart } daemon_stop() { echo "$(date) : Stopping print daemon" >> $LOGFILE /etc/init.d/p910nd stop } send_firmware() { echo "$(date) : Sending firmware to printer" >> $LOGFILE cat $FIRMWARE > $DEVICE echo "$(date) : done." >> $LOGFILE } if [ "$PRODUCT" = "${PROD_ID}" ]; then case "$ACTION" in add) sleep 1 # Check whether dev is character type if [ -c $DEVICE ]; then # Check whether the hotplug devtype is usb_device if [ "$DEVTYPE" = "${DEV_TYPE}" ]; then send_firmware daemon_restart fi fi ;; remove) daemon_stop ;; #Also available: bind) ;; esac fi