<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:html="http://www.w3.org/1999/html" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Ross Burton</title><link>http://www.burtonini.com/blog</link><description>A potted account of Ross' life</description><language>en</language><ttl>60</ttl><dc:creator>Ross Burton</dc:creator><admin:generatorAgent rdf:resource="http://pyblosxom.sourceforge.net/"/><admin:errorReportsTo rdf:resource="mailto:ross@burtonini.com"/><item><title>20 Weeks</title><guid isPermaLink="false">life/bump-2008-05-27-10-30</guid><link>http://www.burtonini.com/blog/life/bump-2008-05-27-10-30</link><description>Over the last few weeks Vicky's previously invisible pregnancy has finally popped out. Much frustration ensued as this meant most ...</description><content:encoded><![CDATA[<p>
  Over the last few weeks Vicky's previously invisible pregnancy has finally
  popped out.  Much frustration ensued as this meant most of her clothes didn't
  fit any more, but that was soon relieved.
</p>
<p>
  <a class="noline" href="http://www.flickr.com/photos/rossburton/2526738845/" title="20 Weeks">
    <img class="thumbnail" src="http://farm4.static.flickr.com/3015/2526738845_3f5a4ec475_m.jpg" width="160" height="240" alt="20 Weeks" />
  </a>
</p>
]]></content:encoded><category domain="http://www.burtonini.com">/life</category><dc:date>2008-05-27T09:30:00Z</dc:date></item><item><title>Postr 0.12.1</title><guid isPermaLink="false">computers/postr/postr-2008-05-27-10-00</guid><link>http://www.burtonini.com/blog/computers/postr/postr-2008-05-27-10-00</link><description>I just made a quick Postr 0.12.1 release to fix authentication with non-trivial HTTP handler strings. If you can't login ...</description><content:encoded><![CDATA[<p>
  I just made a quick Postr 0.12.1 release to fix authentication with
  non-trivial HTTP handler strings.  If you can't login to Flickr with Postr,
  then this release <em>should</em> fix it for you.
</p>
<p>
  The <a href="http://burtonini.com/computing/postr-0.12.1.tar.gz">tarball is
    here</a>, and packages for Debian are being built now.
</p>
<p>
  In other news postr.dev has seen a lot of development and is looking pretty
  damn neat at the moment.
</p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers/postr</category><dc:date>2008-05-27T09:00:00Z</dc:date></item><item><title>GUPnP Bindings Generation</title><guid isPermaLink="false">computers/gupnp-binding-2008-05-23-16-40</guid><link>http://www.burtonini.com/blog/computers/gupnp-binding-2008-05-23-16-40</link><description>I've now finished the first draft of the bindings generation tool for GUPnP, which is now part of libgupnp itself. ...</description><content:encoded><![CDATA[<p>
  I've now finished the first draft of the bindings generation tool for GUPnP,
  which is now part of <tt>libgupnp</tt> itself.  I've added both blocking and
  non-blocking wrappers, so if you wanted to get the external IP there is the
  choice of this for blocking calls:
</p>
<pre>char *ip;
GetExternalIPAddress (proxy, &amp;ip, &amp;error);</pre>
<p>
  Or this for non-blocking calls:
</p>
<pre>static void
external_ip_cb (GUPnPServiceProxy *proxy, char * ip,
                GError *error, gpointer userdata)
{
  // ...
}
...
  GetExternalIPAddress_async (proxy, external_ip_cb, NULL);</pre>
<p>
  I've ported my test applications to use the bindings, which are available in
  <a href="http://burtonini.com/bzr/gupnp-demos">this Bazaar repository</a>.  It
  appears to work quite well, I just need to test it against all of the official
  service descriptions and add a few small features.
</p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-23T15:40:00Z</dc:date></item><item><title>GUPnP Autogeneration</title><guid isPermaLink="false">computers/upnp-gen-2008-05-22-16-25</guid><link>http://www.burtonini.com/blog/computers/upnp-gen-2008-05-22-16-25</link><description>The problem with GUPnP is that (like DBus) when programming from C you need to specify the types of each ...</description><content:encoded><![CDATA[<p>
  The problem with GUPnP is that (like DBus) when programming from C you need to
  specify the types of each argument when making a method call:
</p>
<pre>gupnp_service_proxy_send_action (proxy,
                                   "AddPortMapping", &amp;error,
                                   /* In arguments */
                                   "NewRemoteHost", G_TYPE_STRING, "",
                                   "NewExternalPort", G_TYPE_UINT, external_port,
                                   "NewProtocol", G_TYPE_STRING, "TCP",
                                   "NewInternalPort", G_TYPE_UINT, internal_port,
                                   "NewInternalClient", G_TYPE_STRING, internal_host,
                                   "NewEnabled", G_TYPE_BOOLEAN, TRUE,
                                   "NewPortMappingDescription", G_TYPE_STRING, desc,
                                   "NewLeaseDuration", G_TYPE_UINT, 0,
                                   NULL,
                                   /* Out arguments */
                                   NULL);</pre>
<p>
  Now, that really is quite tiresome.  It basically means that you need to have
  the service reference to hand when coding, because you need to know the name
  and type of each argument. Luckily for DBus part of <tt>dbus-glib</tt> is a
  binding tool which can create type-safe wrappers so that making method calls
  is much easier.  Wouldn't it be nice if there was something similar for GUPnP,
  which generated inline functions with prototypes like this:
</p>
<pre>static inline gboolean
AddPortMapping (GUPnPServiceProxy *proxy,
                char * in_NewRemoteHost,
                unsigned int in_NewExternalPort,
                char * in_NewProtocol,
                unsigned int in_NewInternalPort,
                char * in_NewInternalClient,
                gboolean in_NewEnabled,
                char * in_NewPortMappingDescription,
                unsigned int in_NewLeaseDuration,
                GError **error);</pre>
<p>
  Well, now there is.  I've put
  the <a href="http://burtonini.com/computing/gupnp-bind.py">initial code
  here</a> but will be moving this into GUPnP itself shortly.  The next task is
  to add asynchronous wrappers just as in dbus-glib, but that shouldn't be too
  hard.
</p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-22T15:25:00Z</dc:date></item><item><title>Anjuta+Poky Integration</title><guid isPermaLink="false">computers/anjuta-2008-05-20-17-40</guid><link>http://www.burtonini.com/blog/computers/anjuta-2008-05-20-17-40</link><description>Yesterday I tested and rolled a new release of the Poky integration plugin for Anjuta , created by our fearless ...</description><content:encoded><![CDATA[<p>
  Yesterday I tested and rolled a new release of
  the <a href="http://labs.o-hand.com/anjuta-poky-sdk-plugin/">Poky
    integration plugin for Anjuta</a>, created by our
  fearless <a href="http://www.robster.org.uk/">Sir Bradford</a>.  This is a
  very special piece of magic which lets you use a Poky SDK in Anjuta to
  cross-compile binaries without any pain, and will even deploy, execute and
  debug the binaries in a QEMU for testing. As part of the release process I
  had to test it, so I'll step through what I did as a brief tutorial on how
  to use Anjuta with Poky.
</p>
<p>
  The prerequisites are Anjuta, the Anjuta Poky SDK plugin, and QEMU.  These are
  all available for installation from
  our <a href="http://debian.o-hand.com">Debian repository</a> for Debian/Ubuntu
  users, everyone else will have to build from source, sorry!  You'll also need
  a Poky ARM SDK and QEMU ARM images from
  the <a href="http://pokylinux.org">Poky</a> web site.  The SDK is a tarball
  which contains a cross compiler with base libraries (glibc, GTK+, and so on)
  and should be extracted onto your machine (it extracts the SDK
  into <tt>/usr/local/poky</tt>).  The QEMU image consists of a kernel and
  a <tt>ext3</tt> file system which will boot Poky inside QEMU.
</p>
<p>
  To start I fetched a checkout
  of <a href="http://pimlico-project.org/tasks.html">Tasks</a> and loaded up
  Anjuta.  I don't have an existing Anjuta project for Tasks, so I used
  <cite>File &rarr; New &rarr; Project From Existing Sources</cite> to create a project using
  the checkout.  At this point I could do native development using
  <cite>Build &rarr; Run Configure</cite> and <cite>Build &rarr; Build
    Project</cite> to configure and compile the source, but we want to
  cross-compile.
</p>
<p>
  To activate cross compiling go to <cite>Edit &rarr; Preferences &rarr; General
    &rarr; Installed Plugins</cite> and enable the <cite>Poky SDK</cite> plugin.
  This will add a new page <cite>Poky SDK</cite> to the preferences dialog.
  We're using an external toolchain so set the SDK root
  to <tt>/usr/local/poky/eabi-glibc/arm</tt> and the toolchain triplet
  to <tt>arm-poky-linux-gnueabi</tt>.  We're also using QEMU instead of a real
  device so set the paths to the kernel and root filesystem (remembering to
  uncompress the filesystem).  We're now done configuring, so the preferences
  dialog can be closed.  However notice that if you switch from using a SDK to
  building with a full Poky tree you can use the cross-compiler it produces
  directly, and you can also use an external device instead of QEMU: the only
  requirement is that you can SSH into it.
</p>
<p>
  Now to do the build.  Use <cite>Build &rarr; Run Configure</cite> to configure
  Tasks, passing any extra options you want.  Note that if you want to debug
  your build in the future you'll need to enter <tt>CFLAGS=-g</tt> here to
  disable optimisation (autoconf sets <tt>-O2 -g</tt> by default, which isn't
  useful for debugging).  The configure script is then ran with the right
  environment and options for cross compiling, and with any luck will
  successfully configure.  Then hit <cite>Build &rarr; Build Project</cite> and
  watch the cross-compiler do its thing.  When that has worked, you can prove to
  yourself that the right thing has happened.
</p>
<pre>$ file tasks
  tasks: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, dynamically linked (uses shared libs), not stripped</pre>
<p>
  We have an ARM binary, ready for deployment.  Start the virtual machine
  with <cite>Tools &rarr; Start QEMU</cite> (this may ask for your root password
  to configure networking) and once it has booted you can install the project
  into the VM with <cite>Tools &rarr; Deploy</cite>.  This will run <tt>make
  install</tt> to a temporary directory and then rsync it to the VM.  Now you
  can either interact with the VM directly (if the application installed a new
  desktop file, then it should appear on the desktop), or use <cite>Tools &rarr;
  Run Remote</cite> to execute a binary directly: entering <tt>tasks</tt> will
  execute the freshly installed Tasks.  Neat, huh?
</p>
<p>
  For the final trick there is even GDB integration.  <cite>Tools &rarr; Debug
  Remote</cite> will let you specify a local binary (to extract debug symbols
  from, say <tt>src/gtk/tasks</tt>) and a remote binary to run, and then start a
  GDB on the VM and connect to it.  The binary will be initially running but
  paused at the entrypoint, so you can add breakpoints and
  then <tt>continue</tt> execution.
</p>
<p>
  Hopefully this post has been a good overview of the integration available
  between Poky and Anjuta.  In the future I hope to see Nemiver integrated into
  Anjuta, and gdbserver support in Nemiver, which would be a killer combination
  for Poky integration.
</p>
<p>
  <small>NP: <cite>One On Twoism</cite>, Various</small>
</p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-20T16:40:00Z</dc:date></item><item><title>Gypsy and Geoclue in Fedora</title><guid isPermaLink="false">computers/geo-2008-05-19-10-50</guid><link>http://www.burtonini.com/blog/computers/geo-2008-05-19-10-50</link><description>Thanks to Peter Robinson, both Gypsy and Geoclue are scheduled for addition to Fedora 9 Updates. Thanks Peter!</description><content:encoded><![CDATA[    <p>
      Thanks to Peter Robinson, both Gypsy and Geoclue are scheduled for
      addition to Fedora 9 Updates.  Thanks Peter!
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-19T09:50:00Z</dc:date></item><item><title>Ridicule</title><guid isPermaLink="false">life/metal-2008-05-15-13-40</guid><link>http://www.burtonini.com/blog/life/metal-2008-05-15-13-40</link><description>The problem for mainstream pop since the 70s is that metal has siphoned off many of the best freaks and ...</description><content:encoded><![CDATA[    <blockquote><p><q>
          The problem for mainstream pop since the 70s is that metal has
          siphoned off many of the best freaks and losers.
    </q></p></blockquote>
    <p>
      It's not often you read an article in the Guardian about Adam and The
      Ants, Finnish Battle Metal bands, and being "cool",
      but <a href="http://blogs.guardian.co.uk/music/2008/05/in_metal_ridicule_is_nothing_t.html">today
        I did</a>.
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/life</category><dc:date>2008-05-15T12:40:00Z</dc:date></item><item><title>Galaxy Dark</title><guid isPermaLink="false">life/chocolate-2008-05-14-12-06</guid><link>http://www.burtonini.com/blog/life/chocolate-2008-05-14-12-06</link><description>I got a free bar of the new Galaxy Dark with my shopping yesterday, which is basically a dark chocolate ...</description><content:encoded><![CDATA[    <p>
      I got a free bar of the new <cite>Galaxy Dark</cite> with my shopping
      yesterday, which is basically a dark chocolate (50%) version of a Galaxy
      bar.  Well, I say that, but...
    </p>
    <blockquote><p><q>
          The smooth Galaxy way to enjoy dark chocolate... deeply smooth,
          intensely delicious and not at all bitter.
    </q></p></blockquote>
    <p>
      This should be called <cite>Galaxy Fail</cite>.  It looks like dark
      chocolate but is pumped with sugar so it has a weird sickly sweet taste,
      nothing like the creamy taste of the original Galaxy.  I predict this
      product will be binned soon.
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/life</category><dc:date>2008-05-14T11:06:00Z</dc:date></item><item><title>Today's Second Geohack</title><guid isPermaLink="false">computers/geo-2008-05-13-15-15</guid><link>http://www.burtonini.com/blog/computers/geo-2008-05-13-15-15</link><description>I managed to wangle a Fire Eagle invitation this morning, so over lunch I grabbed the Python API Kit and ...</description><content:encoded><![CDATA[    <p>
      I managed to wangle a Fire Eagle invitation this morning, so over lunch I
      grabbed the Python API Kit and threw it at the sample Gypsy client.
    </p>
    <pre>$ ./gypsy-fireeagle.py 00:0B:0D:88:A4:A3
got 51.861145 0.156275
Updated FireEagle</pre>
    <p>
      The first line is me running my script (this one is 64 lines, but it is
      half whitespace), telling it where my GPS is.  The second line is the
      current position that my rather cheap and nasty GPS determined.  The third
      line tells me that Fire Eagle has been updated with those coordinates.
    </p>
    <p>
      Suffice to say I'm very impressed with Yahoo's geocoding software.  My GPS
      never settles to an accurate reading and will happily jitter around a 20
      metre wide circle for hours, but the location Fire Eagle is reporting me
      at is <em>two doors away</em>.  I'm not exaggerating: it says number 9 on
      my street when it should be number 5.  That is some incredibly accurate
      mapping they have.
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-13T14:15:00Z</dc:date></item><item><title>Today's Geohack</title><guid isPermaLink="false">computers/geo-2008-05-13-10-50</guid><link>http://www.burtonini.com/blog/computers/geo-2008-05-13-10-50</link><description>Following hot on the heels of Yahoo's announcement of their Internet Location Platform , I wrote a quick 20-line Python ...</description><content:encoded><![CDATA[    <p>
      Following hot on the heels of Yahoo's announcement of
      their <a href="http://developer.yahoo.com/geo/">Internet Location
      Platform</a>, I wrote a quick 20-line Python hack to convert from latitude and
      longitude to a place name.  Because the ILP doesn't yet expose the ability
      to go from a position to a <acronym title="Where On Earth
      ID">WOEID</acronym> we have to ask the Flickr web services to do this
      first (as Flickr is owned by Yahoo this is using the same backend).  Once
      we have the WOEID, it can be then be looked up on the ILP and useful
      information obtained.  Example speak more than words:
    </p>
    <pre>$ python geohack.py 
Using position 51.872330 0.161950
Got WOEID 12775
Got town Bishop's Stortford</pre>
    <p>
      Now to write a <a href="http://geoclue.freedesktop.org">GeoClue</a>
      provider which will fill in the locality information from the position.
      Long-term grand plans involve integrating all of this geo magic into
      Postr, somehow.
    </p>
    <p>
      <small>NP: <cite>Third</cite>, Portishead</small>
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-13T09:50:00Z</dc:date></item><item><title>Fire Eagle Invitation?</title><guid isPermaLink="false">computers/fireeagle-2008-05-12-21-50</guid><link>http://www.burtonini.com/blog/computers/fireeagle-2008-05-12-21-50</link><description>Does anyone out there on the Intarwebs work for Yahoo, or have a friend who works at Yahoo? I'd really ...</description><content:encoded><![CDATA[    <p>
      Does anyone out there on the Intarwebs work for Yahoo, or have a friend
      who works at Yahoo?  I'd really like to give
      this <a href="http://fireeagle.yahoo.net/">Fire Eagle</a> thing a go,
      specifically integrating <a href="http://gypsy.freedesktop.org/">Gypsy</a>
      and <a href="http://geoclue.freedesktop.org/">GeoClue</a> with Fire Eagle,
      but it's invitation only at the moment...
    </p>
    <p>
      <strong>Update: </strong> I now have an account!
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-12T20:50:00Z</dc:date></item><item><title>GUPnP Basics, Part 1</title><guid isPermaLink="false">computers/gupnp-basics-2008-05-12-12-50</guid><link>http://www.burtonini.com/blog/computers/gupnp-basics-2008-05-12-12-50</link><description>For the last few days I've been learning more about UPnP and testing it with the few devices I have ...</description><content:encoded><![CDATA[    <!-- -*- Mode: html -*- -->
    <p>
      For the last few days I've been learning more about UPnP and testing it
      with the few devices I have around the house.  One of these is a cheap
      ADSL router, which apparently has the lamest UPnP stack on in existence.
      It does however support the <cite>WAN IP Connection</cite> interface, so
      you can use UPnP to get the external IP address and manipulate the port
      mapping.  I'll skip over the horrific security violations this involves,
      because it's a useful demonstration that the majority of people will be
      able to test.
    </p>
    <p>
      Today we'll start simple and get our external IP address using GUPnP.  The
      first thing to be done is to create a <cite>Control Point</cite>, which in
      the UPnP model handles discovery of resources, be them devices or services
      (a device can have multiple services).  When creating a control point you
      can specify the URN of the resource you want to target.  In this case we
      want all services providing <cite>WANIPConnection</cite> so we'd
      use <tt>urn:schemas-upnp-org:service:WANIPConnection:1</tt>.  If you want
      to browse for all services then use <tt>ssdp:all</tt> (SSDP being the
      <cite>Simple Service Discovery Protocol</cite>).
    </p>
    <pre>static GMainLoop *main_loop;

int
main (int argc, char **argv)
{
  GError *error = NULL;
  GUPnPContext *context;
  GUPnPControlPoint *cp;
  
  /* libsoup requires threading, so we have to initialise it */
  g_thread_init (NULL);
  g_type_init ();

  /* Default GLib context, default host IP, default port */
  context = gupnp_context_new (NULL, NULL, 0, &amp;error);
  if (error) g_error (error->message);

  /* Create a control point targeting WAN IP Connection services */
  cp = gupnp_control_point_new
    (context, "urn:schemas-upnp-org:service:WANIPConnection:1");
  /* The service-proxy-available signal is emitted when any services which match
     our target are found */
  g_signal_connect (cp,
		    "service-proxy-available",
		    G_CALLBACK (service_proxy_available_cb),
		    NULL);
  
  /* Tell the control point to start searching */
  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);

  /* Enter the main loop */
  main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (main_loop);

  /* Clean up */
  g_main_loop_unref (main_loop);
  g_object_unref (cp);
  g_object_unref (context);
  
  return 0;
}

static void
service_proxy_available_cb (GUPnPControlPoint *cp,
                            GUPnPServiceProxy *proxy)
{
  /* ... */
}</pre>
    <p>
      Now we have an application which searches for the service we specified and
      calls <tt>service_proxy_available_cb</tt> for each one it found.  Now, to
      get the external IP address we need to invoke
      the <tt>GetExternalIPAddress</tt> action.  This action takes no in
      arguments, and has a single out argument called "NewExternalIPAddress".
      Yes, the naming scheme is <em>stupid</em>.  GUPnP has a set of methods to
      invoke actions -- which will be very familiar to anyone who has
      used <tt>dbus-glib</tt> -- where you pass a <tt>NULL</tt>-terminated varargs list
      of (name, type, value) tuples for the in arguments, then
      a <tt>NULL</tt>-terminated varargs list of (name, value, return location) tuples
      for the out arguments.  A simple implementation would be as follows.
    </p>
    <pre>static void
service_proxy_available_cb (GUPnPControlPoint *cp,
                            GUPnPServiceProxy *proxy)
{
  GError *error = NULL;
  char *ip = NULL;
  
  gupnp_service_proxy_send_action (proxy,
				   /* Action name and error location */
				   "GetExternalIPAddress", &amp;error,
				   /* IN args */
				   NULL,
				   /* OUT args */
				   "NewExternalIPAddress",
				   G_TYPE_STRING, &amp;ip,
				   NULL);
  
  if (error == NULL) {
    g_print ("External IP address is %s\n", ip);
    g_free (ip);
  } else {
    g_printerr ("Error: %s\n", error-&gt;message);
    g_error_free (error);
  }
  g_main_loop_quit (main_loop);
}</pre>
    <p>
      Note that <tt>_send_action</tt> blocks until the service has replied.  If you
      need to make non-blocking calls then
      use <tt>gupnp_service_proxy_begin_action</tt> which takes a callback.
    </p>
    <p>
      So, that is searching for services and invoking actions in GUPnP.  Next
      time I'll cover subscribing to state variables, and routers which can't
      count.
    </p>
    <p>
      <small>NP: <cite>Folk But Not Folk</cite>, Various</small>
    </p>
]]></content:encoded><category domain="http://www.burtonini.com">/computers</category><dc:date>2008-05-12T11:50:00Z</dc:date></item></channel></rss>