2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
42#include "iot/mqtt/client/Mqtt.h"
44#include "iot/mqtt/MqttContext.h"
45#include "iot/mqtt/client/packets/Connack.h"
46#include "iot/mqtt/client/packets/Pingresp.h"
47#include "iot/mqtt/client/packets/Puback.h"
48#include "iot/mqtt/client/packets/Pubcomp.h"
49#include "iot/mqtt/client/packets/Publish.h"
50#include "iot/mqtt/client/packets/Pubrec.h"
51#include "iot/mqtt/client/packets/Pubrel.h"
52#include "iot/mqtt/client/packets/Suback.h"
53#include "iot/mqtt/client/packets/Unsuback.h"
54#include "iot/mqtt/packets/Connect.h"
55#include "iot/mqtt/packets/Disconnect.h"
56#include "iot/mqtt/packets/Pingreq.h"
57#include "iot/mqtt/packets/Subscribe.h"
58#include "iot/mqtt/packets/Unsubscribe.h"
60#ifndef DOXYGEN_SHOULD_SKIP_THIS
62#include "log/Logger.h"
69#include <nlohmann/json.hpp>
76namespace iot::mqtt::
client {
78 Mqtt::
Mqtt(
const std::string& connectionName,
const std::string& clientId, uint16_t keepAlive,
const std::string& sessionStoreFileName)
79 : Super
(connectionName
, clientId
)
82 if (!sessionStoreFileName.empty()) {
83 std::ifstream sessionStoreFile(sessionStoreFileName);
85 if (sessionStoreFile.is_open()) {
87 nlohmann::json sessionStoreJson;
89 sessionStoreFile >> sessionStoreJson;
93 LOG(DEBUG) << connectionName <<
" MQTT Client: ... Persistent session data loaded successful";
94 }
catch (
const nlohmann::json::exception&) {
95 LOG(DEBUG) << connectionName <<
" MQTT Client: ... Starting with empty session: Session store '"
96 << sessionStoreFileName <<
"' empty or corrupted";
101 sessionStoreFile.close();
102 std::remove(sessionStoreFileName.data());
104 LOG(INFO) << connectionName <<
" MQTT Client: Restoring saved session done";
106 PLOG(WARNING) << connectionName <<
" MQTT Client: ... Could not read session store '" << sessionStoreFileName <<
"'";
109 LOG(INFO) << connectionName <<
" MQTT Client: Session not reloaded: Session store filename empty";
119 if (sessionStoreFile.is_open()) {
120 if (!sessionJson.empty()) {
121 sessionStoreFile << sessionJson;
124 sessionStoreFile.close();
129 LOG(INFO) <<
connectionName <<
" MQTT Client: Session not saved: Session store filename empty";
167 currentPacket =
nullptr;
171 return currentPacket;
200 LOG(ERROR) <<
connectionName <<
" MQTT Client: Negative ack received";
222 LOG(ERROR) <<
connectionName <<
" MQTT Client: PackageIdentifier missing";
225 LOG(DEBUG) <<
connectionName <<
" MQTT Client: PacketIdentifier: 0x" << std::hex << std::setfill(
'0') << std::setw(4)
228 std::stringstream ss;
229 std::list<uint8_t>::size_type i = 0;
237 ss <<
"0x" << std::hex << std::setfill(
'0') << std::setw(2) <<
static_cast<uint16_t>(returnCode) <<
" ";
240 LOG(DEBUG) <<
connectionName <<
" MQTT Client: Return codes: " << ss.str();
248 LOG(ERROR) <<
connectionName <<
" MQTT Client: PacketIdentifier missing";
251 LOG(DEBUG) <<
connectionName <<
" MQTT Client: PacketIdentifier: 0x" << std::hex << std::setfill(
'0') << std::setw(4)
263 const std::string& willTopic,
264 const std::string& willMessage,
267 const std::string& username,
268 const std::string& password,
269 bool loopPrevention)
const {
277 if (!topics.empty()) {
283 if (!topics.empty()) {
Timer & operator=(Timer &&timer) noexcept=default
static Timer intervalTimer(const std::function< void()> &dispatcher, const utils::Timeval &timeout)
virtual void end(bool fatal=false)=0
MqttContext * mqttContext
virtual void onPublish(const iot::mqtt::packets::Publish &publish)
std::string connectionName
Mqtt(const std::string &connectionName, const std::string &clientId)
bool _onPublish(const iot::mqtt::packets::Publish &publish)
void send(const iot::mqtt::ControlPacket &controlPacket) const
void initSession(Session *session, utils::Timeval keepAlive)
uint16_t getPacketIdentifier() const
virtual nlohmann::json toJson() const
void fromJson(const nlohmann::json &json)
virtual void deliverPacket(iot::mqtt::client::Mqtt *mqtt)=0
Mqtt(const std::string &connectionName, const std::string &clientId, uint16_t keepAlive, const std::string &sessionStoreFileName)
void _onPublish(const iot::mqtt::client::packets::Publish &publish)
void sendConnect(bool cleanSession, const std::string &willTopic, const std::string &willMessage, uint8_t willQoS, bool willRetain, const std::string &username, const std::string &password, bool loopPrevention=false) const
iot::mqtt::Session session
std::string sessionStoreFileName
void sendUnsubscribe(const std::list< std::string > &topics) const
void _onPingresp(const iot::mqtt::client::packets::Pingresp &pingresp)
virtual void onConnack(const iot::mqtt::packets::Connack &connack)
virtual void onPingresp(const iot::mqtt::packets::Pingresp &pingresp)
void sendSubscribe(const std::list< Topic > &topics) const
iot::mqtt::ControlPacketDeserializer * createControlPacketDeserializer(iot::mqtt::FixedHeader &fixedHeader) final
void _onSuback(const iot::mqtt::client::packets::Suback &suback)
virtual void onUnsuback(const iot::mqtt::packets::Unsuback &unsuback)
void _onConnack(const iot::mqtt::client::packets::Connack &connack)
void _onUnsuback(const iot::mqtt::client::packets::Unsuback &unsuback)
bool onSignal(int sig) override
virtual void onSuback(const iot::mqtt::packets::Suback &suback)
void deliverPacket(iot::mqtt::ControlPacketDeserializer *controlPacketDeserializer) override
void sendDisconnect() const
core::timer::Timer pingTimer
Connack(uint32_t remainingLength, uint8_t flags)
Pingresp(uint32_t remainingLength, uint8_t flags)
Puback(uint32_t remainingLength, uint8_t flags)
Pubcomp(uint32_t remainingLength, uint8_t flags)
Publish(uint32_t remainingLength, uint8_t flags)
Pubrec(uint32_t remainingLength, uint8_t flags)
Pubrel(uint32_t remainingLength, uint8_t flags)
Suback(uint32_t remainingLength, uint8_t flags)
Unsuback(uint32_t remainingLength, uint8_t flags)
uint8_t getReturnCode() const
bool getSessionPresent() const
uint8_t getAcknowledgeFlags() const
Connect(const std::string &clientId, uint16_t keepAlive, bool cleanSession, const std::string &willTopic, const std::string &willMessage, uint8_t willQoS, bool willRetain, const std::string &username, const std::string &password, bool loopPrevention)
uint16_t getPacketIdentifier() const
const std::list< uint8_t > & getReturnCodes() const
Subscribe(uint16_t packetIdentifier, const std::list< iot::mqtt::Topic > &topics)
uint16_t getPacketIdentifier() const
Unsubscribe(uint16_t packetIdentifier, const std::list< std::string > &topics)
#define MQTT_CONNACK_ACCEPT