Running dweb on OpenWrt

To take OpenWrt for a test drive, I have been messing about with one of these TP-Link WR740N routers. It gives me a small low-power Linux box, which I’m sure I will find many uses for. When you consider that this £30 router comes in a consumer style plastic case with a power supply and even an ethernet cable, you realise that it’s a pretty good deal. It can’t do all the things that a Raspberry Pi can do, but it still has potential. And I also found this link which shows I’m not the only one.

So after getting the cross compiler set up (which I did using a Debian machine running inside VirtualBox) and getting some simple C programs running (flashing the LEDs), I decided to try something a little more interesting.

Despite the fact that OpenWrt seems well catered for in the web server department (it can run uHTTPd which supports SSL and even embedded Lua scripts), I still wanted to try my own web server code, out of curiosity, and just because I can.

So I decided to cross compile my own web server, called dweb for OpenWrt and try it out. I’m pleased to say that it worked without any modification. The only thing that I needed to do was install the POSIX thread library onto the router, using this command:

opkg install libpthread

…and after doing that I could run dweb. My simple web based API example which uses jQuery ajax to post values worked perfectly.

So now I can write code in C and expose it as a web-based API from my router. The problem is, I don’t really know why I’d want to do that. But in any case I can. At the moment it’s a solution looking for a problem. But it’s been fun.

What I wanted to achieve with dweb was to write a small webserver in portable C code and without needing external dependencies. I suppose that using the POSIX thread library would be considered a dependency, but the dweb source code allows you to turn that off.

So hopefully, this means that dweb will run on one of these VoCore one inch Linux machines which would be pretty cool. I am thinking of what I could do with a tiny webserver running an API which exposes the GPIO pins over http. Perhaps I’ll build that home sensor network I’ve been wanting ;-)

OpenWrt Linux on a TP-Link WR740N router

Recently, I have been watching this crowdfunded coin-sized Linux machine with some interest. I also noticed that it runs OpenWrt... which is a version of Linux that's designed to run on routers. So I thought that it would be worth some further investigation. I tried to find the easiest way of running OpenWrt at home, and ended up paying £30 for one of these TP-Link TL-WR740N machines (I bought mine at my local branch of Maplin).

It’s not bad actually, for the money you get the power adaptor and even an ethernet cable included – so you're ready to go. This router will accept the OpenWrt firmware straight from its web interface, so you just fetch the correct bin file from here and upload it to the router in the normal way. Personally I’m using this firmware and my device is a v4.27.

After the firmware has flashed and the router has rebooted you can telnet in and access OpenWrt for the first time. It was very simple indeed. For detailed information look here. Basically I’ve followed the "OEM easy installation". It doesn’t get much easier.

Of course, I want to write C programs for it now, so I’ll be setting up a cross-compiler. I think I’m going to use this page as a guide because it looks like one of the best sets of instructions out there.

So maybe I’ll end up fiddling with one of those VoCore coin sized computers eventually... It looks very tempting.

dweb: a lightweight portable webserver in C

I've been continuing to experiment with the source code to 'nweb' (a minimal web server written in C). In fact, I've probably experimented so much that I've changed most of the code beyond recognition by now. But I'm still calling my version 'dweb' in honour of the original.

Since the C# webserver I wrote ages ago has proved quite popular, I thought that I'd try something similar in C. I realised that I should be able to produce a lightweight little web server, which could also be a starting point for some other things I have in mind. Since I'm not using any external libraries, there are no dependencies to worry about. Well, OK I have used the POSIX thread library, but it can be taken out by changing a #define.

I'm attempting to make something which can easily be adapted, where you simply need to write a function which assembles your html response and everything else is done for you. So I'm making use of C function pointers for that. All you need to do is write your custom "responder" function (using the correct signature) and then call my webserver function, passing in a pointer to your own responder function.

That way, by adding a single C file to a project and writing a few lines of code you can have an embedded web server - albeit a very simple one of course.

Obviously I'm not attempting to write a fully featured web server platform, but this is the type of hobbyist project you could run on a Raspberry Pi to create a very simple web interface for something, whilst keeping it very lightweight and low on dependencies. It might work on different types of embedded Linux too (I'd be quite interested to know if it does).

But for my purposes, it will be an easy way to provide a simple web based API, where I can send commands with an http POST or just retrieve data by sending a GET.

But my main aim was to make a custom webserver possible in C with just a few lines of additional code. Being portable, it should run on Mac OS X, Linux (including Android) and even Windows if Cygwin is installed. It certainly worked OK on the Raspberry Pi and I've also used it on my Android tablet.

Since I've included support for HTTP POST (which nweb didn't have) it means that simple form posting scenarios will work, and Ajaxy type stuff should even work. The example code I've written allows HTML form values to be submitted. It also includes a simple Ajax call where a parameter is sent to the server and a return value comes back in the response.

So how does the code look? Well, here is the simplest (trivial) implementation:

void test_response(struct hitArgs *args,
   char *path, char *request_body, http_verb type)
{
    ok_200(args,
        "<html><head><title>Test Page</title></head>"
        "<body><h1>Testing...</h1>This is a test response.</body>"
        "</html>", path);
}

int main(int argc, char **argv)
{
    if (argc != 2 || !strcmp(argv[1], "-?"))
    {
        printf("hint: dweb [port number]\n");
        exit(0);
    }
    dwebserver(atoi(argv[1]), &test_response, NULL);
}

Not too bad - but it just gives the same response to every incoming request. The full source code includes more advanced examples showing an HTML form posting back some values. It also shows an Ajax call using jQuery.

Like 'nweb', it started out as a multi-process server, where each request spawned a new process using fork(). But I am now including support for single-threaded and multi-threaded modes as well, the default being multi-threaded.

Anyway, the source code is on GitHub, if you're interested (released under the MIT license). Meanwhile, I'll keep tinkering with it...

Islay Woolen Mill

During our recent holiday to Islay we visited the Islay Woolen Mill. In fact we visited it twice, so it must have been good. Not only is it cool to see the old machines working away, but Mr Covell will probably tell you a few stories if you start chatting to him.

You may also end up spending some money though. Vicky and I came out looking like this:

As you can see, I bought a hat, scarf and waistcoat. I also picked out some fabric and am having a second waistcoat made just for me. This is what happens when you get over enthusiastic about things being made the old fashioned way I suppose...

I was quite amazed that they managed to keep the oily bits of the old machines away from the bits where the fabric was being made - you really don't want oil stains on your tartan.

Anyway, it was one of those things that I enjoyed much more than I expected. So if you go to Islay, check it out.

I also enjoyed listening to Mr Covell's interest in newer technology, he was telling me that as a textile manufacturer the humble spreadsheet was one of the most wonderful inventions ever.

Island of drams

We've been back to Islay again (an island in the Hebrides) and had a fantastic time. The weather was just perfect, which even took the locals by surprise. Quite a few of them were quite literally red faced ... with sunburn. So we came back from Scotland with a suntan, which was quite unexpected.

Islay has some amazing beaches, which were very quiet, especially considering it was a bank holiday weekend. We went to a 2km stretch of sandy beach on a lovely sunny day and only had to share it with a handful of other people. It looked empty:

Of course we also visited a few of the distilleries - we were even treated to a private mini-tour of Laphroaig when we missed the official tour. It's really amazing that a company which makes that much whisky can still feel like a family business. They are extremely hospitable at Laphroaig if you visit them. When we walked back to our accommodation later that day, one of the distillery workers recognised us and stopped to offer us a lift in his car!

We stayed at the excellent Old Excise House, just outside Port Ellen (and within easy walking distance from Laphroaig). It's the same place we stayed last year. The accommodation is really excellent:

...and the breakfasts are truly amazing. So I'm sure we'll go back again.

At some point I need to mention the Islay Woollen Mill, but that's a whole separate blog entry.

Lubuntu 13.10 on Toshiba

My old Toshiba Satellite T130 laptop has been pretty much abandoned since I've switched to a MacBook Pro. But it's a shame to have an unused piece of kit. So I decided to use the Toshiba T130 for messing about with different Linux distros. As a test I tried to install Debian 7, but it looked like it was going to be a real pain to get the built in wifi adapter to work, so I gave up.

Then I tried Lubuntu 13.10, which worked a treat. All the hardware seems to have good driver support (even the built in Bluetooth). If anything, the driver support is better than Windows 7 or 8. So installation was very simple and painless.

So I'm very impressed. The machine is nice and responsive and everything is easy to find in the user interface. It's almost like having a new laptop (well OK, you'd have a hard job getting me to part with my MacBook actually).

Since then, I've even tried installing Lubuntu on my Acer Iconia Tab W500. The result is that the machine works fine as a laptop, but you couldn't really use it as a tablet (not without a lot of configuring anyway). Umm, experimenting with Linux distros on one laptop has led to me wiping another; you need to be careful with these types of experiment I guess...

But ... if you have an old machine sitting around doing nothing, and you want to get some more use out of it (without costing any money) then installing Lubuntu might be a good thing to try.

Music by numbers

I wanted to use a Raspberry Pi to play some songs (mp3s) through a very simple interface. Something where you can just type in a number and a corresponding mp3 file would play. This is what I've come up with:

The songs play with mpg321, a simple and lightweight mp3 player. I've used a spare "Dream Cheeky" LED display to show which mp3 is being played (by number). Obviously in the photo shown above there is nothing plugged into the audio socket ... but it was easier to take the picture this way.

The LED display is driven by the excellent dcled utility which works perfectly on the Raspberry Pi. A cheap numeric keypad allows input (although I have also made a web-based interface too).

I'll probably describe some of the software in more detail, when I have time.

Essential Travel Items

We've recently enjoyed a fantastic holiday in Fuerteventura (near the resort of Jandia). A brilliant place to relax, and it's on a 30km stretch of beautiful sandy beach. The weather was fantastic too (it's often a bit breezy on Fuerteventura but we don't mind that).

The view from our balcony was quite nice too:

When travelling, I carry a bag to keep my Camera, Kindle, Tablet, etc... in, but it greatly amuses my wife that I also carry: graph paper, a variety of pens, a ruler, and a protractor. I view this as entirely sensible, since at any moment I may decide I need to draw some kind of diagram.

Now, I don't actually use graph paper or a protractor very often when I'm on holiday, but I still like to carry them... just in case. I find it strangely comforting. Is that weird?

Having said that, I also make sure I have a C compiler on my tablet these days, which is actually quite likely to see gentle use during a holiday. That probably is weird, but I'm happy to accept that.

For example, during this holiday I wrote some C helper functions to make it easier to allocate resizable blocks of memory. Basic boilerplate stuff, but I enjoy tinkering with things like that...

No kill switch on Awesome

Most years I buy a Dilbert calendar for my desk. For some reason, I've kept the title page for the 2014 calendar:

It's now heading towards the end of February and I've still kept it. I don't really know why, but it keeps making me smile. So I thought that I'd post it here, enjoy.

Messing about with Ncurses

For a long time I've been aware of Ncurses, but I've never actually used it. So when I accidentally wandered across this tutorial for using Ncurses in Xcode, I decided that it would be worth checking out.

But, when I found myself with a few spare minutes... I was sitting in front of a machine running Debian Linux rather than Mac OS X. So I experimented there instead. To get the snakey program to run I had to do the following:

  1. First of all, I had to get the ncurses stuff:
    sudo apt-get install libncurses5-dev

  2. Then I had to compile the example code (I had renamed the program to box.c):
    gcc box.c -lncurses -o box

  3. Then finally, I could run it:
    ./box

So that was pretty easy. Ncurses is one of those things that I'd like to mess about with some more, because I still like running stuff in a console window.