diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index de046f0..6d5a45a 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -206,6 +206,50 @@ bool Adafruit_MQTT::subscribe(Adafruit_MQTT_Subscribe *sub) { return false; } +bool Adafruit_MQTT::unsubscribe(Adafruit_MQTT_Subscribe *sub) { + uint8_t i; + + // see if we are already subscribed + for (i=0; itopic); + + // sending unsubscribe failed + if (! sendPacket(buffer, len)) + return false; + + // if QoS for this subscription is 1 or 2, we need + // to wait for the unsuback to confirm unsubscription + if(subscriptions[i]->qos > 0) { + + // wait for UNSUBACK + len = readPacket(buffer, 5, CONNECT_TIMEOUT_MS); + DEBUG_PRINT(F("UNSUBACK:\t")); + DEBUG_PRINTBUFFER(buffer, len); + + if ((len != 5) || (buffer[0] != (MQTT_CTRL_UNSUBACK << 4))) { + return false; // failure to unsubscribe + } + + } + + subscriptions[i] = 0; + return true; + + } + + } + + // subscription not found, so we are unsubscribed + return true; + +} + Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) { uint8_t i, topiclen, datalen; @@ -396,6 +440,31 @@ uint8_t Adafruit_MQTT::subscribePacket(uint8_t *packet, const char *topic, return len; } +uint8_t Adafruit_MQTT::unsubscribePacket(uint8_t *packet, const char *topic) { + + uint8_t *p = packet; + uint16_t len; + + p[0] = MQTT_CTRL_UNSUBSCRIBE << 4 | 0x1; + // fill in packet[1] last + p+=2; + + // packet identifier. used for QoS > 1 + // TODO: this shouldn't be a static value + p[0] = 0xAD; + p[1] = 0xAF; + p+=2; + + p = stringprint_P(p, topic); + + len = p - packet; + packet[1] = len-2; // don't include the 2 bytes of fixed header data + DEBUG_PRINTLN(F("MQTT unsubscription packet:")); + DEBUG_PRINTBUFFER(buffer, len); + return len; + +} + uint8_t Adafruit_MQTT::pingPacket(uint8_t *packet) { packet[0] = MQTT_CTRL_PINGREQ << 4; packet[1] = 0; diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 29e4e70..ad5653d 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -57,7 +57,7 @@ #define MQTT_CTRL_SUBSCRIBE 0x8 #define MQTT_CTRL_SUBACK 0x9 #define MQTT_CTRL_UNSUBSCRIBE 0xA -#define MQTT_CTRL_UNSUBSACK 0xB +#define MQTT_CTRL_UNSUBACK 0xB #define MQTT_CTRL_PINGREQ 0xC #define MQTT_CTRL_PINGRESP 0xD #define MQTT_CTRL_DISCONNECT 0xE