1
0
mirror of https://github.com/adafruit/Adafruit_MQTT_Library.git synced 2025-07-21 18:22:06 +03:00

Merge in KEEPALIVE check.

This commit is contained in:
dlizotte-uwo
2023-07-05 17:39:49 -04:00
14 changed files with 501 additions and 81 deletions

View File

@ -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

View File

@ -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,
@ -117,6 +133,7 @@ Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, const char *cid,
will_retain = 0;
packet_id_counter = 1; // MQTT spec forbids packet id of 0 if QOS=1
keepAliveInterval = MQTT_CONN_KEEPALIVE;
}
Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port,
@ -138,6 +155,8 @@ Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port,
will_retain = 0;
packet_id_counter = 1; // MQTT spec forbids packet id of 0 if QOS=1
keepAliveInterval = MQTT_CONN_KEEPALIVE;
}
int8_t Adafruit_MQTT::connect() {
@ -202,6 +221,32 @@ 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
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);
} else {
DEBUG_PRINTLN(
"ERROR: Subscription packet did not have an associated callback");
return;
}
// mark subscription message as "read""
sub->new_message = false;
}
uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer,
uint8_t waitforpackettype,
uint16_t timeout) {
@ -219,7 +264,9 @@ 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)
processSubscriptionPacket(sub);
} else {
ERROR_PRINTLN(F("Dropped a packet"));
}
@ -233,7 +280,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);
@ -267,7 +314,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 {
@ -316,26 +364,29 @@ 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), 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) {
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,
(uint16_t)sizeof(buffer), retain);
if (!sendPacket(buffer, len))
return false;
// 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];
@ -366,6 +417,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
@ -437,27 +507,8 @@ void Adafruit_MQTT::processPackets(int16_t timeout) {
while (elapsed < (uint32_t)timeout) {
Adafruit_MQTT_Subscribe *sub = readSubscription(timeout - elapsed);
if (sub) {
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
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) {
@ -467,10 +518,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 =
readFullPacket(buffer, MAXBUFFERSIZE, timeout); // return one full packet
return handleSubscriptionPacket(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
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) {
@ -491,7 +564,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
}
// Parse out length of packet.
topiclen = buffer[3];
uint16_t const topicoffset = packetAdditionalLen(len);
uint16_t const topicstart = topicoffset + 4;
topiclen = buffer[3 + topicoffset];
DEBUG_PRINT(F("Looking for subscription len "));
DEBUG_PRINTLN(topiclen);
@ -504,10 +579,16 @@ 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) ==
0) {
if (strncasecmp((char *)buffer + topicstart, subscriptions[i]->topic,
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;
}
}
@ -520,21 +601,21 @@ 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,
datalen);
memmove(subscriptions[i]->lastread,
buffer + topicstart + topiclen + packet_id_len, datalen);
subscriptions[i]->datalen = datalen;
DEBUG_PRINT(F("Data len: "));
DEBUG_PRINTLN(datalen);
@ -629,9 +710,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) {
@ -671,8 +752,8 @@ 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,
uint16_t maxPacketLen, bool retain) {
uint8_t *p = packet;
uint16_t len = 0;
@ -682,10 +763,27 @@ 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 remaining length. When maxPacketLen provided is 0, let's
// assume buffer is big enough. Fingers crossed.
// 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 += 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
@ -810,33 +908,34 @@ Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver,
topic = feed;
qos = q;
}
bool Adafruit_MQTT_Publish::publish(int32_t i) {
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, qos, retain);
}
bool Adafruit_MQTT_Publish::publish(uint32_t i) {
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, qos, retain);
}
bool Adafruit_MQTT_Publish::publish(double f, 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, qos);
return mqtt->publish(topic, payload, qos, retain);
}
bool Adafruit_MQTT_Publish::publish(const char *payload) {
return mqtt->publish(topic, payload, qos);
bool Adafruit_MQTT_Publish::publish(const char *payload, bool retain) {
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);
bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen,
bool retain) {
return mqtt->publish(topic, payload, bLen, qos, retain);
}
// Adafruit_MQTT_Subscribe Definition //////////////////////////////////////////
@ -852,6 +951,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) {

View File

@ -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
@ -184,11 +184,15 @@ 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);
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);
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.
@ -206,10 +210,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.
@ -250,6 +256,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;
@ -262,7 +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 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);
@ -274,15 +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 = false);
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(int32_t i);
bool publish(uint32_t i);
bool publish(uint8_t *b, uint16_t bLen);
2, // Precision controls the minimum number of digits after decimal.
// 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);
bool publish(uint8_t *b, uint16_t bLen, bool retain = false);
private:
Adafruit_MQTT *mqtt;
@ -316,8 +325,10 @@ public:
AdafruitIO_MQTT *io_mqtt;
bool new_message;
private:
Adafruit_MQTT *mqtt;
};
#endif
#endif

View File

@ -83,17 +83,18 @@ 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.");

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -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 <WiFi.h>
#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: <username>/feeds/<feedname>
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!");
}

View File

@ -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 ***************************************/

View File

View File

View File

View File

@ -0,0 +1 @@

View File

@ -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 <ESP8266WiFi.h> // use <WiFi.h> 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);
}
}
}

View File

@ -1,8 +1,8 @@
name=Adafruit MQTT Library
version=2.1.0
version=2.5.4
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
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