Thursday, 15 April 2010

HP Deskjet F4210 All-in-One printer/scanner on Debian Lenny using SANE

This is what I had to do to get the scanner of my HP Deskjet F4210 All-in-One printer/scanner working on my NSLU2 running Debian Lenny. First install the sane packages -

NSLU2:~# apt-get install sane-utils libsane

This also installs a lot of dependencies so will take some time. Then plug in the USB cable from the printer to the NSLU2 and check whether sane recognizes the scanner -

NSLU2:~# sane-find-scanner

...

found USB scanner (vendor=0x03f0 [HP], product=0x2504 [Deskjet F4200 series]) at libusb:001:006

...

Lots of other lines printed out to but the main point is the USB scanner is detected. Check now that sane knows how to drive this scanner -

NSLU2:~# scanimage -L

No scanners were identified. If you were expecting something different,
check that the scanner is plugged in, turned on and detected by the
sane-find-scanner tool (if appropriate). Please read the documentation
which came with this software (README, FAQ, manpages).

OK, this means that the appropriate sane backend is not there. After a bit of googling found that my scanner requires the 'hplip' package to be installed which provides the required sane config files -

NSLU2:~# apt-get install hplip

LOADS of dependencies also installed. Must try and find if there is a smaller package that just gets the minimum for sane to work. Anyway, rechecking that sane can drive the scanner -

NSLU2:~# scanimage -L
device `hpaio:/usb/Deskjet_F4200_series?serial=CN8952V2TC05C3' is a Hewlett-Packard Deskjet_F4200_series all-in-one

Now to run the sane daemon, need to edit
/etc/default/saned

NSLU2:~# nano /etc/default/saned

and change the line to RUN=yes

# Set to yes to start saned
RUN=yes

then start the daemon -

NSLU2:~# /etc/init.d/saned start
Starting SANE network scanner server: saned.

and check it is running -

NSLU2:~# ps -ef | grep sane
saned 10223 1 0 13:26 ? 00:00:00 /usr/sbin/saned -a saned
saned 10224 10223 0 13:26 ? 00:00:00 /usr/sbin/saned -a saned




Monday, 3 November 2008

Add a DNS and DHCP server with dnsmasq

In order to better control the allocation of addresses to the various bits that are now on the local network, I've added a DNS and DHCP server to 'fileserver' with dnsmasq. First install it

fileserver:~# apt-get install dnsmasq

then edit the configuration file /etc/dnsmasq -

# Don't use /etc/resolv.conf or any other
# file, get servers from this file instead
no-resolv
server=192.168.2.1

#This is our home network domain name
domain=ourhouse.net

#Don't forward anything without a full domain name
domain-needed
#Don't try to do reverse lookups of private IP addresses
bogus-priv
#Don't forward these local domains
local=/ourhouse.net/
local=/azea.net/

#Start the DHCP server
dhcp-range=192.168.2.20,192.168.2.49,12h

# Override the default route supplied by dnsmasq, which assumes the
# router is the same machine as the one running dnsmasq.
dhcp-option=3,192.168.2.1

# For debugging purposes, log each DNS query as it passes through
# dnsmasq.
log-queries

'fileserver' itself will have to have a static IP address now - since I will be turning off the DHCP server on the gateway router - therefore need to edit /etc/network/interfaces compared to the one used in the earlier post -

#This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
    address 0.0.0.0

auto br0
iface br0 inet static
    address 192.168.2.18
    netmask 255.255.255.0       
    gateway 192.168.2.1
    bridge_ports eth0 tap0
    pre-up openvpn --mktun --dev tap0
    post-down openvpn --rmtun --dev tap0

/etc/resolv.conf must be edited to make dns lookups originating on 'fileserver' use the local DNS server -

nameserver 127.0.0.1

and /etc/hosts edited so that dns lookups will find the correct addresses for 'fileserver' and 'gateway' - the only devices on the network that will not get their addresses from the new DHCP server -

127.0.0.1       localhost
192.168.2.1     gateway
192.168.2.18    fileserver

dnsmasq writes it's DHCP lease in formation to /var/lib/misc/dnsmasq.leases -

1225776083 00:0e:a6:9f:04:e7 192.168.2.32 Playroom-Router 01:00:0e:a6:9f:04:e7
1225772336 00:1a:73:bf:97:0c 192.168.2.25 AndrewsPC 01:00:1a:73:bf:97:0c
1225748001 00:10:60:a1:3c:79 192.168.2.15 Will-PC 01:00:10:60:a1:3c:79

Now I can let all other devices get there IP addresses via DHCP and I can refer to them by their hostnames - for example pinging 'fileserver' from a Windows machine gives -

C:\Documents and Settings\andrew>ping fileserver

Pinging fileserver.ourhouse.net [192.168.2.18] with 32 bytes of data:

Reply from 192.168.2.18: bytes=32 time=1ms TTL=64
Reply from 192.168.2.18: bytes=32 time=2ms TTL=64
Reply from 192.168.2.18: bytes=32 time=3ms TTL=64
Reply from 192.168.2.18: bytes=32 time=3ms TTL=64

Ping statistics for 192.168.2.18:
     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
     Minimum = 1ms, Maximum = 3ms, Average = 2ms

and similarly pinging 'Playroom-Router' from a linux box -

box:~# ping Playroom-Router
PING Playroom-Router (192.168.2.32) 56(84) bytes of data.
64 bytes from Playroom-Router.ourhouse.net (192.168.2.32): icmp_seq=1 ttl=64 time=17.9 ms
64 bytes from Playroom-Router.ourhouse.net (192.168.2.32): icmp_seq=2 ttl=64 time=4.20 ms
64 bytes from Playroom-Router.ourhouse.net (192.168.2.32): icmp_seq=3 ttl=64 time=3.11 ms
64 bytes from Playroom-Router.ourhouse.net (192.168.2.32): icmp_seq=4 ttl=64 time=2.19 ms
64 bytes from Playroom-Router.ourhouse.net (192.168.2.32): icmp_seq=5 ttl=64 time=3.22 ms

--- Playroom-Router ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4039ms
rtt min/avg/max/mdev = 2.199/6.137/17.943/5.937 ms

Super!

Thursday, 23 October 2008

Install an OpenVPN server on the fileserver

I'm going to use an OpenVPN based Ethernet bridge to allow me to connect to my home LAN via the Internet when I'm away from home.

First install the openvpn, bridge-utils (for the Ethernet bridge) and openssl (to generate certificates) packages

fileserver:~# apt-get install openvpn bridge-utils openssl

The /etc/init.d/openvpn script that comes with the package is far to complicated for me to understand/need so I replaced it with a simpler one (copied the original one to /etc/init.d/openvpn.orig)

#! /bin/sh
# /etc/init.d/openvpn
#

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting openvpn server"
    openvpn --config /etc/openvpn/simple.conf
    ;;
  stop)
    echo "Stopping openvpn server"
    killall openvpn
    ;;
  *)
    echo "Usage: /etc/init.d/openvpn {start|stop}"
    exit 1
    ;;
esac

exit 0

To use the killall command, I had to install the psutils package.

To make the bridge between the tap device and the physical ethernet port, I edited the edit /etc/network/interfaces to -

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
#allow-hotplug eth0
auto eth0
iface eth0 inet static
        address 0.0.0.0
        netmask 255.255.255.0

auto tap0
iface tap0 inet static
        address 0.0.0.0
        netmask 255.255.255.0
        pre-up /usr/sbin/openvpn --mktun --dev tap0

auto br0
iface br0 inet dhcp
        hostname fileserver
        bridge_ports eth0 tap0

Generating the required certificates is as described in openVPN HOWTOs. The easy-rsa directory was at /usr/share/doc/openvpn/examples/easy-rsa/2.0. I copied this to /etc/openvpn and worked there. At the end of the process I copied the files needed on the server to /etc/openvpn -

/etc/openvpn/ca.crt
/etc/openvpn/server.crt
/etc/openvpn/server.key
/etc/openvpn/dh1024.pem

The files needed on the client are -

ca.crt
client.crt
client.key

The openVPN server configuration file /etc/openvpn/simple.conf is -

dev tap0
server-bridge 192.168.2.1 255.255.255.0 192.168.2.101 192.168.2.110
user nobody
persist-key
persist-tun
proto udp
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh1024.pem
daemon

This will allow up to 10 clients to connect which will be given IP addresses from 192.168.2.101 to 192.168.2.110 on the home LAN. Note 192.168.2.1 is the IP address of the home LAN router.

Finally, I needed to forward TCP and UDP ports 1194 on the WAN side of my internet firewall to the fileserver IP address 192.168.1.18.

My first client is the my windows laptop running OpenVPN GUI for Windows. The client config file is -

client
dev tap
proto udp

remote flabby.is-a-geek.com 1194

nobind

persist-key
persist-tun

mute-replay-warnings

ns-cert-type server

verb 3

ca   "ca.crt"
key  "client.key"
cert "client.crt"

float

 

 

OK

Monday, 20 October 2008

Add dynamic DNS service updater

I'm going to be adding a VPN gateway to the fileserver so I can access it over the internet. I have an account at DynDNS that will map the WAN address of my router to my DynDNS domain name. I need a simple client on the LAN to update this account when the WAN address changes.

The simplest client recommened at DynDNS seems to be inadyn which I installed on the fileserver

fileserver:~# apt-get install inadyn

I generated the required config file automatically using the DynDNS tool and saved it on the fileserver at /etc/inadyn.conf.

fileserver:~# cat /etc/inadyn.conf
## inadyn configuration file
update_period_sec 600 # Check for a new IP every 600 seconds

# DynDNS username and password here
username xxxxxx
password xxxxxx

dyndns_system dyndns@dyndns.org

## Dynamic DNS hosts
alias flabby.is-a-geek.com

background

I tested the update process by running inadyn from the command line -

fileserver:~# inadyn
INADYN: Started 'INADYN version 1.96' - dynamic DNS updater.
I:INADYN: IP address for alias 'flabby.is-a-geek.com' needs update to '65.93.163.244'
I:INADYN: Alias 'flabby.is-a-geek.com' to IP '65.93.163.244' updated successful.

I added the line -

background

to the end of /etc/inadyn.conf which causes the process to run in the background and the output to be sent to syslog.

I then set up the required scripts to run inadyn correctly at boot time.

cp /etc/init.d/skeleton /etc/init.d/inadyn
chmod 755 /etc/init.d/inadyn

I changed only the line -

NAME=inadyn
and then tested with -
fileserver:~# /etc/init.d/inadyn start
fileserver:~# ps -ef | grep /etc/init.d/inadyn
root 3275 1 0 18:29 ? 00:00:00 /usr/sbin/inadyn
fileserver:~# tail -n 3 /var/log/syslog
Oct 20 18:29:21 fileserver INADYN[3275]: INADYN: Started 'INADYN version 1.96' - dynamic DNS updater.
Oct 20 18:29:22 fileserver INADYN[3275]: I:INADYN: IP address for alias 'flabby.is-a-geek.com' needs update to '65.93.163.244'
Oct 20 18:29:22 fileserver INADYN[3275]: I:INADYN: Alias 'flabby.is-a-geek.com' to IP '65.93.163.244' updated successful.
Then to make it permanent I did -
fileserver:# update-rc.d /etc/init.d/inadyn defaults
Adding system startup for /etc/init.d/inadyn...
/etc/rc0.d/K20inadyn -> ../init.d/inadyn
/etc/rc1.d/K20inadyn -> ../init.d/inadyn
/etc/rc6.d/K20inadyn -> ../init.d/inadyn
/etc/rc2.d/S20inadyn -> ../init.d/inadyn
/etc/rc3.d/S20inadyn -> ../init.d/inadyn
/etc/rc4.d/S20inadyn -> ../init.d/inadyn
/etc/rc5.d/S20inadyn -> ../init.d/inadyn

So it should run correctly on reboot now.

Saturday, 27 October 2007

Compiling a simple program for OpenWrt

Using the Openwrt Buildroot environment created below, it's now possible to compile our own programs programs and create my own packages for the ASUS WL-500g wireless client.

Following the procedure described in this how-to.

##############################################
<# OpenWrt Makefile for flabbybox program
#
# Most of the variables used here are defined in
# the include directives below. We just need to
# specify a basic description of the package,
# where to build our program, where to find
# the source files, and where to install the
# compiled program on the router.
#
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and
# there should be no trailing whitespace in
# lines that are not commented.
#
##############################################

include $(TOPDIR)/rules.mk

# Name and release number of this package
PKG_NAME:=flabbybox
PKG_RELEASE:=0.12.1

# This specifies the directory where we're going to build the program.
# The root build directory, $(BUILD_DIR), is by default the build_mipsel
# directory in your OpenWrt SDK directory
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

# Specify package information for this program.
# The variables defined here should be self explanatory.
define Package/flabbybox
SECTION:=utils
CATEGORY:=Utilities
TITLE:=flabbybox -- an embbeded client for mpd
DESCRIPTION:=\
Command mpd via a keypad and LCD
endef

# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default. The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this

# Specify where and how to install the program. We install the executable
# by copying it to the /bin directory on the router and the config file to /etc
# The $(1) variable represents the root directory on the router running
# OpenWrt.
# The $(INSTALL_DIR) variable contains a command to prepare the install
# directory if it does not already exist. The $(INSTALL_BIN) contains the
# command to copy the binary file from its current location (the build
# directory) to the install directory.
define Package/flabbybox/install
$(INSTALL_DIR) $(1)/etc
$(CP) $(PKG_BUILD_DIR)/flabbybox.conf $(1)/etc/flabbybox.conf
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/flabbybox $(1)/bin/
endef

# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,flabbybox))

In order to use the usb library, we need to download and compile the libusb package

svn checkout https://svn.openwrt.org/openwrt/packages/libs/libusb/ package/libusb
make package/libusb-compile

In avoid running through the whole toolchain makefile, use the following commands to work on just a single package -

make package/-clean V=99
make package/-compile V=99
make package/-install V=99

Friday, 7 September 2007

Adding keypad and LCD display to the ASUS WL-500g wireless client

The UI for the wireless player is a Targus usb numeric keypad and a homemade usb 20x4 LCD display based on Phil Endecott's slugterm. Unfortunately, as explained in this OpenWrt forum post, USB HID (Human Interface Devices) support is not enabled by default in the OpenWrt kernels - you have to enable it in the kernel config file. After some googling, I found this howto which describes which kernel options are required - but first I needed to set up the build environment.

Following the OpenWrt wiki again, I download the OpenWrt BuildRoot onto my Linux laptop -

svn co https://svn.openwrt.org/openwrt/trunk

and then ran -

make menuconfig

- selected the 'Broadcom BCM947xx/953xx [2.4]' target system otherwise left everything else as default, then did -

make V=99

to build the toolchain (as well as all the packages and kernel itself which we don't really need to do yet - anyway of stopping this?). After a very long time (left overnight ..) it finished.

Now I was able to enable the required kernel configuration options which allow the usb-hid kernel modules to be built. Following the BuildRoot wiki again, I changed the kernel configuration settings by cd'ing to the linux build directory and running make menuconfig, e.g.:

cd build_dir/mipsel/linux
make ARCH=mips menuconfig

- selected the following kernel options -

Input core support --->
Input core support
[M] Keyboard support
< > Mouse support
< > Joystick support
[M] Event interface support
< > User level driver support

USB support --->
--- USB Human Interface Devices (HID)
USB Human Interface Device (full HID) support
[*] HID input layer support
[*] /dev/hiddev raw HID device support

- then had to edit both -

package/kernel/modules/other.mk
package/kernel/modules/usb.mk

to remove the dependencies on kernel-2.6 for the input-core, input-evdev and usb-hid modules.

I removed the stuff from the previous build to force modules to be rebuilt-

rm .image .modules

- then returned to the top level directory and ran -

make menuconfig

again, selected the newly enabled kernel module selections (input-core, input-evdev and usb-hid)

Input Kernel modules --->
Other modules --->
[M] kmod-input-core
[M] kmod-input-evdev
USB Support --->
[M] kmod-usb-hid

and then -

make V=9

This generated the three required packages in bin/packages -

kmod-input-core_2.4.34-brcm-1_mipsel.ipk
kmod-input-edev_2.4.34-brcm-1_mipsel.ipk
kmod-usb-hid_2.4.34-brcm-1_mipsel.ipk

I copied these to the router and installed them with ipkg -

ipkg install kmod-input-core_2.4.34-brcm-1_mipsel.ipk
ipkg install kmod-input-evdev_2.4.34-brcm-1_mipsel.ipk
ipkg install kmod-usb-hid_2.4.34-brcm-1_mipsel.ipk

Now when the usb keyboard is inserted, dmesg gives -

hub.c: new USB device 00:04.0-1, assigned address 3
hub.c: USB hub found
hub.c: 3 ports detected
hub.c: new USB device 00:04.0-1.3, assigned address 4
input: USB HID v1.10 Keyboard [ORTEK USB Keyboard Hub] on usb1:4.0
input: USB HID v1.10 Device [ORTEK USB Keyboard Hub] on usb1:4.1

and the keyboard is correctly recognised!

Wednesday, 29 August 2007

Installing Music Player and usb sound card on the ASUS WL-500g wireless client

Following the wiki, I installed the appropriate kernel modules for an nfs client -
ipkg install kmod-fs-nfs
and then attempted to mount the filesystem export from the fileserver -
mkdir /tmp/music
mount -t nfs 192.168.1.77:/home/share/music /tmp/music -o nolock
then
ls /tmp/music
indeed shows the music directory from the fileserver -
root@OpenWrt:~# ls /tmp/music
2 Many DJ's
Acid House Kings
Al Green
Babyshambles
Barenaked Ladies
Buena Vista Social Club
Bugz in the Attic
Following the Usb Storage and Usb Audio wiki entries, I installed the appropriate kernel modules to enable my usb soundcard -
ipkg install kmod-usb-ohci kmod-soundcore kmod-usb-audio
Then, on plugging the soundcard in, dmesg gives -
hub.c: new USB device 00:04.0-1, assigned address 2
usbaudio: device 2 audiocontrol interface 0 has 0 input and 1 output AudioStreaming interfaces
usbaudio: device 2 interface 1 altsetting 0 does not have an endpoint
usbaudio: device 2 interface 1 altsetting 1 channels 2 framesize 2 configured
usbaudio: valid output sample rate 44100
usbaudio: valid output sample rate 48000
usbaudio: device 2 interface 1 altsetting 1: format 0x01000010 sratelo 44100 sratehi 48000 attributes 0x01
usbaudio: registered dsp 14,3
usbaudio: constructing mixer for Terminal 3 type 0x0301
usbaudio: registered mixer 14,0
usb_audio_parsecontrol: usb_audio_state at 807f8860
I then installed the Music Player application -
ipkg install mpd
and some other dependences that weren't properly flagged when mpd was installed -
ipkg install alsa-lib libpthread
editted the config file -

# MPD CONFIG FILE
# For a full description of all config parameters,
# Check the mpd man page, "man mpd".

##################### REQUIRED ###########################
music_directory "/tmp/music"
playlist_directory "/tmp/music"
db_file "/tmp/music/mpd.db"
log_file "/tmp/mpd.log"
error_file "/tmp/mpd.error"
pid_file "/tmp/mpd.pid"
##########################################################

##########################################################
# EVERYTHING ELSE IS OPTIONAL
##########################################################

################## AUDIO OUTPUT ##########################
#
# use this if you want to use OSS audio output
audio_output {
type "oss"
name "my OSS sound card"
device "/dev/sound/dsp" # optional
format "44100:16:2" #optional
}
#
# OSS Mixer
mixer_type "oss"
mixer_device "/dev/sound/mixer"
mixer_control "PCM"
#

################# SECURITY SETTINGS ######################
#
# It is encouraged to run MPD as
# non-superuser. If you start mpd as root
# (for example, in an init script), set
# this value, then mpd will drop root priveleges
# and runs as the user specified.
#
user "share"
#

################ MISCELLANEOUS OPTIONS ###################
#
port "6600"

added 'share' user and group (by editting /etc/passwd and /etc/group) so that we can properly read and write to the nfs share on the fileserver which is owned by user 'share'. Since we will be running mpd as user 'share', we need to open the permissions of /dev/sound/dsp and /dev/sound/mixer which were created by root
chmod 777 /dev/sound -R
Then try it ! First start the music player -
mpd
There may be a long wait while it builds the database before daemon starts up. Then can use the command-line controller to add all the files in the database to a playlist, shuffle it, then play -
mpc listall mpc add
mpc shuffle
mpc play
and lovely music!

In order for it all to start up properly on power-up of the router, create /etc/init.d/mpd -
#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org
START=70

start() {
mkdir /tmp/music
mount -t nfs 192.168.1.77:/home/share/music /tmp/music -o nolock
chmod 777 /dev/sound -R
mpd
mpc listall mpc add
mpc shuffle
mpc volume 10
mpc update
}

stop() {
killall mpd
umount /tmp/music
}
and then to set it up to run on router restart -
/etc/init.d/mpd enable