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:
Thu Oct 20 17:07:55 2016 -0700
Revision:
8:83bb166aba73
Parent:
6:d9c4702f91ca
Child:
9:37d14c31ff6e
1.0.10

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