started documenting

Docummented Connect ACK and IntVB
This commit is contained in:
brenodetomini
2024-02-15 20:26:43 -03:00
parent f91fe172be
commit ccd31f1802
9 changed files with 223 additions and 73 deletions

View File

@@ -19,4 +19,5 @@ project(mqttd VERSION ${MQTTD_VERSION} LANGUAGES CXX)
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(docs)

View File

@@ -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
View 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")

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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();

View File

@@ -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