Sunday, September 9, 2012

Raspberry Pi tethering

 After some initial experiments with using a Raspberry Pi as a home server, I wanted to try out some configurations  useful to the intended purpose of the Raspberry Pi: promote computer technology literacy among students.

At least some of the initial feedback from trying to deploy Raspberry Pis in a classroom settings seems to indicate that getting the necessary hardware to operate the Pis is non-obvious. Setting up a room full of Pi based workstations requires HDMI or composite connected TVs or monitors, USB mice and keyboards, micro-USB power supplies and ethernet connectivity routed to each workstation. The cost and logistical complexity of doing that seems to defeat the initial low-cost advantage of the Raspberry Pi.

Furthermore, many schools might already have fully equipped computer facilities with incompatible equipment (e.g. SVGA monitors, standard on any not-so-new PC), which could be used, but just not "messed with" for low-level programming and system administration experiments.

Companies often replace their computers as frequently as every 3 years and as this example shows, schools could easily get their hands on a heterogeneous mix of somewhat old, but still working desktop PCs or laptops more than good enough for light usage.

These days, many students might also have access at home to a PC, netbook or tablet, complete with Internet connection, which can be used for many things, except experimenting with computer technology.

For any of those reasons, I think that the scenario of interfacing and accessing a Raspberri Pi board through an existing standard PC or tablet is going to be a very common use-case, if not in the end, most common one.

There are two common network configuration scenarios for remote access:
  1. connect the Raspberry Pi via Ethernet to an existing wired network, e.g. directly to a network port on a home-gateway router/firewall/wifi-basestation and connect to it via ssh from any device on the same network. This is what I have been doing so far.
  2. connect the Raspberry Pi via Ethernet directly to an unused port on the host computer
Using an Apple PowerBook running Mac OS X 10.6 as the host, I was trying to create a setup which allows for easy plug & play network connectivity. The criteria for success would be the usability for doing some Python programming using IDLE, the native Python IDE bundled with the standard Python distribution. The starting point is an SD card with a stock Raspbian "wheezy" image downloaded from the official site. Most of the approaches described here, should also work on Windows, but I can't verify that since I don't have access to any windows machines.

Add caption
For the initial customization of the image, I connected the Pi board initially to the home router. Fortunately, the standard image already boots with SSH enabled, but does not offer any support to locate the device on the network. Since my wife runs production network operations at our house, I don't have root access to the router, so I was using Fing on Android to scan the network for all available hosts and find the IP address of the new device with a MAC address issued by the Raspberry Pi foundation.

After a first ssh connection into the new device,  we run
sudo raspi-config
and choose the options to extend the root partition to the full size of the flash card and maximize the memory available to the CPU, as we don't intent to use the video subsystem.

The most important step is to install Avahi, the mDNS zero-conf demon, which will advertise the presence and address of the device on the local network. To install and activate, type:
sudo apt-get install avahi-daemon
sudo update-rc.d avahi-daemon defaults
It might be a good idea at this point, to give the device a new, unique name as this will be used to connect to it in the future, by replacing the default hostname in /etc/hostname and /etc/hosts - e.g. "rpi" instead of "raspberrypi".

After reboot, we should now be able to ssh into the new device by typing
ssh pi@rpi.local
in a window of the OS X Terminal application (hidden in Applications/Utilities). For added nicety and to have the device appear automatically in the connection selection of some ssh clients (e.g. on iPad), we can also add the ssh service to be explicitly announced by avahi-daemon, by adding a new file /etc/avahi/services/ssh.service:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">%h SSH</name>
  <service>
    <type>_ssh._tcp</type>
    <port>22</port>
  </service>
</service-group>

With an application like BonjourBrowser on OS X, we can see what is being advertised on the network, including the newly configured service.

Before connecting the new device directly to the Ethernet port of the Powerbook, we need to choose one of two network auto-config methods:
  1. enable IPv6, which by standard includes self-assigned link-local addresses for all interfaces. To enable IPv6 at boot,  add ipv6 at the bottom of /etc/modules.
  2. install an IPv4LL auto-conf daemon (sudo apt-get install avahi-autoipd) which on failure of the DHCP client to get an address wil auto-assign one from the 192.254.0.0/16 address pace, designated for the purposed of IPv4LL self-assigned link-local addresses.
I personally prefer the IPv6 solution, as it is a lot less hacky.

After those changes, we can now connect the new Raspberry Pi device directly to the Powerbook with any Cat5 Ethernet cable (no cross-over cable required as the ports are auto-sensing). In the pictures above,  the PI board is powered directly from the laptop using a USB-micro-USB cable. Power consumption appears to be low enough, without the additional power consumption of USB connected peripherals or the HDMI port. (Since this is not recommended, don't try this at home - or at least at your own risk...).

We should now be able to ssh into the directly attached board by typing:
ssh -6 pi@rpi.local
into the Terminal window (-6 option for ssh over IPv6).

For some added magic and convenience, we could also enable Internet connection sharing on the mac host (e.g.  follow these instructions), assuming it is connected to the Internet using the other, wifi network interface.  In this configuration, the  now also acts as a router and DHCP server issuing an IPv4 address configuration to the Raspberry Pi and routing/masquerading its traffic as its own (since this is using NAT, some services not compatible with NAT might not work).

Such a setup is highly portable and can be taken on the road for demos, workshops or between school & home as it does not depend on any infrastructure than a wifi network and power outlet for the laptop's power adapter.

For graphical applications, like games or even IDLE, the Python IDE, we are relying on the X Window System (X11), a widely supported standard for supporting graphical user interfaces. While not natively X11 based, Mac OS X can also support X11 based UI applications - on some versions the X11 server application is pre-installed (in Applications/Utilities) or the latext XQuartz server application can be installed from here. XQuartz offers a (near) seemless side-by-side of native and X11 applications on the same desktop and provides optimal usability and performance, as most of the resource intensive UI processing is happening on the host PC and not the Raspberry Pi board.

To run native X11 apps, simple enable to option for X11 tunneling in ssh:
ssh -X -6 pi@rpi.local

As an alternate solution, we could also use remote desktop access using the VNC protocol, supported by Mac OS X for its own screen-sharing. See here for some very detailed instructions on how to set up file-sharing and tightvnc for exporting a full desktop to the remote desktop client on the mac. However since in this case the X11 server doing all the UI processing and rendering is running on the Raspberry Pi CPU, this results in a very sluggish experience compared to running a native X11 server on the host.

The image below shows among others an ssh session into the Raspberry Pi running IDLE to display via local X11 server, the remote screen sharing app displaying a full desktop of the VNC based X11 server running on the Raspberry Pi itself and the home directory on the PI appearing as a shared folder in the Finder window.

I have not tried any of this on other possible host platforms, like any version of Microsoft Windows. Yet all of this should be possible as well, as Windows supports IPv4, IPv4LL, Internet connection sharing natively as well as SSH (e.g PuTTY), X11 (e.g.  Xming) and VNC through additional applications.