experimental mqtt client supporting large packets

This commit is contained in:
proddy
2021-02-27 14:45:51 +01:00
parent 333c5c16c0
commit ce45374b54
28 changed files with 1358 additions and 1046 deletions

View File

@@ -4,6 +4,7 @@
#include "DisconnectReasons.hpp"
#include "MessageProperties.hpp"
#include "Errors.hpp"
namespace AsyncMqttClientInternals {
// user callbacks
@@ -12,9 +13,8 @@ typedef std::function<void(AsyncMqttClientDisconnectReason reason)> OnDisconnect
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnSubscribeUserCallback;
typedef std::function<void(uint16_t packetId)> OnUnsubscribeUserCallback;
typedef std::function<void(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)> OnMessageUserCallback;
// typedef std::pair<std::string, std::function<void(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)>> onFilteredMessageUserCallback;
typedef std::pair<char*, std::function<void(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)>> onFilteredMessageUserCallback;
typedef std::function<void(uint16_t packetId)> OnPublishUserCallback;
typedef std::function<void(uint16_t packetId, AsyncMqttClientError error)> OnErrorUserCallback;
// internal callbacks
typedef std::function<void(bool sessionPresent, uint8_t connectReturnCode)> OnConnAckInternalCallback;

View File

@@ -0,0 +1,6 @@
#pragma once
enum class AsyncMqttClientError : uint8_t {
MAX_RETRIES = 0,
OUT_OF_MEMORY = 1
};

View File

@@ -35,4 +35,27 @@ class Helpers {
return bytesNeeded;
}
};
#if defined(ARDUINO_ARCH_ESP32)
#define SEMAPHORE_TAKE() xSemaphoreTake(_xSemaphore, portMAX_DELAY)
#define SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
#define GET_FREE_MEMORY() ESP.getMaxAllocHeap()
#include <esp32-hal-log.h>
#elif defined(ARDUINO_ARCH_ESP8266)
#define SEMAPHORE_TAKE(X) while (_xSemaphore) { /*ESP.wdtFeed();*/ } _xSemaphore = true
#define SEMAPHORE_GIVE() _xSemaphore = false
#define GET_FREE_MEMORY() ESP.getMaxFreeBlockSize()
#if defined(DEBUG_ESP_PORT) && defined(DEBUG_ASYNC_MQTT_CLIENT)
#define log_i(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n")
#define log_e(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n")
#define log_w(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n")
#else
#define log_i(...)
#define log_e(...)
#define log_w(...)
#endif
#else
#pragma error "No valid architecture"
#endif
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,162 @@
#include "Connect.hpp"
using AsyncMqttClientInternals::ConnectOutPacket;
ConnectOutPacket::ConnectOutPacket(bool cleanSession,
const char* username,
const char* password,
const char* willTopic,
bool willRetain,
uint8_t willQos,
const char* willPayload,
uint16_t willPayloadLength,
uint16_t keepAlive,
const char* clientId) {
char fixedHeader[5];
fixedHeader[0] = AsyncMqttClientInternals::PacketType.CONNECT;
fixedHeader[0] = fixedHeader[0] << 4;
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.CONNECT_RESERVED;
uint16_t protocolNameLength = 4;
char protocolNameLengthBytes[2];
protocolNameLengthBytes[0] = protocolNameLength >> 8;
protocolNameLengthBytes[1] = protocolNameLength & 0xFF;
char protocolLevel[1];
protocolLevel[0] = 0x04;
char connectFlags[1];
connectFlags[0] = 0;
if (cleanSession) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.CLEAN_SESSION;
if (username != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.USERNAME;
if (password != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.PASSWORD;
if (willTopic != nullptr) {
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL;
if (willRetain) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_RETAIN;
switch (willQos) {
case 0:
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS0;
break;
case 1:
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS1;
break;
case 2:
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS2;
break;
}
}
char keepAliveBytes[2];
keepAliveBytes[0] = keepAlive >> 8;
keepAliveBytes[1] = keepAlive & 0xFF;
uint16_t clientIdLength = strlen(clientId);
char clientIdLengthBytes[2];
clientIdLengthBytes[0] = clientIdLength >> 8;
clientIdLengthBytes[1] = clientIdLength & 0xFF;
// Optional fields
uint16_t willTopicLength = 0;
char willTopicLengthBytes[2];
char willPayloadLengthBytes[2];
if (willTopic != nullptr) {
willTopicLength = strlen(willTopic);
willTopicLengthBytes[0] = willTopicLength >> 8;
willTopicLengthBytes[1] = willTopicLength & 0xFF;
if (willPayload != nullptr && willPayloadLength == 0) willPayloadLength = strlen(willPayload);
willPayloadLengthBytes[0] = willPayloadLength >> 8;
willPayloadLengthBytes[1] = willPayloadLength & 0xFF;
}
uint16_t usernameLength = 0;
char usernameLengthBytes[2];
if (username != nullptr) {
usernameLength = strlen(username);
usernameLengthBytes[0] = usernameLength >> 8;
usernameLengthBytes[1] = usernameLength & 0xFF;
}
uint16_t passwordLength = 0;
char passwordLengthBytes[2];
if (password != nullptr) {
passwordLength = strlen(password);
passwordLengthBytes[0] = passwordLength >> 8;
passwordLengthBytes[1] = passwordLength & 0xFF;
}
uint32_t remainingLength = 2 + protocolNameLength + 1 + 1 + 2 + 2 + clientIdLength; // always present
if (willTopic != nullptr) remainingLength += 2 + willTopicLength + 2 + willPayloadLength;
if (username != nullptr) remainingLength += 2 + usernameLength;
if (password != nullptr) remainingLength += 2 + passwordLength;
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1);
uint32_t neededSpace = 1 + remainingLengthLength;
neededSpace += 2;
neededSpace += protocolNameLength;
neededSpace += 1;
neededSpace += 1;
neededSpace += 2;
neededSpace += 2;
neededSpace += clientIdLength;
if (willTopic != nullptr) {
neededSpace += 2;
neededSpace += willTopicLength;
neededSpace += 2;
if (willPayload != nullptr) neededSpace += willPayloadLength;
}
if (username != nullptr) {
neededSpace += 2;
neededSpace += usernameLength;
}
if (password != nullptr) {
neededSpace += 2;
neededSpace += passwordLength;
}
_data.reserve(neededSpace);
_data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength);
_data.push_back(protocolNameLengthBytes[0]);
_data.push_back(protocolNameLengthBytes[1]);
_data.push_back('M');
_data.push_back('Q');
_data.push_back('T');
_data.push_back('T');
_data.push_back(protocolLevel[0]);
_data.push_back(connectFlags[0]);
_data.push_back(keepAliveBytes[0]);
_data.push_back(keepAliveBytes[1]);
_data.push_back(clientIdLengthBytes[0]);
_data.push_back(clientIdLengthBytes[1]);
_data.insert(_data.end(), clientId, clientId + clientIdLength);
if (willTopic != nullptr) {
_data.insert(_data.end(), willTopicLengthBytes, willTopicLengthBytes + 2);
_data.insert(_data.end(), willTopic, willTopic + willTopicLength);
_data.insert(_data.end(), willPayloadLengthBytes, willPayloadLengthBytes + 2);
if (willPayload != nullptr) _data.insert(_data.end(), willPayload, willPayload + willPayloadLength);
}
if (username != nullptr) {
_data.insert(_data.end(), usernameLengthBytes, usernameLengthBytes + 2);
_data.insert(_data.end(), username, username + usernameLength);
}
if (password != nullptr) {
_data.insert(_data.end(), passwordLengthBytes, passwordLengthBytes + 2);
_data.insert(_data.end(), password, password + passwordLength);
}
}
const uint8_t* ConnectOutPacket::data(size_t index) const {
return &_data.data()[index];
}
size_t ConnectOutPacket::size() const {
return _data.size();
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <vector>
#include <cstring> // strlen
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
namespace AsyncMqttClientInternals {
class ConnectOutPacket : public OutPacket {
public:
ConnectOutPacket(bool cleanSession,
const char* username,
const char* password,
const char* willTopic,
bool willRetain,
uint8_t willQos,
const char* willPayload,
uint16_t willPayloadLength,
uint16_t keepAlive,
const char* clientId);
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
std::vector<uint8_t> _data;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,18 @@
#include "Disconn.hpp"
using AsyncMqttClientInternals::DisconnOutPacket;
DisconnOutPacket::DisconnOutPacket() {
_data[0] = AsyncMqttClientInternals::PacketType.DISCONNECT;
_data[0] = _data[0] << 4;
_data[0] = _data[0] | AsyncMqttClientInternals::HeaderFlag.DISCONNECT_RESERVED;
_data[1] = 0;
}
const uint8_t* DisconnOutPacket::data(size_t index) const {
return &_data[index];
}
size_t DisconnOutPacket::size() const {
return 2;
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
namespace AsyncMqttClientInternals {
class DisconnOutPacket : public OutPacket {
public:
DisconnOutPacket();
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
uint8_t _data[2];
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,44 @@
#include "OutPacket.hpp"
using AsyncMqttClientInternals::OutPacket;
OutPacket::OutPacket()
: next(nullptr)
, timeout(0)
, noTries(0)
, _released(true)
, _packetId(0) {}
OutPacket::~OutPacket() {}
bool OutPacket::released() const {
return _released;
}
uint8_t OutPacket::packetType() const {
return data(0)[0] >> 4;
}
uint16_t OutPacket::packetId() const {
return _packetId;
}
uint8_t OutPacket::qos() const {
if (packetType() == AsyncMqttClientInternals::PacketType.PUBLISH) {
return (data()[1] & 0x06) >> 1;
}
return 0;
}
void OutPacket::release() {
_released = true;
}
uint16_t OutPacket::_nextPacketId = 0;
uint16_t OutPacket::_getNextPacketId() {
if (++_nextPacketId == 0) {
++_nextPacketId;
}
return _nextPacketId;
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <stdint.h> // uint*_t
#include <stddef.h> // size_t
#include <algorithm> // std::min
#include "../../Flags.hpp"
namespace AsyncMqttClientInternals {
class OutPacket {
public:
OutPacket();
virtual ~OutPacket();
virtual const uint8_t* data(size_t index = 0) const = 0;
virtual size_t size() const = 0;
bool released() const;
uint8_t packetType() const;
uint16_t packetId() const;
uint8_t qos() const;
void release();
public:
OutPacket* next;
uint32_t timeout;
uint8_t noTries;
protected:
static uint16_t _getNextPacketId();
bool _released;
uint16_t _packetId;
private:
static uint16_t _nextPacketId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,18 @@
#include "PingReq.hpp"
using AsyncMqttClientInternals::PingReqOutPacket;
PingReqOutPacket::PingReqOutPacket() {
_data[0] = AsyncMqttClientInternals::PacketType.PINGREQ;
_data[0] = _data[0] << 4;
_data[0] = _data[0] | AsyncMqttClientInternals::HeaderFlag.PINGREQ_RESERVED;
_data[1] = 0;
}
const uint8_t* PingReqOutPacket::data(size_t index) const {
return &_data[index];;
}
size_t PingReqOutPacket::size() const {
return 2;
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
namespace AsyncMqttClientInternals {
class PingReqOutPacket : public OutPacket {
public:
PingReqOutPacket();
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
uint8_t _data[2];
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,26 @@
#include "PubAck.hpp"
using AsyncMqttClientInternals::PubAckOutPacket;
PubAckOutPacket::PubAckOutPacket(PendingAck pendingAck) {
_data[0] = pendingAck.packetType;
_data[0] = _data[0] << 4;
_data[0] = _data[0] | pendingAck.headerFlag;
_data[1] = 2;
_packetId = pendingAck.packetId;
_data[2] = pendingAck.packetId >> 8;
_data[3] = pendingAck.packetId & 0xFF;
_released = false;
if (packetType() == AsyncMqttClientInternals::PacketType.PUBREL ||
packetType() == AsyncMqttClientInternals::PacketType.PUBREC) {
_released = false;
}
}
const uint8_t* PubAckOutPacket::data(size_t index) const {
return &_data[index];
}
size_t PubAckOutPacket::size() const {
return 4;
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
#include "../../Storage.hpp"
namespace AsyncMqttClientInternals {
class PubAckOutPacket : public OutPacket {
public:
explicit PubAckOutPacket(PendingAck pendingAck);
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
uint8_t _data[4];
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,69 @@
#include "Publish.hpp"
using AsyncMqttClientInternals::PublishOutPacket;
PublishOutPacket::PublishOutPacket(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length) {
char fixedHeader[5];
fixedHeader[0] = AsyncMqttClientInternals::PacketType.PUBLISH;
fixedHeader[0] = fixedHeader[0] << 4;
// if (dup) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_DUP;
if (retain) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_RETAIN;
switch (qos) {
case 0:
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS0;
break;
case 1:
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS1;
break;
case 2:
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS2;
break;
}
uint16_t topicLength = strlen(topic);
char topicLengthBytes[2];
topicLengthBytes[0] = topicLength >> 8;
topicLengthBytes[1] = topicLength & 0xFF;
uint32_t payloadLength = length;
if (payload != nullptr && payloadLength == 0) payloadLength = strlen(payload);
uint32_t remainingLength = 2 + topicLength + payloadLength;
if (qos != 0) remainingLength += 2;
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1);
size_t neededSpace = 0;
neededSpace += 1 + remainingLengthLength;
neededSpace += 2;
neededSpace += topicLength;
if (qos != 0) neededSpace += 2;
if (payload != nullptr) neededSpace += payloadLength;
_data.reserve(neededSpace);
_packetId = (qos !=0) ? _getNextPacketId() : 1;
char packetIdBytes[2];
packetIdBytes[0] = _packetId >> 8;
packetIdBytes[1] = _packetId & 0xFF;
_data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength);
_data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2);
_data.insert(_data.end(), topic, topic + topicLength);
if (qos != 0) {
_data.insert(_data.end(), packetIdBytes, packetIdBytes + 2);
_released = false;
}
if (payload != nullptr) _data.insert(_data.end(), payload, payload + payloadLength);
}
const uint8_t* PublishOutPacket::data(size_t index) const {
return &_data.data()[index];
}
size_t PublishOutPacket::size() const {
return _data.size();
}
void PublishOutPacket::setDup() {
_data[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_DUP;
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <cstring> // strlen
#include <vector>
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
#include "../../Storage.hpp"
namespace AsyncMqttClientInternals {
class PublishOutPacket : public OutPacket {
public:
PublishOutPacket(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length);
const uint8_t* data(size_t index = 0) const;
size_t size() const;
void setDup(); // you cannot unset dup
private:
std::vector<uint8_t> _data;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,49 @@
#include "Subscribe.hpp"
using AsyncMqttClientInternals::SubscribeOutPacket;
SubscribeOutPacket::SubscribeOutPacket(const char* topic, uint8_t qos) {
char fixedHeader[5];
fixedHeader[0] = AsyncMqttClientInternals::PacketType.SUBSCRIBE;
fixedHeader[0] = fixedHeader[0] << 4;
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.SUBSCRIBE_RESERVED;
uint16_t topicLength = strlen(topic);
char topicLengthBytes[2];
topicLengthBytes[0] = topicLength >> 8;
topicLengthBytes[1] = topicLength & 0xFF;
char qosByte[1];
qosByte[0] = qos;
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength + 1, fixedHeader + 1);
size_t neededSpace = 0;
neededSpace += 1 + remainingLengthLength;
neededSpace += 2;
neededSpace += 2;
neededSpace += topicLength;
neededSpace += 1;
_data.reserve(neededSpace);
_packetId = _getNextPacketId();
char packetIdBytes[2];
packetIdBytes[0] = _packetId >> 8;
packetIdBytes[1] = _packetId & 0xFF;
_data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength);
_data.insert(_data.end(), packetIdBytes, packetIdBytes + 2);
_data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2);
_data.insert(_data.end(), topic, topic + topicLength);
_data.push_back(qosByte[0]);
_released = false;
}
const uint8_t* SubscribeOutPacket::data(size_t index) const {
return &_data.data()[index];
}
size_t SubscribeOutPacket::size() const {
return _data.size();
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <cstring> // strlen
#include <vector>
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
#include "../../Storage.hpp"
namespace AsyncMqttClientInternals {
class SubscribeOutPacket : public OutPacket {
public:
SubscribeOutPacket(const char* topic, uint8_t qos);
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
std::vector<uint8_t> _data;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,42 @@
#include "Unsubscribe.hpp"
using AsyncMqttClientInternals::UnsubscribeOutPacket;
UnsubscribeOutPacket::UnsubscribeOutPacket(const char* topic) {
char fixedHeader[5];
fixedHeader[0] = AsyncMqttClientInternals::PacketType.UNSUBSCRIBE;
fixedHeader[0] = fixedHeader[0] << 4;
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.UNSUBSCRIBE_RESERVED;
uint16_t topicLength = strlen(topic);
char topicLengthBytes[2];
topicLengthBytes[0] = topicLength >> 8;
topicLengthBytes[1] = topicLength & 0xFF;
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength, fixedHeader + 1);
size_t neededSpace = 0;
neededSpace += 1 + remainingLengthLength;
neededSpace += 2;
neededSpace += 2;
neededSpace += topicLength;
_packetId = _getNextPacketId();
char packetIdBytes[2];
packetIdBytes[0] = _packetId >> 8;
packetIdBytes[1] = _packetId & 0xFF;
_data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength);
_data.insert(_data.end(), packetIdBytes, packetIdBytes + 2);
_data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2);
_data.insert(_data.end(), topic, topic + topicLength);
_released = false;
}
const uint8_t* UnsubscribeOutPacket::data(size_t index) const {
return &_data.data()[index];
}
size_t UnsubscribeOutPacket::size() const {
return _data.size();
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <cstring> // strlen
#include <vector>
#include "OutPacket.hpp"
#include "../../Flags.hpp"
#include "../../Helpers.hpp"
#include "../../Storage.hpp"
namespace AsyncMqttClientInternals {
class UnsubscribeOutPacket : public OutPacket {
public:
explicit UnsubscribeOutPacket(const char* topic);
const uint8_t* data(size_t index = 0) const;
size_t size() const;
private:
std::vector<uint8_t> _data;
};
} // namespace AsyncMqttClientInternals

View File

@@ -16,8 +16,7 @@ PublishPacket::PublishPacket(ParsingInformation* parsingInformation, OnMessageIn
, _packetIdMsb(0)
, _packetId(0)
, _payloadLength(0)
, _payloadBytesRead(0)
, _ptempbuff(0) {
, _payloadBytesRead(0) {
_dup = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_DUP;
_retain = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_RETAIN;
char qosMasked = _parsingInformation->packetFlags & 0x06;
@@ -79,36 +78,14 @@ void PublishPacket::_preparePayloadHandling(uint32_t payloadLength) {
void PublishPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
size_t remainToRead = len - (*currentBytePosition);
if (_payloadBytesRead + remainToRead > _payloadLength)
remainToRead = _payloadLength - _payloadBytesRead;
if (!_ignore) {
if (remainToRead < _payloadLength) {
if (!_ptempbuff) {
_ptempbuff = new char[_payloadLength + 1];
if (_ptempbuff == nullptr) {
_ignore = true;
return;
}
memset(_ptempbuff, 0, _payloadLength + 1);
memcpy(&_ptempbuff[_payloadBytesRead], &data[(*currentBytePosition)], remainToRead);
} else {
memcpy(&_ptempbuff[_payloadBytesRead], &data[(*currentBytePosition)], remainToRead);
if ((_payloadBytesRead + remainToRead) == _payloadLength) {
_dataCallback(_parsingInformation->topicBuffer, _ptempbuff, _qos, _dup, _retain, _payloadLength, 0, _payloadLength, _packetId);
delete[] _ptempbuff;
_ptempbuff = NULL;
}
}
} else {
_dataCallback(_parsingInformation->topicBuffer, &data[(*currentBytePosition)], _qos, _dup, _retain, remainToRead, _payloadBytesRead, _payloadLength, _packetId);
}
}
if (_payloadBytesRead + remainToRead > _payloadLength) remainToRead = _payloadLength - _payloadBytesRead;
if (!_ignore) _dataCallback(_parsingInformation->topicBuffer, data + (*currentBytePosition), _qos, _dup, _retain, remainToRead, _payloadBytesRead, _payloadLength, _packetId);
_payloadBytesRead += remainToRead;
(*currentBytePosition) += remainToRead;
if (_payloadBytesRead == _payloadLength) {
_parsingInformation->bufferState = BufferState::NONE;
if (!_ignore)
_completeCallback(_packetId, _qos);
if (!_ignore) _completeCallback(_packetId, _qos);
}
}

View File

@@ -34,6 +34,5 @@ class PublishPacket : public Packet {
uint16_t _packetId;
uint32_t _payloadLength;
uint32_t _payloadBytesRead;
char* _ptempbuff;
};
} // namespace AsyncMqttClientInternals