A small footprint MQTT library

Dependents:   STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more

Committer:
AzureIoTClient
Date:
Thu Oct 20 17:07:55 2016 -0700
Revision:
8:83bb166aba73
Parent:
5:34779607059c
Child:
12:30b08cda82fd
1.0.10

Who changed what in which revision?

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