MQTT-SN Client (emCute)

emCute, the MQTT-SN implementation for RIOT More...

Detailed Description

About

emCute is the implementation of the OASIS MQTT-SN protocol for RIOT. It is designed with a focus on small memory footprint and usability.

Design Decisions and Restrictions

The implementation is based on a 2-thread model: emCute needs one thread of its own, in which receiving of packets and sending of ping messages are handled. All 'user space functions' have to run from (a) different (i.e. user) thread(s). emCute uses thread flags to synchronize between threads.

Further know restrictions are:

Error Handling

This implementation tries minimize parameter checks to a minimum, checking as many parameters as feasible using assertions. For the sake of run-time stability and usability, typical overflow checks are always done during run- time and explicit error values returned in case of errors.

Implementation state

In the current state, emCute supports:

The following features are however still missing (but planned):

Todo:

Gateway discovery (so far there is no support for handling ADVERTISE, GWINFO, and SEARCHGW). Open question to answer here: how to put / how to encode the IPv(4/6) address AND the port of a gateway in the GwAdd field of the GWINFO message

QOS level 2

put the node to sleep (send DISCONNECT with duration field set)

handle DISCONNECT messages initiated by the broker/gateway

support for pre-defined and short topic IDs

handle (previously) active subscriptions on reconnect/disconnect

handle re-connect/disconnect from unresponsive gateway (in case a number of ping requests are unanswered)

react only to incoming ping requests that are actually send by the gateway we are connected to

Files

file  emcute.h
 emCute MQTT-SN interface definition
 
file  emcute_internal.h
 emCute internals
 

Data Structures

struct  emcute_topic_t
 MQTT-SN topic. More...
 
struct  emcute_sub
 Data-structure for keeping track of topics we register to. More...
 

Macros

#define EMCUTE_DEFAULT_PORT   (1883U)
 Default UDP port to listen on (also used as SRC port)
 
#define EMCUTE_BUFSIZE   (512U)
 Buffer size used for emCute's transmit and receive buffers. More...
 
#define EMCUTE_ID_MAXLEN   (196U)
 Maximum client ID length. More...
 
#define EMCUTE_TOPIC_MAXLEN   (196U)
 Maximum topic length. More...
 
#define EMCUTE_KEEPALIVE   (360) /* -> 6 min*/
 Keep-alive interval [in s]. More...
 
#define EMCUTE_T_RETRY   (15U) /* -> 15 sec */
 Re-send interval [in seconds]. More...
 
#define EMCUTE_N_RETRY   (3U)
 Number of retries when sending packets. More...
 

Typedefs

typedef void(* emcute_cb_t) (const emcute_topic_t *topic, void *data, size_t len)
 Signature for callbacks fired when publish messages are received. More...
 
typedef struct emcute_sub emcute_sub_t
 Data-structure for keeping track of topics we register to.
 

Enumerations

enum  {
  EMCUTE_DUP = 0x80, EMCUTE_QOS_MASK = 0x60, EMCUTE_QOS_2 = 0x40, EMCUTE_QOS_1 = 0x20,
  EMCUTE_QOS_0 = 0x00, EMCUTE_RETAIN = 0x10, EMCUTE_WILL = 0x08, EMCUTE_CS = 0x04,
  EMCUTE_TIT_MASK = 0x03, EMCUTE_TIT_SHORT = 0x02, EMCUTE_TIT_PREDEF = 0x01, EMCUTE_TIT_NORMAL = 0x00
}
 MQTT-SN flags. More...
 
enum  {
  EMCUTE_OK = 0, EMCUTE_NOGW = -1, EMCUTE_REJECT = -2, EMCUTE_OVERFLOW = -3,
  EMCUTE_TIMEOUT = -4, EMCUTE_NOTSUP = -5
}
 Possible emCute return values. More...
 

Functions

int emcute_con (sock_udp_ep_t *remote, bool clean, const char *will_topic, const void *will_msg, size_t will_msg_len, unsigned flags)
 Connect to a given MQTT-SN gateway (CONNECT) More...
 
int emcute_discon (void)
 Disconnect from the gateway we are currently connected to. More...
 
int emcute_reg (emcute_topic_t *topic)
 Get a topic ID for the given topic name from the gateway. More...
 
int emcute_pub (emcute_topic_t *topic, const void *buf, size_t len, unsigned flags)
 Publish data on the given topic. More...
 
int emcute_sub (emcute_sub_t *sub, unsigned flags)
 Subscribe to the given topic. More...
 
int emcute_unsub (emcute_sub_t *sub)
 Unsubscripbe the given topic. More...
 
int emcute_willupd_topic (const char *topic, unsigned flags)
 Update the last will topic. More...
 
int emcute_willupd_msg (const void *data, size_t len)
 Update the last will message. More...
 
void emcute_run (uint16_t port, const char *id)
 Run emCute, will 'occupy' the calling thread. More...
 
const char * emcute_type_str (uint8_t type)
 Return the string representation of the given type value. More...
 

Macro Definition Documentation

◆ EMCUTE_BUFSIZE

#define EMCUTE_BUFSIZE   (512U)

The overall buffer size used by emCute is this value time two (Rx + Tx).

Definition at line 111 of file emcute.h.

◆ EMCUTE_ID_MAXLEN

#define EMCUTE_ID_MAXLEN   (196U)
Note
Must be less than (256 - 6) AND less than (EMCUTE_BUFSIZE - 6).

Definition at line 121 of file emcute.h.

◆ EMCUTE_KEEPALIVE

#define EMCUTE_KEEPALIVE   (360) /* -> 6 min*/

The node will communicate this interval to the gateway send a ping message every time when this amount of time has passed.

For the default value, see spec v1.2, section 7.2 -> T_WAIT: > 5 min

Definition at line 143 of file emcute.h.

◆ EMCUTE_N_RETRY

#define EMCUTE_N_RETRY   (3U)

For the default value, see spec v1.2, section 7.2 -> N_RETRY: 3-5

Definition at line 161 of file emcute.h.

◆ EMCUTE_T_RETRY

#define EMCUTE_T_RETRY   (15U) /* -> 15 sec */

For the default value, see spec v1.2, section 7.2 -> T_RETRY: 10 to 15 sec

Definition at line 152 of file emcute.h.

◆ EMCUTE_TOPIC_MAXLEN

#define EMCUTE_TOPIC_MAXLEN   (196U)
Note
Must be less than (256 - 6) AND less than (EMCUTE_BUFSIZE - 6).

Definition at line 131 of file emcute.h.

Typedef Documentation

◆ emcute_cb_t

typedef void(* emcute_cb_t) (const emcute_topic_t *topic, void *data, size_t len)
Parameters
[in]topictopic the received data was published on
[in]datapublished data
[in]lenlength of data in bytes

Definition at line 216 of file emcute.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

All MQTT-SN functions only support a sub-set of the available flags. It is up to the user to only supply valid/supported flags to a function. emCute will trigger assertion fails on the use of unsupported flags (if compiled with DEVELHELP).

Refer to the MQTT-SN spec section 5.3.4 for further information.

Enumerator
EMCUTE_DUP 

duplicate flag

EMCUTE_QOS_MASK 

QoS level mask.

EMCUTE_QOS_2 

QoS level 2.

EMCUTE_QOS_1 

QoS level 1.

EMCUTE_QOS_0 

QoS level 0.

EMCUTE_RETAIN 

retain flag

EMCUTE_WILL 

will flag, used during CONNECT

EMCUTE_CS 

clean session flag

EMCUTE_TIT_MASK 

topic ID type mask

EMCUTE_TIT_SHORT 

topic ID: short

EMCUTE_TIT_PREDEF 

topic ID: pre-defined

EMCUTE_TIT_NORMAL 

topic ID: normal

Definition at line 174 of file emcute.h.

◆ anonymous enum

anonymous enum
Enumerator
EMCUTE_OK 

everything went as expect

EMCUTE_NOGW 

error: not connected to a gateway

EMCUTE_REJECT 

error: operation was rejected by broker

EMCUTE_OVERFLOW 

error: ran out of buffer space

EMCUTE_TIMEOUT 

error: timeout

EMCUTE_NOTSUP 

error: feature not supported

Definition at line 192 of file emcute.h.

Function Documentation

◆ emcute_con()

int emcute_con ( sock_udp_ep_t remote,
bool  clean,
const char *  will_topic,
const void *  will_msg,
size_t  will_msg_len,
unsigned  flags 
)

When called while already connected to a gateway, call emcute_discon() first to disconnect from the current gateway.

Parameters
[in]remoteaddress and port of the target MQTT-SN gateway
[in]cleanset to true to start a clean session
[in]will_topiclast will topic name, no last will will be configured if set to NULL
[in]will_msglast will message content, will be ignored if will_topic is set to NULL
[in]will_msg_lenlength of will_msg in byte
[in]flagsflags used for the last will, allowed are retain and QoS
Returns
EMCUTE_OK on success
EMCUTE_NOGW if already connected to a gateway
EMCUTE_REJECT on connection refused by gateway
EMCUTE_TIMEOUT on connection timeout

◆ emcute_discon()

int emcute_discon ( void  )
Returns
EMCUTE_OK on success
EMCUTE_GW if not connected to a gateway
EMCUTE_TIMEOUT on response timeout

◆ emcute_pub()

int emcute_pub ( emcute_topic_t topic,
const void *  buf,
size_t  len,
unsigned  flags 
)
Parameters
[in]topictopic to send data to, topic must be registered (topic.id must populated).
[in]bufdata to publish
[in]lenlength of data in bytes
[in]flagsflags used for publication, allowed are QoS and retain
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_REJECT if publish message was rejected (QoS > 0 only)
EMCUTE_OVERFLOW if length of data exceeds EMCUTE_BUFSIZE
EMCUTE_TIMEOUT on connection timeout (QoS > 0 only)
EMCUTE_NOTSUP on unsupported flag values

◆ emcute_reg()

int emcute_reg ( emcute_topic_t topic)
Parameters
[in,out]topictopic to register, topic.name must not be NULL
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_OVERFLOW if length of topic name exceeds EMCUTE_TOPIC_MAXLEN
EMCUTE_TIMEOUT on connection timeout

◆ emcute_run()

void emcute_run ( uint16_t  port,
const char *  id 
)

This function will run the emCute message receiver. It will block the thread it is running in.

Parameters
[in]portUDP port used for listening (default: 1883)
[in]idclient ID (should be unique)

◆ emcute_sub()

int emcute_sub ( emcute_sub_t sub,
unsigned  flags 
)

When calling this function, sub->topic.name and sub->cb must be set.

Parameters
[in,out]subsubscription context, sub->topic.name and sub->cb must not be NULL.
[in]flagsflags used when subscribing, allowed are QoS, DUP, and topic ID type
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_OVERFLOW if length of topic name exceeds EMCUTE_TOPIC_MAXLEN
EMCUTE_TIMEOUT on connection timeout

◆ emcute_type_str()

const char* emcute_type_str ( uint8_t  type)

This function is for debugging purposes.

Parameters
[in]typeMQTT-SN message type
Returns
string representation of the given type
'UNKNOWN' on invalid type value

◆ emcute_unsub()

int emcute_unsub ( emcute_sub_t sub)
Parameters
[in]subsubscription context
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_TIMEOUT on connection timeout

◆ emcute_willupd_msg()

int emcute_willupd_msg ( const void *  data,
size_t  len 
)
Parameters
[in]datanew message to send on last will
[in]lenlength of data in bytes
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_OVERFLOW if length of the given message exceeds EMCUTE_BUFSIZE
EMCUTE_REJECT on rejection by the gateway
EMCUTE_TIMEOUT on response timeout

◆ emcute_willupd_topic()

int emcute_willupd_topic ( const char *  topic,
unsigned  flags 
)
Parameters
[in]topicnew last will topic
[in]flagsflags used for the topic, allowed are QoS and retain
Returns
EMCUTE_OK on success
EMCUTE_NOGW if not connected to a gateway
EMCUTE_OVERFLOW if length of topic name exceeds EMCUTE_TOPIC_MAXLEN
EMCUTE_REJECT on rejection by the gateway
EMCUTE_TIMEOUT on response timeout