@@ -323,7 +323,8 @@ bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {
323
323
bool Adafruit_MQTT::publish (const char *topic, uint8_t *data, uint16_t bLen,
324
324
uint8_t qos) {
325
325
// 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));
327
328
if (!sendPacket (buffer, len))
328
329
return false ;
329
330
@@ -686,11 +687,26 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
686
687
return len;
687
688
}
688
689
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
+
689
705
// as per
690
706
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
691
707
uint16_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 ) {
694
710
uint8_t *p = packet;
695
711
uint16_t len = 0 ;
696
712
@@ -700,7 +716,22 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
700
716
if (qos > 0 ) {
701
717
len += 2 ; // qos packet id
702
718
}
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
+ }
704
735
705
736
// Now you can start generating the packet!
706
737
p[0 ] = MQTT_CTRL_PUBLISH << 4 | qos << 1 ;
0 commit comments