started documenting
Docummented Connect ACK and IntVB
This commit is contained in:
@@ -19,4 +19,5 @@ project(mqttd VERSION ${MQTTD_VERSION} LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(docs)
|
||||
|
||||
|
||||
@@ -17,15 +17,16 @@ Result Variables
|
||||
indicates Autotools and associated programs are detected
|
||||
#]=======================================================================]
|
||||
|
||||
find_program(AUTOCONF_EXECUTABLE
|
||||
NAMES autoconf
|
||||
DOC "Autoconf")
|
||||
find_program(
|
||||
AUTOCONF_EXECUTABLE
|
||||
NAMES autoconf
|
||||
DOC "Autoconf")
|
||||
|
||||
if(AUTOCONF_EXECUTABLE)
|
||||
execute_process(COMMAND ${AUTOCONF_EXECUTABLE} --version
|
||||
RESULT_VARIABLE ret
|
||||
OUTPUT_VARIABLE out
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${AUTOCONF_EXECUTABLE} --version
|
||||
RESULT_VARIABLE ret
|
||||
OUTPUT_VARIABLE out)
|
||||
message(DEBUG "${out}")
|
||||
if(ret EQUAL 0)
|
||||
string(REGEX MATCH "autoconf .*([0-9]+\\.[0-9]+)" _m "${out}")
|
||||
@@ -33,30 +34,28 @@ if(AUTOCONF_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(AUTOMAKE_EXECUTABLE
|
||||
NAMES automake
|
||||
DOC "Automake")
|
||||
find_program(
|
||||
AUTOMAKE_EXECUTABLE
|
||||
NAMES automake
|
||||
DOC "Automake")
|
||||
|
||||
find_program(LIBTOOL_EXECUTABLE
|
||||
NAMES glibtool libtool
|
||||
NAMES_PER_DIR
|
||||
DOC "libtool"
|
||||
)
|
||||
find_program(
|
||||
LIBTOOL_EXECUTABLE
|
||||
NAMES glibtool libtool NAMES_PER_DIR
|
||||
DOC "libtool")
|
||||
|
||||
find_program(M4_EXECUTABLE
|
||||
NAMES gm4 m4
|
||||
NAMES_PER_DIR
|
||||
DOC "M4"
|
||||
)
|
||||
|
||||
find_program(MAKE_EXECUTABLE
|
||||
NAMES gmake make
|
||||
NAMES_PER_DIR
|
||||
DOC "GNU Make")
|
||||
find_program(
|
||||
M4_EXECUTABLE
|
||||
NAMES gm4 m4 NAMES_PER_DIR
|
||||
DOC "M4")
|
||||
|
||||
find_program(
|
||||
MAKE_EXECUTABLE
|
||||
NAMES gmake make NAMES_PER_DIR
|
||||
DOC "GNU Make")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Autotools
|
||||
VERSION_VAR AUTOCONF_VERSION
|
||||
REQUIRED_VARS AUTOCONF_EXECUTABLE AUTOMAKE_EXECUTABLE MAKE_EXECUTABLE
|
||||
)
|
||||
find_package_handle_standard_args(
|
||||
Autotools
|
||||
VERSION_VAR AUTOCONF_VERSION
|
||||
REQUIRED_VARS AUTOCONF_EXECUTABLE AUTOMAKE_EXECUTABLE MAKE_EXECUTABLE)
|
||||
|
||||
39
docs/CMakeLists.txt
Normal file
39
docs/CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
option(BUILD_DOC "Build documentation" ON)
|
||||
|
||||
find_package(Doxygen REQUIRED doxygen OPTIONAL_COMPONENTS dot mscgen dia)
|
||||
|
||||
if(NOT DOXYGEN_FOUND)
|
||||
message(ERROR "Doxygen is needed to build documentation, please install it")
|
||||
endif()
|
||||
|
||||
set(DOXYGEN_ALPHABETICAL_INDEX NO)
|
||||
set(DOXYGEN_BUILTIN_STL_SUPPORT YES)
|
||||
set(DOXYGEN_CASE_SENSE_NAMES NO)
|
||||
set(DOXYGEN_CLASS_DIAGRAMS YES)
|
||||
set(DOXYGEN_DISTRIBUTE_GROUP_DOC YES)
|
||||
set(DOXYGEN_EXCLUDE build)
|
||||
set(DOXYGEN_EXTRACT_ALL YES)
|
||||
set(DOXYGEN_EXTRACT_LOCAL_CLASSES NO)
|
||||
set(DOXYGEN_FILE_PATTERNS *.hpp)
|
||||
set(DOXYGEN_GENERATE_TREEVIEW YES)
|
||||
set(DOXYGEN_HIDE_FRIEND_COMPOUNDS YES)
|
||||
set(DOXYGEN_HIDE_IN_BODY_DOCS YES)
|
||||
set(DOXYGEN_HIDE_UNDOC_CLASSES YES)
|
||||
set(DOXYGEN_HIDE_UNDOC_MEMBERS YES)
|
||||
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
|
||||
set(DOXYGEN_QT_AUTOBRIEF YES)
|
||||
set(DOXYGEN_QUIET YES)
|
||||
set(DOXYGEN_RECURSIVE YES)
|
||||
set(DOXYGEN_REFERENCED_BY_RELATION YES)
|
||||
set(DOXYGEN_REFERENCES_RELATION YES)
|
||||
set(DOXYGEN_SORT_BY_SCOPE_NAME YES)
|
||||
set(DOXYGEN_SORT_MEMBER_DOCS NO)
|
||||
set(DOXYGEN_SOURCE_BROWSER YES)
|
||||
set(DOXYGEN_STRIP_CODE_COMMENTS NO)
|
||||
|
||||
doxygen_add_docs(doc
|
||||
"${CMAKE_SOURCE_DIR}/src"
|
||||
"${CMAKE_SOURCE_DIR}/tests"
|
||||
ALL
|
||||
COMMENT "Generate HTML documentation")
|
||||
|
||||
@@ -30,14 +30,14 @@ void SessionManager::add_session_to_pool(Session *session) {
|
||||
std::unique_lock<std::shared_mutex> lock(this->connected_sessions_lock);
|
||||
this->connected_sessions.emplace(session->client_id, session);
|
||||
spdlog::debug("Added session " + session->client_id + " to session pool");
|
||||
lock.unlock();
|
||||
spdlog::info("Client " + session->client_id + " connected");
|
||||
}
|
||||
|
||||
void SessionManager::remove_session_from_pool(Session *session) {
|
||||
std::unique_lock<std::shared_mutex> lock(this->connected_sessions_lock);
|
||||
this->connected_sessions.erase(session->client_id);
|
||||
lock.unlock();
|
||||
spdlog::debug("Removed session " + session->client_id + " from session pool");
|
||||
spdlog::info("Client " + session->client_id + " disconnected");
|
||||
}
|
||||
|
||||
void SessionManager::create_session(int socket_fd) {
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
ConnectACK::ConnectACK() : PacketInterface() {
|
||||
PacketInterface::fixed_header.packet_type = PacketType::CONNACK;
|
||||
PacketInterface::fixed_header.packet_flags = 0;
|
||||
// There is a obrigatory reason code and connect acknowledge flags after fixed header, thus we are garanteed to have at least 2 bytes
|
||||
// There is a obrigatory reason code and connect acknowledge flags after fixed header, thus we are garanted to have at least 2 bytes
|
||||
PacketInterface::fixed_header.remaining_length = 2;
|
||||
this->reason_code = ConnectReasonCode::SUCCESS;
|
||||
this->session_present = false;
|
||||
};
|
||||
|
||||
void ConnectACK::add_property(const PropertyIdentifier &prop, const PropertyValue &value) {
|
||||
|
||||
@@ -4,45 +4,99 @@
|
||||
#include <packet_interface.hpp>
|
||||
#include <property.hpp>
|
||||
|
||||
/**
|
||||
* @brief Enum class representing the reason codes for MQTT Connect packets according to MQTT v5.0 specification.
|
||||
*
|
||||
* These reason codes are used to indicate the result of a connection attempt.
|
||||
* Refer to <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901079">MQTT Version 5.0 topic 3.2.2.2</a> for more information
|
||||
*/
|
||||
enum class ConnectReasonCode : uint8_t {
|
||||
SUCCESS = 0,
|
||||
UNSPECIFIED_ERROR = 128,
|
||||
MALFORMED_PACKET = 129,
|
||||
PROTOCOL_ERROR = 130,
|
||||
IMPLEMENTATION_SPECIFIC_ERROR = 131,
|
||||
UNSUPPORTED_PROTOCOL_VERSION = 132,
|
||||
CLIENT_IDENTIFIER_NOT_VALID = 133,
|
||||
BAD_USERNAME_OR_PASSWORD = 134,
|
||||
NOT_AUTHORIZED = 135,
|
||||
SERVER_UNAVAILABLE = 136,
|
||||
SERVER_BUSY = 137,
|
||||
BANNED = 138,
|
||||
BAD_AUTHENTICATION_METHOD = 140,
|
||||
TOPIC_NAME_INVALID = 144,
|
||||
PACKET_TOO_LARGE = 149,
|
||||
QUOTA_EXCEEDED = 151,
|
||||
PAYLOAD_FORMAT_INVALID = 153,
|
||||
RETAIN_NOT_SUPPORTED = 154,
|
||||
QOS_NOT_SUPPORTED = 155,
|
||||
USER_ANOTHER_SERVER = 156,
|
||||
SERVER_MOVED = 157,
|
||||
CONNECTION_RATE_EXCEEDED = 159
|
||||
SUCCESS = 0, /**< The Connection is accepted. */
|
||||
UNSPECIFIED_ERROR = 128, /**< The Server does not wish to reveal the reason for the failure, or none of the other Reason Codes apply. */
|
||||
MALFORMED_PACKET = 129, /**< Data within the CONNECT packet could not be correctly parsed. */
|
||||
PROTOCOL_ERROR = 130, /**< Data in the CONNECT packet does not conform to this specification. */
|
||||
IMPLEMENTATION_SPECIFIC_ERROR = 131, /**< The CONNECT is valid but is not accepted by this Server. */
|
||||
UNSUPPORTED_PROTOCOL_VERSION = 132, /**< The Server does not support the version of the MQTT protocol requested by the Client. */
|
||||
CLIENT_IDENTIFIER_NOT_VALID = 133, /**< The Client Identifier is a valid string but is not allowed by the Server. */
|
||||
BAD_USERNAME_OR_PASSWORD = 134, /**< The provided username or password is not valid. */
|
||||
NOT_AUTHORIZED = 135, /**< The Client is not authorized to connect. */
|
||||
SERVER_UNAVAILABLE = 136, /**< The MQTT Server is not available. */
|
||||
SERVER_BUSY = 137, /**< The Server is busy. Try again later. */
|
||||
BANNED = 138, /**< This Client has been banned by administrative action. */
|
||||
BAD_AUTHENTICATION_METHOD = 140, /**< The authentication method is not supported or does not match the authentication method currently in use. */
|
||||
TOPIC_NAME_INVALID = 144, /**< The Will Topic Name is not malformed, but is not accepted by this Server. */
|
||||
PACKET_TOO_LARGE = 149, /**< The CONNECT packet exceeded the maximum permissible size. */
|
||||
QUOTA_EXCEEDED = 151, /**< An implementation or administrative imposed limit has been exceeded. */
|
||||
PAYLOAD_FORMAT_INVALID = 153, /**< The Will Payload does not match the specified Payload Format Indicator. */
|
||||
RETAIN_NOT_SUPPORTED = 154, /**< The Server does not support retained messages, and Will Retain was set to 1. */
|
||||
QOS_NOT_SUPPORTED = 155, /**< The Server does not support the QoS set in Will QoS. */
|
||||
USER_ANOTHER_SERVER = 156, /**< The Client should temporarily use another server. */
|
||||
SERVER_MOVED = 157, /**< The Client should permanently use another server. */
|
||||
CONNECTION_RATE_EXCEEDED = 159 /**< The connection rate limit has been exceeded. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Connect Acknowledge packet according to <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901074">MQTT Version 5.0 topic 3.2</a>.
|
||||
*
|
||||
* This class represents a Connect Acknowledge packet as defined in the MQTT Version 5.0 specification (topic 3.2).
|
||||
*/
|
||||
class ConnectACK : public PacketInterface {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new Connect ACK packet with default values.
|
||||
*
|
||||
* The default values are: reason code set to SUCCESS (0x00) and session_present set to false.
|
||||
*/
|
||||
ConnectACK();
|
||||
~ConnectACK() = default;
|
||||
|
||||
/**
|
||||
* @brief Sets the session_present value.
|
||||
*
|
||||
* @param value The value to set for session_present.
|
||||
*/
|
||||
void set_session_present(const bool &value) { this->session_present = value; };
|
||||
|
||||
/**
|
||||
* @brief Sets the reason code to be returned to the client.
|
||||
*
|
||||
* @param value The ConnectReasonCode to set as the reason code.
|
||||
*/
|
||||
void set_reason_code(const ConnectReasonCode &value) { this->reason_code = value; };
|
||||
void add_property(const PropertyIdentifier&, const PropertyValue&);
|
||||
|
||||
/**
|
||||
* @brief Adds a property to the property map.
|
||||
*
|
||||
* @param identifier The identifier of the property to add.
|
||||
* @param value The value of the property to add.
|
||||
*/
|
||||
void add_property(const PropertyIdentifier& identifier, const PropertyValue& value);
|
||||
|
||||
/**
|
||||
* @brief Converts the packet to bytes for transmission over a socket to the client.
|
||||
*
|
||||
* @return A vector of bytes representing the packet.
|
||||
*/
|
||||
std::vector<std::byte> as_bytes();
|
||||
|
||||
private:
|
||||
//Variable Header
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the Server is using Session State from a previous connection for the respective ClientID.
|
||||
*/
|
||||
bool session_present;
|
||||
|
||||
/**
|
||||
* @brief The reason code indicating if the connection was accepted or not.
|
||||
*
|
||||
* Only ConnectReasonCode::SUCCESS indicates a successful connection.
|
||||
*/
|
||||
ConnectReasonCode reason_code;
|
||||
|
||||
/**
|
||||
* @brief Map of MQTT properties associated with the packet.
|
||||
*/
|
||||
MQTTProperties properties;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef INCLUDE_TYPES_VARIABLE_BYTE_INT_HPP_
|
||||
#define INCLUDE_TYPES_VARIABLE_BYTE_INT_HPP_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <type_interface.hpp>
|
||||
@@ -9,42 +8,99 @@
|
||||
#include <bit.hpp>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Class representing a Variable Byte Integer according to MQTT v5 section 1.5.5.
|
||||
*
|
||||
* This class provides functionality to handle Variable Byte Integers as defined in the MQTT v5 specification.
|
||||
*
|
||||
* For more details, refer to: <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901011">MQTT v5.0 specification, section 1.5.5</a>.
|
||||
*/
|
||||
class VariableByteInteger : public TypeInterface {
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a new Variable Byte Integer object with a default value of 0.
|
||||
*/
|
||||
VariableByteInteger();
|
||||
|
||||
// Create a VariableByte Integer from a pure integer value
|
||||
/**
|
||||
* @brief Creates a new Variable Byte Integer object from an integral integer value.
|
||||
*
|
||||
* @param decoded_value The integral value to initialize the Variable Byte Integer with.
|
||||
*/
|
||||
VariableByteInteger(const uint32_t &decoded_value);
|
||||
|
||||
// Create a VariableByte Integer from a byte array that representes a
|
||||
// VariableByteInteger
|
||||
/**
|
||||
* @brief Creates a new Variable Byte Integer object from a byte vector representing an encoded Variable Byte Integer.
|
||||
*
|
||||
* @param encoded_value The byte vector representing the encoded Variable Byte Integer.
|
||||
* The vector must have at least 4 bytes, further bytes will be ignored.
|
||||
*/
|
||||
VariableByteInteger(const std::vector<std::byte> &encoded_value);
|
||||
|
||||
// Create a VariableByte Integer from the start of byte vector that representes a
|
||||
// VariableByteInteger
|
||||
/**
|
||||
* @brief Creates a new Variable Byte Integer object from a byte vector iterator pointing to the beginning of the data representing an encoded Variable Byte Integer.
|
||||
*
|
||||
* @param encoded_value_start The iterator pointing to the beginning of the data representing the encoded Variable Byte Integer.
|
||||
* The vector must have at least 4 bytes, further bytes will be ignored.
|
||||
*/
|
||||
VariableByteInteger(const std::vector<std::byte>::const_iterator &encoded_value_start);
|
||||
|
||||
~VariableByteInteger();
|
||||
|
||||
/**
|
||||
* @brief Gets the size of the Variable Byte Integer in bytes.
|
||||
*
|
||||
* @return The size of the Variable Byte Integer in bytes.
|
||||
*/
|
||||
uint16_t size() const final { return this->bytes_count; };
|
||||
|
||||
/**
|
||||
* @brief Gets the decoded value of the Variable Byte Integer as a string.
|
||||
*
|
||||
* @return The decoded value of the Variable Byte Integer as a string.
|
||||
*/
|
||||
std::string as_string() const final { return std::to_string(this->decoded_value); };
|
||||
|
||||
/**
|
||||
* @brief Gets the byte array representing the encoded value of a Variable Byte Integer.
|
||||
*
|
||||
* @return The byte array representing the encoded value of a Variable Byte Integer.
|
||||
*/
|
||||
std::vector<std::byte> as_bytes() const final { return this->encoded_value; };
|
||||
|
||||
/**
|
||||
* @brief Overloads the assignment operator for integral types.
|
||||
*
|
||||
* Enables assignment of a Variable Byte Integer from an integer.
|
||||
*/
|
||||
template <typename T> typename std::enable_if<std::is_integral<T>::value, VariableByteInteger &>::type operator=(T &);
|
||||
|
||||
/**
|
||||
* @brief Overloads the output stream operator to print a Variable Byte Integer as its decoded value.
|
||||
*/
|
||||
friend std::ostream &operator<<(std::ostream &, const VariableByteInteger &);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Conversion operator to uint32_t.
|
||||
*
|
||||
* @return The value of the Variable Byte Integer as a uint32_t.
|
||||
*/
|
||||
inline operator uint32_t() const { return this->decoded_value; };
|
||||
|
||||
// Maximum allowed value for a VariableByte Integer
|
||||
|
||||
/**
|
||||
* @brief Gets the maximum value allowed for a Variable Byte Integer.
|
||||
*
|
||||
* @return The maximum value allowed for a Variable Byte Integer.
|
||||
*/
|
||||
inline uint32_t max() const { return 268435455; };
|
||||
|
||||
private:
|
||||
std::vector<std::byte> encoded_value;
|
||||
std::vector<std::byte> encode(const unsigned int &);
|
||||
uint32_t decoded_value;
|
||||
uint32_t decode(const std::vector<std::byte> &);
|
||||
uint8_t bytes_count;
|
||||
std::vector<std::byte> encoded_value; /**< The value of the Variable Byte integer. */
|
||||
std::vector<std::byte> encode(const unsigned int &); /**< Encodes an integral type to a byte vector representing a Variable Byte Integer. */
|
||||
|
||||
uint32_t decoded_value; /**< The value of the Variable Byte Integer as an integer. */
|
||||
uint32_t decode(const std::vector<std::byte> &); /**< Decodes a byte vector to an integer. */
|
||||
uint8_t bytes_count; /**< How many bytes the #encoded_value has. */
|
||||
};
|
||||
|
||||
using int_vb = VariableByteInteger;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
|
||||
#include "spdlog/common.h"
|
||||
#include "version.hpp"
|
||||
#include <backtrace.hpp>
|
||||
#include <connection_listener.hpp>
|
||||
@@ -48,7 +47,7 @@ int main() {
|
||||
std::cout << "MQTTd Version " << MQTTD_VERSION_MAJOR << "." << MQTTD_VERSION_MINOR << "." << MQTTD_VERSION_PATCH << std::endl;
|
||||
set_signal_handlers();
|
||||
|
||||
spdlog::set_level(spdlog::level::debug);
|
||||
// spdlog::set_level(spdlog::level::debug);
|
||||
|
||||
clistener.start();
|
||||
clistener.join();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define MQTTD_VERSION_MAJOR 0
|
||||
#define MQTTD_VERSION_MINOR 0
|
||||
#define MQTTD_VERSION_PATCH 1
|
||||
#define MQTTD_COMMIT_HASH c644d9053beb97c953e877372fc938f4094121d2
|
||||
#define MQTTD_BUILD_TIMESTAMP 1707916275
|
||||
#define MQTTD_COMMIT_HASH f91fe172be4c51f393bdd4184e62281d75eac64e
|
||||
#define MQTTD_BUILD_TIMESTAMP 1707947036
|
||||
|
||||
Reference in New Issue
Block a user