Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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