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