update espMqttclient
This commit is contained in:
@@ -9,7 +9,7 @@ the LICENSE file.
|
||||
#pragma once
|
||||
|
||||
#ifndef EMC_TX_TIMEOUT
|
||||
#define EMC_TX_TIMEOUT 5000
|
||||
#define EMC_TX_TIMEOUT 10000
|
||||
#endif
|
||||
|
||||
#ifndef EMC_RX_BUFFER_SIZE
|
||||
@@ -29,7 +29,7 @@ the LICENSE file.
|
||||
#endif
|
||||
|
||||
#ifndef EMC_MIN_FREE_MEMORY
|
||||
#define EMC_MIN_FREE_MEMORY 4096
|
||||
#define EMC_MIN_FREE_MEMORY 16384
|
||||
#endif
|
||||
|
||||
#ifndef EMC_ESP8266_MULTITHREADING
|
||||
@@ -53,6 +53,10 @@ the LICENSE file.
|
||||
#define EMC_TASK_STACK_SIZE 5120
|
||||
#endif
|
||||
|
||||
#ifndef EMC_MULTIPLE_CALLBACKS
|
||||
#define EMC_MULTIPLE_CALLBACKS 0
|
||||
#endif
|
||||
|
||||
#ifndef EMC_USE_WATCHDOG
|
||||
#define EMC_USE_WATCHDOG 0
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@ the LICENSE file.
|
||||
#define EMC_SEMAPHORE_TAKE() xSemaphoreTake(_xSemaphore, portMAX_DELAY)
|
||||
#define EMC_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
|
||||
#define EMC_GET_FREE_MEMORY() std::max(ESP.getMaxAllocHeap(), ESP.getMaxAllocPsram())
|
||||
#define EMC_YIELD() taskYIELD()
|
||||
#define EMC_YIELD() vTaskDelay(1)
|
||||
#define EMC_GENERATE_CLIENTID(x) snprintf(x, EMC_CLIENTID_LENGTH, "esp32%06llx", ESP.getEfuseMac());
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
#include <Arduino.h> // millis(), ESP.getFreeHeap();
|
||||
|
||||
@@ -10,6 +10,8 @@ the LICENSE file.
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#include <esp32-hal-log.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#if defined(DEBUG_ESP_MQTT_CLIENT)
|
||||
// Logging is en/disabled by Arduino framework macros
|
||||
#define emc_log_i(...) log_i(__VA_ARGS__)
|
||||
|
||||
@@ -14,12 +14,8 @@ using espMqttClientTypes::DisconnectReason;
|
||||
using espMqttClientTypes::Error;
|
||||
|
||||
MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority, uint8_t core)
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
: _useInternalTask(useInternalTask)
|
||||
, _transport(nullptr)
|
||||
#else
|
||||
: _transport(nullptr)
|
||||
#endif
|
||||
, _onConnectCallback(nullptr)
|
||||
, _onDisconnectCallback(nullptr)
|
||||
, _onSubscribeCallback(nullptr)
|
||||
@@ -41,7 +37,7 @@ MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint
|
||||
, _willPayloadLength(0)
|
||||
, _willQos(0)
|
||||
, _willRetain(false)
|
||||
, _timeout(10000)
|
||||
, _timeout(EMC_TX_TIMEOUT)
|
||||
, _state(State::disconnected)
|
||||
, _generatedClientId{0}
|
||||
, _packetId(0)
|
||||
@@ -101,7 +97,7 @@ bool MqttClient::disconnected() const {
|
||||
}
|
||||
|
||||
bool MqttClient::connect() {
|
||||
bool result = true;
|
||||
bool result = false;
|
||||
if (_state == State::disconnected) {
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
if (_addPacketFront(_cleanSession,
|
||||
@@ -114,17 +110,17 @@ bool MqttClient::connect() {
|
||||
_willPayloadLength,
|
||||
(uint16_t)(_keepAlive / 1000), // 32b to 16b doesn't overflow because it comes from 16b orignally
|
||||
_clientId)) {
|
||||
result = true;
|
||||
_setState(State::connectingTcp1);
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (_useInternalTask == espMqttClientTypes::UseInternalTask::YES) {
|
||||
vTaskResume(_taskHandle);
|
||||
}
|
||||
#endif
|
||||
_state = State::connectingTcp1;
|
||||
} else {
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
emc_log_e("Could not create CONNECT packet");
|
||||
_onError(0, Error::OUT_OF_MEMORY);
|
||||
result = false;
|
||||
}
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
}
|
||||
@@ -133,11 +129,11 @@ bool MqttClient::connect() {
|
||||
|
||||
bool MqttClient::disconnect(bool force) {
|
||||
if (force && _state != State::disconnected && _state != State::disconnectingTcp1 && _state != State::disconnectingTcp2) {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
return true;
|
||||
}
|
||||
if (!force && _state == State::connected) {
|
||||
_state = State::disconnectingMqtt1;
|
||||
_setState(State::disconnectingMqtt1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -151,8 +147,8 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, const
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||
if (!_addPacket(packetId, topic, payload, length, qos, retain)) {
|
||||
emc_log_e("Could not create PUBLISH packet");
|
||||
_onError(packetId, Error::OUT_OF_MEMORY);
|
||||
@@ -175,8 +171,8 @@ uint16_t MqttClient::publish(const char* topic, uint8_t qos, bool retain, espMqt
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
uint16_t packetId = (qos > 0) ? _getNextPacketId() : 1;
|
||||
if (!_addPacket(packetId, topic, callback, length, qos, retain)) {
|
||||
emc_log_e("Could not create PUBLISH packet");
|
||||
_onError(packetId, Error::OUT_OF_MEMORY);
|
||||
@@ -194,6 +190,14 @@ const char* MqttClient::getClientId() const {
|
||||
return _clientId;
|
||||
}
|
||||
|
||||
size_t MqttClient::queueSize() {
|
||||
size_t ret = 0;
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
ret = _outbox.size();
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MqttClient::loop() {
|
||||
switch (_state) {
|
||||
case State::disconnected:
|
||||
@@ -205,9 +209,9 @@ void MqttClient::loop() {
|
||||
break;
|
||||
case State::connectingTcp1:
|
||||
if (_useIp ? _transport->connect(_ip, _port) : _transport->connect(_host, _port)) {
|
||||
_state = State::connectingTcp2;
|
||||
_setState(State::connectingTcp2);
|
||||
} else {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::TCP_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
@@ -217,7 +221,7 @@ void MqttClient::loop() {
|
||||
if (_transport->connected()) {
|
||||
_parser.reset();
|
||||
_lastClientActivity = _lastServerActivity = millis();
|
||||
_state = State::connectingMqtt;
|
||||
_setState(State::connectingMqtt);
|
||||
}
|
||||
break;
|
||||
case State::connectingMqtt:
|
||||
@@ -227,7 +231,7 @@ void MqttClient::loop() {
|
||||
_checkIncoming();
|
||||
_checkPing();
|
||||
} else {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::TCP_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
@@ -247,7 +251,7 @@ void MqttClient::loop() {
|
||||
_checkPing();
|
||||
_checkTimeout();
|
||||
} else {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::TCP_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
@@ -259,7 +263,7 @@ void MqttClient::loop() {
|
||||
emc_log_e("Could not create DISCONNECT packet");
|
||||
_onError(0, Error::OUT_OF_MEMORY);
|
||||
} else {
|
||||
_state = State::disconnectingMqtt2;
|
||||
_setState(State::disconnectingMqtt2);
|
||||
}
|
||||
}
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
@@ -270,13 +274,13 @@ void MqttClient::loop() {
|
||||
break;
|
||||
case State::disconnectingTcp1:
|
||||
_transport->stop();
|
||||
_state = State::disconnectingTcp2;
|
||||
_setState(State::disconnectingTcp2);
|
||||
break; // keep break to accomodate async clients
|
||||
case State::disconnectingTcp2:
|
||||
if (_transport->disconnected()) {
|
||||
_clearQueue(0);
|
||||
_bytesSent = 0;
|
||||
_state = State::disconnected;
|
||||
_setState(State::disconnected);
|
||||
if (_onDisconnectCallback) _onDisconnectCallback(_disconnectReason);
|
||||
}
|
||||
break;
|
||||
@@ -308,13 +312,15 @@ void MqttClient::_loop(MqttClient* c) {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void MqttClient::_setState(State newState) {
|
||||
emc_log_i("state %i --> %i", static_cast<std::underlying_type<State>::type>(_state.load()), static_cast<std::underlying_type<State>::type>(newState));
|
||||
_state = newState;
|
||||
}
|
||||
|
||||
uint16_t MqttClient::_getNextPacketId() {
|
||||
uint16_t packetId = 0;
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
// cppcheck-suppress knownConditionTrueFalse
|
||||
packetId = (++_packetId == 0) ? ++_packetId : _packetId;
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
return packetId;
|
||||
++_packetId;
|
||||
if (_packetId == 0) ++_packetId;
|
||||
return _packetId;
|
||||
}
|
||||
|
||||
void MqttClient::_checkOutbox() {
|
||||
@@ -329,21 +335,14 @@ int MqttClient::_sendPacket() {
|
||||
EMC_SEMAPHORE_TAKE();
|
||||
OutgoingPacket* packet = _outbox.getCurrent();
|
||||
|
||||
int32_t wantToWrite = 0;
|
||||
int32_t written = 0;
|
||||
if (packet && (wantToWrite == written)) {
|
||||
// mixing signed with unsigned here but safe because of MQTT packet size limits
|
||||
wantToWrite = packet->packet.available(_bytesSent);
|
||||
size_t written = 0;
|
||||
if (packet) {
|
||||
size_t wantToWrite = packet->packet.available(_bytesSent);
|
||||
if (wantToWrite == 0) {
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
return 0;
|
||||
}
|
||||
written = _transport->write(packet->packet.data(_bytesSent), wantToWrite);
|
||||
if (written < 0) {
|
||||
emc_log_w("Write error, check connection");
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
return -1;
|
||||
}
|
||||
packet->timeSent = millis();
|
||||
_lastClientActivity = millis();
|
||||
_bytesSent += written;
|
||||
@@ -358,7 +357,7 @@ bool MqttClient::_advanceOutbox() {
|
||||
OutgoingPacket* packet = _outbox.getCurrent();
|
||||
if (packet && _bytesSent == packet->packet.size()) {
|
||||
if ((packet->packet.packetType()) == PacketType.DISCONNECT) {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::USER_OK;
|
||||
}
|
||||
if (packet->packet.removable()) {
|
||||
@@ -388,7 +387,7 @@ void MqttClient::_checkIncoming() {
|
||||
espMqttClientInternals::MQTTPacketType packetType = _parser.getPacket().fixedHeader.packetType & 0xF0;
|
||||
if (_state == State::connectingMqtt && packetType != PacketType.CONNACK) {
|
||||
emc_log_w("Disconnecting, expected CONNACK - protocol error");
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
return;
|
||||
}
|
||||
switch (packetType & 0xF0) {
|
||||
@@ -426,7 +425,7 @@ void MqttClient::_checkIncoming() {
|
||||
}
|
||||
} else if (result == espMqttClientInternals::ParserResult::protocolError) {
|
||||
emc_log_w("Disconnecting, protocol error");
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::TCP_DISCONNECTED;
|
||||
return;
|
||||
}
|
||||
@@ -446,7 +445,7 @@ void MqttClient::_checkPing() {
|
||||
// disconnect when server was inactive for twice the keepalive time
|
||||
if (currentMillis - _lastServerActivity > 2 * _keepAlive) {
|
||||
emc_log_w("Disconnecting, server exceeded keepalive");
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
_disconnectReason = DisconnectReason::TCP_DISCONNECTED;
|
||||
return;
|
||||
}
|
||||
@@ -484,7 +483,7 @@ void MqttClient::_checkTimeout() {
|
||||
void MqttClient::_onConnack() {
|
||||
if (_parser.getPacket().variableHeader.fixed.connackVarHeader.returnCode == 0x00) {
|
||||
_pingSent = false; // reset after keepalive timeout disconnect
|
||||
_state = State::connected;
|
||||
_setState(State::connected);
|
||||
_advanceOutbox();
|
||||
if (_parser.getPacket().variableHeader.fixed.connackVarHeader.sessionPresent == 0) {
|
||||
_clearQueue(1);
|
||||
@@ -493,14 +492,14 @@ void MqttClient::_onConnack() {
|
||||
_onConnectCallback(_parser.getPacket().variableHeader.fixed.connackVarHeader.sessionPresent);
|
||||
}
|
||||
} else {
|
||||
_state = State::disconnectingTcp1;
|
||||
_setState(State::disconnectingTcp1);
|
||||
// cast is safe because the parser already checked for a valid return code
|
||||
_disconnectReason = static_cast<DisconnectReason>(_parser.getPacket().variableHeader.fixed.connackVarHeader.returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
void MqttClient::_onPublish() {
|
||||
espMqttClientInternals::IncomingPacket p = _parser.getPacket();
|
||||
const espMqttClientInternals::IncomingPacket& p = _parser.getPacket();
|
||||
uint8_t qos = p.qos();
|
||||
bool retain = p.retain();
|
||||
bool dup = p.dup();
|
||||
@@ -633,9 +632,6 @@ void MqttClient::_onPubcomp() {
|
||||
// if it doesn't match the ID, return
|
||||
if ((it.get()->packet.packetType()) == PacketType.PUBREL) {
|
||||
if (it.get()->packet.packetId() == idToMatch) {
|
||||
if (!_addPacket(PacketType.PUBCOMP, idToMatch)) {
|
||||
emc_log_e("Could not create PUBCOMP packet");
|
||||
}
|
||||
callback = true;
|
||||
_outbox.remove(it);
|
||||
break;
|
||||
|
||||
@@ -65,6 +65,7 @@ class MqttClient {
|
||||
uint16_t publish(const char* topic, uint8_t qos, bool retain, espMqttClientTypes::PayloadCallback callback, size_t length);
|
||||
void clearQueue(bool deleteSessionData = false); // Not MQTT compliant and may cause unpredictable results when `deleteSessionData` = true!
|
||||
const char* getClientId() const;
|
||||
size_t queueSize(); // No const because of mutex
|
||||
void loop();
|
||||
|
||||
protected:
|
||||
@@ -110,6 +111,7 @@ class MqttClient {
|
||||
disconnectingTcp2 = 8
|
||||
};
|
||||
std::atomic<State> _state;
|
||||
inline void _setState(State newState);
|
||||
|
||||
private:
|
||||
char _generatedClientId[EMC_CLIENTID_LENGTH];
|
||||
@@ -130,7 +132,7 @@ class MqttClient {
|
||||
uint32_t timeSent;
|
||||
espMqttClientInternals::Packet packet;
|
||||
template <typename... Args>
|
||||
OutgoingPacket(uint32_t t, espMqttClientTypes::Error error, Args&&... args) :
|
||||
OutgoingPacket(uint32_t t, espMqttClientTypes::Error& error, Args&&... args) : // NOLINT(runtime/references)
|
||||
timeSent(t),
|
||||
packet(error, std::forward<Args>(args) ...) {}
|
||||
};
|
||||
@@ -148,16 +150,24 @@ class MqttClient {
|
||||
bool _addPacket(Args&&... args) {
|
||||
espMqttClientTypes::Error error(espMqttClientTypes::Error::SUCCESS);
|
||||
espMqttClientInternals::Outbox<OutgoingPacket>::Iterator it = _outbox.emplace(0, error, std::forward<Args>(args) ...);
|
||||
if (it && error == espMqttClientTypes::Error::SUCCESS) return true;
|
||||
return false;
|
||||
if (it && error == espMqttClientTypes::Error::SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
if (it) _outbox.remove(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
bool _addPacketFront(Args&&... args) {
|
||||
espMqttClientTypes::Error error(espMqttClientTypes::Error::SUCCESS);
|
||||
espMqttClientInternals::Outbox<OutgoingPacket>::Iterator it = _outbox.emplaceFront(0, error, std::forward<Args>(args) ...);
|
||||
if (it && error == espMqttClientTypes::Error::SUCCESS) return true;
|
||||
return false;
|
||||
if (it && error == espMqttClientTypes::Error::SUCCESS) {
|
||||
return true;
|
||||
} else {
|
||||
if (it) _outbox.remove(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void _checkOutbox();
|
||||
|
||||
@@ -11,6 +11,11 @@ the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#include "MqttClient.h"
|
||||
|
||||
template <typename T>
|
||||
@@ -73,36 +78,128 @@ class MqttClientSetup : public MqttClient {
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onConnect(espMqttClientTypes::OnConnectCallback callback) {
|
||||
T& onConnect(espMqttClientTypes::OnConnectCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onConnectCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onConnectCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onDisconnect(espMqttClientTypes::OnDisconnectCallback callback) {
|
||||
T& onDisconnect(espMqttClientTypes::OnDisconnectCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onDisconnectCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onDisconnectCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onSubscribe(espMqttClientTypes::OnSubscribeCallback callback) {
|
||||
T& onSubscribe(espMqttClientTypes::OnSubscribeCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onSubscribeCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onSubscribeCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onUnsubscribe(espMqttClientTypes::OnUnsubscribeCallback callback) {
|
||||
T& onUnsubscribe(espMqttClientTypes::OnUnsubscribeCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onUnsubscribeCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onUnsubscribeCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onMessage(espMqttClientTypes::OnMessageCallback callback) {
|
||||
T& onMessage(espMqttClientTypes::OnMessageCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onMessageCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onMessageCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& onPublish(espMqttClientTypes::OnPublishCallback callback) {
|
||||
T& onPublish(espMqttClientTypes::OnPublishCallback callback, uint32_t id = 0) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onPublishCallbacks.emplace_back(callback, id);
|
||||
#else
|
||||
(void) id;
|
||||
_onPublishCallback = callback;
|
||||
#endif
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
T& removeOnConnect(uint32_t id) {
|
||||
for (auto it = _onConnectCallbacks.begin(); it != _onConnectCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onConnectCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& removeOnDisconnect(uint32_t id) {
|
||||
for (auto it = _onDisconnectCallbacks.begin(); it != _onDisconnectCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onDisconnectCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& removeOnSubscribe(uint32_t id) {
|
||||
for (auto it = _onSubscribeCallbacks.begin(); it != _onSubscribeCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onSubscribeCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& removeOnUnsubscribe(uint32_t id) {
|
||||
for (auto it = _onUnsubscribeCallbacks.begin(); it != _onUnsubscribeCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onUnsubscribeCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& removeOnMessage(uint32_t id) {
|
||||
for (auto it = _onMessageCallbacks.begin(); it != _onMessageCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onMessageCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
|
||||
T& removeOnPublish(uint32_t id) {
|
||||
for (auto it = _onPublishCallbacks.begin(); it != _onPublishCallbacks.end(); ++it) {
|
||||
if (it->second == id) {
|
||||
_onPublishCallbacks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<T&>(*this);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
T& onError(espMqttClientTypes::OnErrorCallback callback) {
|
||||
_onErrorCallback = callback;
|
||||
@@ -112,5 +209,37 @@ class MqttClientSetup : public MqttClient {
|
||||
|
||||
protected:
|
||||
explicit MqttClientSetup(espMqttClientTypes::UseInternalTask useInternalTask, uint8_t priority = 1, uint8_t core = 1)
|
||||
: MqttClient(useInternalTask, priority, core) {}
|
||||
: MqttClient(useInternalTask, priority, core) {
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
_onConnectCallback = [this](bool sessionPresent) {
|
||||
for (auto callback : _onConnectCallbacks) if (callback.first) callback.first(sessionPresent);
|
||||
};
|
||||
_onDisconnectCallback = [this](espMqttClientTypes::DisconnectReason reason) {
|
||||
for (auto callback : _onDisconnectCallbacks) if (callback.first) callback.first(reason);
|
||||
};
|
||||
_onSubscribeCallback = [this](uint16_t packetId, const espMqttClientTypes::SubscribeReturncode* returncodes, size_t len) {
|
||||
for (auto callback : _onSubscribeCallbacks) if (callback.first) callback.first(packetId, returncodes, len);
|
||||
};
|
||||
_onUnsubscribeCallback = [this](int16_t packetId) {
|
||||
for (auto callback : _onUnsubscribeCallbacks) if (callback.first) callback.first(packetId);
|
||||
};
|
||||
_onMessageCallback = [this](const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||
for (auto callback : _onMessageCallbacks) if (callback.first) callback.first(properties, topic, payload, len, index, total);
|
||||
};
|
||||
_onPublishCallback = [this](uint16_t packetId) {
|
||||
for (auto callback : _onPublishCallbacks) if (callback.first) callback.first(packetId);
|
||||
};
|
||||
#else
|
||||
// empty
|
||||
#endif
|
||||
}
|
||||
|
||||
#if EMC_MULTIPLE_CALLBACKS
|
||||
std::list<std::pair<espMqttClientTypes::OnConnectCallback, uint32_t>> _onConnectCallbacks;
|
||||
std::list<std::pair<espMqttClientTypes::OnDisconnectCallback, uint32_t>> _onDisconnectCallbacks;
|
||||
std::list<std::pair<espMqttClientTypes::OnSubscribeCallback, uint32_t>> _onSubscribeCallbacks;
|
||||
std::list<std::pair<espMqttClientTypes::OnUnsubscribeCallback, uint32_t>> _onUnsubscribeCallbacks;
|
||||
std::list<std::pair<espMqttClientTypes::OnMessageCallback, uint32_t>> _onMessageCallbacks;
|
||||
std::list<std::pair<espMqttClientTypes::OnPublishCallback, uint32_t>> _onPublishCallbacks;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -163,6 +163,16 @@ class Outbox {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
Node* n = _first;
|
||||
size_t count = 0;
|
||||
while (n) {
|
||||
n = n->next;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
Node* _first;
|
||||
Node* _last;
|
||||
|
||||
@@ -100,7 +100,7 @@ Packet::Packet(espMqttClientTypes::Error& error,
|
||||
(password ? 2 + strlen(password) : 0);
|
||||
|
||||
// allocate memory
|
||||
if (!_allocate(remainingLength)) {
|
||||
if (!_allocate(remainingLength, false)) {
|
||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
@@ -300,8 +300,8 @@ Packet::Packet(espMqttClientTypes::Error& error, MQTTPacketType type)
|
||||
}
|
||||
|
||||
|
||||
bool Packet::_allocate(size_t remainingLength) {
|
||||
if (EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) {
|
||||
bool Packet::_allocate(size_t remainingLength, bool check) {
|
||||
if (check && EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) {
|
||||
emc_log_w("Packet buffer not allocated: low memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ the LICENSE file.
|
||||
#include <stddef.h>
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Config.h"
|
||||
#include "../Config.h"
|
||||
#include "../TypeDefs.h"
|
||||
#include "../Helpers.h"
|
||||
#include "../Logging.h"
|
||||
#include "RemainingLength.h"
|
||||
#include "String.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace espMqttClientInternals {
|
||||
|
||||
@@ -97,7 +97,7 @@ class Packet {
|
||||
, _payloadStartIndex(0)
|
||||
, _payloadEndIndex(0)
|
||||
, _getPayload(nullptr) {
|
||||
static_assert(sizeof...(Args) % 2 == 0);
|
||||
static_assert(sizeof...(Args) % 2 == 0, "Subscribe should be in topic/qos pairs");
|
||||
size_t numberTopics = 2 + (sizeof...(Args) / 2);
|
||||
SubscribeItem list[numberTopics] = {topic1, qos1, topic2, qos2, args...};
|
||||
_createSubscribe(error, list, numberTopics);
|
||||
@@ -133,7 +133,7 @@ class Packet {
|
||||
|
||||
private:
|
||||
// pass remainingLength = total size - header - remainingLengthLength!
|
||||
bool _allocate(size_t remainingLength);
|
||||
bool _allocate(size_t remainingLength, bool check = true);
|
||||
|
||||
// fills header and returns index of next available byte in buffer
|
||||
size_t _fillPublishHeader(uint16_t packetId,
|
||||
|
||||
@@ -6,7 +6,7 @@ For a copy, see <https://opensource.org/licenses/MIT> or
|
||||
the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "String.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace espMqttClientInternals {
|
||||
|
||||
@@ -40,7 +40,7 @@ bool ClientPosix::connect(IPAddress ip, uint16_t port) {
|
||||
_host.sin_addr.s_addr = htonl(uint32_t(ip));
|
||||
_host.sin_port = ::htons(port);
|
||||
|
||||
int ret = ::connect(_sockfd, (struct sockaddr *)&_host, sizeof(_host));
|
||||
int ret = ::connect(_sockfd, reinterpret_cast<sockaddr*>(&_host), sizeof(_host));
|
||||
|
||||
if (ret < 0) {
|
||||
emc_log_e("Error connecting: %d - (%d) %s", ret, errno, strerror(errno));
|
||||
|
||||
@@ -43,7 +43,7 @@ class ClientPosix : public Transport {
|
||||
|
||||
protected:
|
||||
int _sockfd;
|
||||
struct sockaddr_in _host;
|
||||
sockaddr_in _host;
|
||||
};
|
||||
|
||||
} // namespace espMqttClientInternals
|
||||
|
||||
@@ -8,7 +8,7 @@ the LICENSE file.
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include "IPAddress.h"
|
||||
#include "ClientPosixIPAddress.h"
|
||||
|
||||
IPAddress::IPAddress()
|
||||
: _address(0) {
|
||||
@@ -10,7 +10,7 @@ the LICENSE file.
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#include "IPAddress.h"
|
||||
#include "ClientPosixIPAddress.h"
|
||||
|
||||
namespace espMqttClientInternals {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user