Commit 7edc3b8363283ca77d3e879388ff18ef9bf43cc7
1 parent
0d676dc9
CONNECT with protocol 3.1, mostly
Showing
3 changed files
with
46 additions
and
37 deletions
client.cpp
| @@ -102,11 +102,12 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn) | @@ -102,11 +102,12 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn) | ||
| 102 | // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space. | 102 | // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space. |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | -void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen) | 105 | +void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen, uint16_t keepalive) |
| 106 | { | 106 | { |
| 107 | this->clientid = clientId; | 107 | this->clientid = clientId; |
| 108 | this->username = username; | 108 | this->username = username; |
| 109 | this->connectPacketSeen = connectPacketSeen; | 109 | this->connectPacketSeen = connectPacketSeen; |
| 110 | + this->keepalive = keepalive; | ||
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | 113 |
client.h
| @@ -30,6 +30,7 @@ class Client | @@ -30,6 +30,7 @@ class Client | ||
| 30 | bool connectPacketSeen = false; | 30 | bool connectPacketSeen = false; |
| 31 | std::string clientid; | 31 | std::string clientid; |
| 32 | std::string username; | 32 | std::string username; |
| 33 | + uint16_t keepalive = 0; | ||
| 33 | 34 | ||
| 34 | ThreadData_p threadData; | 35 | ThreadData_p threadData; |
| 35 | 36 | ||
| @@ -58,7 +59,7 @@ public: | @@ -58,7 +59,7 @@ public: | ||
| 58 | int getFd() { return fd;} | 59 | int getFd() { return fd;} |
| 59 | bool readFdIntoBuffer(); | 60 | bool readFdIntoBuffer(); |
| 60 | bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn); | 61 | bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn); |
| 61 | - void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen); | 62 | + void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen, uint16_t keepalive); |
| 62 | void setAuthenticated(bool value) { authenticated = value;} | 63 | void setAuthenticated(bool value) { authenticated = value;} |
| 63 | bool getAuthenticated() { return authenticated; } | 64 | bool getAuthenticated() { return authenticated; } |
| 64 | bool hasConnectPacketSeen() { return connectPacketSeen; } | 65 | bool hasConnectPacketSeen() { return connectPacketSeen; } |
mqttpacket.cpp
| @@ -27,7 +27,7 @@ void MqttPacket::handleConnect() | @@ -27,7 +27,7 @@ void MqttPacket::handleConnect() | ||
| 27 | // TODO: Do all packets have a variable header? | 27 | // TODO: Do all packets have a variable header? |
| 28 | variable_header_length = readTwoBytesToUInt16(); | 28 | variable_header_length = readTwoBytesToUInt16(); |
| 29 | 29 | ||
| 30 | - if (variable_header_length == 4) | 30 | + if (variable_header_length == 4 || variable_header_length == 6) |
| 31 | { | 31 | { |
| 32 | char *c = readBytes(variable_header_length); | 32 | char *c = readBytes(variable_header_length); |
| 33 | std::string magic_marker(c, variable_header_length); | 33 | std::string magic_marker(c, variable_header_length); |
| @@ -37,54 +37,61 @@ void MqttPacket::handleConnect() | @@ -37,54 +37,61 @@ void MqttPacket::handleConnect() | ||
| 37 | if (magic_marker == "MQTT" && protocol_level == 0x04) | 37 | if (magic_marker == "MQTT" && protocol_level == 0x04) |
| 38 | { | 38 | { |
| 39 | protocolVersion = ProtocolVersion::Mqtt311; | 39 | protocolVersion = ProtocolVersion::Mqtt311; |
| 40 | + } | ||
| 41 | + else if (magic_marker == "MQIsdp" && protocol_level == 0x03) | ||
| 42 | + { | ||
| 43 | + protocolVersion = ProtocolVersion::Mqtt31; | ||
| 44 | + } | ||
| 45 | + else | ||
| 46 | + { | ||
| 47 | + throw ProtocolError("Only MQTT 3.1 and 3.1.1 supported."); | ||
| 48 | + } | ||
| 40 | 49 | ||
| 41 | - char flagByte = readByte(); | ||
| 42 | - bool reserved = !!(flagByte & 0b00000001); | 50 | + char flagByte = readByte(); |
| 51 | + bool reserved = !!(flagByte & 0b00000001); | ||
| 43 | 52 | ||
| 44 | - if (reserved) | ||
| 45 | - throw ProtocolError("Protocol demands reserved flag in CONNECT is 0"); | 53 | + if (reserved) |
| 54 | + throw ProtocolError("Protocol demands reserved flag in CONNECT is 0"); | ||
| 46 | 55 | ||
| 47 | 56 | ||
| 48 | - bool user_name_flag = !!(flagByte & 0b10000000); | ||
| 49 | - bool password_flag = !!(flagByte & 0b01000000); | ||
| 50 | - bool will_retain = !!(flagByte & 0b00100000); | ||
| 51 | - char will_qos = (flagByte & 0b00011000) >> 3; | ||
| 52 | - bool will_flag = !!(flagByte & 0b00000100); | ||
| 53 | - bool clean_session = !!(flagByte & 0b00000010); | 57 | + bool user_name_flag = !!(flagByte & 0b10000000); |
| 58 | + bool password_flag = !!(flagByte & 0b01000000); | ||
| 59 | + bool will_retain = !!(flagByte & 0b00100000); | ||
| 60 | + char will_qos = (flagByte & 0b00011000) >> 3; | ||
| 61 | + bool will_flag = !!(flagByte & 0b00000100); | ||
| 62 | + bool clean_session = !!(flagByte & 0b00000010); | ||
| 54 | 63 | ||
| 55 | - uint16_t keep_alive = readTwoBytesToUInt16(); | 64 | + uint16_t keep_alive = readTwoBytesToUInt16(); |
| 56 | 65 | ||
| 57 | - uint16_t client_id_length = readTwoBytesToUInt16(); | ||
| 58 | - std::string client_id(readBytes(client_id_length), client_id_length); | 66 | + uint16_t client_id_length = readTwoBytesToUInt16(); |
| 67 | + std::string client_id(readBytes(client_id_length), client_id_length); | ||
| 59 | 68 | ||
| 60 | - std::string username; | ||
| 61 | - std::string password; | 69 | + std::string username; |
| 70 | + std::string password; | ||
| 62 | 71 | ||
| 63 | - if (will_flag) | ||
| 64 | - { | 72 | + if (will_flag) |
| 73 | + { | ||
| 65 | 74 | ||
| 66 | - } | ||
| 67 | - if (user_name_flag) | ||
| 68 | - { | ||
| 69 | - uint16_t user_name_length = readTwoBytesToUInt16(); | ||
| 70 | - username = std::string(readBytes(user_name_length), user_name_length); | ||
| 71 | - } | ||
| 72 | - if (password_flag) | ||
| 73 | - { | ||
| 74 | - uint16_t password_length = readTwoBytesToUInt16(); | ||
| 75 | - password = std::string(readBytes(password_length), password_length); | ||
| 76 | - } | 75 | + } |
| 76 | + if (user_name_flag) | ||
| 77 | + { | ||
| 78 | + uint16_t user_name_length = readTwoBytesToUInt16(); | ||
| 79 | + username = std::string(readBytes(user_name_length), user_name_length); | ||
| 80 | + } | ||
| 81 | + if (password_flag) | ||
| 82 | + { | ||
| 83 | + uint16_t password_length = readTwoBytesToUInt16(); | ||
| 84 | + password = std::string(readBytes(password_length), password_length); | ||
| 85 | + } | ||
| 77 | 86 | ||
| 78 | - sender->setClientProperties(clientid, username, true); | 87 | + // TODO: validate UTF8 encoded username/password. |
| 79 | 88 | ||
| 80 | - } | 89 | + sender->setClientProperties(clientid, username, true, keep_alive); |
| 81 | } | 90 | } |
| 82 | - else if (variable_header_length == 6) | 91 | + else |
| 83 | { | 92 | { |
| 84 | - throw ProtocolError("Only MQTT 3.1.1 implemented."); | 93 | + throw ProtocolError("Invalid variable header length. Garbage?"); |
| 85 | } | 94 | } |
| 86 | - | ||
| 87 | - throw ProtocolError("Unprogrammed sequence in CONNECT."); | ||
| 88 | } | 95 | } |
| 89 | 96 | ||
| 90 | char *MqttPacket::readBytes(size_t length) | 97 | char *MqttPacket::readBytes(size_t length) |