Monday 3 December 2012

WebRTC Conference and Expo 2012: Mapping SIP to WebRTC - a misunderstanding?


I was fortunate enough to attend the first WebRTC Conference and Expo in San Francisco last month.  This fascinating conference demonstrated the growing hype and interest around WebRTC.

One of the things I observed at the conference was a lot of discussion about "WebRTC obsoleting SIP" and "mapping SIP to WebRTC", both topics that seemed to indicate a misunderstanding of both SIP and WebRTC amongst those discussing them.

SIP and WebRTC are very different protocols (in fact WebRTC is a set of protocols).  SIP relates to the signalling plane and WebRTC to the media plane.  This means that SIP and WebRTC are complementary protocols not competing protocols.

There was a lot of discussion about WebRTC's ability to establish media sessions without signalling or server infrastructure - this is not possible.  When you use the PeerConnection API in a browser you get and provide SDP which needs to be exchanged by the peers to establish the media connection.  How can the peers exchange this SDP without signalling or server infrastructure?

It is clear that some signalling and server infrastructure is required for WebRTC, and this can take one of three obvious forms:
  • Proprietary HTTP/REST signalling
  • XMPP/Jingle over WebSocket
  • SIP over WebSocket
Each of these has advantages and disadvantages.  HTTP/REST signalling is very simple but as HTTP is a transaction (not a session protocol) dialog state must be maintained within the network - this could easily result in resiliency and scaling issues, or complex server infrastructure that replicates dialogs between servers.  XMPP/Jingle is a session protocol, but like HTTP/REST it is lacking in terms of support for common regulatory and privacy features[1].  SIP in many ways is the ideal protocol - the hint is in the name, "Session Initiation Protocol" - as well established extensions (such as outbound) provide resilience and scaling, while regulatory and privacy issues have long been catered for.

Some people indicated that they believed that the use of SIP with WebRTC would be limited due to its complexity and the unwillingness of web-developers to use it.  However, I am not entirely convinced by this argument.  A web-developer is unlikely to want to implement any of the signalling necessary for his WebRTC application, but he will make use of any good libraries that are available.  I believe that SIP will be extensively used in WebRTC applications as long as a good enough set of libraries are available so that web-developers do not need to deal with it directly.

[1] A lot of web-developers ignore regulatory and privacy requirements simply because the large OTT companies have not had to do anything yet.  "Yet" is the operative word here - regulations and privacy are important and cannot be ignored indefinitely.  Using a protocol like SIP for the signalling future proofs web apps and services.  With a good SDK using SIP for the signalling is no harder than using anything else.

Saturday 29 September 2012

Kamailio: SIP over WebSockets

There are a lot of really interesting things happening in the world of telecoms today.  One of the coolest is the work the IETF is doing on RTCWeb - that is media (audio and video) sessions between web-browsers without needing plugins.

RTCWeb is going to be a great enabler for all sorts of new types of web application (many of which haven't even been imagined yet) - but RTCWeb only focusses on the media part of communication.  In a lot of cases (particularly if telephony features or integration are required) the media alone isn't enough.  To this end Inaki Baz Castillo, Jose Luis Millan Villegas, and Victor Pascual have been working on an IETF draft, "The WebSocket Protocol as a Transport for the Session Initiation Protocol (SIP)" (draft-ietf-sipcore-sip-websocket-03).

There are now a number of implementations of SIP over WebSockets.  Servers include Asterisk, Kamailio, Mobicents SIP Servlets, OverSIP, and Repro/webrtc2sip.  Clients include jsSIP and sipML5.  This is not bad for a draft.

The Kamailio implementation of SIP over WebSockets (supporting both WebSockets (ws) and Secure WebSockets (wss)) has been available in the master branch of the SIP Router Git repository since early July 2012.  A number of people have tried using this and, aside from some configuration related issues, it appears to be working well.  I have tested (and seen others test) the Kamailio implementation with both the jsSIP and sipML5 clients.

If you want to try SIP over WebSockets, and you want to use it with a SIP server that supports lots of rich features (including scripting in Lua/Mono/Perl/Python, presence server, offline instant message handling, load-balancing, least-cost-routing, and far too many other things to list), Kamailio is an excellent place to start - there is even an example configuration file for SIP over WebSockets that is ready to go.

Wednesday 20 June 2012

Updating the kernel on Fedora 17 for Raspberry Pi

I've been playing around with Fedora 17 on the Raspberry Pi for a while.  There are excellent nightly images available from http://scotland.proximity.on.ca/arm-nightlies/, but these have an old version of the 3.1.9 Raspberry Pi kernel.

I have had a few problems with this old kernel including:

  • My fast (8 GB SanDisk Extreme Pro (class 10, 95 MB/s)) SD cards don't work - and the class 4 cards are just too slow for certain jobs.
  • Lots of these sort of errors:
    DEBUG_ timer_callback:: Timer hc timer callback
    WARN:: hc_xfer_timeout:1740: hc_xfer_timeout: timeout on channel 5
    WARN:: hc_xfer_timeout:1742 start_hcchar_val 0x00d88a00
  • Lots of these kind of errors when the root partition is on a class 4 card:
    mcc0: note - long write synce 1350000ns - 13603 its.
So tonight I decided to upgrade the kernel following the instructions from this thread http://www.raspberrypi.org/phpBB3/viewtopic.php?f=51&t=8250 (post dated 2012-06-13 9:37am).

So far this has worked brilliantly.  The errors are gone and I can use my fast SD cards now.

Sunday 3 June 2012

Kamailio for Raspberry Pi

I have recently build some RPMs of Kamailio 3.3.0-pre3 (as of yesterday) including for the Raspberry Pi (running Fedora 17).

I haven't done much testing with these yet, but if anyone wants to try them I have put them in my yum repo: http://dl.dropbox.com/u/9300853/yum/index.html

Saturday 2 June 2012

Air Video Server for Linux on Fedora 17

One of the things that stopped working when I upgraded to Fedora 17 was Air Video Server for Linux.  Fortunately, this is a quick fix - I needed to rebuild FFMpeg (step 4 in my previous procedure).

Unfortunately, the version of FFMpeg needed for Air Video Server Linux doesn't compile on Fedora 17 - but this was easy to fix.  So, if you are upgrading to Fedora 17 simply rebuild and install FFMpeg (step 4 in my previous procedure) following the instructions below.  If you have a new installation of Fedora 17 my previous procedure will mostly work but you should replace step 4 with the instructions below.


tar jxvf ffmpeg-for-2.4.5-beta6.tar.bz2
cd ffmpeg/libavcodec/x86
rm h264_qpel_mmx.c
wget http://dl.dropbox.com/u/9300853/AirVideoLinux-alpha6/h264_qpel_mmx.c
cd ../..
./configure --enable-pthreads --disable-shared --enable-static \
  --enable-gpl --enable-libx264 --enable-libmp3lame
make all
[sudo] make install
cd ..


Updated: Mon 4 Jun 2012 00:04

Upgrading to Fedora 17

I upgraded both of my Fedora 16 systems to Fedora 17 today.  I was, unfortunately, affected by four similar, but separate, grub2 bugs.  For those who don't know, grub2 is the bootloader used in Fedora and - if it goes badly wrong you can end up with a system that won't boot.

The four problems I had were:
  1. Whenever a new kernel is installed I get the error: "grubby fatal error: unable to find a suitable template"
  2. When the computer boots grub2 reports "error: file '/boot/grub2/locale/en.mo.gz' not found"
  3. When the computer boots I get a "signal out of range" error on my monitor, and on fixing this
  4. grub2 prints "error: file not found" three times after starting to boot
The fix to these issues is simple:
# vim /etc/default/grub (add the line GRUB_TERMINAL_OUTPUT=console to the end of the file)
# grub2-mkconfig -o /boot/grub2/grub.cfg
# grub2-install /dev/sda (replace /dev/sda with the device your bootloader is installed on)

If (like me) you are paranoid you can check the fixes by reinstalling the kernel (as long as you haven't restarted your machine and are still running the old kernel) and making sure there are no errors reported:
# yum reinstall kernel


Updated: Sun 3 Jun 2012 11:53

Thursday 31 May 2012

Raspberry Pi compiling and development on Fedora 17

My last post explained how to run Fedora 17 on the Raspberry Pi.  An SD card is OK to run software from, but it is not the best configuration for doing things (like compiling software) that involve lots of random "disk" reads and writes.

If you are going to be compiling lots software it makes sense to use a USB hard-drive.  This guide explains how to boot Fedora 17 from an SD card (the Raspberry Pi must boot from an SD card) but run the root file-system from a USB hard-drive.

In addition to the assumptions in my last post, I am assuming:

  • Your USB hard-drive is /dev/sdb when connected to your computer.   If your USB hard-drive is on a different device file then make sure you work out what it is and use the right file-name in the instructions below - getting this wrong could permanently lose data.
Complete steps 1 and 2 from my last post before continuing here:
  1. Delete the unnecessary root filesystem from the SD card:
    # fdisk /dev/mmcblk0 (commands I entered and comments in bold below)

    Command (m for help): d
    Partition number (1-4): 2
    Command (m for help): w
    The partition table has been altered!

    Calling ioctl() to re-read partition table.

    Syncing disks.
  2. Update the SD card so that the Raspberry Pi looks for the root file-system on a USB hard-drive:
    # mkdir /tmp/boot_pi
    # mount /dev/mmcblk0p1 /tmp/boot_pi

    # vim /tmp/boot_pi/cmdline.txt (change root=/dev/mmcblk0p2 to root=/dev/sda2 - this really is /dev/sda here as that is how it will appear on the Raspberry Pi)

    # umount /tmp/boot_pi

    # rmdir /tmp/boot_pi
  3. Connect the USB hard-drive to your computer (unmount it if your computer automounts it for you) and write the image to the hard-drive:
    # xzcat f17arm-latest-arm-rpi-mmcblk0.img.xz > /dev/sdb
  4. Delete the unnecessary boot partition from the hard-drive and resize the root file-system:
    # fdisk /dev/sdb (commands I entered and comments in bold below)

    Command (m for help): p

    Disk /dev/sdb: 80.0 GB, 80026361856 bytes
    81 heads, 63 sectors/track, 30629 cylinders, total 156301488 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000

       Device Boot      Start         End      Blocks   Id System
    /dev/sdb1   *          63     1044224      522081    c  W9...
    /dev/sdb2         1044225     7784447     3370111+  83  Linux

    Command (m for help): d
    Partition number (1-4): 2

    Command (m for help): n
    Partition type:
       p   primary (1 primary, 0 extended, 3 free)
       e   extended
    Select (default p): p
    Partition number (1-4, default 2): 2
    The first sector must be the start sector of /dev/sdb2 (above).  This number may be different on your hard-drive.  It should be the default value here - but check it carefully anyway.

    First sector (1044225-156301488, default 1044225): 1044225
    The last sector should be the default if you want to use all available space on the hard-drive.  If the default is what you want just press return.

    Last sector, +sectors or +size{K,M,G} (1044225-156301488, default 156301488):

    Using default value 156301488

    Command (m for help): d
    Partition number (1-4): 1

    Command (m for help): w

    The partition table has been altered!

    Calling ioctl() to re-read partition table.

    Syncing disks.
    # e2fsck -f /dev/sdb2
    # resize2fs /dev/sdb2
    # mkdir /tmp/rootfs_pi
    # mount /dev/sdb2 /tmp/rootfs_pi
    # rm -f /tmp/rootfs_pi/etc/systemd/system/multi-user.target.wants/rootfs-resize.service
    # umount /tmp/rootfs_pi
    # rmdir /tmp/rootfs_pi
  5. Now eject the SD card from your reader and disconnect your USB hard-drive, put the SD card in your Raspberry Pi and connect the USB hard-drive and power up.  Once it has booted log in as "root" using the password "fedoraarm".  (Assuming that you are connected over a wired LAN with a DHCP server) the Raspberry Pi will automatically obtain an IP address and LAN settings (I am going to assume this is the case - if not the process for configuring networking is exactly the same as it is on any other Fedora 17 machine).
  6. Update your packages:
    # yum update

    Don't worry about the fact that a new kernel is installed - even though this new kernel is not Raspberry Pi compatible.  When a new kernel is installed using "yum update" the old one (and it's modules) are not removed.  Also, because of the way the UBOOT partition in the images works, installing a new kernel does not change the default kernel used when you boot.
Job done.  You now have a perfectly usable and up-to-date Fedora 17 Raspberry Pi SD card and USB hard-drive combination.

Fedora 17 on Raspberry Pi

I received my Raspberry Pi this week and set about installing Fedora, my operating system of choice, on it.  Unfortunately, Fedora 14 is regarded as unstable on the Raspberry Pi and Fedora 17 isn't quite ready for it yet.

However, there are some very good nightly snapshots of Fedora 17 (http://scotland.proximity.on.ca/arm-nightlies/) for Raspberry Pi available.  I thought I would put together a short guide on using these.

This guide assumes:
  • You are logged in as root on a Linux computer
  • Your SD card is /dev/mmcblk0 when inserted into your SD card reader.  If your SD card is on a different device file then make sure you work out what it is and use the right file-name in the instructions below - getting this wrong could permanently lose data.


The first thing to do is to select the image you want to install.  The nightly builds come in three flavours:
  1. Console only (this is the one I use and referred to in the rest of the instructions)
  2. Minimal X Windows
  3. XFCE

Once you have chosen your image the process is:
  1. Download the software (replace the URL here with the one for the image you have selected):
    # wget http://scotland.proximity.on.ca/arm-nightlies/vault/f17arm-latest-arm-rpi-mmcblk0.img.xz
  2. Insert your SD card (unmount it if your computer automounts it for you) and write the image to the card:
    # xzcat f17arm-latest-arm-rpi-mmcblk0.img.xz > /dev/mmcblk0
  3. When your Raspberry Pi boots this image for the first time it will resize the root file-system to use up the whole card.  Waiting for this is tedious and it gets in the way of using your Raspberry Pi right away.  Fortunately, on a Linux PC, you can do this manually (and quickly):
    # fdisk /dev/mmcblk0 (commands I entered and comments in bold below)

    Command (m for help): p

    Disk /dev/mmcblk0: 7822 MB, 7822376960 bytes
    4 heads, 16 sectors/track, 238720 cylinders, total 15278080 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000

            Device Boot      Start         End      Blocks   Id  System
    /dev/mmcblk0p1   *          63     1044224      522081    c  W9...
    /dev/mmcblk0p2         1044225     7784447     3370111+  83  Linux

    Command (m for help): d
    Partition number (1-4): 2

    Command (m for help): n
    Partition type:
       p   primary (1 primary, 0 extended, 3 free)
       e   extended
    Select (default p): p
    Partition number (1-4, default 2): 2
    The first sector must be the start sector of /dev/mmcblk0p2 (above).  This number may be different on your SD card.  It should be the default value here - but check it carefully anyway.

    First sector (1044225-15278079, default 1044225): 1044225
    The last sector should be the default if you want to use all available space on the SD card.  If the default is what you want just press return.

    Last sector, +sectors or +size{K,M,G} (1044225-15278079, default 15278079):

    Using default value 15278079

    Command (m for help): w

    The partition table has been altered!

    Calling ioctl() to re-read partition table.

    Syncing disks.
    # e2fsck -f /dev/mmcblk0p2
    # resize2fs /dev/mmcblk0p2
    # mkdir /tmp/rootfs_pi
    # mount /dev/mmcblk0p2 /tmp/rootfs_pi
    # rm -f /tmp/rootfs_pi/etc/systemd/system/multi-user.target.wants/rootfs-resize.service
    # umount /tmp/rootfs_pi
    # rmdir /tmp/rootfs_pi
  4. Now eject the SD card from your reader, put it in your Raspberry Pi and power up.  Once it has booted log in as "root" using the password "fedoraarm".  (Assuming that you are connected over a wired LAN with a DHCP server) the Raspberry Pi will automatically obtain an IP address and LAN settings (I am going to assume this is the case - if not the process for configuring networking is exactly the same as it is on any other Fedora 17 machine).
  5. Update your packages:
    # yum update

    Don't worry about the fact that a new kernel is installed - even though this new kernel is not Raspberry Pi compatible.  When a new kernel is installed using "yum update" the old one (and it's modules) are not removed.  Also, because of the way the UBOOT partition in the images works, installing a new kernel does not change the default kernel used when you boot.
Job done.  You now have a perfectly usable and up-to-date Fedora 17 Raspberry Pi SD card.




Monday 9 April 2012

Air Video Server for Linux on Fedora 16

I use the excellent Air Video software to stream non-MP4 video (including DivX) to my iPad and iPhone (I then sometimes use Air Sharing to stream the video from the iPad or iPhone to my AppleTV).  The one problem I have with this set-up is that the Air Video Server software is only released for Macs (which I don't have) and Windows (which I do have, but don't like to leave running 24x7).

Luckily InMethod have released an alpha Air Video Server for Linux.  Unfortunately, getting this installed and running on Fedora 16 (my distribution of choice) isn't entirely straight forward.  The rest of this post is a guide to installing Air Video Server Linux alpha 6 on Fedora 16.

  1. Download the software:
    - From InMethodAirVideoServerLinux.jarffmpeg-for-2.4.5-beta6.tar.bz2test.properties
    - From mempeg4ip-1.6.1.tar.gz (no longer available from original website), mpeg4ip-1.6.1-pd.patchairvideo.serviceairvideo

    The patch is required to make mpeg4ip build on Fedora 16.  This patch is the minimum change to get mpeg4ip to build, and has only been tested in the context of getting Air Video Server Linux alpha 6 to work.
  2. Make sure you have installed the RPM Fusion repos.  You should also consider using yum priorities to protect the integrity of your machine - that is, make sure that when the same package is in the Fedora repos and RPM Fusion repos you do not break your machine by installing the RPM Fusion version.
  3. Install the dependencies that are available as RPMs:
    [sudo] yum install esound-devel faac gcc gcc-c++ \
             glib2-devel gtk2-devel java-1.7.0-openjdk lame-devel \
             SDL-devel x264-devel
  4. Build FFMpeg:
    tar jxvf ffmpeg-for-2.4.5-beta6.tar.bz2
    cd ffmpeg
    ./configure --enable-pthreads --disable-shared --enable-static \
      --enable-gpl --enable-libx264 -
    -enable-libmp3lame
    make all
    [sudo] make install
    cd ..
  5. Build mpeg4ip:
    tar zxvf mpeg4ip-1.6.1.tar.gz
    patch -p0 < mpeg4ip-1.6.1-pd.patch
    cd mpeg4ip-1.6.1
    ./configure
    make all
    [sudo] make install
    cd ..
  6. Install Air Video Server for Linux:
    [sudo] mkdir /usr/local/share/AirVideoServer
    [sudo] cp airvideo /usr/local/share/AirVideoServer
    [sudo] cp AirVideoServer.jar /usr/local/share/AirVideoServer
    [sudo] cp test.properties /usr/local/share/airvideo.properties
  7. Update /usr/local/share/AirVideoServer/airvideo.properties to match your system:
    path.ffmeg = /usr/local/bin/ffmpeg
    path.mp4creator = /usr/local/bin/mp4creator
    path.faac = /usr/bin/faac
    folders = <the location of your video files>
  8. Configure Avahi (Bonjour/mDNS):
    [sudo] cp airvideo.service /etc/avahi/services
    [sudo] service avahi-daemon restart
  9. Configure the firewall:
    Use system-config-firewall or system-config-firewall-tui and:
    - add Multicast DNS (mDNS) to the trusted services
    - add 45631:tcp in "Other Ports"
  10. Auto start/stop on system startup/shutdown:
    [sudo] ln -s /usr/local/share/AirVideoServer/airvideo \
             /etc/init.d/airvideo
    [sudo] chkconfig airvideo on
  11. Start Air Video Server for Linux:
    [sudo] service airvideo start
After all this your Fedora 16 PC will be running Air Video Server for Linux.  The Air Video software on your iPad or iPhone will automatically find your PC on your network (thanks to Bonjour/mDNS), and Air Video Server for Linux will automatically start/stop when you startup/shutdown your PC.

Updated Sun 10 Jun 2012 00:13