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:
Tue Jan 24 15:24:05 2017 -0800
Revision:
12:30b08cda82fd
Parent:
11:a0a6a4cf7812
Child:
13:3c202001e4ba
1.1.5

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