p910nd is a small non-spooling printer daemon intended for disk-less workstations. Jobs are being passed 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 Linux workstations booted via Etherboot that have a printer hanging off them. Common Unix Printing System (CUPS) supports this protocol, it's called the AppSocket protocol and has the scheme socket://. LPRng also supports this protocol and the syntax is lp=remotehost%9100 in /etc/printcap.
Alternatives to p910nd can be found at the Print Server overview.
/etc/config/firewall to accept packets on on TCP port 9100: #Allow attached network printer
config 'rule'
option 'src' 'lan'
option 'proto' 'tcp'
option 'dest_port' '9100'
option 'target' 'ACCEPT'
opkg update opkg install kmod-usb-printer
Now plug in the printer, run dmesg and look for lines similar to the following ones:
hub.c: new USB ice 01:02.0-1, assigned address 2 printer.c: usblp0: USB Bidirectional printer 2 if 0 alt 0 proto 2 vid 0x04A9 pid 0x1094 usb.c: USB disconnect on ice 01:02.0-1 address 2 hub.c: new USB ice 01:02.0-1, assigned address 3 printer.c: usblp1: USB Bidirectional printer 3 if 0 alt 0 proto 2 vid 0x04A9 pid 0x1094
On older versions the device /dev/usb/usblp0 is created. More recent versions create the normal /dev/lp0 device, even for usb printers. (Attitude Adjustment 12.09 actually creates /dev/usb/lp0).
TIP: p910nd is reported as working with some noname USB-to-Parport adapter/converter as well
opkg update opkg install kmod-lp
Check the output of the dmesg.
If there is a device node /dev/printers/0 then the installation succeeded.
TIP: p910nd is reported as working with some noname USB-to-Parport adapter/converter as well
opkg update opkg install p910nd
or through luci.essentials: Select Administration View and the System→Software). In case of an error, try to update the package list.
Install packages: luci-app-p910nd and p910nd. The configuration is done (Administration view) via Services → p910nd - Printer Server.
We recommend to configure manually. But for lazy bones, there might be instructions at Zero configuration network setup to utilize auto-magic software.
If your printer (mine hl-2030) spits out garbage after poweron, p910nd might be the cause. Add this to /etc/hotplug.d/usb/20-printer
#!/bin/sh # Copyright (C) 2006 OpenWrt.org if [ "$PRODUCT" = "4f9/27/100" ] then case "$ACTION" in add) /etc/init.d/p910nd stop echo "`date`: Brother HL-2030 added" >> /tmp/hl-2030 /etc/init.d/p910nd start >> /tmp/hl-2030 echo "Done." >> /tmp/hl-2030 ;; remove) echo "`date`: Brother HL-2030 removed" >> /tmp/hl-2030 /etc/init.d/p910nd stop >> /tmp/hl-2030 echo "Done." >> /tmp/hl-2030 ;; esac fi
Where “$PRODUCT” = “4f9/27/100” is your printers VendorId/ProductId/BcdVersion(1.00 = 100). Get it with lsusb -v
You might need to add “-INT” to the kill command in /etc/init.d/p910nd to actually have the stop work.
To avoid having to install the printer on multiple clients, it can be advertised via txt-records so that ZeroConf capable clients can pick it up automatically.
ZeroConf use txt-records to advertise services on a local network. With a lot of annoying config options we can use dnsmasq which is included by default in OpenWrt to accomplish this.
Create or edit the file /etc/dnsmasq.conf and add the lines below.
expand-hosts domain=lan local=/lan/ txt-record=lan,"v=spf1 a -all" # Default Base ptr-record=b._dns-sd._udp.0.1.168.192.in-addr.arpa,lan ptr-record=db._dns-sd._udp.0.1.168.192.in-addr.arpa,lan ptr-record=r._dns-sd._udp.0.1.168.192.in-addr.arpa,lan ptr-record=dr._dns-sd._udp.0.1.168.192.in-addr.arpa,lan ptr-record=lb._dns-sd._udp.0.1.168.192.in-addr.arpa,lan # Services ptr-record=_services._dns-sd._udp.lan,_pdl-datastream._tcp.lan #printer ptr-record=_pdl-datastream._tcp.lan,HP-LaserJet-1200._pdl-datastream._tcp.lan srv-host=HP-LaserJet-1200._pdl-datastream._tcp.lan,HP-LaserJet-1200.lan,9100 txt-record=HP-LaserJet-1200._pdl-datastream._tcp.lan,ty=HP LaserJet 1200,note=Basement,product=(HP LaserJet 1200),usb_MFG=HP,usb_MDL=HP LaserJet 1200,txtvers=1,qtotal=1,priority=20,Color=F,pdl=application/vnd.hp-PCL
lan keyword in the txt record refers to OpenWrt's default local domain name - you need to change it if you use a different local domain.0.1.168.192 keyword in the ptr record refers to OpenWrt's default network range, octets reversed - you need to change it if you use a different range.product, pdl, usb_MFG and usb_MDL attributes specify printer properties_pdl-datastream mime type maps to the “HP JetDirect” service type. other options are _printer and _ipp (but then those printers normally have ethernet builtin)HP-LaserJet-1200 Is both a DNS hostname and the printer name. Because of this you need to follow the LDH rule (letters, digits, hyphen). Avahi does not have this restriction.→ See Zero configuration networking in OpenWrt and try to use the mdns instead of Avahi.
Similar to the dnsmasq variant above, the same can be done using Avahi.
opkg update
opkg install avahi-daemon
Apple's Bonjour Printing Specification discusses pretty much what needs to be done to advertise a printer over the network.
For example Brother HL-2030, a “softprinter” (does not support Postscript or PCL, all processing is done on the client) shared via p910nd:
Create the file /etc/avahi/services/printer.service:
<?xml version="1.0" standalone='no'?><!--*-nxml-*--> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">Brother HL-2030 Laserprinter on %h</name> <service> <type>_pdl-datastream._tcp</type> <port>9100</port> <txt-record>qtotal=1</txt-record> <txt-record>note=room 2</txt-record> <txt-record>ty=Brother HL-2030 Laserdrucker</txt-record> <txt-record>product=(Brother HL-2030 series)</txt-record> <txt-record>usb_MFG=Brother</txt-record> <txt-record>usb_MDL=HL-2030 series</txt-record> <txt-record>Color=F</txt-record> <txt-record>Duplex=F</txt-record> <txt-record>Bind=F</txt-record> <txt-record>Collate=F</txt-record> <txt-record>Sort=F</txt-record> <txt-record>Staple=F</txt-record> <txt-record>Punch=F</txt-record> <txt-record>PaperMax=legal-A4</txt-record> </service> </service-group>
_pdl-datastream._tcp, the "needs a driver" printer typeusb_MFG and usb_MDL TXT records are required. product is used as a fallback in case the other two doesn't exist.txt-records with usb_MFG and usb_MDL, then look up the PPD document for your printer on OpenPrinting.org and search for the line beginning with *1284DeviceID:. This line contains multiple KEY:VALUE pairs separated by ;, but you just need the two called MFG and MDL (Manufacturer and Model).txt-records called Color, Duplex, Bind, Collate, Sort, Staple and Punch all take the values F=False, T=True, and U=unknown. The printer driver installed should override these values with correct defaults.txt-record called PaperMax should always be legal-A4.The printer will now show up in any ZeroConf client (tested with OS X 10.4.10 and Ubuntu 12.04).
#part of /etc/config/network config 'interface' 'lan' option 'type' 'bridge' option 'ifname' 'eth0.0' option 'proto' 'static' option 'ipaddr' '192.168.1.3' option 'netmask' '255.255.255.0 option 'bcast' '192.168.1.255'
NOTE: The default port used by p910nd is TCP 9100 on the device /dev/usb/lp0.
You can check the ports on which p910nd is listening with the command
netstat -an
Assuming the printer driver is installed locally, it's a simple matter of entering http://localhost:631/admin in your favorite web-browser, and pressing add printer under the “Printers” pane. Then:
Then you use your new printer like you would a local one.
Note that many Epson and Canon Inkjet printers (and maybe other brands) do not provide a really full-CUPS driver. If you do not get anything printed try to install the Gutenprint drivers and select them instead.
The following instructions should work on all versions of windows from 2000 onwards, and have been tested in both Windows 2000 and Windows Vista.
Not supported printers shall be reported upstream! → http://p910nd.sourceforge.net/
Some Canon Printers are not working in bidirectional mode in combination with Windows NT based OS. Reported printers that are only working properly in unidirectional mode:
Please add not working combinations here:
Warning : This will/can add a considerable amount of messages to your System Log which is a fixed size buffer in memory, by default, consisting of up to 16 KB utf-8/ASCII encoded characters.
You can relay the p910nd process messages by modifying the p910nd init.d script by adding a couple service parameters.
diff --git a/etc/init.d/p910nd b/etc/init.d/p910nd --- a/etc/init.d/p910nd +++ b/etc/init.d/p910nd @@ -53,7 +53,26 @@ start_p910nd() { config_get mdns_mdl "$section" mdns_mdl config_get mdns_cmd "$section" mdns_cmd [ "$mdns" -gt 0 ] && procd_add_mdns "pdl-datastream" "tcp" "$((p ort+9100))" "note=$mdns_note" "ty=$mdns_ty" "product=$mdns_product" "usb_MFG=$md ns_mfg" "usb_MDL=$mdns_mdl" "usb_CMD=$mdns_cmd" + + procd_set_param stdout 1 # relay stdout to logd + procd_set_param stderr 1 # relay stderr to logd procd_close_instance fi }
note: you will need to restart the service for this to take effect
/etc/init.d/p910nd restart
Under Luci → Status → System Log we will be able to see the debug info: e.g. printing a blank page
Tue Oct 20 13:50:52 2020 daemon.info p910nd[1545]: Connection from 192.168.1.123 port 2484 accepted Tue Oct 20 13:50:52 2020 daemon.info p910nd[1545]: read 1494 bytes from network Tue Oct 20 13:50:52 2020 daemon.info p910nd[1545]: wrote 1494 bytes to printer Tue Oct 20 13:50:52 2020 daemon.info p910nd[1545]: read: eof Tue Oct 20 13:50:52 2020 daemon.info p910nd[1545]: Finished job: 1494/1494 bytes sent to printer, 0/0 bytes sent to network
This can also be read via ssh with the command logread
root@OpenWrt:~# logread -e p910nd
To run HP LaserJet 1005/1018/1020/1022 on OpenWrt Backfire 10.03.1-RC5 do:
Preparations on client computer:
First install the foo2zjs drivers from http://foo2zjs.rkkda.com/ on your client computer (in case of a linux client). The instructions are taken from http://foo2zjs.rkkda.com/.
Click the link, or cut and paste the whole command line below to download the driver.
$ wget -O foo2zjs.tar.gz http://foo2zjs.rkkda.com/foo2zjs.tar.gz
Now unpack it:
$ tar zxf foo2zjs.tar.gz $ cd foo2zjs
Compile and install it. The INSTALL file contains more detailed instructions.
$ make
Get extra files from the web, such as .ICM profiles for color correction and firmware. Select the model number for your printer:
$ ./getweb 2430 # Get Minolta 2430 DL .ICM files $ ./getweb 2300 # Get Minolta 2300 DL .ICM files $ ./getweb 2200 # Get Minolta 2200 DL .ICM files $ ./getweb cpwl # Get Minolta Color PageWorks/Pro L .ICM files $ ./getweb 1020 # Get HP LaserJet 1020 firmware file $ ./getweb 1018 # Get HP LaserJet 1018 firmware file $ ./getweb 1005 # Get HP LaserJet 1005 firmware file $ ./getweb 1000 # Get HP LaserJet 1000 firmware file
Install driver, foomatic XML files, and extra files:
$ su OR $ sudo make install # make install
(Optional) Configure hotplug (USB; HP LJ 1000/1005/1018/1020):
Hint: The hotplug script is used to transfer the printer firmware file (for example 'sihp1020.dl') to the printer. If you don't use the printer directly plugged in into the client computer but only via your router box with p910nd, then this hotplug installation is not needed here (see below, behind section 'Preparations on router:' - hotplug will be configured in the router device).
# make install-hotplug OR $ sudo make install-hotplug
(Optional) If you use CUPS, restart the spooler:
# make cups OR $ sudo make cups
Preparations on router:
Next you need to transfer sihp1020.dl to your Asus box.
On the Asus device you should install the following packages:
opkg update opkg install kmod-usb-printer p910nd
Next:
/etc/init.d/p910nd start /etc/init.d/p910nd enable
Finally you need to create a script that uploads the firmware to your printer after you've plugged it in.
For a quick test, you could just use netcat for loading the firmware manually to the printer (from the client computer, via the router with p910nd established). Enter the following command on the client computer:
nc -q2 192.168.2.99 9100 < /usr/share/foo2zjs/firmware/sihp1020.dl
(the above IP-address has to be replaced with your router address and the path to your correct firmware file needs to be adapted as well)
Another possibility, with the network printer already set up with cups as default printer (replace firmware file path according to your situation):
lp -o raw /usr/share/foo2zjs/firmware/sihp1020.dl
After successfully loading the firmware with one of the above commands printing should work as well (until next power-down of your printer). You can decide to do this always manually one time before sending the first print job after powering up the printer or to configure the mentioned script for automatic firmware upload as following:
Create a new file /etc/hotplug.d/usb/20-hplj1020:
#!/bin/sh set -e # change this to the location where you put the .dl file: FIRMWARE="/usr/lib/sihp1020.dl" DEVICE=/dev/lp0 LOGFILE=/var/log/hp if [ "$PRODUCT" = "3f0/2b17/100" -a "$ACTION" = "add" ]; then for i in $(seq 30); do if [ -c $DEVICE ]; then echo "$(date) : Sending firmware to printer..." > $LOGFILE cat $FIRMWARE > $DEVICE echo "$(date) : done." >> $LOGFILE exit fi sleep 1 done fi
The parameter 3f0/2b17/100 needs to be changed to match your printer.
The format is idVendor/idProduct/bcdDevice from the device descriptor.
Numbers are hexadecimal, without leading '0x' or zeros.
For BcdVersion 1.00 = 100. Get it with lsusb -v.
More information on this can be found at http://linux-hotplug.sourceforge.net/?selected=usb .
Some printers, like HP LaserJet 1005, stop working properly when the firmware is loaded more than once. It's best to check whether the firmware is already present in the printer with the usb_printerid command. You need to cross-compile this command for yourself. It's part of the foo2zjs projet. Furthermore, the hotplug script is called twice for the “add” ACTION for the same value of PRODUCT: first for DEVTYPE='usb_device', then for DEVTYPE='usb_interface'. Therefore, the following is the script that works with HP LaserJet 1005:
#!/bin/sh set -e # change this to the location where you put the .dl file: FIRMWARE=/usr/lib/sihp1005.dl DEVICE=/dev/lp0 LOGFILE=/var/log/hp if [ "$PRODUCT" = "3f0/1317/120" -a "$ACTION" = "add" -a "$DEVTYPE" = "usb_interface" ]; then echo "$(date): STARTING" > $LOGFILE for i in $(seq 30); do echo "$(date): Attempt number $i on $DEVICE" >> $LOGFILE if [ -c $DEVICE ]; then echo "$(date): Device $DEVICE found." >> $LOGFILE if [ -z "`usb_printerid $DEVICE | grep FWVER`" ]; then echo "$(date): No firmware found on $DEVICE" >> $LOGFILE echo "$(date): Sending firmware to printer..." >> $LOGFILE cat $FIRMWARE > $DEVICE echo "$(date): done." >> $LOGFILE else echo "$(date): Firmware already there on $DEVICE" >> $LOGFILE fi echo "$(date): EXITING" >> $LOGFILE exit fi sleep 1 done fi
An alternative to the method described above is to “simulate” a JetDirect device. I've tested this with my HP LaserJet 1020 but should be applicable to other HP printers which need the hplip driver to work.
In short, you need to announce with zeroconf and respond to one SNMP oid.
Install the application, configure, start and enable it
opkg update opkg install kmod-usb-printer p910nd vi /etc/config/p910nd /etc/init.d/p910nd start /etc/init.d/p910nd enable
Install and configure avahi-daemon as describe in the section With Zeroconf
above. I used the following printer.service file:
<?xml version="1.0" standalone='no'?><!--*-nxml-*--> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">HP LaserJet 1020 on %h</name> <service> <type>_pdl-datastream._tcp</type> <port>9100</port> <txt-record>qtotal=1</txt-record> <txt-record>note=I forgot where I placed my printer</txt-record> <txt-record>ty=HP LaserJet 1020</txt-record> <txt-record>product=(HP LaserJet 1020 Printer)</txt-record> <txt-record>usb_MFG=Hewlett-Packard</txt-record> <txt-record>usb_MDL=HP LaserJet 1020</txt-record> <txt-record>Color=F</txt-record> <txt-record>Duplex=F</txt-record> <txt-record>Bind=F</txt-record> <txt-record>Collate=F</txt-record> <txt-record>Sort=F</txt-record> <txt-record>Staple=F</txt-record> <txt-record>Punch=F</txt-record> <txt-record>PaperMax=legal-A4</txt-record> </service> </service-group>
The hp-setup (from hplip) will do an SNMP get for the oid 1.3.6.1.4.1.11.2.3.9.1.1.7.0 (gdStatusId). I don't know exactly what format the string is supposed to have but I've used this troubleshooting guide as a base for the information.
NOTE: once mini_smpd is updated to 2.0, this will be configurable via mini-snmpd.conf without patching:
custom ".1.3.6.1.4.1.11.2.3.9.1.1.7.0" {
value = "MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CLS:PRINTER;SN:XXXXXXX;"
}
With mini_snmpd older than 2.0, you need to compile your own mini-snmpd package. See Using the SDK for more information about how to use the SDK.
Download the source to mini_snmpd, modify the following patch and apply it.
--- a/mib.c +++ b/mib.c @@ -53,6 +53,7 @@ static const oid_t m_cpu_oid = { { 1, 3 #ifdef __DEMO__ static const oid_t m_demo_oid = { { 1, 3, 6, 1, 4, 1, 99999 }, 7, 10 }; #endif +static const oid_t m_dev_status_oid = { { 1, 3, 6, 1, 4, 1, 11, 2, 3, 9, 1, 1}, 12, 13 }; static const int m_load_avg_times[3] = { 1, 5, 15 }; @@ -610,6 +611,10 @@ int mib_build(void) } #endif + if (mib_build_entry(&m_dev_status_oid, 7, 0, BER_TYPE_OCTET_STRING, (const void *)"MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CLS:PRINTER;DES:HP LaserJet 1020;SN:XXXXXXX;") == -1) { + return -1; + } + return 0; }
You need to modify the long line and replace XXXXXXX with your serial number. You can find the serial number with the following commands.
lsusb -v | egrep 'iManufacturer|iProduct|iSerial'
This should give the information you need for MFG:, MDL: and SN: in the patch above.
Another way to get this string is to plug it into another computer with cups and hplip installed.
You can use /usr/lib/cups/backend/hp to get a similar string. I've assumed that they should match
with the one provided over SNMP.
When you recompile, change the PKG_RELEASE in the Makefile to differ it from the upstream version. Otherwise you won't be able to install your newly built package.
When you have installed and started mini_snmpd you can test if it works with the following command.
snmpwalk -Os -c public -v1 192.168.1.1 1.3.6.1.4.1.11.2.3.9.1.1.7.0 enterprises.11.2.3.9.1.1.7.0 = STRING: "MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CLS:PRINTER;DES:HP LaserJet 1020;SN:XXXXXXX;"
If that works, you should be able to use hp-setup to add a network printer. If it doesn't show up in the list of network printers, you have something wrong with the zeroconf part.