From 8ed9b9c41655bf159c431298f9b5dd6de6d64870 Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Sat, 16 Sep 2017 13:13:02 +0100 Subject: [PATCH 1/2] Support MQTT retain flag on publishing. This resolves issue #20 by allowing the user to specify the retain flag on the publisher object. This flag is useful for slow publishers so that a new subscription will immediately receive the last published message. --- Adafruit_MQTT.cpp | 25 +++++++++++++------------ Adafruit_MQTT.h | 9 +++++---- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 40f4610..5edf548 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -293,13 +293,13 @@ bool Adafruit_MQTT::disconnect() { } -bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) { - return publish(topic, (uint8_t*)(data), strlen(data), qos); +bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos, bool retain) { + return publish(topic, (uint8_t*)(data), strlen(data), qos, retain); } -bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) { +bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos, bool retain) { // Construct and send publish packet. - uint16_t len = publishPacket(buffer, topic, data, bLen, qos); + uint16_t len = publishPacket(buffer, topic, data, bLen, qos, retain); if (!sendPacket(buffer, len)) return false; @@ -634,7 +634,7 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { // as per http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040 uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, - uint8_t *data, uint16_t bLen, uint8_t qos) { + uint8_t *data, uint16_t bLen, uint8_t qos, bool retain) { uint8_t *p = packet; uint16_t len=0; @@ -647,7 +647,7 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, len += bLen; // payload length // Now you can start generating the packet! - p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1; + p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1 | (retain ? 1 : 0); p++; // fill in packet[1] last @@ -770,37 +770,38 @@ uint8_t Adafruit_MQTT::disconnectPacket(uint8_t *packet) { // Adafruit_MQTT_Publish Definition //////////////////////////////////////////// Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, - const char *feed, uint8_t q) { + const char *feed, uint8_t q, bool retainFlag) { mqtt = mqttserver; topic = feed; qos = q; + retain = retainFlag; } bool Adafruit_MQTT_Publish::publish(int32_t i) { char payload[12]; ltoa(i, payload, 10); - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, qos, retain); } bool Adafruit_MQTT_Publish::publish(uint32_t i) { char payload[11]; ultoa(i, payload, 10); - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, qos, retain); } bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision) { char payload[41]; // Need to technically hold float max, 39 digits and minus sign. dtostrf(f, 0, precision, payload); - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, qos, retain); } bool Adafruit_MQTT_Publish::publish(const char *payload) { - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, qos, retain); } //publish buffer of arbitrary length bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen) { - return mqtt->publish(topic, payload, bLen, qos); + return mqtt->publish(topic, payload, bLen, qos, retain); } diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 2d7066b..3d82d79 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -178,8 +178,8 @@ class Adafruit_MQTT { // Publish a message to a topic using the specified QoS level. Returns true // if the message was published, false otherwise. - bool publish(const char *topic, const char *payload, uint8_t qos = 0); - bool publish(const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos = 0); + bool publish(const char *topic, const char *payload, uint8_t qos = 0, bool retain = false); + bool publish(const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos = 0, bool retain = false); // Add a subscription to receive messages for a topic. Returns true if the // subscription could be added or was already present, false otherwise. @@ -244,7 +244,7 @@ class Adafruit_MQTT { // Functions to generate MQTT packets. uint8_t connectPacket(uint8_t *packet); uint8_t disconnectPacket(uint8_t *packet); - uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos); + uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos, uint8_t retain); uint8_t subscribePacket(uint8_t *packet, const char *topic, uint8_t qos); uint8_t unsubscribePacket(uint8_t *packet, const char *topic); uint8_t pingPacket(uint8_t *packet); @@ -254,7 +254,7 @@ class Adafruit_MQTT { class Adafruit_MQTT_Publish { public: - Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, const char *feed, uint8_t qos = 0); + Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, const char *feed, uint8_t qos = 0, bool retain = false); bool publish(const char *s); bool publish(double f, uint8_t precision=2); // Precision controls the minimum number of digits after decimal. @@ -268,6 +268,7 @@ class Adafruit_MQTT_Publish { Adafruit_MQTT *mqtt; const char *topic; uint8_t qos; + bool retain; }; class Adafruit_MQTT_Subscribe { From 43f78c7fbb7174d5964efc046a6acbdb8e1f36a0 Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Thu, 28 Sep 2017 12:25:31 +0100 Subject: [PATCH 2/2] Amended the publishPacket prototype to match the implementation. In changing to a bool parameter this was missed off the last commit. --- Adafruit_MQTT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 3d82d79..c146478 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -244,7 +244,7 @@ class Adafruit_MQTT { // Functions to generate MQTT packets. uint8_t connectPacket(uint8_t *packet); uint8_t disconnectPacket(uint8_t *packet); - uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos, uint8_t retain); + uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos, bool retain); uint8_t subscribePacket(uint8_t *packet, const char *topic, uint8_t qos); uint8_t unsubscribePacket(uint8_t *packet, const char *topic); uint8_t pingPacket(uint8_t *packet);