@@ -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
@@ -668,11 +669,26 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
668669 return len;
669670}
670671
672+ // packetAdditionalLen is a helper function used to figure out
673+ // how bigger the payload needs to be in order to account for
674+ // its variable length field. As per
675+ // http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size
676+ static uint16_t packetAdditionalLen (uint16_t currLen) {
677+ /* Increase length field based on current length */
678+ if (currLen < 128 )
679+ return 0 ;
680+ if (currLen < 16384 )
681+ return 1 ;
682+ if (currLen < 2097151 )
683+ return 2 ;
684+ return 3 ;
685+ }
686+
671687// as per
672688// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
673689uint16_t Adafruit_MQTT::publishPacket (uint8_t *packet, const char *topic,
674- uint8_t *data, uint16_t bLen,
675- uint8_t qos ) {
690+ uint8_t *data, uint16_t bLen, uint8_t qos,
691+ uint16_t maxPacketLen ) {
676692 uint8_t *p = packet;
677693 uint16_t len = 0 ;
678694
@@ -682,7 +698,22 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
682698 if (qos > 0 ) {
683699 len += 2 ; // qos packet id
684700 }
685- len += bLen; // payload length
701+ // Calculate additional bytes for length field (if any)
702+ uint16_t additionalLen = packetAdditionalLen (len + bLen);
703+
704+ // Payload length. When maxPacketLen provided is 0, let's
705+ // assume buffer is big enough. Fingers crossed.
706+ if (maxPacketLen == 0 || (len + bLen + 2 + additionalLen <= maxPacketLen)) {
707+ len += bLen + additionalLen;
708+ } else {
709+ // If we make it here, we got a pickle: the payload is not going
710+ // to fit in the packet buffer. Instead of corrupting memory, let's
711+ // do something less damaging by reducing the bLen to what we are
712+ // able to accomodate. Alternatively, consider using a bigger
713+ // maxPacketLen.
714+ bLen = maxPacketLen - (len + 2 + packetAdditionalLen (maxPacketLen));
715+ len = maxPacketLen - 4 ;
716+ }
686717
687718 // Now you can start generating the packet!
688719 p[0 ] = MQTT_CTRL_PUBLISH << 4 | qos << 1 ;
0 commit comments