Apple AirPrint on TomatoUSB Router

In this tutorial, I’m going to show you how to setup Apple AirPrint Server on a router running TomatoUSB firmware. This will allow you to print from your iOS device (iPhone, iPod, iPad) to your non-AirPrint-enabled printer through your router. If you’re familiar with AirPrint Activator or FingerPrint, this solution is similar, except you don’t have to keep your power hungry MAC/PC running 24/7.

Before I start, I want to give special thanks to @davygravy on the TomatoUSB.org forum. He was the one that ultimately made this all possible by compiling, re-compiling and fixing all the required packages.

Another thing, if you’re familiar with my Tutorial on Apple AirPlay on TomatoUSB Router, these two tutorials (currently) are not compatible with each other. Meaning, you either go with AirPrint or AirPlay on your TomatoUSB Router, NOT BOTH. This is because the AirPrint tutorial uses Entware and this tutorial uses Optware, which isn’t compatible with each other. Hopefully we’re get this issue resolved in the near future.

Note: this tutorial is a work in progress (but working). I’ll be updating and flushing out the details as time permits. Please excuse the typos and bad grammar.

YMMV (Your Mileage May Vary) depending on your Printer model.

What you’ll need:

  1. Router with TomatoUSB installed*
  2. USB Flash Drive >1GB (will be completely wiped)
  3. USB or Wireless/Network Printer
* If you’re looking for a recommendation on a router for this project,  please check this post – [Tutorial] Apple AirPlay on TomatoUSB Router. You can pick up a router as low as $24.

Outline of Steps:

  1. Partition and Format USB Flash Drive*
  2. Install Optware
  3. Download and Install Required Packages
  4. Start CUPS and Configure Printer(s)
  5. Generate AirPrint Service File
  6. Startup DBus, Avahi and CUPS
  7. Test Print
  8. Configure the router so that everything works after a reboot
  9. CloudPrint (Bonus Content)

*Note that your USB Flash Drive will be completely wiped clean.

1) Partition and Format USB Drive:

Plug in your USB drive and connect to your router via SSH (Putty) and execute the following commands:

#Partition your usb flash drive
umount /dev/sda1
fdisk /dev/sda

Type in the following commands to create a primary partition on your USB Flash drive
# p # list current partitions
# o # to delete all partitions
# n # new partition
# p # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w # write new partition to disk

#format newly created partition
#label disk as ‘optware’ case sensitive
umount /dev/sda1
mke2fs -j -L optware /dev/sda1

#mount partition as /opt
mount /dev/sda1 /opt

#Make sure /opt is properly mounted on a reboot.
echo “LABEL=optware /opt ext2 defaults 1 1” >> /etc/fstab
nvram setfile2nvram /etc/fstab
nvram commit

2) Install Optware

#Install Optware from scratch.
#Assumes drive is formated and mounted as /opt already
cd /tmp
wget http://tomatousb.org/local–files/tut:optware-installation/optware-install.sh -O – | tr -d ‘\r’ > /tmp/optware-install.sh
chmod +x /tmp/optware-install.sh
sh /tmp/optware-install.sh

3) Download and Install Required Packages

#create a folder to store packages
mkdir -p /opt/ipkgs
cd /opt/ipkgs

#install wget-ssl (for https)
ipkg install wget-ssl

#download packages.
#cut/paste this whole section

/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/dbus_1.2.16-2_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/cups_1.5.4-1_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/poppler_0.12.4-1_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/py26-cups_1.9.62-1_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/ghostscript_8.71-3_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/hplip_3.11.7-1_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/gutenprint_5.2.9-1_mipsel.ipk
/opt/bin/wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/cups-driver-gutenprint_5.2.9-1_mipsel.ipk
#install packages. this may take awhile.
#cut/paste this whole section
ipkg install /opt/ipkgs/dbus_1.2.16-2_mipsel.ipk
ipkg install /opt/ipkgs/cups_1.5.4-1_mipsel.ipk
ipkg install /opt/ipkgs/poppler_0.12.4-1_mipsel.ipk
ipkg install /opt/ipkgs/py26-cups_1.9.62-1_mipsel.ipk
ipkg install /opt/ipkgs/ghostscript_8.71-3_mipsel.ipk
ipkg install /opt/ipkgs/gutenprint_5.2.9-1_mipsel.ipk
ipkg install /opt/ipkgs/cups-driver-gutenprint_5.2.9-1_mipsel.ipk

#install hplip if you have a HP printer
#ipkg install /opt/ipkgs/hplip_3.11.7-1_mipsel.ipk

#install splix for Samsung printers
#ipkg install splix

#Color profiles for Samsung (untested)
#cd /opt/share/cups/model/samsung
#wget http://splix.ap2c.org/samsung_cms.tar.bz2
#tar xvjf samsung_cms.tar.bz2
#rm samsung_cms.tar.bz2

4) Start CUPS and Configure Printer(s)
#start cups
cupsd
Now open up your web browser and go to http://<RouterIPAddress>:631/admin (http://192.168.1.1:631/admin).
Click on “Manage Printers”->”hp990c”
Administration->Delete Printer (this printer was accidentally included)
If you’re prompted for authentication, enter in root and your password.
Go back to Administration->Add Printer
In my case, I am using a Brother HL-2270DW which has built in wireless and supports various printing options – socket, ipp, http, etc. I’m going to use socket (AppSocket/HP JetDirect) which is the same option you would select if you had your USB printer directly connected to your router. Make sure you enable “USB Printer Support” in the Tomato GUI if you’re using a USB attached printer.
For my wireless printer, the Connection address I’m using is “socket://<PrinterIPAddress>:9100” ( for the record “ipp://<PrinterIPAddress>/pcl_p1” would also work).
For a USB attached printer, the Connection address would be: “socket://<RouterIPAddress>:9100” (i.e., socket://192.168.1.1:9100)
Name your printer. Check the “Share This Printer” checkbox (not totally sure if this is required, but for now check it to be safe).
Select the Make/Model of your Printer. Basically you are selecting the drivers to use. For my Brother HL-2270DW, I went with “Generic”->”Generic PCL 6/PCL XL Printer”.
Click Add Printer.
Set your Default Options.

Print a test page. Maintenance->Print Test Page.

Printing a test page needs to work. If not, you can not continue. Not all printers will work. Try different drivers (or a different printer).

5) Generate AirPrint Service File
 
Back in your SSH console session, execute the following:

#Stop CUPS
killall cupsd

#create some needed mime types for AirPrint and iOS6
echo “image/urf urf string(0,UNIRAST<00>)” > /opt/share/cups/mime/airprint.types

echo “image/urf application/pdf 100 pdftoraster” > /opt/share/cups/mime/airprint.convs

#Start CUPS
cupsd

#make airprint folder
mkdir -p /opt/airprint
cd /opt/airprint

#Download airprint-generate.py
#this is all one line

/opt/bin/wget –no-check-certificate https://raw.github.com/tjfontaine/airprint-generate/master/airprint-generate.py

#set the script to be executable
chmod 755 ./airprint-generate.py

#Generate airprint service file
cd /opt/etc/avahi/services
python2.6 /opt/airprint/airprint-generate.py

#There should be a
#AirPrint-<PrinterName>.service file listed
ls

#Stop CUPS
killall cupsd

6) Startup DBus, Avahi (aka Bonjour) and CUPS

#Required for Avahi and dbus
#Ignore the warning
adduser avahi
addgroup netdev

#delete orphan pid files in case they exist
rm /opt/var/run/dbus/pid
rm /opt/var/run/avahi-daemon/pid

#start dbus before avahi
/opt/etc/init.d/S20dbus start

#start avahi (aka bonjour)
avahi-daemon -D

#Start CUPS
cupsd

#verify that your printer is being advertise
avahi-browse –terminate –resolve _ipp._tcp

7) Test Print

From your iPhone/iPad/iPod, do a test print.

8) Configure the router so that everything works after a reboot

Go to USB and NAS -> USB Support (http://192.168.1.1/nas-usb.asp).
In the “Run after mounting” section add the following:

#Required for avahi and dbus
adduser avahi
addgroup netdev

#delete orphan pid files in case they exist
rm /opt/var/run/dbus/pid
rm /opt/var/run/avahi-daemon/pid

#start dbus before avahi
/opt/etc/init.d/S20dbus start

#start avahi (aka bonjour)
avahi-daemon -D

#Start CUPS
cupsd

In the “Run before unmounting” section add the following:

#run before unmounting
killall cupsd
avahi-daemon -k
/opt/etc/init.d/S20dbus stop

You’re done. Enjoy!

9) Google CloudPrint (Bonus Content – Work In Progress)

ipkg install git
cd /opt

git clone git://github.com/armooo/cloudprint

cd /opt/cloudprint
python2.6 setup.py build
python2.6 setup.py install

#Run once to create credential files
#give it about a minute to start up
/opt/local/bin/cloudprint
#enter your google account email and password
#Google username:
#Password:

#test print from your Chrome browser
#Control+C to close cloudprint

#copy your cloudprint authentication files to /opt
cp /tmp/home/root/.cloudprintauth /opt/cloudprint
cp /tmp/home/root/.cloudprintsaslauth /opt/cloudprint

To have cloudprint start automatically on reboot. Go to USB and NAS -> USB Support (http://192.168.1.1/nas-usb.asp). In the “Run after mounting” section add the following:

#copy back cloudprint authentication files to /tmp
cp /opt/cloudprint/.cloudprintauth /tmp/home/root/

cp /opt/cloudprint/.cloudprintsaslauth /tmp/home/root/
/opt/local/bin/cloudprint &

In the “Run before unmounting” section add the following:

killall cloudprint

Cloudprint is very fragile. If you’re having start-up or printing issues try the following steps.

– Clear your Google CloudPrint Print Queue – https://www.google.com/cloudprint/#jobs
– Delete your stored credential and reboot and start over.

One more thing regarding CloudPrint, my recommendation is to set up a new Google Account dedicated just for CloudPrint. Use this account for the above cloudprint login, and then share your printer(s) with your main account. I’m a little paranoid of having my email authentication stored on my router (even though its hashed or whatever).

If you get AirPrint working with your printer, please leave a comment with your printer model and drivers used. This will help other users. Thanks

Please leave a comment with any questions or feedback. Thanks

[Update 4/9/2013] Please check out my PogoPlug Tutorial below. A PogoPlug running Arch Linux ARM is the perfect companion to your TomatoUSB Router. I highly recommend that you run AirPlay/AirPrint on the PogoPlug versus your TomatoUSB router.