Thursday, March 17, 2011

Under the hood

Poking around the shell after telnet'ing in has revealed the following hardware, a bit of googling later and it actually is very impressive given the relative low cost of the device:

Prolific PL1029 Arm Processor


OmniVision OV7720 CMOS Sensor


4 Mbytes NOR (Flash)

32 Mbytes SDRAM

RALink Technology RT61 WiFi Adapter (802.11b/g)

Ethernet Adapter

2 x Status LED connected via GPIO
1 x IR LED connected via GPIO
1 x light sensor connected via GPIO
1 x momentary push button connected via GPIO

Wednesday, March 16, 2011

Taking a peek at the firmware

TRENDnet offer a download for the GPL source at their website; a quick download later allowed me to take a peek at what they had used to pull it together. Annoyingly, they had only included the bare esentials with no buildchain or any other tools to build a custom firmware.

A bit more research showed that they have used a relatively common platform to build the camera (using the PL1209 chipset) which a very capable and self contained device (more on this later).

It seems that other companies also make use of this platform for these type of devices (indeed some look identical to the 312W I have here) and so I had a look around to see if anyone else has had any joy in getting into the firmware.

A company snappily called Airlink 101 Network Solutions offer a similar looking device; the AICN500W which has a very similar case and the same functionality. A quick look around their website and a download later and I have a much more complete firmware source tree and crucially the tools necessary to build a complete firmware image.

I have republished their toolchain here under the terms of the GPL.

The instructions provided with the image indicate that fedora 3 is needed to use the buildchain; not having the desire to have yet another image on my Mac I took the chance that it would work with Ubuntu; a couple of hours later (and a couple of fixes to the make files provided) and I can get the entire toolchain to compile providing the compiler, headers and source files for all the opensource components.

Not wanting to risk installing the firmware from another manufacturer - and bricking the camera - I looked around for a description of the firmware format to see if the 312W resembled that used in the Airlink devices.

I stumbled across a chap who has already done this for the AICN747W which looks similar enough - and interestingly he has used it to enable telnet on the camera. A quick peek at his instructions and a little tinkering later, using the fwpacker source provided in the tool chain to reverse engineer the process and I wrote a script to extract the components in order to modify the firmware provided with the 312W.

You can download the source here

#!/usr/bin/perl
# TrendNet firmware unpacker
# Matt Brain (matt.brain@gmail.com)
#
# Usage: fwunpack.pl
#
# Extracts: prostub.bin
# vmlinuz
# minix.gz
# autoboot.bat
# footer.bin
#
# Writes log to fwunpack.log

use strict;

my $scriptversion=1; #Version of this script

my $headerPointer=0x04; #Header reference in firmware
my $versionLocation=0x08; #Version location in firmware
my $md5Location=0x0c; #md5 location in firmware
my $md5Size=16; #md5 length
my $crcLocation=$md5Location+$md5Size; #crc location
my $crcSize=4; #crc length
my $pkgSizeLocation=$crcLocation+$crcSize; #package size location
my $headerSize=4096; #size of header found at $headerPointer

my $model="Unknown";
my $headerLocation=0x00;
my $tVersion=0x00;
my @version=(0,0,0,0);

my @chunkStart=(0);
my @chunkLength=(0);
my @chunkName=("vmlinuz", "minix.gz", "autoboot.bat");
my @chunk;

my $footer="";
my $prostub="";
my $numArgs=$#ARGV+1;




sub Usage {
print "Usage: fwunpack \n\n";
exit;
}



if ($numArgs<1) {
&Usage;
}

print "** fwunpack version $scriptversion **\n\n";
print "Opening $ARGV[0]\n";
open(FIRMWARE,"<$ARGV[0]");
binmode(FIRMWARE);

#read the header location
seek(FIRMWARE,$headerPointer,0);

read(FIRMWARE,$headerLocation,4) or die "FATAL: Couldn't read the header location\n";

#firmware location is stored in little endian format so need to fiddle the bits
$headerLocation = unpack('L<',$headerLocation);
printf "Header location at 0x%x\n",$headerLocation;

seek(FIRMWARE,$versionLocation,0);
read(FIRMWARE,$tVersion,4) or die "FATAL: Couldn't read the version\n";
@version=unpack('cccc',$tVersion);
printf "Firmware version $version[3].$version[2].$version[1].$version[0]\n";
#read the model name
seek(FIRMWARE,$headerLocation+4088,0);
read(FIRMWARE,$model,8);
print "Model $model\n";

my $chunkCursor=$headerLocation+4096;
#load the header
for (my $counter=0;$counter < 511;$counter++) {
seek(FIRMWARE,$headerLocation+($counter*8),0);
read(FIRMWARE,$chunkStart[$counter],4);
read(FIRMWARE,$chunkLength[$counter],4);
$chunkStart[$counter] = unpack('L<',$chunkStart[$counter]);
$chunkLength[$counter] = unpack('L<',$chunkLength[$counter]);
if ($chunkStart[$counter]>0) {
printf "%s found, deploy at:0x%x length:%d\n",$chunkName[$counter],$chunkStart[$counter],$chunkLength[$counter];
seek(FIRMWARE,$chunkCursor,0);
read(FIRMWARE,$chunk[$counter],$chunkLength[$counter]);
$chunkCursor = tell(FIRMWARE);
open(CHUNK,">$chunkName[$counter]") or die $!;
binmode CHUNK;
print CHUNK $chunk[$counter];
close CHUNK;
}
}

seek(FIRMWARE,$chunkCursor,0);
print "writing footer.bin\n";

read(FIRMWARE,$footer,64);
open(FOOTER,'>footer.bin');
binmode FOOTER;
print FOOTER $footer;
close FOOTER;

print "writing prostub.bin\n";

seek(FIRMWARE,0,0);
read(FIRMWARE,$prostub,$headerLocation);
open(PROSTUB,'>prostub.bin');
binmode PROSTUB;
print PROSTUB $prostub;
close PROSTUB;

close FIRMWARE;


Using the instructions provided with the AICN500W firmware I was then able to rebuild the firmware and do a comparison between the 2 - this was critical to show that i was pulling all the bits out as expected and was able to reconstruct the bits into an identical firmware file. I had to create an ipcam.dsc file to describe the components in the firmware for the fwpacker tool as below and append the footer.bin to the output of fwpacker.

# ipcam.dsc

# describe the firmware version
@version 1.0.0.3

# describe the model which maxium 8 characters
@model IPCAM001

# describe nor flash type and size
@norinit 1 "8x8,64x63"

# describe deployment location and input file
@deployment
vmlinuz 0x20000 777008
minix.gz 0xe0000 2836160
autoboot.bat 0x2000 8192
@end

I then referred back to the instructions found earlier and
enabled telnet access by uncommenting 2 lines in etc/rc.d/init.d/daemon.sh:

# echo "Starting telnetd ..."
# telnetd -p 15566

gzipping the disk image back up produced a smaller image which concerned me - but rebuilding the firmware and uploading proved it worked (bit of a gamble I know) - I had telnet access on 15566.
You may download a bundle which contains the source for the fwunpacker along with the fwpacker and associated files from

It seems all the download links are broken - here is a bundle of all the files used in this project Google Drive ZIP archive

Getting started

Upon returning to the homestead I opened the box and got started; it comes with a neat little wall wart power supply and a setup CD. Having a Mac (and no desire to go through what looks like an unnecessary config process using a Windows VM session) I decided to connect it up to ethernet and use the in built web server to configure it. Out of the box it uses a static IP address on ethernet and was a doddle to configure it to use the wifi and get it fired up.

I won't go through the procedure (it is well documented in the instructions) but it didn't take long to get it streaming video into firefox, albeit without audio as it requires IE for the web client's activex control to stream both video and audio to it.

Out of curiosity I connected to it from a windows VMware session with IE and found it also supports 2 way audio and motion detection - quite impressive for such a low cost device although the handicapping for anything not using the activex control is a bit of a pain.

A quick port scan revealed it was listen on HTTP and RTSP; I would have to look elsewhere to get to the console.

I also connected to it using VLC player (using RTSP) and joy - the audio and video both work perfectly - this should make it easier to use with the target devices I had in mind.

The video quality is ok - I wasn't expecting amazing results, but it is certainly suitable for our needs. There is a slight purple tinge to the image, but I think this is due to the sensor being IR sensitive. Streaming is pretty good - it can get a little choppy at times, but i suspect this is due to the WiFi network being congested rather than an issue with the camera itself. I am still pondering the merits of WiFi over Ethernet, with all the possible implications on the little mites health; I haven't discounted the idea of using Ethernet when it is being used for the baby.

Introducing the TRENDnet TV-IP312W

After looking around for a while I found there are lots of companies producing inexpensive IP Webcams; knowing how reluctant companies could be with releasing the opensource components (or only releasing the bare minimum to meet the GPL license requirements) I needed to find something which I thought I stood a fair chance of modifying. In addition to this I need to find a cam with the following functionality.

1.Work well in low light conditions
  • We don't want to have to be burning 100 Watts and blinding the baby just so we can see it sleeping (or attempting to)
2.Stream video and audio with mjpeg and 3gpp protocols
  • We need something which pretty much already works with stuff we have - I don't have the time (or the knowledge) to build an entire streaming platform
3. Have a mechanism to monitor temperature or at least expansion which could be adapted to monitor temperature

4. Be affordable
  • If she who must be obeyed (SWMBO) had found I had spent thousands of pounds on a fancy streaming platform I don't think she would be happy ;)
  • We also have friends who are in a similar position, and it would be nice to be able to gift them a similar solution
With these additional requirements in mind (and including the requirements from the initial request); I decided on a TRENDnet TV-IP312W.













This camera seems to tick all the boxes; a quick trawl through the internet identified the following features:

  • WiFi (802.11g) and Ethernet
  • Video capture at 640 x 480 and 30fps
  • Audio capture and Audio out (not even thought of using this)
  • Streaming with multiple formats simultaneously
  • USB port (add temperature module here I think)
  • Works down to 0 lux with the support of IR illumination
  • OpenSource firmware (downloadable from the TRENDnet website)
I looked around for a good price and as luck would have it found it for £99.00 (reduced from £145.00) at my local PC world, so I popped out and bought the last one in the store.

Building a baby monitor

We have a baby on the way, and in her infinite wisdom (and knowing my love of hacking around) the other half has requested a baby monitor for the nursery. I have a love of all things gadgetry and decided we needed to be able to view and hear the baby as well as monitor the temperature.

I drew up a short list of the functions needed and then had a look around to see if anything ticks all the boxes.

The requirements are:

1. View and Listen to the baby on devices we already own
  • This includes iOS devices such as the iPad, iPhone and Apple TV2
  • PC's
2. View and Listen to the baby on a dedicated device (and ideally something else we already own)
  • I have an O2 Joggler Picture Frame which I bought for doing other things with - this would be ideal
3. Allow us to view and listen remotely.
  • I'm not planning to be a bad parent (honest), but i travel a lot for work do being able to virtually peek my head around the door and check in on the little might would be a bonus.
4.Monitor and alert on events; specifically:
  • Temperature
  • Noise
5. Be easy to use
  • Unlike many of my hacks; it shouldn't require specific knowledge or constant pampering to operate, it should just work.
6. Be family friendly
  • We don't want to have a maze of wires and dongles floating around - it needs to be self contained
7. Have a privacy setting.
  • The last thing we want is guests to see the good lady breastfeeding before popping the little mite to bed; there needs to be an easy way to turn of the video and audio and for it to automatically restart should we forget to turn it back on
  • Ideally, the other monitoring; i.e. temperature and volume should continue to be monitored
With all these requirements in mind I started hunting around for the perfect device. Whilst there are many good baby monitors (some with camera's, screens, temperature monitors etc) available, none of them ticked all the boxes (and to be honest I relished the challenge).

I then started to look around the market for an IP camera which could be modified to meet our requirements. Having had some experience with embedded devices (such as linksys routers, gumstix and pogoplugs) I thought it would be relatively trivial to enhance something out there based on an opensource Linux platform.