Matterbox

Looks like I was one of the lucky few to get allocated one of this round of Matterboxes.

Mattterbox

Matterbox are an offshoot from the Royal Mail that ships cardboard boxes with samples from different companies to people in the hope that they will try the samples and spread the word (looks like they’ve achieved their goal with me this time). There have been 2 previous boxes, a pilot and the first edition, I got a copy of the first edition last year. I really like the concept of Matterbox, it’s nice to see the Royal Mail branching out and looking for new ways to make use of it’s network in these days of email and declining post.

This time round it was an all Cabury affair, based around their Spots v Stripes campaign. The concept is to encourage a sense of competition in the run up to the 2012 Olympics by creating 2 virtual teams that can compete against each other to score points. The competition can take nearly any form that has 2 opposing teams.

As part of the campaign Cabury ran a competition to create games that could be used, and this release of Matterbox contains the 2 winning entries and a Spots v Stripes chocolate bar.

Egg-a-thon

Egg-a-thon comprises of 4 small platic eggs, a dice and the board (the box), players start with both their eggs in the start zone, then take it in turn to roll the dice. If a player rolls a 6 they get to use the 6 and get another go, if they roll a 1 they loose their turn. The player can move their eggs forward, backward, left or right and move them in such a way as to obstruct their opponent, the score rolled on the dice between eggs. The winner is the first player to get both eggs to the finish line.

Flick Racer

In this box there are 8 numbered counters and a stick of chalk. You use the chalk to draw a racetrack and then between 2 and 8 players take it in turns to flick their cars round the track. If there are only 2 players then each player has 4 cars, 4 players each get 2 cars. If the counters end up out side the lines of the track drawn in chalk then place the counter back on track and turn it over, if you crash in to one of the other players counters, both are turned over. If a players counter is upside down when it gets round to their turn, then all they can do is to turn it the right way up.

The idea is you play the games and then register your scores for one of the two teams, I’ll take them to the office tomorrow and see if anybody wants to play.

First Android App

After mentioning my new toy a couple of posts ago I mentioned I was hoping to do a bit of Android development.

I’ve been doing a bit of Android work as part of my new job (I recently joined a very cool team at work) making some existing Java code run, but this is my first real application.

I had left the TV on and gone to the office one day last week and while it did not permanent damage, there was a slight bit of ghosting from the MythTV menu for a day or 2 afterwards. I already have my TV hooked up a couple of topic on my home MQTT broker, so I though that running up a simple Android Widget to show the state would be a good starting point.

MQTT Topic Tree
MQTT Topic Tree

The TV/Status topic updates every 30 seconds and currently shows either off or a string like on:RGB:6 which is made up of state, input and volume.

The first task is to create a Android Service that will subscribe to this topic and watch for changes. The standard IA92 MQTT drivers can be used with the Android SDK to get access to the broker, so the connect code is very similar to the code used in my Twitter2MQTT bridge except the id for the client is generated from the phones unique id.

private String android_id =Secure.getString(this.getContentResolver(),Secure.ANDROID_ID);

private boolean connect() {
  try {
    client = (MqttClient) MqttClient.createMqttClient("tcp://tiefighter.loc:1883", null);
    client.registerSimpleHandler(new MessageHandler());
    client.connect("droid-"+android_id, true, (short) 240);
    String topics[] = {"TV/Status"};
    int qos[] = {1};
    client.subscribe(topics, qos);
    return true;
  } catch (MqttException e) {
    e.printStackTrace();
    return false;
  }
}

The MessageHandler is an inner class and handles both incoming messages and reconnection using the following 2 methods.

public void publishArrived(String topic, byte[] payload, int qos, boolean retained) throws Exception {
	String message = new String(payload);
	// This is to allow access to the notification service from a none 	
	if (Looper.myLooper() == null) {
		Looper.prepare();
	}
			
	RemoteViews updateViews = new RemoteViews(TVLongService.this.getPackageName(), R.layout.main);
			
	String toastMsg = "";
	String toastHead = "";
	int icon = 0;
	boolean alert = false;

	if (message.equals("off")) {
		if (TVWidget.on) {
			toastMsg = "TV now OFF";
			toastHead = "TV OFF";
			icon = R.drawable.tv_off;
			alert = true;
			TVWidget.on = false;
		}
	} else {
		if (!TVWidget.on) {
			toastMsg = "TV now ON";
			toastHead = "TV ON";
			icon = R.drawable.tv_on;
			alert = true;
			TVWidget.on = true;
		}
	}

	if (alert) {
		Intent intent = new Intent();
		PendingIntent contentIntent = PendingIntent.getActivity(TVLongService.this, 0, intent, 0);
		NotificationManager notificationManager = (NotificationManager) TVLongService.this.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification notification = new Notification(icon, toastHead, System.currentTimeMillis());
		notification.setLatestEventInfo(TVLongService.this, "TV Monitor", toastMsg, contentIntent);
		notificationManager.notify(1, notification);
		updateViews.setImageViewResource(R.id.img, icon);
	}

	ComponentName componentName = new ComponentName(TVLongService.this, TVWidget.class);
	AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(TVLongService.this);
	appWidgetManager.updateAppWidget(componentName, updateViews);
}

TVWidget
The MessageHandler onMessage method fires when a message is posted to the TV/Status topic and then updates the widget Icon from tv_on to tv_off and then triggers a notification pop-up if the state has changed since the previous state.

The connectionLost method fires up a background thread to try and reconnect to the broker every 10 seconds.
TVWidget_on

TVWidget_toast

public void connectionLost() throws Exception {
	client = null;
	Log.v("TVMonitor","connection dropped");
	Thread t = new Thread(new Runnable() {
		
		@Override
		public void run() {
			do {//pause for 5 seconds and try again;
				Log.v("TVMonitor","sleeping for 10 seconds before trying to reconnect");
				try {
					Thread.sleep(10 * 1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} while (!connect());
			System.err.println("reconnected");
		}
	});			
}

Next Steps

  • Survive network changes

    At the moment the code does not handle moving from WIFI to 3G networking all that well, there are collection of BroadCast future PendingIntents that should signal changes in network state.

  • Geo-Fencing

    I don’t really need to know that the TV is on while I’m at home, so I’m planning on adding a filter so notifications are only fired when I’m outside say 200m of home

  • MythTV

    May be add some indication as to what channel is currently being watched and what the upcoming recordings may be

Eightbar

I got added as an author for the Eightbar blog today.

Eightbar is a group of techie/creative people working in and around IBM’s Hursley Park Lab in the UK. We have regular technical community meetings, well more like a cup of tea and a chat really, about all kinds of cool stuff. One of the things we talked about is that although there are lots of cool people and projects going on in Hursley, we never really let anyone know about them. So, we decided to try and record some of the stuff that goes on here in an unofficial blog: eightbar.

The plan is to give a bit of a UK flavour to it all, but talk about the technology coming out of the lab, things people are playing with, but also some of the fun side. Hursley’s a very unusual place (compared to most technology sites), so we want to get that across. Anyway, hopefully lots of different people who work in and around Hursley will contribute.

The name Eightbar comes from the IBM logo which uses letters made up of 8 horizontal bars.

I posted my first article today about Andy Piper’s new AR.Drone that he brought to the office on Tuesday.

Twitter2MQTT bridge

The recent switching off of Basic Auth by Twitter meant I had to rework some of the applications I have running at home. One of these application bridges Twitter to my local MQTT broker so that any DMs and mentions get published to two topics and also a topic that updates my status to what ever is posted.

The original version of the application just made basic http requests and parsed the XML responses, rather than just try and bolt on OAuth support I thought I would be better to start again and use one of the existing libraries that drive the Twitter APIs. There is a list of libraries for different languages http://dev.twitter.com/pages/libraries, I had a bit of a look at a couple of them and settled on Twitter4J.

In order to use OAuth you need to register your application with Twitter, you can do that here http://twitter.com/apps/new. Once registered you will get Consumer Key and a Consumer Secret. Because Twitter are using these keys to help to cut off spammers, keys need to be kept secret in order to prevent spammers knocking legitimate applications off-line, If you want to build the code attached here you will need to apply for your own key.

Before you can use a Twitter application you need to authorise it to act on your behalf, this is a 3 stage process.

  1. The application creates a URL based on it’s Consumer Key and Consumer Secret.
  2. The user follows the URL and signs into Twitter and is then asked if they want to allow the application to access on their behalf. If they allow the application then Twitter supplies a PIN.
  3. The user passes the PIN to the application which uses this to retrieve a Token, This Token is used to authenticate the application when ever it needs to act on the users behalf.
Twitter Application Authentication
Twitter Application Authentication

To do this with Twitter4J you need to do something like this:

    Twitter twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(consumerKey, consumerSecret);
    try {
        RequestToken requestToken = twitter.getOAuthRequestToken();
        AccessToken accessToken = null;
        BufferedReader reader = new BufferedReader(
                                       new InputStreamReader(System.in));
        while (accessToken == null) {
            System.out.println(requestToken.getAuthorizationURL());
            System.out.println("Please follow the URL above," + 
                      " enter the PIN provided and then press Enter");
            String pin = "";
            try {
                pin = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            accessToken = twitter.getOAuthAccessToken(requestToken, pin);
        }
        String token = accesToken.getToken();
        String secret = accesToken.getTokenSecret();
    } catch (TwitterException e) {
        e.printStackTrace();
    }

The token and the secret should be stored so the user doesn’t need to authorise the application each time it starts. Now the application is authorised you can post status updates and access the DM and Mention streams like this:

    List<DirectMessage> dms = twitter.getDirectMessages();
    List<Status> mentionsList = twitter.getMentions();
    twitter.updateStatus(newStatus);

Now that I can access the updates I need to publish them to topics and listen for when a new status is published. There is a Java library for accessing an MQTT broker provided by IBM known as the IA92 package. This package provides both J2SE and J2ME versions of the libraries. To create a connection to the broker

    IMqttClient client = null;
    try {
        client = MqttClient.createMqttClient("tcp://brocker.loc:1883"
                                                            , null);
        client.connect(clientID, true, (short) 100);
        client.subscribe({"Twitter/send"}, {1});
        client.registerSimpleHandler(new MqttSimpleCallback() {
            public void connectionLost() throws Exception {
            }

            public void publishArrived(String topic, byte[] payload, int qos,
                            boolean retained) throws Exception {
                twitter.updateStatus(new String(payload));
            }
        });

    } catch (MqttException e) {
        e.printStackTrace();
    }

Each client needs a unique id, or the older client will be kicked off when the new one collects, if you want to run multiple versions of the bridge then it may be a good idea to append the OAuth access token or the twtter screen name to the clientID.

Taking all that and knocking some of the rough edges off I have an app that will publish DMs on Twitter/<screenName>/dm & mentions on Twitter/<screenName>/mention and listens on Twitter/<screenName>/send for status updates to publish. There is a second app which subscribes to the mention and DM topics and forwards these messages on to the topic that sends SMS messages to my phone.

Next on the list of additions is a filter that will forward photos attached to tweets as MMS messages and probably some support for bridging search terms as well.

You can download my code from here, remember you will need your own Consumer Key and Consumer Secret to build it yourself, but there is a pre-built version with a valid key included.

Twitter2MQTT.tar.gz

Resources

New Toy

I’ve finally got round to getting a smart phone. I have never been sold on the whole iPhone clut craze and I’ve already got a work blackberry that I despise so the choices where really between an Android or Windows Mobile device.

Given the hackability of Android pretty much sealed the deal, but I was torn between a Sony Ericsson Xperia X10 and a HTC Desire.

Sony Erricson – Xperia X10

Sony Xperia X10 front
Image CC licensed by louisvolant on Flickr

My last few phones have all been from Sony Ericsson, I’ve had the following:

  • T68i
  • K700
  • K750
  • w850
  • W880i
  • C905

I’ve been very happy with these phones over the years (with the exception of the C905’s lack of functional Google Maps, but that was down to O2’s “custom” firmware) so getting another SE was definitely a possibility but after getting hold one and having a bit of a play with the Timescape layer that SE have added on top of Android I decided it wasn’t for me.

HTC – Desire

HTC Desire 4
Image CC licensed by louisvolant on Flickr

HTC built the first Android phone the G1 and also the recent Nexus One for Google so they have a decent amount of experience with Android. The Desire shares most of the components of the Nexus One with major differences being cosmetic, the 4 buttons on the front are physical rather than an extension of the touch screen and the track ball in an optical sensor on the Desire.

I am quite taken with the Sense interface that HTC have layered on top of 2.1 Android “Eclaire”, but I’m hoping to have a play with a colleges Desire which is running a plain build of Android 2.2 “Froyo” shortly to see if it’s worth waiting for the Sense skinned version of Android 2.2 which is rumoured to arriving in 3Q, or to root the phone and install a custom image.

Apps

I’ve been taking it easy with apps so far and I’ve not found one I want to pay for just yet but the following free ones have been getting a reasonable amount of use.

  • Simple Last.fm Scrobbler – A scrobbler for the Android built in music player
  • UK Traffic Checker – A very cool app written by Dale Lane that check the route between 2 places for traffic problems
  • Bump – A neat way to send photos and vcards between 2 phones
  • Layar Reality Browser- A AR viewer

Development

So now I have my cool new phone I suppose it would be rude to not make use of it’s open development platform. I’ve downloaded the latest version of the SDK and the Eclipse plugin. I’m working my way through a couple of the tutorials before coming up with a project.

TV Scrobbling

Having seen Dale Lane’s work with VDR to build something similar to Last.FM for the TV he’s been watching, I’ve been looking to see if I could do the same with MythTV.

MythTV 0.23 has shipped recently and with it came a new event system. Having had a quick look at the feature for this it looked like it would be a good starting point for this. The following events looked like they may be able to provide what I needed.

  • Playback started
  • Playback stopped
  • Playback changed

To use events you specify a command to run when each fires. You can set these up with the mythtvsetup command. As well as specifying a command you can also pass arguments, these arguments are passed using the same tokens used for the MythTV job system. The following is not the full list, but should be enough to do what I’m looking for.

  • %TITLE% – Title
  • %SUBTITLE% – Episode subtitle
  • %CHANID% – MythTV channel id
  • %DESCRIPTION% – The blurb from EPG
  • %PROGSTART% – The listed started time for the programme
  • %PROGEND% – The listed end time for the programme

There is also an option to add a command that fires on every event which you can also pass a %EVENTNAME% argument, this is very useful for debugging event ordering. Not all of the events support all of the arguments as the data is not relevant.

After a bit of playing I managed to get most of what I needed, but there where a few problems

  1. No way to tell the difference between watching recorded and live TV
  2. No way to tell when you change channel when watching live TV
  3. No way to tell when one live programme ends and a new one starts with live TV

I raised a bug in the MythTV tracker (#8388) to cover the first 2 (since the 3rd one didn’t occur to me until I got a bit further). Which the guys very quickly added. So there is now a LiveTV Started event fired when a frontend starts watching live tv followed by a Playback Started event with the details of the programme. I’ll raise a ticket for the last one and assuming I can get sign off from the boss I’ll see about submitting a patch to add it in. In the mean time with a little extra work I can infer the programme change from the Record Started and Record Finished events.

Acting on the events

So with all these events which may be reported on either the backend or frontend it’s looking good for another messaging solution. Luckily I already broker up and running for my home power monitoring and security setup. So now I just needed to run up a script or two to publish the events and a consumer with a state machine to act on them.


#!/bin/sh
#
# playStarted.sh %TITLE% %SUBTITLE% %DESCRIPTION% %CHANID%

/home/mythtv/bin/sendMessage TV/watching/start “$1/$2 ($3) on $4″

mythtvsetup events screen

Where sendMessage is a small script that publishes the second argument to the topic in the first. The other end is Java JMS application that keeps the state machine up to date and update the database when a show ends. Dale was kind enough to send me his database schema, so the data should look the same.

What next

Now I’ve got my data logging to a local database I need to come up with a front end to present it all. Next time I get 5mins to chat to Dale when we are both in the office I will see if I can borrow some of his code and if he wants to look at if we can build a site where we can all share what we’ve been watching?

Along with the events for the internal workings of the front and backends there are 10 user configurable events that can be bound to key presses, assuming I can find a spare button on the remote it should be possible to bind one of these to something like Favourite.


Resources

IPv6

It’s been coming for a while, but we really are getting close to running out of IPv4 addresses. The rate of growth of the internet continues to accelerate with not just more and more people getting online but items such as appliances and sensors. This internet of things has been talked about before (small corporate plug) here, all these things need an IP address in order to interact with the rest of the world.

There are a number of technologies that have been deployed try and help eek out the finite pool of IPv4 addresses such as CIDR and NAT. NAT works well when connections are initiated from behind the NAT gateway, but don’t work when the remote end needs to open the connection, e.g. FTP data connections.

The long term solution is to move to IPv6, this new iteration of the protocol has a much larger pool of addresses (capable of supplying 6.67 * 10^27 addresses per square meter of the planet) which should last a while longer.

Playing

Since we are all going to have to move to IPv6 at some point I thought I’d have a play. My ISP at home does not offer IPv6 support yet but there are companies that offer IPv6 over IPv4 tunnels. Wikipedia has a list here, I picked Hurricane Electric who offer free 6in4 tunnels and have multiple end points in Asia, Europe and the US.

Once you have signed up there is a “Create Regular Tunnel” link in the left hand side bar. To use a tunnel from Hurricane Electric you need a static IPv4 address that can be pinged from the internet. When you have entered your IPv4, the site will suggest the closest end point.

By default Hurricane hand out a IPv6 subnet with a /64 prefix, this means that the top 64bits of the address are considered the network mask and the rest of the address can be used for up to 18,446,744,073709,551,616 hosts. With that many addresses to go at I don’t think I’m likely to run out any time soon. It is possible to get /48 subnets assigned as well if for any reason you think that a /64 will not be enough (actually there are good reasons why you might want this which I’ll mention later).

Once you have completed the tunnel request form you should end up with a page which has information similar to this.

Account: hardillb
	Global Tunnel ID: 53560 	Local Tunnel ID: 1701
	Description:
	Registration Date: 	Tue, Apr 13, 2010
Tunnel Endpoints
	Server IPv4 address: 	216.66.80.26
	Server IPv6 address: 	2001:470:xxxx:xxx::1/64
	Client IPv4 address: 	93.97.xxx.xxx
	Client IPv6 address: 	2001:470:xxxx:xxx::2/64
Available DNS Resolvers
	Anycasted IPv6 Caching Nameserver:	2001:470:20::2
	Anycasted IPv4 Caching Nameserver:	74.82.42.42
Routed IPv6 Prefixes and rDNS Delegations
	Routed /48: 	Allocate /48
	Routed /64: 	2001:470:xxxx:xxx::/64
	RDNS Delegation NS1: 	none
	RDNS Delegation NS2: 	none
	RDNS Delegation NS3: 	none

Hurricane also provide helpful little feature at the bottom of the page that details the configuration details for a bunch of different operating systems. There are 2 different sets for Linux depending which tool chain you are using.


modprobe ipv6
ifconfig sit0 up
ifconfig sit0 inet6 tunnel ::216.66.80.26 # Server IPv4 address from above
ifconfig sit1 up
ifconfig sit1 inet6 add 2001:470:xxxx:xxx::2/64  # Client IPv6 address from above
route -A inet6 add ::/0 dev sit1

Configuration

The configuration hints on the Hurricane page are useful for testing but don’t match up with the various distros methods for establishing the tunnel at startup. The following instructions apply to Fedora 12

The first step is to enable IPv6, this is easily done by adding the last line to /etc/sysconfig/network file:


NETWORKING=yes
HOSTNAME=tiefighter
NETWORKING_IPV6=yes

Next the tunnel interface needs setting up. To do this create the following file as /etc/sysconfig/network-scripts/ifcfg-sit1.


DEVICE=sit1
BOOTPROTO=none
ONBOOT=yes
IPV6INIT=yes
IPV6TUNNELIPV4=216.66.80.26       # the IPv4 addres of your ISP's tunnel server
IPV6TUNNELIPV4LOCAL=192.168.1.5     # your host's local IPv4 address
IPV6ADDR=2001:470:xxxx:xxx::2/64         # your host's public IPv6 address

Once these where set restarting the networking component brought up the tunnel. This now means that this machine can send and receive traffic via IPv6, but that doesn’t get me any further than I had with the static IPv4 address I already had. The next step is to enable the other machines on my network so they can route via IPv6 as well. IPv6 has support for automatic address configuration built in called Stateless address autoconfiguration, the specification allows hosts to generate their own addresses based on the MAC address of the network card that it will use to send the packets over. This generates a 64bit number which acts as the host part of the address, the network part is supplied by the local router using the router announce protocol, as long as network part of the address is larger than /64 then it all works fine. . This all works because of IPv6’s hierarchical routing means that all packets with my prefix will be will be directed to tunnel and from then on it becomes my networks job to route them to the end hosts.

Back to the comment earlier about a /64 network not being enough for some people, if you have multiple network segments behind your tunnel then having a /48 network then you can assign different /64 networks to each segment to allow you to use Stateless address autoconfiguration on each.

To make the tunnel machine act as a router for all the other machines on the network it needs to be configured to forward packets and to make router announcements so the other machine can form correct addresses. Setting up the packet forwarding is easy enough, it’s just a case of adding another line to /etc/sysconfig/network file.


NETWORKING=yes
HOSTNAME=tiefighter
NETWORKING_IPV6=yes
IPV6_ROUTER=yes

To enable Router Announce we need the radvd app, once installed edit the /etc/radvd.conf file


interface eth0 {
	AdvSendAdvert on;
	MinRtrAdvInterval 30;
	MaxRtrAdvInterval 100;
	prefix 2001:470:xxxx:xxx::/64
	{
		AdvOnLink on;
		AdvAutonomous on;
	};
};

The last thing that needs doing is assigning a IPv6 address to the eth0 interface by adding it to /etc/sysconfig/network-scripts/ifcfg-eth0.


DEVICE=eth0
TYPE=Ethernet
BOOTPROTO=none
HWADDR=00:1B:FC:10:0E:E5
ONBOOT=yes
DHCP_HOSTNAME=tiefighter
USERCTL=no
IPV6INIT=yes
PEERDNS=no
IPADDR=192.168.1.5
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
DNS2=213.162.97.66
SEARCH=loc
DNS1=127.0.0.1
IPV6ADDR=2001:470:xxxx:xxx::3
NM_CONTROLLED=no

That should be it, I now have a fully functional IPv6 subnet at home. For Linux machines running NetworkManager it should just be a case of enabling IPv6 for the connection.

The only bit that is missing is DNS because remebering IPv6 addresses is even harder than IPv4 addresses, I’ll save that for the next post.


Resources

Off site backups

This long weekends task has been to set up some form of off site backup for my dads business. He has a relatively small set of data (total less than 2gb) that is not going to change a huge amount but it is going to continue to grow over time. Previously dad had been cutting backups to DVDs every night, but as well as being wasteful by generating large numbers of half full DVDs it was slow and required somebody to remember to put a fresh disk in the drive at the end of every day.

Dad has a couple of different machines that need backing up,

  • A ancient Novell 4.x machine running some legacy software
  • A new Windows 2008 Server running a database
  • A small Ubuntu Linux box acting as NAT gateway and mail server

So the plan was to come up with something that would meet the following criteria

  • Automatic
  • Simple
  • Support very varied sources

I looked at a couple of the companies offering hosted backup online but decided to roll my own due to not wanting to have to worry about a monthly bill and knowing that if something went wrong and the backup was actually needed then it would be quicker to be able to carry whatever held the back up to the office and restore from that rather than to wait for it all to download again.

Since there was such a big difference in the type of machine that needed backing up and that the Novell stuff is so out of date that nobody was likely to support it any more I decided the best bet was to mount the bits that needed backing up from the Windows and Novell machines on the Linux box and then back it up from there. Accessing the Windows share from was easy enough using samba and the CIFS filesystem mount options. Getting at the Novell mount was a little harder.

The old NetWare Novell server doesn’t talk IP like everything else on the network, it uses IPX instead. So the first task was to configure the Linux machine to join the IPX network. Detailed instructions for setting up IPX can be found here, but the basics are assuming your Linux distribution has IPX compiled in you should be able to just run the following command as root.

ipx_configure --auto_interface=on --auto_primary=on

Once the network is up and running the next job was to mount the share, for this I needed the NCPFS package. This package is very similar to Samba and allows you to search for and mount Novell NetWare shares. There are 2 useful commands, the first is slist which will list all the Novell servers that can be seen on the network. The second is ncpmount which will mount the share.

ncpmount -S <server> <mount point> -U <Novell user>

Now I had access to all the data I needed somewhere to send it. While dad has a desktop and a laptop at home neither is on all the time or have large amounts of spare disk space, so I needed to find something to store the backups on. I was looking for a low power NAS with rsync support. I had a hunt round and found several, but most of them where big multi disk systems intended for mid sized office use and cost several hundred pounds. A bit more searching turned up the Buffalo LinkStation Live 500GB, which is basically a 500gb disk with a mini ARM based Linux machine strapped to the side. There is a reasonable sized community online hacking these little boxes to do all sorts and there are detailed instructions on how to enable telnet and SSH access which in turn can allow rsync to be used. Peek power draw is about 20W and significantly less when idle so it’s not going to cost much to run.

So I had send dad off to order one of these LinikStations and it was waiting for me when I got home. I initially started off following this set of instructions but had no joy. It turns out with the latest version of the firmware (1.24 at time of writing) the APC commander application no longer works. I started to search round some of the forums and came up with this new set of instructions on how to patch the firmware to add SSH and allow console access. The instructions are good, but it still took 2 attempts to get the firmware to upload, but once it did it all worked like a dream.

At this point I had access to all the data that needed backing up on the Linux box at the office and the LinkStation was ready to go at home, it was time to set up a way to get the data from one to the other. Rsync is perfect for this as it allows you to only copy the differences between 2 directories, these directories don’t even have to be on the same machine and all the communication can be tunnelled over SSH. The basic starting point for rsync over SSH is:

rsync -az -e ssh /path/to/src user@machine:/path/to/destination

Lets just step through the options being used here.

  • -a – This tells rsync to “archive” the src directory, this basically means conserve all the file access permissions, timestamps, symlinks and recurse into directories
  • -z – This tells rsync to compress all the data passed back and forth to save bandwidth
  • -e ssh – This tells rysnc to use ssh to connect to the target machine

That’s ok to start with as it will copy anything new in the source directory to the destination directory but it will not delete things from the destination if they disappear from the source directory, this is fine for this situation since dad is not likely to be deleting anything on the src side. So I wrapped it up in a script to run as a cron job after everybody should have gone home for the night

#!/bin/sh
USER=foo
SERVER=dads-broadband.isp.net
SRC=/mnt/backup
DST=/mnt/disk1/share/backup

rsync -az -e ssh $SRC $USER@$SERVER:$DST

The following line in the crontab runs the backup at 5 past midnight on Tuesday through Saturday so to pick up the changes for the working days.

5 0 * * 2-6 /usr/local/backup


At the moment every time the script runs it will ask for the password for the SSH connection to the Linkstation at home. To get round this I set up an SSH key. There are lots of examples for creating SSH keys and using online so I’ll skip past that now.

So that is nearly that, except having set this all up I started to think about how to recover should a problem happen. What happens if a important file gets trashed at some point and nobody notices for a day or two. If the current script is running every day at midnight then the safe copy of the trashed file will get overwritten as soon as the script runs on the day it was damaged. To get round this I needed some sort of rolling incremental backup. Luckily rsync has this support as well and there is an example on the rsync page of how to set it up. I’ve modified it a little bit to give me this:

#!/bin/sh
USER=hardillb
SERVER=dads-broadband.isp.net
SRCDIR=/mnt/backup
DSTDIR=/mnt/disk1/share/backup
INCDIR=`date --date=yesterday +%A`
OPTS="--backup --backup-dir=$DSTDIR/$INCDIR -az -e ssh"

# the following line clears the last weeks incremental directory
[ -d $HOME/emptydir ] || mkdir $HOME/emptydir
rsync --delete -a $HOME/emptydir/ $USER@$SERVER:/$DSTDIR/$INCDIR/
rmdir $HOME/emptydir

rsync $OPTS $SRCDIR $USER@$SERVER:$DSTDIR/current


This will create a directory called “current” which will hold the most up to date version backed up, it will also create 7 other directories named after the day of the week holding the previous version of any files that changed that day. This should allow any changes in the last week to be reverted.

In order to prevent having to copy all the initial 2gb over the dads broadband I took the LinkStation to the office and set it up on the local network then ran the backup script just with the local IP address rather than the SERVER entry.

For the normal operations I also had to set up dads router at home to assign the LinkStation a static IP address and forward port 22 to it so it was visible to the outside world.

Using Emprex 3009URF III Vista MCE Remote with MythTV

I recently got my hands on a new Acer Aspire Revo R3610, the plan is to use this as a second MythTV frontend in the bedrooom (I’ve still got to find a suitable TV to hang it on the back of). To go with this I needed a new remote control so I don’t need to have a keyboard and mouse plugged in, I had a bit of a search round online and found the Emprex 3009URF on Amazon, it looked like it would be perfect for what I needed. As well as having all the buttons I wanted it also uses RF rather than IR so no need to have the USB dongle in line of sight.

When it arrived I plugged it in and it showed up as 2 separate keyboards, each with about half of the buttons. This wasn’t a major problem as both where seamlessly merged by the Linux HAL keyboard layer and I was planning on wrapping the input with LIRC anyway. What was a problem was that for a few of the buttons I was not getting any key events. The missing buttons where:

  • The Big Green Start Button
  • Most of the menu buttons (TV, DVD, Music, Photos …)
  • Teletex
  • Red, Green, Yellow & Blue

Kernel work

I could have lived with out most of these apart from the Teletext and the colour buttons as these are use by the DVB-T service here in the UK to access the interactive content.I started to have a bit of hunt round online and found that there was already code in the Linux Kernel to support similar remotes. I was just about to start writing my own extention to support this one when I came across a patch that had been submitted about 2 week earlier. Details of the patch can be found here. There is some discusion between the submitter (Wayne Thomas) and the maintainer of the HID code (Dmitry Torokhov) saying that Dmitry would like to remove all the code that provides support for these types of remote now it was possible to achive the same thing with configuration files and udev. I followed the link about how to set up udev, but was unable to get even the “unkown” responses when running the monitoring program.

Given that I could not get the alternative to work it looked like the quickest way to get full support for the remote was going to mean applying the patch. Since the HID code is built into the Kernel I couldn’t just build it as a module to load into an existing Fedora Kernel, I was going to have to rebuild the whole thing. Rather than mess about pulling a raw source tree I decided to let rpmbuild do the heavy lifting since this would mean I ended up with a kernel that was a close as possible to what I already had. I downloaded the src rpm with yumdownloader. Yumdownloader doesn’t actually install the src rpm package so you need to then actually install the package


# yumdownloader kernel
# rpm -ivh kernel-2.6.31.12-174.2.22.fc12.src.rpm

The install will create a rpmbuild directory tree. This is used to do the compiling and packaging when the rpm is built using the rpmbuild command. The tree looks like this:


	rpmbuild
	   |-BUILD
	   |-BUILDROOT
	   |-RPMS
	   |-SOURCES
	   |-SPECS
	   |-SRPMS

The source tar file and all the patch files end up in the SOURCE dir and the rpm spec file goes in the SPECS dir. Applying the patch is a 2 step process. Firstly we need to down load the patch file from patchwork site listed above,I saved that in to the SOURCE dir in a file called btc-remote.patch. Secondly we need to update the spec file to ensure
that the patch is applied. This requires adding 2 lines, one to identify the file with the patch and one to actually apply it.


...
Patch16570: futex-handle-user-space-corruption-gracefully.patch

Patch16580: partitions-use-sector-size-for-efi-gpt.patch

<span style="color: blue">Patch16590: btc-remote.patch</span>

%endif

BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
...
# enable IR receiver on Hauppauge HD PVR (v4l-dvb merge pending)
ApplyPatch hdpvr-ir-enable.patch
# tell usbhid to ignore all imon devices (sent upstream 2009.07.31)
ApplyPatch hid-ignore-all-recent-imon-devices.patch
<span style="color: blue">ApplyPatch btc-remote.patch</span>

# Add kernel KSM support
ApplyPatch linux-2.6-ksm.patch
ApplyPatch linux-2.6-ksm-updates.patch
...

I have created another patch to add these lines as I expect to have to apply this next time Fedora ships a new Kernel. I have submitted a Bugzilla to ask for this patch to be included in future releases. So with patch in the right place and the right bits in the spec file the rpms are built by executing the follow command from the rpmbuild dir


# rpmbuild -bb SPECS/kernel.spec

And remove the Fedora build package then install the new one with:


# yum erase kernel-2.6.31.12-174.2.22.fc12
# yum --nogpgcheck localinstall RPMS/kernel-2.6.31.12-174.2.22.fc12.i686.rpm

LIRC

After rebooting the system to the new Kernel all the buttons now work fine. Now rather than go throw all the applications mapping the keys to the required functions I chose to use LIRC to map the key presses to the functions. LIRC has a dev/input module that will take standard /dev/input/event devices as input. First we need to
stop the HAL layer from grabbing the devices and adding them to the normal keyboard inputs. Put the following in a file called 10-ignore-emprex in /etc/hal/fdi/preprobe


<?xml version="1.0" encoding="UTF-8"?>
<deviceinfo version="0.2">
<device>
 <match key="info.product" contains_ncase="'BTC USB MCE Cordless Remote">
    <merge key="info.ignore" type="bool">true</merge>
 </match>
</device>
</deviceinfo>

Now we need to make sure we can indentify the /dev/input/event entries that map to the remote even if the order changes on boot. To do this we can use the udev rules. Looking in /proc/bus/input/device for the “BTC USB MCE Cordless Remote”, there will 2 entries looking a bit like this:


I: Bus=0003 Vendor=046e Product=5578 Version=0111
N: Name="BTC USB MCE Cordless Remote Control."
P: Phys=usb-0000:00:04.0-6/input1
S: Sysfs=/devices/pci0000:00/0000:00:04.0/usb2/2-6/2-6:1.1/input/input7
U: Uniq=
H: Handlers=kbd event7
B: EV=1f
B: KEY=837fff 2ff2b7 bf004444 0 0 1 f84 8a37c000 667bfa d941dfed 9e0000 0 0 0
B: REL=40
B: ABS=1 0
B: MSC=10

From this we can see that currently one of the 2 event sources is bound to event7, using this information udevadm tool a signature for the device that can be used to map the event devices to unique names.


# udevadm info -a -p $(udevadm info -q path -n /dev/input/event7)
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:04.0/usb2/2-6/2-6:1.1/input/input7/event7':
    KERNEL=="event7"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:04.0/usb2/2-6/2-6:1.1/input/input7':
    KERNELS=="input7"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{name}=="BTC USB MCE Cordless Remote Control."
    ATTRS{phys}=="usb-0000:00:04.0-6/input1"
    ATTRS{uniq}==""
    ATTRS{modalias}=="input:b0003v046Ep5578e0111-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,
8A,8B,8C,8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B1,B2,B5,B6,CE,CF,D0,D1,D2,D5,
D9,DB,DF,E2,E7,E8,E9,EA,EB,100,162,166,16A,16E,178,179,17A,17B,17C,17D,17F,180,181,182,185,18C,18D,192,
193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1,1B7,r6,a20,m4,lsfw"
...

Using this and the instructions from the How to write udev rules I built the following file /etc/udev/rules.d/99-emprex.rules


KERNEL=="event[0-9]*", ATTRS{name}=="BTC USB MCE C*", ATTRS{phys}=="usb-0000:00:04.0-6/input0", SYMLINK+="input/rfremote0"
KERNEL=="event[0-9]*", ATTRS{name}=="BTC USB MCE C*", ATTRS{phys}=="usb-0000:00:04.0-6/input1", SYMLINK+="input/rfremote1"

This adds 2 symlinks to the /dev/input directory called rfremote0 and rfremote1. Using these 2 instances of lircd can be started to read both sets of inputs and pass them to the applications. To bind the lircd instance you need to start one with –listen and one with –connect as follows:


# lircd --driver=dev/input --device=/dev/input/rfremote0  --pidfile=/var/run/lirc/lircd0.pid --listen
# lircd --driver=dev/input --device=/dev/input/rfremote1  --pidfile=/var/run/lirc/lircd1.pid  --connect=localhost:8765

Once these 2 instances are up and running irw can be used to test the input and also to build the .lircrc file


# Play
begin
prog = mythtv
button = KEY_PLAY
config = Return
end

# Stop
begin
prog = mythtv
button = KEY_STOPCD
config = I
end

# Escape/Exit/Back
begin
prog = mythtv
button = KEY_BACK
config = Esc
end
...
begin
prog = xine
button = KEY_PLAY
repeat = 3
config = Play
end

begin
prog = xine
button = KEY_STOPCD
repeat = 3
config = Stop
end

begin
prog = xine
button = KEY_BACK
repeat = 3
config = Quit
end

Now we are all good to go.

Resources