1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #15240 from akshaim/Kconfig_EMCute_1

MQTT-SN Clients ( Emcute/ Asymcute) : Kconfig Updates
This commit is contained in:
Leandro Lanzieri 2020-12-01 09:47:09 +01:00 committed by GitHub
commit 4b7bb8719f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 226 additions and 101 deletions

View File

@ -257,7 +257,7 @@ static int _cmd_connect(int argc, char **argv)
return 1; return 1;
} }
if (ep.port == 0) { if (ep.port == 0) {
ep.port = MQTTSN_DEFAULT_PORT; ep.port = CONFIG_ASYMCUTE_DEFAULT_PORT;
} }
/* get request context */ /* get request context */

View File

@ -31,7 +31,6 @@
#ifndef EMCUTE_ID #ifndef EMCUTE_ID
#define EMCUTE_ID ("gertrud") #define EMCUTE_ID ("gertrud")
#endif #endif
#define EMCUTE_PORT (1883U)
#define EMCUTE_PRIO (THREAD_PRIORITY_MAIN - 1) #define EMCUTE_PRIO (THREAD_PRIORITY_MAIN - 1)
#define NUMOFSUBS (16U) #define NUMOFSUBS (16U)
@ -46,7 +45,7 @@ static char topics[NUMOFSUBS][TOPIC_MAXLEN];
static void *emcute_thread(void *arg) static void *emcute_thread(void *arg)
{ {
(void)arg; (void)arg;
emcute_run(EMCUTE_PORT, EMCUTE_ID); emcute_run(CONFIG_EMCUTE_DEFAULT_PORT, EMCUTE_ID);
return NULL; /* should never be reached */ return NULL; /* should never be reached */
} }
@ -74,7 +73,7 @@ static unsigned get_qos(const char *str)
static int cmd_con(int argc, char **argv) static int cmd_con(int argc, char **argv)
{ {
sock_udp_ep_t gw = { .family = AF_INET6, .port = EMCUTE_PORT }; sock_udp_ep_t gw = { .family = AF_INET6, .port = CONFIG_EMCUTE_DEFAULT_PORT };
char *topic = NULL; char *topic = NULL;
char *message = NULL; char *message = NULL;
size_t len = 0; size_t len = 0;

View File

@ -60,37 +60,58 @@ extern "C" {
/** /**
* @defgroup net_asymcute_conf Asymcute (MQTT-SN Client) compile configurations * @defgroup net_asymcute_conf Asymcute (MQTT-SN Client) compile configurations
* @ingroup config * @ingroup net_mqtt_conf
* @brief Compile-time configuration options for Asymcute, an asynchronous
* MQTT-SN implementation based on the OASIS MQTT-SN protocol. It
* provides a flexible interface that allows users to issue any number
* of concurrent requests to one or more different gateways
* simultaneously.
* @{ * @{
*/ */
/**
* @brief Default UDP port to listen on. Usage can be found in
* examples/asymcute_mqttsn. Application code is expected to use this
* macro to assign the default port.
*/
#ifndef CONFIG_ASYMCUTE_DEFAULT_PORT
#define CONFIG_ASYMCUTE_DEFAULT_PORT (1883U)
#endif
/** /**
* @brief Default buffer size for Asymcute client (as exponent of 2^n) * @brief Default buffer size for Asymcute client (as exponent of 2^n)
* *
* As the buffer size ALWAYS needs to be power of two, this option represents * @deprecated Use @ref CONFIG_ASYMCUTE_BUFSIZE instead. Will be removed after
* the exponent of 2^n, which will be used as the size of the buffer. * 2021.04 release.
*/ */
#ifndef CONFIG_ASYMCUTE_BUFSIZE_EXP #ifndef CONFIG_ASYMCUTE_BUFSIZE_EXP
#define CONFIG_ASYMCUTE_BUFSIZE_EXP (7U) #define CONFIG_ASYMCUTE_BUFSIZE_EXP (7U)
#endif #endif
/**
* @brief Default buffer size used for receive and request buffers
*/
#ifndef CONFIG_ASYMCUTE_BUFSIZE
#define CONFIG_ASYMCUTE_BUFSIZE (128U)
#endif
/** /**
* @brief Maximum topic length * @brief Maximum topic length
* *
* @note Must be less than (256 - 8) AND less than ( @ref ASYMCUTE_BUFSIZE - 8). * @note Must be less than (256 - 8) AND less than ( @ref CONFIG_ASYMCUTE_BUFSIZE - 8).
*/ */
#ifndef CONFIG_ASYMCUTE_TOPIC_MAXLEN #ifndef CONFIG_ASYMCUTE_TOPIC_MAXLEN
#define CONFIG_ASYMCUTE_TOPIC_MAXLEN (32U) #define CONFIG_ASYMCUTE_TOPIC_MAXLEN (32U)
#endif #endif
/** /**
* @brief Keep alive interval [in s] communicated to the gateway * @brief Keep alive interval [in s] communicated to the gateway
* *
* keep alive interval in seconds which is communicated to the gateway in the * Keep alive interval in seconds which is communicated to the gateway in the
* CONNECT message. For more information, see MQTT-SN Spec v1.2, section 5.4.4. * CONNECT message. For more information, see MQTT-SN Spec v1.2, section 5.4.4.
* For default values,see section 7.2 -> TWAIT: > 5 min. * For default values,see section 7.2 -> TWAIT: > 5 min.
*/ */
#ifndef CONFIG_ASYMCUTE_KEEPALIVE #ifndef CONFIG_ASYMCUTE_KEEPALIVE
#define CONFIG_ASYMCUTE_KEEPALIVE (360) #define CONFIG_ASYMCUTE_KEEPALIVE (360)
#endif #endif
/** /**
@ -102,7 +123,7 @@ extern "C" {
* @note Must be less than @ref CONFIG_ASYMCUTE_KEEPALIVE * @note Must be less than @ref CONFIG_ASYMCUTE_KEEPALIVE
*/ */
#ifndef CONFIG_ASYMCUTE_KEEPALIVE_PING #ifndef CONFIG_ASYMCUTE_KEEPALIVE_PING
#define CONFIG_ASYMCUTE_KEEPALIVE_PING ((CONFIG_ASYMCUTE_KEEPALIVE / 4) * 3) #define CONFIG_ASYMCUTE_KEEPALIVE_PING ((CONFIG_ASYMCUTE_KEEPALIVE / 4) * 3)
#endif #endif
/** /**
@ -116,7 +137,7 @@ extern "C" {
* section 6.13. For default values, see section 7.2 -> Tretry: 10 to 15 sec. * section 6.13. For default values, see section 7.2 -> Tretry: 10 to 15 sec.
*/ */
#ifndef CONFIG_ASYMCUTE_T_RETRY #ifndef CONFIG_ASYMCUTE_T_RETRY
#define CONFIG_ASYMCUTE_T_RETRY (10U) #define CONFIG_ASYMCUTE_T_RETRY (10U)
#endif #endif
/** /**
@ -129,29 +150,22 @@ extern "C" {
* For default values, see section 7.2 -> Nretry: 3-5. * For default values, see section 7.2 -> Nretry: 3-5.
*/ */
#ifndef CONFIG_ASYMCUTE_N_RETRY #ifndef CONFIG_ASYMCUTE_N_RETRY
#define CONFIG_ASYMCUTE_N_RETRY (3U) #define CONFIG_ASYMCUTE_N_RETRY (3U)
#endif #endif
/** @} */ /** @} */
#ifndef ASYMCUTE_BUFSIZE
/**
* @brief Default buffer size used for receive and request buffers
*/
#define ASYMCUTE_BUFSIZE (1 << CONFIG_ASYMCUTE_BUFSIZE_EXP)
#endif
#ifndef ASYMCUTE_HANDLER_PRIO #ifndef ASYMCUTE_HANDLER_PRIO
/** /**
* @brief Default priority for Asymcute's handler thread * @brief Default priority for Asymcute's handler thread
*/ */
#define ASYMCUTE_HANDLER_PRIO (THREAD_PRIORITY_MAIN - 2) #define ASYMCUTE_HANDLER_PRIO (THREAD_PRIORITY_MAIN - 2)
#endif #endif
#ifndef ASYMCUTE_HANDLER_STACKSIZE #ifndef ASYMCUTE_HANDLER_STACKSIZE
/** /**
* @brief Default stack size for Asymcute's handler thread * @brief Default stack size for Asymcute's handler thread
*/ */
#define ASYMCUTE_HANDLER_STACKSIZE (THREAD_STACKSIZE_DEFAULT) #define ASYMCUTE_HANDLER_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#endif #endif
#ifndef ASYMCUTE_LISTENER_PRIO #ifndef ASYMCUTE_LISTENER_PRIO
@ -160,14 +174,14 @@ extern "C" {
* *
* @note Must be of higher priority than @ref ASYMCUTE_HANDLER_PRIO * @note Must be of higher priority than @ref ASYMCUTE_HANDLER_PRIO
*/ */
#define ASYMCUTE_LISTENER_PRIO (THREAD_PRIORITY_MAIN - 3) #define ASYMCUTE_LISTENER_PRIO (THREAD_PRIORITY_MAIN - 3)
#endif #endif
#ifndef ASYMCUTE_LISTENER_STACKSIZE #ifndef ASYMCUTE_LISTENER_STACKSIZE
/** /**
* @brief Default stack size for an Asymcute listener thread * @brief Default stack size for an Asymcute listener thread
*/ */
#define ASYMCUTE_LISTENER_STACKSIZE (THREAD_STACKSIZE_DEFAULT) #define ASYMCUTE_LISTENER_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#endif #endif
/** /**
@ -268,7 +282,7 @@ struct asymcute_req {
void *arg; /**< internally used additional state */ void *arg; /**< internally used additional state */
event_callback_t to_evt; /**< timeout event */ event_callback_t to_evt; /**< timeout event */
event_timeout_t to_timer; /**< timeout timer */ event_timeout_t to_timer; /**< timeout timer */
uint8_t data[ASYMCUTE_BUFSIZE]; /**< buffer holding the request's data */ uint8_t data[CONFIG_ASYMCUTE_BUFSIZE]; /**< buffer holding the request's data */
size_t data_len; /**< length of the request packet in byte */ size_t data_len; /**< length of the request packet in byte */
uint16_t msg_id; /**< used message id for this request */ uint16_t msg_id; /**< used message id for this request */
uint8_t retry_cnt; /**< retransmission counter */ uint8_t retry_cnt; /**< retransmission counter */
@ -290,7 +304,7 @@ struct asymcute_con {
* connection */ * connection */
uint8_t keepalive_retry_cnt; /**< keep alive transmission counter */ uint8_t keepalive_retry_cnt; /**< keep alive transmission counter */
uint8_t state; /**< connection state */ uint8_t state; /**< connection state */
uint8_t rxbuf[ASYMCUTE_BUFSIZE]; /**< connection specific receive buf */ uint8_t rxbuf[CONFIG_ASYMCUTE_BUFSIZE]; /**< connection specific receive buf */
char cli_id[MQTTSN_CLI_ID_MAXLEN + 1]; /**< buffer to store client ID */ char cli_id[MQTTSN_CLI_ID_MAXLEN + 1]; /**< buffer to store client ID */
}; };

View File

@ -95,14 +95,23 @@
extern "C" { extern "C" {
#endif #endif
#ifndef EMCUTE_DEFAULT_PORT
/** /**
* @brief Default UDP port to listen on (also used as SRC port) * @defgroup net_emcute_conf EmCute (MQTT-SN Client) compile configurations
* @ingroup net_mqtt_conf
* @brief Compile-time configuration options for emCute, an implementation
* of the OASIS MQTT-SN protocol for RIOT. It is designed with a focus
* on small memory footprint and usability
* @{
*/ */
#define EMCUTE_DEFAULT_PORT (1883U) /**
* @brief Default UDP port to listen on (also used as SRC port). Usage can be
* found in examples/emcute_mqttsn. Application code is expected to use
* this macro to assign the default port.
*/
#ifndef CONFIG_EMCUTE_DEFAULT_PORT
#define CONFIG_EMCUTE_DEFAULT_PORT (1883U)
#endif #endif
#ifndef EMCUTE_BUFSIZE
/** /**
* @brief Buffer size used for emCute's transmit and receive buffers * @brief Buffer size used for emCute's transmit and receive buffers
* *
@ -111,48 +120,57 @@ extern "C" {
* *
* The overall buffer size used by emCute is this value time two (Rx + Tx). * The overall buffer size used by emCute is this value time two (Rx + Tx).
*/ */
#define EMCUTE_BUFSIZE (512U) #ifndef CONFIG_EMCUTE_BUFSIZE
#define CONFIG_EMCUTE_BUFSIZE (512U)
#endif #endif
#ifndef EMCUTE_TOPIC_MAXLEN
/** /**
* @brief Maximum topic length * @brief Maximum topic length
* *
* @note **Must** be less than (256 - 6) AND less than * @note **Must** be less than (256 - 6) AND less than ( @ref CONFIG_EMCUTE_BUFSIZE - 6 )
* (@ref EMCUTE_BUFSIZE - 6).
*/ */
#define EMCUTE_TOPIC_MAXLEN (196U) #ifndef CONFIG_EMCUTE_TOPIC_MAXLEN
#define CONFIG_EMCUTE_TOPIC_MAXLEN (196U)
#endif #endif
#ifndef EMCUTE_KEEPALIVE
/** /**
* @brief Keep-alive interval [in s] * @brief Keep-alive interval [in seconds] communicated to the gateway
* *
* The node will communicate this interval to the gateway send a ping message * Keep alive interval in seconds which is communicated to the gateway in the
* every time when this amount of time has passed. * CONNECT message. For more information, see MQTT-SN Spec v1.2, section 5.4.4.
* * For default values, see section 7.2 -> TWAIT: > 5 min.
* For the default value, see spec v1.2, section 7.2 -> T_WAIT: > 5 min
*/ */
#define EMCUTE_KEEPALIVE (360) /* -> 6 min*/ #ifndef CONFIG_EMCUTE_KEEPALIVE
#define CONFIG_EMCUTE_KEEPALIVE (360) /* -> 6 min*/
#endif #endif
#ifndef EMCUTE_T_RETRY
/** /**
* @brief Re-send interval [in seconds] * @brief Re-send interval [in seconds]
* *
* For the default value, see spec v1.2, section 7.2 -> T_RETRY: 10 to 15 sec * Interval used for timing the retry messages which are sent when the expected
* reply from GW is not received. The retry timer is started by the client when
* the message is sent and stopped when the expected reply from GW is received.
* If the timer times out and the expected GWs reply is not received, the
* client retransmits the message. For more information, see MQTT-SN Spec v1.2,
* section 6.13. For default values, see section 7.2 -> Tretry: 10 to 15 sec.
*/ */
#define EMCUTE_T_RETRY (15U) /* -> 15 sec */ #ifndef CONFIG_EMCUTE_T_RETRY
#define CONFIG_EMCUTE_T_RETRY (15U) /* -> 15 sec */
#endif #endif
#ifndef EMCUTE_N_RETRY
/** /**
* @brief Number of retries when sending packets * @brief Number of retransmissions until requests time out
* *
* For the default value, see spec v1.2, section 7.2 -> N_RETRY: 3-5 * Maximum number of retransmissions in the event that the retry timer times
* out. After 'CONFIG_EMCUTE_N_RETRY' number of retransmissions, the client
* aborts the procedure and assumes that its MQTT-SN connection to the gateway
* is disconnected. For more information, see MQTT-SN Spec v1.2, section 6.13.
* For default values, see section 7.2 -> Nretry: 3-5.
*/ */
#define EMCUTE_N_RETRY (3U) #ifndef CONFIG_EMCUTE_N_RETRY
#define CONFIG_EMCUTE_N_RETRY (3U)
#endif #endif
/** @} */
/** /**
* @brief MQTT-SN flags * @brief MQTT-SN flags
@ -259,7 +277,7 @@ int emcute_discon(void);
* @return EMCUTE_OK on success * @return EMCUTE_OK on success
* @return EMCUTE_NOGW if not connected to a gateway * @return EMCUTE_NOGW if not connected to a gateway
* @return EMCUTE_OVERFLOW if length of topic name exceeds * @return EMCUTE_OVERFLOW if length of topic name exceeds
* @ref EMCUTE_TOPIC_MAXLEN * @ref CONFIG_EMCUTE_TOPIC_MAXLEN
* @return EMCUTE_TIMEOUT on connection timeout * @return EMCUTE_TIMEOUT on connection timeout
*/ */
int emcute_reg(emcute_topic_t *topic); int emcute_reg(emcute_topic_t *topic);
@ -276,7 +294,7 @@ int emcute_reg(emcute_topic_t *topic);
* @return EMCUTE_OK on success * @return EMCUTE_OK on success
* @return EMCUTE_NOGW if not connected to a gateway * @return EMCUTE_NOGW if not connected to a gateway
* @return EMCUTE_REJECT if publish message was rejected (QoS > 0 only) * @return EMCUTE_REJECT if publish message was rejected (QoS > 0 only)
* @return EMCUTE_OVERFLOW if length of data exceeds @ref EMCUTE_BUFSIZE * @return EMCUTE_OVERFLOW if length of data exceeds @ref CONFIG_EMCUTE_BUFSIZE
* @return EMCUTE_TIMEOUT on connection timeout (QoS > 0 only) * @return EMCUTE_TIMEOUT on connection timeout (QoS > 0 only)
* @return EMCUTE_NOTSUP on unsupported flag values * @return EMCUTE_NOTSUP on unsupported flag values
*/ */
@ -297,7 +315,7 @@ int emcute_pub(emcute_topic_t *topic, const void *buf, size_t len,
* @return EMCUTE_OK on success * @return EMCUTE_OK on success
* @return EMCUTE_NOGW if not connected to a gateway * @return EMCUTE_NOGW if not connected to a gateway
* @return EMCUTE_OVERFLOW if length of topic name exceeds * @return EMCUTE_OVERFLOW if length of topic name exceeds
* @ref EMCUTE_TOPIC_MAXLEN * @ref CONFIG_EMCUTE_TOPIC_MAXLEN
* @return EMCUTE_TIMEOUT on connection timeout * @return EMCUTE_TIMEOUT on connection timeout
*/ */
int emcute_sub(emcute_sub_t *sub, unsigned flags); int emcute_sub(emcute_sub_t *sub, unsigned flags);
@ -322,7 +340,7 @@ int emcute_unsub(emcute_sub_t *sub);
* @return EMCUTE_OK on success * @return EMCUTE_OK on success
* @return EMCUTE_NOGW if not connected to a gateway * @return EMCUTE_NOGW if not connected to a gateway
* @return EMCUTE_OVERFLOW if length of topic name exceeds * @return EMCUTE_OVERFLOW if length of topic name exceeds
* @ref EMCUTE_TOPIC_MAXLEN * @ref CONFIG_EMCUTE_TOPIC_MAXLEN
* @return EMCUTE_REJECT on rejection by the gateway * @return EMCUTE_REJECT on rejection by the gateway
* @return EMCUTE_TIMEOUT on response timeout * @return EMCUTE_TIMEOUT on response timeout
*/ */
@ -337,7 +355,7 @@ int emcute_willupd_topic(const char *topic, unsigned flags);
* @return EMCUTE_OK on success * @return EMCUTE_OK on success
* @return EMCUTE_NOGW if not connected to a gateway * @return EMCUTE_NOGW if not connected to a gateway
* @return EMCUTE_OVERFLOW if length of the given message exceeds * @return EMCUTE_OVERFLOW if length of the given message exceeds
* @ref EMCUTE_BUFSIZE * @ref CONFIG_EMCUTE_BUFSIZE
* @return EMCUTE_REJECT on rejection by the gateway * @return EMCUTE_REJECT on rejection by the gateway
* @return EMCUTE_TIMEOUT on response timeout * @return EMCUTE_TIMEOUT on response timeout
*/ */

View File

@ -27,14 +27,6 @@
extern "C" { extern "C" {
#endif #endif
#ifndef MQTTSN_DEFAULT_PORT
/**
* @brief Default UDP port for MQTT-SN servers
*/
#define MQTTSN_DEFAULT_PORT (1883U)
#endif
/** /**
* @name The client ID must contain 1-23 characters * @name The client ID must contain 1-23 characters
* *

View File

@ -4,8 +4,6 @@
# General Public License v2.1. See the file LICENSE in the top level # General Public License v2.1. See the file LICENSE in the top level
# directory for more details. # directory for more details.
# #
rsource "asymcute/Kconfig"
menu "CoAP" menu "CoAP"
rsource "Kconfig.coap" rsource "Kconfig.coap"
@ -16,3 +14,10 @@ endmenu # CoAP
rsource "cord/Kconfig" rsource "cord/Kconfig"
rsource "dhcpv6/Kconfig" rsource "dhcpv6/Kconfig"
menu "MQTT-SN"
rsource "asymcute/Kconfig"
rsource "emcute/Kconfig"
endmenu # MQTT-SN

View File

@ -16,21 +16,24 @@ menuconfig KCONFIG_USEMODULE_ASYMCUTE
if KCONFIG_USEMODULE_ASYMCUTE if KCONFIG_USEMODULE_ASYMCUTE
config ASYMCUTE_BUFSIZE_EXP config ASYMCUTE_DEFAULT_PORT
int "Exponent for the buffer size (resulting in the buffer size 2^n)" int "Default UDP port to listen on"
default 7 default 1883
help help
As the buffer size ALWAYS needs to be power of two, this option Default UDP port to listen on (also used as SRC port). This will write
represents the exponent of 2^n, which will be used as the size of the to macro 'CONFIG_ASYMCUTE_DEFAULT_PORT'. Usage can be found in
buffer ('ASYMCUTE_BUFSIZE'). Default value is 7 which corresponds to a examples/asymcute_mqttsn
buffer size of 128.
config ASYMCUTE_BUFSIZE
int "Size of buffer used for receive and request buffers"
default 128
config ASYMCUTE_TOPIC_MAXLEN config ASYMCUTE_TOPIC_MAXLEN
int "Maximum topic length" int "Maximum topic length"
default 32 default 32
help help
Configure maximum length for client's topic. The value must be less than Configure maximum length for client's topic. The value must be less than
(256 - 8) and less than ('ASYMCUTE_BUFSIZE' - 8). (256 - 8) and less than ('CONFIG_ASYMCUTE_BUFSIZE' - 8).
config ASYMCUTE_KEEPALIVE config ASYMCUTE_KEEPALIVE
int "Keep alive interval in seconds" int "Keep alive interval in seconds"

View File

@ -597,7 +597,7 @@ void *_listener(void *arg)
while (1) { while (1) {
sock_udp_ep_t remote; sock_udp_ep_t remote;
int n = sock_udp_recv(&con->sock, con->rxbuf, ASYMCUTE_BUFSIZE, int n = sock_udp_recv(&con->sock, con->rxbuf, CONFIG_ASYMCUTE_BUFSIZE,
SOCK_NO_TIMEOUT, &remote); SOCK_NO_TIMEOUT, &remote);
if (n > 0) { if (n > 0) {
_on_data(con, (size_t)n, &remote); _on_data(con, (size_t)n, &remote);
@ -860,7 +860,7 @@ int asymcute_publish(asymcute_con_t *con, asymcute_req_t *req,
return ASYMCUTE_NOTSUP; return ASYMCUTE_NOTSUP;
} }
/* check for message size */ /* check for message size */
if ((data_len + 9) > ASYMCUTE_BUFSIZE) { if ((data_len + 9) > CONFIG_ASYMCUTE_BUFSIZE) {
return ASYMCUTE_OVERFLOW; return ASYMCUTE_OVERFLOW;
} }
/* make sure topic is registered */ /* make sure topic is registered */

View File

@ -0,0 +1,13 @@
/*
* Copyright (c) 2020 Freie Universitaet Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_mqtt_conf MQTT client compile configurations
* @ingroup config
* @brief Compile time configurations for different implementations of MQTT clients.
*/

View File

@ -0,0 +1,78 @@
# Copyright (c) 2020 Freie Universitaet Berlin
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
menuconfig KCONFIG_USEMODULE_EMCUTE
bool "Configure EMCUTE"
depends on USEMODULE_EMCUTE
help
Configure EMCUTE using Kconfig.`EMCUTE` is the implementation of the
OASIS MQTT-SN protocol for RIOT. It is designed with a focus on small
memory footprint and usability. It is designed to run on top of UDP
only, making use of net_sock_udp.
if KCONFIG_USEMODULE_EMCUTE
config EMCUTE_DEFAULT_PORT
int "Default UDP port to listen on"
default 1883
help
Default UDP port to listen on (also used as SRC port). This will write
to macro 'CONFIG_EMCUTE_DEFAULT_PORT'. Usage can be found in
examples/emcute_mqttsn.
config EMCUTE_BUFSIZE
int "Buffer size used for TX and RX buffers"
range 1 32768 if HAS_ARCH_16BIT || HAS_ARCH_8BIT
default 512
help
Configure the size of buffer used for TX and RX. The buffer size MUST be
less than 32768 on 16-bit and 8-bit platforms to prevent buffer
overflows.
config EMCUTE_TOPIC_MAXLEN
int "Maximum topic length"
default 196
help
Configure maximum length for client's topic. The value must be less than
(256 - 6) and less than ('CONFIG_EMCUTE_BUFSIZE' - 6).
config EMCUTE_KEEPALIVE
int "Keep alive interval in seconds"
range 300 $(UINT32_MAX)
default 360
help
Configure keep alive interval in seconds. The node will communicate this
interval to the gateway send a ping message every time when this amount
of time has passed. For more information, see MQTT-SN Spec v1.2, section
5.4.4. For default values, see section 7.2 -> TWAIT: > 5 min. Default
value is 360 seconds which corresponds to 6 minutes.
config EMCUTE_T_RETRY
int "Retry timer in seconds"
range 10 15
default 15
help
Configure re-send interval used for timing the retry messages which are
sent when the expected reply from GW is not received. The retry timer is
started by the client when the message is sent and stopped when the
expected reply from GW is received. If the timer times out and the
expected GWs reply is not received, the client retransmits the message.
For more information, see MQTT-SN Spec v1.2, section 6.13. For default
values, see section 7.2 -> Tretry: 10 to 15 sec.
config EMCUTE_N_RETRY
int "Maximum number of retransmissions"
range 3 5
default 3
help
Configure 'CONFIG_EMCUTE_N_RETRY',the maximum number of retransmissions
in the event that the retry timer times out. After
'CONFIG_EMCUTE_N_RETRY' number of retransmissions, the client aborts the
procedure and assumes that its MQTT-SN connection to the gateway is
disconnected. For more information, see MQTT-SN Spec v1.2, section 6.13.
For default values, see section 7.2 -> Nretry: 3-5.
endif # KCONFIG_USEMODULE_EMCUTE

View File

@ -44,13 +44,12 @@
#define TFLAGS_TIMEOUT (0x0002) #define TFLAGS_TIMEOUT (0x0002)
#define TFLAGS_ANY (TFLAGS_RESP | TFLAGS_TIMEOUT) #define TFLAGS_ANY (TFLAGS_RESP | TFLAGS_TIMEOUT)
static const char *cli_id; static const char *cli_id;
static sock_udp_t sock; static sock_udp_t sock;
static sock_udp_ep_t gateway; static sock_udp_ep_t gateway;
static uint8_t rbuf[EMCUTE_BUFSIZE]; static uint8_t rbuf[CONFIG_EMCUTE_BUFSIZE];
static uint8_t tbuf[EMCUTE_BUFSIZE]; static uint8_t tbuf[CONFIG_EMCUTE_BUFSIZE];
static emcute_sub_t *subs = NULL; static emcute_sub_t *subs = NULL;
@ -103,11 +102,11 @@ static int syncsend(uint8_t resp, size_t len, bool unlock)
* remove was called */ * remove was called */
thread_flags_clear(TFLAGS_ANY); thread_flags_clear(TFLAGS_ANY);
for (unsigned retries = 0; retries <= EMCUTE_N_RETRY; retries++) { for (unsigned retries = 0; retries <= CONFIG_EMCUTE_N_RETRY; retries++) {
DEBUG("[emcute] syncsend: sending round %i\n", retries); DEBUG("[emcute] syncsend: sending round %i\n", retries);
sock_udp_send(&sock, tbuf, len, &gateway); sock_udp_send(&sock, tbuf, len, &gateway);
xtimer_set(&timer, (EMCUTE_T_RETRY * US_PER_SEC)); xtimer_set(&timer, (CONFIG_EMCUTE_T_RETRY * US_PER_SEC));
thread_flags_t flags = thread_flags_wait_any(TFLAGS_ANY); thread_flags_t flags = thread_flags_wait_any(TFLAGS_ANY);
if (flags & TFLAGS_RESP) { if (flags & TFLAGS_RESP) {
DEBUG("[emcute] syncsend: got response [%i]\n", result); DEBUG("[emcute] syncsend: got response [%i]\n", result);
@ -241,14 +240,14 @@ int emcute_con(sock_udp_ep_t *remote, bool clean, const char *will_topic,
tbuf[1] = CONNECT; tbuf[1] = CONNECT;
tbuf[2] = flags; tbuf[2] = flags;
tbuf[3] = PROTOCOL_VERSION; tbuf[3] = PROTOCOL_VERSION;
byteorder_htobebufs(&tbuf[4], EMCUTE_KEEPALIVE); byteorder_htobebufs(&tbuf[4], CONFIG_EMCUTE_KEEPALIVE);
memcpy(&tbuf[6], cli_id, strlen(cli_id)); memcpy(&tbuf[6], cli_id, strlen(cli_id));
/* configure 'state machine' and send the connection request */ /* configure 'state machine' and send the connection request */
if (will_topic) { if (will_topic) {
size_t topic_len = strlen(will_topic); size_t topic_len = strlen(will_topic);
if ((topic_len > EMCUTE_TOPIC_MAXLEN) || if ((topic_len > CONFIG_EMCUTE_TOPIC_MAXLEN) ||
((will_msg_len + 4) > EMCUTE_BUFSIZE)) { ((will_msg_len + 4) > CONFIG_EMCUTE_BUFSIZE)) {
gateway.port = 0; gateway.port = 0;
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
@ -307,7 +306,7 @@ int emcute_reg(emcute_topic_t *topic)
if (gateway.port == 0) { if (gateway.port == 0) {
return EMCUTE_NOGW; return EMCUTE_NOGW;
} }
if (strlen(topic->name) > EMCUTE_TOPIC_MAXLEN) { if (strlen(topic->name) > CONFIG_EMCUTE_TOPIC_MAXLEN) {
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
@ -338,7 +337,7 @@ int emcute_pub(emcute_topic_t *topic, const void *data, size_t len,
if (gateway.port == 0) { if (gateway.port == 0) {
return EMCUTE_NOGW; return EMCUTE_NOGW;
} }
if (len >= (EMCUTE_BUFSIZE - 9)) { if (len >= (CONFIG_EMCUTE_BUFSIZE - 9)) {
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
if (flags & EMCUTE_QOS_2) { if (flags & EMCUTE_QOS_2) {
@ -375,7 +374,7 @@ int emcute_sub(emcute_sub_t *sub, unsigned flags)
if (gateway.port == 0) { if (gateway.port == 0) {
return EMCUTE_NOGW; return EMCUTE_NOGW;
} }
if (strlen(sub->topic.name) > EMCUTE_TOPIC_MAXLEN) { if (strlen(sub->topic.name) > CONFIG_EMCUTE_TOPIC_MAXLEN) {
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
@ -451,7 +450,7 @@ int emcute_willupd_topic(const char *topic, unsigned flags)
if (gateway.port == 0) { if (gateway.port == 0) {
return EMCUTE_NOGW; return EMCUTE_NOGW;
} }
if (topic && (strlen(topic) > EMCUTE_TOPIC_MAXLEN)) { if (topic && (strlen(topic) > CONFIG_EMCUTE_TOPIC_MAXLEN)) {
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
@ -477,7 +476,7 @@ int emcute_willupd_msg(const void *data, size_t len)
if (gateway.port == 0) { if (gateway.port == 0) {
return EMCUTE_NOGW; return EMCUTE_NOGW;
} }
if (len > (EMCUTE_BUFSIZE - 4)) { if (len > (CONFIG_EMCUTE_BUFSIZE - 4)) {
return EMCUTE_OVERFLOW; return EMCUTE_OVERFLOW;
} }
@ -509,7 +508,7 @@ void emcute_run(uint16_t port, const char *id)
} }
uint32_t start = xtimer_now_usec(); uint32_t start = xtimer_now_usec();
uint32_t t_out = (EMCUTE_KEEPALIVE * US_PER_SEC); uint32_t t_out = (CONFIG_EMCUTE_KEEPALIVE * US_PER_SEC);
while (1) { while (1) {
ssize_t len = sock_udp_recv(&sock, rbuf, sizeof(rbuf), t_out, &remote); ssize_t len = sock_udp_recv(&sock, rbuf, sizeof(rbuf), t_out, &remote);
@ -556,13 +555,13 @@ void emcute_run(uint16_t port, const char *id)
} }
uint32_t now = xtimer_now_usec(); uint32_t now = xtimer_now_usec();
if ((now - start) >= (EMCUTE_KEEPALIVE * US_PER_SEC)) { if ((now - start) >= (CONFIG_EMCUTE_KEEPALIVE * US_PER_SEC)) {
send_ping(); send_ping();
start = now; start = now;
t_out = (EMCUTE_KEEPALIVE * US_PER_SEC); t_out = (CONFIG_EMCUTE_KEEPALIVE * US_PER_SEC);
} }
else { else {
t_out = (EMCUTE_KEEPALIVE * US_PER_SEC) - (now - start); t_out = (CONFIG_EMCUTE_KEEPALIVE * US_PER_SEC) - (now - start);
} }
} }
} }

View File

@ -25,7 +25,6 @@ USEMODULE += shell
USEMODULE += shell_commands USEMODULE += shell_commands
USEMODULE += sock_util USEMODULE += sock_util
CFLAGS += -DEMCUTE_TOPIC_MAXLEN="249" # 256 - 7
CFLAGS += -DSTDIO_UART_RX_BUFSIZE="512" # Adapt to SHELL_BUFSIZE in app CFLAGS += -DSTDIO_UART_RX_BUFSIZE="512" # Adapt to SHELL_BUFSIZE in app
# The test requires some setup and to be run as root # The test requires some setup and to be run as root
@ -38,3 +37,8 @@ ethos:
$(Q)env -u CC -u CFLAGS $(MAKE) -C $(RIOTTOOLS)/ethos $(Q)env -u CC -u CFLAGS $(MAKE) -C $(RIOTTOOLS)/ethos
include $(RIOTBASE)/Makefile.include include $(RIOTBASE)/Makefile.include
# Set CONFIG_EMCUTE_TOPIC_MAXLEN via CFLAGS if not being set via Kconfig.
ifndef CONFIG_EMCUTE_TOPIC_MAXLEN
CFLAGS += -DCONFIG_EMCUTE_TOPIC_MAXLEN=249 # 256 - 7
endif

View File

@ -39,11 +39,11 @@
static char _emcute_stack[THREAD_STACKSIZE_DEFAULT]; static char _emcute_stack[THREAD_STACKSIZE_DEFAULT];
static char _shell_buffer[SHELL_BUFSIZE]; static char _shell_buffer[SHELL_BUFSIZE];
static uint8_t _pub_buf[EMCUTE_BUFSIZE]; static uint8_t _pub_buf[CONFIG_EMCUTE_BUFSIZE];
static emcute_topic_t _topics[NUMOFTOPS]; static emcute_topic_t _topics[NUMOFTOPS];
static emcute_sub_t _subscriptions[NUMOFTOPS]; static emcute_sub_t _subscriptions[NUMOFTOPS];
static char _topic_names[NUMOFTOPS][EMCUTE_TOPIC_MAXLEN + 1]; static char _topic_names[NUMOFTOPS][CONFIG_EMCUTE_TOPIC_MAXLEN + 1];
static char _addr_str[IPV6_ADDR_MAX_STR_LEN]; static char _addr_str[IPV6_ADDR_MAX_STR_LEN];
static sock_udp_ep_t _gw = { .family = AF_INET6 }; static sock_udp_ep_t _gw = { .family = AF_INET6 };
@ -72,7 +72,7 @@ static const shell_command_t _shell_commands[] = {
static void *_emcute_thread(void *arg) static void *_emcute_thread(void *arg)
{ {
(void)arg; (void)arg;
emcute_run(MQTTSN_DEFAULT_PORT, EMCUTE_ID); emcute_run(CONFIG_EMCUTE_DEFAULT_PORT, EMCUTE_ID);
return NULL; /* should never be reached */ return NULL; /* should never be reached */
} }
@ -111,7 +111,7 @@ static int _con(int argc, char **argv)
return 1; return 1;
} }
if (_gw.port == 0) { if (_gw.port == 0) {
_gw.port = MQTTSN_DEFAULT_PORT; _gw.port = CONFIG_EMCUTE_DEFAULT_PORT;
} }
if (argc >= 4) { if (argc >= 4) {
topic = argv[2]; topic = argv[2];
@ -155,7 +155,7 @@ static int _topic_name_find(const char *name)
if ((_topic_names[i][0] == '\0') && (res < 0)) { if ((_topic_names[i][0] == '\0') && (res < 0)) {
res = i; res = i;
} }
else if (strncmp(name, _topic_names[i], EMCUTE_TOPIC_MAXLEN) == 0) { else if (strncmp(name, _topic_names[i], CONFIG_EMCUTE_TOPIC_MAXLEN) == 0) {
return i; return i;
} }
} }
@ -183,7 +183,7 @@ static int _reg(int argc, char **argv)
was_set = true; was_set = true;
} }
else { else {
strncpy(_topic_names[idx], argv[1], EMCUTE_TOPIC_MAXLEN); strncpy(_topic_names[idx], argv[1], CONFIG_EMCUTE_TOPIC_MAXLEN);
} }
t = &_topics[idx]; t = &_topics[idx];
t->name = _topic_names[idx]; t->name = _topic_names[idx];
@ -251,7 +251,7 @@ static int _sub(int argc, char **argv)
return 1; return 1;
} }
if (strlen(argv[1]) > EMCUTE_TOPIC_MAXLEN) { if (strlen(argv[1]) > CONFIG_EMCUTE_TOPIC_MAXLEN) {
puts("error: topic name exceeds maximum possible size"); puts("error: topic name exceeds maximum possible size");
return 1; return 1;
} }
@ -269,7 +269,7 @@ static int _sub(int argc, char **argv)
was_set = true; was_set = true;
} }
else { else {
strncpy(_topic_names[idx], argv[1], EMCUTE_TOPIC_MAXLEN); strncpy(_topic_names[idx], argv[1], CONFIG_EMCUTE_TOPIC_MAXLEN);
} }
_subscriptions[idx].topic.name = _topic_names[idx]; _subscriptions[idx].topic.name = _topic_names[idx];
if (emcute_sub(&_subscriptions[idx], flags) != EMCUTE_OK) { if (emcute_sub(&_subscriptions[idx], flags) != EMCUTE_OK) {