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, const mosquitto_property *)
12 {
13  MQTTClient* self = static_cast<MQTTClient*>(context);
14 
15  if( !result )
16  {
17  for(const auto& topic: self->config().topics)
18  {
19  mosquitto_subscribe(mosq, nullptr, topic.c_str(), self->config().qos);
20  }
21  }
22  else
23  {
24  QMessageBox::warning(nullptr, "MQTT Client",
25  QString("Connection error: %1").arg(mosquitto_reason_string(result)),
26  QMessageBox::Ok);
27  }
28  self->_connected = true;
29 }
30 
31 void disconnect_callback(struct mosquitto *mosq, void *context, int result)
32 {
33  MQTTClient* self = static_cast<MQTTClient*>(context);
34 
35  if( self->isConnected() && result == MOSQ_ERR_CONN_LOST )
36  {
37  emit self->disconnected();
38  }
39 }
40 
41 void message_callback(struct mosquitto *mosq, void *context, const struct mosquitto_message *message, const mosquitto_property *)
42 {
43  MQTTClient* self = static_cast<MQTTClient*>(context);
44  self->onMessageReceived(message);
45 }
46 
47 //----------------------------
48 
50 {
51  mosquitto_lib_init();
52  _mosq = mosquitto_new(nullptr, true, this);
53 
54  mosquitto_connect_v5_callback_set(_mosq, connect_callback);
55  mosquitto_disconnect_callback_set(_mosq, disconnect_callback);
56  mosquitto_message_v5_callback_set(_mosq, message_callback);
57 }
58 
60 {
61  if(_connected)
62  {
63  disconnect();
64  }
65  mosquitto_lib_cleanup();
66 }
67 
69 {
70  if( _connected )
71  {
72  disconnect();
73  }
74 
75  mosquitto_int_option(_mosq, MOSQ_OPT_PROTOCOL_VERSION, config.protocol_version);
76 
77  if(( !config.username.empty() || !config.password.empty()) )
78  {
79  if(mosquitto_username_pw_set(_mosq, config.username.c_str(), config.password.c_str()))
80  {
81  return false;
82  }
83  }
84 
85  if( config.cafile.empty() == false )
86  {
87  const char *cafile = config.cafile.c_str();
88  const char *certfile = config.certfile.empty() ? nullptr: config.certfile.c_str();
89  const char *keyfile = config.keyfile.empty() ? nullptr: config.keyfile.c_str();
90 
91  mosquitto_tls_set(_mosq, cafile, nullptr, certfile, keyfile, nullptr);
92  }
93 
94  mosquitto_max_inflight_messages_set(_mosq, config.max_inflight);
95 
96  const mosquitto_property *properties = nullptr; // todo
97 
98  int rc = mosquitto_connect_bind_v5(_mosq,
99  config.host.c_str(),
100  config.port,
101  config.keepalive,
102  nullptr,
103  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",
116  QString("Error: %1").arg(err), 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 
152 {
153  std::unique_lock<std::mutex> lk(_mutex);
154  _message_callbacks[topic] = callback;
155 }
156 
157 void MQTTClient::onMessageReceived(const mosquitto_message * message)
158 {
159  std::unique_lock<std::mutex> lk(_mutex);
160 
161  _topics_set.insert(message->topic);
162 
163  auto it = _message_callbacks.find(message->topic);
164  if( it != _message_callbacks.end() )
165  {
166  it->second(message);
167  }
168 }
169 
171 {
172  return _config;
173 }
174 
175 std::unordered_set<std::string> MQTTClient::getTopicList()
176 {
177  std::unique_lock<std::mutex> lk(_mutex);
178  return _topics_set;
179 }
180 
181 void MQTTClient::subscribe(const std::string &topic, int qos)
182 {
183  mosquitto_subscribe(_mosq, nullptr, topic.c_str(), qos);
184 }
185 
186 void MQTTClient::unsubscribe(const std::string &topic)
187 {
188  mosquitto_unsubscribe(_mosq, nullptr, topic.c_str());
189 }
std::function< void(const mosquitto_message *)> TopicCallback
Definition: mqtt_client.h:29
std::string certfile
std::unordered_map< std::string, TopicCallback > _message_callbacks
Definition: mqtt_client.h:50
std::string password
bool isConnected() const
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
void addMessageCallback(const std::string &topic, TopicCallback callback)
void message_callback(struct mosquitto *mosq, void *context, const struct mosquitto_message *message, const mosquitto_property *)
Definition: mqtt_client.cpp:41
std::string username
void disconnect()
std::mutex _mutex
Definition: mqtt_client.h:52
std::unordered_set< std::string > getTopicList()
void connect_callback(struct mosquitto *mosq, void *context, int result, int, const mosquitto_property *)
Definition: mqtt_client.cpp:11
void subscribe(const std::string &topic, int qos)
unsigned int max_inflight
bool connect(const MosquittoConfig &config)
Definition: mqtt_client.cpp:68
std::string cafile
const MosquittoConfig & config() const
std::unordered_set< std::string > _topics_set
Definition: mqtt_client.h:51
void onMessageReceived(const mosquitto_message *message)
std::string keyfile
void unsubscribe(const std::string &topic)
void disconnect_callback(struct mosquitto *mosq, void *context, int result)
Definition: mqtt_client.cpp:31
MosquittoConfig _config
Definition: mqtt_client.h:53
void disconnected()
std::string host
bool _connected
Definition: mqtt_client.h:32
mosquitto * _mosq
Definition: mqtt_client.h:49


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:38