diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index cb03fd4..c5c76aa 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -66,7 +66,7 @@ #define MQTT_CONN_KEEPALIVE 300 // Largest full packet we're able to send. -// Need to be able to store at least ~90 chars for a connect packet with full +// Need to be able to store at least ~90 chars for a connect packet with full // 23 char client ID. #define MAXBUFFERSIZE (125) @@ -111,6 +111,9 @@ class Adafruit_MQTT { // otherwise. virtual bool disconnect() = 0; // Subclasses need to fill this in! + // Return true if connected to the MQTT server, otherwise false. + virtual bool connected() = 0; // Subclasses need to fill this in! + // 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, char *payload, uint8_t qos); diff --git a/Adafruit_MQTT_CC3000.h b/Adafruit_MQTT_CC3000.h index 47ea841..a1f6ea6 100644 --- a/Adafruit_MQTT_CC3000.h +++ b/Adafruit_MQTT_CC3000.h @@ -28,7 +28,7 @@ // delay in ms between calls of available() -#define MQTT_CC3000_INTERAVAILDELAY 10 +#define MQTT_CC3000_INTERAVAILDELAY 10 // CC3000-specific version of the Adafruit_MQTT class. @@ -37,7 +37,7 @@ // in the compilation of the library). class Adafruit_MQTT_CC3000 : public Adafruit_MQTT { public: - Adafruit_MQTT_CC3000(Adafruit_CC3000 *cc3k, const char *server, uint16_t port, + Adafruit_MQTT_CC3000(Adafruit_CC3000 *cc3k, const char *server, uint16_t port, const char *cid, const char *user, const char *pass): Adafruit_MQTT(server, port, cid, user, pass), cc3000(cc3k) @@ -66,9 +66,9 @@ class Adafruit_MQTT_CC3000 : public Adafruit_MQTT { if (!dnsretries) return false; delay(500); } - + serverip = ip; - cc3000->printIPdotsRev(serverip); + cc3000->printIPdotsRev(serverip); Serial.println(); } @@ -77,15 +77,24 @@ class Adafruit_MQTT_CC3000 : public Adafruit_MQTT { // connect to server DEBUG_PRINTLN(F("Connecting to TCP")); mqttclient = cc3000->connectTCP(serverip, portnum); - + return mqttclient.connected(); } bool disconnect() { - return (mqttclient.close() == 0); + if (connected()) { + return (mqttclient.close() == 0); + } + else { + return true; + } } - uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, + bool connected() { + return mqttclient.connected(); + } + + uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, bool checkForValidPubPacket = false) { /* Read data until either the connection is closed, or the idle timeout is reached. */ uint16_t len = 0; @@ -137,7 +146,7 @@ class Adafruit_MQTT_CC3000 : public Adafruit_MQTT { } return true; } - + private: uint32_t serverip; Adafruit_CC3000 *cc3000; diff --git a/Adafruit_MQTT_Client.cpp b/Adafruit_MQTT_Client.cpp index d91e04b..e0686d9 100644 --- a/Adafruit_MQTT_Client.cpp +++ b/Adafruit_MQTT_Client.cpp @@ -34,13 +34,21 @@ bool Adafruit_MQTT_Client::connectServer() { } bool Adafruit_MQTT_Client::disconnect() { - // Stop connection and return success (stop has no indication of failure). - client->stop(); - return true; + // Stop connection if connected and return success (stop has no indication of + // failure). + if (client->connected()) { + client->stop(); + } + return true; +} + +bool Adafruit_MQTT_Client::connected() { + // Return true if connected, false if not connected. + return client->connected(); } uint16_t Adafruit_MQTT_Client::readPacket(uint8_t *buffer, uint8_t maxlen, - int16_t timeout, + int16_t timeout, bool checkForValidPubPacket) { /* Read data until either the connection is closed, or the idle timeout is reached. */ uint16_t len = 0; diff --git a/Adafruit_MQTT_Client.h b/Adafruit_MQTT_Client.h index 1bce8e4..e78c81b 100644 --- a/Adafruit_MQTT_Client.h +++ b/Adafruit_MQTT_Client.h @@ -27,7 +27,7 @@ // How long to delay waiting for new data to be available in readPacket. -#define MQTT_CLIENT_READINTERVAL_MS 10 +#define MQTT_CLIENT_READINTERVAL_MS 10 // MQTT client implementation for a generic Arduino Client interface. Can work @@ -44,10 +44,11 @@ class Adafruit_MQTT_Client : public Adafruit_MQTT { bool connectServer(); bool disconnect(); - uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, + bool connected(); + uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, bool checkForValidPubPacket = false); bool sendPacket(uint8_t *buffer, uint8_t len); - + private: Client* client; }; diff --git a/Adafruit_MQTT_FONA.h b/Adafruit_MQTT_FONA.h index 178dd6b..17d73fe 100644 --- a/Adafruit_MQTT_FONA.h +++ b/Adafruit_MQTT_FONA.h @@ -35,7 +35,7 @@ // in the compilation of the library). class Adafruit_MQTT_FONA : public Adafruit_MQTT { public: - Adafruit_MQTT_FONA(Adafruit_FONA *f, const char *server, uint16_t port, + Adafruit_MQTT_FONA(Adafruit_FONA *f, const char *server, uint16_t port, const char *cid, const char *user, const char *pass): Adafruit_MQTT(server, port, cid, user, pass), fona(f) @@ -55,7 +55,12 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { return fona->TCPclose(); } - uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, + bool connected() { + // Return true if connected, false if not connected. + return fona->TCPconnected(); + } + + uint16_t readPacket(uint8_t *buffer, uint8_t maxlen, int16_t timeout, bool checkForValidPubPacket = false) { uint8_t *buffp = buffer; DEBUG_PRINTLN(F("Reading a packet..")); @@ -72,7 +77,7 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { DEBUG_PRINT('.'); while (avail = fona->TCPavailable()) { DEBUG_PRINT('!'); - + if (len + avail > maxlen) { avail = maxlen - len; if (avail == 0) return len; @@ -80,7 +85,7 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { // try to read the data into the end of the pointer if (! fona->TCPread(buffp, avail)) return len; - + // read it! advance pointer buffp += avail; len += avail; @@ -103,14 +108,14 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { return len; } } - + } Watchdog.reset(); timeout -= MQTT_FONA_INTERAVAILDELAY; timeout -= MQTT_FONA_QUERYDELAY; // this is how long it takes to query the FONA for avail() delay(MQTT_FONA_INTERAVAILDELAY); } - + return len; } @@ -127,9 +132,9 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { DEBUG_PRINTLN(F("Connection failed!")); return false; } - return true; + return true; } - + private: uint32_t serverip; Adafruit_FONA *fona; diff --git a/examples/mqtt_cc3k/mqtt_cc3k.ino b/examples/mqtt_cc3k/mqtt_cc3k.ino index 7e59017..d2490f4 100644 --- a/examples/mqtt_cc3k/mqtt_cc3k.ino +++ b/examples/mqtt_cc3k/mqtt_cc3k.ino @@ -94,33 +94,8 @@ void setup() { while (! CC3000connect(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { Serial.println(F("Retrying WiFi")); - while(1); + delay(1000); } - - Serial.println(F("Connected to WiFi!")); - ////////////////////////////// - Serial.println(F("Connecting to MQTT...")); - int8_t ret; - while ((ret = mqtt.connect()) != 0) { - switch (ret) { - case 1: Serial.println(F("Wrong protocol")); break; - case 2: Serial.println(F("ID rejected")); break; - case 3: Serial.println(F("Server unavail")); break; - case 4: Serial.println(F("Bad user/pass")); break; - case 5: Serial.println(F("Not authed")); break; - case 6: Serial.println(F("Failed to subscribe")); break; - default: { - Serial.println(F("Connection failed")); - CC3000connect(WLAN_SSID, WLAN_PASS, WLAN_SECURITY); // y0w, lets connect to wifi again - return; // restart the loop - } - } - Serial.println(F("Retrying MQTT connection")); - delay(5000); - } - ////////////////////////////// - - Serial.println(F("MQTT Connected!")); } uint32_t x=0; @@ -129,6 +104,11 @@ void loop() { // Make sure to reset watchdog every loop iteration! Watchdog.reset(); + // 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(); + // Try to ping the MQTT server /* if (! mqtt.ping(3) ) { @@ -158,3 +138,35 @@ void loop() { Serial.println(F("OK!")); } } + +// 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... "); + + while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected + switch (ret) { + case 1: Serial.println("Wrong protocol"); break; + case 2: Serial.println("ID rejected"); break; + case 3: Serial.println("Server unavailable"); break; + case 4: Serial.println("Bad user/password"); break; + case 5: Serial.println("Not authenticated"); break; + case 6: Serial.println("Failed to subscribe"); break; + default: + Serial.println(F("Connection failed")); + CC3000connect(WLAN_SSID, WLAN_PASS, WLAN_SECURITY); // y0w, lets connect to wifi again + break; + } + Serial.println("Retrying MQTT connection in 5 seconds..."); + mqtt.disconnect(); + delay(5000); // wait 5 seconds + } + Serial.println("MQTT Connected!"); +} diff --git a/examples/mqtt_esp8266/mqtt_esp8266.ino b/examples/mqtt_esp8266/mqtt_esp8266.ino index fbf503e..5a7d217 100644 --- a/examples/mqtt_esp8266/mqtt_esp8266.ino +++ b/examples/mqtt_esp8266/mqtt_esp8266.ino @@ -84,30 +84,16 @@ void setup() { // Setup MQTT subscription for onoff feed. mqtt.subscribe(&onoffbutton); - - // Connect to MQTT server. - Serial.println(F("Connecting to MQTT...")); - int8_t ret; - while ((ret = mqtt.connect()) != 0) { - switch (ret) { - case 1: Serial.println(F("Wrong protocol")); break; - case 2: Serial.println(F("ID rejected")); break; - case 3: Serial.println(F("Server unavail")); break; - case 4: Serial.println(F("Bad user/pass")); break; - case 5: Serial.println(F("Not authed")); break; - case 6: Serial.println(F("Failed to subscribe")); break; - default: Serial.println(F("Couldn't connect to MQTT server")); break; - } - Serial.println(F("Retrying MQTT connection")); - mqtt.disconnect(); - delay(5000); - } - Serial.println(F("MQTT Connected!")); } 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(); + // Try to ping the MQTT server /* if (! mqtt.ping(3) ) { @@ -137,3 +123,34 @@ void loop() { delay(1000); } + +// 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... "); + + while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected + switch (ret) { + case 1: Serial.println("Wrong protocol"); break; + case 2: Serial.println("ID rejected"); break; + case 3: Serial.println("Server unavailable"); break; + case 4: Serial.println("Bad user/password"); break; + case 5: Serial.println("Not authenticated"); break; + case 6: Serial.println("Failed to subscribe"); break; + default: Serial.print("Couldn't connect to server, code: "); + Serial.println(ret); + break; + } + Serial.println("Retrying MQTT connection in 5 seconds..."); + mqtt.disconnect(); + delay(5000); // wait 5 seconds + } + Serial.println("MQTT Connected!"); +} diff --git a/library.properties b/library.properties index ae677fd..9d42d11 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit MQTT Library -version=0.9.1 +version=0.9.2 author=Adafruit maintainer=Adafruit sentence=MQTT library that supports the CC3000, FONA, ESP8266, and generic Arduino Client hardware.