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:
Sat Oct 21 20:12:49 2017 +0000
Revision:
20:a8254fa69b6c
Parent:
15:ec5a36121959
Child:
22:786a74c2d89b
1.1.26

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
Azure.IoT Build 0:ef4901974abc 16 #define PACKET_TYPE_BYTE(p) ((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 8:83bb166aba73 47 static const char* TRUE_CONST = "true";
AzureIoTClient 8:83bb166aba73 48 static const char* 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
Azure.IoT Build 0:ef4901974abc 87 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
Azure.IoT Build 0:ef4901974abc 96 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
Azure.IoT Build 0:ef4901974abc 107 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
Azure.IoT Build 0:ef4901974abc 117 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);
Azure.IoT Build 0:ef4901974abc 486 packet[CONN_FLAG_BYTE_OFFSET] |= mqttOptions->qualityOfServiceValue;
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 if (totalLen > 0)
Azure.IoT Build 0:ef4901974abc 564 {
Azure.IoT Build 0:ef4901974abc 565 codecData->headerData = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 566 (void)BUFFER_pre_build(codecData->headerData, totalLen);
Azure.IoT Build 0:ef4901974abc 567 codecData->bufferOffset = 0;
Azure.IoT Build 0:ef4901974abc 568 }
Azure.IoT Build 0:ef4901974abc 569 codecData->codecState = CODEC_STATE_VAR_HEADER;
Azure.IoT Build 0:ef4901974abc 570
Azure.IoT Build 0:ef4901974abc 571 // Reset remainLen Index
Azure.IoT Build 0:ef4901974abc 572 codecData->remainLenIndex = 0;
Azure.IoT Build 0:ef4901974abc 573 memset(codecData->storeRemainLen, 0, 4 * sizeof(uint8_t));
Azure.IoT Build 0:ef4901974abc 574 }
Azure.IoT Build 0:ef4901974abc 575 }
Azure.IoT Build 0:ef4901974abc 576 return result;
Azure.IoT Build 0:ef4901974abc 577 }
Azure.IoT Build 0:ef4901974abc 578
Azure.IoT Build 0:ef4901974abc 579 static void completePacketData(MQTTCODEC_INSTANCE* codecData)
Azure.IoT Build 0:ef4901974abc 580 {
Azure.IoT Build 0:ef4901974abc 581 if (codecData)
Azure.IoT Build 0:ef4901974abc 582 {
Azure.IoT Build 0:ef4901974abc 583 if (codecData->packetComplete != NULL)
Azure.IoT Build 0:ef4901974abc 584 {
Azure.IoT Build 0:ef4901974abc 585 codecData->packetComplete(codecData->callContext, codecData->currPacket, codecData->headerFlags, codecData->headerData);
Azure.IoT Build 0:ef4901974abc 586 }
Azure.IoT Build 0:ef4901974abc 587
Azure.IoT Build 0:ef4901974abc 588 // Clean up data
Azure.IoT Build 0:ef4901974abc 589 codecData->currPacket = UNKNOWN_TYPE;
Azure.IoT Build 0:ef4901974abc 590 codecData->codecState = CODEC_STATE_FIXED_HEADER;
Azure.IoT Build 0:ef4901974abc 591 codecData->headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 592 BUFFER_delete(codecData->headerData);
Azure.IoT Build 0:ef4901974abc 593 codecData->headerData = NULL;
Azure.IoT Build 0:ef4901974abc 594 }
Azure.IoT Build 0:ef4901974abc 595 }
Azure.IoT Build 0:ef4901974abc 596
Azure.IoT Build 0:ef4901974abc 597 MQTTCODEC_HANDLE mqtt_codec_create(ON_PACKET_COMPLETE_CALLBACK packetComplete, void* callbackCtx)
Azure.IoT Build 0:ef4901974abc 598 {
Azure.IoT Build 0:ef4901974abc 599 MQTTCODEC_HANDLE result;
AzureIoTClient 8:83bb166aba73 600 result = malloc(sizeof(MQTTCODEC_INSTANCE));
Azure.IoT Build 0:ef4901974abc 601 /* Codes_SRS_MQTT_CODEC_07_001: [If a failure is encountered then mqtt_codec_create shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 602 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 603 {
Azure.IoT Build 0:ef4901974abc 604 /* Codes_SRS_MQTT_CODEC_07_002: [On success mqtt_codec_create shall return a MQTTCODEC_HANDLE value.] */
Azure.IoT Build 0:ef4901974abc 605 result->currPacket = UNKNOWN_TYPE;
Azure.IoT Build 0:ef4901974abc 606 result->codecState = CODEC_STATE_FIXED_HEADER;
Azure.IoT Build 0:ef4901974abc 607 result->headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 608 result->bufferOffset = 0;
Azure.IoT Build 0:ef4901974abc 609 result->packetComplete = packetComplete;
Azure.IoT Build 0:ef4901974abc 610 result->callContext = callbackCtx;
Azure.IoT Build 0:ef4901974abc 611 result->headerData = NULL;
Azure.IoT Build 0:ef4901974abc 612 memset(result->storeRemainLen, 0, 4 * sizeof(uint8_t));
Azure.IoT Build 0:ef4901974abc 613 result->remainLenIndex = 0;
Azure.IoT Build 0:ef4901974abc 614 }
Azure.IoT Build 0:ef4901974abc 615 return result;
Azure.IoT Build 0:ef4901974abc 616 }
Azure.IoT Build 0:ef4901974abc 617
Azure.IoT Build 0:ef4901974abc 618 void mqtt_codec_destroy(MQTTCODEC_HANDLE handle)
Azure.IoT Build 0:ef4901974abc 619 {
Azure.IoT Build 0:ef4901974abc 620 /* Codes_SRS_MQTT_CODEC_07_003: [If the handle parameter is NULL then mqtt_codec_destroy shall do nothing.] */
Azure.IoT Build 0:ef4901974abc 621 if (handle != NULL)
Azure.IoT Build 0:ef4901974abc 622 {
Azure.IoT Build 0:ef4901974abc 623 MQTTCODEC_INSTANCE* codecData = (MQTTCODEC_INSTANCE*)handle;
Azure.IoT Build 0:ef4901974abc 624 /* 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 625 BUFFER_delete(codecData->headerData);
Azure.IoT Build 0:ef4901974abc 626 free(codecData);
Azure.IoT Build 0:ef4901974abc 627 }
Azure.IoT Build 0:ef4901974abc 628 }
Azure.IoT Build 0:ef4901974abc 629
AzureIoTClient 8:83bb166aba73 630 BUFFER_HANDLE mqtt_codec_connect(const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 631 {
Azure.IoT Build 0:ef4901974abc 632 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 633 /* 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 634 if (mqttOptions == NULL)
Azure.IoT Build 0:ef4901974abc 635 {
Azure.IoT Build 0:ef4901974abc 636 result = NULL;
Azure.IoT Build 0:ef4901974abc 637 }
Azure.IoT Build 0:ef4901974abc 638 else
Azure.IoT Build 0:ef4901974abc 639 {
Azure.IoT Build 0:ef4901974abc 640 /* 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 641 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 642 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 643 {
AzureIoTClient 8:83bb166aba73 644 STRING_HANDLE varible_header_log = NULL;
AzureIoTClient 8:83bb166aba73 645 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 646 {
AzureIoTClient 8:83bb166aba73 647 varible_header_log = STRING_new();
AzureIoTClient 8:83bb166aba73 648 }
Azure.IoT Build 0:ef4901974abc 649 // Add Variable Header Information
AzureIoTClient 8:83bb166aba73 650 if (constructConnectVariableHeader(result, mqttOptions, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 651 {
Azure.IoT Build 0:ef4901974abc 652 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 653 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 654 result = NULL;
Azure.IoT Build 0:ef4901974abc 655 }
Azure.IoT Build 0:ef4901974abc 656 else
Azure.IoT Build 0:ef4901974abc 657 {
AzureIoTClient 8:83bb166aba73 658 if (constructConnPayload(result, mqttOptions, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 659 {
Azure.IoT Build 0:ef4901974abc 660 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 661 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 662 result = NULL;
Azure.IoT Build 0:ef4901974abc 663 }
Azure.IoT Build 0:ef4901974abc 664 else
Azure.IoT Build 0:ef4901974abc 665 {
AzureIoTClient 8:83bb166aba73 666 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 667 {
AzureIoTClient 8:83bb166aba73 668 (void)STRING_copy(trace_log, "CONNECT");
AzureIoTClient 8:83bb166aba73 669 }
Azure.IoT Build 0:ef4901974abc 670 if (constructFixedHeader(result, CONNECT_TYPE, 0) != 0)
Azure.IoT Build 0:ef4901974abc 671 {
Azure.IoT Build 0:ef4901974abc 672 /* Codes_SRS_MQTT_CODEC_07_010: [If any error is encountered then mqtt_codec_connect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 673 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 674 result = NULL;
Azure.IoT Build 0:ef4901974abc 675 }
AzureIoTClient 8:83bb166aba73 676 else
AzureIoTClient 8:83bb166aba73 677 {
AzureIoTClient 8:83bb166aba73 678 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 679 {
AzureIoTClient 8:83bb166aba73 680 (void)STRING_concat_with_STRING(trace_log, varible_header_log);
AzureIoTClient 8:83bb166aba73 681 }
AzureIoTClient 8:83bb166aba73 682 }
AzureIoTClient 8:83bb166aba73 683 }
AzureIoTClient 8:83bb166aba73 684 if (varible_header_log != NULL)
AzureIoTClient 8:83bb166aba73 685 {
AzureIoTClient 8:83bb166aba73 686 STRING_delete(varible_header_log);
Azure.IoT Build 0:ef4901974abc 687 }
Azure.IoT Build 0:ef4901974abc 688 }
Azure.IoT Build 0:ef4901974abc 689 }
Azure.IoT Build 0:ef4901974abc 690 }
Azure.IoT Build 0:ef4901974abc 691 return result;
Azure.IoT Build 0:ef4901974abc 692 }
Azure.IoT Build 0:ef4901974abc 693
Azure.IoT Build 0:ef4901974abc 694 BUFFER_HANDLE mqtt_codec_disconnect()
Azure.IoT Build 0:ef4901974abc 695 {
Azure.IoT Build 0:ef4901974abc 696 /* 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 697 BUFFER_HANDLE result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 698 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 699 {
Azure.IoT Build 0:ef4901974abc 700 if (BUFFER_enlarge(result, 2) != 0)
Azure.IoT Build 0:ef4901974abc 701 {
Azure.IoT Build 0:ef4901974abc 702 /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 703 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 704 result = NULL;
Azure.IoT Build 0:ef4901974abc 705 }
Azure.IoT Build 0:ef4901974abc 706 else
Azure.IoT Build 0:ef4901974abc 707 {
Azure.IoT Build 0:ef4901974abc 708 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 709 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 710 {
Azure.IoT Build 0:ef4901974abc 711 /* Codes_SRS_MQTT_CODEC_07_012: [If any error is encountered mqtt_codec_disconnect shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 712 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 713 result = NULL;
Azure.IoT Build 0:ef4901974abc 714 }
Azure.IoT Build 0:ef4901974abc 715 else
Azure.IoT Build 0:ef4901974abc 716 {
Azure.IoT Build 0:ef4901974abc 717 iterator[0] = DISCONNECT_TYPE;
Azure.IoT Build 0:ef4901974abc 718 iterator[1] = 0;
Azure.IoT Build 0:ef4901974abc 719 }
Azure.IoT Build 0:ef4901974abc 720 }
Azure.IoT Build 0:ef4901974abc 721 }
Azure.IoT Build 0:ef4901974abc 722 return result;
Azure.IoT Build 0:ef4901974abc 723 }
Azure.IoT Build 0:ef4901974abc 724
AzureIoTClient 8:83bb166aba73 725 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 726 {
Azure.IoT Build 0:ef4901974abc 727 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 728 /* Codes_SRS_MQTT_CODEC_07_005: [If the parameters topicName is NULL then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 729 if (topicName == NULL)
Azure.IoT Build 0:ef4901974abc 730 {
Azure.IoT Build 0:ef4901974abc 731 result = NULL;
Azure.IoT Build 0:ef4901974abc 732 }
Azure.IoT Build 0:ef4901974abc 733 /* 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 734 else if (buffLen > MAX_SEND_SIZE)
Azure.IoT Build 0:ef4901974abc 735 {
Azure.IoT Build 0:ef4901974abc 736 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 737 result = NULL;
Azure.IoT Build 0:ef4901974abc 738 }
Azure.IoT Build 0:ef4901974abc 739 else
Azure.IoT Build 0:ef4901974abc 740 {
AzureIoTClient 8:83bb166aba73 741 PUBLISH_HEADER_INFO publishInfo ={ 0 };
Azure.IoT Build 0:ef4901974abc 742 publishInfo.topicName = topicName;
Azure.IoT Build 0:ef4901974abc 743 publishInfo.packetId = packetId;
Azure.IoT Build 0:ef4901974abc 744 publishInfo.qualityOfServiceValue = qosValue;
Azure.IoT Build 0:ef4901974abc 745
Azure.IoT Build 0:ef4901974abc 746 uint8_t headerFlags = 0;
Azure.IoT Build 0:ef4901974abc 747 if (duplicateMsg) headerFlags |= PUBLISH_DUP_FLAG;
Azure.IoT Build 0:ef4901974abc 748 if (serverRetain) headerFlags |= PUBLISH_QOS_RETAIN;
Azure.IoT Build 0:ef4901974abc 749 if (qosValue != DELIVER_AT_MOST_ONCE)
Azure.IoT Build 0:ef4901974abc 750 {
Azure.IoT Build 0:ef4901974abc 751 if (qosValue == DELIVER_AT_LEAST_ONCE)
Azure.IoT Build 0:ef4901974abc 752 {
Azure.IoT Build 0:ef4901974abc 753 headerFlags |= PUBLISH_QOS_AT_LEAST_ONCE;
Azure.IoT Build 0:ef4901974abc 754 }
Azure.IoT Build 0:ef4901974abc 755 else
Azure.IoT Build 0:ef4901974abc 756 {
Azure.IoT Build 0:ef4901974abc 757 headerFlags |= PUBLISH_QOS_EXACTLY_ONCE;
Azure.IoT Build 0:ef4901974abc 758 }
Azure.IoT Build 0:ef4901974abc 759 }
Azure.IoT Build 0:ef4901974abc 760
Azure.IoT Build 0:ef4901974abc 761 /* 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 762 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 763 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 764 {
AzureIoTClient 8:83bb166aba73 765 STRING_HANDLE varible_header_log = NULL;
AzureIoTClient 8:83bb166aba73 766 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 767 {
AzureIoTClient 8:83bb166aba73 768 varible_header_log = STRING_construct_sprintf(" | IS_DUP: %s | RETAIN: %d | QOS: %s", duplicateMsg ? TRUE_CONST : FALSE_CONST,
AzureIoTClient 8:83bb166aba73 769 serverRetain ? 1 : 0,
AzureIoTClient 8:83bb166aba73 770 retrieve_qos_value(publishInfo.qualityOfServiceValue) );
AzureIoTClient 8:83bb166aba73 771 }
AzureIoTClient 8:83bb166aba73 772
AzureIoTClient 8:83bb166aba73 773 if (constructPublishVariableHeader(result, &publishInfo, varible_header_log) != 0)
Azure.IoT Build 0:ef4901974abc 774 {
Azure.IoT Build 0:ef4901974abc 775 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 776 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 777 result = NULL;
Azure.IoT Build 0:ef4901974abc 778 }
Azure.IoT Build 0:ef4901974abc 779 else
Azure.IoT Build 0:ef4901974abc 780 {
Azure.IoT Build 0:ef4901974abc 781 size_t payloadOffset = BUFFER_length(result);
Azure.IoT Build 0:ef4901974abc 782 if (buffLen > 0)
Azure.IoT Build 0:ef4901974abc 783 {
Azure.IoT Build 0:ef4901974abc 784 if (BUFFER_enlarge(result, buffLen) != 0)
Azure.IoT Build 0:ef4901974abc 785 {
Azure.IoT Build 0:ef4901974abc 786 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 787 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 788 result = NULL;
Azure.IoT Build 0:ef4901974abc 789 }
Azure.IoT Build 0:ef4901974abc 790 else
Azure.IoT Build 0:ef4901974abc 791 {
Azure.IoT Build 0:ef4901974abc 792 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 793 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 794 {
Azure.IoT Build 0:ef4901974abc 795 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 796 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 797 result = NULL;
Azure.IoT Build 0:ef4901974abc 798 }
Azure.IoT Build 0:ef4901974abc 799 else
Azure.IoT Build 0:ef4901974abc 800 {
Azure.IoT Build 0:ef4901974abc 801 iterator += payloadOffset;
Azure.IoT Build 0:ef4901974abc 802 // Write Message
AzureIoTClient 13:3c202001e4ba 803 (void)memcpy(iterator, msgBuffer, buffLen);
AzureIoTClient 8:83bb166aba73 804 if (trace_log)
AzureIoTClient 8:83bb166aba73 805 {
AzureIoTClient 8:83bb166aba73 806 STRING_sprintf(varible_header_log, " | PAYLOAD_LEN: %zu", buffLen);
AzureIoTClient 8:83bb166aba73 807 }
Azure.IoT Build 0:ef4901974abc 808 }
Azure.IoT Build 0:ef4901974abc 809 }
Azure.IoT Build 0:ef4901974abc 810 }
Azure.IoT Build 0:ef4901974abc 811
Azure.IoT Build 0:ef4901974abc 812 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 813 {
AzureIoTClient 8:83bb166aba73 814 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 815 {
AzureIoTClient 8:83bb166aba73 816 (void)STRING_copy(trace_log, "PUBLISH");
AzureIoTClient 8:83bb166aba73 817 }
Azure.IoT Build 0:ef4901974abc 818 if (constructFixedHeader(result, PUBLISH_TYPE, headerFlags) != 0)
Azure.IoT Build 0:ef4901974abc 819 {
Azure.IoT Build 0:ef4901974abc 820 /* Codes_SRS_MQTT_CODEC_07_006: [If any error is encountered then mqtt_codec_publish shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 821 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 822 result = NULL;
Azure.IoT Build 0:ef4901974abc 823 }
AzureIoTClient 8:83bb166aba73 824 else
AzureIoTClient 8:83bb166aba73 825 {
AzureIoTClient 8:83bb166aba73 826 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 827 {
AzureIoTClient 8:83bb166aba73 828 (void)STRING_concat_with_STRING(trace_log, varible_header_log);
AzureIoTClient 8:83bb166aba73 829 }
AzureIoTClient 8:83bb166aba73 830 }
Azure.IoT Build 0:ef4901974abc 831 }
Azure.IoT Build 0:ef4901974abc 832 }
AzureIoTClient 8:83bb166aba73 833 if (varible_header_log != NULL)
AzureIoTClient 8:83bb166aba73 834 {
AzureIoTClient 8:83bb166aba73 835 STRING_delete(varible_header_log);
AzureIoTClient 8:83bb166aba73 836 }
Azure.IoT Build 0:ef4901974abc 837 }
Azure.IoT Build 0:ef4901974abc 838 }
Azure.IoT Build 0:ef4901974abc 839 return result;
Azure.IoT Build 0:ef4901974abc 840 }
Azure.IoT Build 0:ef4901974abc 841
Azure.IoT Build 0:ef4901974abc 842 BUFFER_HANDLE mqtt_codec_publishAck(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 843 {
Azure.IoT Build 0:ef4901974abc 844 /* 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 845 /* Codes_SRS_MQTT_CODEC_07_014 : [If any error is encountered then mqtt_codec_publishAck shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 846 BUFFER_HANDLE result = constructPublishReply(PUBACK_TYPE, 0, packetId);
Azure.IoT Build 0:ef4901974abc 847 return result;
Azure.IoT Build 0:ef4901974abc 848 }
Azure.IoT Build 0:ef4901974abc 849
Azure.IoT Build 0:ef4901974abc 850 BUFFER_HANDLE mqtt_codec_publishReceived(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 851 {
Azure.IoT Build 0:ef4901974abc 852 /* 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 853 /* Codes_SRS_MQTT_CODEC_07_016 : [If any error is encountered then mqtt_codec_publishRecieved shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 854 BUFFER_HANDLE result = constructPublishReply(PUBREC_TYPE, 0, packetId);
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_publishRelease(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 859 {
Azure.IoT Build 0:ef4901974abc 860 /* 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 861 /* Codes_SRS_MQTT_CODEC_07_018 : [If any error is encountered then mqtt_codec_publishRelease shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 862 BUFFER_HANDLE result = constructPublishReply(PUBREL_TYPE, 2, 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_publishComplete(uint16_t packetId)
Azure.IoT Build 0:ef4901974abc 867 {
Azure.IoT Build 0:ef4901974abc 868 /* 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 869 /* Codes_SRS_MQTT_CODEC_07_020 : [If any error is encountered then mqtt_codec_publishComplete shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 870 BUFFER_HANDLE result = constructPublishReply(PUBCOMP_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_ping()
Azure.IoT Build 0:ef4901974abc 875 {
Azure.IoT Build 0:ef4901974abc 876 /* 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 877 BUFFER_HANDLE result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 878 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 879 {
Azure.IoT Build 0:ef4901974abc 880 if (BUFFER_enlarge(result, 2) != 0)
Azure.IoT Build 0:ef4901974abc 881 {
Azure.IoT Build 0:ef4901974abc 882 /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 883 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 884 result = NULL;
Azure.IoT Build 0:ef4901974abc 885 }
Azure.IoT Build 0:ef4901974abc 886 else
Azure.IoT Build 0:ef4901974abc 887 {
Azure.IoT Build 0:ef4901974abc 888 uint8_t* iterator = BUFFER_u_char(result);
Azure.IoT Build 0:ef4901974abc 889 if (iterator == NULL)
Azure.IoT Build 0:ef4901974abc 890 {
Azure.IoT Build 0:ef4901974abc 891 /* Codes_SRS_MQTT_CODEC_07_022: [If any error is encountered mqtt_codec_ping shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 892 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 893 result = NULL;
Azure.IoT Build 0:ef4901974abc 894 }
Azure.IoT Build 0:ef4901974abc 895 else
Azure.IoT Build 0:ef4901974abc 896 {
Azure.IoT Build 0:ef4901974abc 897 iterator[0] = PINGREQ_TYPE;
Azure.IoT Build 0:ef4901974abc 898 iterator[1] = 0;
Azure.IoT Build 0:ef4901974abc 899 }
Azure.IoT Build 0:ef4901974abc 900 }
Azure.IoT Build 0:ef4901974abc 901 }
Azure.IoT Build 0:ef4901974abc 902 return result;
Azure.IoT Build 0:ef4901974abc 903 }
Azure.IoT Build 0:ef4901974abc 904
AzureIoTClient 8:83bb166aba73 905 BUFFER_HANDLE mqtt_codec_subscribe(uint16_t packetId, SUBSCRIBE_PAYLOAD* subscribeList, size_t count, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 906 {
Azure.IoT Build 0:ef4901974abc 907 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 908 /* 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 909 if (subscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 910 {
Azure.IoT Build 0:ef4901974abc 911 result = NULL;
Azure.IoT Build 0:ef4901974abc 912 }
Azure.IoT Build 0:ef4901974abc 913 else
Azure.IoT Build 0:ef4901974abc 914 {
Azure.IoT Build 0:ef4901974abc 915 /* 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 916 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 917 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 918 {
Azure.IoT Build 0:ef4901974abc 919 if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
Azure.IoT Build 0:ef4901974abc 920 {
Azure.IoT Build 0:ef4901974abc 921 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 922 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 923 result = NULL;
Azure.IoT Build 0:ef4901974abc 924 }
Azure.IoT Build 0:ef4901974abc 925 else
Azure.IoT Build 0:ef4901974abc 926 {
AzureIoTClient 8:83bb166aba73 927 STRING_HANDLE sub_trace = NULL;
AzureIoTClient 8:83bb166aba73 928 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 929 {
AzureIoTClient 8:83bb166aba73 930 sub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
AzureIoTClient 8:83bb166aba73 931 }
Azure.IoT Build 0:ef4901974abc 932 /* Codes_SRS_MQTT_CODEC_07_024: [mqtt_codec_subscribe shall iterate through count items in the subscribeList.] */
AzureIoTClient 8:83bb166aba73 933 if (addListItemsToSubscribePacket(result, subscribeList, count, sub_trace) != 0)
Azure.IoT Build 0:ef4901974abc 934 {
Azure.IoT Build 0:ef4901974abc 935 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 936 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 937 result = NULL;
Azure.IoT Build 0:ef4901974abc 938 }
Azure.IoT Build 0:ef4901974abc 939 else
Azure.IoT Build 0:ef4901974abc 940 {
AzureIoTClient 8:83bb166aba73 941
AzureIoTClient 8:83bb166aba73 942 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 943 {
AzureIoTClient 8:83bb166aba73 944 STRING_concat(trace_log, "SUBSCRIBE");
AzureIoTClient 8:83bb166aba73 945 }
Azure.IoT Build 0:ef4901974abc 946 if (constructFixedHeader(result, SUBSCRIBE_TYPE, SUBSCRIBE_FIXED_HEADER_FLAG) != 0)
Azure.IoT Build 0:ef4901974abc 947 {
Azure.IoT Build 0:ef4901974abc 948 /* Codes_SRS_MQTT_CODEC_07_025: [If any error is encountered then mqtt_codec_subscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 949 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 950 result = NULL;
Azure.IoT Build 0:ef4901974abc 951 }
AzureIoTClient 8:83bb166aba73 952 else
AzureIoTClient 8:83bb166aba73 953 {
AzureIoTClient 8:83bb166aba73 954 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 955 {
AzureIoTClient 8:83bb166aba73 956 (void)STRING_concat_with_STRING(trace_log, sub_trace);
AzureIoTClient 8:83bb166aba73 957 }
AzureIoTClient 8:83bb166aba73 958 }
AzureIoTClient 8:83bb166aba73 959 }
AzureIoTClient 8:83bb166aba73 960 if (sub_trace != NULL)
AzureIoTClient 8:83bb166aba73 961 {
AzureIoTClient 8:83bb166aba73 962 STRING_delete(sub_trace);
Azure.IoT Build 0:ef4901974abc 963 }
Azure.IoT Build 0:ef4901974abc 964 }
Azure.IoT Build 0:ef4901974abc 965 }
Azure.IoT Build 0:ef4901974abc 966 }
Azure.IoT Build 0:ef4901974abc 967 return result;
Azure.IoT Build 0:ef4901974abc 968 }
Azure.IoT Build 0:ef4901974abc 969
AzureIoTClient 8:83bb166aba73 970 BUFFER_HANDLE mqtt_codec_unsubscribe(uint16_t packetId, const char** unsubscribeList, size_t count, STRING_HANDLE trace_log)
Azure.IoT Build 0:ef4901974abc 971 {
Azure.IoT Build 0:ef4901974abc 972 BUFFER_HANDLE result;
Azure.IoT Build 0:ef4901974abc 973 /* 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 974 if (unsubscribeList == NULL || count == 0)
Azure.IoT Build 0:ef4901974abc 975 {
Azure.IoT Build 0:ef4901974abc 976 result = NULL;
Azure.IoT Build 0:ef4901974abc 977 }
Azure.IoT Build 0:ef4901974abc 978 else
Azure.IoT Build 0:ef4901974abc 979 {
Azure.IoT Build 0:ef4901974abc 980 /* 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 981 result = BUFFER_new();
Azure.IoT Build 0:ef4901974abc 982 if (result != NULL)
Azure.IoT Build 0:ef4901974abc 983 {
Azure.IoT Build 0:ef4901974abc 984 if (constructSubscibeTypeVariableHeader(result, packetId) != 0)
Azure.IoT Build 0:ef4901974abc 985 {
Azure.IoT Build 0:ef4901974abc 986 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 987 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 988 result = NULL;
Azure.IoT Build 0:ef4901974abc 989 }
Azure.IoT Build 0:ef4901974abc 990 else
Azure.IoT Build 0:ef4901974abc 991 {
AzureIoTClient 8:83bb166aba73 992 STRING_HANDLE unsub_trace = NULL;
AzureIoTClient 8:83bb166aba73 993 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 994 {
AzureIoTClient 8:83bb166aba73 995 unsub_trace = STRING_construct_sprintf(" | PACKET_ID: %"PRIu16, packetId);
AzureIoTClient 8:83bb166aba73 996 }
Azure.IoT Build 0:ef4901974abc 997 /* Codes_SRS_MQTT_CODEC_07_028: [mqtt_codec_unsubscribe shall iterate through count items in the unsubscribeList.] */
AzureIoTClient 8:83bb166aba73 998 if (addListItemsToUnsubscribePacket(result, unsubscribeList, count, unsub_trace) != 0)
Azure.IoT Build 0:ef4901974abc 999 {
Azure.IoT Build 0:ef4901974abc 1000 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 1001 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 1002 result = NULL;
Azure.IoT Build 0:ef4901974abc 1003 }
Azure.IoT Build 0:ef4901974abc 1004 else
Azure.IoT Build 0:ef4901974abc 1005 {
AzureIoTClient 8:83bb166aba73 1006 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1007 {
AzureIoTClient 8:83bb166aba73 1008 (void)STRING_copy(trace_log, "UNSUBSCRIBE");
AzureIoTClient 8:83bb166aba73 1009 }
Azure.IoT Build 0:ef4901974abc 1010 if (constructFixedHeader(result, UNSUBSCRIBE_TYPE, UNSUBSCRIBE_FIXED_HEADER_FLAG) != 0)
Azure.IoT Build 0:ef4901974abc 1011 {
Azure.IoT Build 0:ef4901974abc 1012 /* Codes_SRS_MQTT_CODEC_07_029: [If any error is encountered then mqtt_codec_unsubscribe shall return NULL.] */
Azure.IoT Build 0:ef4901974abc 1013 BUFFER_delete(result);
Azure.IoT Build 0:ef4901974abc 1014 result = NULL;
Azure.IoT Build 0:ef4901974abc 1015 }
AzureIoTClient 8:83bb166aba73 1016 else
AzureIoTClient 8:83bb166aba73 1017 {
AzureIoTClient 8:83bb166aba73 1018 if (trace_log != NULL)
AzureIoTClient 8:83bb166aba73 1019 {
AzureIoTClient 8:83bb166aba73 1020 (void)STRING_concat_with_STRING(trace_log, unsub_trace);
AzureIoTClient 8:83bb166aba73 1021 }
AzureIoTClient 8:83bb166aba73 1022 }
AzureIoTClient 8:83bb166aba73 1023 }
AzureIoTClient 8:83bb166aba73 1024 if (unsub_trace != NULL)
AzureIoTClient 8:83bb166aba73 1025 {
AzureIoTClient 8:83bb166aba73 1026 STRING_delete(unsub_trace);
Azure.IoT Build 0:ef4901974abc 1027 }
Azure.IoT Build 0:ef4901974abc 1028 }
Azure.IoT Build 0:ef4901974abc 1029 }
Azure.IoT Build 0:ef4901974abc 1030 }
Azure.IoT Build 0:ef4901974abc 1031 return result;
Azure.IoT Build 0:ef4901974abc 1032 }
Azure.IoT Build 0:ef4901974abc 1033
Azure.IoT Build 0:ef4901974abc 1034 int mqtt_codec_bytesReceived(MQTTCODEC_HANDLE handle, const unsigned char* buffer, size_t size)
Azure.IoT Build 0:ef4901974abc 1035 {
Azure.IoT Build 0:ef4901974abc 1036 int result;
Azure.IoT Build 0:ef4901974abc 1037 MQTTCODEC_INSTANCE* codec_Data = (MQTTCODEC_INSTANCE*)handle;
Azure.IoT Build 0:ef4901974abc 1038 /* 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 1039 if (codec_Data == NULL)
Azure.IoT Build 0:ef4901974abc 1040 {
AzureIoTClient 15:ec5a36121959 1041 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1042 }
Azure.IoT Build 0:ef4901974abc 1043 /* 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 1044 /* 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 1045 else if (buffer == NULL || size == 0)
Azure.IoT Build 0:ef4901974abc 1046 {
Azure.IoT Build 0:ef4901974abc 1047 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1048 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1049 }
Azure.IoT Build 0:ef4901974abc 1050 else
Azure.IoT Build 0:ef4901974abc 1051 {
Azure.IoT Build 0:ef4901974abc 1052 /* 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 1053 result = 0;
AzureIoTClient 12:30b08cda82fd 1054 size_t index = 0;
AzureIoTClient 12:30b08cda82fd 1055 for (index = 0; index < size && result == 0; index++)
Azure.IoT Build 0:ef4901974abc 1056 {
Azure.IoT Build 0:ef4901974abc 1057 uint8_t iterator = ((int8_t*)buffer)[index];
Azure.IoT Build 0:ef4901974abc 1058 if (codec_Data->codecState == CODEC_STATE_FIXED_HEADER)
Azure.IoT Build 0:ef4901974abc 1059 {
Azure.IoT Build 0:ef4901974abc 1060 if (codec_Data->currPacket == UNKNOWN_TYPE)
Azure.IoT Build 0:ef4901974abc 1061 {
Azure.IoT Build 0:ef4901974abc 1062 codec_Data->currPacket = processControlPacketType(iterator, &codec_Data->headerFlags);
Azure.IoT Build 0:ef4901974abc 1063 }
Azure.IoT Build 0:ef4901974abc 1064 else
Azure.IoT Build 0:ef4901974abc 1065 {
Azure.IoT Build 0:ef4901974abc 1066 if (prepareheaderDataInfo(codec_Data, iterator) != 0)
Azure.IoT Build 0:ef4901974abc 1067 {
Azure.IoT Build 0:ef4901974abc 1068 /* 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 1069 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1070 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1071 }
Azure.IoT Build 0:ef4901974abc 1072 if (codec_Data->currPacket == PINGRESP_TYPE)
Azure.IoT Build 0:ef4901974abc 1073 {
Azure.IoT Build 0:ef4901974abc 1074 /* 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 1075 completePacketData(codec_Data);
Azure.IoT Build 0:ef4901974abc 1076 }
Azure.IoT Build 0:ef4901974abc 1077 }
Azure.IoT Build 0:ef4901974abc 1078 }
Azure.IoT Build 0:ef4901974abc 1079 else if (codec_Data->codecState == CODEC_STATE_VAR_HEADER)
Azure.IoT Build 0:ef4901974abc 1080 {
Azure.IoT Build 0:ef4901974abc 1081 if (codec_Data->headerData == NULL)
Azure.IoT Build 0:ef4901974abc 1082 {
Azure.IoT Build 0:ef4901974abc 1083 codec_Data->codecState = CODEC_STATE_PAYLOAD;
Azure.IoT Build 0:ef4901974abc 1084 }
Azure.IoT Build 0:ef4901974abc 1085 else
Azure.IoT Build 0:ef4901974abc 1086 {
Azure.IoT Build 0:ef4901974abc 1087 uint8_t* dataBytes = BUFFER_u_char(codec_Data->headerData);
Azure.IoT Build 0:ef4901974abc 1088 if (dataBytes == NULL)
Azure.IoT Build 0:ef4901974abc 1089 {
Azure.IoT Build 0:ef4901974abc 1090 /* 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 1091 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1092 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1093 }
Azure.IoT Build 0:ef4901974abc 1094 else
Azure.IoT Build 0:ef4901974abc 1095 {
Azure.IoT Build 0:ef4901974abc 1096 // Increment the data
Azure.IoT Build 0:ef4901974abc 1097 dataBytes += codec_Data->bufferOffset++;
Azure.IoT Build 0:ef4901974abc 1098 *dataBytes = iterator;
Azure.IoT Build 0:ef4901974abc 1099
Azure.IoT Build 0:ef4901974abc 1100 size_t totalLen = BUFFER_length(codec_Data->headerData);
Azure.IoT Build 0:ef4901974abc 1101 if (codec_Data->bufferOffset >= totalLen)
Azure.IoT Build 0:ef4901974abc 1102 {
Azure.IoT Build 0:ef4901974abc 1103 /* 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 1104 completePacketData(codec_Data);
Azure.IoT Build 0:ef4901974abc 1105 }
Azure.IoT Build 0:ef4901974abc 1106 }
Azure.IoT Build 0:ef4901974abc 1107 }
Azure.IoT Build 0:ef4901974abc 1108 }
Azure.IoT Build 0:ef4901974abc 1109 else
Azure.IoT Build 0:ef4901974abc 1110 {
Azure.IoT Build 0:ef4901974abc 1111 /* 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 1112 codec_Data->currPacket = PACKET_TYPE_ERROR;
AzureIoTClient 15:ec5a36121959 1113 result = __FAILURE__;
Azure.IoT Build 0:ef4901974abc 1114 }
Azure.IoT Build 0:ef4901974abc 1115 }
Azure.IoT Build 0:ef4901974abc 1116 }
Azure.IoT Build 0:ef4901974abc 1117 return result;
Azure.IoT Build 0:ef4901974abc 1118 }