mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
add extra {} to SubscribeItem list[1]
This commit is contained in:
@@ -11,428 +11,426 @@ the LICENSE file.
|
|||||||
namespace espMqttClientInternals {
|
namespace espMqttClientInternals {
|
||||||
|
|
||||||
Packet::~Packet() {
|
Packet::~Packet() {
|
||||||
free(_data);
|
free(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Packet::available(size_t index) {
|
size_t Packet::available(size_t index) {
|
||||||
if (index >= _size) return 0;
|
if (index >= _size)
|
||||||
if (!_getPayload) return _size - index;
|
return 0;
|
||||||
return _chunkedAvailable(index);
|
if (!_getPayload)
|
||||||
|
return _size - index;
|
||||||
|
return _chunkedAvailable(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Packet::data(size_t index) const {
|
const uint8_t * Packet::data(size_t index) const {
|
||||||
if (!_getPayload) {
|
if (!_getPayload) {
|
||||||
if (!_data) return nullptr;
|
if (!_data)
|
||||||
if (index >= _size) return nullptr;
|
return nullptr;
|
||||||
return &_data[index];
|
if (index >= _size)
|
||||||
}
|
return nullptr;
|
||||||
return _chunkedData(index);
|
return &_data[index];
|
||||||
|
}
|
||||||
|
return _chunkedData(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Packet::size() const {
|
size_t Packet::size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::setDup() {
|
void Packet::setDup() {
|
||||||
if (!_data) return;
|
if (!_data)
|
||||||
if (packetType() != PacketType.PUBLISH) return;
|
return;
|
||||||
if (_packetId == 0) return;
|
if (packetType() != PacketType.PUBLISH)
|
||||||
_data[0] |= 0x08;
|
return;
|
||||||
|
if (_packetId == 0)
|
||||||
|
return;
|
||||||
|
_data[0] |= 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Packet::packetId() const {
|
uint16_t Packet::packetId() const {
|
||||||
return _packetId;
|
return _packetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
MQTTPacketType Packet::packetType() const {
|
MQTTPacketType Packet::packetType() const {
|
||||||
if (_data) return static_cast<MQTTPacketType>(_data[0] & 0xF0);
|
if (_data)
|
||||||
return static_cast<MQTTPacketType>(0);
|
return static_cast<MQTTPacketType>(_data[0] & 0xF0);
|
||||||
|
return static_cast<MQTTPacketType>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Packet::removable() const {
|
bool Packet::removable() const {
|
||||||
if (_packetId == 0) return true;
|
if (_packetId == 0)
|
||||||
if ((packetType() == PacketType.PUBACK) || (packetType() == PacketType.PUBCOMP)) return true;
|
return true;
|
||||||
return false;
|
if ((packetType() == PacketType.PUBACK) || (packetType() == PacketType.PUBCOMP))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error,
|
Packet::Packet(espMqttClientTypes::Error & error,
|
||||||
bool cleanSession,
|
bool cleanSession,
|
||||||
const char* username,
|
const char * username,
|
||||||
const char* password,
|
const char * password,
|
||||||
const char* willTopic,
|
const char * willTopic,
|
||||||
bool willRetain,
|
bool willRetain,
|
||||||
uint8_t willQos,
|
uint8_t willQos,
|
||||||
const uint8_t* willPayload,
|
const uint8_t * willPayload,
|
||||||
uint16_t willPayloadLength,
|
uint16_t willPayloadLength,
|
||||||
uint16_t keepAlive,
|
uint16_t keepAlive,
|
||||||
const char* clientId)
|
const char * clientId)
|
||||||
: _packetId(0)
|
: _packetId(0)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(nullptr) {
|
, _getPayload(nullptr) {
|
||||||
if (willPayload && willPayloadLength == 0) {
|
if (willPayload && willPayloadLength == 0) {
|
||||||
size_t length = strlen(reinterpret_cast<const char*>(willPayload));
|
size_t length = strlen(reinterpret_cast<const char *>(willPayload));
|
||||||
if (length > UINT16_MAX) {
|
if (length > UINT16_MAX) {
|
||||||
emc_log_w("Payload length truncated (l:%zu)", length);
|
emc_log_w("Payload length truncated (l:%zu)", length);
|
||||||
willPayloadLength = UINT16_MAX;
|
willPayloadLength = UINT16_MAX;
|
||||||
} else {
|
} else {
|
||||||
willPayloadLength = length;
|
willPayloadLength = length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!clientId || strlen(clientId) == 0) {
|
||||||
if (!clientId || strlen(clientId) == 0) {
|
emc_log_w("clientId not set error");
|
||||||
emc_log_w("clientId not set error");
|
error = espMqttClientTypes::Error::MALFORMED_PARAMETER;
|
||||||
error = espMqttClientTypes::Error::MALFORMED_PARAMETER;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate size
|
|
||||||
size_t remainingLength =
|
|
||||||
6 + // protocol
|
|
||||||
1 + // protocol level
|
|
||||||
1 + // connect flags
|
|
||||||
2 + // keepalive
|
|
||||||
2 + strlen(clientId) +
|
|
||||||
(willTopic ? 2 + strlen(willTopic) + 2 + willPayloadLength : 0) +
|
|
||||||
(username ? 2 + strlen(username) : 0) +
|
|
||||||
(password ? 2 + strlen(password) : 0);
|
|
||||||
|
|
||||||
// allocate memory
|
|
||||||
if (!_allocate(remainingLength, false)) {
|
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialize
|
|
||||||
size_t pos = 0;
|
|
||||||
|
|
||||||
// FIXED HEADER
|
|
||||||
_data[pos++] = PacketType.CONNECT | HeaderFlag.CONNECT_RESERVED;
|
|
||||||
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
|
||||||
pos += encodeString(PROTOCOL, &_data[pos]);
|
|
||||||
_data[pos++] = PROTOCOL_LEVEL;
|
|
||||||
uint8_t connectFlags = 0;
|
|
||||||
if (cleanSession) connectFlags |= espMqttClientInternals::ConnectFlag.CLEAN_SESSION;
|
|
||||||
if (username != nullptr) connectFlags |= espMqttClientInternals::ConnectFlag.USERNAME;
|
|
||||||
if (password != nullptr) connectFlags |= espMqttClientInternals::ConnectFlag.PASSWORD;
|
|
||||||
if (willTopic != nullptr) {
|
|
||||||
connectFlags |= espMqttClientInternals::ConnectFlag.WILL;
|
|
||||||
if (willRetain) connectFlags |= espMqttClientInternals::ConnectFlag.WILL_RETAIN;
|
|
||||||
switch (willQos) {
|
|
||||||
case 0:
|
|
||||||
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS2;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_data[pos++] = connectFlags;
|
|
||||||
_data[pos++] = keepAlive >> 8;
|
|
||||||
_data[pos++] = keepAlive & 0xFF;
|
|
||||||
|
|
||||||
// PAYLOAD
|
// Calculate size
|
||||||
// client ID
|
size_t remainingLength = 6 + // protocol
|
||||||
pos += encodeString(clientId, &_data[pos]);
|
1 + // protocol level
|
||||||
// will
|
1 + // connect flags
|
||||||
if (willTopic != nullptr && willPayload != nullptr) {
|
2 + // keepalive
|
||||||
pos += encodeString(willTopic, &_data[pos]);
|
2 + strlen(clientId) + (willTopic ? 2 + strlen(willTopic) + 2 + willPayloadLength : 0) + (username ? 2 + strlen(username) : 0)
|
||||||
_data[pos++] = willPayloadLength >> 8;
|
+ (password ? 2 + strlen(password) : 0);
|
||||||
_data[pos++] = willPayloadLength & 0xFF;
|
|
||||||
memcpy(&_data[pos], willPayload, willPayloadLength);
|
|
||||||
pos += willPayloadLength;
|
|
||||||
}
|
|
||||||
// credentials
|
|
||||||
if (username != nullptr) pos += encodeString(username, &_data[pos]);
|
|
||||||
if (password != nullptr) encodeString(password, &_data[pos]);
|
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
// allocate memory
|
||||||
|
if (!_allocate(remainingLength, false)) {
|
||||||
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialize
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
// FIXED HEADER
|
||||||
|
_data[pos++] = PacketType.CONNECT | HeaderFlag.CONNECT_RESERVED;
|
||||||
|
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
||||||
|
pos += encodeString(PROTOCOL, &_data[pos]);
|
||||||
|
_data[pos++] = PROTOCOL_LEVEL;
|
||||||
|
uint8_t connectFlags = 0;
|
||||||
|
if (cleanSession)
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.CLEAN_SESSION;
|
||||||
|
if (username != nullptr)
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.USERNAME;
|
||||||
|
if (password != nullptr)
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.PASSWORD;
|
||||||
|
if (willTopic != nullptr) {
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.WILL;
|
||||||
|
if (willRetain)
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_RETAIN;
|
||||||
|
switch (willQos) {
|
||||||
|
case 0:
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_data[pos++] = connectFlags;
|
||||||
|
_data[pos++] = keepAlive >> 8;
|
||||||
|
_data[pos++] = keepAlive & 0xFF;
|
||||||
|
|
||||||
|
// PAYLOAD
|
||||||
|
// client ID
|
||||||
|
pos += encodeString(clientId, &_data[pos]);
|
||||||
|
// will
|
||||||
|
if (willTopic != nullptr && willPayload != nullptr) {
|
||||||
|
pos += encodeString(willTopic, &_data[pos]);
|
||||||
|
_data[pos++] = willPayloadLength >> 8;
|
||||||
|
_data[pos++] = willPayloadLength & 0xFF;
|
||||||
|
memcpy(&_data[pos], willPayload, willPayloadLength);
|
||||||
|
pos += willPayloadLength;
|
||||||
|
}
|
||||||
|
// credentials
|
||||||
|
if (username != nullptr)
|
||||||
|
pos += encodeString(username, &_data[pos]);
|
||||||
|
if (password != nullptr)
|
||||||
|
encodeString(password, &_data[pos]);
|
||||||
|
|
||||||
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error,
|
Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic, const uint8_t * payload, size_t payloadLength, uint8_t qos, bool retain)
|
||||||
uint16_t packetId,
|
: _packetId(packetId)
|
||||||
const char* topic,
|
, _data(nullptr)
|
||||||
const uint8_t* payload,
|
, _size(0)
|
||||||
size_t payloadLength,
|
, _payloadIndex(0)
|
||||||
uint8_t qos,
|
, _payloadStartIndex(0)
|
||||||
bool retain)
|
, _payloadEndIndex(0)
|
||||||
: _packetId(packetId)
|
, _getPayload(nullptr) {
|
||||||
, _data(nullptr)
|
size_t remainingLength = 2 + strlen(topic) + // topic length + topic
|
||||||
, _size(0)
|
2 + // packet ID
|
||||||
, _payloadIndex(0)
|
payloadLength;
|
||||||
, _payloadStartIndex(0)
|
|
||||||
, _payloadEndIndex(0)
|
|
||||||
, _getPayload(nullptr) {
|
|
||||||
size_t remainingLength =
|
|
||||||
2 + strlen(topic) + // topic length + topic
|
|
||||||
2 + // packet ID
|
|
||||||
payloadLength;
|
|
||||||
|
|
||||||
if (qos == 0) {
|
if (qos == 0) {
|
||||||
remainingLength -= 2;
|
remainingLength -= 2;
|
||||||
_packetId = 0;
|
_packetId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_allocate(remainingLength)) {
|
if (!_allocate(remainingLength)) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain);
|
size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain);
|
||||||
|
|
||||||
// PAYLOAD
|
// PAYLOAD
|
||||||
memcpy(&_data[pos], payload, payloadLength);
|
memcpy(&_data[pos], payload, payloadLength);
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error,
|
Packet::Packet(espMqttClientTypes::Error & error,
|
||||||
uint16_t packetId,
|
uint16_t packetId,
|
||||||
const char* topic,
|
const char * topic,
|
||||||
espMqttClientTypes::PayloadCallback payloadCallback,
|
espMqttClientTypes::PayloadCallback payloadCallback,
|
||||||
size_t payloadLength,
|
size_t payloadLength,
|
||||||
uint8_t qos,
|
uint8_t qos,
|
||||||
bool retain)
|
bool retain)
|
||||||
: _packetId(packetId)
|
: _packetId(packetId)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(payloadCallback) {
|
, _getPayload(payloadCallback) {
|
||||||
size_t remainingLength =
|
size_t remainingLength = 2 + strlen(topic) + // topic length + topic
|
||||||
2 + strlen(topic) + // topic length + topic
|
2 + // packet ID
|
||||||
2 + // packet ID
|
payloadLength;
|
||||||
payloadLength;
|
|
||||||
|
|
||||||
if (qos == 0) {
|
if (qos == 0) {
|
||||||
remainingLength -= 2;
|
remainingLength -= 2;
|
||||||
_packetId = 0;
|
_packetId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_allocate(remainingLength - payloadLength + std::min(payloadLength, static_cast<size_t>(EMC_RX_BUFFER_SIZE)))) {
|
if (!_allocate(remainingLength - payloadLength + std::min(payloadLength, static_cast<size_t>(EMC_RX_BUFFER_SIZE)))) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain);
|
size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain);
|
||||||
|
|
||||||
// payload will be added by 'Packet::available'
|
// payload will be added by 'Packet::available'
|
||||||
_size = pos + payloadLength;
|
_size = pos + payloadLength;
|
||||||
_payloadIndex = pos;
|
_payloadIndex = pos;
|
||||||
_payloadStartIndex = _payloadIndex;
|
_payloadStartIndex = _payloadIndex;
|
||||||
_payloadEndIndex = _payloadIndex;
|
_payloadEndIndex = _payloadIndex;
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error, uint16_t packetId, const char* topic, uint8_t qos)
|
Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic, uint8_t qos)
|
||||||
: _packetId(packetId)
|
: _packetId(packetId)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(nullptr) {
|
, _getPayload(nullptr) {
|
||||||
SubscribeItem list[1] = {topic, qos};
|
SubscribeItem list[1] = {{topic, qos}};
|
||||||
_createSubscribe(error, list, 1);
|
_createSubscribe(error, list, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error, MQTTPacketType type, uint16_t packetId)
|
Packet::Packet(espMqttClientTypes::Error & error, MQTTPacketType type, uint16_t packetId)
|
||||||
: _packetId(packetId)
|
: _packetId(packetId)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(nullptr) {
|
, _getPayload(nullptr) {
|
||||||
if (!_allocate(2)) {
|
if (!_allocate(2)) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
_data[pos] = type;
|
_data[pos] = type;
|
||||||
if (type == PacketType.PUBREL) {
|
if (type == PacketType.PUBREL) {
|
||||||
_data[pos++] |= HeaderFlag.PUBREL_RESERVED;
|
_data[pos++] |= HeaderFlag.PUBREL_RESERVED;
|
||||||
} else {
|
} else {
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
pos += encodeRemainingLength(2, &_data[pos]);
|
pos += encodeRemainingLength(2, &_data[pos]);
|
||||||
_data[pos++] = packetId >> 8;
|
_data[pos++] = packetId >> 8;
|
||||||
_data[pos] = packetId & 0xFF;
|
_data[pos] = packetId & 0xFF;
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error, uint16_t packetId, const char* topic)
|
Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic)
|
||||||
: _packetId(packetId)
|
: _packetId(packetId)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(nullptr) {
|
, _getPayload(nullptr) {
|
||||||
const char* list[1] = {topic};
|
const char * list[1] = {topic};
|
||||||
_createUnsubscribe(error, list, 1);
|
_createUnsubscribe(error, list, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::Packet(espMqttClientTypes::Error& error, MQTTPacketType type)
|
Packet::Packet(espMqttClientTypes::Error & error, MQTTPacketType type)
|
||||||
: _packetId(0)
|
: _packetId(0)
|
||||||
, _data(nullptr)
|
, _data(nullptr)
|
||||||
, _size(0)
|
, _size(0)
|
||||||
, _payloadIndex(0)
|
, _payloadIndex(0)
|
||||||
, _payloadStartIndex(0)
|
, _payloadStartIndex(0)
|
||||||
, _payloadEndIndex(0)
|
, _payloadEndIndex(0)
|
||||||
, _getPayload(nullptr) {
|
, _getPayload(nullptr) {
|
||||||
if (!_allocate(0)) {
|
if (!_allocate(0)) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_data[0] |= type;
|
_data[0] |= type;
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Packet::_allocate(size_t remainingLength, bool check) {
|
bool Packet::_allocate(size_t remainingLength, bool check) {
|
||||||
if (check && EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) {
|
if (check && EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) {
|
||||||
emc_log_w("Packet buffer not allocated: low memory");
|
emc_log_w("Packet buffer not allocated: low memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_size = 1 + remainingLengthLength(remainingLength) + remainingLength;
|
_size = 1 + remainingLengthLength(remainingLength) + remainingLength;
|
||||||
_data = reinterpret_cast<uint8_t*>(malloc(_size));
|
_data = reinterpret_cast<uint8_t *>(malloc(_size));
|
||||||
if (!_data) {
|
if (!_data) {
|
||||||
_size = 0;
|
_size = 0;
|
||||||
emc_log_w("Alloc failed (l:%zu)", _size);
|
emc_log_w("Alloc failed (l:%zu)", _size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
emc_log_i("Alloc (l:%zu)", _size);
|
emc_log_i("Alloc (l:%zu)", _size);
|
||||||
memset(_data, 0, _size);
|
memset(_data, 0, _size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Packet::_fillPublishHeader(uint16_t packetId,
|
size_t Packet::_fillPublishHeader(uint16_t packetId, const char * topic, size_t remainingLength, uint8_t qos, bool retain) {
|
||||||
const char* topic,
|
size_t index = 0;
|
||||||
size_t remainingLength,
|
|
||||||
uint8_t qos,
|
|
||||||
bool retain) {
|
|
||||||
size_t index = 0;
|
|
||||||
|
|
||||||
// FIXED HEADER
|
// FIXED HEADER
|
||||||
_data[index] = PacketType.PUBLISH;
|
_data[index] = PacketType.PUBLISH;
|
||||||
if (retain) _data[index] |= HeaderFlag.PUBLISH_RETAIN;
|
if (retain)
|
||||||
if (qos == 0) {
|
_data[index] |= HeaderFlag.PUBLISH_RETAIN;
|
||||||
_data[index++] |= HeaderFlag.PUBLISH_QOS0;
|
if (qos == 0) {
|
||||||
} else if (qos == 1) {
|
_data[index++] |= HeaderFlag.PUBLISH_QOS0;
|
||||||
_data[index++] |= HeaderFlag.PUBLISH_QOS1;
|
} else if (qos == 1) {
|
||||||
} else if (qos == 2) {
|
_data[index++] |= HeaderFlag.PUBLISH_QOS1;
|
||||||
_data[index++] |= HeaderFlag.PUBLISH_QOS2;
|
} else if (qos == 2) {
|
||||||
}
|
_data[index++] |= HeaderFlag.PUBLISH_QOS2;
|
||||||
index += encodeRemainingLength(remainingLength, &_data[index]);
|
}
|
||||||
|
index += encodeRemainingLength(remainingLength, &_data[index]);
|
||||||
|
|
||||||
// VARIABLE HEADER
|
// VARIABLE HEADER
|
||||||
index += encodeString(topic, &_data[index]);
|
index += encodeString(topic, &_data[index]);
|
||||||
if (qos > 0) {
|
if (qos > 0) {
|
||||||
_data[index++] = packetId >> 8;
|
_data[index++] = packetId >> 8;
|
||||||
_data[index++] = packetId & 0xFF;
|
_data[index++] = packetId & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::_createSubscribe(espMqttClientTypes::Error& error,
|
void Packet::_createSubscribe(espMqttClientTypes::Error & error, SubscribeItem * list, size_t numberTopics) {
|
||||||
SubscribeItem* list,
|
// Calculate size
|
||||||
size_t numberTopics) {
|
size_t payload = 0;
|
||||||
// Calculate size
|
for (size_t i = 0; i < numberTopics; ++i) {
|
||||||
size_t payload = 0;
|
payload += 2 + strlen(list[i].topic) + 1; // length bytes, string, qos
|
||||||
for (size_t i = 0; i < numberTopics; ++i) {
|
}
|
||||||
payload += 2 + strlen(list[i].topic) + 1; // length bytes, string, qos
|
size_t remainingLength = 2 + payload; // packetId + payload
|
||||||
}
|
|
||||||
size_t remainingLength = 2 + payload; // packetId + payload
|
|
||||||
|
|
||||||
// allocate memory
|
// allocate memory
|
||||||
if (!_allocate(remainingLength)) {
|
if (!_allocate(remainingLength)) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize
|
// serialize
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
_data[pos++] = PacketType.SUBSCRIBE | HeaderFlag.SUBSCRIBE_RESERVED;
|
_data[pos++] = PacketType.SUBSCRIBE | HeaderFlag.SUBSCRIBE_RESERVED;
|
||||||
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
||||||
_data[pos++] = _packetId >> 8;
|
_data[pos++] = _packetId >> 8;
|
||||||
_data[pos++] = _packetId & 0xFF;
|
_data[pos++] = _packetId & 0xFF;
|
||||||
for (size_t i = 0; i < numberTopics; ++i) {
|
for (size_t i = 0; i < numberTopics; ++i) {
|
||||||
pos += encodeString(list[i].topic, &_data[pos]);
|
pos += encodeString(list[i].topic, &_data[pos]);
|
||||||
_data[pos++] = list[i].qos;
|
_data[pos++] = list[i].qos;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::_createUnsubscribe(espMqttClientTypes::Error& error,
|
void Packet::_createUnsubscribe(espMqttClientTypes::Error & error, const char ** list, size_t numberTopics) {
|
||||||
const char** list,
|
// Calculate size
|
||||||
size_t numberTopics) {
|
size_t payload = 0;
|
||||||
// Calculate size
|
for (size_t i = 0; i < numberTopics; ++i) {
|
||||||
size_t payload = 0;
|
payload += 2 + strlen(list[i]); // length bytes, string
|
||||||
for (size_t i = 0; i < numberTopics; ++i) {
|
}
|
||||||
payload += 2 + strlen(list[i]); // length bytes, string
|
size_t remainingLength = 2 + payload; // packetId + payload
|
||||||
}
|
|
||||||
size_t remainingLength = 2 + payload; // packetId + payload
|
|
||||||
|
|
||||||
// allocate memory
|
// allocate memory
|
||||||
if (!_allocate(remainingLength)) {
|
if (!_allocate(remainingLength)) {
|
||||||
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
error = espMqttClientTypes::Error::OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize
|
// serialize
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
_data[pos++] = PacketType.UNSUBSCRIBE | HeaderFlag.UNSUBSCRIBE_RESERVED;
|
_data[pos++] = PacketType.UNSUBSCRIBE | HeaderFlag.UNSUBSCRIBE_RESERVED;
|
||||||
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
pos += encodeRemainingLength(remainingLength, &_data[pos]);
|
||||||
_data[pos++] = _packetId >> 8;
|
_data[pos++] = _packetId >> 8;
|
||||||
_data[pos++] = _packetId & 0xFF;
|
_data[pos++] = _packetId & 0xFF;
|
||||||
for (size_t i = 0; i < numberTopics; ++i) {
|
for (size_t i = 0; i < numberTopics; ++i) {
|
||||||
pos += encodeString(list[i], &_data[pos]);
|
pos += encodeString(list[i], &_data[pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = espMqttClientTypes::Error::SUCCESS;
|
error = espMqttClientTypes::Error::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Packet::_chunkedAvailable(size_t index) {
|
size_t Packet::_chunkedAvailable(size_t index) {
|
||||||
// index vs size check done in 'available(index)'
|
// index vs size check done in 'available(index)'
|
||||||
|
|
||||||
// index points to header or first payload byte
|
// index points to header or first payload byte
|
||||||
if (index < _payloadIndex) {
|
if (index < _payloadIndex) {
|
||||||
if (_size > _payloadIndex && _payloadEndIndex != 0) {
|
if (_size > _payloadIndex && _payloadEndIndex != 0) {
|
||||||
size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast<size_t>(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index);
|
size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast<size_t>(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index);
|
||||||
_payloadStartIndex = _payloadIndex;
|
_payloadStartIndex = _payloadIndex;
|
||||||
_payloadEndIndex = _payloadStartIndex + copied - 1;
|
_payloadEndIndex = _payloadStartIndex + copied - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// index points to payload unavailable
|
||||||
|
} else if (index > _payloadEndIndex || _payloadStartIndex > index) {
|
||||||
|
_payloadStartIndex = index;
|
||||||
|
size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast<size_t>(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index);
|
||||||
|
_payloadEndIndex = _payloadStartIndex + copied - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// index points to payload unavailable
|
// now index points to header or payload available
|
||||||
} else if (index > _payloadEndIndex || _payloadStartIndex > index) {
|
return _payloadEndIndex - index + 1;
|
||||||
_payloadStartIndex = index;
|
|
||||||
size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast<size_t>(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index);
|
|
||||||
_payloadEndIndex = _payloadStartIndex + copied - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now index points to header or payload available
|
|
||||||
return _payloadEndIndex - index + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Packet::_chunkedData(size_t index) const {
|
const uint8_t * Packet::_chunkedData(size_t index) const {
|
||||||
// CAUTION!! available(index) has to be called first to check available data and possibly fill payloadbuffer
|
// CAUTION!! available(index) has to be called first to check available data and possibly fill payloadbuffer
|
||||||
if (index < _payloadIndex) {
|
if (index < _payloadIndex) {
|
||||||
return &_data[index];
|
return &_data[index];
|
||||||
}
|
}
|
||||||
return &_data[index - _payloadStartIndex + _payloadIndex];
|
return &_data[index - _payloadStartIndex + _payloadIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace espMqttClientInternals
|
} // end namespace espMqttClientInternals
|
||||||
|
|||||||
Reference in New Issue
Block a user