401 lines
14 KiB
C
401 lines
14 KiB
C
/*
|
|
* Copyright (c) 2018 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/** @file mqtt_internal.h
|
|
*
|
|
* @brief Function and data structures internal to MQTT module.
|
|
*/
|
|
|
|
#ifndef MQTT_INTERNAL_H_
|
|
#define MQTT_INTERNAL_H_
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <zephyr/net/mqtt.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**@brief Keep alive time for MQTT (in seconds). Sending of Ping Requests to
|
|
* keep the connection alive are governed by this value.
|
|
*/
|
|
#define MQTT_KEEPALIVE CONFIG_MQTT_KEEPALIVE
|
|
|
|
/**@brief Clean session on every connect (1) or keep subscriptions and messages
|
|
* between connects (0)
|
|
*/
|
|
#define MQTT_CLEAN_SESSION (IS_ENABLED(CONFIG_MQTT_CLEAN_SESSION) ? 1U : 0U)
|
|
|
|
/**@brief Minimum mandatory size of fixed header. */
|
|
#define MQTT_FIXED_HEADER_MIN_SIZE 2
|
|
|
|
/**@brief Maximum size of the fixed header. Remaining length size is 4 in this
|
|
* case.
|
|
*/
|
|
#define MQTT_FIXED_HEADER_MAX_SIZE 5
|
|
|
|
/**@brief MQTT Control Packet Types. */
|
|
#define MQTT_PKT_TYPE_CONNECT 0x10
|
|
#define MQTT_PKT_TYPE_CONNACK 0x20
|
|
#define MQTT_PKT_TYPE_PUBLISH 0x30
|
|
#define MQTT_PKT_TYPE_PUBACK 0x40
|
|
#define MQTT_PKT_TYPE_PUBREC 0x50
|
|
#define MQTT_PKT_TYPE_PUBREL 0x60
|
|
#define MQTT_PKT_TYPE_PUBCOMP 0x70
|
|
#define MQTT_PKT_TYPE_SUBSCRIBE 0x80
|
|
#define MQTT_PKT_TYPE_SUBACK 0x90
|
|
#define MQTT_PKT_TYPE_UNSUBSCRIBE 0xA0
|
|
#define MQTT_PKT_TYPE_UNSUBACK 0xB0
|
|
#define MQTT_PKT_TYPE_PINGREQ 0xC0
|
|
#define MQTT_PKT_TYPE_PINGRSP 0xD0
|
|
#define MQTT_PKT_TYPE_DISCONNECT 0xE0
|
|
|
|
/**@brief Masks for MQTT header flags. */
|
|
#define MQTT_HEADER_DUP_MASK 0x08
|
|
#define MQTT_HEADER_QOS_MASK 0x06
|
|
#define MQTT_HEADER_RETAIN_MASK 0x01
|
|
|
|
/**@brief Masks for MQTT header flags. */
|
|
#define MQTT_CONNECT_FLAG_CLEAN_SESSION 0x02
|
|
#define MQTT_CONNECT_FLAG_WILL_TOPIC 0x04
|
|
#define MQTT_CONNECT_FLAG_WILL_RETAIN 0x20
|
|
#define MQTT_CONNECT_FLAG_PASSWORD 0x40
|
|
#define MQTT_CONNECT_FLAG_USERNAME 0x80
|
|
|
|
#define MQTT_CONNACK_FLAG_SESSION_PRESENT 0x01
|
|
|
|
/**@brief Maximum payload size of MQTT packet. */
|
|
#define MQTT_MAX_PAYLOAD_SIZE 0x0FFFFFFF
|
|
|
|
/**@brief Computes total size needed to pack a UTF8 string. */
|
|
#define GET_UT8STR_BUFFER_SIZE(STR) (sizeof(uint16_t) + (STR)->size)
|
|
|
|
/**@brief Computes total size needed to pack a binary stream. */
|
|
#define GET_BINSTR_BUFFER_SIZE(STR) ((STR)->len)
|
|
|
|
/**@brief Sets MQTT Client's state with one indicated in 'STATE'. */
|
|
#define MQTT_SET_STATE(CLIENT, STATE) ((CLIENT)->internal.state |= (STATE))
|
|
|
|
/**@brief Sets MQTT Client's state exclusive to 'STATE'. */
|
|
#define MQTT_SET_STATE_EXCLUSIVE(CLIENT, STATE) \
|
|
((CLIENT)->internal.state = (STATE))
|
|
|
|
/**@brief Verifies if MQTT Client's state is set with one indicated in 'STATE'.
|
|
*/
|
|
#define MQTT_HAS_STATE(CLIENT, STATE) ((CLIENT)->internal.state & (STATE))
|
|
|
|
/**@brief Reset 'STATE' in MQTT Client's state. */
|
|
#define MQTT_RESET_STATE(CLIENT, STATE) ((CLIENT)->internal.state &= ~(STATE))
|
|
|
|
/**@brief Initialize MQTT Client's state. */
|
|
#define MQTT_STATE_INIT(CLIENT) ((CLIENT)->internal.state = MQTT_STATE_IDLE)
|
|
|
|
/**@brief Computes the first byte of MQTT message header based on message type,
|
|
* duplication flag, QoS and the retain flag.
|
|
*/
|
|
#define MQTT_MESSAGES_OPTIONS(TYPE, DUP, QOS, RETAIN) \
|
|
(((TYPE) & 0xF0) | \
|
|
(((DUP) << 3) & 0x08) | \
|
|
(((QOS) << 1) & 0x06) | \
|
|
((RETAIN) & 0x01))
|
|
|
|
#define MQTT_MAX_LENGTH_BYTES 4
|
|
#define MQTT_LENGTH_VALUE_MASK 0x7F
|
|
#define MQTT_LENGTH_CONTINUATION_BIT 0x80
|
|
#define MQTT_LENGTH_SHIFT 7
|
|
|
|
/**@brief Check if the input pointer is NULL, if so it returns -EINVAL. */
|
|
#define NULL_PARAM_CHECK(param) \
|
|
do { \
|
|
if ((param) == NULL) { \
|
|
return -EINVAL; \
|
|
} \
|
|
} while (false)
|
|
|
|
#define NULL_PARAM_CHECK_VOID(param) \
|
|
do { \
|
|
if ((param) == NULL) { \
|
|
return; \
|
|
} \
|
|
} while (false)
|
|
|
|
/** Buffer context to iterate over buffer. */
|
|
struct buf_ctx {
|
|
uint8_t *cur;
|
|
uint8_t *end;
|
|
};
|
|
|
|
/**@brief MQTT States. */
|
|
enum mqtt_state {
|
|
/** Idle state, implying the client entry in the table is unused/free.
|
|
*/
|
|
MQTT_STATE_IDLE = 0x00000000,
|
|
|
|
/** TCP Connection has been requested, awaiting result of the request.
|
|
*/
|
|
MQTT_STATE_TCP_CONNECTING = 0x00000001,
|
|
|
|
/** TCP Connection successfully established. */
|
|
MQTT_STATE_TCP_CONNECTED = 0x00000002,
|
|
|
|
/** MQTT Connection successful. */
|
|
MQTT_STATE_CONNECTED = 0x00000004,
|
|
};
|
|
|
|
/**@brief Notify application about MQTT event.
|
|
*
|
|
* @param[in] client Identifies the client for which event occurred.
|
|
* @param[in] evt MQTT event.
|
|
*/
|
|
void event_notify(struct mqtt_client *client, const struct mqtt_evt *evt);
|
|
|
|
/**@brief Handles MQTT messages received from the peer.
|
|
*
|
|
* @param[in] client Identifies the client for which the data was received.
|
|
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int mqtt_handle_rx(struct mqtt_client *client);
|
|
|
|
/**@brief Constructs/encodes Connect packet.
|
|
*
|
|
* @param[in] client Identifies the client for which the procedure is requested.
|
|
* All information required for creating the packet like
|
|
* client id, clean session flag, retain session flag etc are
|
|
* assumed to be populated for the client instance when this
|
|
* procedure is requested.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int connect_request_encode(const struct mqtt_client *client,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Publish packet.
|
|
*
|
|
* @param[in] param Publish message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_encode(const struct mqtt_publish_param *param, struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Publish Ack packet.
|
|
*
|
|
* @param[in] param Publish Ack message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_ack_encode(const struct mqtt_puback_param *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Publish Receive packet.
|
|
*
|
|
* @param[in] param Publish Receive message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_receive_encode(const struct mqtt_pubrec_param *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Publish Release packet.
|
|
*
|
|
* @param[in] param Publish Release message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_release_encode(const struct mqtt_pubrel_param *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Publish Complete packet.
|
|
*
|
|
* @param[in] param Publish Complete message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_complete_encode(const struct mqtt_pubcomp_param *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Disconnect packet.
|
|
*
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int disconnect_encode(struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Subscribe packet.
|
|
*
|
|
* @param[in] param Subscribe message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int subscribe_encode(const struct mqtt_subscription_list *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Unsubscribe packet.
|
|
*
|
|
* @param[in] param Unsubscribe message parameters.
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int unsubscribe_encode(const struct mqtt_subscription_list *param,
|
|
struct buf_ctx *buf);
|
|
|
|
/**@brief Constructs/encodes Ping Request packet.
|
|
*
|
|
* @param[inout] buf_ctx Pointer to the buffer context structure,
|
|
* containing buffer for the encoded message.
|
|
* As output points to the beginning and end of
|
|
* the frame.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int ping_request_encode(struct buf_ctx *buf);
|
|
|
|
/**@brief Decode MQTT Packet Type and Length in the MQTT fixed header.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] type_and_flags Message type and flags.
|
|
* @param[out] length Length of variable header and payload in the MQTT message.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int fixed_header_decode(struct buf_ctx *buf, uint8_t *type_and_flags,
|
|
uint32_t *length);
|
|
|
|
/**@brief Decode MQTT Connect Ack packet.
|
|
*
|
|
* @param[in] client MQTT client for which packet is decoded.
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Connect Ack parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int connect_ack_decode(const struct mqtt_client *client, struct buf_ctx *buf,
|
|
struct mqtt_connack_param *param);
|
|
|
|
/**@brief Decode MQTT Publish packet.
|
|
*
|
|
* @param[in] flags Byte containing message type and flags.
|
|
* @param[in] var_length Length of the variable part of the message.
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Publish parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_decode(uint8_t flags, uint32_t var_length, struct buf_ctx *buf,
|
|
struct mqtt_publish_param *param);
|
|
|
|
/**@brief Decode MQTT Publish Ack packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Publish Ack parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_ack_decode(struct buf_ctx *buf, struct mqtt_puback_param *param);
|
|
|
|
/**@brief Decode MQTT Publish Receive packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Publish Receive parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_receive_decode(struct buf_ctx *buf,
|
|
struct mqtt_pubrec_param *param);
|
|
|
|
/**@brief Decode MQTT Publish Release packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Publish Release parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_release_decode(struct buf_ctx *buf,
|
|
struct mqtt_pubrel_param *param);
|
|
|
|
/**@brief Decode MQTT Publish Complete packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Publish Complete parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int publish_complete_decode(struct buf_ctx *buf,
|
|
struct mqtt_pubcomp_param *param);
|
|
|
|
/**@brief Decode MQTT Subscribe packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Subscribe parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int subscribe_ack_decode(struct buf_ctx *buf,
|
|
struct mqtt_suback_param *param);
|
|
|
|
/**@brief Decode MQTT Unsubscribe packet.
|
|
*
|
|
* @param[inout] buf A pointer to the buf_ctx structure containing current
|
|
* buffer position.
|
|
* @param[out] param Pointer to buffer for decoded Unsubscribe parameters.
|
|
*
|
|
* @return 0 if the procedure is successful, an error code otherwise.
|
|
*/
|
|
int unsubscribe_ack_decode(struct buf_ctx *buf,
|
|
struct mqtt_unsuback_param *param);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* MQTT_INTERNAL_H_ */
|