diff --git a/mqtt5properties.cpp b/mqtt5properties.cpp index 2a543de..ae85321 100644 --- a/mqtt5properties.cpp +++ b/mqtt5properties.cpp @@ -1,6 +1,7 @@ #include "mqtt5properties.h" #include "cstring" +#include "vector" #include "exceptions.h" @@ -102,6 +103,11 @@ void Mqtt5PropertyBuilder::writeResponseTopic(const std::string &str) writeStr(Mqtt5Properties::ResponseTopic, str); } +void Mqtt5PropertyBuilder::writeUserProperty(const std::string &key, const std::string &value) +{ + write2Str(Mqtt5Properties::UserProperty, key, value); +} + void Mqtt5PropertyBuilder::writeUint32(Mqtt5Properties prop, const uint32_t x, std::vector &target) { size_t pos = target.size(); @@ -165,3 +171,33 @@ void Mqtt5PropertyBuilder::writeStr(Mqtt5Properties prop, const std::string &str std::memcpy(&genericBytes[pos], str.c_str(), strlen); } +void Mqtt5PropertyBuilder::write2Str(Mqtt5Properties prop, const std::string &one, const std::string &two) +{ + size_t pos = genericBytes.size(); + const size_t newSize = pos + one.length() + two.length() + 5; + genericBytes.resize(newSize); + + genericBytes[pos++] = static_cast(prop); + + std::vector strings; + strings.push_back(&one); + strings.push_back(&two); + + for (const std::string *str : strings) + { + if (str->length() > 0xFFFF) + throw ProtocolError("String too long."); + + const uint16_t strlen = str->length(); + + const uint8_t a = static_cast(strlen >> 8); + const uint8_t b = static_cast(strlen); + + genericBytes[pos++] = a; + genericBytes[pos++] = b; + + std::memcpy(&genericBytes[pos], str->c_str(), strlen); + pos += strlen; + } +} + diff --git a/mqtt5properties.h b/mqtt5properties.h index 30d2042..4b0d6ce 100644 --- a/mqtt5properties.h +++ b/mqtt5properties.h @@ -16,6 +16,7 @@ class Mqtt5PropertyBuilder void writeUint16(Mqtt5Properties prop, const uint16_t x); void writeUint8(Mqtt5Properties prop, const uint8_t x); void writeStr(Mqtt5Properties prop, const std::string &str); + void write2Str(Mqtt5Properties prop, const std::string &one, const std::string &two); public: Mqtt5PropertyBuilder(); @@ -38,6 +39,7 @@ public: void writePayloadFormatIndicator(uint8_t val); void writeMessageExpiryInterval(uint32_t val); void writeResponseTopic(const std::string &str); + void writeUserProperty(const std::string &key, const std::string &value); }; #endif // MQTT5PROPERTIES_H diff --git a/mqttpacket.cpp b/mqttpacket.cpp index c11cb99..9773be5 100644 --- a/mqttpacket.cpp +++ b/mqttpacket.cpp @@ -815,7 +815,14 @@ void MqttPacket::handlePublish() case Mqtt5Properties::CorrelationData: break; case Mqtt5Properties::UserProperty: + { + const uint16_t lenKey = readTwoBytesToUInt16(); + const std::string userPropKey(readBytes(lenKey), lenKey); + const uint16_t lenVal = readTwoBytesToUInt16(); + const std::string userPropVal(readBytes(lenVal), lenVal); + publishData.propertyBuilder->writeUserProperty(userPropKey, userPropVal); break; + } case Mqtt5Properties::SubscriptionIdentifier: break; case Mqtt5Properties::ContentType: