Skip to content

Commit 2ea8a0b

Browse files
author
xdylanm
committed
Support publishing and receiving large messages. Send multiple 250 byte packets (ref PR#113) for larger messages. Correctly identify topic start position for >127byte messages (ref PR#166). Resolves issue #102
1 parent e8922f6 commit 2ea8a0b

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

Adafruit_MQTT.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
233233
// will read a packet and Do The Right Thing with length
234234
uint8_t *pbuff = buffer;
235235

236-
uint8_t rlen;
236+
uint16_t rlen;
237237

238238
// read the packet type:
239239
rlen = readPacket(pbuff, 1, timeout);
@@ -473,6 +473,22 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) {
473473
return handleSubscriptionPacket(len);
474474
}
475475

476+
namespace {
477+
478+
uint16_t topicOffsetFromLenth(uint16_t const len)
479+
{
480+
if (len < 128) { // 7 bits (+1 continuation bit)
481+
return 0;
482+
} else if (len < 16384) { // 14 bits (+2 continuation bits)
483+
return 1;
484+
} else if (len < 2097152) { // 21 bits
485+
return 2;
486+
}
487+
return 3;
488+
}
489+
490+
} // anon
491+
476492
Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
477493
uint16_t i, topiclen, datalen;
478494

@@ -491,7 +507,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
491507
}
492508

493509
// Parse out length of packet.
494-
topiclen = buffer[3];
510+
uint16_t const topicoffset = topicOffsetFromLength(len);
511+
uint16_t const topicstart = topicoffset + 4;
512+
topiclen = buffer[3+topicoffset];
495513
DEBUG_PRINT(F("Looking for subscription len "));
496514
DEBUG_PRINTLN(topiclen);
497515

@@ -504,7 +522,7 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
504522
continue;
505523
// Stop if the subscription topic matches the received topic. Be careful
506524
// to make comparison case insensitive.
507-
if (strncasecmp((char *)buffer + 4, subscriptions[i]->topic, topiclen) ==
525+
if (strncasecmp((char *)buffer + topicstart, subscriptions[i]->topic, topiclen) ==
508526
0) {
509527
DEBUG_PRINT(F("Found sub #"));
510528
DEBUG_PRINTLN(i);
@@ -520,20 +538,20 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
520538
// Check if it is QoS 1, TODO: we dont support QoS 2
521539
if ((buffer[0] & 0x6) == 0x2) {
522540
packet_id_len = 2;
523-
packetid = buffer[topiclen + 4];
541+
packetid = buffer[topiclen + topicstart];
524542
packetid <<= 8;
525-
packetid |= buffer[topiclen + 5];
543+
packetid |= buffer[topiclen + topicstart + 1];
526544
}
527545

528546
// zero out the old data
529547
memset(subscriptions[i]->lastread, 0, SUBSCRIPTIONDATALEN);
530548

531-
datalen = len - topiclen - packet_id_len - 4;
549+
datalen = len - topiclen - packet_id_len - topicstart;
532550
if (datalen > SUBSCRIPTIONDATALEN) {
533551
datalen = SUBSCRIPTIONDATALEN - 1; // cut it off
534552
}
535553
// extract out just the data, into the subscription object itself
536-
memmove(subscriptions[i]->lastread, buffer + 4 + topiclen + packet_id_len,
554+
memmove(subscriptions[i]->lastread, buffer + topicstart + topiclen + packet_id_len,
537555
datalen);
538556
subscriptions[i]->datalen = datalen;
539557
DEBUG_PRINT(F("Data len: "));

Adafruit_MQTT_Client.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,19 @@ 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-
97+
offset += ret;
98+
9899
if (ret != sendlen) {
99100
DEBUG_PRINTLN("Failed to send packet.");
100101
return false;

0 commit comments

Comments
 (0)