Skip to content

Commit ea2fb46

Browse files
authored
Merge pull request #193 from xdylanm/send_rcv_long_packets
Support publishing and receiving large messages.
2 parents ca12d21 + db003d3 commit ea2fb46

File tree

3 files changed

+33
-28
lines changed

3 files changed

+33
-28
lines changed

Adafruit_MQTT.cpp

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,22 @@ static uint8_t *stringprint(uint8_t *p, const char *s, uint16_t maxlen = 0) {
9696
return p + len;
9797
}
9898

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+
99115
// Adafruit_MQTT Definition ////////////////////////////////////////////////////
100116

101117
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,
233249
// will read a packet and Do The Right Thing with length
234250
uint8_t *pbuff = buffer;
235251

236-
uint8_t rlen;
252+
uint16_t rlen;
237253

238254
// read the packet type:
239255
rlen = readPacket(pbuff, 1, timeout);
@@ -267,7 +283,8 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
267283
DEBUG_PRINT(F("Packet Length:\t"));
268284
DEBUG_PRINTLN(value);
269285

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)) {
271288
DEBUG_PRINTLN(F("Packet too big for buffer"));
272289
rlen = readPacket(pbuff, (maxsize - (pbuff - buffer) - 1), timeout);
273290
} else {
@@ -492,7 +509,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
492509
}
493510

494511
// 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];
496515
DEBUG_PRINT(F("Looking for subscription len "));
497516
DEBUG_PRINTLN(topiclen);
498517

@@ -505,8 +524,8 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
505524
continue;
506525
// Stop if the subscription topic matches the received topic. Be careful
507526
// 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) {
510529
DEBUG_PRINT(F("Found sub #"));
511530
DEBUG_PRINTLN(i);
512531
break;
@@ -521,21 +540,21 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
521540
// Check if it is QoS 1, TODO: we dont support QoS 2
522541
if ((buffer[0] & 0x6) == 0x2) {
523542
packet_id_len = 2;
524-
packetid = buffer[topiclen + 4];
543+
packetid = buffer[topiclen + topicstart];
525544
packetid <<= 8;
526-
packetid |= buffer[topiclen + 5];
545+
packetid |= buffer[topiclen + topicstart + 1];
527546
}
528547

529548
// zero out the old data
530549
memset(subscriptions[i]->lastread, 0, SUBSCRIPTIONDATALEN);
531550

532-
datalen = len - topiclen - packet_id_len - 4;
551+
datalen = len - topiclen - packet_id_len - topicstart;
533552
if (datalen > SUBSCRIPTIONDATALEN) {
534553
datalen = SUBSCRIPTIONDATALEN - 1; // cut it off
535554
}
536555
// 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);
539558
subscriptions[i]->datalen = datalen;
540559
DEBUG_PRINT(F("Data len: "));
541560
DEBUG_PRINTLN(datalen);
@@ -669,21 +688,6 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
669688
return len;
670689
}
671690

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-
687691
// as per
688692
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
689693
uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,

Adafruit_MQTT_Client.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,18 @@ uint16_t Adafruit_MQTT_Client::readPacket(uint8_t *buffer, uint16_t maxlen,
8383

8484
bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint16_t len) {
8585
uint16_t ret = 0;
86-
86+
uint16_t offset = 0;
8787
while (len > 0) {
8888
if (client->connected()) {
8989
// send 250 bytes at most at a time, can adjust this later based on Client
9090

9191
uint16_t sendlen = len > 250 ? 250 : len;
9292
// Serial.print("Sending: "); Serial.println(sendlen);
93-
ret = client->write(buffer, sendlen);
93+
ret = client->write(buffer + offset, sendlen);
9494
DEBUG_PRINT(F("Client sendPacket returned: "));
9595
DEBUG_PRINTLN(ret);
9696
len -= ret;
97+
offset += ret;
9798

9899
if (ret != sendlen) {
99100
DEBUG_PRINTLN("Failed to send packet.");

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Adafruit MQTT Library
2-
version=2.2.0
2+
version=2.3.0
33
author=Adafruit
44
maintainer=Adafruit <info@adafruit.com>
55
sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware.

0 commit comments

Comments
 (0)