475 lines
12 KiB
C
475 lines
12 KiB
C
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef _MQTT_H_
|
|
#define _MQTT_H_
|
|
|
|
#include <net/mqtt_types.h>
|
|
#include <net/net_context.h>
|
|
#include <net/net_app.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief MQTT library
|
|
* @defgroup mqtt MQTT library
|
|
* @ingroup networking
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* MQTT application type
|
|
*/
|
|
enum mqtt_app {
|
|
/** Publisher and Subscriber application */
|
|
MQTT_APP_PUBLISHER_SUBSCRIBER,
|
|
/** Publisher only application */
|
|
MQTT_APP_PUBLISHER,
|
|
/** Subscriber only application */
|
|
MQTT_APP_SUBSCRIBER,
|
|
/** MQTT Server */
|
|
MQTT_APP_SERVER
|
|
};
|
|
|
|
/**
|
|
* MQTT context structure
|
|
*
|
|
* @details Context structure for the MQTT high-level API with support for QoS.
|
|
*
|
|
* This API is designed for asynchronous operation, so callbacks are
|
|
* executed when some events must be addressed outside the MQTT routines.
|
|
* Those events are triggered by the reception or transmission of MQTT messages
|
|
* and are defined by the MQTT v3.1.1 spec, see:
|
|
*
|
|
* http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
|
|
*
|
|
* For example, assume that Zephyr is operating as a MQTT_APP_SUBSCRIBER, so it
|
|
* may receive the MQTT PUBLISH and MQTT PUBREL (QoS2) messages. Once the
|
|
* messages are parsed and validated, the #publish_rx callback is executed.
|
|
*
|
|
* Internally, the #publish_rx callback must store the #mqtt_publish_msg message
|
|
* when a MQTT PUBLISH msg is received. When a MQTT PUBREL message is received,
|
|
* the application must evaluate if the PUBREL's Packet Identifier matches a
|
|
* previous received MQTT PUBLISH message. In this case, the user may provide a
|
|
* collection of #mqtt_publish_msg structs (array of structs) to store those
|
|
* messages.
|
|
*
|
|
* <b>NOTE: The application (and not the API) is in charge of keeping track of
|
|
* the state of the received and sent messages.</b>
|
|
*/
|
|
struct mqtt_ctx {
|
|
/** Net app context structure */
|
|
struct net_app_ctx net_app_ctx;
|
|
s32_t net_init_timeout;
|
|
s32_t net_timeout;
|
|
|
|
/** Connectivity */
|
|
char *peer_addr_str;
|
|
u16_t peer_port;
|
|
|
|
#if defined(CONFIG_MQTT_LIB_TLS)
|
|
/** TLS parameters */
|
|
u8_t *request_buf;
|
|
size_t request_buf_len;
|
|
u8_t *personalization_data;
|
|
size_t personalization_data_len;
|
|
char *cert_host;
|
|
|
|
/** TLS thread parameters */
|
|
struct k_mem_pool *tls_mem_pool;
|
|
k_thread_stack_t *tls_stack;
|
|
size_t tls_stack_size;
|
|
|
|
/** TLS callback */
|
|
net_app_ca_cert_cb_t cert_cb;
|
|
net_app_entropy_src_cb_t entropy_src_cb;
|
|
|
|
/** TLS handshake */
|
|
struct k_sem tls_hs_wait;
|
|
s32_t tls_hs_timeout;
|
|
#endif
|
|
|
|
/** Callback executed when a MQTT CONNACK msg is received and validated.
|
|
* If this function pointer is not used, must be set to NULL.
|
|
*/
|
|
void (*connect)(struct mqtt_ctx *ctx);
|
|
|
|
/** Callback executed when a MQTT DISCONNECT msg is sent.
|
|
* If this function pointer is not used, must be set to NULL.
|
|
*/
|
|
void (*disconnect)(struct mqtt_ctx *ctx);
|
|
|
|
/** Callback executed when a #MQTT_APP_PUBLISHER application receives
|
|
* a MQTT PUBxxxx msg.
|
|
* If type is MQTT_PUBACK, MQTT_PUBCOMP or MQTT_PUBREC, this callback
|
|
* must return 0 if pkt_id matches the packet id of a previously
|
|
* received MQTT_PUBxxx message. If this callback returns 0, the caller
|
|
* will continue.
|
|
* Any other value will stop the QoS handshake and the caller will
|
|
* return -EINVAL. The application must discard all the messages
|
|
* already processed.
|
|
*
|
|
* <b>Note: this callback must be not NULL</b>
|
|
*
|
|
* @param [in] ctx MQTT context
|
|
* @param [in] pkt_id Packet Identifier for the input MQTT msg
|
|
* @param [in] type Packet type
|
|
*/
|
|
int (*publish_tx)(struct mqtt_ctx *ctx, u16_t pkt_id,
|
|
enum mqtt_packet type);
|
|
|
|
/** Callback executed when a MQTT_APP_SUBSCRIBER,
|
|
* MQTT_APP_PUBLISHER_SUBSCRIBER or MQTT_APP_SERVER applications receive
|
|
* a MQTT PUBxxxx msg. If this callback returns 0, the caller will
|
|
* continue. If type is MQTT_PUBREL this callback must return 0 if
|
|
* pkt_id matches the packet id of a previously received MQTT_PUBxxx
|
|
* message. Any other value will stop the QoS handshake and the caller
|
|
* will return -EINVAL
|
|
*
|
|
* <b>Note: this callback must be not NULL</b>
|
|
*
|
|
* @param [in] ctx MQTT context
|
|
* @param [in] msg Publish message, this parameter is only used
|
|
* when the type is MQTT_PUBLISH
|
|
* @param [in] pkt_id Packet Identifier for the input msg
|
|
* @param [in] type Packet type
|
|
*/
|
|
int (*publish_rx)(struct mqtt_ctx *ctx, struct mqtt_publish_msg *msg,
|
|
u16_t pkt_id, enum mqtt_packet type);
|
|
|
|
/** Callback executed when a MQTT_APP_SUBSCRIBER or
|
|
* MQTT_APP_PUBLISHER_SUBSCRIBER receives the MQTT SUBACK message
|
|
* If this callback returns 0, the caller will continue. Any other
|
|
* value will make the caller return -EINVAL.
|
|
*
|
|
* <b>Note: this callback must be not NULL</b>
|
|
*
|
|
* @param [in] ctx MQTT context
|
|
* @param [in] pkt_id Packet Identifier for the MQTT SUBACK msg
|
|
* @param [in] items Number of elements in the qos array
|
|
* @param [in] qos Array of QoS values
|
|
*/
|
|
int (*subscribe)(struct mqtt_ctx *ctx, u16_t pkt_id,
|
|
u8_t items, enum mqtt_qos qos[]);
|
|
|
|
/** Callback executed when a MQTT_APP_SUBSCRIBER or
|
|
* MQTT_APP_PUBLISHER_SUBSCRIBER receives the MQTT UNSUBACK message
|
|
* If this callback returns 0, the caller will continue. Any other value
|
|
* will make the caller return -EINVAL
|
|
*
|
|
* <b>Note: this callback must be not NULL</b>
|
|
*
|
|
* @param [in] ctx MQTT context
|
|
* @param [in] pkt_id Packet Identifier for the MQTT SUBACK msg
|
|
*/
|
|
int (*unsubscribe)(struct mqtt_ctx *ctx, u16_t pkt_id);
|
|
|
|
/** Callback executed when an incoming message doesn't pass the
|
|
* validation stage. This callback may be NULL.
|
|
* The pkt_type variable may be set to MQTT_INVALID, if the parsing
|
|
* stage is aborted before determining the MQTT msg packet type.
|
|
*
|
|
* @param [in] ctx MQTT context
|
|
* @param [in] pkt_type MQTT Packet type
|
|
*/
|
|
void (*malformed)(struct mqtt_ctx *ctx, u16_t pkt_type);
|
|
|
|
/* Internal use only */
|
|
int (*rcv)(struct mqtt_ctx *ctx, struct net_pkt *);
|
|
|
|
/** Application type, see: enum mqtt_app */
|
|
u8_t app_type;
|
|
|
|
/* Clean session is also part of the MQTT CONNECT msg, however app
|
|
* behavior is influenced by this parameter, so we keep a copy here
|
|
*/
|
|
/** MQTT Clean Session parameter */
|
|
u8_t clean_session:1;
|
|
|
|
/** 1 if the MQTT application is connected and 0 otherwise */
|
|
u8_t connected:1;
|
|
};
|
|
|
|
/**
|
|
* Initializes the MQTT context structure
|
|
*
|
|
* @param ctx MQTT context structure
|
|
* @param app_type See enum mqtt_app
|
|
* @retval 0 always
|
|
*/
|
|
int mqtt_init(struct mqtt_ctx *ctx, enum mqtt_app app_type);
|
|
|
|
/**
|
|
* Release the MQTT context structure
|
|
*
|
|
* @param ctx MQTT context structure
|
|
* @retval 0 on success, and <0 if error
|
|
*/
|
|
int mqtt_close(struct mqtt_ctx *ctx);
|
|
|
|
/**
|
|
* Connect to an MQTT broker
|
|
*
|
|
* @param ctx MQTT context structure
|
|
* @retval 0 on success, and <0 if error
|
|
*/
|
|
|
|
int mqtt_connect(struct mqtt_ctx *ctx);
|
|
|
|
/**
|
|
* Sends the MQTT CONNECT message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] msg MQTT CONNECT msg
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EIO
|
|
* @retval -ENOMEM
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_tx_connect(struct mqtt_ctx *ctx, struct mqtt_connect_msg *msg);
|
|
|
|
/**
|
|
* Send the MQTT DISCONNECT message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EIO
|
|
* @retval -ENOMEM
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_tx_disconnect(struct mqtt_ctx *ctx);
|
|
|
|
/**
|
|
* Sends the MQTT PUBACK message with the given packet id
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] id MQTT Packet Identifier
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_puback(struct mqtt_ctx *ctx, u16_t id);
|
|
|
|
/**
|
|
* Sends the MQTT PUBCOMP message with the given packet id
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] id MQTT Packet Identifier
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_pubcomp(struct mqtt_ctx *ctx, u16_t id);
|
|
|
|
/**
|
|
* Sends the MQTT PUBREC message with the given packet id
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] id MQTT Packet Identifier
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_pubrec(struct mqtt_ctx *ctx, u16_t id);
|
|
|
|
/**
|
|
* Sends the MQTT PUBREL message with the given packet id
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] id MQTT Packet Identifier
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_pubrel(struct mqtt_ctx *ctx, u16_t id);
|
|
|
|
/**
|
|
* Sends the MQTT PUBLISH message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] msg MQTT PUBLISH msg
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_publish(struct mqtt_ctx *ctx, struct mqtt_publish_msg *msg);
|
|
|
|
/**
|
|
* Sends the MQTT PINGREQ message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_pingreq(struct mqtt_ctx *ctx);
|
|
|
|
/**
|
|
* Sends the MQTT SUBSCRIBE message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] pkt_id Packet identifier for the MQTT SUBSCRIBE msg
|
|
* @param [in] items Number of elements in 'topics' and 'qos' arrays
|
|
* @param [in] topics Array of 'items' elements containing C strings.
|
|
* For example: {"sensors", "lights", "doors"}
|
|
* @param [in] qos Array of 'items' elements containing MQTT QoS values:
|
|
* MQTT_QoS0, MQTT_QoS1, MQTT_QoS2. For example for the 'topics'
|
|
* array above the following QoS may be used: {MQTT_QoS0,
|
|
* MQTT_QoS2, MQTT_QoS1}, indicating that the subscription to
|
|
* 'lights' must be done with MQTT_QoS2
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_subscribe(struct mqtt_ctx *ctx, u16_t pkt_id, u8_t items,
|
|
const char *topics[], const enum mqtt_qos qos[]);
|
|
|
|
/**
|
|
* Sends the MQTT UNSUBSCRIBE message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] pkt_id Packet identifier for the MQTT UNSUBSCRIBE msg
|
|
* @param [in] items Number of elements in the 'topics' array
|
|
* @param [in] topics Array of 'items' elements containing C strings
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
* @retval -EIO
|
|
*/
|
|
int mqtt_tx_unsubscribe(struct mqtt_ctx *ctx, u16_t pkt_id, u8_t items,
|
|
const char *topics[]);
|
|
|
|
|
|
/**
|
|
* Parses and validates the MQTT CONNACK msg
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
* @param [in] clean_session MQTT clean session parameter
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_connack(struct mqtt_ctx *ctx, struct net_buf *rx,
|
|
int clean_session);
|
|
|
|
/**
|
|
* Parses and validates the MQTT PUBACK message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_puback(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses and validates the MQTT PUBCOMP message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_pubcomp(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses and validates the MQTT PUBREC message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_pubrec(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses and validates the MQTT PUBREL message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_pubrel(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses the MQTT PINGRESP message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_pingresp(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses the MQTT SUBACK message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_suback(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses the MQTT UNSUBACK message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
*/
|
|
int mqtt_rx_unsuback(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* Parses the MQTT PUBLISH message
|
|
*
|
|
* @param [in] ctx MQTT context structure
|
|
* @param [in] rx Data buffer
|
|
*
|
|
* @retval 0 on success
|
|
* @retval -EINVAL
|
|
* @retval -ENOMEM
|
|
*/
|
|
int mqtt_rx_publish(struct mqtt_ctx *ctx, struct net_buf *rx);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _MQTT_H_ */
|