From 4e79c8ac57329796a580e5adf2a6c91c50d56116 Mon Sep 17 00:00:00 2001 From: Thomas Meyerdirks Date: Fri, 10 Nov 2023 11:30:17 +0100 Subject: [PATCH 1/4] segmentation fault init mqtt with an old mosquitto version --- .../inc/MqttConnectionClient.h | 8 ++++ .../MqttConnectionClient.cpp | 48 +++++++++++-------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/AgrirouterClient/inc/MqttConnectionClient.h b/lib/AgrirouterClient/inc/MqttConnectionClient.h index f86e7f9..6f8f9bf 100644 --- a/lib/AgrirouterClient/inc/MqttConnectionClient.h +++ b/lib/AgrirouterClient/inc/MqttConnectionClient.h @@ -5,6 +5,8 @@ #include "Settings.h" #include "third_party/mosquitto/mosquitto.h" +#include + class MqttConnectionClient { public: @@ -29,6 +31,9 @@ class MqttConnectionClient { void setMember(void* member); void* getMember(); + static std::string getStaticSecret(); + static void setStaticSecret(std::string secret); + bool isConnected(); private: @@ -45,6 +50,9 @@ class MqttConnectionClient { MqttCallback m_mqttCallback; MqttErrorCallback m_mqttErrorCallback; + static std::string globalSecret; + static std::mutex mutexSecret; + static int onPWCallback(char *buf, int size, int rwflag, void *userdata); static void connectCallback(struct mosquitto *mosq, void *obj, int result); static void disconnectCallback(struct mosquitto *mosq, void *obj, int result); diff --git a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp index 73b442d..6ba079f 100644 --- a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp +++ b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp @@ -2,12 +2,16 @@ #include "third_party/mosquitto/mosquitto_internal.h" +std::string MqttConnectionClient::globalSecret = ""; +std::mutex MqttConnectionClient::mutexSecret; + MqttConnectionClient::MqttConnectionClient(const std::string& clientId, const std::string& host, int port, Settings *settings) { m_clientId = clientId; m_port = port; m_host = host; m_settings = settings; + setStaticSecret(m_settings->getConnectionParameters().secret); } MqttConnectionClient::~MqttConnectionClient() @@ -27,11 +31,6 @@ int MqttConnectionClient::init() if (m_mosq != nullptr) { - // set this to mosq for the pw_callback - // the function mosquitto_user_data_set(..) not working for this callback - // the direct set to struct, not the best solution but it works - m_mosq->userdata = this; - mosquitto_connect_callback_set(m_mosq, connectCallback); mosquitto_disconnect_callback_set(m_mosq, disconnectCallback); mosquitto_publish_callback_set(m_mosq, publishCallback); @@ -114,7 +113,7 @@ int MqttConnectionClient::init() (m_mqttErrorCallback) (loop, errorMessage, "", m_member); return EXIT_FAILURE; } - + if ((connect == MOSQ_ERR_SUCCESS) && (loop == MOSQ_ERR_SUCCESS)) { return EXIT_SUCCESS; @@ -153,11 +152,7 @@ void* MqttConnectionClient::getMember() { return m_member; } int MqttConnectionClient::onPWCallback(char *buf, int size, int rwflag, void *userdata) { - struct mosquitto *mosq = static_cast(userdata); - MqttConnectionClient *self = static_cast(mosq->userdata); - std::string secret = self->m_settings->getConnectionParameters().secret.c_str(); - - strncpy(buf, secret.c_str(), size); + strncpy(buf, getStaticSecret().c_str(), size); buf[size-1] = '\0'; return strlen(buf); } @@ -178,7 +173,6 @@ void MqttConnectionClient::connectCallback(struct mosquitto *mosq, void *obj, in self->m_settings->callOnLog(MG_LFL_ERR, errorMessage); (self->m_mqttErrorCallback) (reasonCode, errorMessage, "", self->m_member); } - } void MqttConnectionClient::disconnectCallback(struct mosquitto *mosq, void *obj, int reasonCode) @@ -187,13 +181,13 @@ void MqttConnectionClient::disconnectCallback(struct mosquitto *mosq, void *obj, self->m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: disconnect callback with result: '" + std::to_string(reasonCode) + ":" + mosquitto_strerror(reasonCode) + "'"); self->m_connected = false; - // reasonCode 0 disconnect is called by client, so no reconnect on destruct mqtt client + // reasonCode 0 disconnect is called by client, so no reconnect on destruct mqtt client if(reasonCode > 0) { std::string errorMessage = "MqttConnectionClient: disconnect unexpected " + std::to_string(reasonCode) + ": " + mosquitto_connack_string(reasonCode); self->m_settings->callOnLog(MG_LFL_ERR, errorMessage); (self->m_mqttErrorCallback) (reasonCode, errorMessage, "", self->m_member); - + // try to reconnect int reconn = mosquitto_reconnect(self->m_mosq); @@ -219,7 +213,7 @@ void MqttConnectionClient::publishCallback(struct mosquitto *mosq, void *obj, in void MqttConnectionClient::loggingCallback(struct mosquitto *mosq, void *obj, int level, const char *message) { MqttConnectionClient *self = static_cast(obj); - self->m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: logging callback with message: '" + std::string(message) + + self->m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: logging callback with message: '" + std::string(message) + "' and Log level: '" + std::to_string(level) + "'"); if(std::string(message).find("tls_process_server_certificate:certificate verify failed") != std::string::npos) @@ -243,7 +237,7 @@ void MqttConnectionClient::subscribeCallback(struct mosquitto *mosq, void *obj, } else { - std::string errorMessage = "MqttConnectionClient: subscribe callback count " + std::to_string(i) + " failed with " + std::to_string(grantedQos[i]); + std::string errorMessage = "MqttConnectionClient: subscribe callback count " + std::to_string(i) + " failed with " + std::to_string(grantedQos[i]); self->m_settings->callOnLog(MG_LFL_ERR, errorMessage); (self->m_mqttErrorCallback) (grantedQos[i], errorMessage, "", self->m_member); } @@ -259,7 +253,7 @@ void MqttConnectionClient::unsubscribeCallback(struct mosquitto *mosq, void *obj void MqttConnectionClient::messageCallback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { MqttConnectionClient *self = static_cast(obj); - self->m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(message->mid) + "] messageCallback on topic " + + self->m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(message->mid) + "] messageCallback on topic " + message->topic + " with qos " + std::to_string(message->qos)); (self->m_mqttCallback)(message->topic, message->payload, message->payloadlen, self->m_member); @@ -267,7 +261,7 @@ void MqttConnectionClient::messageCallback(struct mosquitto *mosq, void *obj, co void MqttConnectionClient::subscribe(const std::string& topic, int qos) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] subscribing on topic " + + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] subscribing on topic " + topic.c_str() + " with qos " + std::to_string(qos)); mosquitto_subscribe(m_mosq, &(m_messageId), topic.c_str(), qos); @@ -276,7 +270,7 @@ void MqttConnectionClient::subscribe(const std::string& topic, int qos) void MqttConnectionClient::publish(const std::string& topic, const std::string& payload, int qos) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + topic.c_str() + " with qos " + std::to_string(qos) + " and payload-length " + std::to_string(payload.length())); mosquitto_publish(m_mosq, &(m_messageId), topic.c_str(), strlen(payload.c_str()), payload.c_str(), qos, 0); @@ -285,7 +279,7 @@ void MqttConnectionClient::publish(const std::string& topic, const std::string& void MqttConnectionClient::publish(const std::string& topic, char *payload, int size, int qos) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + topic.c_str() + " with qos " + std::to_string(qos) + " and size " + std::to_string(size)); mosquitto_publish(m_mosq, &(m_messageId), topic.c_str(), size, payload, qos, false); @@ -294,7 +288,7 @@ void MqttConnectionClient::publish(const std::string& topic, char *payload, int void MqttConnectionClient::publish(const std::string& topic, char *payload, int size, int qos, bool retain) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: [MsgId: " + std::to_string(m_messageId) + "] publishing on topic " + topic.c_str() + " with qos " + std::to_string(qos) + " and size " + std::to_string(size) + " and retain " + std::to_string(retain)); mosquitto_publish(m_mosq, &(m_messageId), topic.c_str(), size, payload, qos, retain); @@ -305,3 +299,15 @@ bool MqttConnectionClient::isConnected() { return m_connected; } + +void MqttConnectionClient::setStaticSecret(std::string secret) +{ + std::lock_guard lock(mutexSecret); + globalSecret = secret; +} + +std::string MqttConnectionClient::getStaticSecret() +{ + std::lock_guard lock(mutexSecret); + return globalSecret; +} From ab0ebcad2bddad3af3e009d00094770aa5dbf598 Mon Sep 17 00:00:00 2001 From: Thomas Meyerdirks Date: Fri, 10 Nov 2023 11:42:52 +0100 Subject: [PATCH 2/4] use private methods --- lib/AgrirouterClient/inc/MqttConnectionClient.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/AgrirouterClient/inc/MqttConnectionClient.h b/lib/AgrirouterClient/inc/MqttConnectionClient.h index 6f8f9bf..7f0e910 100644 --- a/lib/AgrirouterClient/inc/MqttConnectionClient.h +++ b/lib/AgrirouterClient/inc/MqttConnectionClient.h @@ -31,9 +31,6 @@ class MqttConnectionClient { void setMember(void* member); void* getMember(); - static std::string getStaticSecret(); - static void setStaticSecret(std::string secret); - bool isConnected(); private: @@ -50,9 +47,6 @@ class MqttConnectionClient { MqttCallback m_mqttCallback; MqttErrorCallback m_mqttErrorCallback; - static std::string globalSecret; - static std::mutex mutexSecret; - static int onPWCallback(char *buf, int size, int rwflag, void *userdata); static void connectCallback(struct mosquitto *mosq, void *obj, int result); static void disconnectCallback(struct mosquitto *mosq, void *obj, int result); @@ -61,6 +55,11 @@ class MqttConnectionClient { static void subscribeCallback(struct mosquitto *mosq, void *obj, int messageId, int qosCount, const int *grantedQos); static void unsubscribeCallback(struct mosquitto *mosq, void *obj, int messageId); static void messageCallback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message); + + static std::string globalSecret; + static std::mutex mutexSecret; + static std::string getStaticSecret(); + static void setStaticSecret(std::string secret); }; #endif // LIB_AGRIROUTERCLIENT_INC_MQTTCONNECTIONCLIENT_H_ From 55573c50f5a12d676c85fb9d466e58aebdfc04de Mon Sep 17 00:00:00 2001 From: Thomas Meyerdirks Date: Mon, 13 Nov 2023 07:33:54 +0100 Subject: [PATCH 3/4] first loop and then connect to connect on broker that missing on startup --- .../MqttConnectionClient.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp index 6ba079f..4ed1462 100644 --- a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp +++ b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp @@ -88,29 +88,29 @@ int MqttConnectionClient::init() keepAliveTime = DEFAULT_KEEP_ALIVE_TIME; } - int connect = mosquitto_connect_async(m_mosq, m_host.c_str(), m_port, keepAliveTime); - if(connect == MOSQ_ERR_SUCCESS) + int loop = mosquitto_loop_start(m_mosq); + if(loop == MOSQ_ERR_SUCCESS) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: connect set successful - " + std::to_string(connect) + ": " + mosquitto_strerror(connect)); + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: loop set successful - " + std::to_string(loop) + ": " + mosquitto_strerror(loop)); } else { - std::string errorMessage = "MqttConnectionClient: connect set failed " + std::to_string(connect) + ": " + mosquitto_strerror(connect); + std::string errorMessage = "MqttConnectionClient: loop start failed " + std::to_string(loop) + ": " + mosquitto_strerror(loop); m_settings->callOnLog(MG_LFL_ERR, errorMessage); - (m_mqttErrorCallback) (connect, errorMessage, "", m_member); + (m_mqttErrorCallback) (loop, errorMessage, "", m_member); return EXIT_FAILURE; } - int loop = mosquitto_loop_start(m_mosq); - if(loop == MOSQ_ERR_SUCCESS) + int connect = mosquitto_connect_async(m_mosq, m_host.c_str(), m_port, keepAliveTime); + if(connect == MOSQ_ERR_SUCCESS) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: loop set successful - " + std::to_string(loop) + ": " + mosquitto_strerror(loop)); + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: connect set successful - " + std::to_string(connect) + ": " + mosquitto_strerror(connect)); } else { - std::string errorMessage = "MqttConnectionClient: loop start failed " + std::to_string(loop) + ": " + mosquitto_strerror(loop); + std::string errorMessage = "MqttConnectionClient: connect set failed " + std::to_string(connect) + ": " + mosquitto_strerror(connect); m_settings->callOnLog(MG_LFL_ERR, errorMessage); - (m_mqttErrorCallback) (loop, errorMessage, "", m_member); + (m_mqttErrorCallback) (connect, errorMessage, "", m_member); return EXIT_FAILURE; } From 7864fce54be00246ba65d36c8a1531117117d0c8 Mon Sep 17 00:00:00 2001 From: Thomas Meyerdirks Date: Mon, 13 Nov 2023 11:30:15 +0100 Subject: [PATCH 4/4] revert change loop and connect - no connection in this case --- .../MqttConnectionClient.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp index 4ed1462..6ba079f 100644 --- a/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp +++ b/lib/AgrirouterClient/src/ConnectionProvider/MqttConnectionClient.cpp @@ -88,29 +88,29 @@ int MqttConnectionClient::init() keepAliveTime = DEFAULT_KEEP_ALIVE_TIME; } - int loop = mosquitto_loop_start(m_mosq); - if(loop == MOSQ_ERR_SUCCESS) + int connect = mosquitto_connect_async(m_mosq, m_host.c_str(), m_port, keepAliveTime); + if(connect == MOSQ_ERR_SUCCESS) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: loop set successful - " + std::to_string(loop) + ": " + mosquitto_strerror(loop)); + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: connect set successful - " + std::to_string(connect) + ": " + mosquitto_strerror(connect)); } else { - std::string errorMessage = "MqttConnectionClient: loop start failed " + std::to_string(loop) + ": " + mosquitto_strerror(loop); + std::string errorMessage = "MqttConnectionClient: connect set failed " + std::to_string(connect) + ": " + mosquitto_strerror(connect); m_settings->callOnLog(MG_LFL_ERR, errorMessage); - (m_mqttErrorCallback) (loop, errorMessage, "", m_member); + (m_mqttErrorCallback) (connect, errorMessage, "", m_member); return EXIT_FAILURE; } - int connect = mosquitto_connect_async(m_mosq, m_host.c_str(), m_port, keepAliveTime); - if(connect == MOSQ_ERR_SUCCESS) + int loop = mosquitto_loop_start(m_mosq); + if(loop == MOSQ_ERR_SUCCESS) { - m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: connect set successful - " + std::to_string(connect) + ": " + mosquitto_strerror(connect)); + m_settings->callOnLog(MG_LFL_NTC, "MqttConnectionClient: loop set successful - " + std::to_string(loop) + ": " + mosquitto_strerror(loop)); } else { - std::string errorMessage = "MqttConnectionClient: connect set failed " + std::to_string(connect) + ": " + mosquitto_strerror(connect); + std::string errorMessage = "MqttConnectionClient: loop start failed " + std::to_string(loop) + ": " + mosquitto_strerror(loop); m_settings->callOnLog(MG_LFL_ERR, errorMessage); - (m_mqttErrorCallback) (connect, errorMessage, "", m_member); + (m_mqttErrorCallback) (loop, errorMessage, "", m_member); return EXIT_FAILURE; }