This is a simple tutorial showing how to use the embeNET MQTT-SN Client API.
The MQTT-SN Client service relies on the UDP networking being available. It is thus advised to start this service once the underlying networking is operational. In embeNET-enabled node, the networking starts once the node joins the network, which is signalled through the 'onJoined' callback. In this tutorial this callback will start the MQTT-SN Client service.
Once the client is started it will try to connect to a MQTT-SN gateway, given its IPv6 address and port. In this tutorial we will assume, that the gateway runs in the border router on a default port no 1885. Once connected the client will be able to subscribe to MQTT topics, register new topics as well as publish and receive data on these topics.
The software architecture of this client is event driven, meaning that all API calls are non-blocking, and operations requiring longer time are started and their end is signalled through an application defined callback.
MQTT-SN is a UDP-based version of the popular MQTT protocol, used extensively in IoT networks and beyond. In MQTT-SN the clients connect to the MQTT-SN Gateway or MQTT-SN Forwarder (which in turn connects to the MQTT-SN Gateway). The Gateway connects to the standard MQTT broker (or has an integrated broker). The main function of the Gateway is protocol translation between MQTT-SN and MQTT.
This client supports the following functions:
All the functions of this MQTT-SN client are available in the mqttsn_client.h header file:
This MQTT-SN Client follows an object-oriented approach in C, in which there is a single structure representing the client's state. The structure is MQTTSNClient and it needs to instantiated by the user code:
Before any usage, the MQTT-SN client needs to be initialized by a call to MQTTSN_CLIENT_Init
In the above example, the MQTT-SN client will use socket on local port 1885 to receive messages from the gateway, and this socket will be used later to communicate with the gateway. The client will introduce itself as "Client0". Be aware that this client identification string must be unique. One way to achieve this is to use the node's UID in client Id like this:
In order to react to MQTT-SN client events, the application can register callbacks during client initialization. This provides the intended way of working with this client. The callbacks are gathered in the MQTTSNClientEventHandlers structure. All callbacks are optional, meaning that setting each to NULL will disable the callback.
The following example shows how to set up the callbacks:
As mentioned in the overview, we will typically start the MQTT-SN client service once we have connected to the network. First we need to connect to the gateway. We can do that through a call to MQTTSN_CLIENT_Connect. Below is a minimal example of the 'onJoined' embeNET Node callback implementation:
Once connected to the gateway, the client will call the MQTTSNClientEventHandlers::onConnected callback, where further interaction with the gateway can take place.
In MQTT-SN the topics need to be registered in the gateway, before they can be used. The topic registration allows the gateway to assign a topic ID (MQTTSNTopicId) so that the clients can use it instead of string topic names. This makes the UDP payloads much smaller.
In order to register a topic, the application needs to call MQTTSN_CLIENT_RegisterTopic function:
If successfully registered, the onTopicRegisteredByClient will be called as callback:
The topics can also be registered by the gateway. The gateway may have a set of predefined topics, that it wishes to register in each connecting client. For each such topic, the MQTTSNClientEventHandlers::onTopicRegisteredByGateway callback will be called.
This may also happen when the client gets disconnected from the gateway and connects back again. Is such scenario the gateway will update the client with topics it previously registered at the gateway. Again, for each such topic, the MQTTSNClientEventHandlers::onTopicRegisteredByGateway callback will be called. To avoid this particular scenario, the client can connect using the MQTTSN_CLIENT_CleanConnect instead of MQTTSN_CLIENT_Connect to force the gateway 'forget' all previous topics associated with that client.
Wether the topic was registered by the client or by the gateway, the client application can always check the ID of the topic through a call to MQTTSN_CLIENT_GetTopicId
Once the topic is registered, the client can publish on the given topic using either a full topic name and the MQTTSN_CLIENT_PublishMessage function:
or topic ID and the MQTTSN_CLIENT_PublishMessageById function:
The client can subscribe to a topic and receive notifications once any data is published on that topic by any other client. To do that the application code needs to call MQTTSN_CLIENT_Subscribe providing the topic name and the callback function that will be called when the data on the given topic is published:
For more information see MQTT-SN Client