<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Spice World! &#187; Geek</title>
	<atom:link href="http://www.cyberspice.org.uk/blog/category/geek/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cyberspice.org.uk/blog</link>
	<description>The life and times of a jet setting software engineer!</description>
	<lastBuildDate>Fri, 23 Jul 2010 10:25:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using multiple private keys with SSH</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 10:13:39 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=459</guid>
		<description><![CDATA[A couple of days ago I posted on how to set up a subversion server with ssh access.  In that post, in the section about creating your private ssh key I said that if you already had an id_rsa or id_dsa file in your ~/.ssh directory not to go any further because the generation [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago I posted on how to set up a subversion server with ssh access.  In that post, in the section about creating your private ssh key I said that if you already had an <em>id_rsa</em> or <em>id_dsa</em> file in your ~/.ssh directory not to go any further because the generation of a new private key file could over write it.  This post explains how to cope with multiple private keys.</p>
<p>ssh uses <em>~/.ssh/identity</em> as the default filename for the private key when using version 1 of the ssh protocol and it uses <em>~/.ssh/id_rsa</em> and <em>~/.ssh/id_dsa</em> as the default filenames for the RSA and DSA private keys when using version 2 of the ssh protocol.  However there are several ways of changing this behaviour.</p>
<h2>Command line</h2>
<p>ssh allows you to provide a different identity/id file using the -i option on the ssh command line as follows:</p>
<pre>
$ ssh -i /path/to/id_rsa user@some.domain.org
</pre>
<p>Where <em>id_rsa</em> can be substituted with <em>id_dsa</em> or <em>identity</em>.</p>
<p>This is the simplest method.  And when used in conjunction with a subversion client you can create a [tunnel] in the subversion configuration file like so:</p>
<pre>
[general]
ssh = ssh -i /path/to/identity_file
</pre>
<p>If you want to support different identity/id files create a new [tunnel] &#8216;alias&#8217; for each identity file.  You can also use the -p option if you want to specify a different port at the same time.</p>
<h2>Config file &#8211; first method</h2>
<p>Another method is to use the ssh config file.  The global file is found in <em>/etc/ssh/config</em> however you can also provide config files on a per user basic in <em>~/.ssh</em>.  In the config file you can restrict declarations using the <strong>Host</strong> declaration.  Per the man page:</p>
<pre>
Host
   Restricts the following declarations (up to the next Host
   keyword) to be only for those hosts that match one of the
   patterns given after the keyword.  If more than one pattern
   is provided, they should be separated by whitespace.  A
   single `*' as a pattern can be used to provide global defaults
   for all hosts.  The host is the hostname argument given on
   the command line (i.e. the name is not converted to a
   canonicalized host name before matching).
</pre>
<p>The declaration <strong>IdentityFile</strong> allows you to specify the private key file that ssh should use.  By using <strong>Host</strong> and <strong>IdentityFile</strong> you can let ssh pick the identity/id file itself based upon the host name.  The following example will pick <em>~/.ssh/id_dsa</em> for any host other than <strong>my.specific.host.org</strong> and <strong>my.other.host.com</strong>.  In those cases the specified private key files are used.</p>
<pre>
# General settings
IdentityFile ~/.ssh/id_rsa
IdentifyFile ~/.ssh/id_dsa
IdentityFile ~/.ssh/identity

Host my.specific.host.org
IdentityFile ~/.ssh/my_specific_key_file

Host my.other.host.com
IdentityFile ~/.ssh/my_other_key_file
</pre>
<p>Note how the config file allows you to specify more than one file at once.  When you do ssh will try each of the files in turn or as appropriate.</p>
<h2>Config file &#8211; second method</h2>
<p>The problem with the above method is that you have to keep adding new entries to the config file for new hosts.  <strong>IdentityFile</strong> is actually very powerful and allows you to have wild cards in the path specification.  The full man page definition says:</p>
<pre>
IdentityFile
   Specifies a file from which the user's RSA or DSA
   authentication identity is read.  The default is ~/.ssh/identity
   for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa
   for protocol version 2. Additionally, any identities
   represented by the authentication agent will be used for
   authentication.

   The file name may use the tilde syntax to refer to a user's
   home directory or one of the following escape characters:
   `%d' (local user's home directory), `%u' (local user name),
    `%l' (local host name), `%h' (remote host name) or `%r'
   (remote user name).

   It is possible to have multiple identity files specified in
   configuration files; all these identities will be tried in
   sequence.
</pre>
<p>So I have set up my config file as below.  It basically tries ~/.ssh/idents/hostname/username/id_* first, then ~/.ssh/idents/hostname/id_*, then the defaults before giving up.</p>
<pre>
# SSH config file

IdentityFile ~/.ssh/idents/%h/%u/id_rsa
IdentityFile ~/.ssh/idents/%h/%u/id_dsa
IdentityFile ~/.ssh/idents/%h/id_rsa
IdentityFile ~/.ssh/idents/%h/id_dsa
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_dsa
</pre>
<p>This allows me to support a new server/key file combination just by putting the key file in the appropriate place in the <em>~/.ssh</em> without having to edit config files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/23/using-multiple-public-keys-with-ssh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up a subversion plus ssh server</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 14:46:47 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=453</guid>
		<description><![CDATA[As someone who is a strong advocate of source control at work I&#8217;m actually quite bad at following what I preach.  So this lunch time I decided to finally get around to setting up a Subversion server on my Linux server.  
Installation
I am currently running Ubuntu 9.10 so installed subversion as follows:

$ sudo [...]]]></description>
			<content:encoded><![CDATA[<p>As someone who is a strong advocate of source control at work I&#8217;m actually quite bad at following what I preach.  So this lunch time I decided to finally get around to setting up a Subversion server on my Linux server.  </p>
<h2>Installation</h2>
<p>I am currently running Ubuntu 9.10 so installed subversion as follows:</p>
<pre>
$ sudo apt-get install subversion
</pre>
<p>If you don&#8217;t have ssh installed (why not?) install it similarly.</p>
<h2>Users and groups</h2>
<p>Once you have subversion and ssh installed you can set up the SVN server.  Firstly you need to create a suitable users group, an admin user and a repository.</p>
<p>Create the group like so:</p>
<pre>
$ sudo groupadd -g 127 svnusers
</pre>
<p>The group id (127 above) needs to be unique so unless you know a free group id value check to see the last id used in  the groups file as follows:</p>
<pre>
$ tail /etc/group
</pre>
<p>Then create an SVN admin user using useradd as below:</p>
<pre>
$ sudo useradd -c "SVN Admin" -u 2000 -g 127 -d /home/svnadmin -m -s /bin/bash svnadmin
</pre>
<p>Again the user id (2000 above) needs to be unique.  This time look at /etc/passwd to find out the last id used.  The group id (127 above) should be the same value as the group you created.  The rest of the options tell <em>useradd</em> to  create a home directory and to set the default shell to be bash.</p>
<p>Set the password for the SVN admin user like so:</p>
<pre>
$ sudo passwd svnadmin
</pre>
<p>Finally add any other users to the <strong>svnusers</strong> group by editing /etc/group and adding the additional users in a comma separated list on the end.  For example:</p>
<pre>
svnusers:x:127:svnadmin,melanie
</pre>
<h2>Server setup</h2>
<p>Now its time to create a repository.  Firstly create the directory where all the repositories will be stored.  I put mine in /var since my /var is on separate partition (to protect from disk full issues).  However you can put them where you want.  So create the directory and set the permissions as below:</p>
<pre>
$ mkdir -p /path/to/subversion/repositories
$ chown -R root.svnusers /path/to/subversion/repositories
$ chmod -R 770 /path/to/subversion/repositories
</pre>
<p>When using ssh, <em>svnserve</em> is used as the SVN server.  <em>svnserve</em> requires the full path to repository to be provided by the client to access the repository.  You may not want to expose your file system that much so you can write a small script to modify the behaviour.  Use <em>which</em> to find out where <em>svnserve</em> is and rename it.</p>
<pre>
$ which svnserve
/usr/bin/svnserve
$ sudo mv /usr/bin/svnserve /usr/bin/svnserve.bin
</pre>
<p>Then using your favourite editor create the script below and save it under the old <em>svnserve</em> name.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>svnserve.bin <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>subversion<span style="color: #000000; font-weight: bold;">/</span>repositories <span style="color: #ff0000;">&quot;$@&quot;</span></pre></div></div>

<p>Finally set the execute permissions.</p>
<pre>
$ sudo chmod 755 /usr/bin/svnserve
</pre>
<h2>Creating a project</h2>
<p>Now its time to create a project.  Change to the <strong>svnadmin</strong> user and enter the password.</p>
<pre>
$ su - svnadmin
password:
</pre>
<p>Now create a project and turn off other access so that only members of the <strong>svnusers</strong> group and the admin user can access it.</p>
<pre>
$ svnadmin create /path/to/subversion/repositories/my_first_project
$ chmod -R o-rwx /path/to/subversion/repositories/my_first_project
</pre>
<p>Finally you need to configure the project&#8217;s access permissions by editing </p>
<pre>
/path/to/subversion/repositories/my_first_project/conf/svnserve.conf
</pre>
<p>In the <strong>[general]</strong> section uncomment or add:</p>
<pre>
anon-access = none
auth-access = write
</pre>
<p>Now save the file.  </p>
<h2>Testing</h2>
<p>Now you should be able to access the svn repository from anywhere provided the user is in the <strong>svnusers</strong> group.  Test as follows from a client.</p>
<pre>
$ svn list svn+ssh://user@some.domain.org/my_first_project
</pre>
<p>You will be asked for the ssh password for the machine running subversion.  And that&#8217;s it.  You should be able to use your project.  You can add new projects using the <strong>svnadmin</strong> user.</p>
<h2>Further tweaks</h2>
<p>There a couple of additional things you may want to do.  Firstly my subversion server is behind a firewall.  The machine it is on is accessed using ssh on a different port to the default.  Secondly keep being asked for the ssh password can become quite a pain.  Using public key authentication does make things somewhat easier.</p>
<h2>Using an alternative ssh port</h2>
<p>Annoyingly SVN does not understand the &#8216;username@domain:port&#8217; syntax.  It doesn&#8217;t know what to do with the port.  However you can use svn&#8217;s configuration files to create a custom &#8216;protocol&#8217;.  This allows you to add support for an alternative port through the configuration file.</p>
<p>You client user should have a file </p>
<pre>
~/.subversion/config
</pre>
<p>If not, create it.  In it there should be a <strong>[tunnels]</strong> section.  To that you can add a new &#8216;protocol&#8217;.  I created <strong>sshhome</strong> as follows:</p>
<pre>
[general]
sshhome = ssh -q -p 1234
</pre>
<p>The -q option prevents the &#8220;Killed by signal 15&#8243; message that you see with some versions of subversion.  You can then use <strong>sshhome</strong> instead of <strong>ssh</strong> as the protocol and it will use the specified port.  E.g.</p>
<pre>
$ svn list svn+sshhome://user@some.domain.org/my_first_project
</pre>
<h2>Public key authentication</h2>
<p>Finally to save having to enter your password all the time you can create a public key and install it on the server.  On the client change to the ~/.ssh directory.  Now if there&#8217;s already a file in it called <em>id_dsa</em> or <em>id_rsa</em> STOP.  I&#8217;m not sure how to support multiple keys yet and create a new key will over write these files.  If all is well create a set of keys as below.  Do not use an empty passphrase.  It&#8217;s also good security not to use your password as the passphrase.</p>
<pre>
$ ssh-keygen -t dsa -C "username@some.domain.org"
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/username/.ssh/id_dsa.
Your public key has been saved in /Users/username/.ssh/id_dsa.pub.
The key fingerprint is:
</pre>
<p>Now you need to put the public key on to the server.  Copy the file in to your home directory on the SVN server.  You can use <em>scp</em> for that.</p>
<pre>
$ scp id_dsa.pub username@some.domain.org:/path/to/home/directory/.ssh
</pre>
<p>Then log in to the SVN server and change to the ~/.ssh directory.  In that directory add the public key to the file of authorized keys and set the permissions.  Then delete the public key file.  See below:</p>
<pre>
$ cat id_dsa.pub  >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ rm id_dsa.pub
</pre>
<p>And that should be it.  Try listing your project directory again.  This time for the first time it will ask you for your password but then it will only ask for the password infrequently.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/20/setting-up-a-subversion-plus-ssh-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DPC 2010</title>
		<link>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 21:17:08 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[dpc10]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=451</guid>
		<description><![CDATA[A couple of weeks ago I went to the Dutch PHP Conference 2010 and I had an amazing time.  The event was held in Amsterdam at the RAI centre.  The primary sponsor was iBuildings and the entire event was organised by the totally awesome Lornajane.
When DPC 2010 announced the call for papers I [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I went to the Dutch PHP Conference 2010 and I had an amazing time.  The event was held in Amsterdam at the RAI centre.  The primary sponsor was <a href="http://www.ibuildings.nl/">iBuildings</a> and the entire event was organised by the totally awesome <a href="http://www.lornajane.net/">Lornajane</a>.</p>
<p>When DPC 2010 announced the call for papers I submitted both a proposal for a tutorial on PHP extensions and one for a talk on web services.  Both were excepted.  I had proposed both half day and full day versions of the tutorial the organisers chose the full day version.  This turned out to be a lot of work.  Basically I would be talking for 6 hours in four 90 minute slots.<br />
<span id="more-451"></span><br />
The web services talk was to be trailed at the PHP NW group in May.  Unfortunately being stuck in the US due to the Icelandic Volcano and its dust cloud didn&#8217;t give me much time to prepare for it.  However by the time of the group meeting I had a basic talk.  This meant I could devote the rest of the time up to DPC preparing the tutorial.</p>
<p>Since it is still early in my speaking career I don&#8217;t yet have the experience to accurately judge how long a talk will take.  I had never done a tutorial before so I had no experience to base it on.  In the end I came up with a plan where I had some &#8216;optional&#8217; sections which I could add on the end if I ran short.  It was scary to see how much content I required and took me several weeks to prepare in odd evenings.  In the end it came in at over 100 slides together with four example extensions.</p>
<p>I flew to Amsterdam courtesy of KLM&#8217;s direct flight from Leeds Bradford Airport to Schipol.  Since the hotel was right by Amsterdam Centraal train station it was a simple train ride from the airport and a short walk.  After meeting other attendees and speakers in the hotel foyer I headed up to my room to finish preparation for the Friday.  It turned out that I wasn&#8217;t by the station, my room was in a building <strong>over</strong> the station.  It straddled two platforms and a set of tracks.</p>
<p>The following morning I got up early and Lornajane helped me, and others, get to the conference venue.  I was extremely nervous.  This wasn&#8217;t helped by finding out that many of iBuilding&#8217;s own staff would be in my Extensions tutorial.  In the end the day went very quickly.  As usual when I&#8217;m nervous I spoke to quickly.  Luckily I could answer all questions and also had a chance to talk about some side projects.  I finished early so I turned the last session in to a workshop to any who wanted to try their hand at writing an extension.  I was very pleased at how well it had been received.</p>
<p>That evening a whole bunch of us were going to an Indonesian fusion restaurant.  Unfortunately due to our guide getting a little lost and my impractical shoes I arrived tired with sore feet.  The food was great but I wanted to get back to the hotel and sleep.  As I was still nervous about the talk the following day I didn&#8217;t sleep well.  I also had the dilemma of either being too warm or it being too noisy with the trains.</p>
<p>The following morning I woke very tired.  I met with some friends and fellow conference people at breakfast and we all headed off for the first of the two days of conference talks.  It was an awesome Friday keynote from <a href="http://www.two-sdg.demon.co.uk/curbralan/kevlin.html">Kevlin Henney</a>.  I had seen him speak before an PHP NW 2009 and he did not disappoint.  Following talks were equally impressive.  My slot was on after afternoon tea which is always hard work and by then I was tired out.  It was not a great talk.  Although fine for the PHP NW group meeting it was a little basic for an international conference.  I will know for next time.</p>
<p>That evening was the Speakers dinner which was thoroughly enjoyable.  I got to talk to Kevlin and others and since by then I had given all my content I could have a bit of a drink and not worry about having to make it the following morning although since the Saturday keynote was being given by <a href="http://shiflett.org/">Chris Shiflett</a> who I had also seen before and thoroughly enjoyed I was too late to bed so that I could be there on time to see him. </p>
<p>Sunday provided another day of great speakers and talks.  Thoroughly enjoyable.  Then the conference wound down.  Those of us who were staying the Saturday night headed off for pancakes.  Marcus and I got completely lost in Amsterdam due to confusing instructions from Ivo (it was the <em>wrong</em> social he was talking about) and eventually turned up about an hour later than everyone else.  However the pancakes were well worth it.  It was followed by some more drinking and then bed.</p>
<p>Since Lornajane and I live in the same city we were on the same KLM flight back from Amsterdam so we became travel partners.  Sunday was spent mostly hanging out in Amsterdam followed by an unstressed journey to the airport, a couple of beers waiting for our flight, and an uneventful flight home.</p>
<p>DPC 2010 was really good fun.  I learnt a lot, both from the talks and giving the tutorial and the talk.  I met many good friends and made lots of new ones.  Too many to have a check list here.  I&#8217;m now looking forward to my &#8216;home&#8217; conference, PHP NW 2010 in October.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/07/15/dpc-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DPC2010 &#8211; &#8220;PHP Extensions Tutorial&#8221; and &#8220;Web Services For Consumer Devices&#8221;</title>
		<link>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 10:20:42 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[dpc10]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=447</guid>
		<description><![CDATA[I am still at the Dutch PHP Conference and very enjoyable it is too.  I have now given my two talks.  The first was an all day session on writing PHP extensions in C.  The second was a regular 45 minute session on Web Services For Consumer Devices.
PHP Extensions
This tutorial covered writing [...]]]></description>
			<content:encoded><![CDATA[<p>I am still at the Dutch PHP Conference and very enjoyable it is too.  I have now given my two talks.  The first was an all day session on writing PHP extensions in C.  The second was a regular 45 minute session on Web Services For Consumer Devices.</p>
<h2>PHP Extensions</h2>
<p>This tutorial covered writing PHP extensions from the very beginning right through to writing objects and classes in C.  I think this went well.  Its a lot for beginners to cover so naturally some people got lost towards the end but I have had some good feedback.  Links to the slides and examples are below.</p>
<div style="margin-left: auto;margin-right: auto">
<table>
<tr>
<td><strong>Slides</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/PHPExtensions-Final-20100612.pdf">PHPExtensions-Final-20100612.pdf</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Hello World</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/hello_world-20100612.tgz">hello_world-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Hello World (Extended)</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/hello_world-20100612.tgz">hello_world_extended-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Example &#8211; Memory Stream</strong></td>
<td><a href="http://www.cyberspice.org.uk/downloads/ExtensionTutorial/hello_world-20100612.tgz">memory_stream-20100612.tgz</a></td>
</tr>
<tr>
<td><strong>Framegrab (PECL)</strong></td>
<td><a href="http://pecl.php.net/package/framegrab">http://pecl.php.net/package/framegrab</a></td>
</tr>
</table>
</div>
<h2>Web Services For Consumer Devices</h2>
<p>This talk covered what to consider when writing a service to be used by an application on a consumer devices.  I agree with the commenters who felt it was a little light.  Yes it needs revision before it gets reused.</p>
<p><a href="http://www.cyberspice.org.uk/downloads/ WebServicesForConsumerDevices-20100612.pdf">WebServicesForConsumerDevices-20100612.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/06/12/dpc2010-php-extensions-tutorial-and-web-services-for-consumer-devices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maker Faire UK 2010</title>
		<link>http://www.cyberspice.org.uk/blog/2010/04/22/maker-faire-uk-2010/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/04/22/maker-faire-uk-2010/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 01:14:33 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Crafty]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[Beads]]></category>
		<category><![CDATA[Knitting]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Maker]]></category>
		<category><![CDATA[Makerfaire]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=438</guid>
		<description><![CDATA[So in the middle of March I was panicking about whether I would get everything ready in time for Maker Faire UK.  Like last year Maker Faire UK was held at the Life Science&#8217;s Centre in Newcastle-upon-Tyne as part of the Science Week there.  Unlike last year, this year I had been accepted [...]]]></description>
			<content:encoded><![CDATA[<p>So in the middle of March I was panicking about whether I would get everything ready in time for Maker Faire UK.  Like last year Maker Faire UK was held at the Life Science&#8217;s Centre in Newcastle-upon-Tyne as part of the Science Week there.  Unlike last year, this year I had been accepted as an exhibitor and was going to display a variety of projects, so I took the Friday as vacation for final preparation and I needed it.<span id="more-438"></span></p>
<hr />
The theme of my exhibit was the mix of tech and craft.  Basically it was a collection of projects I had been working on and thought were good enough to display.</p>
<table>
<tr>
<td>
<h2>&#8216;Programmable&#8217; Earrings</h2>
<p><span style="float: left; margin-top: 10px; margin-right: 10px; margin-bottom: 10px;"><a href="http://www.flickr.com/photos/39013214@N03/4406446524" title="View 'Programmable earrings' on Flickr.com"><img border="0" width="240" align="right" alt="Programmable earrings" src="http://farm5.static.flickr.com/4022/4406446524_0813f246dc_m.jpg" height="160"/></a></span></p>
<p>Recently I started doing bead work, making necklaces and earrings and so on.  One day when doing some electronics I realised that components would make awesome earrings.  I then thought if you&#8217;re using components why not make them actually do something.  So I prototyped up a design based around an ATTiny part that I thought would work and thought about scaling the design down to something that could actually be worn on the ears.</p>
<p>This turned out to be a bit of a learning curve.  The only way I could do it was to resort to surface mount.  Something I had never done before.  Also I needed to product the PCBs professionally for the project to have any chance of working.  Also something I had never done before.  So this required me to learn to use a PCB CAD package.  Yet more learning curve.  And to add to the pressure because of the turn-round time on the PCBs I had one chance to get it right.  I waited with baited breath for them to return from <a href="http://www.olimex.com/pcb/index.html">Olimex</a>.</p>
<p>There were two issues with the board.  The holes for the LED leads were too narrow.  I fixed that with a pillar drill.  Also the outline for the battery (which is mounted on the bottom of the board) was printed on the top of the board.  That was my mistake since I created the batter holder component in the CAD package.  I fixed that with judicious use of a craft knife to scrape away the print.  I soldered everything up, programmed the micro-controller, and they worked.</p>
<p>They are light and wearable.  The software carries out PWM on three RGB channels varying the colour of the LED.  The colour pattern and speed of flashing changes with light level.  The size is limited by the clearance of the LED and LDR leads and the battery.  They were very popular and I may have to make more due to interest.</p>
</td>
</tr>
<tr>
<td>
<h2>Knitted Cthulhu</h2>
<p><span style="float: right; margin-top: 10px; margin-left: 10px; margin-bottom: 10px;"><a href="http://www.flickr.com/photos/39013214@N03/4403933882" title="View 'Cthulhu' on Flickr.com"><img border="0" width="240" alt="Cthulhu" src="http://farm5.static.flickr.com/4034/4403933882_f3f37fbf86_m.jpg" height="160"/></a></span></p>
<p>This was a fun little project.  I found a pattern for a knitted Cthulhu on the web.  Unfortunately I&#8217;ve mislaid the link right now but I do want to acknowledge the author so when I&#8217;ve found it I will update this post.  The knit was fun in itself and included knitting in the round, adding and removing stitches, and i-cord. </p>
<p>However because I am me I wanted to stuff electronics in to it.  So rather than using beads for eyes I used LEDs.  I built a small circuit on strip board based around the ATTiny part which drove the two LEDs and used a mechanical tilt switch as an input.  Additional output was via a piezo-electric sounder.  The tilt switch was mounted upside down so that it was normally off.  However shaking the cthulhu would activate it.</p>
<p>A software algorithm carried out key de-bounce and counts the number of &#8217;shakes&#8217; within a set time and drives a state machine that flashes the eyes and makes noises dependent upon the speed of the shaking.  The children loved my cthulhu.</p>
</td>
</tr>
<tr>
<td>
<h2>Beebthernet</h2>
<p><span style="float: left; margin-top: 10px; margin-right: 10px; margin-bottom: 10px;"><a href="http://www.flickr.com/photos/39013214@N03/4403934984" title="View 'Beebthernet' on Flickr.com"><img border="0" width="240" align="right" alt="Beebthernet" src="http://farm5.static.flickr.com/4042/4403934984_3221138977_m.jpg" height="160"/></a></span></p>
<p>A while I go i wrote a blog post about my <a href="http://www.cyberspice.org.uk/blog/2009/09/03/beebthernet/">Beebthernet</a> project.  Well since I was getting PCBs made anyway I thought I&#8217;d use the space space available to get a PCB for the parallel port/SPI version of the Beebthernet circuit.</p>
<p>I was hoping to have written a twitter client in time for Makefaire but all I&#8217;d gotten was basic sockets working.  However having a stand with a BBC Microcomputer connected to a flat screen monitor and a network was interesting to many people who attended the fair.  In many cases parents would tell their children how the BBC micro was the computer they used at school.</p>
</td>
</tr>
<tr>
<td>
<h2>Temperature Sensing Hat</h2>
<p><span style="float: right; margin-top: 10px; margin-left: 10px; margin-bottom: 10px;"><a href="http://www.flickr.com/photos/39013214@N03/4405682295" title="View 'Work in progress - Temperature sensing hat' on Flickr.com"><img border="0" width="240" align="left" alt="Work in progress - Temperature sensing hat" src="http://farm3.static.flickr.com/2712/4405682295_cfa4df6fa4_m.jpg" height="160"/></a></span></p>
<p>This project turned out to be a work in progress so I took it anyway together with some tools in order to continue to work on the electronics.  The hat itself is based upon a design in <a href="http://www.amazon.com/Stitch-N-Bitch-Knitters-Handbook/dp/0761128182">Stitch &#8216;N Bitch</a> which is an excellent book.  It is the sequinned hat but without sequins however unlike the hat in the book mine has a long i-cord &#8216;tail&#8217; from the top of the hat than hangs down the back.  The tail houses a temperature sensor in the end. </p>
<p>The rest of the hat is intended to be covered in small LED beads but they were not finished for Makerfaire.  The beads are an idea from <a href="http://thehighlowtech.com/projects/LED_clothing/tank.html">Leah Buechley</a> and are constructed from a surface mount LED and two beading crimp rings solder to each terminal.  I chose gold and silver rings so that I could tell the polarity.  They are awfully small and fiddly to make.</p>
</td>
</tr>
</table>
<hr />
<div  style="display:block">
My exhibits seemed to go down well with the public.  I ended up being <a href="http://www.flickr.com/photos/37996583811@N01/4444428820/in/photostream/">interviewed by the BBC</a> for their <a href="http://www.bbc.co.uk/blogs/podsandblogs/">Pods and Blogs</a> show on Radio 5 Live.  And then I was filmed by the reporter&#8217;s colleague for a YouTube project.</p>
<p><center><object width="445" height="364"><param name="movie" value="http://www.youtube.com/v/d9gRklnJqjE&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x402061&#038;color2=0x9461ca&#038;border=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/d9gRklnJqjE&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x402061&#038;color2=0x9461ca&#038;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"></embed></object></center></p>
<p>I have to admit I don&#8217;t look my best since I was stressed and this was early on the Saturday not long after the faire opened and I hod gotten up early that morning to drive up to the event and set up my things.</p>
<p>The faire was very enjoyable and it would be great to be back there again next year.  Hopefully I would be more organised this time.  There were people I knew there but many more I didn&#8217;t and I made some new friends among the exhibitors.  I would like to thank Molly and Kat who were my support team and who took over talking to the public when I needed a break, food, etc.  I did get a chance to look around the faire and I have to admit the stars of the show were the musical tesla coils they were both awesome and loud!</p>
<div style="text-align:center;"><a href="http://www.flickr.com/photos/39013214@N03/4435866764" title="View 'Musical Tesla Coils' on Flickr.com"><img border="0" width="500" alt="Musical Tesla Coils" src="http://farm5.static.flickr.com/4040/4435866764_82030f986e.jpg" height="333"/></a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/04/22/maker-faire-uk-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DPC &#8211; Dutch PHP Conference 2010</title>
		<link>http://www.cyberspice.org.uk/blog/2010/04/22/dpc-dutch-php-conference-2010/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/04/22/dpc-dutch-php-conference-2010/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 23:45:12 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Women In Technology]]></category>
		<category><![CDATA[Amsterdam]]></category>
		<category><![CDATA[DPC]]></category>
		<category><![CDATA[LinkedIn]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=436</guid>
		<description><![CDATA[Rather belatedly I am delighted to announce that I have been accepted to speak at the Dutch PHP Conference in Amsterdam this June.  DPC is the premier European PHP conference and is sponsored by iBuildings.
I will be running a tutorial Writing a PHP extension in C and speaking about Web Sevices for Consumer Devices. [...]]]></description>
			<content:encoded><![CDATA[<p>Rather belatedly I am delighted to announce that I have been accepted to speak at the Dutch PHP Conference in Amsterdam this June.  <a href="http://phpconference.nl/">DPC</a> is the premier European PHP conference and is sponsored by <a href="http://www.ibuildings.com/">iBuildings</a>.</p>
<p>I will be running a tutorial <a href="http://joind.in/talk/view/1523">Writing a PHP extension in C</a> and speaking about <a href="http://joind.in/talk/view/1546">Web Sevices for Consumer Devices</a>.  I look forward to seeing you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/04/22/dpc-dutch-php-conference-2010/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Capturing still images from video devices in PHP using Framegrab</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 16:10:34 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Framegrab]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=433</guid>
		<description><![CDATA[I found I had a need to capture and process still video images from video devices using PHP so I wrote the Framegrab PECL extension.  This post introduces the basics of Framegrab.

The framegrab extension is currently only available for Linux although Windows and OS X support will be coming soon.  On Linux the [...]]]></description>
			<content:encoded><![CDATA[<p>I found I had a need to capture and process still video images from video devices using PHP so I wrote the Framegrab PECL extension.  This post introduces the basics of Framegrab.<br />
<span id="more-433"></span><br />
The framegrab extension is currently only available for Linux although Windows and OS X support will be coming soon.  On Linux the extension uses the Video For Linux API version 2.</p>
<p>Framegrab adds two classes to PHP.  <em>FrameGrabDevice</em> represents a video capture device and <em>FrameGrabImage</em> an image captured with a FrameGrabDevice.     </p>
<p>You can create a new <em>FrameGrabDevice</em> for the default video capture device as follows:</p>
<pre>
	$device = new FrameGrabDevice();
</pre>
<p>The extension will iterate through available video devices until it finds one that supports video capture.  A <em>FrameGrabDeviceException</em> will be thrown either if no video devices are available or if the available video devices do not support video capture.</p>
<p>You can supply an argument to the constructor (see below) if you want to initialise a specific video device.  In this case the <em>FrameGrabDeviceException</em> will be thrown if that specific device does not exist or does not support video capture.</p>
<pre>
	$device = new FrameGrabDevice('/dev/video1');
</pre>
<p>Once you have a device you can then grab an image using the <em>grab()</em> method.  The method takes no arguments and returns a <em>FrameGrabImage</em> object or false on error.  As the <em>FrameGrabImage</em> constructor is a protected method you cannot create objects directly using new.</p>
<p>Once you have the image you can either save the image to the file in PNG format or have it returned as a string in PNG format using the writeAsPNG() and toStringAsPNG() methods respectively.  The former takes a filename as the sole argument and returns false on error.  The latter takes no arguments and returns either the PNG data as a string or false on error.</p>
<p>The two objects also support a number of properties.  The code below demonstrates the extension in use.  It returns an image captured from the default video device as a PNG.  The image has capture device and image meta data embedded in it visible in the top left corner of the image.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
try <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Get the default frame grabber device.  Throws an exception if a device</span>
	<span style="color: #666666; font-style: italic;">// cannot be found.</span>
	<span style="color: #000088;">$device</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FrameGrabDevice<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Grab am image.</span>
	<span style="color: #000088;">$fgimage</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">grab</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fgimage</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Create a GD image from a frame grab image</span>
		<span style="color: #000088;">$gdimage</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecreatefromstring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toStringAsPNG</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Output data about the image on to the image</span>
		<span style="color: #000088;">$font</span>  <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$black</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecolorallocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$fh</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">imagefontheight</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$font</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$x</span>     <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span>     <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Device: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">device</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Card: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$device</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">card</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Width: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">width</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Height: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">height</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Format: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$y</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$fh</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagestring</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Bytes per line: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$fgimage</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bytes_per_line</span><span style="color: #339933;">,</span> <span style="color: #000088;">$black</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Output the image</span>
		<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: image/png'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagepng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">imagedestroy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$gdimage</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Handle the FrameGrabDevice exception here.</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The extension is available <a href="http://pecl.php.net/package/framegrab">at the PECL site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/28/capturing-still-images-from-video-devices-in-php-using-framegrab/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Serial IO in PHP using the DIO extension</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 16:36:03 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[DIO]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=429</guid>
		<description><![CDATA[DIO is the Direct IO extension for PHP.  I recently took over maintaining this extension and have implemented comprehensive stream support for both POSIX and Windows systems.  To demonstrate the use of DIO this post will describe a PHP script that sends an SMS using a USB 3G modem.

To make control of modems [...]]]></description>
			<content:encoded><![CDATA[<p>DIO is the Direct IO extension for PHP.  I recently took over maintaining this extension and have implemented comprehensive stream support for both POSIX and Windows systems.  To demonstrate the use of DIO this post will describe a PHP script that sends an SMS using a USB 3G modem.<br />
<span id="more-429"></span></p>
<p>To make control of modems easier over twenty years ago the Hayes Corporation developed a serial command protocol, the Hayes or AT command set.  Many other modems adopted the protocol and now its a de-facto standard.  Over the years as modem functionality expanded so did the command set.  Now it supports FAX, cell phone address books, SMSes and so on.  The AT command set comprises a set of text based commands terminated with CRLF.  The responses are similarly text strings terminated with CRLF.  Typically the modem responds with &#8220;OK&#8221;, &#8220;ERROR&#8221; or a setting value.</p>
<p>DIO currently provides two stream types <em>raw</em> and <em>serial</em>.  Raw streams provide low level access to operating system devices.  Serial streams provide access to, and abstract, serial ports.  DIO stream support is accessed just like any other PHP streams.  The appropriate URI is <a href="http://uk2.php.net/manual/en/function.fopen.php">fopen</a>ed.  The relevant URIs are:</p>
<pre>
dio.raw://[device]
</pre>
<p>for raw streams and</p>
<pre>
dio.serial://[device]
</pre>
<p>for serials streams.  In both cases [device] is the device name to open.  For example this could be /dev/random for the random device on Linux; or /dev/ttyS0 for a comms port on Linux; or COM1 for a comms port on Windows.  We&#8217;ll be using the later form of the URI as we&#8217;re opening a serial port.  </p>
<p>The example code opens the serial port as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dio.serial:///dev/tty.ZTEUSBATPort_&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first argument is the device to open.  In this case a serial port to the USB 3G modem connected to my MacBook.  The second is the open mode, in this case read/write.  The third is an optional argument that comprises a flag that indicates whether to search the include path for the file to open.  We don&#8217;t want this.  The final optional argument is a stream context which is a collection of stream specific additional parameters.</p>
<p>A stream context is created using <a href="http://uk2.php.net/manual/en/function.stream-context-create.php">stream_context_create</a>().  The code in the example that creates the context, prior to opening the port, is shown below.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">9600</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'flow_control'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'is_blocking'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first four context options are pretty obvious.  The serial port is being configured for 9600 bits per second, 8 bits per byte with 1 additional stop bit per byte and no parity checking.</p>
<p>The next option disables hardware flow control.  Serial ports are relatively slow so they often have hardware control lines which indicate when there is data ready to be sent and space in the buffer ready to receive data.  My USB modem does not have these so the hardware flow control is disabled.</p>
<p>Next we turn off blocking.  With blocking function calls the operating system waits for data and only returns when it is ready to return the data that was requested i.e. the operating system blocks on the data.  Non-blocking function calls return whether there is data or not.  The POSIX open call also blocks on the state of the Data Carrier Detect (&#8220;DCD&#8221;) hardware control line.  Some modems have this control line and use it to indicate there&#8217;s a carrier signal on the telephone line.  Again since the USB modem does not have this we disable it.</p>
<p>Finally we enable canonical mode.  Canonical IO on POSIX means that the serial port driver will wait for a line of text ending in a newline (or the internal buffer being full) before returning.  If less characters than were entered on the line were requested the driver buffers the data for subsequent reads until the entire line is returned.  In canonical mode you can actually connect a terminal to the serial port as line editing is supported.  Since Windows does not have a canonical mode DIO provides an implementation on top of the Windows driver.  The alternative to canonical mode is byte mode where by DIO waits until the requested number of bytes have been read and returns regardless of whether there are more bytes available.</p>
<p>If all that sounds a little complicated think of it like this.  If you&#8217;re reading strings terminated with a new line use canonical mode otherwise use byte mode.</p>
<p>Remember that blocking was disabled so that opening the serial device did not block.  This isn&#8217;t desirable when actually reading data.  Blocking mode can be re-enabled on an open stream using <a href="http://uk2.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking</a> as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">stream_set_blocking</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Once the serial port has been opened with the appropriate port settings and blocking re-enabled the port can be written and read using the standard <a href="http://uk2.php.net/manual/en/function.fprintf.php">fprintf</a> and <a href="http://uk2.php.net/manual/en/function.fgets.php">fgets</a> PHP functions.</p>
<p>There are two AT commands related to sending an SMS.  The first is &#8220;AT+CMGF=1&#8243; which tells the modem to operate in SMS text mode.  This should respond with &#8220;OK&#8221;.  The second is &#8220;AT+CMGS=&#8221; which is followed by a string comprising a telephone number.  This accepts the text of an SMS which is sent when CTRL-Z is entered.  </p>
<p>There&#8217;s a little bit of additional work in the example as the modem echos data sent to it back to the sender so the PHP code consumes data after a command is sent until it sees the sent command echoed back.  The full example follows.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
&nbsp;
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PHONE_NUMBER'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'5551234'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SMS_TEXT'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Hello world!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Sends data to the modem
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt; <span style="color: #006699; font-weight: bold;">$string</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$string</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Reads lines from the serial port.  It reads until a non blank line is
 * received then returns it.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> get_string<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// remove carriage returns, line feeds and excess white space</span>
		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$response</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Waits for OK to be sent back by the modem.
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> get_string<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&gt; <span style="color: #006699; font-weight: bold;">$response</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;OK&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// MAIN CODE</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create the context</span>
<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">9600</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		  <span style="color: #0000ff;">'flow_control'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'is_blocking'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
		  <span style="color: #0000ff;">'canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Open the port</span>
<span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dio.serial:///dev/tty.ZTEUSBATPort_&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Re-enable blocking</span>
	<span style="color: #990000;">stream_set_blocking</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Set SMS text entry mode</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;AT+CMGF=1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Send an SMS</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;AT+CMGS=<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">.</span> PHONE_NUMBER <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	send_data<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> SMS_TEXT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// Send CTRL-Z to end SMS text entry</span>
	<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span> <span style="color: #990000;">chr</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">26</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	
	wait_for_ok<span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Close the port</span>
	<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP DIO Extension: Looking for beta testers</title>
		<link>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 19:58:20 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[DIO]]></category>
		<category><![CDATA[PECL]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=424</guid>
		<description><![CDATA[A few months ago I had a need to do some serial IO from PHP.  After asking around I found out there was a PHP extension for this but it was unmaintained, unowned and out of date.  To cut a long story short I ended up as the maintainer of said extension and [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago I had a need to do some serial IO from PHP.  After asking around I found out there was a PHP extension for this but it was unmaintained, unowned and out of date.  To cut a long story short I ended up as the maintainer of said extension and since them I have been fixing and extending it.</p>
<p>The original DIO API is very basic and POSIX oriented.  Serial support is not very configurable and doesn&#8217;t work at all on Window platforms.  So I have been working on implementing PHP stream extensions that allow you to do raw and serial IO via streams.  Anyway its ready for testing by people other than me on POSIX (Linux, OS X etc) and Windows platforms so I&#8217;m looking for beta testers.</p>
<p><span id="more-424"></span></p>
<h2>Where to get it</h2>
<p>The release candidate is downloadable as a package from:</p>
<p><a href="http://www.cyberspice.org.uk/downloads/dio-0.0.4rc3.tgz">http://www.cyberspice.org.uk/downloads/dio-0.0.4rc3.tgz</a></p>
<p>And directly from SVN at:</p>
<p><a href="http://svn.php.net/repository/pecl/dio/tags/RELEASE_0_0_4RC3">http://svn.php.net/repository/pecl/dio/tags/RELEASE_0_0_4RC3</a></p>
<h2>Documentation</h2>
<p>While I write proper PHP documentation below is a brief over view of how you use DIO.</p>
<h3>Streams</h3>
<p>DIO streams are just PHP streams.  You use <a href="http://www.php.net/manual/en/function.fopen.php">fopen()</a> to open them and <a href="http://www.php.net/manual/en/function.fread.php">fread()</a>, <a href="http://www.php.net/manual/en/function.fwrite.php">fwrite()</a>, <a href="http://www.php.net/manual/en/function.fgets.php">fgets()</a>, <a href="http://www.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking()</a> etc. There are two DIO streams, dio.raw and dio.serial.  </p>
<p>dio.raw is as it sounds, raw streams.  It uses the low level OS streams such as open(), read(), write(), close() etc. on POSIX and CreateFile(), OpenFile(), ReadFile(), WriteFile(), CloseFile() on Windows.  It does not buffer except the internal PHP buffering.</p>
<p>dio.serial is full serial support.  It allows setting of data rates, data size, stop bits, handshaking and raw/canonical modes etc.</p>
<p>Both stream types support timeouts and blocking/non-blocking use.</p>
<h3>Example code</h3>
<p>Below is a small example that opens a serial port, configuring it with a stream context, and then reads and writes from it before closing it.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
	<span style="color: #666666; font-style: italic;">// Create a stream context that configures the serial port</span>
	<span style="color: #666666; font-style: italic;">// And enables canonical input.</span>
	<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">stream_context_create</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dio'</span> <span style="color: #339933;">=&gt;</span> 
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'data_rate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">115200</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'data_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'stop_bits'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'parity'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> 
		      <span style="color: #0000ff;">'is_canonical'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Are we POSIX or Windows?  POSIX platforms do not have a</span>
	<span style="color: #666666; font-style: italic;">// Standard port naming scheme so it could be /dev/ttyUSB0</span>
	<span style="color: #666666; font-style: italic;">// or some long /dev/tty.serial_port_name_thingy on OSX.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PATH_SEPARATOR <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;dio.serial:///dev/ttyS0&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;dio.serial://COM1&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Open the stream for read only and use it.</span>
	<span style="color: #000088;">$f</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r+&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Writing to port...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">fprintf</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;Hello world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Reading from port...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$f</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<h3>Stream context</h3>
<p>DIO uses the stream context to obtain the port configuration settings.  There are settings which are common to all DIO streams and settings which are sub-stream specific.  The common settings are:</p>
<style type="text/css">
th,td { text-align:left; vertical-align:top; }
</style>
<table style="width: 600px; margin: 0 auto">
<tr>
<th>perms</th>
<td>Integer</td>
<td>Sets the file permissions mask when creating a file (POSIX specific, ignored on Windows)</td>
</tr>
<tr>
<th>is_blocking</th>
<td>Boolean</td>
<td>Indicates whether the stream is blocking (true, default) or non blocking (false)</td>
</tr>
<tr>
<th>timeout_secs</th>
<td>Integer</td>
<td>The time to wait for input in seconds before returning.  Also sets the stream non blocking.</td>
</tr>
<tr>
<th>timeout_usecs</th>
<td>Integer</td>
<td>The time to wait for input in micro seconds before returning.  Used in conjunction with timeout_secs.  If omitted but timeout_secs is defined it is assumed to be zero.</td>
</tr>
</table>
<p>Both the blocking setting and the timeout settings can changed after the stream is open using the PHP functions <a href="http://www.php.net/manual/en/function.stream-set-blocking.php">stream_set_blocking()</a> and <a href="http://www.php.net/manual/en/function.stream-set-timeout.php">stream_set_timeout()</a> respectively.</p>
<p>The serial stream has the following additional configuration settings.</p>
<table style="width: 600px; margin: 0 auto">
<tr>
<th>data_rate</th>
<td>Integer</td>
<td>Sets the data rate in bits per second (Not BAUD.  BAUD is symbols per second.  A symbol may include more than one bit)</td>
</tr>
<tr>
<th>data_bits</th>
<td>Integer</td>
<td>Number of bits per byte.  Typically 5, 6, 7 or 8 (default).</td>
</tr>
<tr>
<th>stop_bits</th>
<td>Integer</td>
<td>The number of stop bits. 1 (default), 2 or 3 (1.5 stop bits)</td>
</tr>
<tr>
<th>parity</th>
<td>Integer</td>
<td>The parity checking.  0 (None, default), 1 (Odd), 2 (Even).</td>
</tr>
<tr>
<th>flow_control</th>
<td>Boolean</td>
<td>Enables/disables hardware flow control</td>
</tr>
<tr>
<th>is_canonical</th>
<td>Boolean</td>
<td>Enables canonical input mode.  Canonical input buffers the input until either internal buffer is full or an end of line has been received.  So a read in canonical mode will block until an end of line or file even if more than the requested characters have been read from the remote machine.  </p>
<p>Full canonical mode handles control characters, delete, echoing characters back to the remote machine and so on.  Its basically used to implement a terminal.  DIO doesn&#8217;t have any of the latter other than the buffering. Yet!</td>
</tr>
</table>
<h3>Finally</h3>
<p>So there you are.  Any results, good or bad, are useful.  DIO has error checking and will return useful warnings if you try and feed it silly values.  Logs, PHP versions, etc. would be useful diagnosing issues.  Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/02/02/php-dio-extension-looking-for-beta-testers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Manchester Geek Girl Afternoon Tea</title>
		<link>http://www.cyberspice.org.uk/blog/2010/01/11/manchester-geek-girl-afternoon-tea/</link>
		<comments>http://www.cyberspice.org.uk/blog/2010/01/11/manchester-geek-girl-afternoon-tea/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 17:24:41 +0000</pubDate>
		<dc:creator>cyberspice</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Women In Technology]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[mggd]]></category>
		<category><![CDATA[mggt]]></category>

		<guid isPermaLink="false">http://www.cyberspice.org.uk/blog/?p=418</guid>
		<description><![CDATA[While I&#8217;m announcing appearances I am excited to announce that I am presenting an Arduino workshop at Manchester Geek Girl Afternoon Tea this month at Madlab, Manchester&#8217;s Hackspace in the Northern Quarter.
I will be bringing a long several Arduino-a-likes together with a variety of components and CDs of the IDE so that we can get [...]]]></description>
			<content:encoded><![CDATA[<p>While I&#8217;m announcing appearances I am excited to announce that I am presenting an <a href="http://www.arduino.cc/">Arduino</a> workshop at <a href="http://girlgeektea.eventbrite.com/">Manchester Geek Girl Afternoon Tea</a> this month at <a href="http://madlab.org.uk/content/girl-geek-afternoon-tea-2/">Madlab</a>, Manchester&#8217;s Hackspace in the Northern Quarter.</p>
<p>I will be bringing a long several Arduino-a-likes together with a variety of components and CDs of the IDE so that we can get together in groups, code and play.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cyberspice.org.uk/blog/2010/01/11/manchester-geek-girl-afternoon-tea/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
