local libs

This commit is contained in:
proddy
2020-10-06 20:54:02 +02:00
parent 13297334cf
commit 50da856c45
451 changed files with 20629 additions and 37550 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
#ifndef SRC_ASYNCMQTTCLIENT_H_
#define SRC_ASYNCMQTTCLIENT_H_
#include "AsyncMqttClient.hpp"
#endif // SRC_ASYNCMQTTCLIENT_H_

View File

@@ -0,0 +1,174 @@
#pragma once
#include <functional>
#include <vector>
#include "Arduino.h"
#ifdef ESP32
#include <AsyncTCP.h>
#include <freertos/semphr.h>
#elif defined(ESP8266)
#include <ESPAsyncTCP.h>
#else
#error Platform not supported
#endif
#if ASYNC_TCP_SSL_ENABLED
#include <tcp_axtls.h>
#define SHA1_SIZE 20
#endif
#include "AsyncMqttClient/Flags.hpp"
#include "AsyncMqttClient/ParsingInformation.hpp"
#include "AsyncMqttClient/MessageProperties.hpp"
#include "AsyncMqttClient/Helpers.hpp"
#include "AsyncMqttClient/Callbacks.hpp"
#include "AsyncMqttClient/DisconnectReasons.hpp"
#include "AsyncMqttClient/Storage.hpp"
#include "AsyncMqttClient/Packets/Packet.hpp"
#include "AsyncMqttClient/Packets/ConnAckPacket.hpp"
#include "AsyncMqttClient/Packets/PingRespPacket.hpp"
#include "AsyncMqttClient/Packets/SubAckPacket.hpp"
#include "AsyncMqttClient/Packets/UnsubAckPacket.hpp"
#include "AsyncMqttClient/Packets/PublishPacket.hpp"
#include "AsyncMqttClient/Packets/PubRelPacket.hpp"
#include "AsyncMqttClient/Packets/PubAckPacket.hpp"
#include "AsyncMqttClient/Packets/PubRecPacket.hpp"
#include "AsyncMqttClient/Packets/PubCompPacket.hpp"
#if ESP32
#define SEMAPHORE_TAKE(X) \
if (xSemaphoreTake(_xSemaphore, 1000 / portTICK_PERIOD_MS) != pdTRUE) { \
return X; \
} // Waits max 1000ms
#define SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore);
#elif defined(ESP8266)
#define SEMAPHORE_TAKE(X) void()
#define SEMAPHORE_GIVE() void()
#endif
class AsyncMqttClient {
public:
AsyncMqttClient();
~AsyncMqttClient();
AsyncMqttClient & setKeepAlive(uint16_t keepAlive);
AsyncMqttClient & setClientId(const char * clientId);
AsyncMqttClient & setCleanSession(bool cleanSession);
AsyncMqttClient & setMaxTopicLength(uint16_t maxTopicLength);
AsyncMqttClient & setCredentials(const char * username, const char * password = nullptr);
AsyncMqttClient & setWill(const char * topic, uint8_t qos, bool retain, const char * payload = nullptr, size_t length = 0);
AsyncMqttClient & setServer(IPAddress ip, uint16_t port);
AsyncMqttClient & setServer(const char * host, uint16_t port);
#if ASYNC_TCP_SSL_ENABLED
AsyncMqttClient & setSecure(bool secure);
AsyncMqttClient & addServerFingerprint(const uint8_t * fingerprint);
#endif
AsyncMqttClient & onConnect(AsyncMqttClientInternals::OnConnectUserCallback callback);
AsyncMqttClient & onDisconnect(AsyncMqttClientInternals::OnDisconnectUserCallback callback);
AsyncMqttClient & onSubscribe(AsyncMqttClientInternals::OnSubscribeUserCallback callback);
AsyncMqttClient & onUnsubscribe(AsyncMqttClientInternals::OnUnsubscribeUserCallback callback);
AsyncMqttClient & onMessage(AsyncMqttClientInternals::OnMessageUserCallback callback, const char * _userTopic = "#");
AsyncMqttClient & onFilteredMessage(AsyncMqttClientInternals::OnMessageUserCallback callback, const char * _userTopic);
AsyncMqttClient & onPublish(AsyncMqttClientInternals::OnPublishUserCallback callback);
bool connected() const;
void connect();
void disconnect(bool force = false);
uint16_t subscribe(const char * topic, uint8_t qos);
uint16_t subscribe(const char * topic, uint8_t qos, AsyncMqttClientInternals::OnMessageUserCallback callback);
uint16_t unsubscribe(const char * topic);
uint16_t publish(const char * topic, uint8_t qos, bool retain, const char * payload = nullptr, size_t length = 0, bool dup = false, uint16_t message_id = 0);
const char * getClientId();
private:
AsyncClient _client;
bool _connected;
bool _lockMutiConnections;
bool _connectPacketNotEnoughSpace;
bool _disconnectFlagged;
bool _tlsBadFingerprint;
uint32_t _lastClientActivity;
uint32_t _lastServerActivity;
uint32_t _lastPingRequestTime;
char _generatedClientId[18 + 1]; // esp8266-abc123 and esp32-abcdef123456
IPAddress _ip;
const char * _host;
bool _useIp;
#if ASYNC_TCP_SSL_ENABLED
bool _secure;
#endif
uint16_t _port;
uint16_t _keepAlive;
bool _cleanSession;
const char * _clientId;
const char * _username;
const char * _password;
const char * _willTopic;
const char * _willPayload;
uint16_t _willPayloadLength;
uint8_t _willQos;
bool _willRetain;
#if ASYNC_TCP_SSL_ENABLED
std::vector<std::array<uint8_t, SHA1_SIZE>> _secureServerFingerprints;
#endif
std::vector<AsyncMqttClientInternals::OnConnectUserCallback> _onConnectUserCallbacks;
std::vector<AsyncMqttClientInternals::OnDisconnectUserCallback> _onDisconnectUserCallbacks;
std::vector<AsyncMqttClientInternals::OnSubscribeUserCallback> _onSubscribeUserCallbacks;
std::vector<AsyncMqttClientInternals::OnUnsubscribeUserCallback> _onUnsubscribeUserCallbacks;
std::vector<AsyncMqttClientInternals::onFilteredMessageUserCallback> _onMessageUserCallbacks;
std::vector<AsyncMqttClientInternals::OnPublishUserCallback> _onPublishUserCallbacks;
AsyncMqttClientInternals::ParsingInformation _parsingInformation;
AsyncMqttClientInternals::Packet * _currentParsedPacket;
uint8_t _remainingLengthBufferPosition;
char _remainingLengthBuffer[4];
uint16_t _nextPacketId;
std::vector<AsyncMqttClientInternals::PendingPubRel> _pendingPubRels;
std::vector<AsyncMqttClientInternals::PendingAck> _toSendAcks;
#ifdef ESP32
SemaphoreHandle_t _xSemaphore = nullptr;
#endif
void _clear();
void _freeCurrentParsedPacket();
// TCP
void _onConnect(AsyncClient * client);
void _onDisconnect(AsyncClient * client);
static void _onError(AsyncClient * client, int8_t error);
void _onTimeout(AsyncClient * client, uint32_t time);
static void _onAck(AsyncClient * client, size_t len, uint32_t time);
void _onData(AsyncClient * client, char * data, size_t len);
void _onPoll(AsyncClient * client);
// MQTT
void _onPingResp();
void _onConnAck(bool sessionPresent, uint8_t connectReturnCode);
void _onSubAck(uint16_t packetId, char status);
void _onUnsubAck(uint16_t packetId);
void _onMessage(char * topic, char * payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId);
void _onPublish(uint16_t packetId, uint8_t qos);
void _onPubRel(uint16_t packetId);
void _onPubAck(uint16_t packetId);
void _onPubRec(uint16_t packetId);
void _onPubComp(uint16_t packetId);
bool _sendPing();
void _sendAcks();
bool _sendDisconnect();
uint16_t _getNextPacketId();
};

View File

@@ -0,0 +1,30 @@
#pragma once
#include <functional>
#include "DisconnectReasons.hpp"
#include "MessageProperties.hpp"
namespace AsyncMqttClientInternals {
// user callbacks
typedef std::function<void(bool sessionPresent)> OnConnectUserCallback;
typedef std::function<void(AsyncMqttClientDisconnectReason reason)> OnDisconnectUserCallback;
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;
// internal callbacks
typedef std::function<void(bool sessionPresent, uint8_t connectReturnCode)> OnConnAckInternalCallback;
typedef std::function<void()> OnPingRespInternalCallback;
typedef std::function<void(uint16_t packetId, char status)> OnSubAckInternalCallback;
typedef std::function<void(uint16_t packetId)> OnUnsubAckInternalCallback;
typedef std::function<void(char* topic, char* payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId)> OnMessageInternalCallback;
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnPublishInternalCallback;
typedef std::function<void(uint16_t packetId)> OnPubRelInternalCallback;
typedef std::function<void(uint16_t packetId)> OnPubAckInternalCallback;
typedef std::function<void(uint16_t packetId)> OnPubRecInternalCallback;
typedef std::function<void(uint16_t packetId)> OnPubCompInternalCallback;
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,15 @@
#pragma once
enum class AsyncMqttClientDisconnectReason : int8_t {
TCP_DISCONNECTED = 0,
MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 1,
MQTT_IDENTIFIER_REJECTED = 2,
MQTT_SERVER_UNAVAILABLE = 3,
MQTT_MALFORMED_CREDENTIALS = 4,
MQTT_NOT_AUTHORIZED = 5,
ESP8266_NOT_ENOUGH_SPACE = 6,
TLS_BAD_FINGERPRINT = 7
};

View File

@@ -0,0 +1,57 @@
#pragma once
namespace AsyncMqttClientInternals {
constexpr struct {
const uint8_t RESERVED = 0;
const uint8_t CONNECT = 1;
const uint8_t CONNACK = 2;
const uint8_t PUBLISH = 3;
const uint8_t PUBACK = 4;
const uint8_t PUBREC = 5;
const uint8_t PUBREL = 6;
const uint8_t PUBCOMP = 7;
const uint8_t SUBSCRIBE = 8;
const uint8_t SUBACK = 9;
const uint8_t UNSUBSCRIBE = 10;
const uint8_t UNSUBACK = 11;
const uint8_t PINGREQ = 12;
const uint8_t PINGRESP = 13;
const uint8_t DISCONNECT = 14;
const uint8_t RESERVED2 = 1;
} PacketType;
constexpr struct {
const uint8_t CONNECT_RESERVED = 0x00;
const uint8_t CONNACK_RESERVED = 0x00;
const uint8_t PUBLISH_DUP = 0x08;
const uint8_t PUBLISH_QOS0 = 0x00;
const uint8_t PUBLISH_QOS1 = 0x02;
const uint8_t PUBLISH_QOS2 = 0x04;
const uint8_t PUBLISH_QOSRESERVED = 0x06;
const uint8_t PUBLISH_RETAIN = 0x01;
const uint8_t PUBACK_RESERVED = 0x00;
const uint8_t PUBREC_RESERVED = 0x00;
const uint8_t PUBREL_RESERVED = 0x02;
const uint8_t PUBCOMP_RESERVED = 0x00;
const uint8_t SUBSCRIBE_RESERVED = 0x02;
const uint8_t SUBACK_RESERVED = 0x00;
const uint8_t UNSUBSCRIBE_RESERVED = 0x02;
const uint8_t UNSUBACK_RESERVED = 0x00;
const uint8_t PINGREQ_RESERVED = 0x00;
const uint8_t PINGRESP_RESERVED = 0x00;
const uint8_t DISCONNECT_RESERVED = 0x00;
const uint8_t RESERVED2_RESERVED = 0x00;
} HeaderFlag;
constexpr struct {
const uint8_t USERNAME = 0x80;
const uint8_t PASSWORD = 0x40;
const uint8_t WILL_RETAIN = 0x20;
const uint8_t WILL_QOS0 = 0x00;
const uint8_t WILL_QOS1 = 0x08;
const uint8_t WILL_QOS2 = 0x10;
const uint8_t WILL = 0x04;
const uint8_t CLEAN_SESSION = 0x02;
const uint8_t RESERVED = 0x00;
} ConnectFlag;
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,38 @@
#pragma once
namespace AsyncMqttClientInternals {
class Helpers {
public:
static uint32_t decodeRemainingLength(char* bytes) {
uint32_t multiplier = 1;
uint32_t value = 0;
uint8_t currentByte = 0;
uint8_t encodedByte;
do {
encodedByte = bytes[currentByte++];
value += (encodedByte & 127) * multiplier;
multiplier *= 128;
} while ((encodedByte & 128) != 0);
return value;
}
static uint8_t encodeRemainingLength(uint32_t remainingLength, char* destination) {
uint8_t currentByte = 0;
uint8_t bytesNeeded = 0;
do {
uint8_t encodedByte = remainingLength % 128;
remainingLength /= 128;
if (remainingLength > 0) {
encodedByte = encodedByte | 128;
}
destination[currentByte++] = encodedByte;
bytesNeeded++;
} while (remainingLength > 0);
return bytesNeeded;
}
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,7 @@
#pragma once
struct AsyncMqttClientMessageProperties {
uint8_t qos;
bool dup;
bool retain;
};

View File

@@ -0,0 +1,30 @@
#include "ConnAckPacket.hpp"
using AsyncMqttClientInternals::ConnAckPacket;
ConnAckPacket::ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _sessionPresent(false)
, _connectReturnCode(0) {
}
ConnAckPacket::~ConnAckPacket() {
}
void ConnAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_sessionPresent = (currentByte << 7) >> 7;
} else {
_connectReturnCode = currentByte;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_sessionPresent, _connectReturnCode);
}
}
void ConnAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class ConnAckPacket : public Packet {
public:
explicit ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback);
~ConnAckPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnConnAckInternalCallback _callback;
uint8_t _bytePosition;
bool _sessionPresent;
uint8_t _connectReturnCode;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,11 @@
#pragma once
namespace AsyncMqttClientInternals {
class Packet {
public:
virtual ~Packet() {}
virtual void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) = 0;
virtual void parsePayload(char* data, size_t len, size_t* currentBytePosition) = 0;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,21 @@
#include "PingRespPacket.hpp"
using AsyncMqttClientInternals::PingRespPacket;
PingRespPacket::PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback) {
}
PingRespPacket::~PingRespPacket() {
}
void PingRespPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}
void PingRespPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PingRespPacket : public Packet {
public:
explicit PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback);
~PingRespPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnPingRespInternalCallback _callback;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,30 @@
#include "PubAckPacket.hpp"
using AsyncMqttClientInternals::PubAckPacket;
PubAckPacket::PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
PubAckPacket::~PubAckPacket() {
}
void PubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId);
}
}
void PubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PubAckPacket : public Packet {
public:
explicit PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback);
~PubAckPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnPubAckInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,30 @@
#include "PubCompPacket.hpp"
using AsyncMqttClientInternals::PubCompPacket;
PubCompPacket::PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
PubCompPacket::~PubCompPacket() {
}
void PubCompPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId);
}
}
void PubCompPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PubCompPacket : public Packet {
public:
explicit PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback);
~PubCompPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnPubCompInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,30 @@
#include "PubRecPacket.hpp"
using AsyncMqttClientInternals::PubRecPacket;
PubRecPacket::PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
PubRecPacket::~PubRecPacket() {
}
void PubRecPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId);
}
}
void PubRecPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PubRecPacket : public Packet {
public:
explicit PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback);
~PubRecPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnPubRecInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,30 @@
#include "PubRelPacket.hpp"
using AsyncMqttClientInternals::PubRelPacket;
PubRelPacket::PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
PubRelPacket::~PubRelPacket() {
}
void PubRelPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId);
}
}
void PubRelPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PubRelPacket : public Packet {
public:
explicit PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback);
~PubRelPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnPubRelInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,114 @@
#include "PublishPacket.hpp"
using AsyncMqttClientInternals::PublishPacket;
PublishPacket::PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback)
: _parsingInformation(parsingInformation)
, _dataCallback(dataCallback)
, _completeCallback(completeCallback)
, _dup(false)
, _qos(0)
, _retain(0)
, _bytePosition(0)
, _topicLengthMsb(0)
, _topicLength(0)
, _ignore(false)
, _packetIdMsb(0)
, _packetId(0)
, _payloadLength(0)
, _payloadBytesRead(0)
, _ptempbuff(0) {
_dup = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_DUP;
_retain = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_RETAIN;
char qosMasked = _parsingInformation->packetFlags & 0x06;
switch (qosMasked) {
case HeaderFlag.PUBLISH_QOS0:
_qos = 0;
break;
case HeaderFlag.PUBLISH_QOS1:
_qos = 1;
break;
case HeaderFlag.PUBLISH_QOS2:
_qos = 2;
break;
}
}
PublishPacket::~PublishPacket() {
}
void PublishPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition == 0) {
_topicLengthMsb = currentByte;
} else if (_bytePosition == 1) {
_topicLength = currentByte | _topicLengthMsb << 8;
if (_topicLength > _parsingInformation->maxTopicLength) {
_ignore = true;
} else {
_parsingInformation->topicBuffer[_topicLength] = '\0';
}
} else if (_bytePosition >= 2 && _bytePosition < 2 + _topicLength) {
// Starting from here, _ignore might be true
if (!_ignore) _parsingInformation->topicBuffer[_bytePosition - 2] = currentByte;
if (_bytePosition == 2 + _topicLength - 1 && _qos == 0) {
_preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1));
return;
}
} else if (_bytePosition == 2 + _topicLength) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1));
}
_bytePosition++;
}
void PublishPacket::_preparePayloadHandling(uint32_t payloadLength) {
_payloadLength = payloadLength;
if (payloadLength == 0) {
_parsingInformation->bufferState = BufferState::NONE;
if (!_ignore) {
_dataCallback(_parsingInformation->topicBuffer, nullptr, _qos, _dup, _retain, 0, 0, 0, _packetId);
_completeCallback(_packetId, _qos);
}
} else {
_parsingInformation->bufferState = BufferState::PAYLOAD;
}
}
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);
}
}
_payloadBytesRead += remainToRead;
(*currentBytePosition) += remainToRead;
if (_payloadBytesRead == _payloadLength) {
_parsingInformation->bufferState = BufferState::NONE;
if (!_ignore)
_completeCallback(_packetId, _qos);
}
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../Flags.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class PublishPacket : public Packet {
public:
explicit PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback);
~PublishPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnMessageInternalCallback _dataCallback;
OnPublishInternalCallback _completeCallback;
void _preparePayloadHandling(uint32_t payloadLength);
bool _dup;
uint8_t _qos;
bool _retain;
uint8_t _bytePosition;
char _topicLengthMsb;
uint16_t _topicLength;
bool _ignore;
char _packetIdMsb;
uint16_t _packetId;
uint32_t _payloadLength;
uint32_t _payloadBytesRead;
char* _ptempbuff;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,46 @@
#include "SubAckPacket.hpp"
using AsyncMqttClientInternals::SubAckPacket;
SubAckPacket::SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
SubAckPacket::~SubAckPacket() {
}
void SubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::PAYLOAD;
}
}
void SubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
char status = data[(*currentBytePosition)++];
/* switch (status) {
case 0:
Serial.println("Success QoS 0");
break;
case 1:
Serial.println("Success QoS 1");
break;
case 2:
Serial.println("Success QoS 2");
break;
case 0x80:
Serial.println("Failure");
break;
} */
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId, status);
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class SubAckPacket : public Packet {
public:
explicit SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback);
~SubAckPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnSubAckInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,30 @@
#include "UnsubAckPacket.hpp"
using AsyncMqttClientInternals::UnsubAckPacket;
UnsubAckPacket::UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback)
: _parsingInformation(parsingInformation)
, _callback(callback)
, _bytePosition(0)
, _packetIdMsb(0)
, _packetId(0) {
}
UnsubAckPacket::~UnsubAckPacket() {
}
void UnsubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
char currentByte = data[(*currentBytePosition)++];
if (_bytePosition++ == 0) {
_packetIdMsb = currentByte;
} else {
_packetId = currentByte | _packetIdMsb << 8;
_parsingInformation->bufferState = BufferState::NONE;
_callback(_packetId);
}
}
void UnsubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
(void)data;
(void)currentBytePosition;
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "Arduino.h"
#include "Packet.hpp"
#include "../ParsingInformation.hpp"
#include "../Callbacks.hpp"
namespace AsyncMqttClientInternals {
class UnsubAckPacket : public Packet {
public:
explicit UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback);
~UnsubAckPacket();
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
private:
ParsingInformation* _parsingInformation;
OnUnsubAckInternalCallback _callback;
uint8_t _bytePosition;
char _packetIdMsb;
uint16_t _packetId;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,21 @@
#pragma once
namespace AsyncMqttClientInternals {
enum class BufferState : uint8_t {
NONE = 0,
REMAINING_LENGTH = 2,
VARIABLE_HEADER = 3,
PAYLOAD = 4
};
struct ParsingInformation {
BufferState bufferState;
uint16_t maxTopicLength;
char* topicBuffer;
uint8_t packetType;
uint16_t packetFlags;
uint32_t remainingLength;
};
} // namespace AsyncMqttClientInternals

View File

@@ -0,0 +1,13 @@
#pragma once
namespace AsyncMqttClientInternals {
struct PendingPubRel {
uint16_t packetId;
};
struct PendingAck {
uint8_t packetType;
uint8_t headerFlag;
uint16_t packetId;
};
} // namespace AsyncMqttClientInternals