A small footprint MQTT library

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Committer:
Azure.IoT Build
Date:
Fri Apr 08 12:01:23 2016 -0700
Revision:
0:ef4901974abc
Child:
5:34779607059c
1.0.4

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