From 7edc3b8363283ca77d3e879388ff18ef9bf43cc7 Mon Sep 17 00:00:00 2001 From: Wiebe Cazemier Date: Wed, 9 Dec 2020 11:24:21 +0100 Subject: [PATCH] CONNECT with protocol 3.1, mostly --- client.cpp | 3 ++- client.h | 3 ++- mqttpacket.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++----------------------------------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/client.cpp b/client.cpp index 81d9087..5ba4a10 100644 --- a/client.cpp +++ b/client.cpp @@ -102,11 +102,12 @@ bool Client::bufferToMqttPackets(std::vector &packetQueueIn) // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space. } -void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen) +void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen, uint16_t keepalive) { this->clientid = clientId; this->username = username; this->connectPacketSeen = connectPacketSeen; + this->keepalive = keepalive; } diff --git a/client.h b/client.h index d4a7434..59f9d0e 100644 --- a/client.h +++ b/client.h @@ -30,6 +30,7 @@ class Client bool connectPacketSeen = false; std::string clientid; std::string username; + uint16_t keepalive = 0; ThreadData_p threadData; @@ -58,7 +59,7 @@ public: int getFd() { return fd;} bool readFdIntoBuffer(); bool bufferToMqttPackets(std::vector &packetQueueIn); - void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen); + void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen, uint16_t keepalive); void setAuthenticated(bool value) { authenticated = value;} bool getAuthenticated() { return authenticated; } bool hasConnectPacketSeen() { return connectPacketSeen; } diff --git a/mqttpacket.cpp b/mqttpacket.cpp index 2c1488f..834448b 100644 --- a/mqttpacket.cpp +++ b/mqttpacket.cpp @@ -27,7 +27,7 @@ void MqttPacket::handleConnect() // TODO: Do all packets have a variable header? variable_header_length = readTwoBytesToUInt16(); - if (variable_header_length == 4) + if (variable_header_length == 4 || variable_header_length == 6) { char *c = readBytes(variable_header_length); std::string magic_marker(c, variable_header_length); @@ -37,54 +37,61 @@ void MqttPacket::handleConnect() if (magic_marker == "MQTT" && protocol_level == 0x04) { protocolVersion = ProtocolVersion::Mqtt311; + } + else if (magic_marker == "MQIsdp" && protocol_level == 0x03) + { + protocolVersion = ProtocolVersion::Mqtt31; + } + else + { + throw ProtocolError("Only MQTT 3.1 and 3.1.1 supported."); + } - char flagByte = readByte(); - bool reserved = !!(flagByte & 0b00000001); + char flagByte = readByte(); + bool reserved = !!(flagByte & 0b00000001); - if (reserved) - throw ProtocolError("Protocol demands reserved flag in CONNECT is 0"); + if (reserved) + throw ProtocolError("Protocol demands reserved flag in CONNECT is 0"); - bool user_name_flag = !!(flagByte & 0b10000000); - bool password_flag = !!(flagByte & 0b01000000); - bool will_retain = !!(flagByte & 0b00100000); - char will_qos = (flagByte & 0b00011000) >> 3; - bool will_flag = !!(flagByte & 0b00000100); - bool clean_session = !!(flagByte & 0b00000010); + bool user_name_flag = !!(flagByte & 0b10000000); + bool password_flag = !!(flagByte & 0b01000000); + bool will_retain = !!(flagByte & 0b00100000); + char will_qos = (flagByte & 0b00011000) >> 3; + bool will_flag = !!(flagByte & 0b00000100); + bool clean_session = !!(flagByte & 0b00000010); - uint16_t keep_alive = readTwoBytesToUInt16(); + uint16_t keep_alive = readTwoBytesToUInt16(); - uint16_t client_id_length = readTwoBytesToUInt16(); - std::string client_id(readBytes(client_id_length), client_id_length); + uint16_t client_id_length = readTwoBytesToUInt16(); + std::string client_id(readBytes(client_id_length), client_id_length); - std::string username; - std::string password; + std::string username; + std::string password; - if (will_flag) - { + if (will_flag) + { - } - if (user_name_flag) - { - uint16_t user_name_length = readTwoBytesToUInt16(); - username = std::string(readBytes(user_name_length), user_name_length); - } - if (password_flag) - { - uint16_t password_length = readTwoBytesToUInt16(); - password = std::string(readBytes(password_length), password_length); - } + } + if (user_name_flag) + { + uint16_t user_name_length = readTwoBytesToUInt16(); + username = std::string(readBytes(user_name_length), user_name_length); + } + if (password_flag) + { + uint16_t password_length = readTwoBytesToUInt16(); + password = std::string(readBytes(password_length), password_length); + } - sender->setClientProperties(clientid, username, true); + // TODO: validate UTF8 encoded username/password. - } + sender->setClientProperties(clientid, username, true, keep_alive); } - else if (variable_header_length == 6) + else { - throw ProtocolError("Only MQTT 3.1.1 implemented."); + throw ProtocolError("Invalid variable header length. Garbage?"); } - - throw ProtocolError("Unprogrammed sequence in CONNECT."); } char *MqttPacket::readBytes(size_t length) -- libgit2 0.21.4