mqtt_client.cpp
Go to the documentation of this file.
1 #include "mqtt_client.h"
2 #include <QDebug>
3 #include <QMessageBox>
4 #include <QString>
5 
6 #ifdef WIN32
7 #include <windows.h>
8 #include <strsafe.h>
9 #endif
10 
11 void connect_callback(struct mosquitto* mosq, void* context, int result, int,
12  const mosquitto_property*)
13 {
14  MQTTClient* self = static_cast<MQTTClient*>(context);
15 
16  if (!result)
17  {
18  for (const auto& topic : self->config().topics)
19  {
20  mosquitto_subscribe(mosq, nullptr, topic.c_str(), self->config().qos);
21  }
22  }
23  else
24  {
25  QMessageBox::warning(
26  nullptr, "MQTT Client",
27  QString("Connection error: %1").arg(mosquitto_reason_string(result)),
28  QMessageBox::Ok);
29  }
30  self->_connected = true;
31 }
32 
33 void disconnect_callback(struct mosquitto* mosq, void* context, int result)
34 {
35  MQTTClient* self = static_cast<MQTTClient*>(context);
36 
37  if (self->isConnected() && result == MOSQ_ERR_CONN_LOST)
38  {
39  emit self->disconnected();
40  }
41 }
42 
43 void message_callback(struct mosquitto* mosq, void* context,
44  const struct mosquitto_message* message, const mosquitto_property*)
45 {
46  MQTTClient* self = static_cast<MQTTClient*>(context);
47  self->onMessageReceived(message);
48 }
49 
50 //----------------------------
51 
53 {
54  mosquitto_lib_init();
55  _mosq = mosquitto_new(nullptr, true, this);
56 
57  mosquitto_connect_v5_callback_set(_mosq, connect_callback);
58  mosquitto_disconnect_callback_set(_mosq, disconnect_callback);
59  mosquitto_message_v5_callback_set(_mosq, message_callback);
60 }
61 
63 {
64  if (_connected)
65  {
66  disconnect();
67  }
68  mosquitto_lib_cleanup();
69 }
70 
72 {
73  if (_connected)
74  {
75  disconnect();
76  }
77 
78  mosquitto_int_option(_mosq, MOSQ_OPT_PROTOCOL_VERSION, config.protocol_version);
79 
80  if ((!config.username.empty() || !config.password.empty()))
81  {
82  if (mosquitto_username_pw_set(_mosq, config.username.c_str(),
83  config.password.c_str()))
84  {
85  return false;
86  }
87  }
88 
89  if (config.cafile.empty() == false)
90  {
91  const char* cafile = config.cafile.c_str();
92  const char* certfile = config.certfile.empty() ? nullptr : config.certfile.c_str();
93  const char* keyfile = config.keyfile.empty() ? nullptr : config.keyfile.c_str();
94 
95  mosquitto_tls_set(_mosq, cafile, nullptr, certfile, keyfile, nullptr);
96  }
97 
98  mosquitto_max_inflight_messages_set(_mosq, config.max_inflight);
99 
100  const mosquitto_property* properties = nullptr; // todo
101 
102  int rc = mosquitto_connect_bind_v5(_mosq, config.host.c_str(), config.port,
103  config.keepalive, nullptr, properties);
104  // TODO bind
105  if (rc > 0)
106  {
107  if (rc == MOSQ_ERR_ERRNO)
108  {
109  char err[1024];
110 #ifndef WIN32
111  strerror_r(errno, err, 1024);
112 #else
113  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL);
114 #endif
115  QMessageBox::warning(nullptr, "MQTT Client", QString("Error: %1").arg(err),
116  QMessageBox::Ok);
117  }
118  else
119  {
120  QMessageBox::warning(nullptr, "MQTT Client",
121  QString("Unable to connect (%1)").arg(mosquitto_strerror(rc)),
122  QMessageBox::Ok);
123  }
124  _connected = false;
125  return false;
126  }
127 
128  _connected = true;
129  _config = config;
130  mosquitto_loop_start(_mosq);
131  return true;
132 }
133 
135 {
136  if (_connected)
137  {
138  mosquitto_disconnect(_mosq);
139  mosquitto_loop_stop(_mosq, true);
140  }
141  _connected = false;
142  _topics_set.clear();
143  _message_callbacks.clear();
144 }
145 
147 {
148  return _connected;
149 }
150 
151 void MQTTClient::addMessageCallback(const std::string& topic,
152  MQTTClient::TopicCallback callback)
153 {
154  std::unique_lock<std::mutex> lk(_mutex);
155  _message_callbacks[topic] = callback;
156 }
157 
158 void MQTTClient::onMessageReceived(const mosquitto_message* message)
159 {
160  std::unique_lock<std::mutex> lk(_mutex);
161 
162  _topics_set.insert(message->topic);
163 
164  auto it = _message_callbacks.find(message->topic);
165  if (it != _message_callbacks.end())
166  {
167  it->second(message);
168  }
169 }
170 
172 {
173  return _config;
174 }
175 
176 std::unordered_set<std::string> MQTTClient::getTopicList()
177 {
178  std::unique_lock<std::mutex> lk(_mutex);
179  return _topics_set;
180 }
181 
182 void MQTTClient::subscribe(const std::string& topic, int qos)
183 {
184  mosquitto_subscribe(_mosq, nullptr, topic.c_str(), qos);
185 }
186 
187 void MQTTClient::unsubscribe(const std::string& topic)
188 {
189  mosquitto_unsubscribe(_mosq, nullptr, topic.c_str());
190 }
MQTTClient::subscribe
void subscribe(const std::string &topic, int qos)
Definition: mqtt_client.cpp:182
MQTTClient::connect
bool connect(const MosquittoConfig &config)
Definition: mqtt_client.cpp:71
MQTTClient::onMessageReceived
void onMessageReceived(const mosquitto_message *message)
Definition: mqtt_client.cpp:158
MosquittoConfig::host
std::string host
Definition: mosquitto_config.h:12
MQTTClient::disconnect
void disconnect()
Definition: mqtt_client.cpp:134
MQTTClient::MQTTClient
MQTTClient()
Definition: mqtt_client.cpp:52
MosquittoConfig::password
std::string password
Definition: mosquitto_config.h:22
MosquittoConfig::port
int port
Definition: mosquitto_config.h:13
MQTTClient::TopicCallback
std::function< void(const mosquitto_message *)> TopicCallback
Definition: mqtt_client.h:29
arg
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1875
MosquittoConfig::username
std::string username
Definition: mosquitto_config.h:21
MQTTClient
Definition: mqtt_client.h:13
message_callback
void message_callback(struct mosquitto *mosq, void *context, const struct mosquitto_message *message, const mosquitto_property *)
Definition: mqtt_client.cpp:43
MQTTClient::config
const MosquittoConfig & config() const
Definition: mqtt_client.cpp:171
MQTTClient::_connected
bool _connected
Definition: mqtt_client.h:32
MQTTClient::_topics_set
std::unordered_set< std::string > _topics_set
Definition: mqtt_client.h:51
MosquittoConfig::keyfile
std::string keyfile
Definition: mosquitto_config.h:27
MQTTClient::_config
MosquittoConfig _config
Definition: mqtt_client.h:53
start_test_publisher.topic
topic
Definition: start_test_publisher.py:22
MosquittoConfig::max_inflight
unsigned int max_inflight
Definition: mosquitto_config.h:20
disconnect_callback
void disconnect_callback(struct mosquitto *mosq, void *context, int result)
Definition: mqtt_client.cpp:33
MQTTClient::unsubscribe
void unsubscribe(const std::string &topic)
Definition: mqtt_client.cpp:187
MosquittoConfig
Definition: mosquitto_config.h:8
MQTTClient::disconnected
void disconnected()
MosquittoConfig::cafile
std::string cafile
Definition: mosquitto_config.h:24
MQTTClient::_message_callbacks
std::unordered_map< std::string, TopicCallback > _message_callbacks
Definition: mqtt_client.h:50
MQTTClient::~MQTTClient
~MQTTClient()
Definition: mqtt_client.cpp:62
connect_callback
void connect_callback(struct mosquitto *mosq, void *context, int result, int, const mosquitto_property *)
Definition: mqtt_client.cpp:11
MQTTClient::_mosq
mosquitto * _mosq
Definition: mqtt_client.h:49
MosquittoConfig::keepalive
int keepalive
Definition: mosquitto_config.h:11
MQTTClient::isConnected
bool isConnected() const
Definition: mqtt_client.cpp:146
MQTTClient::addMessageCallback
void addMessageCallback(const std::string &topic, TopicCallback callback)
Definition: mqtt_client.cpp:151
MQTTClient::_mutex
std::mutex _mutex
Definition: mqtt_client.h:52
MosquittoConfig::certfile
std::string certfile
Definition: mosquitto_config.h:26
MQTTClient::getTopicList
std::unordered_set< std::string > getTopicList()
Definition: mqtt_client.cpp:176
nullptr
#define nullptr
Definition: backward.hpp:386
MosquittoConfig::protocol_version
int protocol_version
Definition: mosquitto_config.h:10
mqtt_client.h


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:23