A small footprint MQTT library
Dependents: STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more
Diff: mqtt_client.c
- Revision:
- 23:80794cfb3565
- Parent:
- 19:e283dcf26037
- Child:
- 24:75f5b91d1c6e
--- a/mqtt_client.c Fri Nov 17 13:58:21 2017 -0800 +++ b/mqtt_client.c Wed Jan 17 08:57:29 2018 -0800 @@ -16,7 +16,6 @@ #include "azure_umqtt_c/mqtt_codec.h" #include <inttypes.h> -#define KEEP_ALIVE_BUFFER_SEC 10 #define VARIABLE_HEADER_OFFSET 2 #define RETAIN_FLAG_MASK 0x1 #define QOS_LEAST_ONCE_FLAG_MASK 0x2 @@ -25,7 +24,7 @@ #define CONNECT_PACKET_MASK 0xf0 #define TIME_MAX_BUFFER 16 #define DEFAULT_MAX_PING_RESPONSE_TIME 80 // % of time to send pings -#define MAX_CLOSE_RETRIES 10 +#define MAX_CLOSE_RETRIES 2 static const char* TRUE_CONST = "true"; static const char* FALSE_CONST = "false"; @@ -73,16 +72,26 @@ static void close_connection(MQTT_CLIENT* mqtt_client) { - (void)xio_close(mqtt_client->xioHandle, on_connection_closed, mqtt_client); - if (mqtt_client->disconnect_cb == NULL) + if (mqtt_client->socketConnected) { - size_t counter = 0; - do + (void)xio_close(mqtt_client->xioHandle, on_connection_closed, mqtt_client); + if (mqtt_client->disconnect_cb == NULL) { - xio_dowork(mqtt_client->xioHandle); - counter++; - ThreadAPI_Sleep(2); - } while (mqtt_client->clientConnected && counter < MAX_CLOSE_RETRIES); + size_t counter = 0; + do + { + xio_dowork(mqtt_client->xioHandle); + counter++; + ThreadAPI_Sleep(2); + } while (mqtt_client->clientConnected && counter < MAX_CLOSE_RETRIES); + } + } + else + { + if (mqtt_client->disconnect_cb) + { + mqtt_client->disconnect_cb(mqtt_client->disconnect_ctx); + } } } @@ -1153,43 +1162,56 @@ } else { - BUFFER_HANDLE disconnectPacket = mqtt_codec_disconnect(); - if (disconnectPacket == NULL) + if (mqtt_client->clientConnected) { - /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/ - LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect failed"); - mqtt_client->packetState = PACKET_TYPE_ERROR; - result = __FAILURE__; - } - else - { - /* Codes_SRS_MQTT_CLIENT_07_037: [ if callback is not NULL callback shall be called once the mqtt connection has been disconnected ] */ - mqtt_client->disconnect_cb = callback; - mqtt_client->disconnect_ctx = ctx; - mqtt_client->packetState = DISCONNECT_TYPE; - - size_t size = BUFFER_length(disconnectPacket); - /*Codes_SRS_MQTT_CLIENT_07_012: [On success mqtt_client_disconnect shall send the MQTT DISCONNECT packet to the endpoint.]*/ - if (sendPacketItem(mqtt_client, BUFFER_u_char(disconnectPacket), size) != 0) + BUFFER_HANDLE disconnectPacket = mqtt_codec_disconnect(); + if (disconnectPacket == NULL) { /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/ - LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect send failed"); + LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect failed"); + mqtt_client->packetState = PACKET_TYPE_ERROR; result = __FAILURE__; } else { - if (mqtt_client->logTrace) + /* Codes_SRS_MQTT_CLIENT_07_037: [ if callback is not NULL callback shall be called once the mqtt connection has been disconnected ] */ + mqtt_client->disconnect_cb = callback; + mqtt_client->disconnect_ctx = ctx; + mqtt_client->packetState = DISCONNECT_TYPE; + + size_t size = BUFFER_length(disconnectPacket); + /*Codes_SRS_MQTT_CLIENT_07_012: [On success mqtt_client_disconnect shall send the MQTT DISCONNECT packet to the endpoint.]*/ + if (sendPacketItem(mqtt_client, BUFFER_u_char(disconnectPacket), size) != 0) { - STRING_HANDLE trace_log = STRING_construct("DISCONNECT"); - log_outgoing_trace(mqtt_client, trace_log); - STRING_delete(trace_log); + /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/ + LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect send failed"); + result = __FAILURE__; } - result = 0; + else + { + if (mqtt_client->logTrace) + { + STRING_HANDLE trace_log = STRING_construct("DISCONNECT"); + log_outgoing_trace(mqtt_client, trace_log); + STRING_delete(trace_log); + } + result = 0; + } + BUFFER_delete(disconnectPacket); } - BUFFER_delete(disconnectPacket); clear_mqtt_options(mqtt_client); mqtt_client->xioHandle = NULL; } + else + { + // If the client is not connected then just close the underlying socket + mqtt_client->disconnect_cb = callback; + mqtt_client->disconnect_ctx = ctx; + + close_connection(mqtt_client); + clear_mqtt_options(mqtt_client); + result = 0; + } } return result; } @@ -1223,7 +1245,7 @@ mqtt_client->packetSendTimeMs = 0; mqtt_client->packetState = UNKNOWN_TYPE; } - else if ((((current_ms - mqtt_client->packetSendTimeMs) / 1000) + KEEP_ALIVE_BUFFER_SEC) > mqtt_client->keepAliveInterval) + else if (((current_ms - mqtt_client->packetSendTimeMs) / 1000) >= mqtt_client->keepAliveInterval) { /*Codes_SRS_MQTT_CLIENT_07_026: [if keepAliveInternal is > 0 and the send time is greater than the MQTT KeepAliveInterval then it shall construct an MQTT PINGREQ packet.]*/ BUFFER_HANDLE pingPacket = mqtt_codec_ping();