Monthly Archives: July 2014

Getting a Windows Printer (Ricoh Aficio SP 204) natively running on Linux

Printing and scanning has always been the bane of Linux.  I thought I solved it three years ago by getting a nice network printer (HP OfficeJet Pro 8600) which spoke postscript and could scan to folder (provided you have samba installed).  Unfortunately, this is an inkjet printer and about three months ago the initial cartridges (which are deliberately lightly loaded) ran out of ink.  Purchasing new ones (it’s colour so I need four) turned out to be an arm and a leg (or 2x what the printer cost to buy in the first place).  Three months after replacement, the whole thing died with a call HP technicians error.  This turns out mostly to mean my ink cartridges are leaking.  Sure enough the entire inside is awash with a substance more costly than liquid gold … plus it’s now all over my shirt and trousers.  Trying to clean it out just gets ink all over the desk and some important papers.  Of course, since it’s a UK purchased printer and I’m now living in the US, HP support “cannot help”.  Vowing never to purchase another @!**#@ inkjet printer as long as I live, it’s time to find a cheap multi-function laser (did I mention the scanner function on the HP won’t work either now because when it gets this error it locks every function).

Investigating lasers, the cheapest multi-function seems to be a Ricoh Aficio SP204 N (the N means netowrk connected, which is nice) for US$60, which is a bargain, plus it’s a laser.  Google confirms it can scan to pdf (via file share or email), the only drawback is that the printer engine is “windows only” (one of those direct render on the system and send to printer ones).  Further googling around for the printer and linux drivers (and even DDST, the Ricoh name for their direct rendering protocol on linux) yields nothing.  Looks like I’ll be writing a driver when it arrives.  Fortunately, there is a way of running it (using KVM instead of VirtualBox) providing you have a windows virtual machine, so that’s the initial plan.  The only other annoyance is it doesn’t do duplex (either for scanning or printing).  Bummer, but you can’t have everything for US$60.

When the printer arrives, it turns out it has a web interface (yay) but you can’t program scan destinations with it (and without scan destinations, it won’t scan) … bummer.  Install the windows virtual machine with the Ricoh driver and use the tool to program scan to email; amazingly enough it all works correctly (it even scans in colour).  Followed the redirection directions with ghostview, ghostscript and redmon and successfully attach the printer to Linux.

Now to get the thing working under linux.  First step is to use tcpdump to track the communication between the windows machine and the printer:

tcpdump -n -w /tmp/trace.ricoh -i eth0 <printer ip>

And then print something.  Looking at the trace file in wireshark, the windows driver uses the HP Jetdirect port (9100).  In wireshark, select the first packet to this port and right click on “follow TCP stream”.  That gives the whole file the windows system sent.  Now save it to a file (tmp.winprint) and see if that’s enough the get the printer going.  You do this by sending the saved file to the printer with netcat:

nc <printer ip> 9100 < tmp.winprint

Wonder of wonders, it prints the same page again, so now we have the correct format to send.  A quick view with emacs reveals a HP PJL (Print Job Language) encoded header and footer with binary data in between.  This is the header:

^[%-12345X@PJL 
@PJL SET TIMESTAMP=2014/07/22 18:31:06 
@PJL SET FILENAME=gsprint 
@PJL SET COMPRESS=JBIG 
@PJL SET USERNAME=SYSTEM 
@PJL SET COVER=OFF 
@PJL SET HOLD=OFF 
@PJL SET PAGESTATUS=START 
@PJL SET COPIES=1 
@PJL SET MEDIASOURCE=TRAY1 
@PJL SET MEDIATYPE=PLAINRECYCLE 
@PJL SET PAPER=A4 
@PJL SET PAPERWIDTH=4961 
@PJL SET PAPERLENGTH=7016 
@PJL SET RESOLUTION=600 
@PJL SET IMAGELEN=61304

And this is the footer:

@PJL SET DOTCOUNT=995745 
@PJL SET PAGESTATUS=END 
@PJL EOJ 
^[%-12345X

So it all seems relatively straightforwards: each page is rendered as a pixel map in the jbig compressed image format (it’s lossless, like gif) and the header describes exactly the size and dimensions of the image.  So getting it working seems to be very straightforward: just generate the jbig images and slap on the header and footer.  Ghostscript doesn’t render natively to jbig, but it will render to ppm and the jbigkit renders what I need.  The image dimensions can be obtained from the ppm with the ImageMagick identify command.  The only fly in the ointment is the DOTCOUNT.  This shows per page how many black pixels are printed and must be something to do with the way the printer tracks the cartridge use; however, it can be faked for the moment.

The jbig format is also used in faxes, so I asked google if anyone else had a piece of code that does the split.  Since it would have the “@PJL SET COMPRESS=JBIG” line, I did a code search for that;  what do you know, it turns up a linux driver for the Ricoh Aficio SP 100:

https://github.com/madlynx/ricoh-sp100

To add insult to injury, the READMEs mention terms I’ve been searching for for ages (like Ricoh and DDST) and the driver filter even has them in the file name … honestly, for being allegedly the primary search engine of the internet, you’d sometimes wonder if google could find its own arse with both hands.

So, download this and install it and, yay, it works.  Looks like the only real difference between the SP 100 and the SP 204 is that the latter has a higher resolution mode (1200×600) and also can be adjusted to use a bypass tray (which is set in the header too).

I’ve done an initial package here and will be updating for the SP 204 additional features.