From 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 23 Aug 2018 17:08:59 +0200 Subject: o Initial import. --- .../components/iot/mqtt/mqtt_internal.h | 446 +++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h') diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h new file mode 100644 index 0000000..807b2f9 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h @@ -0,0 +1,446 @@ +/** + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/** @file mqtt_internal.h + * + * @brief Function and data structures internal to MQTT module. + */ + +#ifndef MQTT_INTERNAL_H_ +#define MQTT_INTERNAL_H_ + +#include "nordic_common.h" +#include "sdk_common.h" +#include "sdk_config.h" +#include "mqtt.h" +#include "iot_errors.h" +#include "nrf_tls.h" +#include +#include +#include "nrf_error.h" +#include "nrf_tls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MQTT_MAX_CLIENTS +#define MQTT_MAX_CLIENTS 1 /**< Maximum number of clients that can be managed by the module. */ +#endif //MQTT_MAX_CLIENTS + +#ifndef MQTT_KEEPALIVE +#define MQTT_KEEPALIVE 60 /**< Keep alive time for MQTT (in seconds). Sending of Ping Requests to be keep the connection alive are governed by this value. */ +#endif //MQTT_KEEPALIVE + +#ifndef MQTT_MAX_PACKET_LENGTH +#define MQTT_MAX_PACKET_LENGTH 128 /**< Maximum MQTT packet size that can be sent (including the fixed and variable header). */ +#endif // MQTT_MAX_PACKET_LENGTH + +#define MQTT_FIXED_HEADER_SIZE 2 /**< Fixed header minimum size. Remaining length size is 1 in this case. */ +#define MQTT_FIXED_HEADER_EXTENDED_SIZE 5 /**< Maximum size of the fixed header. Remaining length size is 4 in this case. */ + +/**@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 0x82 // QoS 1 for subscribe +#define MQTT_PKT_TYPE_SUBACK 0x90 +#define MQTT_PKT_TYPE_UNSUBSCRIBE 0xA2 +#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 +#define MQTT_HEADER_CONNACK_MASK 0x0F + +/**@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 + +/**@brief Size of mandatory header of MQTT Packet. */ +#define MQTT_PKT_HEADER_SIZE 2 + +/**@brief */ +#define MQTT_MAX_PAYLOAD_SIZE 0x0FFFFFFF + +/**@brief Maximum size of variable and payload in the packet. */ +#define MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD (MQTT_MAX_PACKET_LENGTH - MQTT_FIXED_HEADER_EXTENDED_SIZE) + +/**@brief Defines size of uint8 in bytes. */ +#define SIZE_OF_UINT8 1 + +/**@brief Defines size of uint8 in bytes. */ +#define SIZE_OF_UINT16 2 + +/**@brief Computes total size needed to pack a UTF8 string. */ +#define GET_UT8STR_BUFFER_SIZE(STR) (SIZE_OF_UINT16 + (STR)->utf_strlen) + +/**@brief Computes total size needed to pack a binary stream. */ +#define GET_BINSTR_BUFFER_SIZE(STR) ((STR)->bin_strlen) + +/**@brief Unsubscribe packet size. */ +#define MQTT_UNSUBSCRIBE_PKT_SIZE 4 + +/**@brief Sets MQTT Client's state with one indicated in 'STATE'. */ +#define MQTT_SET_STATE(CLIENT, STATE) ((CLIENT)->state |= (STATE)) + +/**@brief Sets MQTT Client's state exclusive to 'STATE'. */ +#define MQTT_SET_STATE_EXCLUSIVE(CLIENT, STATE) ((CLIENT)->state = (STATE)) + +/**@brief Verifies if MQTT Client's state is set with one indicated in 'STATE'. */ +#define MQTT_VERIFY_STATE(CLIENT, STATE) ((CLIENT)->state & (STATE)) + +/**@brief Reset 'STATE' in MQTT Client's state. */ +#define MQTT_RESET_STATE(CLIENT, STATE) ((CLIENT)->state &= ~(STATE)) + +/**@brief Initialize MQTT Client's state. */ +#define MQTT_STATE_INIT(CLIENT) (CLIENT)->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_EVT_FLAG_NONE 0x00000000 +#define MQTT_EVT_FLAG_INSTANCE_RESET 0x00000001 + + +/** + * @defgroup iot_mqtt_mutex_lock_unlock Module's Mutex Lock/Unlock Macros. + * + * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but + * framework is provided in case the need to use an alternative architecture arises. + * @{ + */ +#define MQTT_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mqtt_mutex) /**< Lock module using mutex */ +#define MQTT_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mqtt_mutex) /**< Unlock module using mutex */ + +/** @} */ + +/**@brief Check if the input pointer is NULL, if so it returns NRF_ERROR_NULL. + */ +#define NULL_PARAM_CHECK(PARAM) \ + if ((PARAM) == NULL) \ + { \ + return (NRF_ERROR_NULL | IOT_MQTT_ERR_BASE); \ + } + +#define NULL_PARAM_CHECK_VOID(PARAM) \ + if ((PARAM) == NULL) \ + { \ + return; \ + } + +/**@brief MQTT States. */ +typedef enum +{ + MQTT_STATE_IDLE = 0x00000000, /**< Idle state, implying the client entry in the table is unused/free. */ + MQTT_STATE_TCP_CONNECTING = 0x00000001, /**< TCP Connection has been requested, awaiting result of the request. */ + MQTT_STATE_TCP_CONNECTED = 0x00000002, /**< TCP Connection successfully established. */ + MQTT_STATE_CONNECTED = 0x00000004, /**< MQTT Connection successful. */ + MQTT_STATE_PENDING_WRITE = 0x00000008, /**< State that indicates write callback is awaited for an issued request. */ + MQTT_STATE_DISCONNECTING = 0x00000010 /**< TCP Disconnect has been requested, awaiting result of the request. */ +} mqtt_state_t; + + +/**@brief Packs unsigned 8 bit value to the buffer at the offset requested. + * + * @param[in] val Value to be packed. + * @param[in] buffer_len Total size of the buffer on which value is to be packed. + * This shall not be zero. + * @param[out] p_buffer Buffer where the value is to be packed. + * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure + * is successful, the offset is incremented to point to the next write/pack + * location on the buffer. + * + * @retval NRF_SUCCESS if procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t pack_uint8(uint8_t val, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Packs unsigned 16 bit value to the buffer at the offset requested. + * + * @param[in] val Value to be packed. + * @param[in] buffer_len Total size of the buffer on which value is to be packed. + * This shall not be zero. + * @param[out] p_buffer Buffer where the value is to be packed. + * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure + * is successful, the offset is incremented to point to the next write/pack + * location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus + * the size of unsigned 16 bit integer. + */ +uint32_t pack_uint16(uint16_t val, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Packs utf8 string to the buffer at the offset requested. + * + * @param[in] p_str UTF-8 string and its length to be packed. + * @param[in] buffer_len Total size of the buffer on which string is to be packed. + * This shall not be zero. + * @param[out] p_buffer Buffer where the string is to be packed. + * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure + * is successful, the offset is incremented to point to the next write/pack + * location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus + * the size of unsigned 16 bit integer. + * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string. + */ +uint32_t pack_utf8_str(mqtt_utf8_t const * const p_str, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Packs binary string to the buffer at the offset requested. + * + * @param[in] p_str Binary string and its length to be packed. + * @param[in] buffer_len Total size of the buffer on which string is to be packed. + * @param[in] p_buffer Buffer where the string is to be packed. + * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure + * is successful, the offset is incremented to point to the next write/pack + * location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string. + */ +uint32_t pack_bin_str(mqtt_binstr_t const * const p_str, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Unpacks unsigned 8 bit value from the buffer from the offset requested. + * + * @param[out] p_val Memory where the value is to be unpacked. + * @param[in] buffer_len Total size of the buffer. This shall not be zero. + * @param[in] p_buffer Buffer from which the value is to be unpacked. + * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the + * procedure is successful, the offset is incremented to point to the next + * read/unpack location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t unpack_uint8(uint8_t * p_val, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + +/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested. + * + * @param[out] p_val Memory where the value is to be unpacked. + * @param[in] buffer_len Total size of the buffer. This shall not be zero. + * @param[in] p_buffer Buffer from which the value is to be unpacked. + * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the + * procedure is successful, the offset is incremented to point to the next + * read/unpack location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t unpack_uint16(uint16_t * p_val, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested. + * + * @param[out] p_str Memory where the utf8 string and its value are to be unpacked. + * No copy of data is performed for the string. + * @param[in] buffer_len Total size of the buffer. This shall not be zero. + * @param[in] p_buffer Buffer from which the string is to be unpacked. + * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the + * procedure is successful, the offset is incremented to point to the next + * read/unpack location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Unpacks binary string from the buffer from the offset requested. + * + * @param[out] p_str Memory where the binary string and its length are to be unpacked. + * No copy of data is performed for the string. + * @param[in] buffer_len Total size of the buffer. This shall not be zero. + * @param[in] p_buffer Buffer where the value is to be unpacked. + * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the + * procedure is successful, the offset is incremented to point to the next + * read/unpack location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t unpack_bin_str(mqtt_binstr_t * const p_str, + uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Unpacks utf8 string from the buffer from the offset requested. + * + * @param[out] p_str Memory where the utf8 string and its length are to be unpacked. + * @param[in] buffer_len Total size of the buffer. This shall not be zero. + * @param[in] p_buffer Buffer where the value is to be unpacked. + * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the + * procedure is successful, the offset is incremented to point to the next + * read/unpack location on the buffer. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t zero_len_str_encode(uint32_t buffer_len, + uint8_t * const p_buffer, + uint32_t * const p_offset); + + +/**@brief Computes and encodes length for the MQTT fixed header. + * + * @note The remaining length is not packed as a fixed unsigned 32 bit integer. Instead it is packed + * on algorithm below: + * + * @code + * do + * encodedByte = X MOD 128 + * X = X DIV 128 + * // if there are more data to encode, set the top bit of this byte + * if ( X > 0 ) + * encodedByte = encodedByte OR 128 + * endif + * 'output' encodedByte + * while ( X > 0 ) + * @endcode + * + * @param[in] remaining_length Length of variable header and payload in the MQTT message. + * @param[out] p_buffer Buffer where the length is to be packed. + * @param[inout] p_offset Offset on the buffer where the length is to be packed. + */ +void packet_length_encode(uint32_t remaining_length, uint8_t * p_buffer, uint32_t * p_offset); + + +/**@brief Decode MQTT Packet Length in the MQTT fixed header. + * + * @param[in] p_buffer Buffer where the length is to be decoded. + * @param[in] buffer_len Length of p_buffer + * @param[out] p_remaining_length Length of variable header and payload in the MQTT message. + * @param[inout] p_offset Offset on the buffer from where the length is to be unpacked. + * + * @retval NRF_SUCCESS if the procedure is successful. + * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length. + */ +uint32_t packet_length_decode(uint8_t * p_buffer, + uint32_t buffer_len, + uint32_t * p_remaining_length, + uint32_t * p_offset); + + +/**@brief Encodes fixed header for the MQTT message and provides pointer to start of the header. + * + * @param[in] message_type Message type containing packet type and the flags. + * Use @ref MQTT_MESSAGES_OPTIONS to construct the message_type. + * @param[in] length Buffer where the message payload along with variable header. + * @param[inout] pp_packet Pointer to the MQTT message variable header and payload. + * The 5 bytes before the start of the message are assumed by the + * routine to be available to pack the fixed header. However, since + * the fixed header length is variable length, the pointer to the + * start of the MQTT message along with encoded fixed header is + * supplied as output parameter if the procedure was successful. + * + * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the + * fixed header. + */ +uint32_t mqtt_encode_fixed_header(uint8_t message_type, uint32_t length, uint8_t ** pp_packet); + + +/**@brief Constructs/encodes connect packet. + * + * @param[in] p_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[out] pp_packet Pointer to the MQTT connect message. + * @param[out] p_packet_length Length of the connect request. + * + * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the + * fixed header. + */ +void connect_request_encode(const mqtt_client_t * p_client, + uint8_t ** pp_packet, + uint32_t * p_packet_length); + +#ifdef __cplusplus +} +#endif + +#endif // MQTT_INTERNAL_H_ -- cgit v1.2.3