From d6f07ed4e4b768a62ee5510aa19b595b1b8dc42f Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Sat, 29 Aug 2020 15:56:43 -0400 Subject: [PATCH 01/42] Adafruit_MQTT::publishPacket: Protect against memory corruption. Avoid memory corruption from happening when data payload provided in Adafruit_MQTT::publishPacket is greater than MAXBUFFERSIZE. In order to do that, a helper function is being added to calculate how much space is available for the payload after subtracting what is used as the header. Pull request https://github.com/adafruit/Adafruit_MQTT_Library/pull/166 Fixes https://github.com/adafruit/Adafruit_MQTT_Library/issues/109 Fixes https://github.com/adafruit/Adafruit_MQTT_Library/issues/122 Signed-off-by: Flavio Fernandes --- Adafruit_MQTT.cpp | 39 +++++++++++++++++++++++++++++++++++---- Adafruit_MQTT.h | 2 +- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 7d5141b..fc6c416 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -323,7 +323,8 @@ bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) { bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) { // Construct and send publish packet. - uint16_t len = publishPacket(buffer, topic, data, bLen, qos); + uint16_t len = + publishPacket(buffer, topic, data, bLen, qos, (uint16_t)sizeof(buffer)); if (!sendPacket(buffer, len)) return false; @@ -668,11 +669,26 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { return len; } +// packetAdditionalLen is a helper function used to figure out +// how bigger the payload needs to be in order to account for +// its variable length field. As per +// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size +static uint16_t packetAdditionalLen(uint16_t currLen) { + /* Increase length field based on current length */ + if (currLen < 128) + return 0; + if (currLen < 16384) + return 1; + if (currLen < 2097151) + return 2; + return 3; +} + // 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, + uint16_t maxPacketLen) { uint8_t *p = packet; uint16_t len = 0; @@ -682,7 +698,22 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, if (qos > 0) { len += 2; // qos packet id } - len += bLen; // payload length + // Calculate additional bytes for length field (if any) + uint16_t additionalLen = packetAdditionalLen(len + bLen); + + // Payload length. When maxPacketLen provided is 0, let's + // assume buffer is big enough. Fingers crossed. + if (maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen)) { + len += bLen + additionalLen; + } else { + // If we make it here, we got a pickle: the payload is not going + // to fit in the packet buffer. Instead of corrupting memory, let's + // do something less damaging by reducing the bLen to what we are + // able to accomodate. Alternatively, consider using a bigger + // maxPacketLen. + bLen = maxPacketLen - (len + 2 + packetAdditionalLen(maxPacketLen)); + len = maxPacketLen - 4; + } // Now you can start generating the packet! p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1; diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 089d0d4..495e043 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -262,7 +262,7 @@ private: 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 bLen, uint8_t qos, uint16_t maxPacketLen = 0); 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); From 813585f72b3701af19380b7a683830e095eddc88 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 12 May 2021 17:26:26 -0400 Subject: [PATCH 02/42] add example for esp32s2/esp32 --- .../adafruitio_secure_esp32.ino | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 examples/adafruitio_secure_esp32/adafruitio_secure_esp32.ino diff --git a/examples/adafruitio_secure_esp32/adafruitio_secure_esp32.ino b/examples/adafruitio_secure_esp32/adafruitio_secure_esp32.ino new file mode 100644 index 0000000..f573ede --- /dev/null +++ b/examples/adafruitio_secure_esp32/adafruitio_secure_esp32.ino @@ -0,0 +1,160 @@ +/*********************************************************************** + Adafruit MQTT Library ESP32 Adafruit IO SSL/TLS example + + Use the latest version of the ESP32 Arduino Core: + https://github.com/espressif/arduino-esp32 + + Works great with Adafruit Huzzah32 Feather and Breakout Board: + https://www.adafruit.com/product/3405 + https://www.adafruit.com/products/4172 + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Tony DiCola for Adafruit Industries. + Modified by Brent Rubell for Adafruit Industries + MIT license, all text above must be included in any redistribution + **********************************************************************/ +#include +#include "WiFiClientSecure.h" +#include "Adafruit_MQTT.h" +#include "Adafruit_MQTT_Client.h" + +/************************* WiFi Access Point *********************************/ + +#define WLAN_SSID "WLAN_SSID" +#define WLAN_PASS "WIFI_PASSWORD" + +/************************* Adafruit.io Setup *********************************/ + +#define AIO_SERVER "io.adafruit.com" + +// Using port 8883 for MQTTS +#define AIO_SERVERPORT 8883 + +// Adafruit IO Account Configuration +// (to obtain these values, visit https://io.adafruit.com and click on Active Key) +#define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME" +#define AIO_KEY "YOUR_ADAFRUIT_IO_KEY" + +/************ Global State (you don't need to change this!) ******************/ + +// WiFiFlientSecure for SSL/TLS support +WiFiClientSecure client; + +// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. +Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); + +// io.adafruit.com root CA +const char* adafruitio_root_ca = \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" \ + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \ + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \ + "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" \ + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" \ + "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" \ + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" \ + "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" \ + "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" \ + "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" \ + "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" \ + "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" \ + "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" \ + "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" \ + "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" \ + "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" \ + "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" \ + "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" \ + "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" \ + "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" \ + "-----END CERTIFICATE-----\n"; + +/****************************** Feeds ***************************************/ + +// Setup a feed called 'test' for publishing. +// Notice MQTT paths for AIO follow the form: /feeds/ +Adafruit_MQTT_Publish test = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/test"); + +/*************************** Sketch Code ************************************/ + +void setup() { + Serial.begin(115200); + delay(10); + + Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example")); + + // Connect to WiFi access point. + Serial.println(); Serial.println(); + Serial.print("Connecting to "); + Serial.println(WLAN_SSID); + + delay(1000); + + WiFi.begin(WLAN_SSID, WLAN_PASS); + delay(2000); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); Serial.println(WiFi.localIP()); + + // Set Adafruit IO's root CA + client.setCACert(adafruitio_root_ca); +} + +uint32_t x=0; + +void loop() { + // Ensure the connection to the MQTT server is alive (this will make the first + // connection and automatically reconnect when disconnected). See the MQTT_connect + // function definition further below. + MQTT_connect(); + + // Now we can publish stuff! + Serial.print(F("\nSending val ")); + Serial.print(x); + Serial.print(F(" to test feed...")); + if (! test.publish(x++)) { + Serial.println(F("Failed")); + } else { + Serial.println(F("OK!")); + } + + // wait a couple seconds to avoid rate limit + delay(2000); + +} + +// Function to connect and reconnect as necessary to the MQTT server. +// Should be called in the loop function and it will take care if connecting. +void MQTT_connect() { + int8_t ret; + + // Stop if already connected. + if (mqtt.connected()) { + return; + } + + Serial.print("Connecting to MQTT... "); + + uint8_t retries = 3; + while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected + Serial.println(mqtt.connectErrorString(ret)); + Serial.println("Retrying MQTT connection in 5 seconds..."); + mqtt.disconnect(); + delay(5000); // wait 5 seconds + retries--; + if (retries == 0) { + // basically die and wait for WDT to reset me + while (1); + } + } + + Serial.println("MQTT Connected!"); +} \ No newline at end of file From 2adac525e13b0d639a2f53a223ccd2c573558c44 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 12 May 2021 17:30:17 -0400 Subject: [PATCH 03/42] bump version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 957bb7e..3b57b38 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.1.0 +version=2.1.1 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware. From 1a3ff727a32877eb06346b0fd99d424adfd1ed38 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 12 May 2021 17:33:16 -0400 Subject: [PATCH 04/42] add .skip files for 8266/zero, this is an esp32 example! --- examples/adafruitio_secure_esp32/.esp8266.test.skip | 1 + examples/adafruitio_secure_esp32/.zero.test.skip | 1 + 2 files changed, 2 insertions(+) create mode 100644 examples/adafruitio_secure_esp32/.esp8266.test.skip create mode 100644 examples/adafruitio_secure_esp32/.zero.test.skip diff --git a/examples/adafruitio_secure_esp32/.esp8266.test.skip b/examples/adafruitio_secure_esp32/.esp8266.test.skip new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/adafruitio_secure_esp32/.esp8266.test.skip @@ -0,0 +1 @@ + diff --git a/examples/adafruitio_secure_esp32/.zero.test.skip b/examples/adafruitio_secure_esp32/.zero.test.skip new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/adafruitio_secure_esp32/.zero.test.skip @@ -0,0 +1 @@ + From fff701ee62561fb47771bec961d9aed69aadbbf7 Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Fri, 2 Apr 2021 12:05:34 -0400 Subject: [PATCH 05/42] Bump to 2.2.0 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 957bb7e..230e502 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.1.0 +version=2.2.0 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware. From 2ea8a0b3fce916fa87b6a3730125153965c61f25 Mon Sep 17 00:00:00 2001 From: xdylanm Date: Wed, 12 May 2021 21:31:22 -0700 Subject: [PATCH 06/42] Support publishing and receiving large messages. Send multiple 250 byte packets (ref PR#113) for larger messages. Correctly identify topic start position for >127byte messages (ref PR#166). Resolves issue #102 --- Adafruit_MQTT.cpp | 32 +++++++++++++++++++++++++------- Adafruit_MQTT_Client.cpp | 7 ++++--- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 7d5141b..70a849d 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -233,7 +233,7 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, // will read a packet and Do The Right Thing with length uint8_t *pbuff = buffer; - uint8_t rlen; + uint16_t rlen; // read the packet type: rlen = readPacket(pbuff, 1, timeout); @@ -473,6 +473,22 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { return handleSubscriptionPacket(len); } +namespace { + +uint16_t topicOffsetFromLenth(uint16_t const len) +{ + if (len < 128) { // 7 bits (+1 continuation bit) + return 0; + } else if (len < 16384) { // 14 bits (+2 continuation bits) + return 1; + } else if (len < 2097152) { // 21 bits + return 2; + } + return 3; +} + +} // anon + Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { uint16_t i, topiclen, datalen; @@ -491,7 +507,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { } // Parse out length of packet. - topiclen = buffer[3]; + uint16_t const topicoffset = topicOffsetFromLength(len); + uint16_t const topicstart = topicoffset + 4; + topiclen = buffer[3+topicoffset]; DEBUG_PRINT(F("Looking for subscription len ")); DEBUG_PRINTLN(topiclen); @@ -504,7 +522,7 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { continue; // Stop if the subscription topic matches the received topic. Be careful // to make comparison case insensitive. - if (strncasecmp((char *)buffer + 4, subscriptions[i]->topic, topiclen) == + if (strncasecmp((char *)buffer + topicstart, subscriptions[i]->topic, topiclen) == 0) { DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i); @@ -520,20 +538,20 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { // Check if it is QoS 1, TODO: we dont support QoS 2 if ((buffer[0] & 0x6) == 0x2) { packet_id_len = 2; - packetid = buffer[topiclen + 4]; + packetid = buffer[topiclen + topicstart]; packetid <<= 8; - packetid |= buffer[topiclen + 5]; + packetid |= buffer[topiclen + topicstart + 1]; } // zero out the old data memset(subscriptions[i]->lastread, 0, SUBSCRIPTIONDATALEN); - datalen = len - topiclen - packet_id_len - 4; + datalen = len - topiclen - packet_id_len - topicstart; if (datalen > SUBSCRIPTIONDATALEN) { datalen = SUBSCRIPTIONDATALEN - 1; // cut it off } // extract out just the data, into the subscription object itself - memmove(subscriptions[i]->lastread, buffer + 4 + topiclen + packet_id_len, + memmove(subscriptions[i]->lastread, buffer + topicstart + topiclen + packet_id_len, datalen); subscriptions[i]->datalen = datalen; DEBUG_PRINT(F("Data len: ")); diff --git a/Adafruit_MQTT_Client.cpp b/Adafruit_MQTT_Client.cpp index 560ef46..2720ea9 100644 --- a/Adafruit_MQTT_Client.cpp +++ b/Adafruit_MQTT_Client.cpp @@ -83,18 +83,19 @@ uint16_t Adafruit_MQTT_Client::readPacket(uint8_t *buffer, uint16_t maxlen, bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint16_t len) { uint16_t ret = 0; - + uint16_t offset = 0; while (len > 0) { if (client->connected()) { // send 250 bytes at most at a time, can adjust this later based on Client uint16_t sendlen = len > 250 ? 250 : len; // Serial.print("Sending: "); Serial.println(sendlen); - ret = client->write(buffer, sendlen); + ret = client->write(buffer + offset, sendlen); DEBUG_PRINT(F("Client sendPacket returned: ")); DEBUG_PRINTLN(ret); len -= ret; - + offset += ret; + if (ret != sendlen) { DEBUG_PRINTLN("Failed to send packet."); return false; From 93a35d1a3e63b67a4fa5cbeaa4524312289c3581 Mon Sep 17 00:00:00 2001 From: xdylanm Date: Wed, 12 May 2021 21:54:08 -0700 Subject: [PATCH 07/42] fix typo --- Adafruit_MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 70a849d..84e4ad1 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -475,7 +475,7 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { namespace { -uint16_t topicOffsetFromLenth(uint16_t const len) +uint16_t topicOffsetFromLength(uint16_t const len) { if (len < 128) { // 7 bits (+1 continuation bit) return 0; From db003d30d1c167f8029e746069e801026d3ee1be Mon Sep 17 00:00:00 2001 From: xdylanm Date: Fri, 14 May 2021 08:09:07 -0700 Subject: [PATCH 08/42] Addressing comments from PR #193 with merge from PR#166. Clang-format, version ticked to 2.3.0, replaced duplicate topicOffsetFromLength with packetAdditionalLen. --- Adafruit_MQTT.cpp | 62 ++++++++++++++++------------------------ Adafruit_MQTT_Client.cpp | 2 +- library.properties | 2 +- 3 files changed, 26 insertions(+), 40 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 4c4dd96..a38ec80 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -96,6 +96,22 @@ static uint8_t *stringprint(uint8_t *p, const char *s, uint16_t maxlen = 0) { return p + len; } +// packetAdditionalLen is a helper function used to figure out +// how bigger the payload needs to be in order to account for +// its variable length field. As per +// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size +// See also readFullPacket +static uint16_t packetAdditionalLen(uint32_t currLen) { + /* Increase length field based on current length */ + if (currLen < 128) // 7-bits + return 0; + if (currLen < 16384) // 14-bits + return 1; + if (currLen < 2097152) // 21-bits + return 2; + return 3; +} + // Adafruit_MQTT Definition //////////////////////////////////////////////////// Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, const char *cid, @@ -267,7 +283,8 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, DEBUG_PRINT(F("Packet Length:\t")); DEBUG_PRINTLN(value); - if (value > (maxsize - (pbuff - buffer) - 1)) { + // maxsize is limited to 65536 by 16-bit unsigned + if (value > uint32_t(maxsize - (pbuff - buffer) - 1)) { DEBUG_PRINTLN(F("Packet too big for buffer")); rlen = readPacket(pbuff, (maxsize - (pbuff - buffer) - 1), timeout); } else { @@ -474,22 +491,6 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { return handleSubscriptionPacket(len); } -namespace { - -uint16_t topicOffsetFromLength(uint16_t const len) -{ - if (len < 128) { // 7 bits (+1 continuation bit) - return 0; - } else if (len < 16384) { // 14 bits (+2 continuation bits) - return 1; - } else if (len < 2097152) { // 21 bits - return 2; - } - return 3; -} - -} // anon - Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { uint16_t i, topiclen, datalen; @@ -508,9 +509,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { } // Parse out length of packet. - uint16_t const topicoffset = topicOffsetFromLength(len); + uint16_t const topicoffset = packetAdditionalLen(len); uint16_t const topicstart = topicoffset + 4; - topiclen = buffer[3+topicoffset]; + topiclen = buffer[3 + topicoffset]; DEBUG_PRINT(F("Looking for subscription len ")); DEBUG_PRINTLN(topiclen); @@ -523,8 +524,8 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { continue; // Stop if the subscription topic matches the received topic. Be careful // to make comparison case insensitive. - if (strncasecmp((char *)buffer + topicstart, subscriptions[i]->topic, topiclen) == - 0) { + if (strncasecmp((char *)buffer + topicstart, subscriptions[i]->topic, + topiclen) == 0) { DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i); break; @@ -552,8 +553,8 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { datalen = SUBSCRIPTIONDATALEN - 1; // cut it off } // extract out just the data, into the subscription object itself - memmove(subscriptions[i]->lastread, buffer + topicstart + topiclen + packet_id_len, - datalen); + memmove(subscriptions[i]->lastread, + buffer + topicstart + topiclen + packet_id_len, datalen); subscriptions[i]->datalen = datalen; DEBUG_PRINT(F("Data len: ")); DEBUG_PRINTLN(datalen); @@ -687,21 +688,6 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { return len; } -// packetAdditionalLen is a helper function used to figure out -// how bigger the payload needs to be in order to account for -// its variable length field. As per -// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size -static uint16_t packetAdditionalLen(uint16_t currLen) { - /* Increase length field based on current length */ - if (currLen < 128) - return 0; - if (currLen < 16384) - return 1; - if (currLen < 2097151) - return 2; - return 3; -} - // 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, diff --git a/Adafruit_MQTT_Client.cpp b/Adafruit_MQTT_Client.cpp index 2720ea9..9aa136c 100644 --- a/Adafruit_MQTT_Client.cpp +++ b/Adafruit_MQTT_Client.cpp @@ -95,7 +95,7 @@ bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint16_t len) { DEBUG_PRINTLN(ret); len -= ret; offset += ret; - + if (ret != sendlen) { DEBUG_PRINTLN("Failed to send packet."); return false; diff --git a/library.properties b/library.properties index 230e502..d544748 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.2.0 +version=2.3.0 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware. From a1e64c039eff1f0c14c6bda404efcf39bd133cd5 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 18 May 2021 16:41:26 -0400 Subject: [PATCH 09/42] settable keepalive interval --- Adafruit_MQTT.cpp | 27 +++++++++++++++++++++++++-- Adafruit_MQTT.h | 4 ++++ library.properties | 4 ++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index a38ec80..d9973cd 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -132,6 +132,8 @@ Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, const char *cid, will_qos = 0; will_retain = 0; + keepAliveInterval = MQTT_CONN_KEEPALIVE; + packet_id_counter = 0; } @@ -153,6 +155,8 @@ Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, will_qos = 0; will_retain = 0; + keepAliveInterval = MQTT_CONN_KEEPALIVE; + packet_id_counter = 0; } @@ -384,6 +388,25 @@ bool Adafruit_MQTT::will(const char *topic, const char *payload, uint8_t qos, return true; } +/**************************************************************************/ +/*! + @brief Sets the connect packet's KeepAlive Interval, in seconds. This + function MUST be called prior to connect(). + @param keepAlive + Maximum amount of time without communication between the + client and the MQTT broker, in seconds. + @returns True if called prior to connect(), False otherwise. +*/ +/**************************************************************************/ +bool Adafruit_MQTT::setKeepAliveInterval(uint16_t keepAlive) { + if (connected()) { + DEBUG_PRINT(F("keepAlive defined after connection established.")); + return false; + } + keepAliveInterval = keepAlive; + return true; +} + bool Adafruit_MQTT::subscribe(Adafruit_MQTT_Subscribe *sub) { uint8_t i; // see if we are already subscribed @@ -649,9 +672,9 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { p[0] |= MQTT_CONN_PASSWORDFLAG; p++; - p[0] = MQTT_CONN_KEEPALIVE >> 8; + p[0] = keepAliveInterval >> 8; p++; - p[0] = MQTT_CONN_KEEPALIVE & 0xFF; + p[0] = keepAliveInterval & 0xFF; p++; if (MQTT_PROTOCOL_LEVEL == 3) { diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 495e043..92e927f 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -184,6 +184,9 @@ public: bool will(const char *topic, const char *payload, uint8_t qos = 0, uint8_t retain = 0); + // Sets the KeepAlive Interval, in seconds. + bool setKeepAliveInterval(uint16_t keepAlive); + // 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); @@ -250,6 +253,7 @@ protected: const char *will_payload; uint8_t will_qos; uint8_t will_retain; + uint16_t keepAliveInterval; // MQTT KeepAlive time interval, in seconds uint8_t buffer[MAXBUFFERSIZE]; // one buffer, used for all incoming/outgoing uint16_t packet_id_counter; diff --git a/library.properties b/library.properties index d544748..0022c3b 100644 --- a/library.properties +++ b/library.properties @@ -1,8 +1,8 @@ name=Adafruit MQTT Library -version=2.3.0 +version=2.4.0 author=Adafruit maintainer=Adafruit -sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware. +sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. paragraph=Simple MQTT library that supports the bare minimum to publish and subscribe to topics. category=Communication url=https://github.com/adafruit/Adafruit_MQTT_Library From 86aff92f0ba45dbeb189bc214808277512224e1c Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 18 May 2021 16:43:33 -0400 Subject: [PATCH 10/42] fixup --- Adafruit_MQTT.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index d9973cd..bb7f8cf 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -388,7 +388,7 @@ bool Adafruit_MQTT::will(const char *topic, const char *payload, uint8_t qos, return true; } -/**************************************************************************/ +/***************************************************************************/ /*! @brief Sets the connect packet's KeepAlive Interval, in seconds. This function MUST be called prior to connect(). @@ -397,7 +397,7 @@ bool Adafruit_MQTT::will(const char *topic, const char *payload, uint8_t qos, client and the MQTT broker, in seconds. @returns True if called prior to connect(), False otherwise. */ -/**************************************************************************/ +/***************************************************************************/ bool Adafruit_MQTT::setKeepAliveInterval(uint16_t keepAlive) { if (connected()) { DEBUG_PRINT(F("keepAlive defined after connection established.")); From c5cdfc956422720db3dc9db1003387f41f276230 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 18 May 2021 16:54:01 -0400 Subject: [PATCH 11/42] clang format --- Adafruit_MQTT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 92e927f..1307753 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -253,7 +253,7 @@ protected: const char *will_payload; uint8_t will_qos; uint8_t will_retain; - uint16_t keepAliveInterval; // MQTT KeepAlive time interval, in seconds + uint16_t keepAliveInterval; // MQTT KeepAlive time interval, in seconds uint8_t buffer[MAXBUFFERSIZE]; // one buffer, used for all incoming/outgoing uint16_t packet_id_counter; From 4cb40f87d27a10e0f84aa7f911ac94deac58cf5e Mon Sep 17 00:00:00 2001 From: Ricardo Gorosito Date: Sun, 23 May 2021 15:52:35 -0300 Subject: [PATCH 12/42] stop loosing messages --- Adafruit_MQTT.cpp | 41 +++++++++++++++++++++++++++++++++++------ Adafruit_MQTT.h | 2 ++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index bb7f8cf..e35c0b8 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -351,13 +351,13 @@ bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, // If QOS level is high enough verify the response packet. if (qos > 0) { - len = readFullPacket(buffer, MAXBUFFERSIZE, PUBLISH_TIMEOUT_MS); + len = processPacketsUntil(buffer, MQTT_CTRL_PUBACK, PUBLISH_TIMEOUT_MS); + DEBUG_PRINT(F("Publish QOS1+ reply:\t")); DEBUG_PRINTBUFFER(buffer, len); if (len != 4) return false; - if ((buffer[0] >> 4) != MQTT_CTRL_PUBACK) - return false; + uint16_t packnum = buffer[2]; packnum <<= 8; packnum |= buffer[3]; @@ -508,10 +508,32 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { } } Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { - // Check if data is available to read. - uint16_t len = + + // Sync or Async subscriber with message + Adafruit_MQTT_Subscribe* s=0; + + // Check if are unread messages + for (uint8_t i = 0; i < MAXSUBSCRIPTIONS; i++) { + if (subscriptions[i] && subscriptions[i]->new_message) { + s=subscriptions[i]; + break; + } + } + + // not unread message + if ( ! s ) { + // Check if data is available to read. + uint16_t len = readFullPacket(buffer, MAXBUFFERSIZE, timeout); // return one full packet - return handleSubscriptionPacket(len); + s=handleSubscriptionPacket(len); + } + + // it there is a message, mark it as not pending + if ( s ) { + s->new_message=false; + } + + return s; } Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { @@ -551,6 +573,12 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { topiclen) == 0) { DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i); + if ( subscriptions[i]->new_message ) { + DEBUG_PRINTLN(F("Lost previous message")); + } else { + subscriptions[i]->new_message=true; + } + break; } } @@ -910,6 +938,7 @@ Adafruit_MQTT_Subscribe::Adafruit_MQTT_Subscribe(Adafruit_MQTT *mqttserver, callback_double = 0; callback_io = 0; io_mqtt = 0; + new_message = false; } void Adafruit_MQTT_Subscribe::setCallback(SubscribeCallbackUInt32Type cb) { diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 1307753..7249aa1 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -320,6 +320,8 @@ public: AdafruitIO_MQTT *io_mqtt; + bool new_message; + private: Adafruit_MQTT *mqtt; }; From 986c1b405cc76953b3ece64b3a5405955f07e696 Mon Sep 17 00:00:00 2001 From: Ricardo Gorosito Date: Tue, 25 May 2021 13:16:43 -0300 Subject: [PATCH 13/42] fix c formatting --- Adafruit_MQTT.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index e35c0b8..8ba4726 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -510,27 +510,27 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { // Sync or Async subscriber with message - Adafruit_MQTT_Subscribe* s=0; + Adafruit_MQTT_Subscribe *s=0; // Check if are unread messages for (uint8_t i = 0; i < MAXSUBSCRIPTIONS; i++) { if (subscriptions[i] && subscriptions[i]->new_message) { - s=subscriptions[i]; + s = subscriptions[i]; break; } } // not unread message - if ( ! s ) { + if (!s) { // Check if data is available to read. - uint16_t len = - readFullPacket(buffer, MAXBUFFERSIZE, timeout); // return one full packet - s=handleSubscriptionPacket(len); + uint16_t len = readFullPacket(buffer, MAXBUFFERSIZE, + timeout); // return one full packet + s = handleSubscriptionPacket(len); } // it there is a message, mark it as not pending - if ( s ) { - s->new_message=false; + if (s) { + s->new_message = false; } return s; @@ -573,12 +573,12 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) { topiclen) == 0) { DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i); - if ( subscriptions[i]->new_message ) { + if (subscriptions[i]->new_message) { DEBUG_PRINTLN(F("Lost previous message")); } else { - subscriptions[i]->new_message=true; + subscriptions[i]->new_message = true; } - + break; } } From ab78b291b2ac9c447ef70faac31f641d818379cf Mon Sep 17 00:00:00 2001 From: Ricardo Gorosito Date: Tue, 25 May 2021 13:23:51 -0300 Subject: [PATCH 14/42] more c formatting fixing --- Adafruit_MQTT.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 8ba4726..ddf2d82 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -510,7 +510,7 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { // Sync or Async subscriber with message - Adafruit_MQTT_Subscribe *s=0; + Adafruit_MQTT_Subscribe *s = 0; // Check if are unread messages for (uint8_t i = 0; i < MAXSUBSCRIPTIONS; i++) { @@ -524,7 +524,7 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { if (!s) { // Check if data is available to read. uint16_t len = readFullPacket(buffer, MAXBUFFERSIZE, - timeout); // return one full packet + timeout); // return one full packet s = handleSubscriptionPacket(len); } From b007806ac1c2c66b25f5877c357f4a4d011bb20f Mon Sep 17 00:00:00 2001 From: xdylanm Date: Sun, 30 May 2021 14:13:57 -0700 Subject: [PATCH 15/42] Fixed length calculation when payload exceeds 128bytes --- Adafruit_MQTT.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index bb7f8cf..7c593f1 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -728,19 +728,20 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, // Calculate additional bytes for length field (if any) uint16_t additionalLen = packetAdditionalLen(len + bLen); - // Payload length. When maxPacketLen provided is 0, let's + // Payload remaining length. When maxPacketLen provided is 0, let's // assume buffer is big enough. Fingers crossed. - if (maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen)) { - len += bLen + additionalLen; - } else { + // 2 + additionalLen: header byte + remaining length field (from 1 to 4 bytes) + // len = topic size field + value (string) + // bLen = buffer size + if (!(maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen))) { // If we make it here, we got a pickle: the payload is not going // to fit in the packet buffer. Instead of corrupting memory, let's // do something less damaging by reducing the bLen to what we are // able to accomodate. Alternatively, consider using a bigger // maxPacketLen. bLen = maxPacketLen - (len + 2 + packetAdditionalLen(maxPacketLen)); - len = maxPacketLen - 4; } + len += bLen; // remaining len excludes header byte & length field // Now you can start generating the packet! p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1; From a2bdbacb17f4445239e92873a6ebde54211aa76a Mon Sep 17 00:00:00 2001 From: xdylanm Date: Sun, 30 May 2021 16:16:14 -0700 Subject: [PATCH 16/42] format --- Adafruit_MQTT.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 7c593f1..d167c32 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -733,7 +733,8 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, // 2 + additionalLen: header byte + remaining length field (from 1 to 4 bytes) // len = topic size field + value (string) // bLen = buffer size - if (!(maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen))) { + if (!(maxPacketLen == 0 || + (len + bLen + 2 + additionalLen <= maxPacketLen))) { // If we make it here, we got a pickle: the payload is not going // to fit in the packet buffer. Instead of corrupting memory, let's // do something less damaging by reducing the bLen to what we are From d4667730760eaa0dffcfdb1b8432511d2aa1c8d6 Mon Sep 17 00:00:00 2001 From: Brent Rubell Date: Tue, 22 Jun 2021 13:29:31 -0400 Subject: [PATCH 17/42] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0022c3b..255b486 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.4.0 +version=2.4.1 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 223d419ebdff8f594da6132755628b12ecbbf7d7 Mon Sep 17 00:00:00 2001 From: Brent Rubell Date: Mon, 12 Jul 2021 09:53:23 -0400 Subject: [PATCH 18/42] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 255b486..962ac90 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.4.1 +version=2.4.2 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 25662868c52f695eb62591008b5100482e4ec54a Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 15 Aug 2022 13:18:56 -0400 Subject: [PATCH 19/42] add cert and warning --- .../adafruitio_secure_esp8266.ino | 7 ++++++- library.properties | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/adafruitio_secure_esp8266/adafruitio_secure_esp8266.ino b/examples/adafruitio_secure_esp8266/adafruitio_secure_esp8266.ino index bd069fe..87ad8ea 100644 --- a/examples/adafruitio_secure_esp8266/adafruitio_secure_esp8266.ino +++ b/examples/adafruitio_secure_esp8266/adafruitio_secure_esp8266.ino @@ -44,7 +44,12 @@ WiFiClientSecure client; Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); // io.adafruit.com SHA1 fingerprint -static const char *fingerprint PROGMEM = "59 3C 48 0A B1 8B 39 4E 0D 58 50 47 9A 13 55 60 CC A0 1D AF"; +/* WARNING - This value was last updated on 08/15/22 and may not be up-to-date! +* If security is a concern for your project, we strongly recommend users impacted by this moving +* to ESP32 which has certificate verification by storing root certs and having a +* chain-of-trust rather than doing individual certificate fingerprints. +*/ +static const char *fingerprint PROGMEM = "18 C0 C2 3D BE DD 81 37 73 40 E7 E4 36 61 CB 0A DF 96 AD 25"; /****************************** Feeds ***************************************/ diff --git a/library.properties b/library.properties index 962ac90..8baa280 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.4.2 +version=2.4.3 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 0ba089d1e818202539381d190802adb9d029b970 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 12:27:33 -0400 Subject: [PATCH 20/42] fixes processUntil --- Adafruit_MQTT.cpp | 32 +++++++++++++++++++++++++++++++- Adafruit_MQTT.h | 4 ++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 9d5128e..d4ddd49 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -226,6 +226,9 @@ uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, uint8_t waitforpackettype, uint16_t timeout) { uint16_t len; + DEBUG_PRINTLN("call: processPacketsUntil()"); + DEBUG_PRINT("Looking for packetType: "); + DEBUG_PRINTLN(waitforpackettype); while (true) { len = readFullPacket(buffer, MAXBUFFERSIZE, timeout); @@ -239,7 +242,31 @@ uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, return len; } else { if (packetType == MQTT_CTRL_PUBLISH) { - handleSubscriptionPacket(len); + + Adafruit_MQTT_Subscribe *sub = handleSubscriptionPacket(len); + if (sub) { + DEBUG_PRINTLN("processPacketsUntil got subscription!"); + if (sub->callback_uint32t != NULL) { + // huh lets do the callback in integer mode + uint32_t data = 0; + data = atoi((char *)sub->lastread); + sub->callback_uint32t(data); + } else if (sub->callback_double != NULL) { + // huh lets do the callback in doublefloat mode + double data = 0; + data = atof((char *)sub->lastread); + sub->callback_double(data); + } else if (sub->callback_buffer != NULL) { + // huh lets do the callback in buffer mode + DEBUG_PRINTLN("processPacketsUntil called the callback_buffer!"); + sub->callback_buffer((char *)sub->lastread, sub->datalen); + } else if (sub->callback_io != NULL) { + // huh lets do the callback in io mode + ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, + sub->datalen); + } + } + } else { ERROR_PRINTLN(F("Dropped a packet")); } @@ -477,8 +504,10 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { uint32_t elapsed = 0, endtime, starttime = millis(); while (elapsed < (uint32_t)timeout) { + DEBUG_PRINTLN("L480: readSubscription() called by processPackets()"); Adafruit_MQTT_Subscribe *sub = readSubscription(timeout - elapsed); if (sub) { + DEBUG_PRINTLN("processPackets got subscription!"); if (sub->callback_uint32t != NULL) { // huh lets do the callback in integer mode uint32_t data = 0; @@ -491,6 +520,7 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { sub->callback_double(data); } else if (sub->callback_buffer != NULL) { // huh lets do the callback in buffer mode + DEBUG_PRINTLN("processPackets callback_buffer!"); sub->callback_buffer((char *)sub->lastread, sub->datalen); } else if (sub->callback_io != NULL) { // huh lets do the callback in io mode diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 7249aa1..c7ec436 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -34,7 +34,7 @@ #define ADAFRUIT_MQTT_VERSION_PATCH 0 // Uncomment/comment to turn on/off debug output messages. -//#define MQTT_DEBUG +#define MQTT_DEBUG // Uncomment/comment to turn on/off error output messages. #define MQTT_ERROR @@ -107,7 +107,7 @@ // Largest full packet we're able to send. // Need to be able to store at least ~90 chars for a connect packet with full // 23 char client ID. -#define MAXBUFFERSIZE (150) +#define MAXBUFFERSIZE (512) #define MQTT_CONN_USERNAMEFLAG 0x80 #define MQTT_CONN_PASSWORDFLAG 0x40 From 5c00e84d085ae38574362a93fed9d5332dd71559 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 13:01:06 -0400 Subject: [PATCH 21/42] add new processSubscriptionPacket func --- Adafruit_MQTT.cpp | 74 +++++++++++++++++------------------------------ Adafruit_MQTT.h | 6 ++-- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index d4ddd49..e4bd2cc 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -222,6 +222,29 @@ int8_t Adafruit_MQTT::connect(const char *user, const char *pass) { return connect(); } +void Adafruit_MQTT::processSubscriptionPacket(Adafruit_MQTT_Subscribe *sub) { + if (sub->callback_uint32t != NULL) { + // execute callback in integer mode + uint32_t data = 0; + data = atoi((char *)sub->lastread); + sub->callback_uint32t(data); + } else if (sub->callback_double != NULL) { + // execute callback in doublefloat mode + double data = 0; + data = atof((char *)sub->lastread); + sub->callback_double(data); + } else if (sub->callback_buffer != NULL) { + // execute callback in buffer mode + DEBUG_PRINTLN("processPacketsUntil called the callback_buffer!"); + sub->callback_buffer((char *)sub->lastread, sub->datalen); + } else if (sub->callback_io != NULL) { + // execute callback in io mode + ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, sub->datalen); + } + // mark subscription message as "read"" + sub->new_message = false; +} + uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, uint8_t waitforpackettype, uint16_t timeout) { @@ -242,31 +265,9 @@ uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, return len; } else { if (packetType == MQTT_CTRL_PUBLISH) { - Adafruit_MQTT_Subscribe *sub = handleSubscriptionPacket(len); - if (sub) { - DEBUG_PRINTLN("processPacketsUntil got subscription!"); - if (sub->callback_uint32t != NULL) { - // huh lets do the callback in integer mode - uint32_t data = 0; - data = atoi((char *)sub->lastread); - sub->callback_uint32t(data); - } else if (sub->callback_double != NULL) { - // huh lets do the callback in doublefloat mode - double data = 0; - data = atof((char *)sub->lastread); - sub->callback_double(data); - } else if (sub->callback_buffer != NULL) { - // huh lets do the callback in buffer mode - DEBUG_PRINTLN("processPacketsUntil called the callback_buffer!"); - sub->callback_buffer((char *)sub->lastread, sub->datalen); - } else if (sub->callback_io != NULL) { - // huh lets do the callback in io mode - ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, - sub->datalen); - } - } - + if (sub) + processSubscriptionPacket(sub); } else { ERROR_PRINTLN(F("Dropped a packet")); } @@ -506,29 +507,8 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { while (elapsed < (uint32_t)timeout) { DEBUG_PRINTLN("L480: readSubscription() called by processPackets()"); Adafruit_MQTT_Subscribe *sub = readSubscription(timeout - elapsed); - if (sub) { - DEBUG_PRINTLN("processPackets got subscription!"); - if (sub->callback_uint32t != NULL) { - // huh lets do the callback in integer mode - uint32_t data = 0; - data = atoi((char *)sub->lastread); - sub->callback_uint32t(data); - } else if (sub->callback_double != NULL) { - // huh lets do the callback in doublefloat mode - double data = 0; - data = atof((char *)sub->lastread); - sub->callback_double(data); - } else if (sub->callback_buffer != NULL) { - // huh lets do the callback in buffer mode - DEBUG_PRINTLN("processPackets callback_buffer!"); - sub->callback_buffer((char *)sub->lastread, sub->datalen); - } else if (sub->callback_io != NULL) { - // huh lets do the callback in io mode - ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, - sub->datalen); - } - } - + if (sub) + processSubscriptionPacket(sub); // keep track over elapsed time endtime = millis(); if (endtime < starttime) { diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index c7ec436..e2609b1 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -209,10 +209,12 @@ public: // messages! Adafruit_MQTT_Subscribe *readSubscription(int16_t timeout = 0); - // Handle any data coming in for subscriptions and fires them off to the - // appropriate callback + // Handle any data coming in for subscriptions Adafruit_MQTT_Subscribe *handleSubscriptionPacket(uint16_t len); + // Execute a subscription packet's associated callback and mark as "read" + void processSubscriptionPacket(Adafruit_MQTT_Subscribe *sub); + void processPackets(int16_t timeout); // Ping the server to ensure the connection is still alive. From 30d4af81799b4351c4fc4bf6a08b28ea03578283 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 14:53:32 -0400 Subject: [PATCH 22/42] remove debug --- Adafruit_MQTT.cpp | 5 ----- Adafruit_MQTT.h | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index e4bd2cc..1da9be2 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -235,7 +235,6 @@ void Adafruit_MQTT::processSubscriptionPacket(Adafruit_MQTT_Subscribe *sub) { sub->callback_double(data); } else if (sub->callback_buffer != NULL) { // execute callback in buffer mode - DEBUG_PRINTLN("processPacketsUntil called the callback_buffer!"); sub->callback_buffer((char *)sub->lastread, sub->datalen); } else if (sub->callback_io != NULL) { // execute callback in io mode @@ -249,9 +248,6 @@ uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, uint8_t waitforpackettype, uint16_t timeout) { uint16_t len; - DEBUG_PRINTLN("call: processPacketsUntil()"); - DEBUG_PRINT("Looking for packetType: "); - DEBUG_PRINTLN(waitforpackettype); while (true) { len = readFullPacket(buffer, MAXBUFFERSIZE, timeout); @@ -505,7 +501,6 @@ void Adafruit_MQTT::processPackets(int16_t timeout) { uint32_t elapsed = 0, endtime, starttime = millis(); while (elapsed < (uint32_t)timeout) { - DEBUG_PRINTLN("L480: readSubscription() called by processPackets()"); Adafruit_MQTT_Subscribe *sub = readSubscription(timeout - elapsed); if (sub) processSubscriptionPacket(sub); diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index e2609b1..00657b4 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -34,7 +34,7 @@ #define ADAFRUIT_MQTT_VERSION_PATCH 0 // Uncomment/comment to turn on/off debug output messages. -#define MQTT_DEBUG +// #define MQTT_DEBUG // Uncomment/comment to turn on/off error output messages. #define MQTT_ERROR @@ -107,7 +107,7 @@ // Largest full packet we're able to send. // Need to be able to store at least ~90 chars for a connect packet with full // 23 char client ID. -#define MAXBUFFERSIZE (512) +#define MAXBUFFERSIZE (150) #define MQTT_CONN_USERNAMEFLAG 0x80 #define MQTT_CONN_PASSWORDFLAG 0x40 From a80db209cd9f76172269a435a5cc6014850370aa Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 14:53:54 -0400 Subject: [PATCH 23/42] bump lib prop --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 8baa280..5231595 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.4.3 +version=2.4.4 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 52e04bebe98b2f03116d58b24d6fa5dde83aa537 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 16:32:51 -0400 Subject: [PATCH 24/42] loren review --- Adafruit_MQTT.cpp | 3 +++ library.properties | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 1da9be2..85f91d8 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -239,6 +239,9 @@ void Adafruit_MQTT::processSubscriptionPacket(Adafruit_MQTT_Subscribe *sub) { } else if (sub->callback_io != NULL) { // execute callback in io mode ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, sub->datalen); + } else { + DEBUG_PRINTLN("ERROR: Subscription packet did not have an associated callback"); + return; } // mark subscription message as "read"" sub->new_message = false; diff --git a/library.properties b/library.properties index 5231595..f2aca1f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.4.4 +version=2.5.0 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 1eb56066eff1f1e3e6f23ef17c5a36cad4b76146 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 28 Oct 2022 16:44:07 -0400 Subject: [PATCH 25/42] clang --- Adafruit_MQTT.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 85f91d8..eaaff81 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -240,7 +240,8 @@ void Adafruit_MQTT::processSubscriptionPacket(Adafruit_MQTT_Subscribe *sub) { // execute callback in io mode ((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, sub->datalen); } else { - DEBUG_PRINTLN("ERROR: Subscription packet did not have an associated callback"); + DEBUG_PRINTLN( + "ERROR: Subscription packet did not have an associated callback"); return; } // mark subscription message as "read"" From 2c667d9a3053c949effb669f9a503042c3259121 Mon Sep 17 00:00:00 2001 From: Lucas Jandrew Date: Wed, 26 Feb 2020 13:06:21 -0500 Subject: [PATCH 26/42] Use ternary operator to set retain bit rather than relying on compiler definition of 0/1 --- Adafruit_MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index eaaff81..752e252 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -782,7 +782,7 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, len += bLen; // remaining len excludes header byte & length field // 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 From de5059eb9234434bc25da4aa846b43563d61ecdf Mon Sep 17 00:00:00 2001 From: Lucas Jandrew Date: Wed, 26 Feb 2020 13:16:10 -0500 Subject: [PATCH 27/42] Make publishPacket retain flag default to false --- Adafruit_MQTT.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 00657b4..76c4eb0 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -268,7 +268,8 @@ private: 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 maxPacketLen = 0); + uint16_t bLen, uint8_t qos, uint16_t maxPacketLen = 0, + bool retain = false); 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); From d3fdbb2f7c4f3107faba56bbfa22030691c28855 Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 2 Nov 2022 11:17:06 +0000 Subject: [PATCH 28/42] Use function overloading instead of optional arguments --- Adafruit_MQTT.cpp | 57 ++++++++++++++++++++++++++++++++++++++--------- Adafruit_MQTT.h | 13 +++++++++-- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 752e252..e8336db 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -366,14 +366,24 @@ 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); + return publish(topic, (uint8_t*)(data), strlen(data), false, qos); } bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) { + return publish(topic, data, bLen, false, qos); +} + +bool Adafruit_MQTT::publish(const char *topic, const char *data, + bool retain, uint8_t qos) { + return publish(topic, (uint8_t*)(data), strlen(data), retain, qos); +} + +bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, + bool retain, uint8_t qos) { // Construct and send publish packet. - uint16_t len = - publishPacket(buffer, topic, data, bLen, qos, (uint16_t)sizeof(buffer)); + uint16_t len = publishPacket(buffer, topic, data, bLen, retain, qos, (uint16_t)sizeof(buffer)); + if (!sendPacket(buffer, len)) return false; @@ -753,6 +763,12 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos, uint16_t maxPacketLen) { + return publishPacket(packet, topic, data, bLen, false, qos, maxPacketLen); +} + +uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, + uint8_t *data, uint16_t bLen, bool retain, + uint8_t qos, uint16_t maxPacketLen) { uint8_t *p = packet; uint16_t len = 0; @@ -907,33 +923,54 @@ Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, topic = feed; qos = q; } + bool Adafruit_MQTT_Publish::publish(int32_t i) { + return publish(i, false); +} + +bool Adafruit_MQTT_Publish::publish(int32_t i, bool retain) { char payload[12]; ltoa(i, payload, 10); - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, retain, qos); } bool Adafruit_MQTT_Publish::publish(uint32_t i) { + return publish(i, false); +} + +bool Adafruit_MQTT_Publish::publish(uint32_t i, bool retain) { char payload[11]; ultoa(i, payload, 10); - return mqtt->publish(topic, payload, qos); + return mqtt->publish(topic, payload, retain, qos); } bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision) { - char payload[41]; // Need to technically hold float max, 39 digits and minus - // sign. + return publish(f, false, precision); +} + +bool Adafruit_MQTT_Publish::publish(double f, bool retain, 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, retain, qos); } bool Adafruit_MQTT_Publish::publish(const char *payload) { - return mqtt->publish(topic, payload, qos); + return publish(payload, false); +} + +bool Adafruit_MQTT_Publish::publish(const char *payload, bool retain) { + return mqtt->publish(topic, payload, retain, qos); } // publish buffer of arbitrary length bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen) { + return publish(payload, bLen, false); +} - return mqtt->publish(topic, payload, bLen, qos); +bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen, bool retain) { + + return mqtt->publish(topic, payload, bLen, retain, qos); } // Adafruit_MQTT_Subscribe Definition ////////////////////////////////////////// diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 76c4eb0..7ab48d7 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -192,6 +192,8 @@ public: 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, bool retain, uint8_t qos = 0); + bool publish(const char *topic, uint8_t *payload, uint16_t bLen, bool retain, uint8_t qos = 0); // Add a subscription to receive messages for a topic. Returns true if the // subscription could be added or was already present, false otherwise. @@ -268,8 +270,10 @@ private: 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 maxPacketLen = 0, - bool retain = false); + uint16_t bLen, uint8_t qos, uint16_t maxPacketLen = 0); + uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, + uint16_t bLen, bool retain, uint8_t qos, uint16_t maxPacketLen = 0); + 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); @@ -282,14 +286,19 @@ public: uint8_t qos = 0); bool publish(const char *s); + bool publish(const char *s, bool retain); bool publish( double f, uint8_t precision = 2); // Precision controls the minimum number of digits after decimal. // This might be ignored and a higher precision value sent. + bool publish(double f, bool retain, uint8_t precision = 2); bool publish(int32_t i); + bool publish(int32_t i, bool retain); bool publish(uint32_t i); + bool publish(uint32_t i, bool retain); bool publish(uint8_t *b, uint16_t bLen); + bool publish(uint8_t *b, uint16_t bLen, bool retain); private: Adafruit_MQTT *mqtt; From e6ab3a9631623d9e2f14092339fc3225be71b706 Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 2 Nov 2022 11:37:01 +0000 Subject: [PATCH 29/42] Tidy code --- Adafruit_MQTT.cpp | 13 +++++++------ Adafruit_MQTT.h | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index e8336db..e21653c 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -369,20 +369,21 @@ bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) { return publish(topic, (uint8_t*)(data), strlen(data), false, qos); } -bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, - uint8_t qos) { - return publish(topic, data, bLen, false, qos); -} - bool Adafruit_MQTT::publish(const char *topic, const char *data, bool retain, uint8_t qos) { return publish(topic, (uint8_t*)(data), strlen(data), retain, qos); } +bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, + uint8_t qos) { + return publish(topic, data, bLen, false, qos); +} + bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, bool retain, uint8_t qos) { // Construct and send publish packet. - uint16_t len = publishPacket(buffer, topic, data, bLen, retain, qos, (uint16_t)sizeof(buffer)); + uint16_t len = publishPacket(buffer, topic, data, bLen, retain, qos, + (uint16_t)sizeof(buffer)); if (!sendPacket(buffer, len)) return false; diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 7ab48d7..409d1b8 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -190,10 +190,11 @@ public: // 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, const char *payload, bool retain, 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, bool retain, uint8_t qos = 0); - bool publish(const char *topic, uint8_t *payload, uint16_t bLen, bool retain, uint8_t qos = 0); + bool publish(const char *topic, uint8_t *payload, uint16_t bLen, + bool retain, uint8_t qos = 0); // Add a subscription to receive messages for a topic. Returns true if the // subscription could be added or was already present, false otherwise. From 8b27fdb77567887e17eebcffbb181399abf65d27 Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 2 Nov 2022 20:17:05 +0000 Subject: [PATCH 30/42] Fix formatting --- Adafruit_MQTT.cpp | 21 +++++++++------------ Adafruit_MQTT.h | 10 ++++++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index e21653c..c610239 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -366,17 +366,17 @@ 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), false, qos); + return publish(topic, (uint8_t*)(data), strlen(data), false, qos); } bool Adafruit_MQTT::publish(const char *topic, const char *data, bool retain, uint8_t qos) { - return publish(topic, (uint8_t*)(data), strlen(data), retain, qos); + return publish(topic, (uint8_t*)(data), strlen(data), retain, qos); } bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) { - return publish(topic, data, bLen, false, qos); + return publish(topic, data, bLen, false, qos); } bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, @@ -925,9 +925,7 @@ Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, qos = q; } -bool Adafruit_MQTT_Publish::publish(int32_t i) { - return publish(i, false); -} +bool Adafruit_MQTT_Publish::publish(int32_t i) { return publish(i, false); } bool Adafruit_MQTT_Publish::publish(int32_t i, bool retain) { char payload[12]; @@ -935,9 +933,7 @@ bool Adafruit_MQTT_Publish::publish(int32_t i, bool retain) { return mqtt->publish(topic, payload, retain, qos); } -bool Adafruit_MQTT_Publish::publish(uint32_t i) { - return publish(i, false); -} +bool Adafruit_MQTT_Publish::publish(uint32_t i) { return publish(i, false); } bool Adafruit_MQTT_Publish::publish(uint32_t i, bool retain) { char payload[11]; @@ -950,8 +946,8 @@ bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision) { } bool Adafruit_MQTT_Publish::publish(double f, bool retain, uint8_t precision) { - char payload[41]; // Need to technically hold float max, 39 digits and minus - // sign. + char payload[41]; // Need to technically hold float max, 39 digits and minus + // sign. dtostrf(f, 0, precision, payload); return mqtt->publish(topic, payload, retain, qos); } @@ -969,7 +965,8 @@ bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen) { return publish(payload, bLen, false); } -bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen, bool retain) { +bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen, + bool retain) { return mqtt->publish(topic, payload, bLen, retain, qos); } diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 409d1b8..a66ff3f 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -190,11 +190,12 @@ public: // 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, const char *payload, bool retain, uint8_t qos = 0); - bool publish(const char *topic, uint8_t *payload, uint16_t bLen, + bool publish(const char *topic, const char *payload, bool retain, uint8_t qos = 0); bool publish(const char *topic, uint8_t *payload, uint16_t bLen, - bool retain, uint8_t qos = 0); + uint8_t qos = 0); + bool publish(const char *topic, uint8_t *payload, uint16_t bLen, bool retain, + uint8_t qos = 0); // Add a subscription to receive messages for a topic. Returns true if the // subscription could be added or was already present, false otherwise. @@ -273,7 +274,8 @@ private: uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos, uint16_t maxPacketLen = 0); uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, - uint16_t bLen, bool retain, uint8_t qos, uint16_t maxPacketLen = 0); + uint16_t bLen, bool retain, uint8_t qos, + uint16_t maxPacketLen = 0); uint8_t subscribePacket(uint8_t *packet, const char *topic, uint8_t qos); uint8_t unsubscribePacket(uint8_t *packet, const char *topic); From 3f2b25339e1a77adfcb1ca4c5b37b9cf4c133e24 Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 2 Nov 2022 20:24:41 +0000 Subject: [PATCH 31/42] More formatting fixes --- Adafruit_MQTT.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index c610239..fd7d2dd 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -366,12 +366,12 @@ 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), false, qos); + return publish(topic, (uint8_t *)(data), strlen(data), false, qos); } -bool Adafruit_MQTT::publish(const char *topic, const char *data, - bool retain, uint8_t qos) { - return publish(topic, (uint8_t*)(data), strlen(data), retain, qos); +bool Adafruit_MQTT::publish(const char *topic, const char *data, bool retain, + uint8_t qos) { + return publish(topic, (uint8_t *)(data), strlen(data), retain, qos); } bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, From 96880c03c0c1331f4f6a91131ae5e14a4c15b7b3 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 2 Nov 2022 16:59:00 -0400 Subject: [PATCH 32/42] larger buffer for WS --- Adafruit_MQTT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 00657b4..2eb59c9 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -34,7 +34,7 @@ #define ADAFRUIT_MQTT_VERSION_PATCH 0 // Uncomment/comment to turn on/off debug output messages. -// #define MQTT_DEBUG +#define MQTT_DEBUG // Uncomment/comment to turn on/off error output messages. #define MQTT_ERROR @@ -107,7 +107,7 @@ // Largest full packet we're able to send. // Need to be able to store at least ~90 chars for a connect packet with full // 23 char client ID. -#define MAXBUFFERSIZE (150) +#define MAXBUFFERSIZE (512) #define MQTT_CONN_USERNAMEFLAG 0x80 #define MQTT_CONN_PASSWORDFLAG 0x40 @@ -124,7 +124,7 @@ #define SUBSCRIPTIONDATALEN 20 #else #define MAXSUBSCRIPTIONS 15 -#define SUBSCRIPTIONDATALEN 100 +#define SUBSCRIPTIONDATALEN MAXBUFFERSIZE #endif class AdafruitIO_MQTT; // forward decl From da5b49930706986fdb9cea7105da4fdf9706651d Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 9 Nov 2022 20:01:14 +0000 Subject: [PATCH 33/42] Add example of retain usage --- examples/mqtt_retain/mqtt_retain.ino | 140 +++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 examples/mqtt_retain/mqtt_retain.ino diff --git a/examples/mqtt_retain/mqtt_retain.ino b/examples/mqtt_retain/mqtt_retain.ino new file mode 100644 index 0000000..41197cc --- /dev/null +++ b/examples/mqtt_retain/mqtt_retain.ino @@ -0,0 +1,140 @@ +/*************************************************** + Adafruit MQTT Library Retain Flag Example + + This example demonstrates use of the retain flag when publishing messages. + If retain is set, the MQTT broker will store the message. When a new + client subscribes to the topic, the retained message will be republished + to that client. This is useful for configuration messages and 'last known + good' values. + + Written by Ben Willmore. + MIT license, all text above must be included in any redistribution + ****************************************************/ + +#include // use for ESP32 +#include "Adafruit_MQTT.h" +#include "Adafruit_MQTT_Client.h" + +/************************* WiFi Access Point *********************************/ + +#define WLAN_SSID "...your SSID..." +#define WLAN_PASS "...your password..." + +/************************* Adafruit.io Setup *********************************/ + +#define MQTT_SERVER "...your MQTT server..." +#define MQTT_SERVERPORT 1883 // use 8883 for SSL +#define MQTT_USERNAME "MQTT username" +#define MQTT_KEY "MQTT key" +#define DEVICE_ID "mqtt-retain-example" + +/************ Global State (you don't need to change this!) ******************/ + +// Create a WiFiClient class to connect to the MQTT server. +WiFiClient client; +// or... use WiFiClientSecure for SSL +//WiFiClientSecure client; + +// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. +Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_KEY); + +/****************************** Feeds ***************************************/ + +// Set up for publishing and subscribing to the same feed, for demonstration only +Adafruit_MQTT_Publish publish_feed = Adafruit_MQTT_Publish(&mqtt, DEVICE_ID "/temp"); +Adafruit_MQTT_Subscribe subscribe_feed = Adafruit_MQTT_Subscribe(&mqtt, DEVICE_ID "/temp"); + +/*************************** Sketch Code ************************************/ + +void setup() { + Serial.begin(115200); + delay(10); + + Serial.println(F("MQTT retain flag demo")); + + // Connect to WiFi access point. + Serial.println(); Serial.println(); + Serial.print("Connecting to "); + Serial.println(WLAN_SSID); + + WiFi.begin(WLAN_SSID, WLAN_PASS); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + // Connect to MQTT broker, then publish a retained message and a + // non-retained message. + Serial.print("\nConnecting to MQTT broker..."); + MQTT_connect(); + Serial.println("connected"); + + Serial.println("Publishing messages while not subscribed"); + publish_feed.publish("This message should be retained", true); + publish_feed.publish("This message should not be retained"); + + Serial.println("Disconnecting from MQTT broker\n"); + mqtt.disconnect(); + + subscribe_feed.setCallback(subscribe_callback); + mqtt.subscribe(&subscribe_feed); +} + +void subscribe_callback(char *data, uint16_t len) { + Serial.print("--> Message received: \""); + Serial.print(data); + Serial.println("\"\n"); +} + +void loop() { + + // Connect to MQTT broker. We should receive the retained message only. + Serial.println("Connecting to broker. Expect to receive retained message:"); + MQTT_connect(); + + mqtt.processPackets(1000); + + Serial.println("Publishing non-retained message. Expect to receive it immediately:"); + publish_feed.publish("This message should be received immediately but not retained"); + + mqtt.processPackets(1000); + + Serial.println("Publishing retained message. Expect to receive it immediately and on re-subscribing:"); + publish_feed.publish("This message should be received immediately AND retained", true); + + mqtt.processPackets(10000); + + Serial.println("Disconnecting from broker\n"); + mqtt.disconnect(); + + delay(15000); +} + +// Function to connect and reconnect as necessary to the MQTT server. +// Should be called in the loop function and it will take care if connecting. +void MQTT_connect() { + int8_t ret; + + // Stop if already connected. + if (mqtt.connected()) { + return; + } + + uint8_t retries = 3; + while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected + Serial.println(mqtt.connectErrorString(ret)); + Serial.println("Retrying MQTT connection in 5 seconds..."); + mqtt.disconnect(); + delay(5000); // wait 5 seconds + retries--; + if (retries == 0) { + // basically die and wait for WDT to reset me + while (1); + } + } +} From 33b62c7a64f9cd8557c1b89428fd607aae79e509 Mon Sep 17 00:00:00 2001 From: Ben Willmore Date: Wed, 9 Nov 2022 20:36:12 +0000 Subject: [PATCH 34/42] Add skip files --- examples/mqtt_retain/.due.test.skip | 0 examples/mqtt_retain/.leonardo.test.skip | 0 examples/mqtt_retain/.uno.test.skip | 0 examples/mqtt_retain/.zero.test.skip | 1 + 4 files changed, 1 insertion(+) create mode 100644 examples/mqtt_retain/.due.test.skip create mode 100644 examples/mqtt_retain/.leonardo.test.skip create mode 100644 examples/mqtt_retain/.uno.test.skip create mode 100644 examples/mqtt_retain/.zero.test.skip diff --git a/examples/mqtt_retain/.due.test.skip b/examples/mqtt_retain/.due.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/mqtt_retain/.leonardo.test.skip b/examples/mqtt_retain/.leonardo.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/mqtt_retain/.uno.test.skip b/examples/mqtt_retain/.uno.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/mqtt_retain/.zero.test.skip b/examples/mqtt_retain/.zero.test.skip new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/mqtt_retain/.zero.test.skip @@ -0,0 +1 @@ + From abe90ec6f6e24287ba827619da5baac9d4c445d5 Mon Sep 17 00:00:00 2001 From: Brent Rubell Date: Fri, 11 Nov 2022 09:56:50 -0500 Subject: [PATCH 35/42] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index f2aca1f..cb1ce44 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.5.0 +version=2.5.1 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 28435eaf58d85b3c30e55b965a73447d129c7774 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 14 Nov 2022 16:23:51 -0500 Subject: [PATCH 36/42] fixes from @ben-willmore on https://github.com/ben-willmore/Adafruit_MQTT_Library/commit/83af73f4e52a96d40d73ff2b258605fcc0d18bfb --- Adafruit_MQTT.cpp | 60 +++++++++++----------------------------------- Adafruit_MQTT.h | 40 ++++++++++++------------------- library.properties | 2 +- 3 files changed, 30 insertions(+), 72 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index fd7d2dd..da50bce 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -365,25 +365,16 @@ bool Adafruit_MQTT::disconnect() { return disconnectServer(); } -bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) { - return publish(topic, (uint8_t *)(data), strlen(data), false, qos); -} - -bool Adafruit_MQTT::publish(const char *topic, const char *data, bool retain, - uint8_t qos) { - return publish(topic, (uint8_t *)(data), strlen(data), retain, 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) { - return publish(topic, data, bLen, false, qos); -} - -bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, - bool retain, uint8_t qos) { + uint8_t qos, bool retain) { // Construct and send publish packet. - uint16_t len = publishPacket(buffer, topic, data, bLen, retain, qos, - (uint16_t)sizeof(buffer)); + uint16_t len = publishPacket(buffer, topic, data, bLen, qos, + (uint16_t)sizeof(buffer), retain); if (!sendPacket(buffer, len)) return false; @@ -763,13 +754,7 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) { // 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, - uint16_t maxPacketLen) { - return publishPacket(packet, topic, data, bLen, false, qos, maxPacketLen); -} - -uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, - uint8_t *data, uint16_t bLen, bool retain, - uint8_t qos, uint16_t maxPacketLen) { + uint16_t maxPacketLen, bool retain) { uint8_t *p = packet; uint16_t len = 0; @@ -925,50 +910,33 @@ Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, qos = q; } -bool Adafruit_MQTT_Publish::publish(int32_t i) { return publish(i, false); } - bool Adafruit_MQTT_Publish::publish(int32_t i, bool retain) { char payload[12]; ltoa(i, payload, 10); - return mqtt->publish(topic, payload, retain, qos); + return mqtt->publish(topic, payload, qos, retain); } -bool Adafruit_MQTT_Publish::publish(uint32_t i) { return publish(i, false); } - bool Adafruit_MQTT_Publish::publish(uint32_t i, bool retain) { char payload[11]; ultoa(i, payload, 10); - return mqtt->publish(topic, payload, retain, qos); + return mqtt->publish(topic, payload, qos, retain); } -bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision) { - return publish(f, false, precision); -} - -bool Adafruit_MQTT_Publish::publish(double f, bool retain, uint8_t precision) { +bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision, bool retain) { char payload[41]; // Need to technically hold float max, 39 digits and minus // sign. dtostrf(f, 0, precision, payload); - return mqtt->publish(topic, payload, retain, qos); -} - -bool Adafruit_MQTT_Publish::publish(const char *payload) { - return publish(payload, false); + return mqtt->publish(topic, payload, qos, retain); } bool Adafruit_MQTT_Publish::publish(const char *payload, bool retain) { - return mqtt->publish(topic, payload, retain, 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 publish(payload, bLen, false); -} - bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen, bool retain) { - - return mqtt->publish(topic, payload, bLen, retain, qos); + return mqtt->publish(topic, payload, bLen, qos, retain); } // Adafruit_MQTT_Subscribe Definition ////////////////////////////////////////// @@ -1011,4 +979,4 @@ void Adafruit_MQTT_Subscribe::removeCallback(void) { callback_double = 0; callback_io = 0; io_mqtt = 0; -} +} \ No newline at end of file diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 5639c09..7f825f6 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -34,7 +34,7 @@ #define ADAFRUIT_MQTT_VERSION_PATCH 0 // Uncomment/comment to turn on/off debug output messages. -#define MQTT_DEBUG +// #define MQTT_DEBUG // Uncomment/comment to turn on/off error output messages. #define MQTT_ERROR @@ -107,7 +107,7 @@ // Largest full packet we're able to send. // Need to be able to store at least ~90 chars for a connect packet with full // 23 char client ID. -#define MAXBUFFERSIZE (512) +#define MAXBUFFERSIZE (150) #define MQTT_CONN_USERNAMEFLAG 0x80 #define MQTT_CONN_PASSWORDFLAG 0x40 @@ -124,7 +124,7 @@ #define SUBSCRIPTIONDATALEN 20 #else #define MAXSUBSCRIPTIONS 15 -#define SUBSCRIPTIONDATALEN MAXBUFFERSIZE +#define SUBSCRIPTIONDATALEN 100 #endif class AdafruitIO_MQTT; // forward decl @@ -189,13 +189,10 @@ public: // 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, const char *payload, bool retain, - 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 publish(const char *topic, uint8_t *payload, uint16_t bLen, bool retain, - uint8_t qos = 0); + 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. @@ -272,11 +269,8 @@ private: 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 maxPacketLen = 0); - uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, - uint16_t bLen, bool retain, uint8_t qos, - uint16_t maxPacketLen = 0); - + uint16_t bLen, uint8_t qos, uint16_t maxPacketLen = 0, + bool retain = false); 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); @@ -288,20 +282,16 @@ public: Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, const char *feed, uint8_t qos = 0); - bool publish(const char *s); - bool publish(const char *s, bool retain); + bool publish(const char *s, bool retain = false); bool publish( double f, uint8_t precision = - 2); // Precision controls the minimum number of digits after decimal. + 2, // Precision controls the minimum number of digits after decimal. // This might be ignored and a higher precision value sent. - bool publish(double f, bool retain, uint8_t precision = 2); - bool publish(int32_t i); - bool publish(int32_t i, bool retain); - bool publish(uint32_t i); - bool publish(uint32_t i, bool retain); - bool publish(uint8_t *b, uint16_t bLen); - bool publish(uint8_t *b, uint16_t bLen, bool retain); + bool retain = false); + bool publish(int32_t i, bool retain = false); + bool publish(uint32_t i, bool retain = false); + bool publish(uint8_t *b, uint16_t bLen, bool retain = false); private: Adafruit_MQTT *mqtt; @@ -341,4 +331,4 @@ private: Adafruit_MQTT *mqtt; }; -#endif +#endif \ No newline at end of file diff --git a/library.properties b/library.properties index cb1ce44..a2dbe7a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.5.1 +version=2.5.2 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From d6b8436fb9df974fc7950983806e4bb3eb39c68e Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 14 Nov 2022 16:24:03 -0500 Subject: [PATCH 37/42] clang format --- Adafruit_MQTT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 7f825f6..01b373b 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -287,7 +287,7 @@ public: double f, uint8_t precision = 2, // Precision controls the minimum number of digits after decimal. - // This might be ignored and a higher precision value sent. + // This might be ignored and a higher precision value sent. bool retain = false); bool publish(int32_t i, bool retain = false); bool publish(uint32_t i, bool retain = false); From dd72b39489685edf2d6b40f4e8bc75c9d747f4e3 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 21 Apr 2023 13:05:51 -0400 Subject: [PATCH 38/42] fix return type for esp bsp 2.0.8 --- Adafruit_MQTT.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ Adafruit_MQTT.h | 10 +++++++++- library.properties | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index da50bce..274f1fc 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -327,6 +327,47 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, return ((pbuff - buffer) + rlen); } +#ifdef ARDUINO_ARCH_ESP32 +const char *Adafruit_MQTT::connectErrorString(int8_t code) { + const char *statusMsg; + switch (code) { + case 1: + statusMsg = + "The Server does not support the level of the MQTT protocol requested"; + break; + case 2: + statusMsg = + "The Client identifier is correct UTF-8 but not allowed by the Server"; + break; + case 3: + statusMsg = "The MQTT service is unavailable"; + break; + case 4: + statusMsg = "The data in the user name or password is malformed"; + break; + case 5: + statusMsg = "Not authorized to connect"; + break; + case 6: + statusMsg = "Exceeded reconnect rate limit. Please try again later."; + break; + case 7: + statusMsg = "You have been banned from connecting. Please contact the MQTT " + "server administrator for more details."; + break; + case -1: + statusMsg = "Connection failed"; + break; + case -2: + statusMsg = "Failed to subscribe"; + break; + default: + statusMsg = "Unknown error"; + break; + } + return statusMsg; +} +#else const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) { switch (code) { case 1: @@ -354,6 +395,7 @@ const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) { return F("Unknown error"); } } +#endif bool Adafruit_MQTT::disconnect() { diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 01b373b..f0257f1 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -166,11 +166,19 @@ public: int8_t connect(); int8_t connect(const char *user, const char *pass); - // Return a printable string version of the error code returned by +#ifdef ARDUINO_ARCH_ESP32 + // Returns a printable string version of the error code returned by + // connect(). Preprocessor due to breaking change within + // Arduino ESP32 BSP v2.0.8 + // see: https://github.com/espressif/arduino-esp32/pull/7941 + const char *connectErrorString(int8_t code); +#else + // Returns a printable string version of the error code returned by // connect(). This returns a __FlashStringHelper*, which points to a // string stored in flash, but can be directly passed to e.g. // Serial.println without any further processing. const __FlashStringHelper *connectErrorString(int8_t code); +#endif; // Sends MQTT disconnect packet and calls disconnectServer() bool disconnect(); diff --git a/library.properties b/library.properties index a2dbe7a..2bd2907 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.5.2 +version=2.5.3 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From a94f4d512e966718f466d4b97ecb129a67e38347 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 21 Apr 2023 15:23:01 -0400 Subject: [PATCH 39/42] carter feedback implemented --- Adafruit_MQTT.cpp | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index 274f1fc..c31d0c1 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -329,46 +329,9 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, #ifdef ARDUINO_ARCH_ESP32 const char *Adafruit_MQTT::connectErrorString(int8_t code) { - const char *statusMsg; - switch (code) { - case 1: - statusMsg = - "The Server does not support the level of the MQTT protocol requested"; - break; - case 2: - statusMsg = - "The Client identifier is correct UTF-8 but not allowed by the Server"; - break; - case 3: - statusMsg = "The MQTT service is unavailable"; - break; - case 4: - statusMsg = "The data in the user name or password is malformed"; - break; - case 5: - statusMsg = "Not authorized to connect"; - break; - case 6: - statusMsg = "Exceeded reconnect rate limit. Please try again later."; - break; - case 7: - statusMsg = "You have been banned from connecting. Please contact the MQTT " - "server administrator for more details."; - break; - case -1: - statusMsg = "Connection failed"; - break; - case -2: - statusMsg = "Failed to subscribe"; - break; - default: - statusMsg = "Unknown error"; - break; - } - return statusMsg; -} #else const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) { +#endif switch (code) { case 1: return F( @@ -395,7 +358,6 @@ const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) { return F("Unknown error"); } } -#endif bool Adafruit_MQTT::disconnect() { From e9a6c12184e491dec741aa4798f07ba1882fb86c Mon Sep 17 00:00:00 2001 From: Brent Rubell Date: Thu, 4 May 2023 14:26:19 -0400 Subject: [PATCH 40/42] Revert "Fix connectErrorString return type for ESP-32 BSP 2.0.8" --- Adafruit_MQTT.cpp | 4 ---- Adafruit_MQTT.h | 10 +--------- library.properties | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index c31d0c1..da50bce 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -327,11 +327,7 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, return ((pbuff - buffer) + rlen); } -#ifdef ARDUINO_ARCH_ESP32 -const char *Adafruit_MQTT::connectErrorString(int8_t code) { -#else const __FlashStringHelper *Adafruit_MQTT::connectErrorString(int8_t code) { -#endif switch (code) { case 1: return F( diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index f0257f1..01b373b 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -166,19 +166,11 @@ public: int8_t connect(); int8_t connect(const char *user, const char *pass); -#ifdef ARDUINO_ARCH_ESP32 - // Returns a printable string version of the error code returned by - // connect(). Preprocessor due to breaking change within - // Arduino ESP32 BSP v2.0.8 - // see: https://github.com/espressif/arduino-esp32/pull/7941 - const char *connectErrorString(int8_t code); -#else - // Returns a printable string version of the error code returned by + // Return a printable string version of the error code returned by // connect(). This returns a __FlashStringHelper*, which points to a // string stored in flash, but can be directly passed to e.g. // Serial.println without any further processing. const __FlashStringHelper *connectErrorString(int8_t code); -#endif; // Sends MQTT disconnect packet and calls disconnectServer() bool disconnect(); diff --git a/library.properties b/library.properties index 2bd2907..a2dbe7a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.5.3 +version=2.5.2 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From d56a6c7bfac107fe354356e05c26256de0fb3dbc Mon Sep 17 00:00:00 2001 From: Brent Rubell Date: Thu, 4 May 2023 14:34:44 -0400 Subject: [PATCH 41/42] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index a2dbe7a..024fb08 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=2.5.2 +version=2.5.4 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware. From 0c57bf6c1d727ac11555abc0d1a854a75347515b Mon Sep 17 00:00:00 2001 From: dherrada Date: Fri, 12 May 2023 11:24:05 -0400 Subject: [PATCH 42/42] Update CI action versions --- .github/workflows/githubci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/githubci.yml b/.github/workflows/githubci.yml index 2a270b1..0856b05 100644 --- a/.github/workflows/githubci.yml +++ b/.github/workflows/githubci.yml @@ -7,11 +7,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v4 with: python-version: '3.x' - - uses: actions/checkout@v2 - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - uses: actions/checkout@v3 with: repository: adafruit/ci-arduino path: ci