MQTT-SN Client (emCute)

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

Detailed Description

emCute, the MQTT-SN implementation for RIOT

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_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)

Buffer size used for emCute's transmit and receive buffers.

Note
The buffer size MUST be less than 32768 on 16-bit and 8-bit platforms to prevent buffer overflows.

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

Definition at line 114 of file emcute.h.

◆ EMCUTE_KEEPALIVE

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

Keep-alive interval [in s].

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 136 of file emcute.h.

◆ EMCUTE_N_RETRY

#define EMCUTE_N_RETRY   (3U)

Number of retries when sending packets.

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

Definition at line 154 of file emcute.h.

◆ EMCUTE_T_RETRY

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

Re-send interval [in seconds].

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

Definition at line 145 of file emcute.h.

◆ EMCUTE_TOPIC_MAXLEN

#define EMCUTE_TOPIC_MAXLEN   (196U)

Maximum topic length.

Note
Must be less than (256 - 6) AND less than (EMCUTE_BUFSIZE - 6).

Definition at line 124 of file emcute.h.

Typedef Documentation

◆ emcute_cb_t

typedef void(* emcute_cb_t) (const emcute_topic_t *topic, void *data, size_t len)

Signature for callbacks fired when publish messages are received.

Parameters
[in]topictopic the received data was published on
[in]datapublished data, can be NULL
[in]lenlength of data in bytes

Definition at line 209 of file emcute.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

MQTT-SN flags.

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 167 of file emcute.h.

◆ anonymous enum

anonymous enum

Possible emCute return values.

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 185 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 
)

Connect to a given MQTT-SN gateway (CONNECT)

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  )

Disconnect from the gateway we are currently connected to.

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 
)

Publish data on the given topic.

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)

Get a topic ID for the given topic name from the gateway.

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 
)

Run emCute, will 'occupy' the calling thread.

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 
)

Subscribe to the given topic.

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)

Return the string representation of the given type value.

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)

Unsubscripbe the given topic.

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 
)

Update the last will message.

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 
)

Update the last will topic.

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