@@ -96,6 +96,22 @@ static uint8_t *stringprint(uint8_t *p, const char *s, uint16_t maxlen = 0) {
96
96
return p + len;
97
97
}
98
98
99
+ // packetAdditionalLen is a helper function used to figure out
100
+ // how bigger the payload needs to be in order to account for
101
+ // its variable length field. As per
102
+ // http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size
103
+ // See also readFullPacket
104
+ static uint16_t packetAdditionalLen (uint32_t currLen) {
105
+ /* Increase length field based on current length */
106
+ if (currLen < 128 ) // 7-bits
107
+ return 0 ;
108
+ if (currLen < 16384 ) // 14-bits
109
+ return 1 ;
110
+ if (currLen < 2097152 ) // 21-bits
111
+ return 2 ;
112
+ return 3 ;
113
+ }
114
+
99
115
// Adafruit_MQTT Definition ////////////////////////////////////////////////////
100
116
101
117
Adafruit_MQTT::Adafruit_MQTT (const char *server, uint16_t port, const char *cid,
@@ -233,7 +249,7 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
233
249
// will read a packet and Do The Right Thing with length
234
250
uint8_t *pbuff = buffer;
235
251
236
- uint8_t rlen;
252
+ uint16_t rlen;
237
253
238
254
// read the packet type:
239
255
rlen = readPacket (pbuff, 1 , timeout);
@@ -267,7 +283,8 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
267
283
DEBUG_PRINT (F (" Packet Length:\t " ));
268
284
DEBUG_PRINTLN (value);
269
285
270
- if (value > (maxsize - (pbuff - buffer) - 1 )) {
286
+ // maxsize is limited to 65536 by 16-bit unsigned
287
+ if (value > uint32_t (maxsize - (pbuff - buffer) - 1 )) {
271
288
DEBUG_PRINTLN (F (" Packet too big for buffer" ));
272
289
rlen = readPacket (pbuff, (maxsize - (pbuff - buffer) - 1 ), timeout);
273
290
} else {
@@ -492,7 +509,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
492
509
}
493
510
494
511
// Parse out length of packet.
495
- topiclen = buffer[3 ];
512
+ uint16_t const topicoffset = packetAdditionalLen (len);
513
+ uint16_t const topicstart = topicoffset + 4 ;
514
+ topiclen = buffer[3 + topicoffset];
496
515
DEBUG_PRINT (F (" Looking for subscription len " ));
497
516
DEBUG_PRINTLN (topiclen);
498
517
@@ -505,8 +524,8 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
505
524
continue ;
506
525
// Stop if the subscription topic matches the received topic. Be careful
507
526
// to make comparison case insensitive.
508
- if (strncasecmp ((char *)buffer + 4 , subscriptions[i]->topic , topiclen) ==
509
- 0 ) {
527
+ if (strncasecmp ((char *)buffer + topicstart , subscriptions[i]->topic ,
528
+ topiclen) == 0 ) {
510
529
DEBUG_PRINT (F (" Found sub #" ));
511
530
DEBUG_PRINTLN (i);
512
531
break ;
@@ -521,21 +540,21 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
521
540
// Check if it is QoS 1, TODO: we dont support QoS 2
522
541
if ((buffer[0 ] & 0x6 ) == 0x2 ) {
523
542
packet_id_len = 2 ;
524
- packetid = buffer[topiclen + 4 ];
543
+ packetid = buffer[topiclen + topicstart ];
525
544
packetid <<= 8 ;
526
- packetid |= buffer[topiclen + 5 ];
545
+ packetid |= buffer[topiclen + topicstart + 1 ];
527
546
}
528
547
529
548
// zero out the old data
530
549
memset (subscriptions[i]->lastread , 0 , SUBSCRIPTIONDATALEN);
531
550
532
- datalen = len - topiclen - packet_id_len - 4 ;
551
+ datalen = len - topiclen - packet_id_len - topicstart ;
533
552
if (datalen > SUBSCRIPTIONDATALEN) {
534
553
datalen = SUBSCRIPTIONDATALEN - 1 ; // cut it off
535
554
}
536
555
// extract out just the data, into the subscription object itself
537
- memmove (subscriptions[i]->lastread , buffer + 4 + topiclen + packet_id_len,
538
- datalen);
556
+ memmove (subscriptions[i]->lastread ,
557
+ buffer + topicstart + topiclen + packet_id_len, datalen);
539
558
subscriptions[i]->datalen = datalen;
540
559
DEBUG_PRINT (F (" Data len: " ));
541
560
DEBUG_PRINTLN (datalen);
@@ -669,21 +688,6 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
669
688
return len;
670
689
}
671
690
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
-
687
691
// as per
688
692
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
689
693
uint16_t Adafruit_MQTT::publishPacket (uint8_t *packet, const char *topic,
0 commit comments