Sometimes simple things can take a lot of time, such as this: How to make the Paho MQTT-SN gateway to listen to UDP6 instead of the standard UDP4 ports…
A lot can be written about MQTT-SN and it’s counterpart MQTT. To keep it simple and short, MQTT-SN (SN for Sensor Networks) uses UDP instead of TCP/IP and is streamlined to be more efficient in transmitting information, and so more adequate to be used on constrained devices than MQTT on WSN (Wireless Sensor Networks).
One important key element in using MQTT-SN is that MQTT-SN clients use UDP broadcasts to find gateways, and so they have no need to hardcode a broker address on the firmware code, since gateways can be dynamically discover at run time. Still MQTT-SN depends on MQTT broker to connect to the outside world (and that’s why MQTT-SN is a gateway, not a broker), but that is configured at the gateway level, not at the node level.
Compiling and configuring:
If we just clone the MQTT-SN Github repository, we can for UDP version 4, just do the following:
git clone https://github.com/eclipse/paho.mqtt-sn.embedded-c cd MQTTSNGateway/ make
And that’s it. On the Build/ directory there are the executables, among them the MQTT-SNGateway, and on the current directory there is the configuration file gateway.conf that is used by the gateway to startup. Out of the box the only thing that we need to change is the upstream MQTT broker address that by default points to the iot.eclipse.org MQTT broker, the gateway name, and maybe the ports:
BrokerName=iot.eclipse.org BrokerPortNo=1883 BrokerSecurePortNo=8883 GatewayID=1 GatewayName=PahoGateway-01 KeepAlive=900 # UDP GatewayPortNo=10000 MulticastIP=184.108.40.206 MulticastPortNo=1883
So if we start with this config, the output is:
20190612 142837.189 PahoGateway-01 has been started. ConfigFile: ./gateway.conf PreDefFile: ./predefinedTopic.conf SensorN/W: UDP Multicast 220.127.116.11:1883 Gateway Port 10000 Broker: 172.17.0.4 : 1883, 8883 RootCApath: (null) RootCAfile: (null) CertKey: (null) PrivateKey: (null)
We can see that in this case my upstream broker is at 172.17.0.4 (a docker image of the Mosquitto broker).
Checking which ports the gateway is listening:
root@b74f5ad3fd8e:/app/mqttsn# lsof -c MQTT-SNGateway -a -i4 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME MQTT-SNGa 923 root 3u IPv4 5017719 0t0 UDP *:10000 MQTT-SNGa 923 root 4u IPv4 5017720 0t0 UDP *:1883 root@b74f5ad3fd8e:/app/mqttsn# lsof -c MQTT-SNGateway -a -i6 root@b74f5ad3fd8e:/app/mqttsn#
We can see that the gateway is listening on UDP4 and not on UDP6.
Sensor networks such as Openthread networks work only with IPv6… and so the MQTT-SN gateway must listen to UDP6 instead of UDP4. It can still communicate with the MQTT broker over IPv4, and hence bridging the IPv4 network with the IPv6 sensor network.
To add support to UDP6 for the MQTT-SN gateway we need to change the Makefile (and hence the time to find information for this little bit… ) to change the protocol used by the sensor network and recompile.
So again on the source folder for the MQTT-SN gateway, edit the Makefile and change the following line from
SENSORNET := udp
SENSORNET := udp6
Or just change the parameter at the make call: make SENSORNET=udp6
And then clean and build:
make clean make SENSORNET=udp6
We have now a MQTT-SN gateway version for UDP6. We need now to add the configuration entries to the gateway configuration file so that the UDP6 configuration is set:
#UDP v6 GatewayUDP6Broadcast = ff03::1 GatewayUDP6Port = 47193 GatewayUDP6If = wpan0
We can now start the UDP6 MQTT-SN enabled version:
20190612 144124.280 PahoGateway-01 has been started. ConfigFile: ./gateway.conf PreDefFile: ./predefinedTopic.conf SensorN/W: Gateway Port: 47193 Broadcast Address: ff03::1 Interface: wpan0 Broker: 172.17.0.4 : 1883, 8883 RootCApath: (null) RootCAfile: (null) CertKey: (null) PrivateKey: (null)
Specifically in this case the GatewayUDP6If interface that is defined is the NCP OpenThread interface, but it should be the interface where we want the gateway to listen. The broadcast address is the address defined on the Nordic SDK for Thread, namely on the file mqttsn_packet_internal.h.
Checking the ports:
root@b74f5ad3fd8e:/app/mqttsn# lsof -c MQTT-SNGateway -a -i4 root@b74f5ad3fd8e:/app/mqttsn# lsof -c MQTT-SNGateway -a -i6 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME MQTT-SNGa 947 root 4u IPv6 5050130 0t0 UDP *:47193 root@b74f5ad3fd8e:/app/mqttsn#
And that’s it.
A simple lack of documentation regarding MQTT-SN and UDP6 took a while to solve since it was so “simple”.
Still one still needs two compiled versions of MQTT-SN for supporting UDP4 and UDP6 based networks, but since MQTT-SN is light there is no big issue with this.