Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/rest_client: a multi-transport rest-client for RIOT #17785

Draft
wants to merge 55 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
0bef732
[treewide] lora: use int16_t for RSSI value
jia200x Jan 10, 2022
4b3d699
drivers/atwinc15x0: adapt NETOPT_RSSI to int16_t
jia200x Jan 10, 2022
5e99374
Merge pull request #17527 from jia200x/backport/2022.01/pr/lora/fix_r…
aabadie Jan 18, 2022
b8994e9
tests/pkg_relic: increase stacksize
fjmolinas Jan 18, 2022
6a8dedf
Merge pull request #17529 from fjmolinas/backport/2022.01/pr_test_pkg…
fjmolinas Jan 18, 2022
69198a4
drivers/rtt_rtc: select rtc_utils
fjmolinas Jan 18, 2022
79794fd
Merge pull request #17532 from fjmolinas/backport/2022.01/pr_rtt_rtc_…
aabadie Jan 19, 2022
c13b529
tests/pkg_edhoc: handle multiple interfaces
fjmolinas Jan 18, 2022
33c360c
Merge pull request #17549 from fjmolinas/backport/2022.01/pr_edhoc_te…
aabadie Jan 21, 2022
f052a9b
sys/ztimer64/util.c: fix ztimer64_set_timeout_flag
fjmolinas Jan 24, 2022
ec3cc22
Merge pull request #17562 from fjmolinas/backport/2022.01/pr_ztimer64…
emmanuelsearch Jan 25, 2022
336fd75
boards/nucleo-f767zi: Fix adc pin config in periph_conf.h
ststrell Jan 24, 2022
5db69b4
Merge pull request #17570 from maribu/backport/2022.01/nucleo_f767zi_…
aabadie Jan 25, 2022
5ffdabc
release-notes.txt: add 2022.01 release notes
emmanuelsearch Jan 25, 2022
9640e20
Merge pull request #17585 from emmanuelsearch/backport/2022.01/pr-rel…
bergzand Jan 28, 2022
ba4857a
VERSION: add 2022.01 version file
emmanuelsearch Jan 28, 2022
5265213
Merge pull request #17587 from emmanuelsearch/2022.01-branch
kaspar030 Jan 28, 2022
d33e144
pkg/lwip: replace boolean with simple expression
HendrikVE Dec 21, 2021
12ccc0a
pkg/lwip: rename offset to recvd
HendrikVE Dec 21, 2021
9d782bc
pkg/lwip: use intermediate variable instead of max_len
HendrikVE Dec 21, 2021
9395791
pkg/lwip: give lines some more space
HendrikVE Dec 22, 2021
9328e6b
pkg/lwip: remove redundant pointer
HendrikVE Dec 22, 2021
4743823
pkg/lwip: add peek to sock_ip
HendrikVE Dec 27, 2021
50d91de
pkg/lwip: add peek to sock_udp
HendrikVE Dec 27, 2021
cea7731
pkg/lwip: add peek to sock_tcp
HendrikVE Dec 27, 2021
98b5e70
sys/posix: add flag definitions
HendrikVE Feb 3, 2021
8f7c757
sys/posix/socket: implement MSG_PEEK for recvfrom
HendrikVE Feb 3, 2021
371183f
pkg/lwip: add missing initialization for async_cb
HendrikVE Dec 31, 2021
92f569c
sys/posix: add module posix_netdb
HendrikVE Jun 16, 2021
1e83372
tests/posix_netdb: add test
HendrikVE Jan 7, 2022
07f498a
sys/net/application_layer/sock_dns: add pseudomodule auto_init_sock_dns
HendrikVE Jan 1, 2022
845b58a
pkg/wolfmqtt: add wolfmqtt
HendrikVE Jan 14, 2021
28f71a5
examples/wolfmqtt_mqttclient: add example from wolfmqtt pkg
HendrikVE Jan 14, 2021
5e2b332
examples/wolfmqtt_snclient: add example from wolfmqtt pkg
HendrikVE Jan 29, 2021
538e202
examples/wolfmqtt_nbclient: add example from wolfmqtt pkg
HendrikVE Feb 5, 2021
f410a7f
examples/wolfmqtt_multithread: add example from wolfmqtt pkg
HendrikVE Feb 5, 2021
9512727
pkg/wolfmqtt: update package from v1.7 to v1.12.0
HendrikVE Apr 17, 2022
6ac4b49
sys/net/ipv4: ipv4_addr_t pointer should be const
HendrikVE Mar 5, 2022
efae541
pkg/tinydtls: rename condition WITH_RIOT_GNRC to WITH_RIOT
HendrikVE Mar 5, 2022
4288e4b
pkg/tinydtls: remove unnecessary void casts
HendrikVE Mar 5, 2022
eade2b7
pkg/tinydtls: add IPv4 support
HendrikVE Mar 5, 2022
2471588
sys/net/sock_util: fix compilation for IPv4-only mode
HendrikVE Mar 6, 2022
ae425db
sys/net/netutils: add missing string.h include
HendrikVE Mar 6, 2022
862094b
sys/net/netutils: add netutils_get_ipv4()
HendrikVE Mar 6, 2022
9f80903
examples/gcoap: add IPv4 support
HendrikVE Mar 5, 2022
ec54d85
examples/gcoap_dtls: add IPv4 support
HendrikVE Mar 5, 2022
c412e4d
wolfMQTT
HendrikVE Apr 30, 2022
c36c26d
fix wolfmqtt pkg
HendrikVE May 1, 2022
f7e4845
initial rest_client
HendrikVE Nov 2, 2021
ffbedd4
sys/rest_client: add CoAP and CoAPs transport
HendrikVE Apr 30, 2022
0c07b0a
sys/rest_client: add MQTT and MQTT-SN transport
HendrikVE Apr 30, 2022
4a78290
pkg/lwip: make LWIP_NETDEV_STACKSIZE configurable
HendrikVE Apr 30, 2022
0dd366f
sys/net/coap: add kafka media types
HendrikVE Apr 30, 2022
3e6fa50
examples/rest_client_django: add new application
HendrikVE Apr 30, 2022
2b14bbf
examples/rest_client_kafka: add new application
HendrikVE Apr 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
sys/rest_client: add MQTT and MQTT-SN transport
  • Loading branch information
HendrikVE committed May 12, 2022
commit 0c07b0a338586a16a7dd9fee39ad0e5114bbe9de
13 changes: 13 additions & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ ifneq (,$(filter rest_client_transport_coaps,$(USEMODULE)))
USEMODULE += sock_util
endif

ifneq (,$(filter rest_client_transport_mqtt%,$(USEMODULE)))
USEMODULE += wolfmqtt
USEMODULE += posix_netdb
USEMODULE += posix_sockets
USEMODULE += posix_select
USEMODULE += ztimer_sec
USEMODULE += uuid
endif

ifneq (,$(filter rest_client_transport_mqtt,$(USEMODULE)))
USEMODULE += sock_tcp
endif

ifneq (,$(filter arduino,$(USEMODULE)))
FEATURES_OPTIONAL += periph_adc
FEATURES_OPTIONAL += periph_i2c
Expand Down
92 changes: 92 additions & 0 deletions sys/include/rest_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
#include <sys/socket.h>
#include "net/sock/udp.h"

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTT) || IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN)
#include "wolfmqtt/mqtt_socket.h"
#include "wolfmqtt/mqtt_client.h"
#endif

#define REST_CLIENT_DEFAULT_PORT_COAP 5683
#define REST_CLIENT_DEFAULT_PORT_COAP_SECURE 5684
#define REST_CLIENT_DEFAULT_PORT_HTTP 80
Expand Down Expand Up @@ -135,6 +140,70 @@ typedef struct rest_client_response_listener_t {
void (*listener) (struct rest_client_response_listener_t*);
} rest_client_response_listener_t;

// Todo: #if ... || defined(DOXYGEN)
#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTT) || IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN)
/* MQTT Client state */
typedef enum {
WMQ_BEGIN = 0,
WMQ_NET_INIT,
WMQ_INIT,
WMQ_TCP_CONN,
WMQ_MQTT_CONN,
WMQ_SUB,
WMQ_PUB,
WMQ_WAIT_MSG,
WMQ_UNSUB,
WMQ_DISCONNECT,
WMQ_NET_DISCONNECT,
WMQ_DONE
} rest_client_mqtt_context_state_t;

/* MQTT Client context */
typedef struct {
rest_client_mqtt_context_state_t stat;

//void* app_ctx; /* For storing application specific data */
rest_client_response_listener_t* listener;

/* client and net containers */
MqttClient client;
MqttNet net;

/* temp mqtt containers */
MqttConnect connect;
MqttSubscribe subscribe;
MqttUnsubscribe unsubscribe;
/* Todo: convert to single value */
MqttTopic topics[1];
MqttPublish publish;
MqttDisconnect disconnect;

#ifdef WOLFMQTT_SN
SN_Publish publish_sn;
#endif

/* configuration */
const char *app_name;
const char *host;
bool is_numeric_host;
uint16_t port;
_ipvx_addr_t *addr;
const char *username;
const char *password;
uint8_t *tx_buf, *rx_buf;
#ifdef WOLFMQTT_NONBLOCK
uint32_t start_sec; /* used for keep-alive */
unsigned int use_non_block_mode:1; /* set to use non-blocking mode. network callbacks can return
MQTT_CODE_CONTINUE to indicate "would block" */
#endif
#ifdef WOLFMQTT_CLIENT_ID
uint8_t clean_session;
const char *client_id;
unsigned int dynamic_client_id:1;
#endif
} rest_client_mqtt_context_t;
#endif /* IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTT) || IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN) */

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_COAP)
typedef struct rest_client_coap_proxy_t {
rest_client_scheme_t scheme;
Expand All @@ -160,16 +229,39 @@ typedef struct {
} rest_client_coap_context_t;
#endif

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN)
typedef struct {
char *hostname;
bool is_numeric_hostname;
uint16_t port;
_ipvx_addr_t _addr; /* For internal use only */
} rest_client_mqttsn_gateway_t;
#endif

/**
* @brief Structure containing all information to connect to an endpoint. Besides basic
* information like the hostname and port this struct also contains transport
* specific members such as a reference to rest_client_coap_proxy_t when using CoAP.
*/
typedef struct {
rest_client_scheme_t scheme;
char *hostname;
bool is_numeric_hostname;
uint16_t port;
_ipvx_addr_t _addr; /* For internal use only */

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_COAP)
rest_client_coap_context_t coap_context;
rest_client_coap_proxy_t *coap_proxy;
#endif

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTT) || IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN)
rest_client_mqtt_context_t mqtt_context;
#endif

#if IS_USED(MODULE_REST_CLIENT_TRANSPORT_MQTTSN)
rest_client_mqttsn_gateway_t *mqttsn_gateway;
#endif
} rest_client_t;

/**
Expand Down
98 changes: 98 additions & 0 deletions sys/include/rest_client/internal/mqtt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (C) 2022 Freie Universität 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.
*/

/**
* @ingroup sys_rest_client_mqtt
* @{
*
* @file
* @brief Internal functions for MQTT-based transport modules
*
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*
* @}
*/

#ifndef REST_CLIENT_INTERNAL_MQTT_H
#define REST_CLIENT_INTERNAL_MQTT_H

#include "uuid.h"

#include "rest_client.h"

/**
* @brief Struct for custom MQTT payload, including header fields and payload
*/
typedef struct {
uuid_t *request_id;
rest_client_content_type_t content_type;
rest_client_content_type_t accept;
rest_client_content_type_t target_content_type;
rest_client_content_type_t target_accept;
char *authorization;
char *query_string;
uint8_t *body;
int body_len;
} _mqtt_payload_t;

/**
* @brief Create a request topic string from access method and path.
* Example request topic: GET/api/user/profile
*
* @param[out] buf Output buffer
* @param[in] buf_len Output buffer size
* @param[in] method Access method (like GET or POST)
* @param[in] path Resource path
*/
void _rest_client_internal_mqtt_build_mqtt_request_topic(
char *buf, size_t buf_len, rest_client_method_t method, const char *path);

/**
* @brief Create response topic from access method, path and a uuid
* Example response topic: GET/api/user/profile
*
* @param[out] buf Output buffer
* @param[in] buf_len Output buffer size
* @param[in] method Access method (like GET or POST)
* @param[in] path Resource path
* @param[in] uuid Unique request ID
*/
void _rest_client_internal_mqtt_build_mqtt_response_topic(
char *buf, size_t buf_len, rest_client_method_t method, const char *path, const char *uuid);

/**
* @brief Encode custom MQTT payload
*
* @param[out] mqtt_payload MQTT payload struct
* @param[in] encoder_buf Encoder buffer
* @param[in] encoder_buf_len Encoder buffer size
*
* @return Length of encoded data
*/
size_t _rest_client_internal_mqtt_encode_mqtt_payload(
_mqtt_payload_t *mqtt_payload, uint8_t *encoder_buf, size_t encoder_buf_len);

/**
* @brief Parse custom MQTT payload
*
* @param[in] buf Input buffer
* @param[in] buf_size Input buffer size
* @param[in] http_status HTTP status
* @param[in] content_type Content type
* @param[in] cbor_payload_buf Buffer for extracted body
* @param[in] cbor_payload_buf_size Length of the extracted body
*
* @retval 0 On success
* @retval 1 On error
*/
int _rest_client_internal_mqtt_parse_mqtt_payload(
const uint8_t *buf, size_t buf_size,
int *http_status, rest_client_content_type_t *content_type,
uint8_t *cbor_payload_buf, size_t *cbor_payload_buf_size);

#endif /* REST_CLIENT_INTERNAL_MQTT_H */
63 changes: 63 additions & 0 deletions sys/include/rest_client/mqttexample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (C) 2022 Freie Universität 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.
*/

/**
* @ingroup sys_rest_client_mqttexample
* @{
*
* @file
* @brief Helper functions wolfMQTT interactions
*
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*
* @}
*/

#ifndef REST_CLIENT_MQTTEXAMPLE_H
#define REST_CLIENT_MQTTEXAMPLE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "rest_client.h"

#ifndef CONFIG_REST_CLIENT_MQTT_CMD_TIMEOUT_MS
#define CONFIG_REST_CLIENT_MQTT_CMD_TIMEOUT_MS 30000
#endif

#ifndef CONFIG_REST_CLIENT_MQTT_CON_TIMEOUT_MS
#define CONFIG_REST_CLIENT_MQTT_CON_TIMEOUT_MS 5000
#endif

#ifndef CONFIG_REST_CLIENT_MQTT_DEFAULT_KEEP_ALIVE_SEC
#define CONFIG_REST_CLIENT_MQTT_DEFAULT_KEEP_ALIVE_SEC 60
#endif

#ifndef CONFIG_REST_CLIENT_MQTT_PRINT_BUFFER_SIZE
#define CONFIG_REST_CLIENT_MQTT_PRINT_BUFFER_SIZE 180
#endif

#ifndef CONFIG_REST_CLIENT_MQTT_CLIENT_ID
#define CONFIG_REST_CLIENT_MQTT_CLIENT_ID "riot-os"
#endif

void mqtt_init_ctx(rest_client_mqtt_context_t *mqtt_context);
void mqtt_free_ctx(rest_client_mqtt_context_t *mqtt_context);

uint16_t mqtt_get_packetid(void);

#ifdef WOLFMQTT_NONBLOCK
int mqtt_check_timeout(int rc, uint32_t *start_sec, uint32_t timeout_sec);
#endif

#ifdef __cplusplus
}
#endif

#endif /* REST_CLIENT_MQTTEXAMPLE_H */
45 changes: 45 additions & 0 deletions sys/include/rest_client/mqttnet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2022 Freie Universität 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.
*/

/**
* @ingroup sys_rest_client_mqttnet
* @{
*
* @file
* @brief Definitions for basic wolfMQTT interactions
*
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*
* @}
*/

#ifndef REST_CLIENT_MQTTNET_H
#define REST_CLIENT_MQTTNET_H

#ifdef __cplusplus
extern "C" {
#endif

#include "rest_client/mqttexample.h"

#ifndef DEFAULT_MQTT_HOST
#define DEFAULT_MQTT_HOST "mqtt.eclipse.org" /* broker.hivemq.com */
#endif

int mqttnet_init(MqttNet *net, rest_client_mqtt_context_t *mqtt_context);
int mqttnet_deinit(MqttNet *net);

#ifdef WOLFMQTT_SN
int mqttnet_sn_init(MqttNet *net, rest_client_mqtt_context_t *mqtt_context);
#endif

#ifdef __cplusplus
}
#endif

#endif /* REST_CLIENT_MQTTNET_H */
37 changes: 37 additions & 0 deletions sys/include/rest_client/transport/mqtt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2021 Freie Universität 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.
*/

/**
* @ingroup sys_rest_client_transport_mqtt
* @{
*
* @file
* @brief REST client transport module for MQTT
*
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*
* @}
*/

#ifndef REST_CLIENT_TRANSPORT_MQTT_H
#define REST_CLIENT_TRANSPORT_MQTT_H

#include "rest_client.h"

rest_client_result_t rest_client_transport_mqtt_send(
rest_client_t *rest_client, rest_client_response_listener_t *listener,
rest_client_method_t method, rest_client_qos_t qos,
rest_client_header_t *headers, char *path, char *query_string, uint8_t *body, int body_len);

rest_client_result_t rest_client_transport_mqtt_init(rest_client_t *rest_client);
rest_client_result_t rest_client_transport_mqtt_deinit(rest_client_t *rest_client);
rest_client_result_t rest_client_transport_mqtt_connect(rest_client_t *rest_client);
rest_client_result_t rest_client_transport_mqtt_disconnect(rest_client_t *rest_client);


#endif /* REST_CLIENT_TRANSPORT_MQTT_H */
Loading