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,
const std::string& sessionStoreFileName)
79 : Super
(connectionName
, clientId
)
81 if (!sessionStoreFileName.empty()) {
82 std::ifstream sessionStoreFile(sessionStoreFileName);
84 if (sessionStoreFile.is_open()) {
86 nlohmann::json sessionStoreJson;
88 sessionStoreFile >> sessionStoreJson;
92 LOG(DEBUG) << connectionName <<
" MQTT Client: ... Persistent session data loaded successful";
93 }
catch (
const nlohmann::json::exception&) {
94 LOG(DEBUG) << connectionName <<
" MQTT Client: ... Starting with empty session: Session store '"
95 << sessionStoreFileName <<
"' empty or corrupted";
100 sessionStoreFile.close();
101 std::remove(sessionStoreFileName.data());
103 LOG(INFO) << connectionName <<
" MQTT Client: Restoring saved session done";
105 PLOG(WARNING) << connectionName <<
" MQTT Client: ... Could not read session store '" << sessionStoreFileName <<
"'";
108 LOG(INFO) << connectionName <<
" MQTT Client: Session not reloaded: Session store filename empty";
118 if (sessionStoreFile.is_open()) {
119 if (!sessionJson.empty()) {
120 sessionStoreFile << sessionJson;
123 sessionStoreFile.close();
128 LOG(INFO) <<
connectionName <<
" MQTT Client: Session not saved: Session store filename empty";
166 currentPacket =
nullptr;
170 return currentPacket;
199 LOG(ERROR) <<
connectionName <<
" MQTT Client: Negative ack received";
221 LOG(ERROR) <<
connectionName <<
" MQTT Client: PackageIdentifier missing";
224 LOG(DEBUG) <<
connectionName <<
" MQTT Client: PacketIdentifier: 0x" << std::hex << std::setfill(
'0') << std::setw(4)
227 std::stringstream ss;
228 std::list<uint8_t>::size_type i = 0;
236 ss <<
"0x" << std::hex << std::setfill(
'0') << std::setw(2) <<
static_cast<uint16_t>(returnCode) <<
" ";
239 LOG(DEBUG) <<
connectionName <<
" MQTT Client: Return codes: " << ss.str();
247 LOG(ERROR) <<
connectionName <<
" MQTT Client: PacketIdentifier missing";
250 LOG(DEBUG) <<
connectionName <<
" MQTT Client: PacketIdentifier: 0x" << std::hex << std::setfill(
'0') << std::setw(4)
262 const std::string& clientId,
264 const std::string& willTopic,
265 const std::string& willMessage,
268 const std::string& username,
269 const std::string& password,
270 bool loopPrevention) {
273 LOG(INFO) <<
connectionName <<
" MQTT Client: CONNECT send: " << clientId;
276 clientId
, keepAlive
, cleanSession
, willTopic
, willMessage
, willQoS
, willRetain
, username
, password
, loopPrevention
));
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)
uint16_t getPacketIdentifier()
bool _onPublish(const iot::mqtt::packets::Publish &publish)
void send(const iot::mqtt::ControlPacket &controlPacket) const
void initSession(Session *session, utils::Timeval keepAlive)
virtual nlohmann::json toJson() const
void fromJson(const nlohmann::json &json)
virtual void deliverPacket(iot::mqtt::client::Mqtt *mqtt)=0
void _onPublish(const iot::mqtt::client::packets::Publish &publish)
void sendConnect(uint16_t keepAlive, const std::string &clientId, 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)
iot::mqtt::Session session
std::string sessionStoreFileName
Mqtt(const std::string &connectionName, const std::string &clientId, const std::string &sessionStoreFileName)
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)
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)
void sendUnsubscribe(const std::list< std::string > &topics)
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