| /* |
| * 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 (0) |
| |
| #define NULL_PARAM_CHECK_VOID(param) \ |
| do { \ |
| if ((param) == NULL) { \ |
| return; \ |
| } \ |
| } while (0) |
| |
| /** 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_ */ |