Sunday, September 2, 2012

Making an IP webcam using an old router



Recently I got my hands on an old Comtrend CT536+ router. It wasn't working. When turned on, some times it worked for a while, but most of the times it just didn't even boot. I decided to try fixing it, so I opened the unit, had a look at its internals and found two capacitors in the power source with a slight bulging. These capacitors could be victims of the annoying capacitor plague, so I replaced them with new low ESR ones and... the router started working!

One of the damaged capacitors next to the two new ones

Installing a USB Host port

Since I took the trouble to open the router, I decided to add some enhancements. The components for the USB Host were not populated in the PCB, so I added a USB Host connector, a capacitor, some SMD resistors and some wiring to get the extremely useful USB Host port. I also added some wires to connect a 3.3V UART, just in case I need to access the GNU+Linux console.

USB mod

Finally I used a file to enlarge the hole for the Ethernet ports in the back of the router, to make room for the new connector. This is how the back of the router looks like now:

The new USB Host connector, ready to be tested

WARNING: Before you plug anything to the new USB Host, you must have in mind the 5V for the host are provided by a 78L05 linear regulator. This regulator was already populated inside the router (I don't know why, because it's only used for the USB Host) and can only supply 100 mA. Some USB devices can draw up to 500 mA, so you have to be careful. Only plug devices drawing less than 100 mA. If you need to plug something needing more juice, use a self-powered USB Hub to plug it, or remove the 78L05 regulator and add a bigger one.

Router internals, including the USB mod

Installing OpenWrt and USB Host driver

Unfortunately, the USB Host port is useless with the firmware that comes with the router. The solution to this problem is installing OpenWrt, a GNU+Linux distro suited for routers. Installation process for this router is dead easy, because it can be done directly using the Firmware Update function in the router configuration web page. Just download the OpenWrt image for this router and point it to the Firmware Update page.

After installing OpenWrt, it's recommended to configure the network. There are tons of ways of doing it, depending on your setup. Just have a look to the OpenWrt Wiki. You can also ask in the forum.

Once you have network working, to get the USB Host working, you have to install the host controller kernel module. The host controller in my router is an OHCI one. Other routers may have a different host controller (UHCI or EHCI). To install the OHCI host controller driver, access the router using SSH and use OPKG package manager:
opkg update
opkg install kmod-usb-ohci
The driver should be automatically loaded by the kernel, but if it is not, you can load it entering the command:
insmod usb-ohci
You can plug some USB stuff and have a look to the kernel messages (dmesg) to see if it's working. If you need to use the useful lsusb command, you can install usbutils package, but don't do it unless needed, because these routers usually have an extremely reduced storage (CT536+ only has 4 MB), so installing stuff can easily fill it.

Installing the webcam drivers

Now we can try getting the webcam working. To stream the video I use mjpg-streamer. But before using it, we have to configure the webcam. Supported webcams can be sorted in two families:

  1. The ones that have UVC support.
  2. The ones that have SPCA support.

I have tried two webcams. The first is this one I bought at DealExtreme. lsusb command lists it as Aveo Technology Corp (1871:0142). It supports UVC profile. The second one is a Logitech QuickCam for Notebooks (046d:08dd). It's supported by SPCA.

To get UVC webcams working, just install kmod-video-uvc package:
opkg install kmod-video-uvc
To get SPCA webcams working, you have to find its driver first. Search it inside this list. For example, for my Logitech webcam, the driver is zc3xx, so I have to install kmod-video-gspca-core + kmod-video-gspca-zc3xx:
opkg install kmod-video-gspca-core kmod-video-gspca-zc3xx

mjpg-streamer

Once you have the drivers for your webcam installed, plug it in the USB port and have a look to the kernel messages (dmesg) to see if it's properly recognized. If everything is OK, install mjpg-streamer:
opkg install mjpg-streamer
You can configure some mjpg-streamer parameters by editing /etc/config/mjpg-streamer. To start mjpg-streamer daemon, use the comand:
/etc/init.d/mjpg-streamer start
You can also enable it so it will be automatically started each boot, using the command:
/etc/init.d/mjpg-streamer enable
Once it's running, to watch the video captured by the webcam and streamed through mjpg-streamer, launch for example VLC media player, and select Media/Open Network Stream... (Ctrl+N). Then in the dialog enter the URL: http://<ip_address_of_the_router>:8080/?action=stream and click the Play button. Of course replace <ip_address_of_the_router> with the address (or dns name) matching your router. You should be able to see the video stream. Congratulations! You can also input that URL in any browser and it should work. It worked for me in Firefox 15 and Opera, but Chromium 21 displayed only a still image. The router can be configured as a wireless/wired IP webcam, and it retains its old functionality, so it still can be used as a standard router!
Opening network streams using VLC

You might wonder which driver is better: SPCA or UVC. These are my findings:
  • Using SPCA with the Logitech webcam, I got a very good framerate at 640x480 resolution. As this camera supported the MJPEG profile, mjpg-streamer only has to encapsulate the frames captured by the camera and send them. With this camera, router CPU usage is very low (around 5%).
  • Using UVC with the Aveo webcam I could only get 320x240 resolution and a very poor framerate (around 1 fps, I think). This camera only supports YUYV profile, so mjpg-streamer has to transcode the image captured by the camera. Even with the poor resolution and framerate, router CPU usage with this webcam is higher (around 15-20% with default compression quality). I wasn't able to make this webcam work with higher resolution/framerate.
Maybe the driver used (either SPCA or UVC) doesn't matter, but to avoid image transcoding, I suppose cameras supporting the MJPEG profile are preferred over the ones not supporting it.

Troubleshooting:

If your webcam supports only the YUYV profile (like my Aveo webcam), you will have to explicitly tell mjpg-streamer to use this profile, or it will not start. Edit /etc/init.d/mjpg-streamer and add the -y switch to the --input section. The line in which mjpg-streamer is called (the last line in the start{} section) should look like:
    [ $enabled -gt 0 -a -c $device ] && sleep 3 && $SSD -S -m -p $PIDF -q -x $PROG -- --input "input_uvc.so -y --device $device --fps $fps --resolution $resolution" --output "output_http.so --port $port" &
Note the -y switch after input_uvc.so, that enables YUYV mode.

Saturday, September 1, 2012

Arch Linux for WM8650 kernel/modules update

I got some time to update my build of the kernel and modules for the WM8650 netbooks. The main features of the updated kernel and modules are:
  • Includes all my previous patches to improve Ethernet compatibility, get battery readings, remove  some nasty debug messages, etc.
  • I have included a lot of drivers missing in my first builds: more wireless dongles, Bluetooth dongles, USB to serial adapters, ipv6, etc.
You can grab the updated kernel (and wmt_scriptcmd) here, and the updated kernel modules here. Extract the kernel to the root of the BOOT partition and the kernel modules to the root of the ARCH_SYS partition (as explained on steps 2 and 4 here).

I had no time to make modifications to the RT5370 driver to build it inside the kernel tree, so it's not included in the kernel modules I posted above. But don't panic, finally I got it to build, and it looks like it's working. I have not an RT5370 dongle to test if it works, but now insmod returns no errors when I load the module, so I suppose it should work. To install this module, first download it here. Then insert the SD card in your computer and unpack the driver (as usual replace /run/media/doragasu/ARCH_SYS/ with the path where the system partition of the SD card is mounted):
tar -xjf wm8650-rt5370_driver.tar.bz2 -C /run/media/doragasu/ARCH_SYS/
Then boot ArchLinux in your netbook and load the module using insmod (with root privileges):
insmod /lib/modules/2.6.32.9-test/kernel/drivers/net/wireless/rt5370sta.ko
As usual you can add this line to /etc/rc.local if you want the module to load each boot. You can also create a script lo load it whenever you want. Don't forget to enable the module with the gpio command!

In my netbook the module loads perfectly and outputs these messages:
rtusb init rt2870 --->
usbcore: registered new interface driver rt2870
Note the driver is the same for RT2870 and RT5370 chipsets. If you try this driver, please confirm if it works.

I also wanted to upgrade the entire distro to the latest version, but unfortunately I'm pretty busy and I have no time to do it. It was nice playing with this netbook, but I'd like to move to other projects, so I think I will not be releasing updates for it anymore.

I hope this updated kernel solves most of the problems with Ethernet, drivers, etc.

Enjoy!