Wirelessly control an Arduino with NodeJS over Bluetooth

I wanted to control my Arduino via Bluetooth using NodeJS but I could not find a Node module to do it. That is why I decided to build my own. This post describes how to use it.

Arduino setup

First, lets take a look at the Arduino setup I am using. It is a simple Arduino Uno with breadboard. For Bluetooth connectivity I’ve added a Bluetooth shield. For testing purposes I’ve configured a simple layout on the breadboard that allows me to control a LED. The picture below shows the configuration.

arduinosetup

I wrote a simple schema to control the LED. The program can change the status of the LED according to the value that is read from the serial Bluetooth connection. The program also allows to read the current state of the LED.

Bluetooth-serial-port

On the NodeJS side I have created a module that allows a script to communicate via a Bluetooth serial connection. The module can be used to communicate via Bluetooth as well as to search for Bluetooth devices and serial port channels.

Currently the module only supports the Bluez Bluetooth stack on Linux. I might add OS X support in the future. supports both Linux, Mac OS X and Windows (thanks Elmar!).

The module is available on npm and can be installed by issuing:

$ npm install bluetooth-serial-port

Using the module

To use the module you’ll have to import it into your script. Below is a simple example program that controls the Arduino configuration described above.

var BTSP = require('bluetooth-serial-port');
var serial = new BTSP.BluetoothSerialPort();

serial.on('found', function(address, name) {

    // you might want to check the found address with the address of your
    // bluetooth enabled Arduino device here.

    serial.findSerialPortChannel(address, function(channel) {
        serial.connect(bluetoothAddress, channel, function() {
            console.log('connected');
            process.stdin.resume();
            process.stdin.setEncoding('utf8');
            console.log('Press "1" or "0" and "ENTER" to turn on or off the light.')

            process.stdin.on('data', function (data) {
                serial.write(data);
            });

            serial.on('data', function(data) {
                console.log('Received: ' + data);
            });
        }, function () {
            console.log('cannot connect');
        });
    });
});

serial.inquire();

Open issue

Currently the module works quite well. The only thing not working is when a script wants to reconnect the Bluetooth connection.

When a connection is ended, for example when the Arduino is switched off, and the scripts starts a new Bluetooth inquiry the module will find the Bluetooth serial channel again but does not connect to it.

My current work around for this issue is to terminate my script when a connection has ended and than restart the script again. To achieve this I’m using forever.

For example…

I hope this post helps you to build cool stuff using using NodeJS and Bluetooth. I’m curious about the applications you’ll come up with. Please drop me a note ;-)

I’ve used the above configuration to make a UPnP controlable Bluetooth lightbulb prototype. For the UPnP side of the prototype I used the upnp-device module. The prototype will be part of the Figaro demonstrator that will demonstrate how IP-based and non-IP based home networks can be converged (PDF). This demonstrator is shown in the IEEE booth on the CES coming January.

All sources from this post are available as gist.

Happy programming!

Advertisement
Posted in programming | Tagged , , , , , , , , , | 15 Comments

Creating a Java WebStart (JNLP) application

Java WebStart, also called Java Network Launching Protocol (JNLP), allows you to launch Java applications directly from the internet using a webbrowser. In this article we will create a simple application and all configuration files necessary to launch it through Java WebStart.

We start with a simple Java program with a GUI:

package nl.jansipke.samplegui;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class SampleGUI extends JFrame {

    private static final long serialVersionUID = 522159447010444143L;

    public SampleGUI() {
        setTitle("Sample GUI");
        setSize(300, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                SampleGUI sampleGUI = new SampleGUI();
                sampleGUI.setVisible(true);
            }
        });
    }
}

Java WebStart applications run in a sandbox with very limited default capabilities. The application can ask for extra permissions in the JNLP file, as can be seen in the following file.

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://www.jansipke.nl" href="SampleGUI.jnlp">

    <information>
        <title>SampleGUI</title>
        <vendor>Some Vendor Name</vendor>
        <homepage href="http://www.jansipke.nl"/>
        <description>SampleGUI description</description>
    </information>

    <security>
        <all-permissions/>
    </security>

    <resources>
        <j2se version="1.6+"/>
        <jar href="SampleGUI.jar"/>
    </resources>

    <application-desc main-class="nl.jansipke.samplegui.SampleGUI"/>

</jnlp>

The JAR file needs to be signed for these permissions to take effect. We need to create a keystore file for that first. If needed you may change the alias and the keystore file name.

keytool -genkey -alias alias -keystore keystore.bin

Answer the questions the keytool command asks and copy the file into a directory where the following ANT build script can find it:

<?xml version="1.0" encoding="UTF-8"?>
<project name="samplegui" basedir=".">

    <property name="dir.build" value="bin" />
    <property name="dir.dist" value="dist" />
    <property name="dir.src" value="src" />
    <property name="file.jar" value="SampleGUI.jar" />

    <path id="compile.classpath">
        <fileset dir=".">
            <include name="lib/*.jar" />
        </fileset>
    </path>

    <target name="clean" description="Clean project">
        <delete dir="${dir.build}" />
    </target>

    <target name="prepare" description="Prepare project">
        <mkdir dir="${dir.build}" />
    </target>

    <target name="compile" description="Compile project" depends="prepare">
        <javac destdir="${dir.build}" classpathref="compile.classpath" debug="true" includeantruntime="false">
            <src path="${dir.src}" />
        </javac>
    </target>

    <target name="jar" description="Build jar file" depends="compile">
        <mkdir dir="${dir.dist}" />
        <jar destfile="${dir.dist}/${file.jar}" basedir="${dir.build}">
            <manifest>
                <attribute name="Main-Class" value="nl.jansipke.samplegui.SampleGUI"/>
            </manifest>
        </jar>
    </target>

    <target name="signjar" description="Sign jar file" depends="jar">
        <signjar jar="${dir.dist}/${file.jar}" alias="alias" storepass="secret" keystore="keystore.bin"/>
    </target>

</project>

Now run the ANT script (target signjar) and copy the resulting JAR file and the JNLP file to a directory on your webserver. Fire up a webbrowser and point it to the JNLP file. If all goes well, it will present you with a warning about permissions. Check yes and it will start the application.

Posted in programming | Tagged , , | Leave a comment

Creating network diagrams with D3.js

D3.js is a JavaScript library for manipulating documents based on data. It can be used for all sorts of visualizations including network diagrams. In this article we will create a network diagram with nodes and directed links between them, visualized by circles and lines with arrowheads. We start with the file index.html that holds the HTML and basic SVG structure:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <title>Cloud</title>
        <script type="text/javascript" src="d3.v2.js"></script>
    </head>
    <body>
        <svg id="cloud" width="800" height="600">
            <defs>
                <marker id="arrow" viewbox="0 -5 10 10" refX="18" refY="0"
                        markerWidth="6" markerHeight="6" orient="auto">
                    <path d="M0,-5L10,0L0,5Z">
                </marker>
           </defs>
        </svg>
        <link href="cloud.css" rel="stylesheet" type="text/css" />
        <script src="cloud.js" type="text/javascript"></script>
    </body>
</html>

The file cloud.js contains the Javascript code to generate the SVG code according to some JSON content:

var width = 1200;
var height = 800;

var color = d3.scale.category10();

var force = d3.layout.force()
    .charge(-180)
    .linkDistance(70)
    .size([width, height]);

var svg = d3.select("#cloud");

d3.json("cloud.json", function(json) {
    force
        .nodes(json.nodes)
        .links(json.links)
        .start();

    var links = svg.append("g").selectAll("line.link")
        .data(force.links())
        .enter().append("line")
        .attr("class", "link")
        .attr("marker-end", "url(#arrow)");

    var nodes = svg.selectAll("circle.node")
        .data(force.nodes())
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", 8)
        .style("fill", function(d) { return color(d.group); })
        .call(force.drag);

    nodes.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function() {
        links.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });

        nodes.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
    });
});

The file cloud.json contains the JSON that the Javascript uses to create SVG:

{
    "nodes":
        [
            {"name":"Client 1",       "group":1},
            {"name":"Loadbalancer 1", "group":2},
            {"name":"Webserver 1",    "group":3},
            {"name":"Webserver 2",    "group":3}
        ],
    "links":
        [
            {"source":0, "target":1, "value":1},
            {"source":1, "target":2, "value":1},
            {"source":1, "target":3, "value":1}
        ]
}

The final file cloud.css contains the CSS to make things more pretty:

circle.node {
    stroke: #fff;
    stroke-width: 3px;
}

line.link {
    stroke-width: 2px;
    stroke: #999;
    stroke-opacity: 0.6;
}

marker#arrow {
    stroke: #999;
    fill: #999;
}
Posted in programming | Tagged , | Leave a comment

Welcome to Framework Limbo! Using Eclipse, Maven, GWT and Lombok

One of the main advantages of service engineering in Java is that there are quite a lot of environments, libraries, frameworks, IDEs and plugins to choose from. That’s also a major drawback. We ran into this while doing a recent prototyping project, and once again discovered the hard way that there is a certain threshold before you run into framework limbo, dependency hell and assorted related afflictions.

There is a saying in Dutch about donkeys and bumping into the same stone twice. Our new general rule of thumb is that you should use never use more than about two (plus or minus one) environments, libraries, frameworks, IDEs and / or plugins at once. Ever. You’ll save yourself from being a donkey by using only the stuff you really need. So read on if you want to risk countless hours of frustration with Eclipse, Maven Google Web Toolkit and Lombok.

Disclaimer: we have switched to using another GUI framework which is more suited to our needs.

Continue reading

Posted in programming | Tagged , , , , , | 1 Comment

Update on the TUMe protocol

Yesterday I did a writeup of my first impressions on the TUMe protocol. Today I want to give some more details about the JSON over HTTPS part of the protocol. TUMe definitively uses SIP for signaling.

The JSON protocol is used for the provisioning of the service. For both initial setup as for removal of the service. The protocol is also used for authorizing the application on every startup.

When registering for the TUMe a JSON message is to register your phone number together with your locale. After this some setup is send to setup Apple’s push message service for TUMe. In the meanwhile you will receive a PIN code from TUMe via SMS.

The PIN code and your phone number are then send in a subsequent JSON message meant to validate your phone number. The server replies with a configuration message for the app. The message contains a SIP (over TLS) configuration and some information for authentication. You can see this message below:

Configuration message of TU Me

The TUMe configuration message containing authentication and service (SIP) information.

After this TUMe is ready to rock.

When still in the progress of setting up the service for the first time, the app will send personal information via JSON. Your MSISDN (phone number), screen  name and user id (from the config message) are sent first. After that, when you choose to, your contacts are send to the server.

Every time the application is started it will first authorizes itself via a JSON message. It sends a HTTP request with a basic authentication string and receives an access token in return. I suspect this token is used to setup the TLS connection that is used for SIP signaling.

The app also requests a history from the JSON server but for me this message is always empty. I’m not sure what this message is for.

Canceling the account also goes via JSON, a HTTP DELETE request is send to the server to trigger the account removal.

This concludes the analysis of the JSON RPC protocol.

Posted in telecommunications | Tagged , , , , , , , , , | Leave a comment

First analysis of the TUMe protocol

*UPDATE* more on the JSON part of the protocol.

Today Telefonica release the TUMe App. With this App you can text, talk and share for free. Telefonica launches this as Telco-OTT style.

I won’t go into details about the TUMe App itself or what this means to the telco world. But I was wondering about the protocols that are used and I will do a quick writeup of my findings.

Since I wanted to make traces of the TUMe signaling I first setup mitmproxy for intercepting HTTP traffic. This showed me that for provisioning (setting your name, receiving history, sending the address book, etc.) a JSON protocol is used which is being communicated over HTTPS.

However, calls and messages did not show up in mitmproxy which means that these are not send over HTTP (or at least do not use the system wide HTTP proxy settings in iOS).

To see all the traffic that is send by my iOS device I would have to sniff in the middle or trace on my device itself. Since I have jailbroken my device I did the latter. I installed tcpdump on my iPhone and did a trace while I was sending text messages with TUMe.

At first I started looking for the obvious, SIP or XMPP messages that are send over the default SIP and XMPP ports but I found none. Than I looked for traffic to unknown IP addresses. This was made easy since all HTTP traffic was still going via my mitmproxy. I noticed that there was traffic that was marked as HTTPS that was not send via the proxy. I found this traffic suspicious because when it would use iOS HTTP APIs it should end up being send via the HTTP proxy.

Analysis of this data stream showed a TLS connection is being setup. Because of the TLS encryption the protocol itself is not revealed but the TLS setup shows that a server certificate belonging to Jajah.com is being used.

Wireshark shows the Jajah certificate

Jajah is a Telefonica owned company that offers a range of products. Some are SIP based, others not. So from this trace it is clear if TUMe is a SIP or RCSe client. Although suggesting it triggers a reaction that it might very well be SIP… The TCP port being used is, however, not a SIP port but port 443 (HTTPS).

So what is the conclusion? To me (pun intended) it is not clear what protocol is being used for signaling, although the reaction on Twitters seems to acknowledge that it is SIP over TLS on port 443 (HTTPS). Some stuff is being done out-of-band via a proprietary JSON over HTTPS protocol. To me this sounds like TUMe is not a RCSe client but a proprietary client. This is fine since TUMe is OTT anyway so there is no need to federate with anyone.

Posted in telecommunications | Tagged , , , , , , , , , , | Leave a comment

How to use XMPP SASL EXTERNAL with Node.js

Almost a year ago I came across Node.js for the first time. Without going into details I must admit that a kind of like it. It has been useful to me in various projects. I especially like it for rapid prototyping or for creating some temporary service that is useful within a development environment. Like every framework, Node.js has some issues. Personally I don’t like for larger, more complex, projects.

But… This post is not about Node.js. I wanted to give a brief introduction because I never blogged about Node.js before.

The post is about using SASL EXTERNAL in node-xmpp, a Node.js module for XMPP communication. For a project that I am a part of I investigated certificate based authentication to an XMPP server. I found the node-xmpp module to be the best available XMPP module for Node.js out there but it didn’t support the EXTERNAL authentication scheme as describe in XEP-0178, so I decided to add it myself.

SASL EXTERNAL is not used widely in the XMPP world. There are only a few clients and servers supporting it (as far as I know of). Openfire and Prosody support EXTERNAL for client to server authentication on the server side. Since I was already running an Openfire server I decided to give it a try on that.

To get stuff working I went trough the following steps:

  1. Create a test certificate authority (CA) and configure Openfire to use the EXTERNAL authentication mechanism
  2. Pull node-xmpp from the git (EXTERAL will hopefully be part of the 0.4 release of node-xmpp)
  3. Create a test client
  4. Test if it works

I will go through these steps in more detail below.

Create a test CA and configure Openfire

On the Pidgin wiki I found a walkthrough that guided me to most of these steps. I am not going to repeat these steps but I will give some pointers to solve issues I ran in to:

  • Configure Openfire first. Openfire will create a client.trustore when it is restarted
  • Restart Openfire after adding the CA key to the keystore
  • The property sasl.mechs should have a comma separated list of SASL mechanisms as the value. For example: EXTERNAL,DIGEST-MD5,PLAIN,CRAM-MD5
  • Create a test CA. Convert the public certificate of the CA to x509 and import it into the client.trusttore. After that create certificate/key pair for each user and sign the certificates with the CA.

Pull node-xmpp from the git

That is simple, just issue:


git clone git://github.com/astro/node-xmpp.git

Create a test client

I did that piece of work already, just copy my echo_bot_sasl_external.js gist.


#!/usr/bin/env node
/**
* Echo Bot – the XMPP Hello World
*
* Copied from the echo_bot.js example from node-xmpp.
**/
var xmpp = require('../lib/node-xmpp');
var argv = require('optimist').argv;
var fs = require('fs');
var argv = require('optimist')
.usage('Usage: echo_bot_sasl_external.js –jid=<my-jid> [–host=<host>] [–port=<port>] [–legacy_ssl]')
.demand(['jid'])
.boolean('legacy_ssl')
.argv;
var credentials = {
// These are necessary only if using the client certificate authentication
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
// You might want to put the passphrase of the key file here. You'll be prompted otherwise.
// passphrase: 'YOUR_PASSPHRASE'
};
var options = { jid: argv.jid, 'credentials': credentials };
if (argv.host) options['host'] = argv.host;
if (argv.port) options['port'] = argv.port;
if (argv.legacy_ssl) options['legacySSL'] = argv.legacy_ssl;
var cl = new xmpp.Client(options);
cl.on('online', function() {
console.log('online');
cl.send(new xmpp.Element('presence', { }).
c('show').t('chat').up().
c('status').t('Happily echoing your <message/> stanzas')
);
});
cl.on('stanza', function(stanza) {
if (stanza.is('message') &&
// Important: never reply to errors!
stanza.attrs.type !== 'error') {
// Swap addresses…
stanza.attrs.to = stanza.attrs.from;
delete stanza.attrs.from;
// and send back.
cl.send(stanza);
}
});
cl.on('error', function(e) {
console.error(e);
});

Finally, test if it works

If you are using the test script from my gist you should copy the key and certifiate of your test user to the folder the script is in. The key file should be called key.pem and the certificate should be called cert.pem.

To connect via starttls run:

node echo_bot_sasl_external.js --jid=user@domain.com

To use the legacy SSL port run:

node echo_bot_sasl_external.js --jid=user@domain.com --server=domain.com --legacy_ssl

Thats it.

Posted in programming | Tagged , , , , , | Leave a comment

Google Maps icons and circles revisited

Recently I needed to add icons and circles to a Google Map. My colleague Jan Sipke did a nice write up on this topic a couple of years ago. Unfortunatly things did change since then. Google released a new version of the Maps API (3.8 at the time of writing) and the resources that were used in his writeup moved to new locations. That why I decided to write an update on his story.

I wanted to achieve something like this:

I downloaded the icon from the same source as Jan Sipke did: The Map Icons Collection.

Only the site moved to a new location. The site features a great set of nice icons you can use on Google Maps. Check them out!

I used Matt Williamson’s Google Maps Circle Overlays to draw the circles. This script uses miles for the radius of the circle. I wanted to use kilo meters and made a simple function that converts kilo meters into miles.

The following code wraps this all up into the result I was looking for:

<!DOCTYPE html>
<html>
  <head>
    <title>Google Maps icons and circles revisted</title>
    <script type="text/javascript"
      src="http://maps.google.com/maps/api/js?key=YOUR_KEY&sensor=false"/>
    <script src="scripts/maps.google.circleoverlay.js"
      type="text/javascript"/>

    <script type="text/javascript">
      var IconsAndCircles = {
        map: null,
        KMS_THAT_MAKE_A_MILE: 1.609344,

        /* converts a distances in kilo meters into miles */
        kmToMiles: function(distanceInKm) {
          return distanceInKm / this.KMS_THAT_MAKE_A_MILE;
        }

        /* show a maker on the map */
        showMarker: function(point) {

          // create a marker with an icon
          marker = new google.maps.Marker(
            {position: point, map: map, icon: 'res/wifi.png'}
          );

          // Create and add a circle for 200 meters
          new CircleOverlay(
            map, point, this.kmToMiles(0.2),
            "#0000FF", 0, 1, '#0000FF', 0.10
          );

          // Create and add a circle for 50 meters
          new CircleOverlay(
            map, point, this.kmToMiles(0.05),
            "#0000FF", 0, 1, '#0000AA', 0.25
          );
        },

        /* loads the map */
        load: function() {
          // Create Map
          var center = new google.maps.LatLng(52.026129,4.357066);
          map = new google.maps.Map(document.getElementById("map"), {
              center: center,
              zoom: 16,
              mapTypeId: google.maps.MapTypeId.ROADMAP
          });
          this.showMarker(map.getCenter());
        }
      };
    </script>
  </head>
  <body onload="IconsAndCircles.load()">
    <div id="map" style="width: 100%; height: 500px; border: 1px solid #666666;"/>
  </body>
</html>

After I wrote this code I found that Google also offers a way to create circles on a map in the Maps API. You might want to check out their example as well.

Posted in programming | Tagged , | Leave a comment

What is this that stands before me …

Ozzy Osbourne wailing this line in 1970 demarcated the birth of heavy metal. Lately this line also springs to mind when I read about the latest “discoveries” in service delivery paradigms presented by telecom operators.

To them, it still seems to be the middle ’90s when the Internet was regarded to be an interesting experiment that would soon erode and be replaced by the constellations developed by the telecom industry. And while no one still argues that the Internet Protocol should by replaced by the much more powerful Asynchronous Transfer Mode (ATM) when it comes to service provisioning the telco industry still dreams up very complex service delivery platforms. And yes, from an academic approach that would be the way to go. But apparently telcos lack the power to execute such a strategy. Location-based services and the corresponding service architectures were a new and coming thing in the late 1990s. Had the industry acted on it at the time, the telcos could have been today’s Google. However, instead of bringing the idea to market the industry discussed for over a decade what would the business model and what would be the technology to deliver LBS. Would it be SOAP? Or would it be CORBA? Or maybe, yet something else.

Meanwhile, Google did what at the time everyone believed to be impossible, they paid people to drive around the globe and collect information about cell coverage. Suddenly, the information that telcos believed to be pure gold had evaporated because Google provided it for free. But instead of learning from this experience, the telco industry apparently think they have only lost a battle and not the war and dream up exciting new services such as the Rich Communication Suite.

What is this that stands before me? Well, being a former Bellhead myself I hate to admit it, but it might very well be a herd of dinosaurs.

Posted in Uncategorized | Leave a comment

Grep lines before and after matched line

The command grep is really useful for finding matches of a certain word in files or streams. However, until recently I didn’t know how to display lines before and after the matched line(s).

Let’s say we have a file named test.txt that contains the following content:

ALICE was beginning to get
very tired of sitting by
her sister on the bank
and of having nothing to do:
once or twice she had peeped
into the book her sister was reading,
but it had no pictures or conversations in it,
"and what is the use of a book," thought Alice,
"without pictures or conversations?'

If we use grep to find lines matching “bank”, we write:

grep bank test.txt

and get:

her sister on the bank

If we want to list some line(s) before the matched line, we write:

grep -B1 bank test.txt

where the 1 denotes the number of lines to list, and get:

very tired of sitting by
her sister on the bank

If we want to list some line(s) after the matched line, we write:

grep -A2 bank test.txt

where the 2 denotes the number of lines to list, and get:

her sister on the bank
and of having nothing to do:
once or twice she had peeped

The two options can be combined as well, but I leave that as an exercise to the reader :-).

Posted in programming | Tagged | 1 Comment