A small footprint MQTT library

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Committer:
AzureIoTClient
Date:
Tue Jan 24 15:24:05 2017 -0800
Revision:
12:30b08cda82fd
Parent:
8:83bb166aba73
Child:
13:3c202001e4ba
1.1.5

Who changed what in which revision?

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