diff --git a/Adafruit_MQTT.cpp b/Adafruit_MQTT.cpp index c0de9c9..ef130af 100644 --- a/Adafruit_MQTT.cpp +++ b/Adafruit_MQTT.cpp @@ -319,9 +319,9 @@ 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, uint8_t *data, uint8_t bLen, uint8_t qos) { +bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) { // Construct and send publish packet. - uint8_t len = publishPacket(buffer, topic, data, bLen, qos); + uint16_t len = publishPacket(buffer, topic, data, bLen, qos); if (!sendPacket(buffer, len)) return false; @@ -611,14 +611,34 @@ 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 -uint8_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, - uint8_t *data, uint8_t bLen, uint8_t qos) { +uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, + uint8_t *data, uint16_t bLen, uint8_t qos) { uint8_t *p = packet; - uint16_t len; + uint16_t len=0; + // calc length of non-header data + len += 2; // two bytes to set the topic size + len += strlen_P(topic); // topic length + if(qos > 0) { + len += 2; // qos packet id + } + len += bLen; // payload length + + // Now you can start generating the packet! p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1; + p++; + // fill in packet[1] last - p+=2; + do { + uint8_t encodedByte = len % 128; + len /= 128; + // if there are more data to encode, set the top bit of this byte + if ( len > 0 ) { + encodedByte |= 0x80; + } + p[0] = encodedByte; + p++; + } while ( len > 0 ); // topic comes before packet identifier p = stringprint_P(p, topic); @@ -636,11 +656,9 @@ uint8_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic, memmove(p, data, bLen); p+= bLen; len = p - packet; - packet[1] = len-2; // don't include the 2 bytes of fixed header data DEBUG_PRINTLN(F("MQTT publish packet:")); DEBUG_PRINTBUFFER(buffer, len); return len; - } uint8_t Adafruit_MQTT::subscribePacket(uint8_t *packet, const char *topic, @@ -766,7 +784,7 @@ bool Adafruit_MQTT_Publish::publish(const char *payload) { } //publish buffer of arbitrary length -bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint8_t bLen) { +bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen) { return mqtt->publish(topic, payload, bLen, qos); } diff --git a/Adafruit_MQTT.h b/Adafruit_MQTT.h index 6df4b01..2fcf251 100644 --- a/Adafruit_MQTT.h +++ b/Adafruit_MQTT.h @@ -163,7 +163,7 @@ class Adafruit_MQTT { // The topic must be stored in PROGMEM. It can either be a // char*, or a __FlashStringHelper* (the result of the F() macro). bool publish(const char *topic, const char *payload, uint8_t qos = 0); - bool publish(const char *topic, uint8_t *payload, uint8_t bLen, uint8_t qos = 0); + bool publish(const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos = 0); bool publish(const __FlashStringHelper *topic, const char *payload, uint8_t qos = 0) { return publish((const char *)topic, payload, qos); } @@ -196,7 +196,7 @@ class Adafruit_MQTT { virtual bool disconnectServer() = 0; // Subclasses need to fill this in! // Send data to the server specified by the buffer and length of data. - virtual bool sendPacket(uint8_t *buffer, uint8_t len) = 0; + virtual bool sendPacket(uint8_t *buffer, uint16_t len) = 0; // Read MQTT packet from the server. Will read up to maxlen bytes and store // the data in the provided buffer. Waits up to the specified timeout (in @@ -229,7 +229,7 @@ class Adafruit_MQTT { // Functions to generate MQTT packets. uint8_t connectPacket(uint8_t *packet); uint8_t disconnectPacket(uint8_t *packet); - uint8_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint8_t bLen, uint8_t qos); + uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos); uint8_t 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); @@ -247,7 +247,7 @@ class Adafruit_MQTT_Publish { // 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, uint8_t bLen); + bool publish(uint8_t *b, uint16_t bLen); private: diff --git a/Adafruit_MQTT_Client.cpp b/Adafruit_MQTT_Client.cpp index 1487856..d954bc8 100644 --- a/Adafruit_MQTT_Client.cpp +++ b/Adafruit_MQTT_Client.cpp @@ -74,17 +74,27 @@ uint16_t Adafruit_MQTT_Client::readPacket(uint8_t *buffer, uint16_t maxlen, return len; } -bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint8_t len) { - if (client->connected()) { - uint16_t ret = client->write(buffer, len); - DEBUG_PRINT(F("sendPacket returned: ")); DEBUG_PRINTLN(ret); - if (ret != len) { - DEBUG_PRINTLN("Failed to send complete packet.") +bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint16_t len) { + uint16_t ret = 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 = min(len, 250); + Serial.print("Sending: "); Serial.println(sendlen); + ret = client->write(buffer, sendlen); + DEBUG_PRINT(F("Client sendPacket returned: ")); DEBUG_PRINTLN(ret); + len -= ret; + + if (ret != sendlen) { + DEBUG_PRINTLN("Failed to send complete packet."); + return false; + } + } else { + DEBUG_PRINTLN(F("Connection failed!")); return false; } - } else { - DEBUG_PRINTLN(F("Connection failed!")); - return false; } return true; } diff --git a/Adafruit_MQTT_Client.h b/Adafruit_MQTT_Client.h index bb99e3f..f51cb29 100644 --- a/Adafruit_MQTT_Client.h +++ b/Adafruit_MQTT_Client.h @@ -51,7 +51,7 @@ class Adafruit_MQTT_Client : public Adafruit_MQTT { bool disconnectServer(); bool connected(); uint16_t readPacket(uint8_t *buffer, uint16_t maxlen, int16_t timeout); - bool sendPacket(uint8_t *buffer, uint8_t len); + bool sendPacket(uint8_t *buffer, uint16_t len); private: Client* client; diff --git a/Adafruit_MQTT_FONA.h b/Adafruit_MQTT_FONA.h index b8e3ba2..dbbdb9e 100644 --- a/Adafruit_MQTT_FONA.h +++ b/Adafruit_MQTT_FONA.h @@ -117,7 +117,7 @@ class Adafruit_MQTT_FONA : public Adafruit_MQTT { return len; } - bool sendPacket(uint8_t *buffer, uint8_t len) { + bool sendPacket(uint8_t *buffer, uint16_t len) { DEBUG_PRINTLN(F("Writing packet")); if (fona->TCPconnected()) { boolean ret = fona->TCPsend((char *)buffer, len);