@@ -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
@@ -668,11 +669,26 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
668
669
return len;
669
670
}
670
671
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
+
671
687
// as per
672
688
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
673
689
uint16_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 ) {
676
692
uint8_t *p = packet;
677
693
uint16_t len = 0 ;
678
694
@@ -682,7 +698,22 @@ uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
682
698
if (qos > 0 ) {
683
699
len += 2 ; // qos packet id
684
700
}
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
+ }
686
717
687
718
// Now you can start generating the packet!
688
719
p[0 ] = MQTT_CTRL_PUBLISH << 4 | qos << 1 ;
0 commit comments