-
Notifications
You must be signed in to change notification settings - Fork 57
MQTTSN client implementation
This project was made during Google Summer of Code 2014 - 'MQTT-SN implementation for Wiselib'
Introduction
MQTT is machine-to-machine connectivity protocol. Is is designed to use publisher/subscriber message pattern and is very lightweight. Clients are connected to a MQTT broker and can work as publishers and subscribers. Publishers registers topics on a broker and then send messages for these certain topics, without a knowledge about any receivers. Subscribers express interest in one or more topics and receive only messages sent for topics which they are subscribed for.
MQTT-SN is a variation of MQTT designed especially for sensor networks. It an open communication standard between devices that communicate with each other without human interaction. It is suitable for constrained environments which consist of low-power devices with limited processing capabilities. As MQTT-SN is slightly different from MQTT it is needed to use MQTT-SN gateway between clients and a broker.
Code structure
Code of MQTT-SN client is located in wiselib.testing/algorithms/protocols/mqttsn
messages
- contains implementation of messages:
- ADVERTISE
- CONACK
- CONNECT
- DISCONNECT
- GWINFO
- PINGREQ
- PINGRESP
- PUBACK
- PUBLISH
- REGACK
- REGISTER
- SEARCHGW
- SUBACK
- SUBSCRIBE
- UNSUBACK
- UNSUBSCRIBE
- WILLMSG
- WILLMSGREQ
- WILLTOPIC
- WILLTOPICREQ
mqttsn_flex_static_string
- simple string non template parameter class designed to create fixed size string objects without using dynamic allocation
mqttsn_messages.h
- contains includes to all messages
mqttsn_topics.h
- class which represents a container for registered/subscribed topics
mqttsn.h
- class which represents an instance of a MQTT-SN client
Implementation
First thing to do when writing MQTT-SN client application is to create an instance and initialize it. This is a template of application:
#include "external_interface/external_interface.h"
#include "algorithms/protocols/mqttsn/mqttsn.h"
typedef wiselib::OSMODEL Os;
typedef wiselib::MqttSn<Os, Os::Radio> MqttSnClient;
class MqttsnExampleApplication
{
public:
typedef MqttsnExampleApplication self_type;
void init( Os::AppMainParameter& value )
{
radio_ = &wiselib::FacetProvider<Os, Os::Radio>::get_facet( value );
timer_ = &wiselib::FacetProvider<Os, Os::Timer>::get_facet( value );
debug_ = &wiselib::FacetProvider<Os, Os::Debug>::get_facet( value );
rand_ = &wiselib::FacetProvider<Os, Os::Rand>::get_facet( value );
debug_->debug( "Hello World from MqttSn Client!\n" );
timer_->set_timer<MqttsnExampleApplication,
&MqttsnExampleApplication::start>( 1000, this, 0 );
}
void start( void* )
{
// INITIALIZATION
mqttsn_client.init( *radio_, *debug_, *timer_, *rand_ );
}
/ --------------------------------------------------------------------
private:
Os::Radio::self_pointer_t radio_;
Os::Timer::self_pointer_t timer_;
Os::Debug::self_pointer_t debug_;
Os::Rand::self_pointer_t rand_;
MqttSnClient mqttsn_client;
};
// --------------------------------------------------------------------------
wiselib::WiselibApplication<Os, MqttsnExampleApplication> example_app;
// --------------------------------------------------------------------------
void application_main( Os::AppMainParameter& value )
{
example_app.init( value );
}
Before client is initialized we can set a type of connection procedure with will flag
-
Setting will connect - sets a
will flag
in CONNECT message and then providedwill topic
andwill message
will be sent as reponse for WILLTOPICREQ and WILLMSGREQmqttsn_client.set_will_connect("ExampleTopic", "Not connected");
After client is initialized we can use MQTT specific operations like:
-
Topic registration - to publish a data for registered topic
mqttsn_client.send_register("TopicToRegister");
-
Topic subscription - to receive data published for subscribed topic
mqttsn_client.send_subscribe("TopicToSubscribe");
-
Topic unsubscription - to stop receiving data published for previously subscribed topic
mqttsn_client.send_unsubscribe("TopicToUnsubscribe");
-
Publishing data - nodes which are subscribed for a topic which we publish for will receive a data
block_data_t message[] = {'H','e','l','l','o','\0'};
mqttsn_client.send_publish("RegisteredTopicName", message, sizeof(message));
-
Will topic update - to update a topic previously provided by set_will_connect(...) function
mqttsn_client.send_will_topic_update("WillTopicUpd");
-
Will message update - to update a message previously provided by set_will_connect(...) function
mqttsn_client.send_will_msg_update("WillMessageUpd");
-
Delete will data - to delete will data previously provided by set_will_connect(...) function
mqttsn_client.send_delete_will();
-
Disconnect - disconnects with currently connected gateway
mqttsn_client.send_disconnect();
Registering callbacks for PUBLISH messages
It is possible to register a function which will process a data provided by PUBLISH function.
-
Global callback registration - registers a callback which will be used with every received PUBLISH message
void myRecvPublish( const char* topic_name, block_data_t *data )
{
...
}
mqttsn_client.reg_recv_publish<self_type, &self_type::myRecvPublish>( this );
-
Specific topics callback registration - register a callback which will be used only for received PUBLISH messages connected with specified topic, this callback has higher priority than a global one
void myRecvPublish( const char* topic_name, block_data_t *data )
{
...
}
void myRecvPublish2( const char* topic_name, block_data_t *data )
{
...
}
mqttsn_client.reg_recv_publish_topic<self_type, &self_type::myRecvPublish>(this, "Topic1");
mqttsn_client.reg_recv_publish_topic<self_type, &self_type::myRecvPublish2>(this, "Topic2");
Check Example MQTT-SN network with use of Raspberry Pi and Arduino
Łukasz Dmitrowski