diff --git a/src/MQTTAsync.c b/src/MQTTAsync.c index c6a11f6d..a45c9fec 100644 --- a/src/MQTTAsync.c +++ b/src/MQTTAsync.c @@ -1644,6 +1644,26 @@ int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* return rc; } +int MQTTAsync_setConnectionError(MQTTAsync handle, void* context, MQTTAsync_connectionError* ce) +{ + int rc = MQTTASYNC_SUCCESS; + MQTTAsyncs* m = handle; + + FUNC_ENTRY; + MQTTAsync_lock_mutex(mqttasync_mutex); + + if (m == NULL || m->c->connect_state != NOT_IN_PROGRESS) + rc = MQTTASYNC_FAILURE; + else + { + m->connection_error_context = context; + m->connection_error = ce; + } + + MQTTAsync_unlock_mutex(mqttasync_mutex); + FUNC_EXIT_RC(rc); + return rc; +} int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* updateOptions) { diff --git a/src/MQTTAsync.h b/src/MQTTAsync.h index e11af048..593c5911 100644 --- a/src/MQTTAsync.h +++ b/src/MQTTAsync.h @@ -429,6 +429,25 @@ typedef void MQTTAsync_connectionLost(void* context, char* cause); */ typedef void MQTTAsync_connected(void* context, char* cause); +/** + * This is a callback function, which will be called when the client library + * have some errors during connection process. This is superfluous when the + * connection is made in response to a MQTTAsync_connect call, because the + * onFailure callback can be used. It is intended for use when automatic + * reconnect is enabled or after MQTTAsync_reconnect() function, so that when + * a connection attempt failed in the background, the application is notified + * and can take any required actions. + * + * Note: Neither MQTTAsync_create() nor MQTTAsync_destroy() should be + * called within this callback. + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param code A numeric code identifying the error. + * @param cause Optional text explaining the error. Can be NULL. + */ +typedef void MQTTAsync_connectionError(void* context, int code, char *cause); + /** * This is a callback function, which will be called when the client * library receives a disconnect packet from the server. This applies to MQTT V5 and above only. @@ -889,6 +908,21 @@ LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* co */ LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co); +/** + * This function sets the callback function for a situation when there is + * a problem connecting to the broker after calling the MQTTAsync_connect(), + * MQTTAsync_reconnect() or automatic reconnection functions. + * @param handle A valid client handle from a successful call to + * MQTTAsync_create(). + * @param context A pointer to any application-specific context. The + * the context pointer is passed to each of the callback functions to + * provide access to the context information in the callback. + * @param ce A pointer to an MQTTAsync_connectionError() callback + * function. NULL removes the callback setting. + * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set, + * ::MQTTASYNC_FAILURE if an error occurred. + */ +LIBMQTT_API int MQTTAsync_setConnectionError(MQTTAsync handle, void* context, MQTTAsync_connectionError* ce); /** * Reconnects a client with the previously used connect options. Connect diff --git a/src/MQTTAsyncUtils.c b/src/MQTTAsyncUtils.c index 6d933040..be4a3ffb 100644 --- a/src/MQTTAsyncUtils.c +++ b/src/MQTTAsyncUtils.c @@ -1504,6 +1504,11 @@ static int MQTTAsync_processCommand(void) command->client->connect.onFailure5 = NULL; command->client->connect.onSuccess5 = NULL; } + if (command->client->connection_error) { + Log(TRACE_MIN, -1, "Calling connection error for client %s", command->client->c->clientID); + (*(command->client->connection_error))(command->client->connection_error_context, + MQTTASYNC_OPERATION_INCOMPLETE, NULL); + } } command->client->c->connect_state = DISCONNECTING; MQTTAsync_checkDisconnect(command->client, &command->command); @@ -1577,6 +1582,10 @@ static int MQTTAsync_processCommand(void) Log(TRACE_MIN, -1, "Calling command failure for client %s", command->client->c->clientID); (*(command->command.onFailure5))(command->command.context, &data); } + if (command->client->connection_error) { + Log(TRACE_MIN, -1, "Calling connection error for client %s", command->client->c->clientID); + (*(command->client->connection_error))(command->client->connection_error_context, rc, NULL); + } if (command->command.type == CONNECT) { command->client->connect = command->command; @@ -1668,6 +1677,10 @@ static void nextOrClose(MQTTAsyncs* m, int rc, char* message) m->connect.onFailure5 = NULL; m->connect.onSuccess5 = NULL; } + if (m->connection_error) { + Log(TRACE_MIN, -1, "Calling connection error for client %s", m->c->clientID); + (*(m->connection_error))(m->connection_error_context, rc, message); + } if (connectionLost_called == 0 && m->cl && was_connected) { Log(TRACE_MIN, -1, "Calling connectionLost for client %s", m->c->clientID); diff --git a/src/MQTTAsyncUtils.h b/src/MQTTAsyncUtils.h index 0e08beac..df959c76 100644 --- a/src/MQTTAsyncUtils.h +++ b/src/MQTTAsyncUtils.h @@ -104,6 +104,9 @@ typedef struct MQTTAsync_struct MQTTAsync_connected* connected; void* connected_context; /* the context to be associated with the connected callback*/ + MQTTAsync_connectionError* connection_error; + void* connection_error_context; /* the context to be associated with the connection error callback*/ + MQTTAsync_disconnected* disconnected; void* disconnected_context; /* the context to be associated with the disconnected callback*/