test

Committer:
peyo
Date:
Wed Apr 12 14:09:46 2017 +0200
Revision:
1:3f75eb8d46f4
Parent:
0:cd5404401c2f
add main

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peyo 0:cd5404401c2f 1 /*
peyo 0:cd5404401c2f 2 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
peyo 0:cd5404401c2f 3 *
peyo 0:cd5404401c2f 4 * Licensed under the Apache License, Version 2.0 (the "License").
peyo 0:cd5404401c2f 5 * You may not use this file except in compliance with the License.
peyo 0:cd5404401c2f 6 * A copy of the License is located at
peyo 0:cd5404401c2f 7 *
peyo 0:cd5404401c2f 8 * http://aws.amazon.com/apache2.0
peyo 0:cd5404401c2f 9 *
peyo 0:cd5404401c2f 10 * or in the "license" file accompanying this file. This file is distributed
peyo 0:cd5404401c2f 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
peyo 0:cd5404401c2f 12 * express or implied. See the License for the specific language governing
peyo 0:cd5404401c2f 13 * permissions and limitations under the License.
peyo 0:cd5404401c2f 14 */
peyo 0:cd5404401c2f 15
peyo 0:cd5404401c2f 16 // Based on Eclipse Paho.
peyo 0:cd5404401c2f 17 /*******************************************************************************
peyo 0:cd5404401c2f 18 * Copyright (c) 2014 IBM Corp.
peyo 0:cd5404401c2f 19 *
peyo 0:cd5404401c2f 20 * All rights reserved. This program and the accompanying materials
peyo 0:cd5404401c2f 21 * are made available under the terms of the Eclipse Public License v1.0
peyo 0:cd5404401c2f 22 * and Eclipse Distribution License v1.0 which accompany this distribution.
peyo 0:cd5404401c2f 23 *
peyo 0:cd5404401c2f 24 * The Eclipse Public License is available at
peyo 0:cd5404401c2f 25 * http://www.eclipse.org/legal/epl-v10.html
peyo 0:cd5404401c2f 26 * and the Eclipse Distribution License is available at
peyo 0:cd5404401c2f 27 * http://www.eclipse.org/org/documents/edl-v10.php.
peyo 0:cd5404401c2f 28 *
peyo 0:cd5404401c2f 29 * Contributors:
peyo 0:cd5404401c2f 30 * Ian Craggs - initial API and implementation and/or initial documentation
peyo 0:cd5404401c2f 31 * Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
peyo 0:cd5404401c2f 32 *******************************************************************************/
peyo 0:cd5404401c2f 33
peyo 0:cd5404401c2f 34 /**
peyo 0:cd5404401c2f 35 * @file aws_iot_mqtt_client_publish.c
peyo 0:cd5404401c2f 36 * @brief MQTT client publish API definitions
peyo 0:cd5404401c2f 37 */
peyo 0:cd5404401c2f 38
peyo 0:cd5404401c2f 39 #ifdef __cplusplus
peyo 0:cd5404401c2f 40 extern "C" {
peyo 0:cd5404401c2f 41 #endif
peyo 0:cd5404401c2f 42
peyo 0:cd5404401c2f 43 #include "aws_iot_mqtt_client_common_internal.h"
peyo 0:cd5404401c2f 44
peyo 0:cd5404401c2f 45 /**
peyo 0:cd5404401c2f 46 * @param stringVar pointer to the String into which the data is to be read
peyo 0:cd5404401c2f 47 * @param stringLen pointer to variable which has the length of the string
peyo 0:cd5404401c2f 48 * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
peyo 0:cd5404401c2f 49 * @param enddata pointer to the end of the data: do not read beyond
peyo 0:cd5404401c2f 50 * @return SUCCESS if successful, FAILURE if not
peyo 0:cd5404401c2f 51 */
peyo 0:cd5404401c2f 52 static IoT_Error_t _aws_iot_mqtt_read_string_with_len(char **stringVar, uint16_t *stringLen,
peyo 0:cd5404401c2f 53 unsigned char **pptr, unsigned char *enddata) {
peyo 0:cd5404401c2f 54 IoT_Error_t rc = FAILURE;
peyo 0:cd5404401c2f 55
peyo 0:cd5404401c2f 56 FUNC_ENTRY;
peyo 0:cd5404401c2f 57 /* the first two bytes are the length of the string */
peyo 0:cd5404401c2f 58 /* enough length to read the integer? */
peyo 0:cd5404401c2f 59 if(enddata - (*pptr) > 1) {
peyo 0:cd5404401c2f 60 *stringLen = aws_iot_mqtt_internal_read_uint16_t(pptr); /* increments pptr to point past length */
peyo 0:cd5404401c2f 61 if(&(*pptr)[*stringLen] <= enddata) {
peyo 0:cd5404401c2f 62 *stringVar = (char *) *pptr;
peyo 0:cd5404401c2f 63 *pptr += *stringLen;
peyo 0:cd5404401c2f 64 rc = SUCCESS;
peyo 0:cd5404401c2f 65 }
peyo 0:cd5404401c2f 66 }
peyo 0:cd5404401c2f 67
peyo 0:cd5404401c2f 68 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 69 }
peyo 0:cd5404401c2f 70
peyo 0:cd5404401c2f 71 /**
peyo 0:cd5404401c2f 72 * Serializes the supplied publish data into the supplied buffer, ready for sending
peyo 0:cd5404401c2f 73 * @param pTxBuf the buffer into which the packet will be serialized
peyo 0:cd5404401c2f 74 * @param txBufLen the length in bytes of the supplied buffer
peyo 0:cd5404401c2f 75 * @param dup uint8_t - the MQTT dup flag
peyo 0:cd5404401c2f 76 * @param qos QoS - the MQTT QoS value
peyo 0:cd5404401c2f 77 * @param retained uint8_t - the MQTT retained flag
peyo 0:cd5404401c2f 78 * @param packetId uint16_t - the MQTT packet identifier
peyo 0:cd5404401c2f 79 * @param pTopicName char * - the MQTT topic in the publish
peyo 0:cd5404401c2f 80 * @param topicNameLen uint16_t - the length of the Topic Name
peyo 0:cd5404401c2f 81 * @param pPayload byte buffer - the MQTT publish payload
peyo 0:cd5404401c2f 82 * @param payloadLen size_t - the length of the MQTT payload
peyo 0:cd5404401c2f 83 * @param pSerializedLen uint32_t - pointer to the variable that stores serialized len
peyo 0:cd5404401c2f 84 *
peyo 0:cd5404401c2f 85 * @return An IoT Error Type defining successful/failed call
peyo 0:cd5404401c2f 86 */
peyo 0:cd5404401c2f 87 static IoT_Error_t _aws_iot_mqtt_internal_serialize_publish(unsigned char *pTxBuf, size_t txBufLen, uint8_t dup,
peyo 0:cd5404401c2f 88 QoS qos, uint8_t retained, uint16_t packetId,
peyo 0:cd5404401c2f 89 const char *pTopicName, uint16_t topicNameLen,
peyo 0:cd5404401c2f 90 const unsigned char *pPayload, size_t payloadLen,
peyo 0:cd5404401c2f 91 uint32_t *pSerializedLen) {
peyo 0:cd5404401c2f 92 unsigned char *ptr;
peyo 0:cd5404401c2f 93 uint32_t rem_len;
peyo 0:cd5404401c2f 94 IoT_Error_t rc;
peyo 0:cd5404401c2f 95 MQTTHeader header = {0};
peyo 0:cd5404401c2f 96
peyo 0:cd5404401c2f 97 FUNC_ENTRY;
peyo 0:cd5404401c2f 98 if(NULL == pTxBuf || NULL == pPayload || NULL == pSerializedLen) {
peyo 0:cd5404401c2f 99 FUNC_EXIT_RC(NULL_VALUE_ERROR);
peyo 0:cd5404401c2f 100 }
peyo 0:cd5404401c2f 101
peyo 0:cd5404401c2f 102 ptr = pTxBuf;
peyo 0:cd5404401c2f 103 rem_len = 0;
peyo 0:cd5404401c2f 104
peyo 0:cd5404401c2f 105 rem_len += (uint32_t) (topicNameLen + payloadLen + 2);
peyo 0:cd5404401c2f 106 if(qos > 0) {
peyo 0:cd5404401c2f 107 rem_len += 2; /* packetId */
peyo 0:cd5404401c2f 108 }
peyo 0:cd5404401c2f 109 if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(rem_len) > txBufLen) {
peyo 0:cd5404401c2f 110 FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR);
peyo 0:cd5404401c2f 111 }
peyo 0:cd5404401c2f 112
peyo 0:cd5404401c2f 113 rc = aws_iot_mqtt_internal_init_header(&header, PUBLISH, qos, dup, retained);
peyo 0:cd5404401c2f 114 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 115 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 116 }
peyo 0:cd5404401c2f 117 aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */
peyo 0:cd5404401c2f 118
peyo 0:cd5404401c2f 119 ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, rem_len); /* write remaining length */;
peyo 0:cd5404401c2f 120
peyo 0:cd5404401c2f 121 aws_iot_mqtt_internal_write_utf8_string(&ptr, pTopicName, topicNameLen);
peyo 0:cd5404401c2f 122
peyo 0:cd5404401c2f 123 if(qos > 0) {
peyo 0:cd5404401c2f 124 aws_iot_mqtt_internal_write_uint_16(&ptr, packetId);
peyo 0:cd5404401c2f 125 }
peyo 0:cd5404401c2f 126
peyo 0:cd5404401c2f 127 memcpy(ptr, pPayload, payloadLen);
peyo 0:cd5404401c2f 128 ptr += payloadLen;
peyo 0:cd5404401c2f 129
peyo 0:cd5404401c2f 130 *pSerializedLen = (uint32_t) (ptr - pTxBuf);
peyo 0:cd5404401c2f 131
peyo 0:cd5404401c2f 132 FUNC_EXIT_RC(SUCCESS);
peyo 0:cd5404401c2f 133 }
peyo 0:cd5404401c2f 134
peyo 0:cd5404401c2f 135 /**
peyo 0:cd5404401c2f 136 * Serializes the ack packet into the supplied buffer.
peyo 0:cd5404401c2f 137 * @param pTxBuf the buffer into which the packet will be serialized
peyo 0:cd5404401c2f 138 * @param txBufLen the length in bytes of the supplied buffer
peyo 0:cd5404401c2f 139 * @param msgType the MQTT packet type
peyo 0:cd5404401c2f 140 * @param dup the MQTT dup flag
peyo 0:cd5404401c2f 141 * @param packetId the MQTT packet identifier
peyo 0:cd5404401c2f 142 * @param pSerializedLen uint32_t - pointer to the variable that stores serialized len
peyo 0:cd5404401c2f 143 *
peyo 0:cd5404401c2f 144 * @return An IoT Error Type defining successful/failed call
peyo 0:cd5404401c2f 145 */
peyo 0:cd5404401c2f 146 IoT_Error_t aws_iot_mqtt_internal_serialize_ack(unsigned char *pTxBuf, size_t txBufLen,
peyo 0:cd5404401c2f 147 MessageTypes msgType, uint8_t dup, uint16_t packetId,
peyo 0:cd5404401c2f 148 uint32_t *pSerializedLen) {
peyo 0:cd5404401c2f 149 unsigned char *ptr;
peyo 0:cd5404401c2f 150 QoS requestQoS;
peyo 0:cd5404401c2f 151 IoT_Error_t rc;
peyo 0:cd5404401c2f 152 MQTTHeader header = {0};
peyo 0:cd5404401c2f 153 FUNC_ENTRY;
peyo 0:cd5404401c2f 154 if(NULL == pTxBuf || pSerializedLen == NULL) {
peyo 0:cd5404401c2f 155 FUNC_EXIT_RC(NULL_VALUE_ERROR);
peyo 0:cd5404401c2f 156 }
peyo 0:cd5404401c2f 157
peyo 0:cd5404401c2f 158 ptr = pTxBuf;
peyo 0:cd5404401c2f 159
peyo 0:cd5404401c2f 160 /* Minimum byte length required by ACK headers is
peyo 0:cd5404401c2f 161 * 2 for fixed and 2 for variable part */
peyo 0:cd5404401c2f 162 if(4 > txBufLen) {
peyo 0:cd5404401c2f 163 FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR);
peyo 0:cd5404401c2f 164 }
peyo 0:cd5404401c2f 165
peyo 0:cd5404401c2f 166 requestQoS = (PUBREL == msgType) ? QOS1 : QOS0;
peyo 0:cd5404401c2f 167 rc = aws_iot_mqtt_internal_init_header(&header, msgType, requestQoS, dup, 0);
peyo 0:cd5404401c2f 168 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 169 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 170 }
peyo 0:cd5404401c2f 171 aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */
peyo 0:cd5404401c2f 172
peyo 0:cd5404401c2f 173 ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, 2); /* write remaining length */
peyo 0:cd5404401c2f 174 aws_iot_mqtt_internal_write_uint_16(&ptr, packetId);
peyo 0:cd5404401c2f 175 *pSerializedLen = (uint32_t) (ptr - pTxBuf);
peyo 0:cd5404401c2f 176
peyo 0:cd5404401c2f 177 FUNC_EXIT_RC(SUCCESS);
peyo 0:cd5404401c2f 178 }
peyo 0:cd5404401c2f 179
peyo 0:cd5404401c2f 180 /**
peyo 0:cd5404401c2f 181 * @brief Publish an MQTT message on a topic
peyo 0:cd5404401c2f 182 *
peyo 0:cd5404401c2f 183 * Called to publish an MQTT message on a topic.
peyo 0:cd5404401c2f 184 * @note Call is blocking. In the case of a QoS 0 message the function returns
peyo 0:cd5404401c2f 185 * after the message was successfully passed to the TLS layer. In the case of QoS 1
peyo 0:cd5404401c2f 186 * the function returns after the receipt of the PUBACK control packet.
peyo 0:cd5404401c2f 187 * This is the internal function which is called by the publish API to perform the operation.
peyo 0:cd5404401c2f 188 * Not meant to be called directly as it doesn't do validations or client state changes
peyo 0:cd5404401c2f 189 *
peyo 0:cd5404401c2f 190 * @param pClient Reference to the IoT Client
peyo 0:cd5404401c2f 191 * @param pTopicName Topic Name to publish to
peyo 0:cd5404401c2f 192 * @param topicNameLen Length of the topic name
peyo 0:cd5404401c2f 193 * @param pParams Pointer to Publish Message parameters
peyo 0:cd5404401c2f 194 *
peyo 0:cd5404401c2f 195 * @return An IoT Error Type defining successful/failed publish
peyo 0:cd5404401c2f 196 */
peyo 0:cd5404401c2f 197 static IoT_Error_t _aws_iot_mqtt_internal_publish(AWS_IoT_Client *pClient, const char *pTopicName,
peyo 0:cd5404401c2f 198 uint16_t topicNameLen, IoT_Publish_Message_Params *pParams) {
peyo 0:cd5404401c2f 199 TimerAWS timer;
peyo 0:cd5404401c2f 200 uint32_t len = 0;
peyo 0:cd5404401c2f 201 uint16_t packet_id;
peyo 0:cd5404401c2f 202 unsigned char dup, type;
peyo 0:cd5404401c2f 203 IoT_Error_t rc;
peyo 0:cd5404401c2f 204
peyo 0:cd5404401c2f 205 FUNC_ENTRY;
peyo 0:cd5404401c2f 206
peyo 0:cd5404401c2f 207 init_timer(&timer);
peyo 0:cd5404401c2f 208 countdown_ms(&timer, pClient->clientData.commandTimeoutMs);
peyo 0:cd5404401c2f 209
peyo 0:cd5404401c2f 210 if(QOS1 == pParams->qos) {
peyo 0:cd5404401c2f 211 pParams->id = aws_iot_mqtt_get_next_packet_id(pClient);
peyo 0:cd5404401c2f 212 }
peyo 0:cd5404401c2f 213
peyo 0:cd5404401c2f 214 rc = _aws_iot_mqtt_internal_serialize_publish(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, 0,
peyo 0:cd5404401c2f 215 pParams->qos, pParams->isRetained, pParams->id, pTopicName,
peyo 0:cd5404401c2f 216 topicNameLen, (unsigned char *) pParams->payload,
peyo 0:cd5404401c2f 217 pParams->payloadLen, &len);
peyo 0:cd5404401c2f 218 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 219 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 220 }
peyo 0:cd5404401c2f 221
peyo 0:cd5404401c2f 222 /* send the publish packet */
peyo 0:cd5404401c2f 223 rc = aws_iot_mqtt_internal_send_packet(pClient, len, &timer);
peyo 0:cd5404401c2f 224 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 225 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 226 }
peyo 0:cd5404401c2f 227
peyo 0:cd5404401c2f 228 /* Wait for ack if QoS1 */
peyo 0:cd5404401c2f 229 if(QOS1 == pParams->qos) {
peyo 0:cd5404401c2f 230 rc = aws_iot_mqtt_internal_wait_for_read(pClient, PUBACK, &timer);
peyo 0:cd5404401c2f 231 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 232 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 233 }
peyo 0:cd5404401c2f 234
peyo 0:cd5404401c2f 235 rc = aws_iot_mqtt_internal_deserialize_ack(&type, &dup, &packet_id, pClient->clientData.readBuf,
peyo 0:cd5404401c2f 236 pClient->clientData.readBufSize);
peyo 0:cd5404401c2f 237 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 238 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 239 }
peyo 0:cd5404401c2f 240 }
peyo 0:cd5404401c2f 241
peyo 0:cd5404401c2f 242 FUNC_EXIT_RC(SUCCESS);
peyo 0:cd5404401c2f 243 }
peyo 0:cd5404401c2f 244
peyo 0:cd5404401c2f 245 /**
peyo 0:cd5404401c2f 246 * @brief Publish an MQTT message on a topic
peyo 0:cd5404401c2f 247 *
peyo 0:cd5404401c2f 248 * Called to publish an MQTT message on a topic.
peyo 0:cd5404401c2f 249 * @note Call is blocking. In the case of a QoS 0 message the function returns
peyo 0:cd5404401c2f 250 * after the message was successfully passed to the TLS layer. In the case of QoS 1
peyo 0:cd5404401c2f 251 * the function returns after the receipt of the PUBACK control packet.
peyo 0:cd5404401c2f 252 * This is the outer function which does the validations and calls the internal publish above
peyo 0:cd5404401c2f 253 * to perform the actual operation. It is also responsible for client state changes
peyo 0:cd5404401c2f 254 *
peyo 0:cd5404401c2f 255 * @param pClient Reference to the IoT Client
peyo 0:cd5404401c2f 256 * @param pTopicName Topic Name to publish to
peyo 0:cd5404401c2f 257 * @param topicNameLen Length of the topic name
peyo 0:cd5404401c2f 258 * @param pParams Pointer to Publish Message parameters
peyo 0:cd5404401c2f 259 *
peyo 0:cd5404401c2f 260 * @return An IoT Error Type defining successful/failed publish
peyo 0:cd5404401c2f 261 */
peyo 0:cd5404401c2f 262 IoT_Error_t aws_iot_mqtt_publish(AWS_IoT_Client *pClient, const char *pTopicName, uint16_t topicNameLen,
peyo 0:cd5404401c2f 263 IoT_Publish_Message_Params *pParams) {
peyo 0:cd5404401c2f 264 IoT_Error_t rc, pubRc;
peyo 0:cd5404401c2f 265 ClientState clientState;
peyo 0:cd5404401c2f 266
peyo 0:cd5404401c2f 267 FUNC_ENTRY;
peyo 0:cd5404401c2f 268
peyo 0:cd5404401c2f 269 if(NULL == pClient || NULL == pTopicName || 0 == topicNameLen || NULL == pParams) {
peyo 0:cd5404401c2f 270 FUNC_EXIT_RC(NULL_VALUE_ERROR);
peyo 0:cd5404401c2f 271 }
peyo 0:cd5404401c2f 272
peyo 0:cd5404401c2f 273 if(!aws_iot_mqtt_is_client_connected(pClient)) {
peyo 0:cd5404401c2f 274 FUNC_EXIT_RC(NETWORK_DISCONNECTED_ERROR);
peyo 0:cd5404401c2f 275 }
peyo 0:cd5404401c2f 276
peyo 0:cd5404401c2f 277 clientState = aws_iot_mqtt_get_client_state(pClient);
peyo 0:cd5404401c2f 278 if(CLIENT_STATE_CONNECTED_IDLE != clientState && CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN != clientState) {
peyo 0:cd5404401c2f 279 FUNC_EXIT_RC(MQTT_CLIENT_NOT_IDLE_ERROR);
peyo 0:cd5404401c2f 280 }
peyo 0:cd5404401c2f 281
peyo 0:cd5404401c2f 282 rc = aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS);
peyo 0:cd5404401c2f 283 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 284 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 285 }
peyo 0:cd5404401c2f 286
peyo 0:cd5404401c2f 287 pubRc = _aws_iot_mqtt_internal_publish(pClient, pTopicName, topicNameLen, pParams);
peyo 0:cd5404401c2f 288
peyo 0:cd5404401c2f 289 rc = aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS, clientState);
peyo 0:cd5404401c2f 290 if(SUCCESS == pubRc && SUCCESS != rc) {
peyo 0:cd5404401c2f 291 pubRc = rc;
peyo 0:cd5404401c2f 292 }
peyo 0:cd5404401c2f 293
peyo 0:cd5404401c2f 294 FUNC_EXIT_RC(pubRc);
peyo 0:cd5404401c2f 295 }
peyo 0:cd5404401c2f 296
peyo 0:cd5404401c2f 297 /**
peyo 0:cd5404401c2f 298 * Deserializes the supplied (wire) buffer into publish data
peyo 0:cd5404401c2f 299 * @param dup returned uint8_t - the MQTT dup flag
peyo 0:cd5404401c2f 300 * @param qos returned QoS type - the MQTT QoS value
peyo 0:cd5404401c2f 301 * @param retained returned uint8_t - the MQTT retained flag
peyo 0:cd5404401c2f 302 * @param pPacketId returned uint16_t - the MQTT packet identifier
peyo 0:cd5404401c2f 303 * @param pTopicName returned String - the MQTT topic in the publish
peyo 0:cd5404401c2f 304 * @param topicNameLen returned uint16_t - the length of the MQTT topic in the publish
peyo 0:cd5404401c2f 305 * @param payload returned byte buffer - the MQTT publish payload
peyo 0:cd5404401c2f 306 * @param payloadlen returned size_t - the length of the MQTT payload
peyo 0:cd5404401c2f 307 * @param pRxBuf the raw buffer data, of the correct length determined by the remaining length field
peyo 0:cd5404401c2f 308 * @param rxBufLen the length in bytes of the data in the supplied buffer
peyo 0:cd5404401c2f 309 *
peyo 0:cd5404401c2f 310 * @return An IoT Error Type defining successful/failed call
peyo 0:cd5404401c2f 311 */
peyo 0:cd5404401c2f 312 IoT_Error_t aws_iot_mqtt_internal_deserialize_publish(uint8_t *dup, QoS *qos,
peyo 0:cd5404401c2f 313 uint8_t *retained, uint16_t *pPacketId,
peyo 0:cd5404401c2f 314 char **pTopicName, uint16_t *topicNameLen,
peyo 0:cd5404401c2f 315 unsigned char **payload, size_t *payloadLen,
peyo 0:cd5404401c2f 316 unsigned char *pRxBuf, size_t rxBufLen) {
peyo 0:cd5404401c2f 317 unsigned char *curData = pRxBuf;
peyo 0:cd5404401c2f 318 unsigned char *endData = NULL;
peyo 0:cd5404401c2f 319 IoT_Error_t rc = FAILURE;
peyo 0:cd5404401c2f 320 uint32_t decodedLen = 0;
peyo 0:cd5404401c2f 321 uint32_t readBytesLen = 0;
peyo 0:cd5404401c2f 322 MQTTHeader header = {0};
peyo 0:cd5404401c2f 323
peyo 0:cd5404401c2f 324 FUNC_ENTRY;
peyo 0:cd5404401c2f 325
peyo 0:cd5404401c2f 326 if(NULL == dup || NULL == qos || NULL == retained || NULL == pPacketId) {
peyo 0:cd5404401c2f 327 FUNC_EXIT_RC(FAILURE);
peyo 0:cd5404401c2f 328 }
peyo 0:cd5404401c2f 329
peyo 0:cd5404401c2f 330 /* Publish header size is at least four bytes.
peyo 0:cd5404401c2f 331 * Fixed header is two bytes.
peyo 0:cd5404401c2f 332 * Variable header size depends on QoS And Topic Name.
peyo 0:cd5404401c2f 333 * QoS level 0 doesn't have a message identifier (0 - 2 bytes)
peyo 0:cd5404401c2f 334 * Topic Name length fields decide size of topic name field (at least 2 bytes)
peyo 0:cd5404401c2f 335 * MQTT v3.1.1 Specification 3.3.1 */
peyo 0:cd5404401c2f 336 if(4 > rxBufLen) {
peyo 0:cd5404401c2f 337 FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR);
peyo 0:cd5404401c2f 338 }
peyo 0:cd5404401c2f 339
peyo 0:cd5404401c2f 340 header.byte = aws_iot_mqtt_internal_read_char(&curData);
peyo 0:cd5404401c2f 341 if(PUBLISH != header.bits.type) {
peyo 0:cd5404401c2f 342 FUNC_EXIT_RC(FAILURE);
peyo 0:cd5404401c2f 343 }
peyo 0:cd5404401c2f 344
peyo 0:cd5404401c2f 345 *dup = header.bits.dup;
peyo 0:cd5404401c2f 346 *qos = (QoS) header.bits.qos;
peyo 0:cd5404401c2f 347 *retained = header.bits.retain;
peyo 0:cd5404401c2f 348
peyo 0:cd5404401c2f 349 /* read remaining length */
peyo 0:cd5404401c2f 350 rc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curData, &decodedLen, &readBytesLen);
peyo 0:cd5404401c2f 351 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 352 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 353 return rc;
peyo 0:cd5404401c2f 354 }
peyo 0:cd5404401c2f 355 curData += (readBytesLen);
peyo 0:cd5404401c2f 356 endData = curData + decodedLen;
peyo 0:cd5404401c2f 357
peyo 0:cd5404401c2f 358 /* do we have enough data to read the protocol version byte? */
peyo 0:cd5404401c2f 359 if(SUCCESS != _aws_iot_mqtt_read_string_with_len(pTopicName, topicNameLen, &curData, endData)
peyo 0:cd5404401c2f 360 || (0 > (endData - curData))) {
peyo 0:cd5404401c2f 361 FUNC_EXIT_RC(FAILURE);
peyo 0:cd5404401c2f 362 }
peyo 0:cd5404401c2f 363
peyo 0:cd5404401c2f 364 if(QOS0 != *qos) {
peyo 0:cd5404401c2f 365 *pPacketId = aws_iot_mqtt_internal_read_uint16_t(&curData);
peyo 0:cd5404401c2f 366 }
peyo 0:cd5404401c2f 367
peyo 0:cd5404401c2f 368 *payloadLen = (size_t) (endData - curData);
peyo 0:cd5404401c2f 369 *payload = curData;
peyo 0:cd5404401c2f 370
peyo 0:cd5404401c2f 371 FUNC_EXIT_RC(SUCCESS);
peyo 0:cd5404401c2f 372 }
peyo 0:cd5404401c2f 373
peyo 0:cd5404401c2f 374 /**
peyo 0:cd5404401c2f 375 * Deserializes the supplied (wire) buffer into an ack
peyo 0:cd5404401c2f 376 * @param pPacketType returned integer - the MQTT packet type
peyo 0:cd5404401c2f 377 * @param dup returned integer - the MQTT dup flag
peyo 0:cd5404401c2f 378 * @param pPacketId returned integer - the MQTT packet identifier
peyo 0:cd5404401c2f 379 * @param pRxBuf the raw buffer data, of the correct length determined by the remaining length field
peyo 0:cd5404401c2f 380 * @param rxBuflen the length in bytes of the data in the supplied buffer
peyo 0:cd5404401c2f 381 *
peyo 0:cd5404401c2f 382 * @return An IoT Error Type defining successful/failed call
peyo 0:cd5404401c2f 383 */
peyo 0:cd5404401c2f 384 IoT_Error_t aws_iot_mqtt_internal_deserialize_ack(unsigned char *pPacketType, unsigned char *dup,
peyo 0:cd5404401c2f 385 uint16_t *pPacketId, unsigned char *pRxBuf,
peyo 0:cd5404401c2f 386 size_t rxBuflen) {
peyo 0:cd5404401c2f 387 IoT_Error_t rc = FAILURE;
peyo 0:cd5404401c2f 388 unsigned char *curdata = pRxBuf;
peyo 0:cd5404401c2f 389 unsigned char *enddata = NULL;
peyo 0:cd5404401c2f 390 uint32_t decodedLen = 0;
peyo 0:cd5404401c2f 391 uint32_t readBytesLen = 0;
peyo 0:cd5404401c2f 392 MQTTHeader header = {0};
peyo 0:cd5404401c2f 393
peyo 0:cd5404401c2f 394 FUNC_ENTRY;
peyo 0:cd5404401c2f 395
peyo 0:cd5404401c2f 396 if(NULL == pPacketType || NULL == dup || NULL == pPacketId || NULL == pRxBuf) {
peyo 0:cd5404401c2f 397 FUNC_EXIT_RC(NULL_VALUE_ERROR);
peyo 0:cd5404401c2f 398 }
peyo 0:cd5404401c2f 399
peyo 0:cd5404401c2f 400 /* PUBACK fixed header size is two bytes, variable header is 2 bytes, MQTT v3.1.1 Specification 3.4.1 */
peyo 0:cd5404401c2f 401 if(4 > rxBuflen) {
peyo 0:cd5404401c2f 402 FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR);
peyo 0:cd5404401c2f 403 }
peyo 0:cd5404401c2f 404
peyo 0:cd5404401c2f 405
peyo 0:cd5404401c2f 406 header.byte = aws_iot_mqtt_internal_read_char(&curdata);
peyo 0:cd5404401c2f 407 *dup = header.bits.dup;
peyo 0:cd5404401c2f 408 *pPacketType = header.bits.type;
peyo 0:cd5404401c2f 409
peyo 0:cd5404401c2f 410 /* read remaining length */
peyo 0:cd5404401c2f 411 rc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curdata, &decodedLen, &readBytesLen);
peyo 0:cd5404401c2f 412 if(SUCCESS != rc) {
peyo 0:cd5404401c2f 413 FUNC_EXIT_RC(rc);
peyo 0:cd5404401c2f 414 }
peyo 0:cd5404401c2f 415 curdata += (readBytesLen);
peyo 0:cd5404401c2f 416 enddata = curdata + decodedLen;
peyo 0:cd5404401c2f 417
peyo 0:cd5404401c2f 418 if(enddata - curdata < 2) {
peyo 0:cd5404401c2f 419 FUNC_EXIT_RC(FAILURE);
peyo 0:cd5404401c2f 420 }
peyo 0:cd5404401c2f 421
peyo 0:cd5404401c2f 422 *pPacketId = aws_iot_mqtt_internal_read_uint16_t(&curdata);
peyo 0:cd5404401c2f 423
peyo 0:cd5404401c2f 424 FUNC_EXIT_RC(SUCCESS);
peyo 0:cd5404401c2f 425 }
peyo 0:cd5404401c2f 426
peyo 0:cd5404401c2f 427 #ifdef __cplusplus
peyo 0:cd5404401c2f 428 }
peyo 0:cd5404401c2f 429 #endif