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 04 09:16:34 2018 -0700
Revision:
30:712bcbf21afa
Parent:
28:35eea447689a
1.2.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 <limits.h>
AzureIoTClient 15:ec5a36121959 6 #include "azure_c_shared_utility/optimize_size.h"
Azure.IoT Build 0:ef4901974abc 7 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:ef4901974abc 8 #include "azure_c_shared_utility/buffer_.h"
AzureIoTClient 8:83bb166aba73 9 #include "azure_c_shared_utility/strings.h"
Azure.IoT Build 0:ef4901974abc 10 #include "azure_c_shared_utility/macro_utils.h"
Azure.IoT Build 0:ef4901974abc 11 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 0:ef4901974abc 12 #include "azure_umqtt_c/mqtt_codec.h"
AzureIoTClient 8:83bb166aba73 13 #include <inttypes.h>
Azure.IoT Build 0:ef4901974abc 14
Azure.IoT Build 0:ef4901974abc 15 #define PAYLOAD_OFFSET 5
AzureIoTClient 28:35eea447689a 16 #define PACKET_TYPE_BYTE(p) (CONTROL_PACKET_TYPE)((uint8_t)(((uint8_t)(p)) & 0xf0))
Azure.IoT Build 0:ef4901974abc 17 #define FLAG_VALUE_BYTE(p) ((uint8_t)(((uint8_t)(p)) & 0xf))
Azure.IoT Build 0:ef4901974abc 18
Azure.IoT Build 0:ef4901974abc 19 #define USERNAME_FLAG 0x80
Azure.IoT Build 0:ef4901974abc 20 #define PASSWORD_FLAG 0x40
Azure.IoT Build 0:ef4901974abc 21 #define WILL_RETAIN_FLAG 0x20
Azure.IoT Build 0:ef4901974abc 22 #define WILL_QOS_FLAG_ 0x18
Azure.IoT Build 0:ef4901974abc 23 #define WILL_FLAG_FLAG 0x04
Azure.IoT Build 0:ef4901974abc 24 #define CLEAN_SESSION_FLAG 0x02
Azure.IoT Build 0:ef4901974abc 25
Azure.IoT Build 0:ef4901974abc 26 #define NEXT_128_CHUNK 0x80
Azure.IoT Build 0:ef4901974abc 27 #define PUBLISH_DUP_FLAG 0x8
Azure.IoT Build 0:ef4901974abc 28 #define PUBLISH_QOS_EXACTLY_ONCE 0x4
Azure.IoT Build 0:ef4901974abc 29 #define PUBLISH_QOS_AT_LEAST_ONCE 0x2
Azure.IoT Build 0:ef4901974abc 30 #define PUBLISH_QOS_RETAIN 0x1
Azure.IoT Build 0:ef4901974abc 31
Azure.IoT Build 0:ef4901974abc 32 #define PROTOCOL_NUMBER 4
Azure.IoT Build 0:ef4901974abc 33 #define CONN_FLAG_BYTE_OFFSET 7
Azure.IoT Build 0:ef4901974abc 34
Azure.IoT Build 0:ef4901974abc 35 #define CONNECT_FIXED_HEADER_SIZE 2
Azure.IoT Build 0:ef4901974abc 36 #define CONNECT_VARIABLE_HEADER_SIZE 10
Azure.IoT Build 0:ef4901974abc 37 #define SUBSCRIBE_FIXED_HEADER_FLAG 0x2
Azure.IoT Build 0:ef4901974abc 38 #define UNSUBSCRIBE_FIXED_HEADER_FLAG 0x2
Azure.IoT Build 0:ef4901974abc 39
Azure.IoT Build 0:ef4901974abc 40 #define MAX_SEND_SIZE 0xFFFFFF7F
Azure.IoT Build 0:ef4901974abc 41
Azure.IoT Build 0:ef4901974abc 42 #define CODEC_STATE_VALUES \
Azure.IoT Build 0:ef4901974abc 43 CODEC_STATE_FIXED_HEADER, \
Azure.IoT Build 0:ef4901974abc 44 CODEC_STATE_VAR_HEADER, \
Azure.IoT Build 0:ef4901974abc 45 CODEC_STATE_PAYLOAD
Azure.IoT Build 0:ef4901974abc 46
AzureIoTClient 24:75f5b91d1c6e 47 static const char* const TRUE_CONST = "true";
AzureIoTClient 24:75f5b91d1c6e 48 static const char* const FALSE_CONST = "false";
AzureIoTClient 8:83bb166aba73 49
Azure.IoT Build 0:ef4901974abc 50 DEFINE_ENUM(CODEC_STATE_RESULT, CODEC_STATE_VALUES);
Azure.IoT Build 0:ef4901974abc 51
Azure.IoT Build 0:ef4901974abc 52 typedef struct MQTTCODEC_INSTANCE_TAG
Azure.IoT Build 0:ef4901974abc 53 {
Azure.IoT Build 0:ef4901974abc 54 CONTROL_PACKET_TYPE currPacket;
Azure.IoT Build 0:ef4901974abc 55 CODEC_STATE_RESULT codecState;
Azure.IoT Build 0:ef4901974abc 56 size_t bufferOffset;
Azure.IoT Build 0:ef4901974abc 57 int headerFlags;
Azure.IoT Build 0:ef4901974abc 58 BUFFER_HANDLE headerData;
Azure.IoT Build 0:ef4901974abc 59 ON_PACKET_COMPLETE_CALLBACK packetComplete;
Azure.IoT Build 0:ef4901974abc 60 void* callContext;
Azure.IoT Build 0:ef4901974abc 61 uint8_t storeRemainLen[4];
Azure.IoT Build 0:ef4901974abc 62 size_t remainLenIndex;
Azure.IoT Build 0:ef4901974abc 63 } MQTTCODEC_INSTANCE;
Azure.IoT Build 0:ef4901974abc 64
Azure.IoT Build 0:ef4901974abc 65 typedef struct PUBLISH_HEADER_INFO_TAG
Azure.IoT Build 0:ef4901974abc 66 {
Azure.IoT Build 0:ef4901974abc 67 const char* topicName;
Azure.IoT Build 0:ef4901974abc 68 uint16_t packetId;
Azure.IoT Build 0:ef4901974abc 69 const char* msgBuffer;
Azure.IoT Build 0:ef4901974abc 70 QOS_VALUE qualityOfServiceValue;
Azure.IoT Build 0:ef4901974abc 71 } PUBLISH_HEADER_INFO;
Azure.IoT Build 0:ef4901974abc 72
AzureIoTClient 8:83bb166aba73 73 static const char* retrieve_qos_value(QOS_VALUE value)
AzureIoTClient 8:83bb166aba73 74 {
AzureIoTClient 8:83bb166aba73 75 switch (value)
AzureIoTClient 8:83bb166aba73 76 {
AzureIoTClient 8:83bb166aba73 77 case DELIVER_AT_MOST_ONCE:
AzureIoTClient 8:83bb166aba73 78 return "DELIVER_AT_MOST_ONCE";
AzureIoTClient 8:83bb166aba73 79 case DELIVER_AT_LEAST_ONCE:
AzureIoTClient 8:83bb166aba73 80 return "DELIVER_AT_LEAST_ONCE";
AzureIoTClient 8:83bb166aba73 81 case DELIVER_EXACTLY_ONCE:
AzureIoTClient 8:83bb166aba73 82 default:
AzureIoTClient 8:83bb166aba73 83 return "DELIVER_EXACTLY_ONCE";
AzureIoTClient 8:83bb166aba73 84 }
AzureIoTClient 8:83bb166aba73 85 }
AzureIoTClient 8:83bb166aba73 86
AzureIoTClient 26:53b5ecbf74f9 87 static void byteutil_writeByte(uint8_t** buffer, uint8_t value)
Azure.IoT Build 0:ef4901974abc 88 {
Azure.IoT Build 0:ef4901974abc 89 if (buffer != NULL)
Azure.IoT Build 0:ef4901974abc 90 {
Azure.IoT Build 0:ef4901974abc 91 **buffer = value;
Azure.IoT Build 0:ef4901974abc 92 (*buffer)++;
Azure.IoT Build 0:ef4901974abc 93 }
Azure.IoT Build 0:ef4901974abc 94 }
Azure.IoT Build 0:ef4901974abc 95
AzureIoTClient 26:53b5ecbf74f9 96 static void byteutil_writeInt(uint8_t** buffer, uint16_t value)
Azure.IoT Build 0:ef4901974abc 97 {
Azure.IoT Build 0:ef4901974abc 98 if (buffer != NULL)
Azure.IoT Build 0:ef4901974abc 99 {
Azure.IoT Build 0:ef4901974abc 100 **buffer = (char)(value / 256);
Azure.IoT Build 0:ef4901974abc 101 (*buffer)++;
Azure.IoT Build 0:ef4901974abc 102 **buffer = (char)(value % 256);
Azure.IoT Build 0:ef4901974abc 103 (*buffer)++;
Azure.IoT Build 0:ef4901974abc 104 }
Azure.IoT Build 0:ef4901974abc 105 }
Azure.IoT Build 0:ef4901974abc 106
AzureIoTClient 26:53b5ecbf74f9 107 static void byteutil_writeUTF(uint8_t** buffer, const char* stringData, uint16_t len)
Azure.IoT Build 0:ef4901974abc 108 {
Azure.IoT Build 0:ef4901974abc 109 if (buffer != NULL)
Azure.IoT Build 0:ef4901974abc 110 {
Azure.IoT Build 0:ef4901974abc 111 byteutil_writeInt(buffer, len);
Azure.IoT Build 0:ef4901974abc 112 (void)memcpy(*buffer, stringData, len);
Azure.IoT Build 0:ef4901974abc 113 *buffer += len;
Azure.IoT Build 0:ef4901974abc 114 }
Azure.IoT Build 0:ef4901974abc 115 }
Azure.IoT Build 0:ef4901974abc 116
AzureIoTClient 26:53b5ecbf74f9 117 static CONTROL_PACKET_TYPE processControlPacketType(uint8_t pktByte, int* flags)
Azure.IoT Build 0:ef4901974abc 118 {
Azure.IoT Build 0:ef4901974abc 119 CONTROL_PACKET_TYPE result;
Azure.IoT Build 0:ef4901974abc 120 result = PACKET_TYPE_BYTE(pktByte);
Azure.IoT Build 0:ef4901974abc 121 if (flags != NULL)
Azure.IoT Build 0:ef4901974abc 122 {
Azure.IoT Build 0:ef4901974abc 123 *flags = FLAG_VALUE_BYTE(pktByte);
Azure.IoT Build 0:ef4901974abc 124 }
Azure.IoT Build 0:ef4901974abc 125 return result;
Azure.IoT Build 0:ef4901974abc 126 }
Azure.IoT Build 0:ef4901974abc 127
AzureIoTClient 8:83bb166aba73 128 static int addListItemsToUnsubscribePacket(BUFFER_HANDLE ctrlPacket, const char** payloadList, size_t payloadCount, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 129 {
Azure.IoT Build 0:ef4901974abc 130 int result = 0;
Azure.IoT Build 0:ef4901974abc 131 if (payloadList == NULL || ctrlPacket == NULL)
Azure.IoT Build 0:ef4901974abc 132 {
AzureIoTClient 15:ec5a36121959 133 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 134 }
Azure.IoT Build 0:ef4901974abc 135 else
Azure.IoT Build 0:ef4901974abc 136 {
AzureIoTClient 12:30b08cda82fd 137 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 138 for (index = 0; index < payloadCount && result == 0; index++)
Azure.IoT Build 0:ef4901974abc 139 {
Azure.IoT Build 0:ef4901974abc 140 // Add the Payload
Azure.IoT Build 0:ef4901974abc 141 size_t offsetLen = BUFFER_length(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 142 size_t topicLen = strlen(payloadList[index]);
Azure.IoT Build 0:ef4901974abc 143 if (topicLen > USHRT_MAX)
Azure.IoT Build 0:ef4901974abc 144 {
AzureIoTClient 15:ec5a36121959 145 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 146 }
Azure.IoT Build 0:ef4901974abc 147 else if (BUFFER_enlarge(ctrlPacket, topicLen + 2) != 0)
Azure.IoT Build 0:ef4901974abc 148 {
AzureIoTClient 15:ec5a36121959 149 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 150 }
Azure.IoT Build 0:ef4901974abc 151 else
Azure.IoT Build 0:ef4901974abc 152 {
Azure.IoT Build 0:ef4901974abc 153 uint8_t* iterator = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 154 iterator += offsetLen;
Azure.IoT Build 0:ef4901974abc 155 byteutil_writeUTF(&iterator, payloadList[index], (uint16_t)topicLen);
Azure.IoT Build 0:ef4901974abc 156 }
AzureIoTClient 8:83bb166aba73 157 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 158 {
AzureIoTClient 8:83bb166aba73 159 STRING_sprintf(trace_log, " | TOPIC_NAME: %s", payloadList[index]);
AzureIoTClient 8:83bb166aba73 160 }
Azure.IoT Build 0:ef4901974abc 161 }
Azure.IoT Build 0:ef4901974abc 162 }
Azure.IoT Build 0:ef4901974abc 163 return result;
Azure.IoT Build 0:ef4901974abc 164 }
Azure.IoT Build 0:ef4901974abc 165
AzureIoTClient 8:83bb166aba73 166 static int addListItemsToSubscribePacket(BUFFER_HANDLE ctrlPacket, SUBSCRIBE_PAYLOAD* payloadList, size_t payloadCount, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 167 {
Azure.IoT Build 0:ef4901974abc 168 int result = 0;
Azure.IoT Build 0:ef4901974abc 169 if (payloadList == NULL || ctrlPacket == NULL)
Azure.IoT Build 0:ef4901974abc 170 {
AzureIoTClient 15:ec5a36121959 171 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 172 }
Azure.IoT Build 0:ef4901974abc 173 else
Azure.IoT Build 0:ef4901974abc 174 {
AzureIoTClient 12:30b08cda82fd 175 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 176 for (index = 0; index < payloadCount && result == 0; index++)
Azure.IoT Build 0:ef4901974abc 177 {
Azure.IoT Build 0:ef4901974abc 178 // Add the Payload
Azure.IoT Build 0:ef4901974abc 179 size_t offsetLen = BUFFER_length(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 180 size_t topicLen = strlen(payloadList[index].subscribeTopic);
Azure.IoT Build 0:ef4901974abc 181 if (topicLen > USHRT_MAX)
Azure.IoT Build 0:ef4901974abc 182 {
AzureIoTClient 15:ec5a36121959 183 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 184 }
Azure.IoT Build 0:ef4901974abc 185 else if (BUFFER_enlarge(ctrlPacket, topicLen + 2 + 1) != 0)
Azure.IoT Build 0:ef4901974abc 186 {
AzureIoTClient 15:ec5a36121959 187 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 188 }
Azure.IoT Build 0:ef4901974abc 189 else
Azure.IoT Build 0:ef4901974abc 190 {
Azure.IoT Build 0:ef4901974abc 191 uint8_t* iterator = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 192 iterator += offsetLen;
Azure.IoT Build 0:ef4901974abc 193 byteutil_writeUTF(&iterator, payloadList[index].subscribeTopic, (uint16_t)topicLen);
Azure.IoT Build 0:ef4901974abc 194 *iterator = payloadList[index].qosReturn;
AzureIoTClient 8:83bb166aba73 195
AzureIoTClient 8:83bb166aba73 196 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 197 {
AzureIoTClient 8:83bb166aba73 198 STRING_sprintf(trace_log, " | TOPIC_NAME: %s | QOS: %d", payloadList[index].subscribeTopic, (int)payloadList[index].qosReturn);
AzureIoTClient 8:83bb166aba73 199 }
Azure.IoT Build 0:ef4901974abc 200 }
Azure.IoT Build 0:ef4901974abc 201 }
Azure.IoT Build 0:ef4901974abc 202 }
Azure.IoT Build 0:ef4901974abc 203 return result;
Azure.IoT Build 0:ef4901974abc 204 }
Azure.IoT Build 0:ef4901974abc 205
AzureIoTClient 8:83bb166aba73 206 static int constructConnectVariableHeader(BUFFER_HANDLE ctrlPacket, const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 207 {
Azure.IoT Build 0:ef4901974abc 208 int result = 0;
Azure.IoT Build 0:ef4901974abc 209 if (BUFFER_enlarge(ctrlPacket, CONNECT_VARIABLE_HEADER_SIZE) != 0)
Azure.IoT Build 0:ef4901974abc 210 {
AzureIoTClient 15:ec5a36121959 211 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 212 }
Azure.IoT Build 0:ef4901974abc 213 else
Azure.IoT Build 0:ef4901974abc 214 {
Azure.IoT Build 0:ef4901974abc 215 uint8_t* iterator = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 216 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 217 {
AzureIoTClient 15:ec5a36121959 218 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 219 }
Azure.IoT Build 0:ef4901974abc 220 else
Azure.IoT Build 0:ef4901974abc 221 {
AzureIoTClient 8:83bb166aba73 222 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 223 {
AzureIoTClient 8:83bb166aba73 224 STRING_sprintf(trace_log, " | VER: %d | KEEPALIVE: %d | FLAGS:", PROTOCOL_NUMBER, mqttOptions->keepAliveInterval);
AzureIoTClient 8:83bb166aba73 225 }
Azure.IoT Build 0:ef4901974abc 226 byteutil_writeUTF(&iterator, "MQTT", 4);
Azure.IoT Build 0:ef4901974abc 227 byteutil_writeByte(&iterator, PROTOCOL_NUMBER);
Azure.IoT Build 0:ef4901974abc 228 byteutil_writeByte(&iterator, 0); // Flags will be entered later
Azure.IoT Build 0:ef4901974abc 229 byteutil_writeInt(&iterator, mqttOptions->keepAliveInterval);
Azure.IoT Build 0:ef4901974abc 230 result = 0;
Azure.IoT Build 0:ef4901974abc 231 }
Azure.IoT Build 0:ef4901974abc 232 }
Azure.IoT Build 0:ef4901974abc 233 return result;
Azure.IoT Build 0:ef4901974abc 234 }
Azure.IoT Build 0:ef4901974abc 235
AzureIoTClient 8:83bb166aba73 236 static int constructPublishVariableHeader(BUFFER_HANDLE ctrlPacket, const PUBLISH_HEADER_INFO* publishHeader, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 237 {
Azure.IoT Build 0:ef4901974abc 238 int result = 0;
Azure.IoT Build 0:ef4901974abc 239 size_t topicLen = 0;
Azure.IoT Build 0:ef4901974abc 240 size_t spaceLen = 0;
Azure.IoT Build 0:ef4901974abc 241 size_t idLen = 0;
Azure.IoT Build 0:ef4901974abc 242
Azure.IoT Build 0:ef4901974abc 243 size_t currLen = BUFFER_length(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 244
Azure.IoT Build 0:ef4901974abc 245 topicLen = strlen(publishHeader->topicName);
Azure.IoT Build 0:ef4901974abc 246 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 247
Azure.IoT Build 0:ef4901974abc 248 if (publishHeader->qualityOfServiceValue != DELIVER_AT_MOST_ONCE)
Azure.IoT Build 0:ef4901974abc 249 {
Azure.IoT Build 0:ef4901974abc 250 // Packet Id is only set if the QOS is not 0
Azure.IoT Build 0:ef4901974abc 251 idLen = 2;
Azure.IoT Build 0:ef4901974abc 252 }
Azure.IoT Build 0:ef4901974abc 253
Azure.IoT Build 0:ef4901974abc 254 if (topicLen > USHRT_MAX)
Azure.IoT Build 0:ef4901974abc 255 {
AzureIoTClient 15:ec5a36121959 256 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 257 }
Azure.IoT Build 0:ef4901974abc 258 else if (BUFFER_enlarge(ctrlPacket, topicLen + idLen + spaceLen) != 0)
Azure.IoT Build 0:ef4901974abc 259 {
AzureIoTClient 15:ec5a36121959 260 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 261 }
Azure.IoT Build 0:ef4901974abc 262 else
Azure.IoT Build 0:ef4901974abc 263 {
Azure.IoT Build 0:ef4901974abc 264 uint8_t* iterator = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 265 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 266 {
AzureIoTClient 15:ec5a36121959 267 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 268 }
Azure.IoT Build 0:ef4901974abc 269 else
Azure.IoT Build 0:ef4901974abc 270 {
Azure.IoT Build 0:ef4901974abc 271 iterator += currLen;
Azure.IoT Build 0:ef4901974abc 272 /* The Topic Name MUST be present as the first field in the PUBLISH Packet Variable header.It MUST be 792 a UTF-8 encoded string [MQTT-3.3.2-1] as defined in section 1.5.3.*/
Azure.IoT Build 0:ef4901974abc 273 byteutil_writeUTF(&iterator, publishHeader->topicName, (uint16_t)topicLen);
AzureIoTClient 8:83bb166aba73 274 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 275 {
AzureIoTClient 8:83bb166aba73 276 STRING_sprintf(trace_log, " | TOPIC_NAME: %s", publishHeader->topicName);
AzureIoTClient 8:83bb166aba73 277 }
Azure.IoT Build 0:ef4901974abc 278 if (idLen > 0)
Azure.IoT Build 0:ef4901974abc 279 {
AzureIoTClient 8:83bb166aba73 280 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 281 {
AzureIoTClient 8:83bb166aba73 282 STRING_sprintf(trace_log, " | PACKET_ID: %"PRIu16, publishHeader->packetId);
AzureIoTClient 8:83bb166aba73 283 }
Azure.IoT Build 0:ef4901974abc 284 byteutil_writeInt(&iterator, publishHeader->packetId);
Azure.IoT Build 0:ef4901974abc 285 }
Azure.IoT Build 0:ef4901974abc 286 result = 0;
Azure.IoT Build 0:ef4901974abc 287 }
Azure.IoT Build 0:ef4901974abc 288 }
Azure.IoT Build 0:ef4901974abc 289 return result;
Azure.IoT Build 0:ef4901974abc 290 }
Azure.IoT Build 0:ef4901974abc 291
Azure.IoT Build 0:ef4901974abc 292 static int constructSubscibeTypeVariableHeader(BUFFER_HANDLE ctrlPacket, uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 293 {
Azure.IoT Build 0:ef4901974abc 294 int result = 0;
Azure.IoT Build 0:ef4901974abc 295 if (BUFFER_enlarge(ctrlPacket, 2) != 0)
Azure.IoT Build 0:ef4901974abc 296 {
AzureIoTClient 15:ec5a36121959 297 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 298 }
Azure.IoT Build 0:ef4901974abc 299 else
Azure.IoT Build 0:ef4901974abc 300 {
Azure.IoT Build 0:ef4901974abc 301 uint8_t* iterator = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 302 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 303 {
AzureIoTClient 15:ec5a36121959 304 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 305 }
Azure.IoT Build 0:ef4901974abc 306 else
Azure.IoT Build 0:ef4901974abc 307 {
Azure.IoT Build 0:ef4901974abc 308 byteutil_writeInt(&iterator, packetId);
Azure.IoT Build 0:ef4901974abc 309 result = 0;
Azure.IoT Build 0:ef4901974abc 310 }
Azure.IoT Build 0:ef4901974abc 311 }
Azure.IoT Build 0:ef4901974abc 312 return result;
Azure.IoT Build 0:ef4901974abc 313 }
Azure.IoT Build 0:ef4901974abc 314
AzureIoTClient 5:34779607059c 315 static BUFFER_HANDLE constructPublishReply(CONTROL_PACKET_TYPE type, uint8_t flags, uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 316 {
Azure.IoT Build 0:ef4901974abc 317 BUFFER_HANDLE result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 318 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 319 {
Azure.IoT Build 0:ef4901974abc 320 if (BUFFER_pre_build(result, 4) != 0)
Azure.IoT Build 0:ef4901974abc 321 {
Azure.IoT Build 0:ef4901974abc 322 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 323 result = NULL;
Azure.IoT Build 0:ef4901974abc 324 }
Azure.IoT Build 0:ef4901974abc 325 else
Azure.IoT Build 0:ef4901974abc 326 {
Azure.IoT Build 0:ef4901974abc 327 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 328 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 329 {
Azure.IoT Build 0:ef4901974abc 330 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 331 result = NULL;
Azure.IoT Build 0:ef4901974abc 332 }
Azure.IoT Build 0:ef4901974abc 333 else
Azure.IoT Build 0:ef4901974abc 334 {
AzureIoTClient 5:34779607059c 335 *iterator = (uint8_t)type | flags;
Azure.IoT Build 0:ef4901974abc 336 iterator++;
Azure.IoT Build 0:ef4901974abc 337 *iterator = 0x2;
Azure.IoT Build 0:ef4901974abc 338 iterator++;
Azure.IoT Build 0:ef4901974abc 339 byteutil_writeInt(&iterator, packetId);
Azure.IoT Build 0:ef4901974abc 340 }
Azure.IoT Build 0:ef4901974abc 341 }
Azure.IoT Build 0:ef4901974abc 342 }
Azure.IoT Build 0:ef4901974abc 343 return result;
Azure.IoT Build 0:ef4901974abc 344 }
Azure.IoT Build 0:ef4901974abc 345
Azure.IoT Build 0:ef4901974abc 346 static int constructFixedHeader(BUFFER_HANDLE ctrlPacket, CONTROL_PACKET_TYPE packetType, uint8_t flags)
Azure.IoT Build 0:ef4901974abc 347 {
Azure.IoT Build 0:ef4901974abc 348 int result;
Azure.IoT Build 0:ef4901974abc 349 if (ctrlPacket == NULL)
Azure.IoT Build 0:ef4901974abc 350 {
AzureIoTClient 15:ec5a36121959 351 return __FAILURE__;
Azure.IoT Build 0:ef4901974abc 352 }
Azure.IoT Build 0:ef4901974abc 353 else
Azure.IoT Build 0:ef4901974abc 354 {
Azure.IoT Build 0:ef4901974abc 355 size_t packetLen = BUFFER_length(ctrlPacket);
AzureIoTClient 8:83bb166aba73 356 uint8_t remainSize[4] ={ 0 };
Azure.IoT Build 0:ef4901974abc 357 size_t index = 0;
Azure.IoT Build 0:ef4901974abc 358
Azure.IoT Build 0:ef4901974abc 359 // Calculate the length of packet
Azure.IoT Build 0:ef4901974abc 360 do
Azure.IoT Build 0:ef4901974abc 361 {
Azure.IoT Build 0:ef4901974abc 362 uint8_t encode = packetLen % 128;
Azure.IoT Build 0:ef4901974abc 363 packetLen /= 128;
Azure.IoT Build 0:ef4901974abc 364 // if there are more data to encode, set the top bit of this byte
Azure.IoT Build 0:ef4901974abc 365 if (packetLen > 0)
Azure.IoT Build 0:ef4901974abc 366 {
Azure.IoT Build 0:ef4901974abc 367 encode |= NEXT_128_CHUNK;
Azure.IoT Build 0:ef4901974abc 368 }
Azure.IoT Build 0:ef4901974abc 369 remainSize[index++] = encode;
Azure.IoT Build 0:ef4901974abc 370 } while (packetLen > 0);
Azure.IoT Build 0:ef4901974abc 371
Azure.IoT Build 0:ef4901974abc 372 BUFFER_HANDLE fixedHeader = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 373 if (fixedHeader == NULL)
Azure.IoT Build 0:ef4901974abc 374 {
AzureIoTClient 15:ec5a36121959 375 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 376 }
Azure.IoT Build 0:ef4901974abc 377 else if (BUFFER_pre_build(fixedHeader, index + 1) != 0)
Azure.IoT Build 0:ef4901974abc 378 {
Azure.IoT Build 0:ef4901974abc 379 BUFFER_delete(fixedHeader);
AzureIoTClient 15:ec5a36121959 380 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 381 }
Azure.IoT Build 0:ef4901974abc 382 else
Azure.IoT Build 0:ef4901974abc 383 {
Azure.IoT Build 0:ef4901974abc 384 uint8_t* iterator = BUFFER_u_char(fixedHeader);
AzureIoTClient 5:34779607059c 385 *iterator = (uint8_t)packetType | flags;
Azure.IoT Build 0:ef4901974abc 386 iterator++;
Azure.IoT Build 0:ef4901974abc 387 (void)memcpy(iterator, remainSize, index);
Azure.IoT Build 0:ef4901974abc 388
Azure.IoT Build 0:ef4901974abc 389 result = BUFFER_prepend(ctrlPacket, fixedHeader);
Azure.IoT Build 0:ef4901974abc 390 BUFFER_delete(fixedHeader);
Azure.IoT Build 0:ef4901974abc 391 }
Azure.IoT Build 0:ef4901974abc 392 }
Azure.IoT Build 0:ef4901974abc 393 return result;
Azure.IoT Build 0:ef4901974abc 394 }
Azure.IoT Build 0:ef4901974abc 395
AzureIoTClient 8:83bb166aba73 396 static int constructConnPayload(BUFFER_HANDLE ctrlPacket, const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 397 {
Azure.IoT Build 0:ef4901974abc 398 int result = 0;
Azure.IoT Build 0:ef4901974abc 399 if (mqttOptions == NULL || ctrlPacket == NULL)
Azure.IoT Build 0:ef4901974abc 400 {
AzureIoTClient 15:ec5a36121959 401 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 402 }
Azure.IoT Build 0:ef4901974abc 403 else
Azure.IoT Build 0:ef4901974abc 404 {
Azure.IoT Build 0:ef4901974abc 405 size_t clientLen = 0;
Azure.IoT Build 0:ef4901974abc 406 size_t usernameLen = 0;
Azure.IoT Build 0:ef4901974abc 407 size_t passwordLen = 0;
Azure.IoT Build 0:ef4901974abc 408 size_t willMessageLen = 0;
Azure.IoT Build 0:ef4901974abc 409 size_t willTopicLen = 0;
Azure.IoT Build 0:ef4901974abc 410 size_t spaceLen = 0;
Azure.IoT Build 0:ef4901974abc 411
Azure.IoT Build 0:ef4901974abc 412 if (mqttOptions->clientId != NULL)
Azure.IoT Build 0:ef4901974abc 413 {
Azure.IoT Build 0:ef4901974abc 414 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 415 clientLen = strlen(mqttOptions->clientId);
Azure.IoT Build 0:ef4901974abc 416 }
Azure.IoT Build 0:ef4901974abc 417 if (mqttOptions->username != NULL)
Azure.IoT Build 0:ef4901974abc 418 {
Azure.IoT Build 0:ef4901974abc 419 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 420 usernameLen = strlen(mqttOptions->username);
Azure.IoT Build 0:ef4901974abc 421 }
Azure.IoT Build 0:ef4901974abc 422 if (mqttOptions->password != NULL)
Azure.IoT Build 0:ef4901974abc 423 {
Azure.IoT Build 0:ef4901974abc 424 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 425 passwordLen = strlen(mqttOptions->password);
Azure.IoT Build 0:ef4901974abc 426 }
Azure.IoT Build 0:ef4901974abc 427 if (mqttOptions->willMessage != NULL)
Azure.IoT Build 0:ef4901974abc 428 {
Azure.IoT Build 0:ef4901974abc 429 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 430 willMessageLen = strlen(mqttOptions->willMessage);
Azure.IoT Build 0:ef4901974abc 431 }
Azure.IoT Build 0:ef4901974abc 432 if (mqttOptions->willTopic != NULL)
Azure.IoT Build 0:ef4901974abc 433 {
Azure.IoT Build 0:ef4901974abc 434 spaceLen += 2;
Azure.IoT Build 0:ef4901974abc 435 willTopicLen = strlen(mqttOptions->willTopic);
Azure.IoT Build 0:ef4901974abc 436 }
Azure.IoT Build 0:ef4901974abc 437
Azure.IoT Build 0:ef4901974abc 438 size_t currLen = BUFFER_length(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 439 size_t totalLen = clientLen + usernameLen + passwordLen + willMessageLen + willTopicLen + spaceLen;
Azure.IoT Build 0:ef4901974abc 440
Azure.IoT Build 0:ef4901974abc 441 // Validate the Username & Password
Azure.IoT Build 0:ef4901974abc 442 if (clientLen > USHRT_MAX)
Azure.IoT Build 0:ef4901974abc 443 {
AzureIoTClient 15:ec5a36121959 444 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 445 }
AzureIoTClient 5:34779607059c 446 else if (usernameLen == 0 && passwordLen > 0)
Azure.IoT Build 0:ef4901974abc 447 {
AzureIoTClient 15:ec5a36121959 448 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 449 }
AzureIoTClient 8:83bb166aba73 450 else if ((willMessageLen > 0 && willTopicLen == 0) || (willTopicLen > 0 && willMessageLen == 0))
Azure.IoT Build 0:ef4901974abc 451 {
AzureIoTClient 15:ec5a36121959 452 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 453 }
Azure.IoT Build 0:ef4901974abc 454 else if (BUFFER_enlarge(ctrlPacket, totalLen) != 0)
Azure.IoT Build 0:ef4901974abc 455 {
AzureIoTClient 15:ec5a36121959 456 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 457 }
Azure.IoT Build 0:ef4901974abc 458 else
Azure.IoT Build 0:ef4901974abc 459 {
Azure.IoT Build 0:ef4901974abc 460 uint8_t* packet = BUFFER_u_char(ctrlPacket);
Azure.IoT Build 0:ef4901974abc 461 uint8_t* iterator = packet;
Azure.IoT Build 0:ef4901974abc 462
Azure.IoT Build 0:ef4901974abc 463 iterator += currLen;
Azure.IoT Build 0:ef4901974abc 464 byteutil_writeUTF(&iterator, mqttOptions->clientId, (uint16_t)clientLen);
Azure.IoT Build 0:ef4901974abc 465
Azure.IoT Build 0:ef4901974abc 466 // TODO: Read on the Will Topic
Azure.IoT Build 0:ef4901974abc 467 if (willMessageLen > USHRT_MAX || willTopicLen > USHRT_MAX || usernameLen > USHRT_MAX || passwordLen > USHRT_MAX)
Azure.IoT Build 0:ef4901974abc 468 {
AzureIoTClient 15:ec5a36121959 469 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 470 }
Azure.IoT Build 0:ef4901974abc 471 else
Azure.IoT Build 0:ef4901974abc 472 {
AzureIoTClient 8:83bb166aba73 473 STRING_HANDLE connect_payload_trace = NULL;
AzureIoTClient 8:83bb166aba73 474 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 475 {
AzureIoTClient 8:83bb166aba73 476 connect_payload_trace = STRING_new();
AzureIoTClient 8:83bb166aba73 477 }
Azure.IoT Build 0:ef4901974abc 478 if (willMessageLen > 0 && willTopicLen > 0)
Azure.IoT Build 0:ef4901974abc 479 {
AzureIoTClient 8:83bb166aba73 480 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 481 {
AzureIoTClient 8:83bb166aba73 482 (void)STRING_sprintf(connect_payload_trace, " | WILL_TOPIC: %s", mqttOptions->willTopic);
AzureIoTClient 8:83bb166aba73 483 }
Azure.IoT Build 0:ef4901974abc 484 packet[CONN_FLAG_BYTE_OFFSET] |= WILL_FLAG_FLAG;
Azure.IoT Build 0:ef4901974abc 485 byteutil_writeUTF(&iterator, mqttOptions->willTopic, (uint16_t)willTopicLen);
AzureIoTClient 25:413b95a07625 486 packet[CONN_FLAG_BYTE_OFFSET] |= (mqttOptions->qualityOfServiceValue << 3);
Azure.IoT Build 0:ef4901974abc 487 if (mqttOptions->messageRetain)
Azure.IoT Build 0:ef4901974abc 488 {
Azure.IoT Build 0:ef4901974abc 489 packet[CONN_FLAG_BYTE_OFFSET] |= WILL_RETAIN_FLAG;
Azure.IoT Build 0:ef4901974abc 490 }
Azure.IoT Build 0:ef4901974abc 491 byteutil_writeUTF(&iterator, mqttOptions->willMessage, (uint16_t)willMessageLen);
Azure.IoT Build 0:ef4901974abc 492 }
Azure.IoT Build 0:ef4901974abc 493 if (usernameLen > 0)
Azure.IoT Build 0:ef4901974abc 494 {
AzureIoTClient 5:34779607059c 495 packet[CONN_FLAG_BYTE_OFFSET] |= USERNAME_FLAG;
Azure.IoT Build 0:ef4901974abc 496 byteutil_writeUTF(&iterator, mqttOptions->username, (uint16_t)usernameLen);
AzureIoTClient 8:83bb166aba73 497 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 498 {
AzureIoTClient 8:83bb166aba73 499 (void)STRING_sprintf(connect_payload_trace, " | USERNAME: %s", mqttOptions->username);
AzureIoTClient 8:83bb166aba73 500 }
AzureIoTClient 5:34779607059c 501 }
AzureIoTClient 5:34779607059c 502 if (passwordLen > 0)
AzureIoTClient 5:34779607059c 503 {
AzureIoTClient 5:34779607059c 504 packet[CONN_FLAG_BYTE_OFFSET] |= PASSWORD_FLAG;
Azure.IoT Build 0:ef4901974abc 505 byteutil_writeUTF(&iterator, mqttOptions->password, (uint16_t)passwordLen);
AzureIoTClient 8:83bb166aba73 506 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 507 {
AzureIoTClient 8:83bb166aba73 508 (void)STRING_sprintf(connect_payload_trace, " | PWD: XXXX");
AzureIoTClient 8:83bb166aba73 509 }
Azure.IoT Build 0:ef4901974abc 510 }
Azure.IoT Build 0:ef4901974abc 511 // TODO: Get the rest of the flags
AzureIoTClient 8:83bb166aba73 512 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 513 {
AzureIoTClient 8:83bb166aba73 514 (void)STRING_sprintf(connect_payload_trace, " | CLEAN: %s", mqttOptions->useCleanSession ? "1" : "0");
AzureIoTClient 8:83bb166aba73 515 }
Azure.IoT Build 0:ef4901974abc 516 if (mqttOptions->useCleanSession)
Azure.IoT Build 0:ef4901974abc 517 {
Azure.IoT Build 0:ef4901974abc 518 packet[CONN_FLAG_BYTE_OFFSET] |= CLEAN_SESSION_FLAG;
Azure.IoT Build 0:ef4901974abc 519 }
AzureIoTClient 8:83bb166aba73 520 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 521 {
AzureIoTClient 8:83bb166aba73 522 (void)STRING_sprintf(trace_log, " %zu", packet[CONN_FLAG_BYTE_OFFSET]);
AzureIoTClient 8:83bb166aba73 523 (void)STRING_concat_with_STRING(trace_log, connect_payload_trace);
AzureIoTClient 8:83bb166aba73 524 STRING_delete(connect_payload_trace);
AzureIoTClient 8:83bb166aba73 525 }
Azure.IoT Build 0:ef4901974abc 526 result = 0;
Azure.IoT Build 0:ef4901974abc 527 }
Azure.IoT Build 0:ef4901974abc 528 }
Azure.IoT Build 0:ef4901974abc 529 }
Azure.IoT Build 0:ef4901974abc 530 return result;
Azure.IoT Build 0:ef4901974abc 531 }
Azure.IoT Build 0:ef4901974abc 532
Azure.IoT Build 0:ef4901974abc 533 static int prepareheaderDataInfo(MQTTCODEC_INSTANCE* codecData, uint8_t remainLen)
Azure.IoT Build 0:ef4901974abc 534 {
Azure.IoT Build 0:ef4901974abc 535 int result;
Azure.IoT Build 0:ef4901974abc 536 if (codecData == NULL)
Azure.IoT Build 0:ef4901974abc 537 {
AzureIoTClient 15:ec5a36121959 538 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 539 }
Azure.IoT Build 0:ef4901974abc 540 else
Azure.IoT Build 0:ef4901974abc 541 {
Azure.IoT Build 0:ef4901974abc 542 result = 0;
Azure.IoT Build 0:ef4901974abc 543 codecData->storeRemainLen[codecData->remainLenIndex++] = remainLen;
AzureIoTClient 20:a8254fa69b6c 544 if (remainLen <= 0x7f)
Azure.IoT Build 0:ef4901974abc 545 {
Azure.IoT Build 0:ef4901974abc 546 int multiplier = 1;
Azure.IoT Build 0:ef4901974abc 547 int totalLen = 0;
Azure.IoT Build 0:ef4901974abc 548 size_t index = 0;
Azure.IoT Build 0:ef4901974abc 549 uint8_t encodeByte = 0;
Azure.IoT Build 0:ef4901974abc 550 do
Azure.IoT Build 0:ef4901974abc 551 {
Azure.IoT Build 0:ef4901974abc 552 encodeByte = codecData->storeRemainLen[index++];
Azure.IoT Build 0:ef4901974abc 553 totalLen += (encodeByte & 127) * multiplier;
Azure.IoT Build 0:ef4901974abc 554 multiplier *= NEXT_128_CHUNK;
Azure.IoT Build 0:ef4901974abc 555
Azure.IoT Build 0:ef4901974abc 556 if (multiplier > 128 * 128 * 128)
Azure.IoT Build 0:ef4901974abc 557 {
AzureIoTClient 15:ec5a36121959 558 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 559 break;
Azure.IoT Build 0:ef4901974abc 560 }
AzureIoTClient 8:83bb166aba73 561 } while ((encodeByte & NEXT_128_CHUNK) != 0);
Azure.IoT Build 0:ef4901974abc 562
Azure.IoT Build 0:ef4901974abc 563 codecData->codecState = CODEC_STATE_VAR_HEADER;
Azure.IoT Build 0:ef4901974abc 564
Azure.IoT Build 0:ef4901974abc 565 // Reset remainLen Index
Azure.IoT Build 0:ef4901974abc 566 codecData->remainLenIndex = 0;
Azure.IoT Build 0:ef4901974abc 567 memset(codecData->storeRemainLen, 0, 4 * sizeof(uint8_t));
AzureIoTClient 22:786a74c2d89b 568
AzureIoTClient 22:786a74c2d89b 569 if (totalLen > 0)
AzureIoTClient 22:786a74c2d89b 570 {
AzureIoTClient 22:786a74c2d89b 571 codecData->bufferOffset = 0;
AzureIoTClient 22:786a74c2d89b 572 codecData->headerData = BUFFER_new();
AzureIoTClient 22:786a74c2d89b 573 if (codecData->headerData == NULL)
AzureIoTClient 22:786a74c2d89b 574 {
AzureIoTClient 22:786a74c2d89b 575 /* Codes_SRS_MQTT_CODEC_07_035: [ If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value. ] */
AzureIoTClient 22:786a74c2d89b 576 LogError("Failed BUFFER_new");
AzureIoTClient 22:786a74c2d89b 577 result = __FAILURE__;
AzureIoTClient 22:786a74c2d89b 578 }
AzureIoTClient 22:786a74c2d89b 579 else
AzureIoTClient 22:786a74c2d89b 580 {
AzureIoTClient 22:786a74c2d89b 581 if (BUFFER_pre_build(codecData->headerData, totalLen) != 0)
AzureIoTClient 22:786a74c2d89b 582 {
AzureIoTClient 22:786a74c2d89b 583 /* Codes_SRS_MQTT_CODEC_07_035: [ If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value. ] */
AzureIoTClient 22:786a74c2d89b 584 LogError("Failed BUFFER_pre_build");
AzureIoTClient 22:786a74c2d89b 585 result = __FAILURE__;
AzureIoTClient 22:786a74c2d89b 586 }
AzureIoTClient 22:786a74c2d89b 587
AzureIoTClient 22:786a74c2d89b 588 }
AzureIoTClient 22:786a74c2d89b 589 }
Azure.IoT Build 0:ef4901974abc 590 }
Azure.IoT Build 0:ef4901974abc 591 }
Azure.IoT Build 0:ef4901974abc 592 return result;
Azure.IoT Build 0:ef4901974abc 593 }
Azure.IoT Build 0:ef4901974abc 594
Azure.IoT Build 0:ef4901974abc 595 static void completePacketData(MQTTCODEC_INSTANCE* codecData)
Azure.IoT Build 0:ef4901974abc 596 {
Azure.IoT Build 0:ef4901974abc 597 if (codecData)
Azure.IoT Build 0:ef4901974abc 598 {
Azure.IoT Build 0:ef4901974abc 599 if (codecData->packetComplete != NULL)
Azure.IoT Build 0:ef4901974abc 600 {
Azure.IoT Build 0:ef4901974abc 601 codecData->packetComplete(codecData->callContext, codecData->currPacket, codecData->headerFlags, codecData->headerData);
Azure.IoT Build 0:ef4901974abc 602 }
Azure.IoT Build 0:ef4901974abc 603
Azure.IoT Build 0:ef4901974abc 604 // Clean up data
Azure.IoT Build 0:ef4901974abc 605 codecData->currPacket = UNKNOWN_TYPE;
Azure.IoT Build 0:ef4901974abc 606 codecData->codecState = CODEC_STATE_FIXED_HEADER;
Azure.IoT Build 0:ef4901974abc 607 codecData->headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 608 BUFFER_delete(codecData->headerData);
Azure.IoT Build 0:ef4901974abc 609 codecData->headerData = NULL;
Azure.IoT Build 0:ef4901974abc 610 }
Azure.IoT Build 0:ef4901974abc 611 }
Azure.IoT Build 0:ef4901974abc 612
Azure.IoT Build 0:ef4901974abc 613 MQTTCODEC_HANDLE mqtt_codec_create(ON_PACKET_COMPLETE_CALLBACK packetComplete, void* callbackCtx)
Azure.IoT Build 0:ef4901974abc 614 {
Azure.IoT Build 0:ef4901974abc 615 MQTTCODEC_HANDLE result;
AzureIoTClient 8:83bb166aba73 616 result = malloc(sizeof(MQTTCODEC_INSTANCE));
Azure.IoT Build 0:ef4901974abc 617 /* Codes_SRS_MQTT_CODEC_07_001: [If a failure is encountered then mqtt_codec_create shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 618 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 619 {
Azure.IoT Build 0:ef4901974abc 620 /* Codes_SRS_MQTT_CODEC_07_002: [On success mqtt_codec_create shall return a MQTTCODEC_HANDLE value.] */
Azure.IoT Build 0:ef4901974abc 621 result->currPacket = UNKNOWN_TYPE;
Azure.IoT Build 0:ef4901974abc 622 result->codecState = CODEC_STATE_FIXED_HEADER;
Azure.IoT Build 0:ef4901974abc 623 result->headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 624 result->bufferOffset = 0;
Azure.IoT Build 0:ef4901974abc 625 result->packetComplete = packetComplete;
Azure.IoT Build 0:ef4901974abc 626 result->callContext = callbackCtx;
Azure.IoT Build 0:ef4901974abc 627 result->headerData = NULL;
Azure.IoT Build 0:ef4901974abc 628 memset(result->storeRemainLen, 0, 4 * sizeof(uint8_t));
Azure.IoT Build 0:ef4901974abc 629 result->remainLenIndex = 0;
Azure.IoT Build 0:ef4901974abc 630 }
Azure.IoT Build 0:ef4901974abc 631 return result;
Azure.IoT Build 0:ef4901974abc 632 }
Azure.IoT Build 0:ef4901974abc 633
Azure.IoT Build 0:ef4901974abc 634 void mqtt_codec_destroy(MQTTCODEC_HANDLE handle)
Azure.IoT Build 0:ef4901974abc 635 {
Azure.IoT Build 0:ef4901974abc 636 /* Codes_SRS_MQTT_CODEC_07_003: [If the handle parameter is NULL then mqtt_codec_destroy shall do nothing.] */
Azure.IoT Build 0:ef4901974abc 637 if (handle != NULL)
Azure.IoT Build 0:ef4901974abc 638 {
Azure.IoT Build 0:ef4901974abc 639 MQTTCODEC_INSTANCE* codecData = (MQTTCODEC_INSTANCE*)handle;
Azure.IoT Build 0:ef4901974abc 640 /* Codes_SRS_MQTT_CODEC_07_004: [mqtt_codec_destroy shall deallocate all memory that has been allocated by this object.] */
Azure.IoT Build 0:ef4901974abc 641 BUFFER_delete(codecData->headerData);
Azure.IoT Build 0:ef4901974abc 642 free(codecData);
Azure.IoT Build 0:ef4901974abc 643 }
Azure.IoT Build 0:ef4901974abc 644 }
Azure.IoT Build 0:ef4901974abc 645
AzureIoTClient 8:83bb166aba73 646 BUFFER_HANDLE mqtt_codec_connect(const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 647 {
Azure.IoT Build 0:ef4901974abc 648 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 649 /* Codes_SRS_MQTT_CODEC_07_008: [If the parameters mqttOptions is NULL then mqtt_codec_connect shall return a null value.] */
Azure.IoT Build 0:ef4901974abc 650 if (mqttOptions == NULL)
Azure.IoT Build 0:ef4901974abc 651 {
Azure.IoT Build 0:ef4901974abc 652 result = NULL;
Azure.IoT Build 0:ef4901974abc 653 }
Azure.IoT Build 0:ef4901974abc 654 else
Azure.IoT Build 0:ef4901974abc 655 {
Azure.IoT Build 0:ef4901974abc 656 /* Codes_SRS_MQTT_CODEC_07_009: [mqtt_codec_connect shall construct a BUFFER_HANDLE that represents a MQTT CONNECT packet.] */
Azure.IoT Build 0:ef4901974abc 657 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 658 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 659 {
AzureIoTClient 8:83bb166aba73 660 STRING_HANDLE varible_header_log = NULL;
AzureIoTClient 8:83bb166aba73 661 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 662 {
AzureIoTClient 8:83bb166aba73 663 varible_header_log = STRING_new();
AzureIoTClient 8:83bb166aba73 664 }
Azure.IoT Build 0:ef4901974abc 665 // Add Variable Header Information
AzureIoTClient 8:83bb166aba73 666 if (constructConnectVariableHeader(result, mqttOptions, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 667 {
Azure.IoT Build 0:ef4901974abc 668 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 669 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 670 result = NULL;
Azure.IoT Build 0:ef4901974abc 671 }
Azure.IoT Build 0:ef4901974abc 672 else
Azure.IoT Build 0:ef4901974abc 673 {
AzureIoTClient 8:83bb166aba73 674 if (constructConnPayload(result, mqttOptions, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 675 {
Azure.IoT Build 0:ef4901974abc 676 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 677 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 678 result = NULL;
Azure.IoT Build 0:ef4901974abc 679 }
Azure.IoT Build 0:ef4901974abc 680 else
Azure.IoT Build 0:ef4901974abc 681 {
AzureIoTClient 8:83bb166aba73 682 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 683 {
AzureIoTClient 8:83bb166aba73 684 (void)STRING_copy(trace_log, "CONNECT");
AzureIoTClient 8:83bb166aba73 685 }
Azure.IoT Build 0:ef4901974abc 686 if (constructFixedHeader(result, CONNECT_TYPE, 0) != 0)
Azure.IoT Build 0:ef4901974abc 687 {
Azure.IoT Build 0:ef4901974abc 688 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 689 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 690 result = NULL;
Azure.IoT Build 0:ef4901974abc 691 }
AzureIoTClient 8:83bb166aba73 692 else
AzureIoTClient 8:83bb166aba73 693 {
AzureIoTClient 8:83bb166aba73 694 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 695 {
AzureIoTClient 8:83bb166aba73 696 (void)STRING_concat_with_STRING(trace_log, varible_header_log);
AzureIoTClient 8:83bb166aba73 697 }
AzureIoTClient 8:83bb166aba73 698 }
AzureIoTClient 8:83bb166aba73 699 }
AzureIoTClient 8:83bb166aba73 700 if (varible_header_log != NULL)
AzureIoTClient 8:83bb166aba73 701 {
AzureIoTClient 8:83bb166aba73 702 STRING_delete(varible_header_log);
Azure.IoT Build 0:ef4901974abc 703 }
Azure.IoT Build 0:ef4901974abc 704 }
Azure.IoT Build 0:ef4901974abc 705 }
Azure.IoT Build 0:ef4901974abc 706 }
Azure.IoT Build 0:ef4901974abc 707 return result;
Azure.IoT Build 0:ef4901974abc 708 }
Azure.IoT Build 0:ef4901974abc 709
Azure.IoT Build 0:ef4901974abc 710 BUFFER_HANDLE mqtt_codec_disconnect()
Azure.IoT Build 0:ef4901974abc 711 {
Azure.IoT Build 0:ef4901974abc 712 /* Codes_SRS_MQTT_CODEC_07_011: [On success mqtt_codec_disconnect shall construct a BUFFER_HANDLE that represents a MQTT DISCONNECT packet.] */
Azure.IoT Build 0:ef4901974abc 713 BUFFER_HANDLE result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 714 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 715 {
Azure.IoT Build 0:ef4901974abc 716 if (BUFFER_enlarge(result, 2) != 0)
Azure.IoT Build 0:ef4901974abc 717 {
Azure.IoT Build 0:ef4901974abc 718 /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 719 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 720 result = NULL;
Azure.IoT Build 0:ef4901974abc 721 }
Azure.IoT Build 0:ef4901974abc 722 else
Azure.IoT Build 0:ef4901974abc 723 {
Azure.IoT Build 0:ef4901974abc 724 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 725 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 726 {
Azure.IoT Build 0:ef4901974abc 727 /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 728 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 729 result = NULL;
Azure.IoT Build 0:ef4901974abc 730 }
Azure.IoT Build 0:ef4901974abc 731 else
Azure.IoT Build 0:ef4901974abc 732 {
Azure.IoT Build 0:ef4901974abc 733 iterator[0] = DISCONNECT_TYPE;
Azure.IoT Build 0:ef4901974abc 734 iterator[1] = 0;
Azure.IoT Build 0:ef4901974abc 735 }
Azure.IoT Build 0:ef4901974abc 736 }
Azure.IoT Build 0:ef4901974abc 737 }
Azure.IoT Build 0:ef4901974abc 738 return result;
Azure.IoT Build 0:ef4901974abc 739 }
Azure.IoT Build 0:ef4901974abc 740
AzureIoTClient 8:83bb166aba73 741 BUFFER_HANDLE mqtt_codec_publish(QOS_VALUE qosValue, bool duplicateMsg, bool serverRetain, uint16_t packetId, const char* topicName, const uint8_t* msgBuffer, size_t buffLen, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 742 {
Azure.IoT Build 0:ef4901974abc 743 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 744 /* Codes_SRS_MQTT_CODEC_07_005: [If the parameters topicName is NULL then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 745 if (topicName == NULL)
Azure.IoT Build 0:ef4901974abc 746 {
Azure.IoT Build 0:ef4901974abc 747 result = NULL;
Azure.IoT Build 0:ef4901974abc 748 }
Azure.IoT Build 0:ef4901974abc 749 /* Codes_SRS_MQTT_CODEC_07_036: [mqtt_codec_publish shall return NULL if the buffLen variable is greater than the MAX_SEND_SIZE (0xFFFFFF7F).] */
Azure.IoT Build 0:ef4901974abc 750 else if (buffLen > MAX_SEND_SIZE)
Azure.IoT Build 0:ef4901974abc 751 {
Azure.IoT Build 0:ef4901974abc 752 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 753 result = NULL;
Azure.IoT Build 0:ef4901974abc 754 }
Azure.IoT Build 0:ef4901974abc 755 else
Azure.IoT Build 0:ef4901974abc 756 {
AzureIoTClient 8:83bb166aba73 757 PUBLISH_HEADER_INFO publishInfo ={ 0 };
Azure.IoT Build 0:ef4901974abc 758 publishInfo.topicName = topicName;
Azure.IoT Build 0:ef4901974abc 759 publishInfo.packetId = packetId;
Azure.IoT Build 0:ef4901974abc 760 publishInfo.qualityOfServiceValue = qosValue;
Azure.IoT Build 0:ef4901974abc 761
Azure.IoT Build 0:ef4901974abc 762 uint8_t headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 763 if (duplicateMsg) headerFlags |= PUBLISH_DUP_FLAG;
Azure.IoT Build 0:ef4901974abc 764 if (serverRetain) headerFlags |= PUBLISH_QOS_RETAIN;
Azure.IoT Build 0:ef4901974abc 765 if (qosValue != DELIVER_AT_MOST_ONCE)
Azure.IoT Build 0:ef4901974abc 766 {
Azure.IoT Build 0:ef4901974abc 767 if (qosValue == DELIVER_AT_LEAST_ONCE)
Azure.IoT Build 0:ef4901974abc 768 {
Azure.IoT Build 0:ef4901974abc 769 headerFlags |= PUBLISH_QOS_AT_LEAST_ONCE;
Azure.IoT Build 0:ef4901974abc 770 }
Azure.IoT Build 0:ef4901974abc 771 else
Azure.IoT Build 0:ef4901974abc 772 {
Azure.IoT Build 0:ef4901974abc 773 headerFlags |= PUBLISH_QOS_EXACTLY_ONCE;
Azure.IoT Build 0:ef4901974abc 774 }
Azure.IoT Build 0:ef4901974abc 775 }
Azure.IoT Build 0:ef4901974abc 776
Azure.IoT Build 0:ef4901974abc 777 /* Codes_SRS_MQTT_CODEC_07_007: [mqtt_codec_publish shall return a BUFFER_HANDLE that represents a MQTT PUBLISH message.] */
Azure.IoT Build 0:ef4901974abc 778 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 779 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 780 {
AzureIoTClient 8:83bb166aba73 781 STRING_HANDLE varible_header_log = NULL;
AzureIoTClient 8:83bb166aba73 782 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 783 {
AzureIoTClient 8:83bb166aba73 784 varible_header_log = STRING_construct_sprintf(" | IS_DUP: %s | RETAIN: %d | QOS: %s", duplicateMsg ? TRUE_CONST : FALSE_CONST,
AzureIoTClient 8:83bb166aba73 785 serverRetain ? 1 : 0,
AzureIoTClient 8:83bb166aba73 786 retrieve_qos_value(publishInfo.qualityOfServiceValue) );
AzureIoTClient 8:83bb166aba73 787 }
AzureIoTClient 8:83bb166aba73 788
AzureIoTClient 8:83bb166aba73 789 if (constructPublishVariableHeader(result, &publishInfo, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 790 {
Azure.IoT Build 0:ef4901974abc 791 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 792 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 793 result = NULL;
Azure.IoT Build 0:ef4901974abc 794 }
Azure.IoT Build 0:ef4901974abc 795 else
Azure.IoT Build 0:ef4901974abc 796 {
Azure.IoT Build 0:ef4901974abc 797 size_t payloadOffset = BUFFER_length(result);
Azure.IoT Build 0:ef4901974abc 798 if (buffLen > 0)
Azure.IoT Build 0:ef4901974abc 799 {
Azure.IoT Build 0:ef4901974abc 800 if (BUFFER_enlarge(result, buffLen) != 0)
Azure.IoT Build 0:ef4901974abc 801 {
Azure.IoT Build 0:ef4901974abc 802 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 803 BUFFER_delete(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 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 809 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 810 {
Azure.IoT Build 0:ef4901974abc 811 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 812 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 813 result = NULL;
Azure.IoT Build 0:ef4901974abc 814 }
Azure.IoT Build 0:ef4901974abc 815 else
Azure.IoT Build 0:ef4901974abc 816 {
Azure.IoT Build 0:ef4901974abc 817 iterator += payloadOffset;
Azure.IoT Build 0:ef4901974abc 818 // Write Message
AzureIoTClient 13:3c202001e4ba 819 (void)memcpy(iterator, msgBuffer, buffLen);
AzureIoTClient 8:83bb166aba73 820 if (trace_log)
AzureIoTClient 8:83bb166aba73 821 {
AzureIoTClient 8:83bb166aba73 822 STRING_sprintf(varible_header_log, " | PAYLOAD_LEN: %zu", buffLen);
AzureIoTClient 8:83bb166aba73 823 }
Azure.IoT Build 0:ef4901974abc 824 }
Azure.IoT Build 0:ef4901974abc 825 }
Azure.IoT Build 0:ef4901974abc 826 }
Azure.IoT Build 0:ef4901974abc 827
Azure.IoT Build 0:ef4901974abc 828 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 829 {
AzureIoTClient 8:83bb166aba73 830 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 831 {
AzureIoTClient 8:83bb166aba73 832 (void)STRING_copy(trace_log, "PUBLISH");
AzureIoTClient 8:83bb166aba73 833 }
Azure.IoT Build 0:ef4901974abc 834 if (constructFixedHeader(result, PUBLISH_TYPE, headerFlags) != 0)
Azure.IoT Build 0:ef4901974abc 835 {
Azure.IoT Build 0:ef4901974abc 836 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 837 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 838 result = NULL;
Azure.IoT Build 0:ef4901974abc 839 }
AzureIoTClient 8:83bb166aba73 840 else
AzureIoTClient 8:83bb166aba73 841 {
AzureIoTClient 8:83bb166aba73 842 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 843 {
AzureIoTClient 8:83bb166aba73 844 (void)STRING_concat_with_STRING(trace_log, varible_header_log);
AzureIoTClient 8:83bb166aba73 845 }
AzureIoTClient 8:83bb166aba73 846 }
Azure.IoT Build 0:ef4901974abc 847 }
Azure.IoT Build 0:ef4901974abc 848 }
AzureIoTClient 8:83bb166aba73 849 if (varible_header_log != NULL)
AzureIoTClient 8:83bb166aba73 850 {
AzureIoTClient 8:83bb166aba73 851 STRING_delete(varible_header_log);
AzureIoTClient 8:83bb166aba73 852 }
Azure.IoT Build 0:ef4901974abc 853 }
Azure.IoT Build 0:ef4901974abc 854 }
Azure.IoT Build 0:ef4901974abc 855 return result;
Azure.IoT Build 0:ef4901974abc 856 }
Azure.IoT Build 0:ef4901974abc 857
Azure.IoT Build 0:ef4901974abc 858 BUFFER_HANDLE mqtt_codec_publishAck(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 859 {
Azure.IoT Build 0:ef4901974abc 860 /* Codes_SRS_MQTT_CODEC_07_013: [On success mqtt_codec_publishAck shall return a BUFFER_HANDLE representation of a MQTT PUBACK packet.] */
Azure.IoT Build 0:ef4901974abc 861 /* Codes_SRS_MQTT_CODEC_07_014 : [If any error is encountered then mqtt_codec_publishAck shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 862 BUFFER_HANDLE result = constructPublishReply(PUBACK_TYPE, 0, packetId);
Azure.IoT Build 0:ef4901974abc 863 return result;
Azure.IoT Build 0:ef4901974abc 864 }
Azure.IoT Build 0:ef4901974abc 865
Azure.IoT Build 0:ef4901974abc 866 BUFFER_HANDLE mqtt_codec_publishReceived(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 867 {
Azure.IoT Build 0:ef4901974abc 868 /* Codes_SRS_MQTT_CODEC_07_015: [On success mqtt_codec_publishRecieved shall return a BUFFER_HANDLE representation of a MQTT PUBREC packet.] */
Azure.IoT Build 0:ef4901974abc 869 /* Codes_SRS_MQTT_CODEC_07_016 : [If any error is encountered then mqtt_codec_publishRecieved shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 870 BUFFER_HANDLE result = constructPublishReply(PUBREC_TYPE, 0, packetId);
Azure.IoT Build 0:ef4901974abc 871 return result;
Azure.IoT Build 0:ef4901974abc 872 }
Azure.IoT Build 0:ef4901974abc 873
Azure.IoT Build 0:ef4901974abc 874 BUFFER_HANDLE mqtt_codec_publishRelease(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 875 {
Azure.IoT Build 0:ef4901974abc 876 /* Codes_SRS_MQTT_CODEC_07_017: [On success mqtt_codec_publishRelease shall return a BUFFER_HANDLE representation of a MQTT PUBREL packet.] */
Azure.IoT Build 0:ef4901974abc 877 /* Codes_SRS_MQTT_CODEC_07_018 : [If any error is encountered then mqtt_codec_publishRelease shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 878 BUFFER_HANDLE result = constructPublishReply(PUBREL_TYPE, 2, packetId);
Azure.IoT Build 0:ef4901974abc 879 return result;
Azure.IoT Build 0:ef4901974abc 880 }
Azure.IoT Build 0:ef4901974abc 881
Azure.IoT Build 0:ef4901974abc 882 BUFFER_HANDLE mqtt_codec_publishComplete(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 883 {
Azure.IoT Build 0:ef4901974abc 884 /* Codes_SRS_MQTT_CODEC_07_019: [On success mqtt_codec_publishComplete shall return a BUFFER_HANDLE representation of a MQTT PUBCOMP packet.] */
Azure.IoT Build 0:ef4901974abc 885 /* Codes_SRS_MQTT_CODEC_07_020 : [If any error is encountered then mqtt_codec_publishComplete shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 886 BUFFER_HANDLE result = constructPublishReply(PUBCOMP_TYPE, 0, packetId);
Azure.IoT Build 0:ef4901974abc 887 return result;
Azure.IoT Build 0:ef4901974abc 888 }
Azure.IoT Build 0:ef4901974abc 889
Azure.IoT Build 0:ef4901974abc 890 BUFFER_HANDLE mqtt_codec_ping()
Azure.IoT Build 0:ef4901974abc 891 {
Azure.IoT Build 0:ef4901974abc 892 /* Codes_SRS_MQTT_CODEC_07_021: [On success mqtt_codec_ping shall construct a BUFFER_HANDLE that represents a MQTT PINGREQ packet.] */
Azure.IoT Build 0:ef4901974abc 893 BUFFER_HANDLE result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 894 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 895 {
Azure.IoT Build 0:ef4901974abc 896 if (BUFFER_enlarge(result, 2) != 0)
Azure.IoT Build 0:ef4901974abc 897 {
Azure.IoT Build 0:ef4901974abc 898 /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 899 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 900 result = NULL;
Azure.IoT Build 0:ef4901974abc 901 }
Azure.IoT Build 0:ef4901974abc 902 else
Azure.IoT Build 0:ef4901974abc 903 {
Azure.IoT Build 0:ef4901974abc 904 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 905 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 906 {
Azure.IoT Build 0:ef4901974abc 907 /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 908 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 909 result = NULL;
Azure.IoT Build 0:ef4901974abc 910 }
Azure.IoT Build 0:ef4901974abc 911 else
Azure.IoT Build 0:ef4901974abc 912 {
Azure.IoT Build 0:ef4901974abc 913 iterator[0] = PINGREQ_TYPE;
Azure.IoT Build 0:ef4901974abc 914 iterator[1] = 0;
Azure.IoT Build 0:ef4901974abc 915 }
Azure.IoT Build 0:ef4901974abc 916 }
Azure.IoT Build 0:ef4901974abc 917 }
Azure.IoT Build 0:ef4901974abc 918 return result;
Azure.IoT Build 0:ef4901974abc 919 }
Azure.IoT Build 0:ef4901974abc 920
AzureIoTClient 8:83bb166aba73 921 BUFFER_HANDLE mqtt_codec_subscribe(uint16_t packetId, SUBSCRIBE_PAYLOAD* subscribeList, size_t count, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 922 {
Azure.IoT Build 0:ef4901974abc 923 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 924 /* Codes_SRS_MQTT_CODEC_07_023: [If the parameters subscribeList is NULL or if count is 0 then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 925 if (subscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 926 {
Azure.IoT Build 0:ef4901974abc 927 result = NULL;
Azure.IoT Build 0:ef4901974abc 928 }
Azure.IoT Build 0:ef4901974abc 929 else
Azure.IoT Build 0:ef4901974abc 930 {
Azure.IoT Build 0:ef4901974abc 931 /* Codes_SRS_MQTT_CODEC_07_026: [mqtt_codec_subscribe shall return a BUFFER_HANDLE that represents a MQTT SUBSCRIBE message.]*/
Azure.IoT Build 0:ef4901974abc 932 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 933 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 934 {
Azure.IoT Build 0:ef4901974abc 935 if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
Azure.IoT Build 0:ef4901974abc 936 {
Azure.IoT Build 0:ef4901974abc 937 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 938 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 939 result = NULL;
Azure.IoT Build 0:ef4901974abc 940 }
Azure.IoT Build 0:ef4901974abc 941 else
Azure.IoT Build 0:ef4901974abc 942 {
AzureIoTClient 8:83bb166aba73 943 STRING_HANDLE sub_trace = NULL;
AzureIoTClient 8:83bb166aba73 944 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 945 {
AzureIoTClient 8:83bb166aba73 946 sub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
AzureIoTClient 8:83bb166aba73 947 }
Azure.IoT Build 0:ef4901974abc 948 /* Codes_SRS_MQTT_CODEC_07_024: [mqtt_codec_subscribe shall iterate through count items in the subscribeList.] */
AzureIoTClient 8:83bb166aba73 949 if (addListItemsToSubscribePacket(result, subscribeList, count, sub_trace) != 0)
Azure.IoT Build 0:ef4901974abc 950 {
Azure.IoT Build 0:ef4901974abc 951 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 952 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 953 result = NULL;
Azure.IoT Build 0:ef4901974abc 954 }
Azure.IoT Build 0:ef4901974abc 955 else
Azure.IoT Build 0:ef4901974abc 956 {
AzureIoTClient 8:83bb166aba73 957
AzureIoTClient 8:83bb166aba73 958 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 959 {
AzureIoTClient 8:83bb166aba73 960 STRING_concat(trace_log, "SUBSCRIBE");
AzureIoTClient 8:83bb166aba73 961 }
Azure.IoT Build 0:ef4901974abc 962 if (constructFixedHeader(result, SUBSCRIBE_TYPE, SUBSCRIBE_FIXED_HEADER_FLAG) != 0)
Azure.IoT Build 0:ef4901974abc 963 {
Azure.IoT Build 0:ef4901974abc 964 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 965 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 966 result = NULL;
Azure.IoT Build 0:ef4901974abc 967 }
AzureIoTClient 8:83bb166aba73 968 else
AzureIoTClient 8:83bb166aba73 969 {
AzureIoTClient 8:83bb166aba73 970 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 971 {
AzureIoTClient 8:83bb166aba73 972 (void)STRING_concat_with_STRING(trace_log, sub_trace);
AzureIoTClient 8:83bb166aba73 973 }
AzureIoTClient 8:83bb166aba73 974 }
AzureIoTClient 8:83bb166aba73 975 }
AzureIoTClient 8:83bb166aba73 976 if (sub_trace != NULL)
AzureIoTClient 8:83bb166aba73 977 {
AzureIoTClient 8:83bb166aba73 978 STRING_delete(sub_trace);
Azure.IoT Build 0:ef4901974abc 979 }
Azure.IoT Build 0:ef4901974abc 980 }
Azure.IoT Build 0:ef4901974abc 981 }
Azure.IoT Build 0:ef4901974abc 982 }
Azure.IoT Build 0:ef4901974abc 983 return result;
Azure.IoT Build 0:ef4901974abc 984 }
Azure.IoT Build 0:ef4901974abc 985
AzureIoTClient 8:83bb166aba73 986 BUFFER_HANDLE mqtt_codec_unsubscribe(uint16_t packetId, const char** unsubscribeList, size_t count, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 987 {
Azure.IoT Build 0:ef4901974abc 988 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 989 /* Codes_SRS_MQTT_CODEC_07_027: [If the parameters unsubscribeList is NULL or if count is 0 then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 990 if (unsubscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 991 {
Azure.IoT Build 0:ef4901974abc 992 result = NULL;
Azure.IoT Build 0:ef4901974abc 993 }
Azure.IoT Build 0:ef4901974abc 994 else
Azure.IoT Build 0:ef4901974abc 995 {
Azure.IoT Build 0:ef4901974abc 996 /* Codes_SRS_MQTT_CODEC_07_030: [mqtt_codec_unsubscribe shall return a BUFFER_HANDLE that represents a MQTT SUBSCRIBE message.] */
Azure.IoT Build 0:ef4901974abc 997 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 998 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 999 {
Azure.IoT Build 0:ef4901974abc 1000 if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
Azure.IoT Build 0:ef4901974abc 1001 {
Azure.IoT Build 0:ef4901974abc 1002 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 1003 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 1004 result = NULL;
Azure.IoT Build 0:ef4901974abc 1005 }
Azure.IoT Build 0:ef4901974abc 1006 else
Azure.IoT Build 0:ef4901974abc 1007 {
AzureIoTClient 8:83bb166aba73 1008 STRING_HANDLE unsub_trace = NULL;
AzureIoTClient 8:83bb166aba73 1009 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1010 {
AzureIoTClient 8:83bb166aba73 1011 unsub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
AzureIoTClient 8:83bb166aba73 1012 }
Azure.IoT Build 0:ef4901974abc 1013 /* Codes_SRS_MQTT_CODEC_07_028: [mqtt_codec_unsubscribe shall iterate through count items in the unsubscribeList.] */
AzureIoTClient 8:83bb166aba73 1014 if (addListItemsToUnsubscribePacket(result, unsubscribeList, count, unsub_trace) != 0)
Azure.IoT Build 0:ef4901974abc 1015 {
Azure.IoT Build 0:ef4901974abc 1016 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 1017 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 1018 result = NULL;
Azure.IoT Build 0:ef4901974abc 1019 }
Azure.IoT Build 0:ef4901974abc 1020 else
Azure.IoT Build 0:ef4901974abc 1021 {
AzureIoTClient 8:83bb166aba73 1022 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1023 {
AzureIoTClient 8:83bb166aba73 1024 (void)STRING_copy(trace_log, "UNSUBSCRIBE");
AzureIoTClient 8:83bb166aba73 1025 }
Azure.IoT Build 0:ef4901974abc 1026 if (constructFixedHeader(result, UNSUBSCRIBE_TYPE, UNSUBSCRIBE_FIXED_HEADER_FLAG) != 0)
Azure.IoT Build 0:ef4901974abc 1027 {
Azure.IoT Build 0:ef4901974abc 1028 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 1029 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 1030 result = NULL;
Azure.IoT Build 0:ef4901974abc 1031 }
AzureIoTClient 8:83bb166aba73 1032 else
AzureIoTClient 8:83bb166aba73 1033 {
AzureIoTClient 8:83bb166aba73 1034 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1035 {
AzureIoTClient 8:83bb166aba73 1036 (void)STRING_concat_with_STRING(trace_log, unsub_trace);
AzureIoTClient 8:83bb166aba73 1037 }
AzureIoTClient 8:83bb166aba73 1038 }
AzureIoTClient 8:83bb166aba73 1039 }
AzureIoTClient 8:83bb166aba73 1040 if (unsub_trace != NULL)
AzureIoTClient 8:83bb166aba73 1041 {
AzureIoTClient 8:83bb166aba73 1042 STRING_delete(unsub_trace);
Azure.IoT Build 0:ef4901974abc 1043 }
Azure.IoT Build 0:ef4901974abc 1044 }
Azure.IoT Build 0:ef4901974abc 1045 }
Azure.IoT Build 0:ef4901974abc 1046 }
Azure.IoT Build 0:ef4901974abc 1047 return result;
Azure.IoT Build 0:ef4901974abc 1048 }
Azure.IoT Build 0:ef4901974abc 1049
Azure.IoT Build 0:ef4901974abc 1050 int mqtt_codec_bytesReceived(MQTTCODEC_HANDLE handle, const unsigned char* buffer, size_t size)
Azure.IoT Build 0:ef4901974abc 1051 {
Azure.IoT Build 0:ef4901974abc 1052 int result;
Azure.IoT Build 0:ef4901974abc 1053 MQTTCODEC_INSTANCE* codec_Data = (MQTTCODEC_INSTANCE*)handle;
Azure.IoT Build 0:ef4901974abc 1054 /* Codes_SRS_MQTT_CODEC_07_031: [If the parameters handle or buffer is NULL then mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1055 if (codec_Data == NULL)
Azure.IoT Build 0:ef4901974abc 1056 {
AzureIoTClient 15:ec5a36121959 1057 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1058 }
Azure.IoT Build 0:ef4901974abc 1059 /* Codes_SRS_MQTT_CODEC_07_031: [If the parameters handle or buffer is NULL then mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1060 /* Codes_SRS_MQTT_CODEC_07_032: [If the parameters size is zero then mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1061 else if (buffer == NULL || size == 0)
Azure.IoT Build 0:ef4901974abc 1062 {
Azure.IoT Build 0:ef4901974abc 1063 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1064 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1065 }
Azure.IoT Build 0:ef4901974abc 1066 else
Azure.IoT Build 0:ef4901974abc 1067 {
Azure.IoT Build 0:ef4901974abc 1068 /* Codes_SRS_MQTT_CODEC_07_033: [mqtt_codec_bytesReceived constructs a sequence of bytes into the corresponding MQTT packets and on success returns zero.] */
Azure.IoT Build 0:ef4901974abc 1069 result = 0;
AzureIoTClient 12:30b08cda82fd 1070 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 1071 for (index = 0; index < size && result == 0; index++)
Azure.IoT Build 0:ef4901974abc 1072 {
Azure.IoT Build 0:ef4901974abc 1073 uint8_t iterator = ((int8_t*)buffer)[index];
Azure.IoT Build 0:ef4901974abc 1074 if (codec_Data->codecState == CODEC_STATE_FIXED_HEADER)
Azure.IoT Build 0:ef4901974abc 1075 {
Azure.IoT Build 0:ef4901974abc 1076 if (codec_Data->currPacket == UNKNOWN_TYPE)
Azure.IoT Build 0:ef4901974abc 1077 {
Azure.IoT Build 0:ef4901974abc 1078 codec_Data->currPacket = processControlPacketType(iterator, &codec_Data->headerFlags);
Azure.IoT Build 0:ef4901974abc 1079 }
Azure.IoT Build 0:ef4901974abc 1080 else
Azure.IoT Build 0:ef4901974abc 1081 {
Azure.IoT Build 0:ef4901974abc 1082 if (prepareheaderDataInfo(codec_Data, iterator) != 0)
Azure.IoT Build 0:ef4901974abc 1083 {
Azure.IoT Build 0:ef4901974abc 1084 /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1085 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1086 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1087 }
Azure.IoT Build 0:ef4901974abc 1088 if (codec_Data->currPacket == PINGRESP_TYPE)
Azure.IoT Build 0:ef4901974abc 1089 {
Azure.IoT Build 0:ef4901974abc 1090 /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */
Azure.IoT Build 0:ef4901974abc 1091 completePacketData(codec_Data);
Azure.IoT Build 0:ef4901974abc 1092 }
Azure.IoT Build 0:ef4901974abc 1093 }
Azure.IoT Build 0:ef4901974abc 1094 }
Azure.IoT Build 0:ef4901974abc 1095 else if (codec_Data->codecState == CODEC_STATE_VAR_HEADER)
Azure.IoT Build 0:ef4901974abc 1096 {
Azure.IoT Build 0:ef4901974abc 1097 if (codec_Data->headerData == NULL)
Azure.IoT Build 0:ef4901974abc 1098 {
Azure.IoT Build 0:ef4901974abc 1099 codec_Data->codecState = CODEC_STATE_PAYLOAD;
Azure.IoT Build 0:ef4901974abc 1100 }
Azure.IoT Build 0:ef4901974abc 1101 else
Azure.IoT Build 0:ef4901974abc 1102 {
Azure.IoT Build 0:ef4901974abc 1103 uint8_t* dataBytes = BUFFER_u_char(codec_Data->headerData);
Azure.IoT Build 0:ef4901974abc 1104 if (dataBytes == NULL)
Azure.IoT Build 0:ef4901974abc 1105 {
Azure.IoT Build 0:ef4901974abc 1106 /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1107 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1108 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1109 }
Azure.IoT Build 0:ef4901974abc 1110 else
Azure.IoT Build 0:ef4901974abc 1111 {
Azure.IoT Build 0:ef4901974abc 1112 // Increment the data
Azure.IoT Build 0:ef4901974abc 1113 dataBytes += codec_Data->bufferOffset++;
Azure.IoT Build 0:ef4901974abc 1114 *dataBytes = iterator;
Azure.IoT Build 0:ef4901974abc 1115
Azure.IoT Build 0:ef4901974abc 1116 size_t totalLen = BUFFER_length(codec_Data->headerData);
Azure.IoT Build 0:ef4901974abc 1117 if (codec_Data->bufferOffset >= totalLen)
Azure.IoT Build 0:ef4901974abc 1118 {
Azure.IoT Build 0:ef4901974abc 1119 /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */
Azure.IoT Build 0:ef4901974abc 1120 completePacketData(codec_Data);
Azure.IoT Build 0:ef4901974abc 1121 }
Azure.IoT Build 0:ef4901974abc 1122 }
Azure.IoT Build 0:ef4901974abc 1123 }
Azure.IoT Build 0:ef4901974abc 1124 }
Azure.IoT Build 0:ef4901974abc 1125 else
Azure.IoT Build 0:ef4901974abc 1126 {
Azure.IoT Build 0:ef4901974abc 1127 /* Codes_SRS_MQTT_CODEC_07_035: [If any error is encountered then the packet state will be marked as error and mqtt_codec_bytesReceived shall return a non-zero value.] */
Azure.IoT Build 0:ef4901974abc 1128 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1129 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1130 }
Azure.IoT Build 0:ef4901974abc 1131 }
Azure.IoT Build 0:ef4901974abc 1132 }
Azure.IoT Build 0:ef4901974abc 1133 return result;
Azure.IoT Build 0:ef4901974abc 1134 }