Archive for July, 2013

Nicholas Skaggs

An autopilot emulator for ubuntu sdk apps: Part II

A little over a month ago, I posted about creating an autopilot emulator for
ubuntu sdk applications. Thanks to some hard work by Leo Arias and the ubuntu sdk team, I'm happy to announce the little side project from my +junk branch is all grown up and even more ready for your consumption. Leo has made the emulator a proper part of the sdk, complete with tests for all of it's functions!  You can now easily install it and incorporate it into your project. Here's how to snag your copy.

1) Add the ubuntu sdk team ppa if you haven't already

sudo add-apt-repository ppa:ubuntu-sdk-team/ppa

2) Install the ubuntu-ui-toolkit-autopilot package

sudo apt-get update && sudo apt-get install ubuntu-ui-toolkit-autopilot

This will install the emulator as a python module, ready for you to import. If you want to checkout what the module can do, have a look at the documentation.

Incorporating the module might seem a little tricky, so Leo has also put together an example of one of the ubuntu touch core apps using the new module. Check out it. Here's a branch showing off the work done for ubuntu-filemanager-app. And here's one for dropping-letters.

Please do check out the module and incorporate it into your ubuntu sdk project. Feedback is encouraged, and bug reports too! Please file any issues you find against the ubuntu-ui-toolkit project. Happy Automated Testing!
Jean-Baptiste

In previous post we have seen how to configure a touch device and the host system to provide network connectivity over USB to the devices via USB. This article describes how to automate this setup when a device is connected.

There are 2 distinct phases to this setup:

  1. Configuration of the bridge, trafic forwarding and DHCP on the host.
  2. Add the interface to the bridge when a device is connected.

Step one must be done only once, when the host system starts. In Ubuntu the answer is to write an upstart job that would for example start when networking is ready.

The script below (shamelessly inspired by the work of Serge Hallyn on packaging of LXC) is an example of an upstart job that will go into /etc/init/touch-net.conf:

description "touch usb network"
author "Jean-Baptiste Lallement <jean-baptiste.lallement@canonical.com>"

start on started networking
stop on runlevel [!023456]

env USE_TOUCH_BRIDGE="true"
env TOUCH_BRIDGE="usbbr0"
env TOUCH_ADDR="192.168.124.1"
env TOUCH_NETMASK="255.255.255.0"
env TOUCH_NETWORK="192.168.124.0/24"
env TOUCH_DHCP_RANGE="192.168.124.2,192.168.124.254"
env TOUCH_DHCP_MAX="253"
env TOUCH_DHCP_CONFILE=""
env varrun="/var/run/touch"

pre-start script
    [ -f /etc/default/touch-net ] && . /etc/default/touch-net
    [ "x$USE_TOUCH_BRIDGE" = "xtrue" ] || { stop; exit 0; }

    cleanup() {
        # dnsmasq failed to start, clean up the bridge
        iptables -t nat -D POSTROUTING -s ${TOUCH_NETWORK} ! -d ${TOUCH_NETWORK} -j MASQUERADE || true
        ifconfig ${TOUCH_BRIDGE} down || true
        brctl delbr ${TOUCH_BRIDGE} || true
    }

    if [ -d /sys/class/net/${TOUCH_BRIDGE} ]; then
        if [ ! -f ${varrun}/network_up ]; then
        # bridge exists, but we didn't start it
            stop;
        fi
        exit 0;
    fi

    # set up the usb network
    brctl addbr ${TOUCH_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; }
    echo 1 > /proc/sys/net/ipv4/ip_forward
    mkdir -p ${varrun}
    ifconfig ${TOUCH_BRIDGE} ${TOUCH_ADDR} netmask ${TOUCH_NETMASK} up
    iptables -t nat -A POSTROUTING -s ${TOUCH_NETWORK} ! -d ${TOUCH_NETWORK} -j MASQUERADE

    dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${TOUCH_DHCP_CONFILE} --listen-address ${TOUCH_ADDR} --dhcp-range ${TOUCH_DHCP_RANGE} --dhcp-lease-max=${TOUCH_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${TOUCH_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq.${TOUCH_BRIDGE}.leases --dhcp-authoritative || cleanup
    [ ! -d ${varrun} ] && mkdir -p ${varrun}
    touch ${varrun}/network_up
end script

post-stop script
    [ -f /etc/default/touch ] && . /etc/default/touch
    [ -f "${varrun}/network_up" ] || exit 0;
    # if $TOUCH_BRIDGE has attached interfaces, don't shut it down
    ls /sys/class/net/${TOUCH_BRIDGE}/brif/* > /dev/null 2>&1 && exit 0;

    if [ -d /sys/class/net/${TOUCH_BRIDGE} ]; then
        ifconfig ${TOUCH_BRIDGE} down
        iptables -t nat -D POSTROUTING -s ${TOUCH_NETWORK} ! -d ${TOUCH_NETWORK} -j MASQUERADE || true
        pid=`cat ${varrun}/dnsmasq.pid 2>/dev/null` && kill -9 $pid || true
        rm -f ${varrun}/dnsmasq.pid
        brctl delbr ${TOUCH_BRIDGE}
    fi
    rm -f ${varrun}/network_up
end script

You will recognize in this upstart job the configuration of the bridge, the forwarding rule and dnsmasq. The configuration will be loaded from /etc/default/touch-net if this file exists.

This is all for step 1.

Step 2, adding the interface to the bridge, can be achieved with an udev rule that will run a script when a network interface of type usb is added. This rule looks like:

$ cat /lib/udev/rules.d/77-touch-net.rules
# Udev rules for letting adding a usb network interface to the bridge
ACTION=="add|change", SUBSYSTEM=="net", DRIVERS=="usb", KERNEL=="usb[0-9]*", \
ATTRS{idVendor}=="18d1", RUN+="/usr/local/bin/touch-bridge-addif"

In english this rule says, when a network device using a usb driver with a name starting with usb and a digit from vendor 18d1 (Google Inc.) is added or changed execute the script /usr/local/bin/touch-bridge-addif

The following script simply adds the network device to the bridge.

$ cat /usr/local/bin/touch-bridge-addif
#!/bin/sh -eu
TOUCH_BRIDGE=usbbr0
if ! ip link show $TOUCH_BRIDGE >/dev/null 2>&1; then
    echo "E: Bridge interface $TOUCH_BRIDGE is not ready!"
    exit 1
fi
# $INTERFACE is exported by udev, this script will fail if it is not defined
brctl addif $TOUCH_BRIDGE $INTERFACE

At this stage you can reboot the host system and verify that the bridge is up and dnsmasq is running.

Now, make sure you have a touch device booted and connected to the USB port of the PC.

Add the following entry to the file /etc/network/interfaces of the device

auto usb0
iface usb0 inet dhcp

(or rndis0 on Nexus 7/grouper)

Enable rndis:

setprop sys.usb.config rndis,adb

And the device usb0 will auto-configure and get an IP address from the DHCP running on the host.

We can confirm that everything is configured as expected by:

1. Checking that the device has acquired an IP address:

# adb -s $SERIAL shell ip addr show usb0
20: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 22:81:9e:70:e0:fb brd ff:ff:ff:ff:ff:ff
inet 192.168.124.132/24 brd 192.168.124.255 scope global usb0

2. That this IP address is registered against the DHCP:

$ cat /var/lib/misc/dnsmasq.usbbr0.leases
1374758220 22:81:9e:70:e0:fb 192.168.124.132 ubuntu-phablet *

3. And the exchange with the DHCP is recorded in syslog:

Jul 25 13:00:32 white dnsmasq-dhcp[916]: DHCPOFFER(usbbr0) 192.168.124.132 22:81:9e:70:e0:fb
Jul 25 13:00:32 white dnsmasq-dhcp[916]: DHCPREQUEST(usbbr0) 192.168.124.132 22:81:9e:70:e0:fb
Jul 25 13:00:32 white dnsmasq-dhcp[916]: DHCPACK(usbbr0) 192.168.124.132 22:81:9e:70:e0:fb ubuntu-phablet
Jul 25 13:00:32 white dnsmasq-dhcp[916]: DHCPREQUEST(usbbr0) 192.168.124.132 22:81:9e:70:e0:fb
Jul 25 13:00:32 white dnsmasq-dhcp[916]: DHCPACK(usbbr0) 192.168.124.132 22:81:9e:70:e0:fb ubuntu-phablet

That’s all for today. Volunteer requested to make these steps more robust and package it into phablet-tools.


Jean-Baptiste

Internet over USB on Ubuntu Touch devices

When testing touch devices it is necessary to interfere as little as possible with the device under tests. This is the case for network connections on Touch devices (Nexus phones and tablets for example) where the main connection to internet is via Wifi, and even more true if you want to test Wifi itself.

This article describes how to share the network connection of the host system and provide Internet to the Touch devices over USB.

Make sure your device is booted and connected to your PC via the USB cable. Then activate the usb connection on your device and bring in up.

 $ adb shell sh -c "setprop sys.usb.config rndis,adb"
 $ adb kill-server && adb start-server

On the device, ‘ip link’ should show the interface

root@ubuntu-phablet:/# ip link show
[...]
19: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000

On a Nexus 4 (mako) the interface is shown as usb0, while on a Nexus 7 (grouper) it is shown as rndis0.

Now, we have 1 connection to share and several devices connected to the PC, and we’ll want to bridge them together. Create a new bridge interface, and assign it an IP address:

$ sudo brctl addbr usbbr0
$ ifconfig usbbr0 192.168.124.1 netmask 255.255.255.0 up

This will be the end-point of the USB connection on the PC side, but not the end of the connection. All the trafic going through the bridge must be forwarded to the interface connected to internet on the PC. This is done with iptables on the host:

$ sudo iptables --table nat --append POSTROUTING --out-interface eth0 \
    -j MASQUERADE
$ sudo iptables --append FORWARD --in-interface usbbr0 -j ACCEPT
$ echo 1 >> sudo tee /proc/sys/net/ipv4/ip_forward

And finally we can glue eth0 and usb0 together by bringing up usb0 on the host and adding it to the bridge:

$ sudo ip link set usb0 up
$ sudo brctl addif usbbr0 usb0

We have connected all the wires:

  1. a usb network interface on the device,
  2. a usb network interface on the host,
  3. a bridge to share the physical interface of the host with USB network interfaces of several devices,
  4. iptables rules to forward trafic from the bridge to the physical network interface of the host

The last piece to complete the configuration is to assign an address to the network interface of the device. Remember that this setup is for testing, it means that several devices are connected to the same host, and we bring them up and down countless times a day. We’ll want a DHCP for IP address allocation and dnsmasq is a good candidate for this task. Start a dnsmasq instance that listen to the same network than the bridge interface:

$ sudo dnsmasq --strict-order --bind-interfaces \
    --pid-file=/var/run/touch/dnsmasq.pid --conf-file= \
    --listen-address 192.168.124.1 --dhcp-range 192.168.124.2,192.168.124.254 \
    --dhcp-lease-max=253 --dhcp-no-override --except-interface=lo \
    --interface=usbbr0 --dhcp-leasefile=/var/lib/misc/dnsmasq.usbbr0.leases \
    --dhcp-authoritative

(man dnsmasq for details on the command)

You should now be able to acquire an IP address on the device from the DHCP service running on the host:

$ adb shell dhclient usb0
19: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 32:5b:92:84:fc:22 brd ff:ff:ff:ff:ff:ff
inet 192.168.124.3/24 brd 192.168.124.255 scope global usb0

We can verify than the connection is working fine:

1. Ping the device end point from the device:

$ adb shell ping  192.168.124.3
 PING 192.168.124.3 (192.168.124.3) 56(84) bytes of data.
 64 bytes from 192.168.124.3: icmp_seq=1 ttl=64 time=0.030 ms

2. Ping the host end point from the device:

$ adb shell ping  192.168.124.1
 PING 192.168.124.1 (192.168.124.1) 56(84) bytes of data.
 64 bytes from 192.168.124.1: icmp_seq=1 ttl=64 time=0.305 ms

3. Ping an external address by name:

$ adb shell ping www.ubuntu.com
 PING www.ubuntu.com (91.189.90.58) 56(84) bytes of data.
 64 bytes from www-ubuntu-com.avocado.canonical.com (91.189.90.58): icmp_seq=1 ttl=51 time=34.3 ms

And to verify that we are not cheating by using the wireless card:

$ adb shell ip addr show wlan0
 13: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN qlen 100

It’s down!

What next? To add another device to the bridge, activate the usb network interface on the device and the host, add this interface (they are be named usb1, …, usbN) to the bridge and run dhclient on the device.

Executing all these steps automatically on startup and when a new device is connected is left as an exercise :)


Nicholas Skaggs

Ubuntu Edge: Convergence in the palm of your hand

Several years ago I was having a conversation with a bunch of colleagues of mine, most of whom would not be described as linux or ubuntu advocates. Seeing the launch of the tablet era with the iPad I lamented on having a truly portable pc in my pocket. We talked at length about the idea of a converged device. Within a few years we've seen android tablets ship (I was truly thrilled to see the transformer series come out) and phones like the atrix supporting webtop mode with ubuntu.

Still, even with a new android phone in my hand I want something a bit more. I don't enjoy carrying around heavy laptops, so a few years ago, I stopped when given the opportunity. I finally got rid of my old CRT from 1997 (yes, you read that right, RIP old friend) and got a nice widescreen display to replace it. But I'm still running the same tired old desktop, with my phone sitting next to it on the desk. It's certainly powerful enough to do everything I need, and if not, I've got a cloud server for long running computational tasks. So, why have the tower?

Why not carry my phone with me as my pc? Throw it on my desk and I can use my big screen, mouse and keyboard. At the train station I can use it with it's built in screen, but still have local and remote access to everything I need. Then perhaps while seated on the train I use it in something more akin to a traditional laptop since I have the room.

Well, this idea of a convergent device is here, and it's called ubuntu edge. A device that looks like a traditional phone but has pc-like specifications. It runs the same applications and OS as a computer. And it supports multiple form factors for interacting and using the applications. This idea of convergence is the biggest story for me.

So, Check out the campaign page on indiegogo. Watch the video that shows off the beautiful OS and applications we're building to go with the amazing hardware. That's right, "we" the community are building the applications. Now it's our chance as a community to help build an amazing piece of hardware and run them.
Nicholas Skaggs

Ubuntu Edge: Convergence in the palm of your hand

Several years ago I was having a conversation with a bunch of colleagues of mine, most of whom would not be described as linux or ubuntu advocates. Seeing the launch of the tablet era with the iPad I lamented on having a truly portable pc in my pocket. We talked at length about the idea of a converged device. Within a few years we've seen android tablets ship (I was truly thrilled to see the transformer series come out) and phones like the atrix supporting webtop mode with ubuntu.

Still, even with a new android phone in my hand I want something a bit more. I don't enjoy carrying around heavy laptops, so a few years ago, I stopped when given the opportunity. I finally got rid of my old CRT from 1997 (yes, you read that right, RIP old friend) and got a nice widescreen display to replace it. But I'm still running the same tired old desktop, with my phone sitting next to it on the desk. It's certainly powerful enough to do everything I need, and if not, I've got a cloud server for long running computational tasks. So, why have the tower?

Why not carry my phone with me as my pc? Throw it on my desk and I can use my big screen, mouse and keyboard. At the train station I can use it with it's built in screen, but still have local and remote access to everything I need. Then perhaps while seated on the train I use it in something more akin to a traditional laptop since I have the room.

Well, this idea of a convergent device is here, and it's called ubuntu edge. A device that looks like a traditional phone but has pc-like specifications. It runs the same applications and OS as a computer. And it supports multiple form factors for interacting and using the applications. This idea of convergence is the biggest story for me.

So, Check out the campaign page on indiegogo. Watch the video that shows off the beautiful OS and applications we're building to go with the amazing hardware. That's right, "we" the community are building the applications. Now it's our chance as a community to help build an amazing piece of hardware and run them.