@@ -323,7 +323,8 @@ bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {
323323bool Adafruit_MQTT::publish (const char *topic, uint8_t *data, uint16_t bLen,
324324 uint8_t qos) {
325325 // Construct and send publish packet.
326- uint16_t len = publishPacket (buffer, topic, data, bLen, qos);
326+ uint16_t len =
327+ publishPacket (buffer, topic, data, bLen, qos, (uint16_t )sizeof (buffer));
327328 if (!sendPacket (buffer, len))
328329 return false ;
329330
@@ -686,11 +687,26 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
686687 return len;
687688}
688689
690+ // packetAdditionalLen is a helper function used to figure out
691+ // how bigger the payload needs to be in order to account for
692+ // its variable length field. As per
693+ // http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size
694+ static uint16_t packetAdditionalLen (uint16_t currLen) {
695+ /* Increase length field based on current length */
696+ if (currLen < 128 )
697+ return 0 ;
698+ if (currLen < 16384 )
699+ return 1 ;
700+ if (currLen < 2097151 )
701+ return 2 ;
702+ return 3 ;
703+ }
704+
689705// as per
690706// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
691707uint16_t Adafruit_MQTT::publishPacket (uint8_t *packet, const char *topic,
692- uint8_t *data, uint16_t bLen,
693- uint8_t qos ) {
708+ uint8_t *data, uint16_t bLen, uint8_t qos,
709+ uint16_t maxPacketLen ) {
694710 uint8_t *p = packet;
695711 uint16_t len = 0 ;
696712
@@ -700,7 +716,22 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
700716 if (qos > 0 ) {
701717 len += 2 ; // qos packet id
702718 }
703- len += bLen; // payload length
719+ // Calculate additional bytes for length field (if any)
720+ uint16_t additionalLen = packetAdditionalLen (len + bLen);
721+
722+ // Payload length. When maxPacketLen provided is 0, let's
723+ // assume buffer is big enough. Fingers crossed.
724+ if (maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen)) {
725+ len += bLen + additionalLen;
726+ } else {
727+ // If we make it here, we got a pickle: the payload is not going
728+ // to fit in the packet buffer. Instead of corrupting memory, let's
729+ // do something less damaging by reducing the bLen to what we are
730+ // able to accomodate. Alternatively, consider using a bigger
731+ // maxPacketLen.
732+ bLen = maxPacketLen - (len + 2 + packetAdditionalLen (maxPacketLen));
733+ len = maxPacketLen - 4 ;
734+ }
704735
705736 // Now you can start generating the packet!
706737 p[0 ] = MQTT_CTRL_PUBLISH << 4 | qos << 1 ;
0 commit comments