Latest Paho Status (2)

I last wrote about the state of Paho in October. This post is a continuation of that one.

Java Client

Some of you might know that James Sutton, who is co-project lead with me and has worked on the Paho project for several years, has moved jobs within IBM.  He intended to be able to spend some 20% of his time on the Java client, but that has proved infeasible up to now.  There was supposed to be an IBM replacement for James to work with me, but that arrangement has fallen through for the time being.  We hope that will actually happen early next year.

In the meantime, I’m going to look at the immediate needs for the Java client:

  1. A service release of 1.2.1 to incorporate the fixes that have been made since 1.2.0, and maybe some others
  2. Finish the tasks needed for the new MQTT 5.0 release, 1.3.  These are mainly around tests: adding some load tests and looking at unreliability in the Travis CI test runs.
  3. Release 1.3 of the Java client.

Other components

I’m also working on, or being responsible for:

  • the C client (MQTT V5 release completed)
  • embedded C client (MQTT V5 work in progress)
  • JavaScript client (MQTT V5 updates being thought about)
  • MQTT test material
  • embedded MQTT-SN client (shared with Tomoaki!)Python client (MQTT V5 only – first PR submitted, needs updates)

as well as the routine project lead and Eclipse IoT PMC work.  I mention this topic not to garner sympathy, but to ask for patience from those who are waiting for me to respond to issues and PRs, and to think more about how we can encourage more participation from our community to help the committers with their work.  And for contributors to become committers of course.

Welcoming Communities

I did write another blog post in June about how to get more help for the Paho project.  I had some useful responses and also found this guide on building welcoming open source communities. 

Looking at the Paho website it’s quite formal, and the text was mostly written years ago.  I’ve decided to re-write it so it focuses more on the Paho community, and how to get involved, as well as the software we provide.  Of course the website is not the only way that people find out about Paho, and indeed may not be the most frequent route.  That could well be through the Github repos, so each of them needs to empahisize the community aspects too.  For the repos I’m responsible for, I’ll make some changes, then talk/write about what I’ve done. 

Paho Logo

As part of the website update, I’d like to change the project logo too.  The existing Paho logo:

has been around from the beginning.  I’d like to make it more symmetrical  so it fits more nicely on laptops or websites.  That’s “as far as I’m concerned” of course, as it’s subjective, and I want to thank the person who put it together in the first place.  So I thought I’d have a go at producing a new one.  My very first quick attempt is:

a simple moving of the text within the bubble.  ‘Paho’ is a Maori word meaning ‘broadcast’, so I assume that the bubble signifies speech or some other method of sending messages.  I do have some other ideas that I’m working on too, but the reason for mentioning it now is to encourage contributions from anyone else who is interested.

Comment and contribute!

Please do comment on these thoughts or contribute any ideas.  

Latest on the Eclipse Paho Project

We recently announced the release of Eclipse Paho 1.4, which includes updates to the C, Python and Go client libraries. The embedded C and Java clients are delayed somewhat. The fact that we have a Paho project release may pass many people by because they only look at the activities of individual components. Paho is an unusual Eclipse project in that regard. I think the notion is useful however, if ‘only’ in practical terms, because these releases accomplish some Eclipse formalities which are worth the effort: IP log checking, Eclipse IoT and Foundation release reviews. A global Paho release saves the individual committers from having to do this separately and for each component.

The next release I’m tentatively thinking about for later this year or early next, with more MQTT V5 updates. So its schedule pretty much depends on when those updates are ready (C++, embedded C, Go, Python?).

We do have some work outstanding on the website, and it can always be improved. We’re always interested in ideas. Apart from the specific calls for help below, we are open and would appreciate help in any of the areas, especially if anyone is interested in becoming a committer. I wrote a another blog post with some more thoughts a while back.

C client

Recently I finally cut a the 1.3 release of the Paho C client which is notable for adding support for MQTT V5. It took longer than I had hoped to get to the point where I was happy to stamp the release tag on, which in hindsight is not that surprising as MQTT V5 support is the biggest addition to the client since it was originally created around around 10 years ago.

Obviously the amount of functionality needed in an MQTT client library is not infinite, and I’ve wondered when it would be basically complete, with no more new features needed by anyone. With the addition of support for MQTT V5, and also WebSockets courtesy of Keith Holman’s contribution, we’re closer than ever. But if you look at the outstanding list of enhancements we’re not quite there yet! We’re always interested in contributions, so if you are interested in fixing any of these issues, please do have a go.

Java

A similar story with the Java client and its support for MQTT V5, but we’re not quite there yet, as you can see from the outstanding issues. James, the maintainer for the Java client, has just moved jobs and is stretched for time. I’m working with him to resolve those final issues and make the release available as soon as we can. The basic support for MQTT V5 is ready, so you can go ahead and try it, it’s the tests and minor issues around the edge that we want to clean up.

Kamil’s mqtt-spy utility relies on the Java client, so I’m hoping that can move ahead soon.

Test Material

The Paho test material includes a (Python) broker which supports MQTT V5. I wrote it as an update to the existing broker so that we could use it for testing V5 client implementations. It supports TLS and WebSockets too, and is used by the C and Java clients in their CI tests.

C++

The C++ client is a layer over the C client, so now that is ready, I’m hoping Frank is good to start. In a recent email, Frank said that he aims to get V5 support in by the end of the year. I’m keeping my fingers crossed for that 🙂

Likewise with Frank’s Rust client, which is also based on the C. I expect V5 support will be added after the C++ client is done?

Python

Pierre has cut a new release of the Python client, 1.4. It doesn’t include MQTT V5 support, but I’ve created a PR with a start of that. I’m hoping we can see V5 support available by the end of the year too.

Embedded C

I started with V5 updates to this client library, and completed the implementation of V5 support in the MQTTPacket low level library. That was where I paused to turn my attention to the mainline C library. Now it’s the turn of the embedded library again. I also hope to work on the long intended threaded MQTTAsync, threaded embedded library.

Go

A service update 1.1.1 was delivered in March this year. Al has started developing MQTT V5 updates some time ago, using the Paho V5 Python broker for testing. I’m hoping we can see the fruits of his labour produce a V5 release in the near future.

C#

Unfortunately there haven’t been any regular updates to the C# client for quite a while. I’ve spoken to Paolo about the future, and he would like to see this project continue, but can’t necessarily devote much time to it. We did ask if anyone out there is interested, and had one offer which we’re waiting to see if that works out. If anyone else is interested in contributing to the C# client, do get in touch.

Ruby

The Ruby client is a recent contribution which we’re very happy to have on board. Another Pierre, Goudet, is responsible for it. It took a long time for the contribution to be accepted because of the IP questions that had to be resolved, and we appreciate the persistence of the contributors for working through that very much. I hope that we can get a first official Paho release soon.

JavaScript

We haven’t had a specific maintainer for the JavaScript client for a while. James and I between us have taken it on as and when needed, and I intend to look at MQTT V5 updates soon. If anyone is interested in helping out, please let us know.

MQTT-SN

This client has taken a bit of a back burner for a while, partly because we have a creator and maintainer for the MQTT-SN transparent gateway in the shape of Tomoaki, who I had the pleasure of meeting recently in Singapore. For those that don’t know, MQTT-SN is a variant of MQTT explicitly designed for non-TCP networks such as UDP, ZigBee or BLE.

As it has not been standardized as MQTT has, it has been left behind a little. I hope that we can take steps to remedy that next year by looking at MQTT-SN within the OASIS MQTT TC. How exactly that will work hasn’t been formulated yet. I’ll keep everyone in touch as it happens. I hope Tomoaki and I can work together on some presentations about MQTT-SN for Eclipse IoT events next year.

Eclipse IoT Day Singapore

In July or August of this year, Benjamin Cabé of the Eclipse Foundation asked if there were any volunteers for presenting at an Eclipse IoT day in Singapore. As I had already given talks on MQTT V5 earlier in the year at the Eclipse IoT day in Santa Clara and EclipseCon France, I thought, why not? We do have a lot of interest from all over the world in MQTT, IoT and Eclipse, so it was a good opportunity to reach part of the world I don’t normally see in a professional capacity.

I should have known how far Singapore is from the UK, as I’ve stopped off there once or twice when travelling to New Zealand to visit family in recent years. Evidently I’d forgotten, as when I realised how far away Singapore is, I did have some second thoughts. Well, I thought, I’ll let the IBM travel authorization decision make the choice for me. As it happens I found some flights at a very reasonable cost, the travel authorization was granted, and my travel plans confirmed.

I am happy to stay at home and not travel extensively, so this year has been unusual for me. But the completion of the MQTT 5.0 standardization process is a significant milestone, and people want to hear about the standard and its implementations, so I’ve made the effort. The first stage was getting to Singapore, which involved two 7 hour flights, arriving on the Monday morning of the week of the conference. This was the day after the Singapore F1 GP had taken place, so the course was still being dismantled. It took the taxi driver an extra 25 minutes to reach the hotel because of the continuing road closures!

After I had a few hours sleep, Benjamin and I met up later in the day and took a walk through the Gardens by the Bay which is the one sight that I definitely wanted to see in Singapore. We had some crushed sugar cane to drink, and chicken rice to eat, all of which was very satisfying. After taking some photos of the garden I walked back to the hotel, which was still complicated by the road closures, but I made it.

After a fairly good night’s sleep, I made the short walk from the hotel to the Conference Center using the bay Double Helix footbridge. The conference centre is opposite the Marina Bay Sands hotel (the one with the ‘ship’ on top of three towers) which always features extensively in the F1 TV coverage.

After the morning coffee and registration, Benjamin was first up with the State of The Union of Eclipse IoT, summarizing the progress that has been made over the past six or seven years. The room was full to overflowing, and the interest high.

Eclipse IoT State of the Union

Then I was up, largely giving a re-rerun of the talks I had given in California and France earlier in the year. The videos of these talks, as well as the others recorded on those days, are available on YouTube. As before, I ran through a quick history of MQTT, the reasons for defining a new version relatively soon after 3.1.1 had been finished, the new features of version 5.0, and a quick demo of Paho support.

Where next for MQTT?

My demo included sending messages over MQTT 5.0 to IBM’s IoT Platform which has announced beta support for this latest version of MQTT.

To explain again, the reason for another version of MQTT now is that the first standardized version, 3.1.1, was limited in the scope for changes to:

  • reach a completed standard quickly, and
  • be compatible with existing implementations.

This left some outstanding irritants. MQTT 5.0 attempts to fix them while still conforming to the goals of being lightweight and simple.

During the breaks I had chance to talk with a collaborator of mine on the Eclipse Paho project. Tomoaki and I have been working together on MQTT-SN projects for several years, separately for a number of years before then. As Tomoaki lives in Japan, I never thought I would meet him in person, but he made the long journey to Singapore so that we could. It was an extremely pleasant and productive meeting, as we discussed other potential MQTT-SN activities such as support for DTLS.

Ian and Tomoaki!

When the photo was taken I was also enjoying the warm tropical rain. Rain in the UK is always cold – here it felt like it was almost evaporating before it hit the ground, due to the high temperature.

The last session of the morning was Oliver Meili of Bosch SI describing the company’s extensive involvement with Eclipse IoT.

Bosh SI Eclipse IoT Projects

The lunch break was followed by talks on the ioFog, Vorto and Cyclone DDS Eclipse IoT projects. ioFog is an approach to edge computing developed by a startup company embracing open source at its core. Vorto enables translation between IoT model definitions in a variety of formats, and Cyclone is an open source DDS implementation.

The variety of Eclipse IoT projects available now is impressive. You can discover the full range at the Eclipse IoT website.

After the day’s sessions, I met with Tomoaki, then Kilton Hopkins (the driving force behind ioFog) and Benjamin for stimulating discussions, food and drink before retiring to the hotel. The following two days I spent mostly at the Eclipse IoT booth at IoT World, answering questions about the Eclipse Foundation, the Eclipse IoT portfolio, IBM and other companies’ contributions to Eclipse IoT, and the Eclipse Paho project and MQTT. There was unfamiliarity with all of these topics, so the trip was well worthwhile, even given the amount of travelling involved.

Using MQTT V5 with the IBM Watson IoT Platform and the Eclipse Paho C client

I’ve just finished off release 1.3 of the Eclipse Paho C client which includes MQTT 5.0 and WebSockets support. Another thing I’ve done is to update the command line utilities to be much more capable, so in this post I’ll describe how they can be used to connect to the IBM Watson IoT Platform using MQTT V5.

MQTT V5 is the latest version of the successful protocol which is the core of Paho’s capability. I’ve delivered a number of talks about MQTT V5, if you’d like to learn more about it that way. I’ve also previously written about how the C client command line utilities can use MQTT V5 to connect an MQTT server which supports V5 – we have one within the Paho project.

First you need to install the Eclipse Paho C client, if you haven’t already. As described on the linked page, the easiest way on Windows is probably to install the pre-built binaries, while on Linux and the Mac, for the time being, building from source. Running the command

paho_c_pub

will check that it runs, and display the full list of options.

IBM’s IoT Platform has a quick start playground, where you don’t have to sign up to try sending events. We’re going to connect to that first of all. Go to the web page, accept IBM’s terms of use, then enter a device id in the input box. This can be any sequence of characters you like (there are some restrictions and there is a length limit) – its purpose is to distinguish your device from other peoples’. So make it something unique enough, then push ‘Go’.

To connect the Paho publisher program to the platform with MQTT version 5, run the command:

paho_c_pub -c ssl://quickstart.messaging.internetofthings.ibmcloud.com:8883 -t iot-2/evt/myevent/fmt/json -i d:quickstart:my_device_type:my_device_id -V 5

replacing my_device_id with the device id you typed into the IoT Platform input box. Now the program is waiting for you to type an input message. The message should be in JSON format, because that’s what the quick start application is expecting, so type something like this:

{"t":2}

and press enter. You should see a point appear on the graph. Try sending a few more values, varying the number but keeping the rest the same, and you should see a line graph drawn something like this:

And that’s it! The -V 5 option at the end of the command line indicates that MQTT 5.0 was used rather than MQTT 3.1.1. There are two MQTT V5 specific options taken currently by the utility – user-property and message-expiry, although the platform doesn’t make use of them yet. The “–trace protocol” option will display details of the TLS exchange and MQTT packets sent and received.

If you already use the platform, to connect to an existing organization, use:

paho_c_pub -c ssl://orgid.messaging.internetofthings.ibmcloud.com:8883 -t iot-2/evt/event-id/fmt/json -i d:orgid:device-type:device-id --password auth-token --username use-token-auth -V5 

substituting appropriate values:

orgid – your organization id
event-id – the event id you want send events on
device-type – your device type
device-id – your device id
auth-token – the authentication token of the device previously defined

You can then send event data in the same way.

Paho C Client – MQTT 5.0 and Command-Line Utilities

I’m almost at the end of implementing the changes to the Eclipse Paho C client that I described in an earlier post to support MQTT 5.0. I haven’t quite finished off the release yet, so I thought I’d allow a little more time for anyone to comment. I had to compromise in my naming of the APIs for MQTT 5.0 support; none of the proposals I created were perfect, so I’m particularly interested in any feedback in that area.

MQTT 5.0 is not the only change for this release of the C client, but it is the biggest. You can find the complete list in the milestone. Another major addition is WebSocket support, thanks to the contribution of Keith Holman.

Another improvement I’ve been able to make is the update of the command line utilities. Back in 2010, I called them stdinpub and stdoutsub, the idea being that they could be used in Unix pipe combinations. Stdinpub reads data from stdin and publishes the results to an MQTT server; stdoutsub subscribes to an MQTT server and sends the data to stdout. I hadn’t really touched these programs in the meantime except to change the names to paho_c_pub and paho_c_sub. I always had intended to add TLS and other functionality to make them comparable to the Eclipse Mosquitto utilities mosquitto_pub and mosquitto_sub.

Now I’ve actually done that (small cheer!). Along with TLS I’ve added support for WebSockets and of course, MQTT 5.0. In each case, I have followed the Mosquitto utilities options where possible, so that it should be easy to switch from one to the other. There are actually two versions of each, one for each style of Paho C library, MQTTClient and MQTTAsync:

As well as being a useful way to experiment with V5 support, they also serve as examples on how to use the various APIs, for instance, how to write an application which combines support for all MQTT versions. You can try the following examples of using the command line utilities against the Paho test broker which supports all the combinations needed: WebSockets, MQTT 5.0 and TLS. To to start it up:

git clone git@github.com:eclipse/paho.mqtt.testing.git
cd git/paho.mqtt.testing/interoperability
python3 startbroker.py -c localhost_testing.conf

Typing paho_c_pub on the command line will display the option help:

-t (--topic)        : MQTT topic to publish to
-c (--connection)   : connection string, overrides host/port e.g wss://hostname:port/ws.  Use this option rather than host/port to connect with TLS and/or web sockets. No default.
-h (--host)         : host to connect to.  Default is localhost.
-p (--port)         : network port to connect to. Default is 1883.
-q (--qos)          : MQTT QoS to publish with (0, 1 or 2). Default is 0.
-V (--MQTTversion)  : MQTT version (31, 311, or 5).  Default is 311.
--quiet             : do not print error messages.
--trace             : print internal trace ("error", "min", "max" or "protocol").
-r (--retained)     : use MQTT retain option.  Default is off.
-n (--null-message) : send 0-length message.
-m (--message)      : the payload to send.
-f (--filename)     : use the contents of the named file as the payload.
-i (--clientid)     : MQTT client id. Default is paho-c-pub.
-u (--username)     : MQTT username. No default.
-P (--password)     : MQTT password. No default.
-k (--keepalive)    : MQTT keepalive timeout value. Default is 10 seconds.
--delimiter         : delimiter string.  Default is \n.
--maxdatalen        : maximum length of data to read when publishing strings (default is 100)
--message-expiry    : MQTT 5 only.  Sets the message expiry property in seconds.
--user-property     : MQTT 5 only.  Sets a user property.
--will-topic        : will topic on connect.  No default.
--will-payload      : will message.  If the will topic is set, but not payload, a null message will be set.
--will-retain       : set the retained flag on the will message.  The default is off.
--will-qos          : the will message QoS.  The default is 0.
--cafile            : a filename for the TLS truststore.
--capath            : a directory name containing TLS trusted server certificates.
--cert              : a filename for the TLS keystore containing client certificates.
--key               : client private key file.
--keypass           : password for the client private key file.
--ciphers           : the list of cipher suites that the client will present to the server during the TLS handshake.
--insecure          : don't check that the server certificate common name matches the hostname.

Here are some examples of use. To publish to the test broker on localhost over WebSockets using MQTT 5.0:

paho_c_pub -t topic --connection ws://localhost:1883 -V 5

To subscribe to the test broker on localhost over WebSockets with TLS server authentication using MQTT 3.1.1 by default:

paho_c_sub -t topic --connection wss://localhost:18885 --cafile test/ssl/test-root-ca.crt

And with mutual authentication without WebSockets:

paho_c_pub x --connection ssl://localhost:18884 --cafile test/ssl/test-root-ca.crt --cert test/ssl/client.pem --trace protocol

The –trace option displays various levels of trace, for debugging. A particularly useful level is ‘protocol’, which displays the MQTT and OpenSSL exchanges:

paho_c_pub x --connection ws://localhost:1883 -V 5 --trace protocol
Trace : 3, =========================================================
Trace : 3,                    Trace Output
Trace : 3, Product name: Eclipse Paho Asynchronous MQTT C Client Library
Trace : 3, Version: 1.2.1
Trace : 3, Build level: 2018-08-06T19:00:57Z
Trace : 3, OpenSSL version: OpenSSL 1.0.2o  27 Mar 2018
Trace : 3, OpenSSL flags: compiler: clang -I. -I.. -I../include  -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
Trace : 3, OpenSSL build timestamp: built on: reproducible build, date unspecified
Trace : 3, OpenSSL platform: platform: darwin64-x86_64-cc
Trace : 3, OpenSSL directory: OPENSSLDIR: "/usr/local/etc/openssl"
Trace : 3, =========================================================
Trace : 4, 20180809 144216.424 Connecting to serverURI localhost:1883 with MQTT version 5
Trace : 4, 20180809 144216.525 WebSocket connection upgraded
Trace : 4, 20180809 144216.525 5 paho-c-pub -> CONNECT cleansession: 0 (0)
Trace : 4, 20180809 144216.528 5 paho-c-pub <- CONNACK rc: 0
dfsdf
Trace : 4, 20180809 144259.493 5 paho-c-pub -> PUBLISH qos: 0 retained: 0 (0)

If using MQTT 5.0, you can attach user and message expiry properties to the sent message:

paho_c_pub -t topic --connection ws://localhost:1883 -V 5 --user-property name value --message-expiry 55

when received can be displayed with the –verbose option:

paho_c_sub x -V 5 -v
URL is localhost:1883
Subscribing to topic x with client paho-c-sub at QoS 0
13 x	dadasd
Property name MESSAGE_EXPIRY_INTERVAL value 55
Property name USER_PROPERTY key name value value

These utilities now have man pages too, as does the API itself, so I’ll have to make sure those are installed appropriately.

Thoughts on Help for Eclipse Paho

I gave a talk about MQTT V5 today at EclipseCon France, and at the end I gave the usual spiel about ways that people could help. After the talk, Cyrille Francois tweeted a great pictorial summary of the talk, as he did for other talks he attended. (Thanks Cyrille!) As part of the title of the tweet was the phrase “we need help”.

I’d like to add some more context to this. It’s of course true that we can always use more help. It’s also true that we are getting a lot of help already: issues, PRs, comments and feedback of all sorts. For example, one recent contribution to the Paho C client adds WebSocket support – thanks Keith! Paho is one of the most active Eclipse IoT projects as shown by this table extracted from an Eclipse IoT Metrics report:

Paho is also one of the most popular, in website visits:

although that metric is not definitive by any means, nor is this one:

as people obtain software from all the projects by many different means, not just downloads, but I don’t mind showing it given where Paho lies on it! At the time of writing, the Paho components have been starred 4108 times in total (up from 1766 last year) and users have forked the code 1969 times (up from 967). The number of committers now stands at 13, and the number of code authors is at least 88 (up from 50).

Paho is composed of distinct projects; client libraries and utilities, so those 13 committers are spread thinly across them. It’s an Eclipse convention that one committer doesn’t interfere in another’s repository without permission. Even without that, each committer is generally responsible for one or two specific components.

So I think we could do with some more committers, on just about all the Paho components. There are some that are in more need than others. The JavaScript client doesn’t really have a current owner, James Sutton and I step in when we can and as needed. We plan to update it for MQTT 5.0 later this year. The .Net client hasn’t been updated for a while and we’ve asked for help. All the other components could be helped by having more than one committer responsible.  Benjamin Cabé recently asked what would happen to the Paho C client if I was unable to continue (for whatever reason!) for instance.

When I became project lead I read the Eclipse documents quite thoroughly to learn what was expected.  About new committers, this is written:

Contributors who have the trust of the project’s committers can, through election, be promoted committer for that project. The breadth of a committer’s influence corresponds to the breadth of their contribution. A development team’s contributors and committers may (and should) come from a diverse set of organizations. A committer gains voting rights allowing them to affect the future of the project.

Becoming a committer is a privilege that is earned by contributing and showing discipline and good judgment. It is a responsibility that should be neither given nor taken lightly, nor is it a right based on employment by an Eclipse member company or any company employing existing committers.

I have taken these words quite seriously, maybe too seriously.  Should I lighten up a bit?

If anyone would like to become a committer then you definitely let me know and we can start talking.  Whether that’s for a particular component, or a wider remit such as helping with the website, or release process, it isn’t just coding.  There’s process development, design, documentation, tests for continuous integration, release packaging and distribution for example.

Of course you don’t need to be a committer to help by opening issues, responding to issues you didn’t open, raising PRs, or answering questions on mailing lists or forums.  If you haven’t done any of that already, you should start there.  There are many reasons to contribute to open source projects too.  Here’s what looks like a pretty helpful guide.

At EclipseCon today, Simon Phipps gave a great talk about Open Source, where it came from, where it’s going and why you should think about contributing if you use open source projects.  I expect that the slides will be up soon and you should take a look.  Seeing such talks in person is of course one of the benefits of attending conferences such as EclipseCon – you should do that too!

The new MQTT V5 API for the Eclipse Paho C client

I’ve started to write the new MQTT version 5.0 support for the Eclipse Paho C clients. As I’ve reached the stage where some very simple tests are running, I thought this was a good time to try to elicit some feedback. I’ve had to make some compromises in the API, balancing the minimization of disruption to application programs with the natural incorporation the new MQTT 5.0 capabilities.

If you’ve used the main Paho C client, you’ll know it comes in two flavours:

MQTTClient
The synchronous version – intended to be easy to get started. Most calls block, waiting for a response from the server. This was the first API, and the only one when I created it. I modelled it after the existing Java API for consistency.
MQTTAsync
The asynchronous version – (almost) entirely non-blocking. Responses are reported in callback functions. This was a response to the need to run in asynchronous environments such as iOS and Windows.

The mqttv5 branch in the Github repo contains all the MQTT V5 updates to date. The test15 and test45 test programs have the first tests for MQTTClient and MQTTAsync libraries respectively. (At the moment, only test1 in each file has been migrated to MQTT V5, so only look at those).

MQTTClient for V5

First we have to create the client object with MQTTClient_create – this stays the same.


rc = MQTTClient_create(&client, options.connection,
 "single_threaded_test", MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);

Next we must connect to the server.  As outlined in my previous post the main difference in MQTT V5 packets is the addition of the properties section, and for acknowledgements and disconnect, a reason code byte. Properties exist on both requests and their acknowledgements.

The connect call thus adds a properties object, for the connect request itself, plus the will message, and as part of the response. The MQTT V3 code:


MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

int rc = MQTTClient_connect(client, &conn_opts))

becomes:


MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
MQTTProperties props = MQTTProperties_initializer;
MQTTProperties willProps = MQTTProperties_initializer;
MQTTResponse response = {SUCCESS, NULL};

response = MQTTClient_connect5(c, &opts, &props, &willProps);

The property and will property fields can be NULL if not required. The properties structure is manipulated with the add, free and copy functions. To add properties:


property.identifier = SESSION_EXPIRY_INTERVAL;
property.value.integer4 = 30;
MQTTProperties_add(&props, &property);

and


property.identifier = USER_PROPERTY;
property.value.data.data = "test user property";
property.value.data.len = strlen(property.value.data.data);
property.value.value.data = "test user property value";
property.value.value.len = strlen(property.value.value.data);
MQTTProperties_add(&props, &property);

Memory is allocated in the process of adding a property to the properties structure, so when you’ve finished with it this must be freed:


MQTTProperties_free(response.properties);

The response structure looks like this:


typedef struct MQTTResponse
{
  enum MQTTReasonCodes reasonCode;
  MQTTProperties* properties; /* optional */
} MQTTResponse;

I’m not particularly happy with the name of the function, MQTTClient_connect5, but it does have the benefit of being short with a minimal change of name. Other options I considered were:

  • MQTT5Client_connect
  • MQTTClient_connectWithProperties
  • MQTTClient_connectExt

I quite like the “connectWithProperties” option, but it didn’t get much approval from the audience I’ve questioned so far — it also doesn’t reflect all the parameters required.

The other MQTT functions have similar changes. An MQTTResponse return structure instead of a single int, and an extra input parameter for properties. For the publishMessage function, the properties are added to the MQTTClient_message structure:


MQTTClient_message pubmsg = MQTTClient_message_initializer;

property.identifier = USER_PROPERTY;
property.value.data.data = "test user property";
property.value.data.len = strlen(property.value.data.data);
property.value.value.data = "test user property value";
property.value.value.len = strlen(property.value.value.data);
MQTTProperties_add(&pubmsg.properties, &property);

response = MQTTClient_publishMessage5(c, test_topic, &pubmsg, &dt);

And for the subscribe function, there are added subscribe-specific options:


MQTTSubscribe_options subopts = MQTTSubscribe_options_initializer;

subopts.retainAsPublished = 1;
subopts.noLocal = 0;
subopts.retainHandling = 0; /* 0, 1 or 2*/

response = MQTTClient_subscribe5(client, test_topic, subsqos, &subopts, &props);

Finally the disconnect function has both input properties and reason code:


enum MQTTReasonCodes reasonCode = SUCCESS;

rc = MQTTClient_disconnect5(client, 0, reasonCode, &props);

At the moment, the return from disconnect is still just an integer, as there is no MQTT response to a disconnect packet other than closing the connection.

I haven’t implemented the new MQTT V5 auth exchange packets yet, but I envisage this callback and call:



MQTTResponse MQTTClient_authArrived(void* context, enum MQTTReasonCodes rc, MQTTProperties props);

response = MQTTClient_auth(client, reasonCode, &props);

The callback will be used to implement an extended auth exchange initiated by the server, the function when the exchange is started by the client.

MQTTAsync for V5

Most of the changes to the MQTTAsync API are in parameter structures and in callback signatures rather than the API signatures themselves. The “create” and “setCallbacks” calls remain the same. V5 properties for both the connect and will messages are added to the existing connect options along with new callback signatures for success and failure:


MQTTAsync_connectOptions opts = MQTTAsync_connectOptions_initializer;
MQTTAsync_willOptions wopts = MQTTAsync_willOptions_initializer;
opts.onSuccess5 = test1_onConnect;
opts.onFailure = NULL;
opts.context = c;

property.identifier = SESSION_EXPIRY_INTERVAL;
property.value.integer4 = 30;
MQTTProperties_add(&props, &property);

property.identifier = USER_PROPERTY;
property.value.data.data = "test user property";
property.value.data.len = strlen(property.value.data.data);
property.value.value.data = "test user property value";
property.value.value.len = strlen(property.value.value.data);
MQTTProperties_add(&props, &property);

opts.connectProperties = &props;
opts.willProperties = &willProps;

rc = MQTTAsync_connect(c, &opts);

The return from the connect call remains an integer, as the expanded response information is made available in the callbacks in the MQTTAsync_successData5 structure:


typedef struct
{
	...
	enum MQTTReasonCodes reasonCode; /* MQTT V5 reason code returned */
	MQTTProperties props; /* MQTT V5 properties returned, if any */
	/** A union of the different values that can be returned for subscribe, unsubscribe and publish. */
	union
	{
		...
		/* For connect, the server connected to, MQTT version used, and sessionPresent flag */
		struct
		{
			char* serverURI;
			int MQTTVersion;
			int sessionPresent;
		} connect;
		...
	} alt;
} MQTTAsync_successData5;

In the test, the contents of the properties returned by the connack are logged in the success callback:


void test1_onConnect(void* context, MQTTAsync_successData5* response)
{
	...
	MyLog(LOGA_INFO, "Connack properties:");
	logProperties(&response->props);
	...
}

In subscribe, unsubscribe and send (publish) calls, the response options structure contains the properties as well as the new success and callback function pointers. As the options are now not just for responses, there is a synonym for the structure, called callOptions:


MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
MQTTAsync_callOptions opts = MQTTAsync_callOptions_initializer;
MQTTProperty property;
MQTTProperties props = MQTTProperties_initializer;

property.identifier = USER_PROPERTY;
property.value.data.data = "test user property";
property.value.data.len = strlen(property.value.data.data);
property.value.value.data = "test user property value";
property.value.value.len = strlen(property.value.value.data);
MQTTProperties_add(&props, &property);
opts.properties = props;

pubmsg.payload = "a much longer message that we can shorten to the extent that we need to payload up to 11";
pubmsg.payloadlen = 11;
pubmsg.qos = 2;
pubmsg.retained = 0;
rc = MQTTAsync_sendMessage(c, test_topic, &pubmsg, &opts);
MQTTProperties_free(&props);

The call options structure also includes the new V5 subscribe options:


MQTTAsync_callOptions opts = MQTTAsync_callOptions_initializer;
opts.properties = props;

opts.subscribe_options.retainAsPublished = 1;
rc = MQTTAsync_subscribe(c, test_topic, 2, &opts);
MQTTProperties_free(&props);

and for disconnect, similarly as for connect, the disconnectOptions structure is extended:


MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
MQTTProperty property;
int rc;

opts.onSuccess = test1_onDisconnect;
opts.context = c;
opts.reasonCode = UNSPECIFIED_ERROR;

property.identifier = SESSION_EXPIRY_INTERVAL;
property.value.integer4 = 0;
MQTTProperties_add(&opts.properties, &property);

rc = MQTTAsync_disconnect(c, &opts);
MQTTProperties_free(&opts.properties);

As for the MQTTClient API I’ve not added the AUTH packet capabilities yet. They will echo the other APIs:


int rc = MQTTAsync_setAuthReceived(c, context, callback_pointer);

rc = MQTTAsync_auth(c, &opts);

The MQTTAsync_auth call, to send an AUTH packet, will be able to be called from the AuthReceived callback in response to an AUTH packet from the server, or separately to enable the client to initiate an authentication exchange.

That rounds up the summary for now, I’m very interested to hear any thoughts.

A Story of MQTT 5.0

The MQTT protocol has been around since the late 90s when it was created to enable the monitoring of a long distance oil pipeline. It went through several iterations before landing on version 3.1, published by IBM.

The next step was standardisation, at the OASIS standards body. As anyone who has taken part in a standardisation committee will know, this process is necessarily bureaucratic and slow. To speed up adoption, the main imperative was minimising disruption to existing implementations, as set out in the Technical Committee (TC) charter.

As a result, wholesale changes to the MQTT 3.1 specification were not allowed in the 3.1.1 standard. This meant that many irritating flaws could not be fixed nor widely sought enhancements included. This is where MQTT 5.0 comes in. While we still wanted to minimise disruption (no-one wanted to repeat the experiences of say AMQP 0.9 to 1.0), we also wanted to address the MQTT wish-list as far as possible so that major changes would not be needed for a long time to come. Whether we succeeded in that aim, time will tell.

To help us make sense of the multitude of items on that wish list, as I wrote in September 2016, they were grouped into four Big Ideas:

  • Improved error reporting
  • Extensible metadata
  • Scalability and large scale systems
  • Resource Constrained Clients and Performance Improvements

At that time, many of the solutions were not decided upon, but now with the availability of Committee Specification 01, I can write about the details. We are in the final stages of the standardisation process for 5.0. We hope to complete the process of rubber stamping in the next few months, and expect no substantive changes during that time.

Improved Error Reporting

Negative responses, or nacks, were the biggest omission from earlier versions of MQTT. If the client or server had a problem with the request or packet from the other end, the only recourse in many circumstances was to close the TCP connection. Connect packets were the exception to this: the connack always had a return code. MQTT 3.1.1 added a negative response code to subscribe requests because there was space available in the “granted QoS” field of the suback packet. Publish requests, however, were still not catered for. This is now remedied.

Reason Codes

As all ack packets now have reason codes, they have been consolidated into one set, which starts like this:

Reason codes are one byte. Values from 0 to 127 inclusive indicate successful outcomes, those from 128 to 0xFF unsuccessful. So as the subscribe response can have an error code:

msc {
    arcgradient="4";

    c [label="client"], b [label="broker"];

    c => b [label="connect"];
    b => c [label="connack(rc=0)"];

    c => b [label="subscribe"];
    b => c [label="suback(rc=0x80)"];

    ...;
}

so can the publish, when the QoS is greater than 0:

msc {
    arcgradient="4";

    c [label="client"], b [label="broker"];

    c => b [label="connect"];
    b => c [label="connack(rc=0)"];
    ...;
    c => b [label="publish, qos=1"];
    b => c [label="puback(rc=0x80)"];
    ...;
    c => b [label="publish, qos=2"];
    b => c [label="pubrec(rc=0x80)"];
    ...;
    c => b [label="publish, qos=2"];
    b => c [label="pubrec(rc=0x0)"];
    c => b [label="pubrel(rc=0x80)"];
    ...;
    c => b [label="publish, qos=2"];
    b => c [label="pubrec(rc=0x0)"];
    c => b [label="pubrel(rc=0x0)"];
    b => c [label="pubcomp(rc=0x80)"];
    ...;
}

For the QoS 2 exchange, it stops if any of the reason codes are 0x80 or above. This is a major improvement on previous versions of MQTT, where continuing with the exchange or terminating the connection were the only options.

Server initiated disconnect

In MQTT versions prior to 5.0, only the client could send a disconnect packet. This meant that in any case where the server wanted to end the conversation with a client, there was no option but to just terminate the TCP connection. A common case is when the server shuts down – there is no error in the interaction between broker and client, but the client has no idea what’s happening. In MQTT 5.0, the server can send a disconnect packet with a “Server shutting down” reason code:

msc {
    arcgradient="4";

    c [label="client"], b [label="broker"];

    c => b [label="connect"];
    b => c [label="connack(rc=0)"];
    ...;
    c => b [label="publish, qos=1"];
    b => c [label="disconnect(rc=139)"];
}

In this case, the client might wait for a while before attempting a reconnect, knowing that the server might not be available for a while.

Extensible metadata

The big change here is in addition to reason codes, each packet (apart from pings) can have properties. This is an extract of the full list:

Properties can be used to add extra information to responses, such as a reason string, or extra parameters to requests. A lot of the rest of the changes rely on properties because now we had a mechanism for adding that extra information to packets, we had to use it!

Request/response

The new request/response capability makes good use of properties. The requester subscribes to the topic it expects to receive responses on, then sets the value of the “Response Topic” property to that topic name. The responder simply uses that property to set the topic name for its response.

msc {
    arcgradient="4";

    c1 [label="client1"], b [label="broker"], c2 [label="client2"];

    c1 => b [label="subscribe, topic=resp"];
    b => c1 [label="suback"];

    c1 => b [label="publish, response_topic=resp"];
    b => c2 [label="publish, response_topic=resp"];

    ...;

    c2 => b [label="publish, topic=resp"];
    b => c1 [label="publish, topic=resp"];
}

The “Correlation Data” property can be used to set an id for each request, so that replies can be matched to requests by the requester.

Payload format indicator

There were fairly contentious discussions about how much flexibility there should be in payload format settings. Some were in favour of user definable payload formats. Others felt that if people could define their own formats it was no better than the current position, unless some body kept an approved list of format indicators and their meanings. That seemed a step too far for MQTT. MIME types were discussed, but the final approach is minimalistic – just two values: binary, as 3.1.1, or UTF-8 data.

Enhancements for Scalability

Improved error reporting helps scalability because exchanges between servers and clients become more efficient. Properties are again crucial to the following functions.

Simplified session state

One of the other big irritations with 3.1.1, along with the lack of nacks for publish commands, is the behaviour of the “clean session” flag. In earlier versions of MQTT, this started out as the “clean start” flag, where the session state was only cleaned up at the start of a session, not at the end. This was good for clients, because it meant you could ensure a clean starting point, and leave the session around in case you needed to reconnect. Not so good for servers, because clients would tend to leave the state lying around for ever.

Later on, this flag was changed to “clean session”, cleaning the session state both at the start and end of the session. Good for servers. For clients, if they want to ensure a clean slate to start with, but then want to have session state saved, they have to connect twice:

msc {
    arcgradient="4";

    c [label="client"], b [label="broker"];

    c => b [label="connect cleansession=true"];
    b => c [label="connack"];
    c => b [label="disconnect"];
    ...;
    c => b [label="connect cleansession=false"];
}

We knew we should fix this situation once and for all. The “clean session” flag becomes “clean start” once more – session state is only cleaned up at the start of the session. Then there is the “session expiry interval” property, a four-byte integer value in seconds which defaults to zero if omitted. If it is set to 0xFFFFFFFF (UINT_MAX), the session does not expire. To accomplish the above scenario:

msc {
    arcgradient="4", wordwraparcs=on;

    c [label="client"], b [label="broker"];

    c => b [label="connect cleanstart=true, expiry_interval=0xFFFFFFFF"];
    ...;
}

The MQTT-SN “offline keep alive” scenario is also catered for. By setting the expiry interval to a suitable non-zero value, the client can ensure that the session state is saved as long as it reconnects regularly. If the client disappears entirely, the session state will be cleaned up at some point. Both clients and servers are happy.

Shared subscriptions

To allow load balancing of high throughput topics, the concept of shared subscriptions is introduced to MQTT. Messages on these topics are sent to one of a group of subscribers rather than to them all. The subscriber indicates that the subscription is shared simply by subscribing to a special topic pattern:


$share/{ShareName}/{filter}

where ShareName is the name of the shared subscription group, and filter is the usual topic filter used in the subscribe request.

Optional server capabilities

Some server functionality is expensive to implement at large scale. In MQTT 5.0, the server can advertise the limitations on the functionality it provides in the connack properties. Some examples:

Retain Available
are retained messages supported?
Maximum QoS
the maximum publish QoS the server will accept
Maximum Packet Size
the maximum packet size the server will accept
Receive maximum
the maximum number of concurrent QoS 1 and 2 message the server will handle

Resource Constrained Clients and Performance Improvements

Various features fall into this category, including some already described. Some further examples follow.

Nolocal subscriptions

Up until MQTT 5.0, the publisher of a message will receive that message back if it is subscribed to the same topic. People often find this out in their first experience of writing an MQTT application, when they implement a shared chat room. There is now a subscribe option noLocal which when set, indicates that the publishing application should not receive its own messages.

msc {
    arcgradient="4", wordwraparcs=on;

    c [label="client"], b [label="broker"];

    c => b [label="subscribe topic=a"];
    b => c [label="suback"];
    c => b [label="publish topic=a"];
    b => c [label="publish topic=a"];
    ...;
    c => b [label="subscribe topic=b, noLocal"];
    b => c [label="suback"];
    c => b [label="publish topic=b"];
    ...;
}

Retained message control

Options on the subscribe request have been added to:

  • 0 = Send retained messages at the time of the subscribe
  • 1 = Send retained messages at subscribe only if the subscription does not currently exist
  • 2 = Do not send retained messages at the time of the subscribe

This could help particularly with the implementation of MQTT bridges from one broker to another.

Topic aliases

This capability exists in MQTT-SN, to reduce the size of the publish packet when long topic names are used. The publish request allows a numeric topic alias to be specified, which can be used in subsequent publish packets. Topic aliases on the client and the server are independent of each other, in much the same way as packet ids are.

msc {
    arcgradient="4", wordwraparcs=on;

    c [label="client"], b [label="broker"];

    c => b [label="publish topic=long_name,alias=1"];
    c => b [label="publish alias=1"];
    ...;
    b => c [label="publish topic=server_long_name, alias=1"];
    b => c [label="publish alias=1"];
    ...;
}

Topic aliases only exist for the lifetime of a TCP connection.

Specifying client limitations

To help protect implementations on small devices, the client can specify its limitations using properties on the connect packet. Some examples:

Maximum Packet Size
the maximum packet size the client can accept
Receive maximum
the maximum number of concurrent QoS 1 and 2 message the client can handle

It is an administrative action or decision on the part of the server to decide what to do with messages that it receives bound for a client for which that message exceeds the constraints. This is not particularly different from 3.1.1 where the message would be sent anyway, and then the client might be forced to disconnect as its only recourse. At a minimum, the server should probably emit a warning log message.

Eclipse Paho Progress

A release of the Eclipse Paho project is planned for June 2018 with its first implementations of MQTT 5.0. I first implemented a broker to test against in the Paho test project. It combines 3.1.1 and 5.0 implementations, and has been used by James Sutton to implement the Java MQTT 5.0 support. It is used in Travis and AppVeyor continuous integration tests for the MQTT 5.0 branches. Example output when you start it up is shown below.

My own C clients, embedded and main are planned to have a June release. The MQTT 5.0 implementations continue in the embedded mqttv5 and mqttv5 branches. Please do give your feedback or thoughts on these implementations as they progress via the GitHub issues:

A New Fate for the Eclipse Paho “Test” Broker?

If you’re familiar with the Eclipse Paho test material, you’ll know that I wrote an MQTT 3.1.1 broker in Python with the purpose of providing a benchmark or oracle against which other implementations could be compared. Last year, I added support for the new MQTT V5.0 definition, so that client implementations of V5, including my own, could be easily tested. It has been used by Paho colleagues of mine, James Sutton and Allan Stockdill-Mander to develop MQTT V5 Java and Golang client libraries.

Then, I added the missing TLS support, so that it could satisfy testing requirements for secured connections. Adding TLS support in Python turned out to be really easy, much easier than I expected. I know how hard it is to add OpenSSL support in C, and I was prepared for at least some proportion of that effort, but there was none. I enabled multiple MQTT listeners to be configured, a la RSMB/Mosquitto. That meant the broker was comprehensive enough to be used for automated testing of existing client implementations. I used it to replace a remote Mosquitto broker in the automated Paho C client testing for Windows using AppVeyor, as installing Mosquitto on Windows is a little tricky, and it works fine in that capacity. All I had to do in the AppVeyor configuration file was to add these lines:


- cmd: git clone https://github.com/eclipse/paho.mqtt.testing.git
- cmd: cd paho.mqtt.testing\interoperability
- ps: Start-Process C:\Python36\python -ArgumentList 'startbroker.py -c client_testing.conf'

to get the broker running locally. WebSockets support was already included, so it means that each MQTT listener supports both 3.1.1 and V5, WebSockets and TLS. The 3.1.1 and V5 clients can communicate with each other (although this work is not complete and tested yet), both through normal publish commands and retained messages.

In a recent project at work I had added persistence to a Python project by using the ZODB object database, and that had turned out to be really easy too. These experiences got me to thinking that it should be easy to add MQTT-SN support as well, and create a broker with the capabilities that I had envisaged for RSMB before it was superseded by Mosquitto. Roger Light, the author of Mosquitto, has intended to add MQTT-SN support for a long time, but wanted to restructure the internals first. Due to other commitments, and some licensing obstacles, this has not yet come about, and with the advent of MQTT V5 which will have a higher priority, looks even further out.

A broker written in Python will not be as efficient as Mosquitto, nor is it particularly scalable as currently written because it uses Python’s threading model which does not take advantage of multiple cores. But as it is so easy to add new capabilities, it could well be one of the most complete MQTT implementations, soonest. In this way it would be complementary to Mosquitto.

I have now experimented with adding MQTT-SN support, a framework for bridges, and an HTTP listener which can provide APIs to query and update the broker state and configuration. We can add APIs to allow queries to return information about the currently connected clients, their subscriptions and messages for instance. The set of capabilities I envisage looks like this:

  • TCP listener supporting WebSockets, TLS, MQTT 3.1.1 and 5.0
  • UDP listener supporting MQTT-SN with DTLS, multicast
  • other potential MQTT-SN listeners: BLE, ZigBee
  • HTTP listener for state/configuration APIs. The broker behaviour for test purposes can potentially be reconfigured dynamically
  • TCP bridge capable supporting MQTT 3.1.1 and 5.0, WebSockets and TLS
  • UDP bridge supporting MQTT-SN with DTLS, multicast
  • HTTP bridge supporting webhooks?
  • dynamic bridge connections – adding/deleting bridges
  • variety of persistence options including ZODB

I think it’s obvious to state that with these capabilities it could serve as an MQTT-SN gateway for services that support MQTT, as a conversion mechanism between MQTT V3.1.1 and V5, and a dynamic flexible component of an MQTT network. I would still keep a focus on enabling MQTT testing, including for test suite generation. A lot of this work could be completed in the first half of 2018, other commitments depending.

This brings me on to my main motivation for writing this blog post. Perhaps this broker should have a life of its own, separate to Paho, as an Eclipse IoT project. It could quite well do the job as part of Paho, conversely it could have a higher profile and encourage more community participation if stood on its own. So, if you have an interest in seeing this broker as an Eclipse IoT standalone project, from the point of view of using it, or also contributing to it, please let me know – thanks.

What’s happening with RSMB?

Some people will be aware that I wrote a small MQTT broker in about 2008, made available on IBM’s alphaWorks website. It was called RSMB (Really Small Message Broker) when released, because the name we used first for it, Nanobroker, was already taken. Somewhat amusingly, an IBM website for RSMB still exists.

A year or two later, Roger Light asked Andy Stanford-Clark why RSMB wasn’t open source (not my decision), so Andy suggested Roger write his own. And that’s how Mosquitto started, as a drop in replacement for RSMB. When MQTT software was being contributed to the Eclipse foundation, IBM contributed a Java client and my C client to the Paho project, and Mosquitto was contributed as the broker. IBM did contribute the RSMB source to the Mosquitto project on my encouragement, to serve as a repository of potentially useful code, and because it had support for MQTT-SN.

So in my mind, Mosquitto became the official replacement for RSMB, and I expected RSMB to outlive its usefulness pretty quickly. As it happens, MQTT-SN support in Mosquitto has been on the back burner ever since, because Roger wanted to rebase the internals of Mosquitto on an event library before tackling it. Unfortunately, this ran into a number of issues, social and technical. I’m still hoping that it will happen.

But one of the alternative approaches to MQTT-SN support is now available in Paho (written by Tomoaki Yamaguchi) – a transparent gateway which converts MQTT-SN into MQTT. Transparent because it creates a new MQTT connection for each MQTT-SN client, so that the MQTT broker has visibility of those clients. RSMB acts as an aggregating gateway, where one MQTT bridge connection carries the traffic for all MQTT-SN clients, and the MQTT broker sees only one.

I do wonder if an MQTT-SN to MQTT gateway will in fact be a better solution because it may allow easier support of additional underlying transports. The gateway has UDP and XBee right now, others such as BLE and even serial could be useful.

Mosquitto in the meantime has added further capabilities such as TLS and WebSocket support, and many more. If there were a niche that Mosquitto has left open then I would be happy to support RSMB in that, but I don’t think there is. The combination of Mosquitto and the Paho transparent gateway will do a better job all round.