A small footprint MQTT library

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Committer:
AzureIoTClient
Date:
Fri Feb 24 14:01:11 2017 -0800
Revision:
15:ec5a36121959
Parent:
14:4b5b4dccfc8b
Child:
16:4e4835036f27
1.1.8

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:ef4901974abc 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:ef4901974abc 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:ef4901974abc 3
Azure.IoT Build 0:ef4901974abc 4 #include <stdlib.h>
AzureIoTClient 15:ec5a36121959 5 #include "azure_c_shared_utility/optimize_size.h"
Azure.IoT Build 0:ef4901974abc 6 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:ef4901974abc 7 #include "azure_c_shared_utility/platform.h"
Azure.IoT Build 0:ef4901974abc 8 #include "azure_c_shared_utility/tickcounter.h"
Azure.IoT Build 0:ef4901974abc 9 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 4:e7167dabd6e4 10 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 8:83bb166aba73 11 #include "azure_c_shared_utility/strings.h"
AzureIoTClient 8:83bb166aba73 12 #include "azure_c_shared_utility/agenttime.h"
AzureIoTClient 9:37d14c31ff6e 13 #include "azure_c_shared_utility/threadapi.h"
Azure.IoT Build 0:ef4901974abc 14
Azure.IoT Build 0:ef4901974abc 15 #include "azure_umqtt_c/mqtt_client.h"
Azure.IoT Build 0:ef4901974abc 16 #include "azure_umqtt_c/mqtt_codec.h"
AzureIoTClient 8:83bb166aba73 17 #include <inttypes.h>
Azure.IoT Build 0:ef4901974abc 18
Azure.IoT Build 0:ef4901974abc 19 #define KEEP_ALIVE_BUFFER_SEC 10
Azure.IoT Build 0:ef4901974abc 20 #define VARIABLE_HEADER_OFFSET 2
Azure.IoT Build 0:ef4901974abc 21 #define RETAIN_FLAG_MASK 0x1
Azure.IoT Build 0:ef4901974abc 22 #define QOS_LEAST_ONCE_FLAG_MASK 0x2
Azure.IoT Build 0:ef4901974abc 23 #define QOS_EXACTLY_ONCE_FLAG_MASK 0x4
Azure.IoT Build 0:ef4901974abc 24 #define DUPLICATE_FLAG_MASK 0x8
Azure.IoT Build 0:ef4901974abc 25 #define CONNECT_PACKET_MASK 0xf0
AzureIoTClient 1:8dba42ff9701 26 #define TIME_MAX_BUFFER 16
AzureIoTClient 8:83bb166aba73 27 #define DEFAULT_MAX_PING_RESPONSE_TIME 80 // % of time to send pings
AzureIoTClient 9:37d14c31ff6e 28 #define MAX_CLOSE_RETRIES 10
Azure.IoT Build 0:ef4901974abc 29
AzureIoTClient 8:83bb166aba73 30 static const char* TRUE_CONST = "true";
AzureIoTClient 8:83bb166aba73 31 static const char* FALSE_CONST = "false";
AzureIoTClient 8:83bb166aba73 32
AzureIoTClient 8:83bb166aba73 33 DEFINE_ENUM_STRINGS(QOS_VALUE, QOS_VALUE_VALUES);
Azure.IoT Build 0:ef4901974abc 34
Azure.IoT Build 0:ef4901974abc 35 typedef struct MQTT_CLIENT_TAG
Azure.IoT Build 0:ef4901974abc 36 {
Azure.IoT Build 0:ef4901974abc 37 XIO_HANDLE xioHandle;
Azure.IoT Build 0:ef4901974abc 38 MQTTCODEC_HANDLE codec_handle;
Azure.IoT Build 0:ef4901974abc 39 CONTROL_PACKET_TYPE packetState;
Azure.IoT Build 0:ef4901974abc 40 TICK_COUNTER_HANDLE packetTickCntr;
Azure.IoT.Build 10:2ab268507775 41 tickcounter_ms_t packetSendTimeMs;
Azure.IoT Build 0:ef4901974abc 42 ON_MQTT_OPERATION_CALLBACK fnOperationCallback;
Azure.IoT Build 0:ef4901974abc 43 ON_MQTT_MESSAGE_RECV_CALLBACK fnMessageRecv;
Azure.IoT Build 0:ef4901974abc 44 void* ctx;
AzureIoTClient 9:37d14c31ff6e 45 ON_MQTT_ERROR_CALLBACK fnOnErrorCallBack;
AzureIoTClient 9:37d14c31ff6e 46 void* errorCBCtx;
Azure.IoT Build 0:ef4901974abc 47 QOS_VALUE qosValue;
Azure.IoT Build 0:ef4901974abc 48 uint16_t keepAliveInterval;
Azure.IoT Build 0:ef4901974abc 49 MQTT_CLIENT_OPTIONS mqttOptions;
Azure.IoT Build 0:ef4901974abc 50 bool clientConnected;
Azure.IoT Build 0:ef4901974abc 51 bool socketConnected;
Azure.IoT Build 0:ef4901974abc 52 bool logTrace;
Azure.IoT Build 0:ef4901974abc 53 bool rawBytesTrace;
Azure.IoT.Build 10:2ab268507775 54 tickcounter_ms_t timeSincePing;
AzureIoTClient 3:9b4e7158ca0d 55 uint16_t maxPingRespTime;
Azure.IoT Build 0:ef4901974abc 56 } MQTT_CLIENT;
Azure.IoT Build 0:ef4901974abc 57
AzureIoTClient 9:37d14c31ff6e 58 static void on_connection_closed(void* context)
AzureIoTClient 9:37d14c31ff6e 59 {
AzureIoTClient 9:37d14c31ff6e 60 size_t* close_complete = (size_t*)context;
AzureIoTClient 9:37d14c31ff6e 61 *close_complete = 1;
AzureIoTClient 9:37d14c31ff6e 62 }
AzureIoTClient 9:37d14c31ff6e 63
AzureIoTClient 9:37d14c31ff6e 64 static void close_connection(MQTT_CLIENT* mqtt_client)
AzureIoTClient 9:37d14c31ff6e 65 {
AzureIoTClient 9:37d14c31ff6e 66 size_t close_complete = 0;
AzureIoTClient 9:37d14c31ff6e 67 (void)xio_close(mqtt_client->xioHandle, on_connection_closed, &close_complete);
AzureIoTClient 9:37d14c31ff6e 68
AzureIoTClient 9:37d14c31ff6e 69 size_t counter = 0;
AzureIoTClient 9:37d14c31ff6e 70 do
AzureIoTClient 9:37d14c31ff6e 71 {
AzureIoTClient 9:37d14c31ff6e 72 xio_dowork(mqtt_client->xioHandle);
AzureIoTClient 9:37d14c31ff6e 73 counter++;
AzureIoTClient 9:37d14c31ff6e 74 ThreadAPI_Sleep(10);
AzureIoTClient 9:37d14c31ff6e 75 } while (close_complete == 0 && counter < MAX_CLOSE_RETRIES);
AzureIoTClient 9:37d14c31ff6e 76 mqtt_client->socketConnected = false;
AzureIoTClient 9:37d14c31ff6e 77 mqtt_client->clientConnected = false;
AzureIoTClient 9:37d14c31ff6e 78 }
AzureIoTClient 9:37d14c31ff6e 79
AzureIoTClient 9:37d14c31ff6e 80 static void set_error_callback(MQTT_CLIENT* mqtt_client, MQTT_CLIENT_EVENT_ERROR error_type)
AzureIoTClient 9:37d14c31ff6e 81 {
AzureIoTClient 9:37d14c31ff6e 82 if (mqtt_client->fnOnErrorCallBack)
AzureIoTClient 9:37d14c31ff6e 83 {
AzureIoTClient 9:37d14c31ff6e 84 mqtt_client->fnOnErrorCallBack(mqtt_client, error_type, mqtt_client->errorCBCtx);
AzureIoTClient 9:37d14c31ff6e 85 }
AzureIoTClient 9:37d14c31ff6e 86 close_connection(mqtt_client);
AzureIoTClient 9:37d14c31ff6e 87 }
AzureIoTClient 9:37d14c31ff6e 88
AzureIoTClient 8:83bb166aba73 89 static STRING_HANDLE construct_trace_log_handle(MQTT_CLIENT* mqtt_client)
AzureIoTClient 8:83bb166aba73 90 {
AzureIoTClient 8:83bb166aba73 91 STRING_HANDLE trace_log;
AzureIoTClient 8:83bb166aba73 92 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 93 {
AzureIoTClient 8:83bb166aba73 94 trace_log = STRING_new();
AzureIoTClient 8:83bb166aba73 95 }
AzureIoTClient 8:83bb166aba73 96 else
AzureIoTClient 8:83bb166aba73 97 {
AzureIoTClient 8:83bb166aba73 98 trace_log = NULL;
AzureIoTClient 8:83bb166aba73 99 }
AzureIoTClient 8:83bb166aba73 100 return trace_log;
AzureIoTClient 8:83bb166aba73 101 }
AzureIoTClient 8:83bb166aba73 102
AzureIoTClient 8:83bb166aba73 103 static uint16_t byteutil_read_uint16(uint8_t** buffer, size_t len)
Azure.IoT Build 0:ef4901974abc 104 {
Azure.IoT Build 0:ef4901974abc 105 uint16_t result = 0;
AzureIoTClient 8:83bb166aba73 106 if (buffer != NULL && *buffer != NULL && len >= 2)
Azure.IoT Build 0:ef4901974abc 107 {
AzureIoTClient 8:83bb166aba73 108 result = 256 * (**buffer) + (*(*buffer + 1));
Azure.IoT Build 0:ef4901974abc 109 *buffer += 2; // Move the ptr
Azure.IoT Build 0:ef4901974abc 110 }
AzureIoTClient 8:83bb166aba73 111 else
AzureIoTClient 8:83bb166aba73 112 {
AzureIoTClient 11:a0a6a4cf7812 113 LOG(AZ_LOG_ERROR, LOG_LINE, "byteutil_read_uint16 == NULL or less than 2");
AzureIoTClient 8:83bb166aba73 114 }
Azure.IoT Build 0:ef4901974abc 115 return result;
Azure.IoT Build 0:ef4901974abc 116 }
Azure.IoT Build 0:ef4901974abc 117
Azure.IoT Build 0:ef4901974abc 118 static char* byteutil_readUTF(uint8_t** buffer, size_t* byteLen)
Azure.IoT Build 0:ef4901974abc 119 {
Azure.IoT Build 0:ef4901974abc 120 char* result = NULL;
Azure.IoT Build 0:ef4901974abc 121 if (buffer != NULL)
Azure.IoT Build 0:ef4901974abc 122 {
Azure.IoT Build 0:ef4901974abc 123 // Get the length of the string
AzureIoTClient 8:83bb166aba73 124 uint16_t len = byteutil_read_uint16(buffer, *byteLen);
Azure.IoT Build 0:ef4901974abc 125 if (len > 0)
Azure.IoT Build 0:ef4901974abc 126 {
Azure.IoT Build 0:ef4901974abc 127 result = (char*)malloc(len + 1);
Azure.IoT Build 0:ef4901974abc 128 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 129 {
Azure.IoT Build 0:ef4901974abc 130 (void)memcpy(result, *buffer, len);
Azure.IoT Build 0:ef4901974abc 131 result[len] = '\0';
Azure.IoT Build 0:ef4901974abc 132 *buffer += len;
Azure.IoT Build 0:ef4901974abc 133 if (byteLen != NULL)
Azure.IoT Build 0:ef4901974abc 134 {
Azure.IoT Build 0:ef4901974abc 135 *byteLen = len;
Azure.IoT Build 0:ef4901974abc 136 }
Azure.IoT Build 0:ef4901974abc 137 }
Azure.IoT Build 0:ef4901974abc 138 }
Azure.IoT Build 0:ef4901974abc 139 }
AzureIoTClient 8:83bb166aba73 140 else
AzureIoTClient 8:83bb166aba73 141 {
AzureIoTClient 11:a0a6a4cf7812 142 LOG(AZ_LOG_ERROR, LOG_LINE, "readByte buffer == NULL.");
AzureIoTClient 8:83bb166aba73 143 }
Azure.IoT Build 0:ef4901974abc 144 return result;
Azure.IoT Build 0:ef4901974abc 145 }
Azure.IoT Build 0:ef4901974abc 146
Azure.IoT Build 0:ef4901974abc 147 static uint8_t byteutil_readByte(uint8_t** buffer)
Azure.IoT Build 0:ef4901974abc 148 {
Azure.IoT Build 0:ef4901974abc 149 uint8_t result = 0;
Azure.IoT Build 0:ef4901974abc 150 if (buffer != NULL)
Azure.IoT Build 0:ef4901974abc 151 {
Azure.IoT Build 0:ef4901974abc 152 result = **buffer;
Azure.IoT Build 0:ef4901974abc 153 (*buffer)++;
Azure.IoT Build 0:ef4901974abc 154 }
AzureIoTClient 8:83bb166aba73 155 else
AzureIoTClient 8:83bb166aba73 156 {
AzureIoTClient 11:a0a6a4cf7812 157 LOG(AZ_LOG_ERROR, LOG_LINE, "readByte buffer == NULL.");
AzureIoTClient 8:83bb166aba73 158 }
Azure.IoT Build 0:ef4901974abc 159 return result;
Azure.IoT Build 0:ef4901974abc 160 }
Azure.IoT Build 0:ef4901974abc 161
Azure.IoT Build 0:ef4901974abc 162 static void sendComplete(void* context, IO_SEND_RESULT send_result)
Azure.IoT Build 0:ef4901974abc 163 {
AzureIoTClient 8:83bb166aba73 164 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
AzureIoTClient 9:37d14c31ff6e 165 if (mqtt_client != NULL)
Azure.IoT Build 0:ef4901974abc 166 {
AzureIoTClient 9:37d14c31ff6e 167 if (send_result == IO_SEND_OK)
Azure.IoT Build 0:ef4901974abc 168 {
AzureIoTClient 9:37d14c31ff6e 169 if (mqtt_client->packetState == DISCONNECT_TYPE)
AzureIoTClient 5:34779607059c 170 {
AzureIoTClient 9:37d14c31ff6e 171 /*Codes_SRS_MQTT_CLIENT_07_032: [If the actionResult parameter is of type MQTT_CLIENT_ON_DISCONNECT the the msgInfo value shall be NULL.]*/
AzureIoTClient 9:37d14c31ff6e 172 if (mqtt_client->fnOperationCallback != NULL)
AzureIoTClient 9:37d14c31ff6e 173 {
AzureIoTClient 9:37d14c31ff6e 174 mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_DISCONNECT, NULL, mqtt_client->ctx);
AzureIoTClient 9:37d14c31ff6e 175 }
AzureIoTClient 9:37d14c31ff6e 176 // close the xio
AzureIoTClient 9:37d14c31ff6e 177 close_connection(mqtt_client);
AzureIoTClient 5:34779607059c 178 }
AzureIoTClient 9:37d14c31ff6e 179 }
AzureIoTClient 9:37d14c31ff6e 180 else if (send_result == IO_SEND_ERROR)
AzureIoTClient 9:37d14c31ff6e 181 {
AzureIoTClient 11:a0a6a4cf7812 182 LOG(AZ_LOG_ERROR, LOG_LINE, "MQTT Send Complete Failure send_result: %d", (int)send_result);
AzureIoTClient 9:37d14c31ff6e 183 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR);
Azure.IoT Build 0:ef4901974abc 184 }
Azure.IoT Build 0:ef4901974abc 185 }
AzureIoTClient 5:34779607059c 186 else
AzureIoTClient 5:34779607059c 187 {
AzureIoTClient 11:a0a6a4cf7812 188 LOG(AZ_LOG_ERROR, LOG_LINE, "MQTT Send Complete Failure with NULL mqtt_client");
AzureIoTClient 5:34779607059c 189 }
Azure.IoT Build 0:ef4901974abc 190 }
Azure.IoT Build 0:ef4901974abc 191
Azure.IoT Build 0:ef4901974abc 192 static const char* retrievePacketType(CONTROL_PACKET_TYPE packet)
Azure.IoT Build 0:ef4901974abc 193 {
Azure.IoT Build 0:ef4901974abc 194 switch (packet&CONNECT_PACKET_MASK)
Azure.IoT Build 0:ef4901974abc 195 {
Azure.IoT Build 0:ef4901974abc 196 case CONNECT_TYPE: return "CONNECT";
Azure.IoT Build 0:ef4901974abc 197 case CONNACK_TYPE: return "CONNACK";
Azure.IoT Build 0:ef4901974abc 198 case PUBLISH_TYPE: return "PUBLISH";
Azure.IoT Build 0:ef4901974abc 199 case PUBACK_TYPE: return "PUBACK";
Azure.IoT Build 0:ef4901974abc 200 case PUBREC_TYPE: return "PUBREC";
Azure.IoT Build 0:ef4901974abc 201 case PUBREL_TYPE: return "PUBREL";
Azure.IoT Build 0:ef4901974abc 202 case SUBSCRIBE_TYPE: return "SUBSCRIBE";
Azure.IoT Build 0:ef4901974abc 203 case SUBACK_TYPE: return "SUBACK";
Azure.IoT Build 0:ef4901974abc 204 case UNSUBSCRIBE_TYPE: return "UNSUBSCRIBE";
Azure.IoT Build 0:ef4901974abc 205 case UNSUBACK_TYPE: return "UNSUBACK";
Azure.IoT Build 0:ef4901974abc 206 case PINGREQ_TYPE: return "PINGREQ";
Azure.IoT Build 0:ef4901974abc 207 case PINGRESP_TYPE: return "PINGRESP";
Azure.IoT Build 0:ef4901974abc 208 case DISCONNECT_TYPE: return "DISCONNECT";
Azure.IoT Build 0:ef4901974abc 209 default:
Azure.IoT Build 0:ef4901974abc 210 case PACKET_TYPE_ERROR:
Azure.IoT Build 0:ef4901974abc 211 case UNKNOWN_TYPE:
Azure.IoT Build 0:ef4901974abc 212 return "UNKNOWN";
Azure.IoT Build 0:ef4901974abc 213 }
Azure.IoT Build 0:ef4901974abc 214 }
Azure.IoT Build 0:ef4901974abc 215
AzureIoTClient 1:8dba42ff9701 216 static void getLogTime(char* timeResult, size_t len)
AzureIoTClient 1:8dba42ff9701 217 {
AzureIoTClient 1:8dba42ff9701 218 if (timeResult != NULL)
AzureIoTClient 1:8dba42ff9701 219 {
AzureIoTClient 8:83bb166aba73 220 time_t agent_time = get_time(NULL);
AzureIoTClient 8:83bb166aba73 221 if (agent_time == (time_t)-1)
AzureIoTClient 1:8dba42ff9701 222 {
AzureIoTClient 1:8dba42ff9701 223 timeResult[0] = '\0';
AzureIoTClient 1:8dba42ff9701 224 }
AzureIoTClient 8:83bb166aba73 225 else
AzureIoTClient 8:83bb166aba73 226 {
AzureIoTClient 8:83bb166aba73 227 struct tm* tmInfo = localtime(&agent_time);
AzureIoTClient 8:83bb166aba73 228 if (tmInfo == NULL)
AzureIoTClient 8:83bb166aba73 229 {
AzureIoTClient 8:83bb166aba73 230 timeResult[0] = '\0';
AzureIoTClient 8:83bb166aba73 231 }
AzureIoTClient 8:83bb166aba73 232 else
AzureIoTClient 8:83bb166aba73 233 {
AzureIoTClient 8:83bb166aba73 234 if (strftime(timeResult, len, "%H:%M:%S", tmInfo) == 0)
AzureIoTClient 8:83bb166aba73 235 {
AzureIoTClient 8:83bb166aba73 236 timeResult[0] = '\0';
AzureIoTClient 8:83bb166aba73 237 }
AzureIoTClient 8:83bb166aba73 238 }
AzureIoTClient 8:83bb166aba73 239 }
AzureIoTClient 1:8dba42ff9701 240 }
AzureIoTClient 1:8dba42ff9701 241 }
AzureIoTClient 1:8dba42ff9701 242
AzureIoTClient 8:83bb166aba73 243 static void log_outgoing_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 244 {
AzureIoTClient 8:83bb166aba73 245 if (mqtt_client != NULL && mqtt_client->logTrace && trace_log != NULL)
AzureIoTClient 8:83bb166aba73 246 {
AzureIoTClient 8:83bb166aba73 247 char tmBuffer[TIME_MAX_BUFFER];
AzureIoTClient 8:83bb166aba73 248 getLogTime(tmBuffer, TIME_MAX_BUFFER);
AzureIoTClient 11:a0a6a4cf7812 249 LOG(AZ_LOG_TRACE, LOG_LINE, "-> %s %s", tmBuffer, STRING_c_str(trace_log));
AzureIoTClient 8:83bb166aba73 250 }
AzureIoTClient 8:83bb166aba73 251 }
AzureIoTClient 8:83bb166aba73 252
AzureIoTClient 8:83bb166aba73 253 static void logOutgoingingRawTrace(MQTT_CLIENT* mqtt_client, const uint8_t* data, size_t length)
AzureIoTClient 8:83bb166aba73 254 {
AzureIoTClient 8:83bb166aba73 255 if (mqtt_client != NULL && data != NULL && length > 0 && mqtt_client->rawBytesTrace)
Azure.IoT Build 0:ef4901974abc 256 {
AzureIoTClient 1:8dba42ff9701 257 char tmBuffer[TIME_MAX_BUFFER];
AzureIoTClient 1:8dba42ff9701 258 getLogTime(tmBuffer, TIME_MAX_BUFFER);
AzureIoTClient 1:8dba42ff9701 259
AzureIoTClient 11:a0a6a4cf7812 260 LOG(AZ_LOG_TRACE, 0, "-> %s %s: ", tmBuffer, retrievePacketType((unsigned char)data[0]));
AzureIoTClient 12:30b08cda82fd 261 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 262 for (index = 0; index < length; index++)
Azure.IoT Build 0:ef4901974abc 263 {
AzureIoTClient 11:a0a6a4cf7812 264 LOG(AZ_LOG_TRACE, 0, "0x%02x ", data[index]);
Azure.IoT Build 0:ef4901974abc 265 }
AzureIoTClient 11:a0a6a4cf7812 266 LOG(AZ_LOG_TRACE, LOG_LINE, "");
Azure.IoT Build 0:ef4901974abc 267 }
Azure.IoT Build 0:ef4901974abc 268 }
Azure.IoT Build 0:ef4901974abc 269
AzureIoTClient 8:83bb166aba73 270 static void log_incoming_trace(MQTT_CLIENT* mqtt_client, STRING_HANDLE trace_log)
AzureIoTClient 8:83bb166aba73 271 {
AzureIoTClient 8:83bb166aba73 272 if (mqtt_client != NULL && mqtt_client->logTrace && trace_log != NULL)
AzureIoTClient 8:83bb166aba73 273 {
AzureIoTClient 8:83bb166aba73 274 char tmBuffer[TIME_MAX_BUFFER];
AzureIoTClient 8:83bb166aba73 275 getLogTime(tmBuffer, TIME_MAX_BUFFER);
AzureIoTClient 11:a0a6a4cf7812 276 LOG(AZ_LOG_TRACE, LOG_LINE, "<- %s %s", tmBuffer, STRING_c_str(trace_log) );
AzureIoTClient 8:83bb166aba73 277 }
AzureIoTClient 8:83bb166aba73 278 }
AzureIoTClient 8:83bb166aba73 279
AzureIoTClient 8:83bb166aba73 280 static void logIncomingRawTrace(MQTT_CLIENT* mqtt_client, CONTROL_PACKET_TYPE packet, uint8_t flags, const uint8_t* data, size_t length)
Azure.IoT Build 0:ef4901974abc 281 {
AzureIoTClient 6:d9c4702f91ca 282 #ifdef NO_LOGGING
AzureIoTClient 8:83bb166aba73 283 UNUSED(flags);
AzureIoTClient 6:d9c4702f91ca 284 #endif
AzureIoTClient 8:83bb166aba73 285 if (mqtt_client != NULL && mqtt_client->rawBytesTrace)
Azure.IoT Build 0:ef4901974abc 286 {
AzureIoTClient 3:9b4e7158ca0d 287 if (data != NULL && length > 0)
AzureIoTClient 3:9b4e7158ca0d 288 {
AzureIoTClient 3:9b4e7158ca0d 289 char tmBuffer[TIME_MAX_BUFFER];
AzureIoTClient 3:9b4e7158ca0d 290 getLogTime(tmBuffer, TIME_MAX_BUFFER);
AzureIoTClient 1:8dba42ff9701 291
AzureIoTClient 11:a0a6a4cf7812 292 LOG(AZ_LOG_TRACE, 0, "<- %s %s: 0x%02x 0x%02x ", tmBuffer, retrievePacketType((CONTROL_PACKET_TYPE)packet), (unsigned char)(packet | flags), length);
AzureIoTClient 12:30b08cda82fd 293 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 294 for (index = 0; index < length; index++)
AzureIoTClient 3:9b4e7158ca0d 295 {
AzureIoTClient 11:a0a6a4cf7812 296 LOG(AZ_LOG_TRACE, 0, "0x%02x ", data[index]);
AzureIoTClient 3:9b4e7158ca0d 297 }
AzureIoTClient 11:a0a6a4cf7812 298 LOG(AZ_LOG_TRACE, LOG_LINE, "");
AzureIoTClient 3:9b4e7158ca0d 299 }
AzureIoTClient 3:9b4e7158ca0d 300 else if (packet == PINGRESP_TYPE)
Azure.IoT Build 0:ef4901974abc 301 {
AzureIoTClient 3:9b4e7158ca0d 302 char tmBuffer[TIME_MAX_BUFFER];
AzureIoTClient 3:9b4e7158ca0d 303 getLogTime(tmBuffer, TIME_MAX_BUFFER);
AzureIoTClient 11:a0a6a4cf7812 304 LOG(AZ_LOG_TRACE, LOG_LINE, "<- %s %s: 0x%02x 0x%02x ", tmBuffer, retrievePacketType((CONTROL_PACKET_TYPE)packet), (unsigned char)(packet | flags), length);
Azure.IoT Build 0:ef4901974abc 305 }
Azure.IoT Build 0:ef4901974abc 306 }
Azure.IoT Build 0:ef4901974abc 307 }
Azure.IoT Build 0:ef4901974abc 308
AzureIoTClient 8:83bb166aba73 309 static int sendPacketItem(MQTT_CLIENT* mqtt_client, const unsigned char* data, size_t length)
Azure.IoT Build 0:ef4901974abc 310 {
Azure.IoT Build 0:ef4901974abc 311 int result;
Azure.IoT Build 0:ef4901974abc 312
AzureIoTClient 8:83bb166aba73 313 if (tickcounter_get_current_ms(mqtt_client->packetTickCntr, &mqtt_client->packetSendTimeMs) != 0)
Azure.IoT Build 0:ef4901974abc 314 {
AzureIoTClient 11:a0a6a4cf7812 315 LOG(AZ_LOG_ERROR, LOG_LINE, "Failure getting current ms tickcounter");
AzureIoTClient 15:ec5a36121959 316 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 317 }
Azure.IoT Build 0:ef4901974abc 318 else
Azure.IoT Build 0:ef4901974abc 319 {
AzureIoTClient 8:83bb166aba73 320 result = xio_send(mqtt_client->xioHandle, (const void*)data, length, sendComplete, mqtt_client);
Azure.IoT Build 0:ef4901974abc 321 if (result != 0)
Azure.IoT Build 0:ef4901974abc 322 {
AzureIoTClient 11:a0a6a4cf7812 323 LOG(AZ_LOG_ERROR, LOG_LINE, "%d: Failure sending control packet data", result);
AzureIoTClient 15:ec5a36121959 324 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 325 }
Azure.IoT Build 4:e7167dabd6e4 326 else
Azure.IoT Build 4:e7167dabd6e4 327 {
AzureIoTClient 8:83bb166aba73 328 logOutgoingingRawTrace(mqtt_client, (const uint8_t*)data, length);
Azure.IoT Build 4:e7167dabd6e4 329 }
Azure.IoT Build 0:ef4901974abc 330 }
Azure.IoT Build 0:ef4901974abc 331 return result;
Azure.IoT Build 0:ef4901974abc 332 }
Azure.IoT Build 0:ef4901974abc 333
Azure.IoT Build 0:ef4901974abc 334 static void onOpenComplete(void* context, IO_OPEN_RESULT open_result)
Azure.IoT Build 0:ef4901974abc 335 {
AzureIoTClient 8:83bb166aba73 336 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
AzureIoTClient 8:83bb166aba73 337 if (mqtt_client != NULL)
Azure.IoT Build 0:ef4901974abc 338 {
AzureIoTClient 8:83bb166aba73 339 if (open_result == IO_OPEN_OK && !mqtt_client->socketConnected)
Azure.IoT Build 0:ef4901974abc 340 {
AzureIoTClient 8:83bb166aba73 341 mqtt_client->packetState = CONNECT_TYPE;
AzureIoTClient 8:83bb166aba73 342 mqtt_client->socketConnected = true;
AzureIoTClient 8:83bb166aba73 343
AzureIoTClient 8:83bb166aba73 344 STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
AzureIoTClient 8:83bb166aba73 345
Azure.IoT Build 0:ef4901974abc 346 // Send the Connect packet
AzureIoTClient 8:83bb166aba73 347 BUFFER_HANDLE connPacket = mqtt_codec_connect(&mqtt_client->mqttOptions, trace_log);
Azure.IoT Build 0:ef4901974abc 348 if (connPacket == NULL)
Azure.IoT Build 0:ef4901974abc 349 {
AzureIoTClient 11:a0a6a4cf7812 350 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_codec_connect failed");
Azure.IoT Build 0:ef4901974abc 351 }
Azure.IoT Build 0:ef4901974abc 352 else
Azure.IoT Build 0:ef4901974abc 353 {
AzureIoTClient 13:3c202001e4ba 354 size_t size = BUFFER_length(connPacket);
Azure.IoT Build 0:ef4901974abc 355 /*Codes_SRS_MQTT_CLIENT_07_009: [On success mqtt_client_connect shall send the MQTT CONNECT to the endpoint.]*/
AzureIoTClient 13:3c202001e4ba 356 if (sendPacketItem(mqtt_client, BUFFER_u_char(connPacket), size) != 0)
Azure.IoT Build 0:ef4901974abc 357 {
AzureIoTClient 11:a0a6a4cf7812 358 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_codec_connect failed");
Azure.IoT Build 0:ef4901974abc 359 }
AzureIoTClient 8:83bb166aba73 360 else
AzureIoTClient 8:83bb166aba73 361 {
AzureIoTClient 8:83bb166aba73 362 log_outgoing_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 363 }
Azure.IoT Build 0:ef4901974abc 364 BUFFER_delete(connPacket);
Azure.IoT Build 0:ef4901974abc 365 }
AzureIoTClient 8:83bb166aba73 366 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 367 {
AzureIoTClient 8:83bb166aba73 368 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 369 }
Azure.IoT Build 0:ef4901974abc 370 }
AzureIoTClient 8:83bb166aba73 371 else
Azure.IoT Build 0:ef4901974abc 372 {
AzureIoTClient 9:37d14c31ff6e 373 if (mqtt_client->socketConnected == false && mqtt_client->fnOnErrorCallBack)
AzureIoTClient 8:83bb166aba73 374 {
AzureIoTClient 9:37d14c31ff6e 375 mqtt_client->fnOnErrorCallBack(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR, mqtt_client->errorCBCtx);
AzureIoTClient 8:83bb166aba73 376 }
AzureIoTClient 9:37d14c31ff6e 377 close_connection(mqtt_client);
Azure.IoT Build 0:ef4901974abc 378 }
Azure.IoT Build 0:ef4901974abc 379 }
AzureIoTClient 8:83bb166aba73 380 else
AzureIoTClient 8:83bb166aba73 381 {
AzureIoTClient 11:a0a6a4cf7812 382 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client is NULL");
AzureIoTClient 8:83bb166aba73 383 }
Azure.IoT Build 0:ef4901974abc 384 }
Azure.IoT Build 0:ef4901974abc 385
Azure.IoT Build 0:ef4901974abc 386 static void onBytesReceived(void* context, const unsigned char* buffer, size_t size)
Azure.IoT Build 0:ef4901974abc 387 {
AzureIoTClient 8:83bb166aba73 388 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
AzureIoTClient 8:83bb166aba73 389 if (mqtt_client != NULL)
Azure.IoT Build 0:ef4901974abc 390 {
AzureIoTClient 8:83bb166aba73 391 if (mqtt_codec_bytesReceived(mqtt_client->codec_handle, buffer, size) != 0)
Azure.IoT Build 0:ef4901974abc 392 {
AzureIoTClient 9:37d14c31ff6e 393 set_error_callback(mqtt_client, MQTT_CLIENT_PARSE_ERROR);
Azure.IoT Build 0:ef4901974abc 394 }
Azure.IoT Build 0:ef4901974abc 395 }
AzureIoTClient 8:83bb166aba73 396 else
AzureIoTClient 8:83bb166aba73 397 {
AzureIoTClient 11:a0a6a4cf7812 398 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client is NULL");
AzureIoTClient 8:83bb166aba73 399 }
Azure.IoT Build 0:ef4901974abc 400 }
Azure.IoT Build 0:ef4901974abc 401
Azure.IoT Build 0:ef4901974abc 402 static void onIoError(void* context)
Azure.IoT Build 0:ef4901974abc 403 {
AzureIoTClient 8:83bb166aba73 404 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
AzureIoTClient 8:83bb166aba73 405 if (mqtt_client != NULL && mqtt_client->fnOperationCallback)
Azure.IoT Build 0:ef4901974abc 406 {
AzureIoTClient 9:37d14c31ff6e 407 /*Codes_SRS_MQTT_CLIENT_07_032: [If the actionResult parameter is of type MQTT_CLIENT_ON_DISCONNECT the the msgInfo value shall be NULL.]*/
AzureIoTClient 8:83bb166aba73 408 /* Codes_SRS_MQTT_CLIENT_07_036: [ If an error is encountered by the ioHandle the mqtt_client shall call xio_close. ] */
AzureIoTClient 9:37d14c31ff6e 409 set_error_callback(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR);
AzureIoTClient 8:83bb166aba73 410 }
AzureIoTClient 8:83bb166aba73 411 else
AzureIoTClient 8:83bb166aba73 412 {
AzureIoTClient 11:a0a6a4cf7812 413 LOG(AZ_LOG_ERROR, LOG_LINE, "Error invalid parameter: mqtt_client: %p", mqtt_client);
Azure.IoT Build 0:ef4901974abc 414 }
Azure.IoT Build 0:ef4901974abc 415 }
Azure.IoT Build 0:ef4901974abc 416
AzureIoTClient 14:4b5b4dccfc8b 417 static void clear_mqtt_options(MQTT_CLIENT* mqtt_client)
AzureIoTClient 14:4b5b4dccfc8b 418 {
AzureIoTClient 14:4b5b4dccfc8b 419 free(mqtt_client->mqttOptions.clientId);
AzureIoTClient 14:4b5b4dccfc8b 420 mqtt_client->mqttOptions.clientId = NULL;
AzureIoTClient 14:4b5b4dccfc8b 421 free(mqtt_client->mqttOptions.willTopic);
AzureIoTClient 14:4b5b4dccfc8b 422 mqtt_client->mqttOptions.willTopic = NULL;
AzureIoTClient 14:4b5b4dccfc8b 423 free(mqtt_client->mqttOptions.willMessage);
AzureIoTClient 14:4b5b4dccfc8b 424 mqtt_client->mqttOptions.willMessage = NULL;
AzureIoTClient 14:4b5b4dccfc8b 425 free(mqtt_client->mqttOptions.username);
AzureIoTClient 14:4b5b4dccfc8b 426 mqtt_client->mqttOptions.username = NULL;
AzureIoTClient 14:4b5b4dccfc8b 427 free(mqtt_client->mqttOptions.password);
AzureIoTClient 14:4b5b4dccfc8b 428 mqtt_client->mqttOptions.password = NULL;
AzureIoTClient 14:4b5b4dccfc8b 429 }
AzureIoTClient 14:4b5b4dccfc8b 430
AzureIoTClient 8:83bb166aba73 431 static int cloneMqttOptions(MQTT_CLIENT* mqtt_client, const MQTT_CLIENT_OPTIONS* mqttOptions)
Azure.IoT Build 0:ef4901974abc 432 {
Azure.IoT Build 0:ef4901974abc 433 int result = 0;
Azure.IoT Build 0:ef4901974abc 434 if (mqttOptions->clientId != NULL)
Azure.IoT Build 0:ef4901974abc 435 {
AzureIoTClient 8:83bb166aba73 436 if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.clientId, mqttOptions->clientId) != 0)
Azure.IoT Build 0:ef4901974abc 437 {
AzureIoTClient 15:ec5a36121959 438 result = __FAILURE__;
AzureIoTClient 11:a0a6a4cf7812 439 LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s clientId");
Azure.IoT Build 0:ef4901974abc 440 }
Azure.IoT Build 0:ef4901974abc 441 }
Azure.IoT Build 0:ef4901974abc 442 if (result == 0 && mqttOptions->willTopic != NULL)
Azure.IoT Build 0:ef4901974abc 443 {
AzureIoTClient 8:83bb166aba73 444 if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.willTopic, mqttOptions->willTopic) != 0)
Azure.IoT Build 0:ef4901974abc 445 {
AzureIoTClient 15:ec5a36121959 446 result = __FAILURE__;
AzureIoTClient 11:a0a6a4cf7812 447 LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s willTopic");
Azure.IoT Build 0:ef4901974abc 448 }
Azure.IoT Build 0:ef4901974abc 449 }
Azure.IoT Build 0:ef4901974abc 450 if (result == 0 && mqttOptions->willMessage != NULL)
Azure.IoT Build 0:ef4901974abc 451 {
AzureIoTClient 8:83bb166aba73 452 if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.willMessage, mqttOptions->willMessage) != 0)
Azure.IoT Build 0:ef4901974abc 453 {
AzureIoTClient 11:a0a6a4cf7812 454 LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s willMessage");
AzureIoTClient 15:ec5a36121959 455 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 456 }
Azure.IoT Build 0:ef4901974abc 457 }
Azure.IoT Build 0:ef4901974abc 458 if (result == 0 && mqttOptions->username != NULL)
Azure.IoT Build 0:ef4901974abc 459 {
AzureIoTClient 8:83bb166aba73 460 if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.username, mqttOptions->username) != 0)
Azure.IoT Build 0:ef4901974abc 461 {
AzureIoTClient 11:a0a6a4cf7812 462 LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s username");
AzureIoTClient 15:ec5a36121959 463 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 464 }
Azure.IoT Build 0:ef4901974abc 465 }
Azure.IoT Build 0:ef4901974abc 466 if (result == 0 && mqttOptions->password != NULL)
Azure.IoT Build 0:ef4901974abc 467 {
AzureIoTClient 8:83bb166aba73 468 if (mallocAndStrcpy_s(&mqtt_client->mqttOptions.password, mqttOptions->password) != 0)
Azure.IoT Build 0:ef4901974abc 469 {
AzureIoTClient 11:a0a6a4cf7812 470 LOG(AZ_LOG_ERROR, LOG_LINE, "mallocAndStrcpy_s password");
AzureIoTClient 15:ec5a36121959 471 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 472 }
Azure.IoT Build 0:ef4901974abc 473 }
Azure.IoT Build 0:ef4901974abc 474 if (result == 0)
Azure.IoT Build 0:ef4901974abc 475 {
AzureIoTClient 8:83bb166aba73 476 mqtt_client->mqttOptions.keepAliveInterval = mqttOptions->keepAliveInterval;
AzureIoTClient 8:83bb166aba73 477 mqtt_client->mqttOptions.messageRetain = mqttOptions->messageRetain;
AzureIoTClient 8:83bb166aba73 478 mqtt_client->mqttOptions.useCleanSession = mqttOptions->useCleanSession;
AzureIoTClient 8:83bb166aba73 479 mqtt_client->mqttOptions.qualityOfServiceValue = mqttOptions->qualityOfServiceValue;
Azure.IoT Build 0:ef4901974abc 480 }
Azure.IoT Build 0:ef4901974abc 481 else
Azure.IoT Build 0:ef4901974abc 482 {
AzureIoTClient 14:4b5b4dccfc8b 483 clear_mqtt_options(mqtt_client);
Azure.IoT Build 0:ef4901974abc 484 }
Azure.IoT Build 0:ef4901974abc 485 return result;
Azure.IoT Build 0:ef4901974abc 486 }
Azure.IoT Build 0:ef4901974abc 487
Azure.IoT Build 0:ef4901974abc 488 static void recvCompleteCallback(void* context, CONTROL_PACKET_TYPE packet, int flags, BUFFER_HANDLE headerData)
Azure.IoT Build 0:ef4901974abc 489 {
AzureIoTClient 8:83bb166aba73 490 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
AzureIoTClient 8:83bb166aba73 491 if ((mqtt_client != NULL && headerData != NULL) || packet == PINGRESP_TYPE)
Azure.IoT Build 0:ef4901974abc 492 {
Azure.IoT Build 0:ef4901974abc 493 size_t len = BUFFER_length(headerData);
Azure.IoT Build 0:ef4901974abc 494 uint8_t* iterator = BUFFER_u_char(headerData);
Azure.IoT Build 0:ef4901974abc 495
AzureIoTClient 8:83bb166aba73 496 logIncomingRawTrace(mqtt_client, packet, (uint8_t)flags, iterator, len);
Azure.IoT Build 0:ef4901974abc 497
AzureIoTClient 3:9b4e7158ca0d 498 if ((iterator != NULL && len > 0) || packet == PINGRESP_TYPE)
Azure.IoT Build 0:ef4901974abc 499 {
Azure.IoT Build 0:ef4901974abc 500 switch (packet)
Azure.IoT Build 0:ef4901974abc 501 {
AzureIoTClient 3:9b4e7158ca0d 502 case CONNACK_TYPE:
Azure.IoT Build 0:ef4901974abc 503 {
AzureIoTClient 8:83bb166aba73 504 if (mqtt_client->fnOperationCallback != NULL)
AzureIoTClient 3:9b4e7158ca0d 505 {
AzureIoTClient 8:83bb166aba73 506 STRING_HANDLE trace_log = NULL;
AzureIoTClient 8:83bb166aba73 507
AzureIoTClient 3:9b4e7158ca0d 508 /*Codes_SRS_MQTT_CLIENT_07_028: [If the actionResult parameter is of type CONNECT_ACK then the msgInfo value shall be a CONNECT_ACK structure.]*/
AzureIoTClient 3:9b4e7158ca0d 509 CONNECT_ACK connack = { 0 };
AzureIoTClient 3:9b4e7158ca0d 510 connack.isSessionPresent = (byteutil_readByte(&iterator) == 0x1) ? true : false;
AzureIoTClient 3:9b4e7158ca0d 511 connack.returnCode = byteutil_readByte(&iterator);
Azure.IoT Build 0:ef4901974abc 512
AzureIoTClient 8:83bb166aba73 513 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 514 {
AzureIoTClient 8:83bb166aba73 515 trace_log = STRING_construct_sprintf("CONNACK | SESSION_PRESENT: %s | RETURN_CODE: 0x%x", connack.isSessionPresent ? TRUE_CONST : FALSE_CONST, connack.returnCode);
AzureIoTClient 8:83bb166aba73 516 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 517 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 518 }
AzureIoTClient 8:83bb166aba73 519 mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_CONNACK, (void*)&connack, mqtt_client->ctx);
AzureIoTClient 3:9b4e7158ca0d 520
AzureIoTClient 3:9b4e7158ca0d 521 if (connack.returnCode == CONNECTION_ACCEPTED)
AzureIoTClient 3:9b4e7158ca0d 522 {
AzureIoTClient 8:83bb166aba73 523 mqtt_client->clientConnected = true;
AzureIoTClient 3:9b4e7158ca0d 524 }
Azure.IoT Build 0:ef4901974abc 525 }
AzureIoTClient 8:83bb166aba73 526 else
AzureIoTClient 8:83bb166aba73 527 {
AzureIoTClient 11:a0a6a4cf7812 528 LOG(AZ_LOG_ERROR, LOG_LINE, "fnOperationCallback NULL");
AzureIoTClient 8:83bb166aba73 529 }
AzureIoTClient 3:9b4e7158ca0d 530 break;
Azure.IoT Build 0:ef4901974abc 531 }
AzureIoTClient 3:9b4e7158ca0d 532 case PUBLISH_TYPE:
Azure.IoT Build 0:ef4901974abc 533 {
AzureIoTClient 8:83bb166aba73 534 if (mqtt_client->fnMessageRecv != NULL)
AzureIoTClient 3:9b4e7158ca0d 535 {
AzureIoTClient 8:83bb166aba73 536 STRING_HANDLE trace_log = NULL;
AzureIoTClient 8:83bb166aba73 537
AzureIoTClient 3:9b4e7158ca0d 538 bool isDuplicateMsg = (flags & DUPLICATE_FLAG_MASK) ? true : false;
AzureIoTClient 3:9b4e7158ca0d 539 bool isRetainMsg = (flags & RETAIN_FLAG_MASK) ? true : false;
AzureIoTClient 3:9b4e7158ca0d 540 QOS_VALUE qosValue = (flags == 0) ? DELIVER_AT_MOST_ONCE : (flags & QOS_LEAST_ONCE_FLAG_MASK) ? DELIVER_AT_LEAST_ONCE : DELIVER_EXACTLY_ONCE;
AzureIoTClient 3:9b4e7158ca0d 541
AzureIoTClient 8:83bb166aba73 542 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 543 {
AzureIoTClient 8:83bb166aba73 544 trace_log = STRING_construct_sprintf("PUBLISH | IS_DUP: %s | RETAIN: %d | QOS: %s", isDuplicateMsg ? TRUE_CONST : FALSE_CONST,
AzureIoTClient 8:83bb166aba73 545 isRetainMsg ? 1 : 0, ENUM_TO_STRING(QOS_VALUE, qosValue) );
AzureIoTClient 8:83bb166aba73 546 }
AzureIoTClient 8:83bb166aba73 547
AzureIoTClient 3:9b4e7158ca0d 548 uint8_t* initialPos = iterator;
AzureIoTClient 8:83bb166aba73 549 size_t length = len - (iterator - initialPos);
AzureIoTClient 8:83bb166aba73 550 char* topicName = byteutil_readUTF(&iterator, &length);
AzureIoTClient 5:34779607059c 551 if (topicName == NULL)
AzureIoTClient 3:9b4e7158ca0d 552 {
AzureIoTClient 11:a0a6a4cf7812 553 LOG(AZ_LOG_ERROR, LOG_LINE, "Publish MSG: failure reading topic name");
AzureIoTClient 9:37d14c31ff6e 554 set_error_callback(mqtt_client, MQTT_CLIENT_PARSE_ERROR);
AzureIoTClient 8:83bb166aba73 555 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 556 {
AzureIoTClient 8:83bb166aba73 557 STRING_delete(trace_log);
AzureIoTClient 5:34779607059c 558 }
AzureIoTClient 3:9b4e7158ca0d 559 }
AzureIoTClient 3:9b4e7158ca0d 560 else
AzureIoTClient 3:9b4e7158ca0d 561 {
AzureIoTClient 8:83bb166aba73 562 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 563 {
AzureIoTClient 8:83bb166aba73 564 STRING_sprintf(trace_log, " | TOPIC_NAME: %s", topicName);
AzureIoTClient 8:83bb166aba73 565 }
AzureIoTClient 5:34779607059c 566 uint16_t packetId = 0;
AzureIoTClient 8:83bb166aba73 567 length = len - (iterator - initialPos);
AzureIoTClient 5:34779607059c 568 if (qosValue != DELIVER_AT_MOST_ONCE)
AzureIoTClient 5:34779607059c 569 {
AzureIoTClient 8:83bb166aba73 570 packetId = byteutil_read_uint16(&iterator, length);
AzureIoTClient 8:83bb166aba73 571 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 572 {
AzureIoTClient 8:83bb166aba73 573 STRING_sprintf(trace_log, " | PACKET_ID: %"PRIu16, packetId);
AzureIoTClient 8:83bb166aba73 574 }
AzureIoTClient 5:34779607059c 575 }
AzureIoTClient 8:83bb166aba73 576 length = len - (iterator - initialPos);
AzureIoTClient 3:9b4e7158ca0d 577
AzureIoTClient 5:34779607059c 578 MQTT_MESSAGE_HANDLE msgHandle = mqttmessage_create(packetId, topicName, qosValue, iterator, length);
AzureIoTClient 5:34779607059c 579 if (msgHandle == NULL)
AzureIoTClient 3:9b4e7158ca0d 580 {
AzureIoTClient 11:a0a6a4cf7812 581 LOG(AZ_LOG_ERROR, LOG_LINE, "failure in mqttmessage_create");
AzureIoTClient 9:37d14c31ff6e 582 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 8:83bb166aba73 583 if (trace_log != NULL) {
AzureIoTClient 8:83bb166aba73 584 STRING_delete(trace_log);
AzureIoTClient 5:34779607059c 585 }
AzureIoTClient 3:9b4e7158ca0d 586 }
AzureIoTClient 5:34779607059c 587 else
AzureIoTClient 3:9b4e7158ca0d 588 {
AzureIoTClient 5:34779607059c 589 if (mqttmessage_setIsDuplicateMsg(msgHandle, isDuplicateMsg) != 0 ||
AzureIoTClient 5:34779607059c 590 mqttmessage_setIsRetained(msgHandle, isRetainMsg) != 0)
AzureIoTClient 5:34779607059c 591 {
AzureIoTClient 11:a0a6a4cf7812 592 LOG(AZ_LOG_ERROR, LOG_LINE, "failure setting mqtt message property");
AzureIoTClient 9:37d14c31ff6e 593 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 8:83bb166aba73 594 if (trace_log != NULL) {
AzureIoTClient 8:83bb166aba73 595 STRING_delete(trace_log);
AzureIoTClient 5:34779607059c 596 }
AzureIoTClient 5:34779607059c 597 }
AzureIoTClient 5:34779607059c 598 else
AzureIoTClient 5:34779607059c 599 {
AzureIoTClient 8:83bb166aba73 600 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 601 {
AzureIoTClient 8:83bb166aba73 602 STRING_sprintf(trace_log, " | PAYLOAD_LEN: %zu", length);
AzureIoTClient 8:83bb166aba73 603 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 604 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 605 }
AzureIoTClient 8:83bb166aba73 606
AzureIoTClient 8:83bb166aba73 607 mqtt_client->fnMessageRecv(msgHandle, mqtt_client->ctx);
AzureIoTClient 5:34779607059c 608
AzureIoTClient 5:34779607059c 609 BUFFER_HANDLE pubRel = NULL;
AzureIoTClient 5:34779607059c 610 if (qosValue == DELIVER_EXACTLY_ONCE)
AzureIoTClient 5:34779607059c 611 {
AzureIoTClient 5:34779607059c 612 pubRel = mqtt_codec_publishReceived(packetId);
AzureIoTClient 5:34779607059c 613 if (pubRel == NULL)
AzureIoTClient 5:34779607059c 614 {
AzureIoTClient 11:a0a6a4cf7812 615 LOG(AZ_LOG_ERROR, LOG_LINE, "Failed to allocate publish receive message.");
AzureIoTClient 9:37d14c31ff6e 616 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 5:34779607059c 617 }
AzureIoTClient 5:34779607059c 618 }
AzureIoTClient 5:34779607059c 619 else if (qosValue == DELIVER_AT_LEAST_ONCE)
AzureIoTClient 5:34779607059c 620 {
AzureIoTClient 5:34779607059c 621 pubRel = mqtt_codec_publishAck(packetId);
AzureIoTClient 5:34779607059c 622 if (pubRel == NULL)
AzureIoTClient 5:34779607059c 623 {
AzureIoTClient 11:a0a6a4cf7812 624 LOG(AZ_LOG_ERROR, LOG_LINE, "Failed to allocate publish ack message.");
AzureIoTClient 9:37d14c31ff6e 625 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 5:34779607059c 626 }
AzureIoTClient 5:34779607059c 627 }
AzureIoTClient 5:34779607059c 628 if (pubRel != NULL)
AzureIoTClient 5:34779607059c 629 {
AzureIoTClient 13:3c202001e4ba 630 size_t size = BUFFER_length(pubRel);
AzureIoTClient 13:3c202001e4ba 631 (void)sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size);
AzureIoTClient 5:34779607059c 632 BUFFER_delete(pubRel);
AzureIoTClient 5:34779607059c 633 }
AzureIoTClient 5:34779607059c 634 }
AzureIoTClient 5:34779607059c 635 mqttmessage_destroy(msgHandle);
AzureIoTClient 3:9b4e7158ca0d 636 }
AzureIoTClient 3:9b4e7158ca0d 637 free(topicName);
AzureIoTClient 3:9b4e7158ca0d 638 }
Azure.IoT Build 0:ef4901974abc 639 }
AzureIoTClient 3:9b4e7158ca0d 640 break;
AzureIoTClient 3:9b4e7158ca0d 641 }
AzureIoTClient 3:9b4e7158ca0d 642 case PUBACK_TYPE:
AzureIoTClient 3:9b4e7158ca0d 643 case PUBREC_TYPE:
AzureIoTClient 3:9b4e7158ca0d 644 case PUBREL_TYPE:
AzureIoTClient 3:9b4e7158ca0d 645 case PUBCOMP_TYPE:
AzureIoTClient 3:9b4e7158ca0d 646 {
AzureIoTClient 8:83bb166aba73 647 if (mqtt_client->fnOperationCallback)
Azure.IoT Build 0:ef4901974abc 648 {
AzureIoTClient 8:83bb166aba73 649 STRING_HANDLE trace_log = NULL;
AzureIoTClient 8:83bb166aba73 650
AzureIoTClient 3:9b4e7158ca0d 651 /*Codes_SRS_MQTT_CLIENT_07_029: [If the actionResult parameter are of types PUBACK_TYPE, PUBREC_TYPE, PUBREL_TYPE or PUBCOMP_TYPE then the msgInfo value shall be a PUBLISH_ACK structure.]*/
AzureIoTClient 3:9b4e7158ca0d 652 MQTT_CLIENT_EVENT_RESULT action = (packet == PUBACK_TYPE) ? MQTT_CLIENT_ON_PUBLISH_ACK :
AzureIoTClient 3:9b4e7158ca0d 653 (packet == PUBREC_TYPE) ? MQTT_CLIENT_ON_PUBLISH_RECV :
AzureIoTClient 3:9b4e7158ca0d 654 (packet == PUBREL_TYPE) ? MQTT_CLIENT_ON_PUBLISH_REL : MQTT_CLIENT_ON_PUBLISH_COMP;
AzureIoTClient 3:9b4e7158ca0d 655
AzureIoTClient 3:9b4e7158ca0d 656 PUBLISH_ACK publish_ack = { 0 };
AzureIoTClient 8:83bb166aba73 657 publish_ack.packetId = byteutil_read_uint16(&iterator, len);
AzureIoTClient 8:83bb166aba73 658
AzureIoTClient 8:83bb166aba73 659 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 660 {
AzureIoTClient 8:83bb166aba73 661 trace_log = STRING_construct_sprintf("%s | PACKET_ID: %"PRIu16, packet == PUBACK_TYPE ? "PUBACK" : (packet == PUBREC_TYPE) ? "PUBREC" : (packet == PUBREL_TYPE) ? "PUBREL" : "PUBCOMP",
AzureIoTClient 8:83bb166aba73 662 publish_ack.packetId);
AzureIoTClient 8:83bb166aba73 663
AzureIoTClient 8:83bb166aba73 664 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 665 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 666 }
Azure.IoT Build 0:ef4901974abc 667
Azure.IoT Build 0:ef4901974abc 668 BUFFER_HANDLE pubRel = NULL;
AzureIoTClient 8:83bb166aba73 669 mqtt_client->fnOperationCallback(mqtt_client, action, (void*)&publish_ack, mqtt_client->ctx);
AzureIoTClient 3:9b4e7158ca0d 670 if (packet == PUBREC_TYPE)
Azure.IoT Build 0:ef4901974abc 671 {
AzureIoTClient 3:9b4e7158ca0d 672 pubRel = mqtt_codec_publishRelease(publish_ack.packetId);
AzureIoTClient 5:34779607059c 673 if (pubRel == NULL)
AzureIoTClient 5:34779607059c 674 {
AzureIoTClient 11:a0a6a4cf7812 675 LOG(AZ_LOG_ERROR, LOG_LINE, "Failed to allocate publish release message.");
AzureIoTClient 9:37d14c31ff6e 676 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 5:34779607059c 677 }
Azure.IoT Build 0:ef4901974abc 678 }
AzureIoTClient 3:9b4e7158ca0d 679 else if (packet == PUBREL_TYPE)
Azure.IoT Build 0:ef4901974abc 680 {
AzureIoTClient 3:9b4e7158ca0d 681 pubRel = mqtt_codec_publishComplete(publish_ack.packetId);
AzureIoTClient 5:34779607059c 682 if (pubRel == NULL)
AzureIoTClient 5:34779607059c 683 {
AzureIoTClient 11:a0a6a4cf7812 684 LOG(AZ_LOG_ERROR, LOG_LINE, "Failed to allocate publish complete message.");
AzureIoTClient 9:37d14c31ff6e 685 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 5:34779607059c 686 }
Azure.IoT Build 0:ef4901974abc 687 }
Azure.IoT Build 0:ef4901974abc 688 if (pubRel != NULL)
Azure.IoT Build 0:ef4901974abc 689 {
AzureIoTClient 13:3c202001e4ba 690 size_t size = BUFFER_length(pubRel);
AzureIoTClient 13:3c202001e4ba 691 (void)sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size);
Azure.IoT Build 0:ef4901974abc 692 BUFFER_delete(pubRel);
Azure.IoT Build 0:ef4901974abc 693 }
Azure.IoT Build 0:ef4901974abc 694 }
AzureIoTClient 3:9b4e7158ca0d 695 break;
Azure.IoT Build 0:ef4901974abc 696 }
AzureIoTClient 3:9b4e7158ca0d 697 case SUBACK_TYPE:
Azure.IoT Build 0:ef4901974abc 698 {
AzureIoTClient 8:83bb166aba73 699 if (mqtt_client->fnOperationCallback)
AzureIoTClient 3:9b4e7158ca0d 700 {
AzureIoTClient 8:83bb166aba73 701 STRING_HANDLE trace_log = NULL;
AzureIoTClient 8:83bb166aba73 702
AzureIoTClient 3:9b4e7158ca0d 703 /*Codes_SRS_MQTT_CLIENT_07_030: [If the actionResult parameter is of type SUBACK_TYPE then the msgInfo value shall be a SUBSCRIBE_ACK structure.]*/
AzureIoTClient 3:9b4e7158ca0d 704 SUBSCRIBE_ACK suback = { 0 };
AzureIoTClient 3:9b4e7158ca0d 705
AzureIoTClient 3:9b4e7158ca0d 706 size_t remainLen = len;
AzureIoTClient 8:83bb166aba73 707 suback.packetId = byteutil_read_uint16(&iterator, len);
AzureIoTClient 3:9b4e7158ca0d 708 remainLen -= 2;
Azure.IoT Build 0:ef4901974abc 709
AzureIoTClient 8:83bb166aba73 710 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 711 {
AzureIoTClient 8:83bb166aba73 712 trace_log = STRING_construct_sprintf("SUBACK | PACKET_ID: %"PRIu16, suback.packetId);
AzureIoTClient 8:83bb166aba73 713 }
AzureIoTClient 8:83bb166aba73 714
AzureIoTClient 3:9b4e7158ca0d 715 // Allocate the remaining len
AzureIoTClient 3:9b4e7158ca0d 716 suback.qosReturn = (QOS_VALUE*)malloc(sizeof(QOS_VALUE)*remainLen);
AzureIoTClient 3:9b4e7158ca0d 717 if (suback.qosReturn != NULL)
Azure.IoT Build 0:ef4901974abc 718 {
AzureIoTClient 3:9b4e7158ca0d 719 while (remainLen > 0)
AzureIoTClient 3:9b4e7158ca0d 720 {
AzureIoTClient 3:9b4e7158ca0d 721 suback.qosReturn[suback.qosCount++] = byteutil_readByte(&iterator);
AzureIoTClient 3:9b4e7158ca0d 722 remainLen--;
AzureIoTClient 8:83bb166aba73 723 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 724 {
AzureIoTClient 8:83bb166aba73 725 STRING_sprintf(trace_log, " | RETURN_CODE: %"PRIu16, suback.qosReturn[suback.qosCount-1]);
AzureIoTClient 8:83bb166aba73 726 }
AzureIoTClient 3:9b4e7158ca0d 727 }
AzureIoTClient 8:83bb166aba73 728
AzureIoTClient 8:83bb166aba73 729 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 730 {
AzureIoTClient 8:83bb166aba73 731 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 732 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 733 }
AzureIoTClient 8:83bb166aba73 734 mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_SUBSCRIBE_ACK, (void*)&suback, mqtt_client->ctx);
AzureIoTClient 3:9b4e7158ca0d 735 free(suback.qosReturn);
Azure.IoT Build 0:ef4901974abc 736 }
AzureIoTClient 5:34779607059c 737 else
AzureIoTClient 5:34779607059c 738 {
AzureIoTClient 11:a0a6a4cf7812 739 LOG(AZ_LOG_ERROR, LOG_LINE, "allocation of quality of service value failed.");
AzureIoTClient 9:37d14c31ff6e 740 set_error_callback(mqtt_client, MQTT_CLIENT_MEMORY_ERROR);
AzureIoTClient 5:34779607059c 741 }
Azure.IoT Build 0:ef4901974abc 742 }
AzureIoTClient 3:9b4e7158ca0d 743 break;
Azure.IoT Build 0:ef4901974abc 744 }
AzureIoTClient 3:9b4e7158ca0d 745 case UNSUBACK_TYPE:
Azure.IoT Build 0:ef4901974abc 746 {
AzureIoTClient 8:83bb166aba73 747 if (mqtt_client->fnOperationCallback)
AzureIoTClient 3:9b4e7158ca0d 748 {
AzureIoTClient 8:83bb166aba73 749 STRING_HANDLE trace_log = NULL;
AzureIoTClient 8:83bb166aba73 750
AzureIoTClient 3:9b4e7158ca0d 751 /*Codes_SRS_MQTT_CLIENT_07_031: [If the actionResult parameter is of type UNSUBACK_TYPE then the msgInfo value shall be a UNSUBSCRIBE_ACK structure.]*/
AzureIoTClient 3:9b4e7158ca0d 752 UNSUBSCRIBE_ACK unsuback = { 0 };
AzureIoTClient 3:9b4e7158ca0d 753 iterator += VARIABLE_HEADER_OFFSET;
AzureIoTClient 8:83bb166aba73 754 unsuback.packetId = byteutil_read_uint16(&iterator, len);
Azure.IoT Build 0:ef4901974abc 755
AzureIoTClient 8:83bb166aba73 756 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 757 {
AzureIoTClient 8:83bb166aba73 758 trace_log = STRING_construct_sprintf("UNSUBACK | PACKET_ID: %"PRIu16, unsuback.packetId);
AzureIoTClient 8:83bb166aba73 759 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 760 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 761 }
AzureIoTClient 8:83bb166aba73 762 mqtt_client->fnOperationCallback(mqtt_client, MQTT_CLIENT_ON_UNSUBSCRIBE_ACK, (void*)&unsuback, mqtt_client->ctx);
AzureIoTClient 3:9b4e7158ca0d 763 }
AzureIoTClient 3:9b4e7158ca0d 764 break;
Azure.IoT Build 0:ef4901974abc 765 }
AzureIoTClient 3:9b4e7158ca0d 766 case PINGRESP_TYPE:
AzureIoTClient 8:83bb166aba73 767 mqtt_client->timeSincePing = 0;
AzureIoTClient 3:9b4e7158ca0d 768 // Ping responses do not get forwarded
AzureIoTClient 8:83bb166aba73 769 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 770 {
AzureIoTClient 8:83bb166aba73 771 STRING_HANDLE trace_log = STRING_construct_sprintf("PINGRESP");
AzureIoTClient 8:83bb166aba73 772 log_incoming_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 773 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 774 }
AzureIoTClient 3:9b4e7158ca0d 775 break;
AzureIoTClient 3:9b4e7158ca0d 776 default:
AzureIoTClient 3:9b4e7158ca0d 777 break;
Azure.IoT Build 0:ef4901974abc 778 }
Azure.IoT Build 0:ef4901974abc 779 }
Azure.IoT Build 0:ef4901974abc 780 }
Azure.IoT Build 0:ef4901974abc 781 }
Azure.IoT Build 0:ef4901974abc 782
AzureIoTClient 9:37d14c31ff6e 783 MQTT_CLIENT_HANDLE mqtt_client_init(ON_MQTT_MESSAGE_RECV_CALLBACK msgRecv, ON_MQTT_OPERATION_CALLBACK opCallback, void* opCallbackCtx, ON_MQTT_ERROR_CALLBACK onErrorCallBack, void* errorCBCtx)
Azure.IoT Build 0:ef4901974abc 784 {
Azure.IoT Build 0:ef4901974abc 785 MQTT_CLIENT* result;
Azure.IoT Build 0:ef4901974abc 786 /*Codes_SRS_MQTT_CLIENT_07_001: [If the parameters ON_MQTT_MESSAGE_RECV_CALLBACK is NULL then mqttclient_init shall return NULL.]*/
Azure.IoT Build 0:ef4901974abc 787 if (msgRecv == NULL)
Azure.IoT Build 0:ef4901974abc 788 {
Azure.IoT Build 0:ef4901974abc 789 result = NULL;
Azure.IoT Build 0:ef4901974abc 790 }
Azure.IoT Build 0:ef4901974abc 791 else
Azure.IoT Build 0:ef4901974abc 792 {
Azure.IoT Build 0:ef4901974abc 793 result = malloc(sizeof(MQTT_CLIENT));
Azure.IoT Build 0:ef4901974abc 794 if (result == NULL)
Azure.IoT Build 0:ef4901974abc 795 {
Azure.IoT Build 0:ef4901974abc 796 /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
AzureIoTClient 11:a0a6a4cf7812 797 LOG(AZ_LOG_ERROR, LOG_LINE, "mqtt_client_init failure: Allocation Failure");
Azure.IoT Build 0:ef4901974abc 798 }
Azure.IoT Build 0:ef4901974abc 799 else
Azure.IoT Build 0:ef4901974abc 800 {
Azure.IoT Build 0:ef4901974abc 801 /*Codes_SRS_MQTT_CLIENT_07_003: [mqttclient_init shall allocate MQTTCLIENT_DATA_INSTANCE and return the MQTTCLIENT_HANDLE on success.]*/
Azure.IoT Build 0:ef4901974abc 802 result->xioHandle = NULL;
Azure.IoT Build 0:ef4901974abc 803 result->packetState = UNKNOWN_TYPE;
Azure.IoT Build 0:ef4901974abc 804 result->packetSendTimeMs = 0;
Azure.IoT Build 0:ef4901974abc 805 result->fnOperationCallback = opCallback;
AzureIoTClient 9:37d14c31ff6e 806 result->ctx = opCallbackCtx;
Azure.IoT Build 0:ef4901974abc 807 result->fnMessageRecv = msgRecv;
AzureIoTClient 9:37d14c31ff6e 808 result->fnOnErrorCallBack = onErrorCallBack;
AzureIoTClient 9:37d14c31ff6e 809 result->errorCBCtx = errorCBCtx;
Azure.IoT Build 0:ef4901974abc 810 result->qosValue = DELIVER_AT_MOST_ONCE;
Azure.IoT Build 0:ef4901974abc 811 result->keepAliveInterval = 0;
Azure.IoT Build 0:ef4901974abc 812 result->packetTickCntr = tickcounter_create();
Azure.IoT Build 0:ef4901974abc 813 result->mqttOptions.clientId = NULL;
Azure.IoT Build 0:ef4901974abc 814 result->mqttOptions.willTopic = NULL;
Azure.IoT Build 0:ef4901974abc 815 result->mqttOptions.willMessage = NULL;
Azure.IoT Build 0:ef4901974abc 816 result->mqttOptions.username = NULL;
Azure.IoT Build 0:ef4901974abc 817 result->mqttOptions.password = NULL;
Azure.IoT Build 0:ef4901974abc 818 result->socketConnected = false;
Azure.IoT Build 0:ef4901974abc 819 result->clientConnected = false;
Azure.IoT Build 0:ef4901974abc 820 result->logTrace = false;
Azure.IoT Build 0:ef4901974abc 821 result->rawBytesTrace = false;
AzureIoTClient 3:9b4e7158ca0d 822 result->timeSincePing = 0;
AzureIoTClient 3:9b4e7158ca0d 823 result->maxPingRespTime = DEFAULT_MAX_PING_RESPONSE_TIME;
Azure.IoT Build 0:ef4901974abc 824 if (result->packetTickCntr == NULL)
Azure.IoT Build 0:ef4901974abc 825 {
Azure.IoT Build 0:ef4901974abc 826 /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
AzureIoTClient 11:a0a6a4cf7812 827 LOG(AZ_LOG_ERROR, LOG_LINE, "mqtt_client_init failure: tickcounter_create failure");
Azure.IoT Build 0:ef4901974abc 828 free(result);
Azure.IoT Build 0:ef4901974abc 829 result = NULL;
Azure.IoT Build 0:ef4901974abc 830 }
Azure.IoT Build 0:ef4901974abc 831 else
Azure.IoT Build 0:ef4901974abc 832 {
Azure.IoT Build 0:ef4901974abc 833 result->codec_handle = mqtt_codec_create(recvCompleteCallback, result);
Azure.IoT Build 0:ef4901974abc 834 if (result->codec_handle == NULL)
Azure.IoT Build 0:ef4901974abc 835 {
Azure.IoT Build 0:ef4901974abc 836 /*Codes_SRS_MQTT_CLIENT_07_002: [If any failure is encountered then mqttclient_init shall return NULL.]*/
AzureIoTClient 11:a0a6a4cf7812 837 LOG(AZ_LOG_ERROR, LOG_LINE, "mqtt_client_init failure: mqtt_codec_create failure");
Azure.IoT Build 0:ef4901974abc 838 tickcounter_destroy(result->packetTickCntr);
Azure.IoT Build 0:ef4901974abc 839 free(result);
Azure.IoT Build 0:ef4901974abc 840 result = NULL;
Azure.IoT Build 0:ef4901974abc 841 }
Azure.IoT Build 0:ef4901974abc 842 }
Azure.IoT Build 0:ef4901974abc 843 }
Azure.IoT Build 0:ef4901974abc 844 }
Azure.IoT Build 0:ef4901974abc 845 return result;
Azure.IoT Build 0:ef4901974abc 846 }
Azure.IoT Build 0:ef4901974abc 847
Azure.IoT Build 0:ef4901974abc 848 void mqtt_client_deinit(MQTT_CLIENT_HANDLE handle)
Azure.IoT Build 0:ef4901974abc 849 {
Azure.IoT Build 0:ef4901974abc 850 /*Codes_SRS_MQTT_CLIENT_07_004: [If the parameter handle is NULL then function mqtt_client_deinit shall do nothing.]*/
Azure.IoT Build 0:ef4901974abc 851 if (handle != NULL)
Azure.IoT Build 0:ef4901974abc 852 {
Azure.IoT Build 0:ef4901974abc 853 /*Codes_SRS_MQTT_CLIENT_07_005: [mqtt_client_deinit shall deallocate all memory allocated in this unit.]*/
AzureIoTClient 8:83bb166aba73 854 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 855 tickcounter_destroy(mqtt_client->packetTickCntr);
AzureIoTClient 8:83bb166aba73 856 mqtt_codec_destroy(mqtt_client->codec_handle);
AzureIoTClient 8:83bb166aba73 857 free(mqtt_client);
Azure.IoT Build 0:ef4901974abc 858 }
Azure.IoT Build 0:ef4901974abc 859 }
Azure.IoT Build 0:ef4901974abc 860
Azure.IoT Build 0:ef4901974abc 861 int mqtt_client_connect(MQTT_CLIENT_HANDLE handle, XIO_HANDLE xioHandle, MQTT_CLIENT_OPTIONS* mqttOptions)
Azure.IoT Build 0:ef4901974abc 862 {
Azure.IoT Build 0:ef4901974abc 863 int result;
Azure.IoT Build 0:ef4901974abc 864 /*SRS_MQTT_CLIENT_07_006: [If any of the parameters handle, ioHandle, or mqttOptions are NULL then mqtt_client_connect shall return a non-zero value.]*/
Azure.IoT Build 0:ef4901974abc 865 if (handle == NULL || mqttOptions == NULL)
Azure.IoT Build 0:ef4901974abc 866 {
AzureIoTClient 11:a0a6a4cf7812 867 LOG(AZ_LOG_ERROR, LOG_LINE, "mqtt_client_connect: NULL argument (handle = %p, mqttOptions = %p)", handle, mqttOptions);
AzureIoTClient 15:ec5a36121959 868 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 869 }
Azure.IoT Build 0:ef4901974abc 870 else
Azure.IoT Build 0:ef4901974abc 871 {
AzureIoTClient 8:83bb166aba73 872 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
Azure.IoT Build 0:ef4901974abc 873 if (xioHandle == NULL)
Azure.IoT Build 0:ef4901974abc 874 {
Azure.IoT Build 0:ef4901974abc 875 /*Codes_SRS_MQTT_CLIENT_07_007: [If any failure is encountered then mqtt_client_connect shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 876 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqttcodec_connect failed");
AzureIoTClient 15:ec5a36121959 877 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 878 }
Azure.IoT Build 0:ef4901974abc 879 else
Azure.IoT Build 0:ef4901974abc 880 {
AzureIoTClient 8:83bb166aba73 881 mqtt_client->xioHandle = xioHandle;
AzureIoTClient 8:83bb166aba73 882 mqtt_client->packetState = UNKNOWN_TYPE;
AzureIoTClient 8:83bb166aba73 883 mqtt_client->qosValue = mqttOptions->qualityOfServiceValue;
AzureIoTClient 8:83bb166aba73 884 mqtt_client->keepAliveInterval = mqttOptions->keepAliveInterval;
AzureIoTClient 8:83bb166aba73 885 mqtt_client->maxPingRespTime = (DEFAULT_MAX_PING_RESPONSE_TIME < mqttOptions->keepAliveInterval/2) ? DEFAULT_MAX_PING_RESPONSE_TIME : mqttOptions->keepAliveInterval/2;
AzureIoTClient 8:83bb166aba73 886 if (cloneMqttOptions(mqtt_client, mqttOptions) != 0)
Azure.IoT Build 0:ef4901974abc 887 {
AzureIoTClient 11:a0a6a4cf7812 888 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: Clone Mqtt Options failed");
AzureIoTClient 15:ec5a36121959 889 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 890 }
Azure.IoT Build 0:ef4901974abc 891 /*Codes_SRS_MQTT_CLIENT_07_008: [mqtt_client_connect shall open the XIO_HANDLE by calling into the xio_open interface.]*/
AzureIoTClient 8:83bb166aba73 892 else if (xio_open(xioHandle, onOpenComplete, mqtt_client, onBytesReceived, mqtt_client, onIoError, mqtt_client) != 0)
Azure.IoT Build 0:ef4901974abc 893 {
Azure.IoT Build 0:ef4901974abc 894 /*Codes_SRS_MQTT_CLIENT_07_007: [If any failure is encountered then mqtt_client_connect shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 895 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: io_open failed");
AzureIoTClient 15:ec5a36121959 896 result = __FAILURE__;
AzureIoTClient 14:4b5b4dccfc8b 897 // Remove cloned options
AzureIoTClient 14:4b5b4dccfc8b 898 clear_mqtt_options(mqtt_client);
Azure.IoT Build 0:ef4901974abc 899 }
Azure.IoT Build 0:ef4901974abc 900 else
Azure.IoT Build 0:ef4901974abc 901 {
Azure.IoT Build 0:ef4901974abc 902 result = 0;
Azure.IoT Build 0:ef4901974abc 903 }
Azure.IoT Build 0:ef4901974abc 904 }
Azure.IoT Build 0:ef4901974abc 905 }
Azure.IoT Build 0:ef4901974abc 906 return result;
Azure.IoT Build 0:ef4901974abc 907 }
Azure.IoT Build 0:ef4901974abc 908
Azure.IoT Build 0:ef4901974abc 909 int mqtt_client_publish(MQTT_CLIENT_HANDLE handle, MQTT_MESSAGE_HANDLE msgHandle)
Azure.IoT Build 0:ef4901974abc 910 {
Azure.IoT Build 0:ef4901974abc 911 int result;
AzureIoTClient 8:83bb166aba73 912 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 913 if (mqtt_client == NULL || msgHandle == NULL)
Azure.IoT Build 0:ef4901974abc 914 {
Azure.IoT Build 0:ef4901974abc 915 /*Codes_SRS_MQTT_CLIENT_07_019: [If one of the parameters handle or msgHandle is NULL then mqtt_client_publish shall return a non-zero value.]*/
AzureIoTClient 15:ec5a36121959 916 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 917 }
Azure.IoT Build 0:ef4901974abc 918 else
Azure.IoT Build 0:ef4901974abc 919 {
Azure.IoT Build 0:ef4901974abc 920 /*Codes_SRS_MQTT_CLIENT_07_021: [mqtt_client_publish shall get the message information from the MQTT_MESSAGE_HANDLE.]*/
Azure.IoT Build 0:ef4901974abc 921 const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle);
Azure.IoT Build 0:ef4901974abc 922 if (payload == NULL)
Azure.IoT Build 0:ef4901974abc 923 {
Azure.IoT Build 0:ef4901974abc 924 /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 925 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqttmessage_getApplicationMsg failed");
AzureIoTClient 15:ec5a36121959 926 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 927 }
Azure.IoT Build 0:ef4901974abc 928 else
Azure.IoT Build 0:ef4901974abc 929 {
AzureIoTClient 8:83bb166aba73 930 STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
AzureIoTClient 8:83bb166aba73 931
AzureIoTClient 13:3c202001e4ba 932 QOS_VALUE qos = mqttmessage_getQosType(msgHandle);
AzureIoTClient 13:3c202001e4ba 933 bool isDuplicate = mqttmessage_getIsDuplicateMsg(msgHandle);
AzureIoTClient 13:3c202001e4ba 934 bool isRetained = mqttmessage_getIsRetained(msgHandle);
AzureIoTClient 13:3c202001e4ba 935 uint16_t packetId = mqttmessage_getPacketId(msgHandle);
AzureIoTClient 13:3c202001e4ba 936 const char* topicName = mqttmessage_getTopicName(msgHandle);
AzureIoTClient 13:3c202001e4ba 937 BUFFER_HANDLE publishPacket = mqtt_codec_publish(qos, isDuplicate, isRetained, packetId, topicName, payload->message, payload->length, trace_log);
Azure.IoT Build 0:ef4901974abc 938 if (publishPacket == NULL)
Azure.IoT Build 0:ef4901974abc 939 {
Azure.IoT Build 0:ef4901974abc 940 /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 941 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_codec_publish failed");
AzureIoTClient 15:ec5a36121959 942 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 943 }
Azure.IoT Build 0:ef4901974abc 944 else
Azure.IoT Build 0:ef4901974abc 945 {
AzureIoTClient 8:83bb166aba73 946 mqtt_client->packetState = PUBLISH_TYPE;
Azure.IoT Build 0:ef4901974abc 947
Azure.IoT Build 0:ef4901974abc 948 /*Codes_SRS_MQTT_CLIENT_07_022: [On success mqtt_client_publish shall send the MQTT SUBCRIBE packet to the endpoint.]*/
AzureIoTClient 13:3c202001e4ba 949 size_t size = BUFFER_length(publishPacket);
AzureIoTClient 13:3c202001e4ba 950 if (sendPacketItem(mqtt_client, BUFFER_u_char(publishPacket), size) != 0)
Azure.IoT Build 0:ef4901974abc 951 {
Azure.IoT Build 0:ef4901974abc 952 /*Codes_SRS_MQTT_CLIENT_07_020: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 953 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_publish send failed");
AzureIoTClient 15:ec5a36121959 954 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 955 }
Azure.IoT Build 0:ef4901974abc 956 else
Azure.IoT Build 0:ef4901974abc 957 {
AzureIoTClient 8:83bb166aba73 958 log_outgoing_trace(mqtt_client, trace_log);
Azure.IoT Build 0:ef4901974abc 959 result = 0;
Azure.IoT Build 0:ef4901974abc 960 }
Azure.IoT Build 0:ef4901974abc 961 BUFFER_delete(publishPacket);
Azure.IoT Build 0:ef4901974abc 962 }
AzureIoTClient 8:83bb166aba73 963 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 964 {
AzureIoTClient 8:83bb166aba73 965 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 966 }
Azure.IoT Build 0:ef4901974abc 967 }
Azure.IoT Build 0:ef4901974abc 968 }
Azure.IoT Build 0:ef4901974abc 969 return result;
Azure.IoT Build 0:ef4901974abc 970 }
Azure.IoT Build 0:ef4901974abc 971
Azure.IoT Build 0:ef4901974abc 972 int mqtt_client_subscribe(MQTT_CLIENT_HANDLE handle, uint16_t packetId, SUBSCRIBE_PAYLOAD* subscribeList, size_t count)
Azure.IoT Build 0:ef4901974abc 973 {
Azure.IoT Build 0:ef4901974abc 974 int result;
AzureIoTClient 8:83bb166aba73 975 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 976 if (mqtt_client == NULL || subscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 977 {
Azure.IoT Build 0:ef4901974abc 978 /*Codes_SRS_MQTT_CLIENT_07_013: [If any of the parameters handle, subscribeList is NULL or count is 0 then mqtt_client_subscribe shall return a non-zero value.]*/
AzureIoTClient 15:ec5a36121959 979 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 980 }
Azure.IoT Build 0:ef4901974abc 981 else
Azure.IoT Build 0:ef4901974abc 982 {
AzureIoTClient 8:83bb166aba73 983 STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
AzureIoTClient 8:83bb166aba73 984
AzureIoTClient 8:83bb166aba73 985 BUFFER_HANDLE subPacket = mqtt_codec_subscribe(packetId, subscribeList, count, trace_log);
Azure.IoT Build 0:ef4901974abc 986 if (subPacket == NULL)
Azure.IoT Build 0:ef4901974abc 987 {
Azure.IoT Build 0:ef4901974abc 988 /*Codes_SRS_MQTT_CLIENT_07_014: [If any failure is encountered then mqtt_client_subscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 989 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_codec_subscribe failed");
AzureIoTClient 15:ec5a36121959 990 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 991 }
Azure.IoT Build 0:ef4901974abc 992 else
Azure.IoT Build 0:ef4901974abc 993 {
AzureIoTClient 8:83bb166aba73 994 mqtt_client->packetState = SUBSCRIBE_TYPE;
Azure.IoT Build 0:ef4901974abc 995
AzureIoTClient 13:3c202001e4ba 996 size_t size = BUFFER_length(subPacket);
Azure.IoT Build 0:ef4901974abc 997 /*Codes_SRS_MQTT_CLIENT_07_015: [On success mqtt_client_subscribe shall send the MQTT SUBCRIBE packet to the endpoint.]*/
AzureIoTClient 13:3c202001e4ba 998 if (sendPacketItem(mqtt_client, BUFFER_u_char(subPacket), size) != 0)
Azure.IoT Build 0:ef4901974abc 999 {
Azure.IoT Build 0:ef4901974abc 1000 /*Codes_SRS_MQTT_CLIENT_07_014: [If any failure is encountered then mqtt_client_subscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 1001 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_subscribe send failed");
AzureIoTClient 15:ec5a36121959 1002 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1003 }
Azure.IoT Build 0:ef4901974abc 1004 else
Azure.IoT Build 0:ef4901974abc 1005 {
AzureIoTClient 8:83bb166aba73 1006 log_outgoing_trace(mqtt_client, trace_log);
Azure.IoT Build 0:ef4901974abc 1007 result = 0;
Azure.IoT Build 0:ef4901974abc 1008 }
Azure.IoT Build 0:ef4901974abc 1009 BUFFER_delete(subPacket);
Azure.IoT Build 0:ef4901974abc 1010 }
AzureIoTClient 8:83bb166aba73 1011 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1012 {
AzureIoTClient 8:83bb166aba73 1013 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 1014 }
Azure.IoT Build 0:ef4901974abc 1015 }
Azure.IoT Build 0:ef4901974abc 1016 return result;
Azure.IoT Build 0:ef4901974abc 1017 }
Azure.IoT Build 0:ef4901974abc 1018
Azure.IoT Build 0:ef4901974abc 1019 int mqtt_client_unsubscribe(MQTT_CLIENT_HANDLE handle, uint16_t packetId, const char** unsubscribeList, size_t count)
Azure.IoT Build 0:ef4901974abc 1020 {
Azure.IoT Build 0:ef4901974abc 1021 int result;
AzureIoTClient 8:83bb166aba73 1022 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 1023 if (mqtt_client == NULL || unsubscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 1024 {
Azure.IoT Build 0:ef4901974abc 1025 /*Codes_SRS_MQTT_CLIENT_07_016: [If any of the parameters handle, unsubscribeList is NULL or count is 0 then mqtt_client_unsubscribe shall return a non-zero value.]*/
AzureIoTClient 15:ec5a36121959 1026 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1027 }
Azure.IoT Build 0:ef4901974abc 1028 else
Azure.IoT Build 0:ef4901974abc 1029 {
AzureIoTClient 8:83bb166aba73 1030 STRING_HANDLE trace_log = construct_trace_log_handle(mqtt_client);
AzureIoTClient 8:83bb166aba73 1031
AzureIoTClient 8:83bb166aba73 1032 BUFFER_HANDLE unsubPacket = mqtt_codec_unsubscribe(packetId, unsubscribeList, count, trace_log);
Azure.IoT Build 0:ef4901974abc 1033 if (unsubPacket == NULL)
Azure.IoT Build 0:ef4901974abc 1034 {
Azure.IoT Build 0:ef4901974abc 1035 /*Codes_SRS_MQTT_CLIENT_07_017: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 1036 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_codec_unsubscribe failed");
AzureIoTClient 15:ec5a36121959 1037 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1038 }
Azure.IoT Build 0:ef4901974abc 1039 else
Azure.IoT Build 0:ef4901974abc 1040 {
AzureIoTClient 8:83bb166aba73 1041 mqtt_client->packetState = UNSUBSCRIBE_TYPE;
Azure.IoT Build 0:ef4901974abc 1042
AzureIoTClient 13:3c202001e4ba 1043 size_t size = BUFFER_length(unsubPacket);
Azure.IoT Build 0:ef4901974abc 1044 /*Codes_SRS_MQTT_CLIENT_07_018: [On success mqtt_client_unsubscribe shall send the MQTT SUBCRIBE packet to the endpoint.]*/
AzureIoTClient 13:3c202001e4ba 1045 if (sendPacketItem(mqtt_client, BUFFER_u_char(unsubPacket), size) != 0)
Azure.IoT Build 0:ef4901974abc 1046 {
Azure.IoT Build 0:ef4901974abc 1047 /*Codes_SRS_MQTT_CLIENT_07_017: [If any failure is encountered then mqtt_client_unsubscribe shall return a non-zero value.].]*/
AzureIoTClient 11:a0a6a4cf7812 1048 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_unsubscribe send failed");
AzureIoTClient 15:ec5a36121959 1049 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1050 }
Azure.IoT Build 0:ef4901974abc 1051 else
Azure.IoT Build 0:ef4901974abc 1052 {
AzureIoTClient 8:83bb166aba73 1053 log_outgoing_trace(mqtt_client, trace_log);
Azure.IoT Build 0:ef4901974abc 1054 result = 0;
Azure.IoT Build 0:ef4901974abc 1055 }
Azure.IoT Build 0:ef4901974abc 1056 BUFFER_delete(unsubPacket);
Azure.IoT Build 0:ef4901974abc 1057 }
AzureIoTClient 8:83bb166aba73 1058 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1059 {
AzureIoTClient 8:83bb166aba73 1060 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 1061 }
Azure.IoT Build 0:ef4901974abc 1062 }
Azure.IoT Build 0:ef4901974abc 1063 return result;
Azure.IoT Build 0:ef4901974abc 1064 }
Azure.IoT Build 0:ef4901974abc 1065
Azure.IoT Build 0:ef4901974abc 1066 int mqtt_client_disconnect(MQTT_CLIENT_HANDLE handle)
Azure.IoT Build 0:ef4901974abc 1067 {
Azure.IoT Build 0:ef4901974abc 1068 int result;
AzureIoTClient 8:83bb166aba73 1069 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 1070 if (mqtt_client == NULL)
Azure.IoT Build 0:ef4901974abc 1071 {
Azure.IoT Build 0:ef4901974abc 1072 /*Codes_SRS_MQTT_CLIENT_07_010: [If the parameters handle is NULL then mqtt_client_disconnect shall return a non-zero value.]*/
AzureIoTClient 15:ec5a36121959 1073 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1074 }
Azure.IoT Build 0:ef4901974abc 1075 else
Azure.IoT Build 0:ef4901974abc 1076 {
Azure.IoT Build 0:ef4901974abc 1077 BUFFER_HANDLE disconnectPacket = mqtt_codec_disconnect();
Azure.IoT Build 0:ef4901974abc 1078 if (disconnectPacket == NULL)
Azure.IoT Build 0:ef4901974abc 1079 {
Azure.IoT Build 0:ef4901974abc 1080 /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 1081 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect failed");
AzureIoTClient 8:83bb166aba73 1082 mqtt_client->packetState = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1083 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1084 }
Azure.IoT Build 0:ef4901974abc 1085 else
Azure.IoT Build 0:ef4901974abc 1086 {
AzureIoTClient 8:83bb166aba73 1087 mqtt_client->packetState = DISCONNECT_TYPE;
Azure.IoT Build 0:ef4901974abc 1088
AzureIoTClient 13:3c202001e4ba 1089 size_t size = BUFFER_length(disconnectPacket);
Azure.IoT Build 0:ef4901974abc 1090 /*Codes_SRS_MQTT_CLIENT_07_012: [On success mqtt_client_disconnect shall send the MQTT DISCONNECT packet to the endpoint.]*/
AzureIoTClient 13:3c202001e4ba 1091 if (sendPacketItem(mqtt_client, BUFFER_u_char(disconnectPacket), size) != 0)
Azure.IoT Build 0:ef4901974abc 1092 {
Azure.IoT Build 0:ef4901974abc 1093 /*Codes_SRS_MQTT_CLIENT_07_011: [If any failure is encountered then mqtt_client_disconnect shall return a non-zero value.]*/
AzureIoTClient 11:a0a6a4cf7812 1094 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: mqtt_client_disconnect send failed");
AzureIoTClient 15:ec5a36121959 1095 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1096 }
Azure.IoT Build 0:ef4901974abc 1097 else
Azure.IoT Build 0:ef4901974abc 1098 {
AzureIoTClient 8:83bb166aba73 1099 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 1100 {
AzureIoTClient 8:83bb166aba73 1101 STRING_HANDLE trace_log = STRING_construct("DISCONNECT");
AzureIoTClient 8:83bb166aba73 1102 log_outgoing_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 1103 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 1104 }
Azure.IoT Build 0:ef4901974abc 1105 result = 0;
Azure.IoT Build 0:ef4901974abc 1106 }
Azure.IoT Build 0:ef4901974abc 1107 BUFFER_delete(disconnectPacket);
AzureIoTClient 14:4b5b4dccfc8b 1108 clear_mqtt_options(mqtt_client);
Azure.IoT Build 0:ef4901974abc 1109 }
Azure.IoT Build 0:ef4901974abc 1110 }
Azure.IoT Build 0:ef4901974abc 1111 return result;
Azure.IoT Build 0:ef4901974abc 1112 }
Azure.IoT Build 0:ef4901974abc 1113
Azure.IoT Build 0:ef4901974abc 1114 void mqtt_client_dowork(MQTT_CLIENT_HANDLE handle)
Azure.IoT Build 0:ef4901974abc 1115 {
AzureIoTClient 8:83bb166aba73 1116 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
Azure.IoT Build 0:ef4901974abc 1117 /*Codes_SRS_MQTT_CLIENT_07_023: [If the parameter handle is NULL then mqtt_client_dowork shall do nothing.]*/
AzureIoTClient 8:83bb166aba73 1118 if (mqtt_client != NULL)
Azure.IoT Build 0:ef4901974abc 1119 {
Azure.IoT Build 0:ef4901974abc 1120 /*Codes_SRS_MQTT_CLIENT_07_024: [mqtt_client_dowork shall call the xio_dowork function to complete operations.]*/
AzureIoTClient 8:83bb166aba73 1121 xio_dowork(mqtt_client->xioHandle);
Azure.IoT Build 0:ef4901974abc 1122
Azure.IoT Build 0:ef4901974abc 1123 /*Codes_SRS_MQTT_CLIENT_07_025: [mqtt_client_dowork shall retrieve the the last packet send value and ...]*/
AzureIoTClient 8:83bb166aba73 1124 if (mqtt_client->socketConnected && mqtt_client->clientConnected && mqtt_client->keepAliveInterval > 0)
Azure.IoT Build 0:ef4901974abc 1125 {
Azure.IoT.Build 10:2ab268507775 1126 tickcounter_ms_t current_ms;
AzureIoTClient 8:83bb166aba73 1127 if (tickcounter_get_current_ms(mqtt_client->packetTickCntr, &current_ms) != 0)
Azure.IoT Build 0:ef4901974abc 1128 {
AzureIoTClient 11:a0a6a4cf7812 1129 LOG(AZ_LOG_ERROR, LOG_LINE, "Error: tickcounter_get_current_ms failed");
Azure.IoT Build 0:ef4901974abc 1130 }
Azure.IoT Build 0:ef4901974abc 1131 else
Azure.IoT Build 0:ef4901974abc 1132 {
AzureIoTClient 9:37d14c31ff6e 1133 /* Codes_SRS_MQTT_CLIENT_07_035: [If the timeSincePing has expired past the maxPingRespTime then mqtt_client_dowork shall call the Error Callback function with the message MQTT_CLIENT_NO_PING_RESPONSE] */
AzureIoTClient 8:83bb166aba73 1134 if (mqtt_client->timeSincePing > 0 && ((current_ms - mqtt_client->timeSincePing)/1000) > mqtt_client->maxPingRespTime)
AzureIoTClient 3:9b4e7158ca0d 1135 {
AzureIoTClient 3:9b4e7158ca0d 1136 // We haven't gotten a ping response in the alloted time
AzureIoTClient 9:37d14c31ff6e 1137 set_error_callback(mqtt_client, MQTT_CLIENT_NO_PING_RESPONSE);
AzureIoTClient 8:83bb166aba73 1138 mqtt_client->timeSincePing = 0;
AzureIoTClient 8:83bb166aba73 1139 mqtt_client->packetSendTimeMs = 0;
AzureIoTClient 8:83bb166aba73 1140 mqtt_client->packetState = UNKNOWN_TYPE;
AzureIoTClient 3:9b4e7158ca0d 1141 }
AzureIoTClient 8:83bb166aba73 1142 else if ((((current_ms - mqtt_client->packetSendTimeMs) / 1000) + KEEP_ALIVE_BUFFER_SEC) > mqtt_client->keepAliveInterval)
Azure.IoT Build 0:ef4901974abc 1143 {
Azure.IoT Build 0:ef4901974abc 1144 /*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.]*/
Azure.IoT Build 0:ef4901974abc 1145 BUFFER_HANDLE pingPacket = mqtt_codec_ping();
Azure.IoT Build 0:ef4901974abc 1146 if (pingPacket != NULL)
Azure.IoT Build 0:ef4901974abc 1147 {
AzureIoTClient 13:3c202001e4ba 1148 size_t size = BUFFER_length(pingPacket);
AzureIoTClient 13:3c202001e4ba 1149 (void)sendPacketItem(mqtt_client, BUFFER_u_char(pingPacket), size);
Azure.IoT Build 0:ef4901974abc 1150 BUFFER_delete(pingPacket);
AzureIoTClient 8:83bb166aba73 1151 (void)tickcounter_get_current_ms(mqtt_client->packetTickCntr, &mqtt_client->timeSincePing);
AzureIoTClient 8:83bb166aba73 1152
AzureIoTClient 8:83bb166aba73 1153 if (mqtt_client->logTrace)
AzureIoTClient 8:83bb166aba73 1154 {
AzureIoTClient 8:83bb166aba73 1155 STRING_HANDLE trace_log = STRING_construct("PINGREQ");
AzureIoTClient 8:83bb166aba73 1156 log_outgoing_trace(mqtt_client, trace_log);
AzureIoTClient 8:83bb166aba73 1157 STRING_delete(trace_log);
AzureIoTClient 8:83bb166aba73 1158 }
Azure.IoT Build 0:ef4901974abc 1159 }
Azure.IoT Build 0:ef4901974abc 1160 }
Azure.IoT Build 0:ef4901974abc 1161 }
Azure.IoT Build 0:ef4901974abc 1162 }
Azure.IoT Build 0:ef4901974abc 1163 }
Azure.IoT Build 0:ef4901974abc 1164 }
Azure.IoT Build 0:ef4901974abc 1165
Azure.IoT Build 0:ef4901974abc 1166 void mqtt_client_set_trace(MQTT_CLIENT_HANDLE handle, bool traceOn, bool rawBytesOn)
Azure.IoT Build 0:ef4901974abc 1167 {
AzureIoTClient 8:83bb166aba73 1168 MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
AzureIoTClient 8:83bb166aba73 1169 if (mqtt_client != NULL)
Azure.IoT Build 0:ef4901974abc 1170 {
AzureIoTClient 8:83bb166aba73 1171 mqtt_client->logTrace = traceOn;
AzureIoTClient 8:83bb166aba73 1172 mqtt_client->rawBytesTrace = rawBytesOn;
Azure.IoT Build 0:ef4901974abc 1173 }
Azure.IoT Build 0:ef4901974abc 1174 }