Pierre-Marie Ancèle
/
AWS-test
test
aws-iot/src/aws_iot_mqtt_client_connect.cpp@1:3f75eb8d46f4, 2017-04-12 (annotated)
- 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?
User | Revision | Line number | New 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 | *******************************************************************************/ |
peyo |
0:cd5404401c2f | 32 | |
peyo |
0:cd5404401c2f | 33 | /** |
peyo |
0:cd5404401c2f | 34 | * @file aws_iot_mqtt_client_connect.c |
peyo |
0:cd5404401c2f | 35 | * @brief MQTT client connect API definition and related functions |
peyo |
0:cd5404401c2f | 36 | */ |
peyo |
0:cd5404401c2f | 37 | |
peyo |
0:cd5404401c2f | 38 | #ifdef __cplusplus |
peyo |
0:cd5404401c2f | 39 | extern "C" { |
peyo |
0:cd5404401c2f | 40 | #endif |
peyo |
0:cd5404401c2f | 41 | |
peyo |
0:cd5404401c2f | 42 | #include <aws_iot_mqtt_client.h> |
peyo |
0:cd5404401c2f | 43 | #include "aws_iot_mqtt_client_interface.h" |
peyo |
0:cd5404401c2f | 44 | #include "aws_iot_mqtt_client_common_internal.h" |
peyo |
0:cd5404401c2f | 45 | |
peyo |
0:cd5404401c2f | 46 | typedef union { |
peyo |
0:cd5404401c2f | 47 | uint8_t all; /**< all connect flags */ |
peyo |
0:cd5404401c2f | 48 | #if defined(REVERSED) |
peyo |
0:cd5404401c2f | 49 | struct |
peyo |
0:cd5404401c2f | 50 | { |
peyo |
0:cd5404401c2f | 51 | unsigned int username : 1; /**< 3.1 user name */ |
peyo |
0:cd5404401c2f | 52 | unsigned int password : 1; /**< 3.1 password */ |
peyo |
0:cd5404401c2f | 53 | unsigned int willRetain : 1; /**< will retain setting */ |
peyo |
0:cd5404401c2f | 54 | unsigned int willQoS : 2; /**< will QoS value */ |
peyo |
0:cd5404401c2f | 55 | unsigned int will : 1; /**< will flag */ |
peyo |
0:cd5404401c2f | 56 | unsigned int cleansession : 1; /**< clean session flag */ |
peyo |
0:cd5404401c2f | 57 | unsigned int : 1; /**< unused */ |
peyo |
0:cd5404401c2f | 58 | } bits; |
peyo |
0:cd5404401c2f | 59 | #else |
peyo |
0:cd5404401c2f | 60 | struct { |
peyo |
0:cd5404401c2f | 61 | unsigned int : 1; |
peyo |
0:cd5404401c2f | 62 | /**< unused */ |
peyo |
0:cd5404401c2f | 63 | unsigned int cleansession : 1; |
peyo |
0:cd5404401c2f | 64 | /**< cleansession flag */ |
peyo |
0:cd5404401c2f | 65 | unsigned int will : 1; |
peyo |
0:cd5404401c2f | 66 | /**< will flag */ |
peyo |
0:cd5404401c2f | 67 | unsigned int willQoS : 2; |
peyo |
0:cd5404401c2f | 68 | /**< will QoS value */ |
peyo |
0:cd5404401c2f | 69 | unsigned int willRetain : 1; |
peyo |
0:cd5404401c2f | 70 | /**< will retain setting */ |
peyo |
0:cd5404401c2f | 71 | unsigned int password : 1; |
peyo |
0:cd5404401c2f | 72 | /**< 3.1 password */ |
peyo |
0:cd5404401c2f | 73 | unsigned int username : 1; /**< 3.1 user name */ |
peyo |
0:cd5404401c2f | 74 | } bits; |
peyo |
0:cd5404401c2f | 75 | #endif |
peyo |
0:cd5404401c2f | 76 | } MQTT_Connect_Header_Flags; |
peyo |
0:cd5404401c2f | 77 | /**< connect flags byte */ |
peyo |
0:cd5404401c2f | 78 | |
peyo |
0:cd5404401c2f | 79 | typedef union { |
peyo |
0:cd5404401c2f | 80 | uint8_t all; /**< all connack flags */ |
peyo |
0:cd5404401c2f | 81 | #if defined(REVERSED) |
peyo |
0:cd5404401c2f | 82 | struct |
peyo |
0:cd5404401c2f | 83 | { |
peyo |
0:cd5404401c2f | 84 | unsigned int sessionpresent : 1; /**< session present flag */ |
peyo |
0:cd5404401c2f | 85 | unsigned int : 7; /**< unused */ |
peyo |
0:cd5404401c2f | 86 | } bits; |
peyo |
0:cd5404401c2f | 87 | #else |
peyo |
0:cd5404401c2f | 88 | struct { |
peyo |
0:cd5404401c2f | 89 | unsigned int : 7; |
peyo |
0:cd5404401c2f | 90 | /**< unused */ |
peyo |
0:cd5404401c2f | 91 | unsigned int sessionpresent : 1; /**< session present flag */ |
peyo |
0:cd5404401c2f | 92 | } bits; |
peyo |
0:cd5404401c2f | 93 | #endif |
peyo |
0:cd5404401c2f | 94 | } MQTT_Connack_Header_Flags; |
peyo |
0:cd5404401c2f | 95 | /**< connack flags byte */ |
peyo |
0:cd5404401c2f | 96 | |
peyo |
0:cd5404401c2f | 97 | typedef enum { |
peyo |
0:cd5404401c2f | 98 | CONNACK_CONNECTION_ACCEPTED = 0, |
peyo |
0:cd5404401c2f | 99 | CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR = 1, |
peyo |
0:cd5404401c2f | 100 | CONNACK_IDENTIFIER_REJECTED_ERROR = 2, |
peyo |
0:cd5404401c2f | 101 | CONNACK_SERVER_UNAVAILABLE_ERROR = 3, |
peyo |
0:cd5404401c2f | 102 | CONNACK_BAD_USERDATA_ERROR = 4, |
peyo |
0:cd5404401c2f | 103 | CONNACK_NOT_AUTHORIZED_ERROR = 5 |
peyo |
0:cd5404401c2f | 104 | } MQTT_Connack_Return_Codes; /**< Connect request response codes from server */ |
peyo |
0:cd5404401c2f | 105 | |
peyo |
0:cd5404401c2f | 106 | |
peyo |
0:cd5404401c2f | 107 | /** |
peyo |
0:cd5404401c2f | 108 | * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. |
peyo |
0:cd5404401c2f | 109 | * @param options the options to be used to build the connect packet |
peyo |
0:cd5404401c2f | 110 | * @param the length of buffer needed to contain the serialized version of the packet |
peyo |
0:cd5404401c2f | 111 | * @return IoT_Error_t indicating function execution status |
peyo |
0:cd5404401c2f | 112 | */ |
peyo |
0:cd5404401c2f | 113 | static uint32_t _aws_iot_get_connect_packet_length(IoT_Client_Connect_Params *pConnectParams) { |
peyo |
0:cd5404401c2f | 114 | uint32_t len; |
peyo |
0:cd5404401c2f | 115 | /* Enable when adding further MQTT versions */ |
peyo |
0:cd5404401c2f | 116 | /*size_t len = 0; |
peyo |
0:cd5404401c2f | 117 | switch(pConnectParams->MQTTVersion) { |
peyo |
0:cd5404401c2f | 118 | case MQTT_3_1_1: |
peyo |
0:cd5404401c2f | 119 | len = 10; |
peyo |
0:cd5404401c2f | 120 | break; |
peyo |
0:cd5404401c2f | 121 | }*/ |
peyo |
0:cd5404401c2f | 122 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 123 | |
peyo |
0:cd5404401c2f | 124 | len = 10; // Len = 10 for MQTT_3_1_1 |
peyo |
0:cd5404401c2f | 125 | len = len + pConnectParams->clientIDLen + 2; |
peyo |
0:cd5404401c2f | 126 | |
peyo |
0:cd5404401c2f | 127 | if(pConnectParams->isWillMsgPresent) { |
peyo |
0:cd5404401c2f | 128 | len = len + pConnectParams->will.topicNameLen + 2 + pConnectParams->will.msgLen + 2; |
peyo |
0:cd5404401c2f | 129 | } |
peyo |
0:cd5404401c2f | 130 | |
peyo |
0:cd5404401c2f | 131 | if(NULL != pConnectParams->pUsername) { |
peyo |
0:cd5404401c2f | 132 | len = len + pConnectParams->usernameLen + 2; |
peyo |
0:cd5404401c2f | 133 | } |
peyo |
0:cd5404401c2f | 134 | |
peyo |
0:cd5404401c2f | 135 | if(NULL != pConnectParams->pPassword) { |
peyo |
0:cd5404401c2f | 136 | len = len + pConnectParams->passwordLen + 2; |
peyo |
0:cd5404401c2f | 137 | } |
peyo |
0:cd5404401c2f | 138 | |
peyo |
0:cd5404401c2f | 139 | FUNC_EXIT_RC(len); |
peyo |
0:cd5404401c2f | 140 | } |
peyo |
0:cd5404401c2f | 141 | |
peyo |
0:cd5404401c2f | 142 | /** |
peyo |
0:cd5404401c2f | 143 | * Serializes the connect options into the buffer. |
peyo |
0:cd5404401c2f | 144 | * @param buf the buffer into which the packet will be serialized |
peyo |
0:cd5404401c2f | 145 | * @param len the length in bytes of the supplied buffer |
peyo |
0:cd5404401c2f | 146 | * @param options the options to be used to build the connect packet |
peyo |
0:cd5404401c2f | 147 | * @param serialized length |
peyo |
0:cd5404401c2f | 148 | * @return IoT_Error_t indicating function execution status |
peyo |
0:cd5404401c2f | 149 | */ |
peyo |
0:cd5404401c2f | 150 | static IoT_Error_t _aws_iot_mqtt_serialize_connect(unsigned char *pTxBuf, size_t txBufLen, |
peyo |
0:cd5404401c2f | 151 | IoT_Client_Connect_Params *pConnectParams, |
peyo |
0:cd5404401c2f | 152 | size_t *pSerializedLen) { |
peyo |
0:cd5404401c2f | 153 | unsigned char *ptr; |
peyo |
0:cd5404401c2f | 154 | uint32_t len; |
peyo |
0:cd5404401c2f | 155 | IoT_Error_t rc; |
peyo |
0:cd5404401c2f | 156 | MQTTHeader header = {0}; |
peyo |
0:cd5404401c2f | 157 | MQTT_Connect_Header_Flags flags = {0}; |
peyo |
0:cd5404401c2f | 158 | |
peyo |
0:cd5404401c2f | 159 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 160 | |
peyo |
0:cd5404401c2f | 161 | if(NULL == pTxBuf || NULL == pConnectParams || NULL == pSerializedLen || |
peyo |
0:cd5404401c2f | 162 | (NULL == pConnectParams->pClientID && 0 != pConnectParams->clientIDLen) || |
peyo |
0:cd5404401c2f | 163 | (NULL != pConnectParams->pClientID && 0 == pConnectParams->clientIDLen)) { |
peyo |
0:cd5404401c2f | 164 | FUNC_EXIT_RC(NULL_VALUE_ERROR); |
peyo |
0:cd5404401c2f | 165 | } |
peyo |
0:cd5404401c2f | 166 | |
peyo |
0:cd5404401c2f | 167 | /* Check needed here before we start writing to the Tx buffer */ |
peyo |
0:cd5404401c2f | 168 | switch(pConnectParams->MQTTVersion) { |
peyo |
0:cd5404401c2f | 169 | case MQTT_3_1_1: |
peyo |
0:cd5404401c2f | 170 | break; |
peyo |
0:cd5404401c2f | 171 | default: |
peyo |
0:cd5404401c2f | 172 | return MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; |
peyo |
0:cd5404401c2f | 173 | } |
peyo |
0:cd5404401c2f | 174 | |
peyo |
0:cd5404401c2f | 175 | ptr = pTxBuf; |
peyo |
0:cd5404401c2f | 176 | len = _aws_iot_get_connect_packet_length(pConnectParams); |
peyo |
0:cd5404401c2f | 177 | if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(len) > txBufLen) { |
peyo |
0:cd5404401c2f | 178 | FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); |
peyo |
0:cd5404401c2f | 179 | } |
peyo |
0:cd5404401c2f | 180 | |
peyo |
0:cd5404401c2f | 181 | rc = aws_iot_mqtt_internal_init_header(&header, CONNECT, QOS0, 0, 0); |
peyo |
0:cd5404401c2f | 182 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 183 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 184 | } |
peyo |
0:cd5404401c2f | 185 | |
peyo |
0:cd5404401c2f | 186 | aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */ |
peyo |
0:cd5404401c2f | 187 | |
peyo |
0:cd5404401c2f | 188 | ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, len); /* write remaining length */ |
peyo |
0:cd5404401c2f | 189 | |
peyo |
0:cd5404401c2f | 190 | // Enable if adding support for more versions |
peyo |
0:cd5404401c2f | 191 | //if(MQTT_3_1_1 == pConnectParams->MQTTVersion) { |
peyo |
0:cd5404401c2f | 192 | aws_iot_mqtt_internal_write_utf8_string(&ptr, "MQTT", 4); |
peyo |
0:cd5404401c2f | 193 | aws_iot_mqtt_internal_write_char(&ptr, (unsigned char) pConnectParams->MQTTVersion); |
peyo |
0:cd5404401c2f | 194 | //} |
peyo |
0:cd5404401c2f | 195 | |
peyo |
0:cd5404401c2f | 196 | flags.all = 0; |
peyo |
0:cd5404401c2f | 197 | flags.bits.cleansession = (pConnectParams->isCleanSession) ? 1 : 0; |
peyo |
0:cd5404401c2f | 198 | flags.bits.will = (pConnectParams->isWillMsgPresent) ? 1 : 0; |
peyo |
0:cd5404401c2f | 199 | if(flags.bits.will) { |
peyo |
0:cd5404401c2f | 200 | flags.bits.willQoS = pConnectParams->will.qos; |
peyo |
0:cd5404401c2f | 201 | flags.bits.willRetain = (pConnectParams->will.isRetained) ? 1 : 0; |
peyo |
0:cd5404401c2f | 202 | } |
peyo |
0:cd5404401c2f | 203 | |
peyo |
0:cd5404401c2f | 204 | if(pConnectParams->pUsername) { |
peyo |
0:cd5404401c2f | 205 | flags.bits.username = 1; |
peyo |
0:cd5404401c2f | 206 | } |
peyo |
0:cd5404401c2f | 207 | |
peyo |
0:cd5404401c2f | 208 | if(pConnectParams->pPassword) { |
peyo |
0:cd5404401c2f | 209 | flags.bits.password = 1; |
peyo |
0:cd5404401c2f | 210 | } |
peyo |
0:cd5404401c2f | 211 | |
peyo |
0:cd5404401c2f | 212 | aws_iot_mqtt_internal_write_char(&ptr, flags.all); |
peyo |
0:cd5404401c2f | 213 | aws_iot_mqtt_internal_write_uint_16(&ptr, pConnectParams->keepAliveIntervalInSec); |
peyo |
0:cd5404401c2f | 214 | |
peyo |
0:cd5404401c2f | 215 | /* If the code have passed the check for incorrect values above, no client id was passed as argument */ |
peyo |
0:cd5404401c2f | 216 | if(NULL == pConnectParams->pClientID) { |
peyo |
0:cd5404401c2f | 217 | aws_iot_mqtt_internal_write_uint_16(&ptr, 0); |
peyo |
0:cd5404401c2f | 218 | } else { |
peyo |
0:cd5404401c2f | 219 | aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pClientID, pConnectParams->clientIDLen); |
peyo |
0:cd5404401c2f | 220 | } |
peyo |
0:cd5404401c2f | 221 | |
peyo |
0:cd5404401c2f | 222 | if(pConnectParams->isWillMsgPresent) { |
peyo |
0:cd5404401c2f | 223 | aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pTopicName, |
peyo |
0:cd5404401c2f | 224 | pConnectParams->will.topicNameLen); |
peyo |
0:cd5404401c2f | 225 | aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pMessage, pConnectParams->will.msgLen); |
peyo |
0:cd5404401c2f | 226 | } |
peyo |
0:cd5404401c2f | 227 | |
peyo |
0:cd5404401c2f | 228 | if(flags.bits.username) { |
peyo |
0:cd5404401c2f | 229 | aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pUsername, pConnectParams->usernameLen); |
peyo |
0:cd5404401c2f | 230 | } |
peyo |
0:cd5404401c2f | 231 | |
peyo |
0:cd5404401c2f | 232 | if(flags.bits.password) { |
peyo |
0:cd5404401c2f | 233 | aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pPassword, pConnectParams->passwordLen); |
peyo |
0:cd5404401c2f | 234 | } |
peyo |
0:cd5404401c2f | 235 | |
peyo |
0:cd5404401c2f | 236 | *pSerializedLen = (size_t) (ptr - pTxBuf); |
peyo |
0:cd5404401c2f | 237 | |
peyo |
0:cd5404401c2f | 238 | FUNC_EXIT_RC(SUCCESS); |
peyo |
0:cd5404401c2f | 239 | } |
peyo |
0:cd5404401c2f | 240 | |
peyo |
0:cd5404401c2f | 241 | /** |
peyo |
0:cd5404401c2f | 242 | * Deserializes the supplied (wire) buffer into connack data - return code |
peyo |
0:cd5404401c2f | 243 | * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) |
peyo |
0:cd5404401c2f | 244 | * @param connack_rc returned integer value of the connack return code |
peyo |
0:cd5404401c2f | 245 | * @param buf the raw buffer data, of the correct length determined by the remaining length field |
peyo |
0:cd5404401c2f | 246 | * @param buflen the length in bytes of the data in the supplied buffer |
peyo |
0:cd5404401c2f | 247 | * @return IoT_Error_t indicating function execution status |
peyo |
0:cd5404401c2f | 248 | */ |
peyo |
0:cd5404401c2f | 249 | static IoT_Error_t _aws_iot_mqtt_deserialize_connack(unsigned char *pSessionPresent, IoT_Error_t *pConnackRc, |
peyo |
0:cd5404401c2f | 250 | unsigned char *pRxBuf, size_t rxBufLen) { |
peyo |
0:cd5404401c2f | 251 | unsigned char *curdata, *enddata; |
peyo |
0:cd5404401c2f | 252 | unsigned char connack_rc_char; |
peyo |
0:cd5404401c2f | 253 | uint32_t decodedLen, readBytesLen; |
peyo |
0:cd5404401c2f | 254 | IoT_Error_t rc; |
peyo |
0:cd5404401c2f | 255 | MQTT_Connack_Header_Flags flags = {0}; |
peyo |
0:cd5404401c2f | 256 | MQTTHeader header = {0}; |
peyo |
0:cd5404401c2f | 257 | |
peyo |
0:cd5404401c2f | 258 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 259 | |
peyo |
0:cd5404401c2f | 260 | if(NULL == pSessionPresent || NULL == pConnackRc || NULL == pRxBuf) { |
peyo |
0:cd5404401c2f | 261 | FUNC_EXIT_RC(NULL_VALUE_ERROR); |
peyo |
0:cd5404401c2f | 262 | } |
peyo |
0:cd5404401c2f | 263 | |
peyo |
0:cd5404401c2f | 264 | /* CONNACK header size is fixed at two bytes for fixed and 2 bytes for variable, |
peyo |
0:cd5404401c2f | 265 | * using that as minimum size |
peyo |
0:cd5404401c2f | 266 | * MQTT v3.1.1 Specification 3.2.1 */ |
peyo |
0:cd5404401c2f | 267 | if(4 > rxBufLen) { |
peyo |
0:cd5404401c2f | 268 | FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR); |
peyo |
0:cd5404401c2f | 269 | } |
peyo |
0:cd5404401c2f | 270 | |
peyo |
0:cd5404401c2f | 271 | curdata = pRxBuf; |
peyo |
0:cd5404401c2f | 272 | enddata = NULL; |
peyo |
0:cd5404401c2f | 273 | decodedLen = 0; |
peyo |
0:cd5404401c2f | 274 | readBytesLen = 0; |
peyo |
0:cd5404401c2f | 275 | |
peyo |
0:cd5404401c2f | 276 | header.byte = aws_iot_mqtt_internal_read_char(&curdata); |
peyo |
0:cd5404401c2f | 277 | if(CONNACK != header.bits.type) { |
peyo |
0:cd5404401c2f | 278 | FUNC_EXIT_RC(FAILURE); |
peyo |
0:cd5404401c2f | 279 | } |
peyo |
0:cd5404401c2f | 280 | |
peyo |
0:cd5404401c2f | 281 | /* read remaining length */ |
peyo |
0:cd5404401c2f | 282 | rc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curdata, &decodedLen, &readBytesLen); |
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 | /* CONNACK remaining length should always be 2 as per MQTT 3.1.1 spec */ |
peyo |
0:cd5404401c2f | 288 | curdata += (readBytesLen); |
peyo |
0:cd5404401c2f | 289 | enddata = curdata + decodedLen; |
peyo |
0:cd5404401c2f | 290 | if(2 != (enddata - curdata)) { |
peyo |
0:cd5404401c2f | 291 | FUNC_EXIT_RC(MQTT_DECODE_REMAINING_LENGTH_ERROR); |
peyo |
0:cd5404401c2f | 292 | } |
peyo |
0:cd5404401c2f | 293 | |
peyo |
0:cd5404401c2f | 294 | flags.all = aws_iot_mqtt_internal_read_char(&curdata); |
peyo |
0:cd5404401c2f | 295 | *pSessionPresent = flags.bits.sessionpresent; |
peyo |
0:cd5404401c2f | 296 | connack_rc_char = aws_iot_mqtt_internal_read_char(&curdata); |
peyo |
0:cd5404401c2f | 297 | switch(connack_rc_char) { |
peyo |
0:cd5404401c2f | 298 | case CONNACK_CONNECTION_ACCEPTED: |
peyo |
0:cd5404401c2f | 299 | *pConnackRc = MQTT_CONNACK_CONNECTION_ACCEPTED; |
peyo |
0:cd5404401c2f | 300 | break; |
peyo |
0:cd5404401c2f | 301 | case CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR: |
peyo |
0:cd5404401c2f | 302 | *pConnackRc = MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; |
peyo |
0:cd5404401c2f | 303 | break; |
peyo |
0:cd5404401c2f | 304 | case CONNACK_IDENTIFIER_REJECTED_ERROR: |
peyo |
0:cd5404401c2f | 305 | *pConnackRc = MQTT_CONNACK_IDENTIFIER_REJECTED_ERROR; |
peyo |
0:cd5404401c2f | 306 | break; |
peyo |
0:cd5404401c2f | 307 | case CONNACK_SERVER_UNAVAILABLE_ERROR: |
peyo |
0:cd5404401c2f | 308 | *pConnackRc = MQTT_CONNACK_SERVER_UNAVAILABLE_ERROR; |
peyo |
0:cd5404401c2f | 309 | break; |
peyo |
0:cd5404401c2f | 310 | case CONNACK_BAD_USERDATA_ERROR: |
peyo |
0:cd5404401c2f | 311 | *pConnackRc = MQTT_CONNACK_BAD_USERDATA_ERROR; |
peyo |
0:cd5404401c2f | 312 | break; |
peyo |
0:cd5404401c2f | 313 | case CONNACK_NOT_AUTHORIZED_ERROR: |
peyo |
0:cd5404401c2f | 314 | *pConnackRc = MQTT_CONNACK_NOT_AUTHORIZED_ERROR; |
peyo |
0:cd5404401c2f | 315 | break; |
peyo |
0:cd5404401c2f | 316 | default: |
peyo |
0:cd5404401c2f | 317 | *pConnackRc = MQTT_CONNACK_UNKNOWN_ERROR; |
peyo |
0:cd5404401c2f | 318 | break; |
peyo |
0:cd5404401c2f | 319 | } |
peyo |
0:cd5404401c2f | 320 | |
peyo |
0:cd5404401c2f | 321 | FUNC_EXIT_RC(SUCCESS); |
peyo |
0:cd5404401c2f | 322 | } |
peyo |
0:cd5404401c2f | 323 | |
peyo |
0:cd5404401c2f | 324 | /** |
peyo |
0:cd5404401c2f | 325 | * @brief Check if client state is valid for a connect request |
peyo |
0:cd5404401c2f | 326 | * |
peyo |
0:cd5404401c2f | 327 | * Called to check if client state is valid for a connect request |
peyo |
0:cd5404401c2f | 328 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 329 | * |
peyo |
0:cd5404401c2f | 330 | * @return bool true = state is valid, false = not valid |
peyo |
0:cd5404401c2f | 331 | */ |
peyo |
0:cd5404401c2f | 332 | static bool _aws_iot_mqtt_is_client_state_valid_for_connect(ClientState clientState) { |
peyo |
0:cd5404401c2f | 333 | bool isValid = false; |
peyo |
0:cd5404401c2f | 334 | |
peyo |
0:cd5404401c2f | 335 | switch(clientState) { |
peyo |
0:cd5404401c2f | 336 | case CLIENT_STATE_INVALID: |
peyo |
0:cd5404401c2f | 337 | isValid = false; |
peyo |
0:cd5404401c2f | 338 | break; |
peyo |
0:cd5404401c2f | 339 | case CLIENT_STATE_INITIALIZED: |
peyo |
0:cd5404401c2f | 340 | isValid = true; |
peyo |
0:cd5404401c2f | 341 | break; |
peyo |
0:cd5404401c2f | 342 | case CLIENT_STATE_CONNECTING: |
peyo |
0:cd5404401c2f | 343 | case CLIENT_STATE_CONNECTED_IDLE: |
peyo |
0:cd5404401c2f | 344 | case CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS: |
peyo |
0:cd5404401c2f | 345 | case CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS: |
peyo |
0:cd5404401c2f | 346 | case CLIENT_STATE_CONNECTED_SUBSCRIBE_IN_PROGRESS: |
peyo |
0:cd5404401c2f | 347 | case CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS: |
peyo |
0:cd5404401c2f | 348 | case CLIENT_STATE_CONNECTED_RESUBSCRIBE_IN_PROGRESS: |
peyo |
0:cd5404401c2f | 349 | case CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN: |
peyo |
0:cd5404401c2f | 350 | case CLIENT_STATE_DISCONNECTING: |
peyo |
0:cd5404401c2f | 351 | isValid = false; |
peyo |
0:cd5404401c2f | 352 | break; |
peyo |
0:cd5404401c2f | 353 | case CLIENT_STATE_DISCONNECTED_ERROR: |
peyo |
0:cd5404401c2f | 354 | case CLIENT_STATE_DISCONNECTED_MANUALLY: |
peyo |
0:cd5404401c2f | 355 | case CLIENT_STATE_PENDING_RECONNECT: |
peyo |
0:cd5404401c2f | 356 | isValid = true; |
peyo |
0:cd5404401c2f | 357 | break; |
peyo |
0:cd5404401c2f | 358 | default: |
peyo |
0:cd5404401c2f | 359 | break; |
peyo |
0:cd5404401c2f | 360 | } |
peyo |
0:cd5404401c2f | 361 | |
peyo |
0:cd5404401c2f | 362 | return isValid; |
peyo |
0:cd5404401c2f | 363 | } |
peyo |
0:cd5404401c2f | 364 | |
peyo |
0:cd5404401c2f | 365 | /** |
peyo |
0:cd5404401c2f | 366 | * @brief MQTT Connection Function |
peyo |
0:cd5404401c2f | 367 | * |
peyo |
0:cd5404401c2f | 368 | * Called to establish an MQTT connection with the AWS IoT Service |
peyo |
0:cd5404401c2f | 369 | * This is the internal function which is called by the connect API to perform the operation. |
peyo |
0:cd5404401c2f | 370 | * Not meant to be called directly as it doesn't do validations or client state changes |
peyo |
0:cd5404401c2f | 371 | * |
peyo |
0:cd5404401c2f | 372 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 373 | * @param pConnectParams Pointer to MQTT connection parameters |
peyo |
0:cd5404401c2f | 374 | * |
peyo |
0:cd5404401c2f | 375 | * @return An IoT Error Type defining successful/failed connection |
peyo |
0:cd5404401c2f | 376 | */ |
peyo |
0:cd5404401c2f | 377 | static IoT_Error_t _aws_iot_mqtt_internal_connect(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pConnectParams) { |
peyo |
0:cd5404401c2f | 378 | TimerAWS connect_timer; |
peyo |
0:cd5404401c2f | 379 | IoT_Error_t connack_rc = FAILURE; |
peyo |
0:cd5404401c2f | 380 | char sessionPresent = 0; |
peyo |
0:cd5404401c2f | 381 | size_t len = 0; |
peyo |
0:cd5404401c2f | 382 | IoT_Error_t rc = FAILURE; |
peyo |
0:cd5404401c2f | 383 | |
peyo |
0:cd5404401c2f | 384 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 385 | |
peyo |
0:cd5404401c2f | 386 | if(NULL != pConnectParams) { |
peyo |
0:cd5404401c2f | 387 | /* override default options if new options were supplied */ |
peyo |
0:cd5404401c2f | 388 | rc = aws_iot_mqtt_set_connect_params(pClient, pConnectParams); |
peyo |
0:cd5404401c2f | 389 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 390 | FUNC_EXIT_RC(MQTT_CONNECTION_ERROR); |
peyo |
0:cd5404401c2f | 391 | } |
peyo |
0:cd5404401c2f | 392 | } |
peyo |
0:cd5404401c2f | 393 | |
peyo |
0:cd5404401c2f | 394 | rc = pClient->networkStack.connect(&(pClient->networkStack), NULL); |
peyo |
0:cd5404401c2f | 395 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 396 | /* TLS Connect failed, return error */ |
peyo |
0:cd5404401c2f | 397 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 398 | } |
peyo |
0:cd5404401c2f | 399 | |
peyo |
0:cd5404401c2f | 400 | init_timer(&connect_timer); |
peyo |
0:cd5404401c2f | 401 | countdown_ms(&connect_timer, pClient->clientData.commandTimeoutMs); |
peyo |
0:cd5404401c2f | 402 | |
peyo |
0:cd5404401c2f | 403 | pClient->clientData.keepAliveInterval = pClient->clientData.options.keepAliveIntervalInSec; |
peyo |
0:cd5404401c2f | 404 | rc = _aws_iot_mqtt_serialize_connect(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, |
peyo |
0:cd5404401c2f | 405 | &(pClient->clientData.options), &len); |
peyo |
0:cd5404401c2f | 406 | if(SUCCESS != rc || 0 >= len) { |
peyo |
0:cd5404401c2f | 407 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 408 | } |
peyo |
0:cd5404401c2f | 409 | |
peyo |
0:cd5404401c2f | 410 | /* send the connect packet */ |
peyo |
0:cd5404401c2f | 411 | rc = aws_iot_mqtt_internal_send_packet(pClient, len, &connect_timer); |
peyo |
0:cd5404401c2f | 412 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 413 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 414 | } |
peyo |
0:cd5404401c2f | 415 | |
peyo |
0:cd5404401c2f | 416 | /* this will be a blocking call, wait for the CONNACK */ |
peyo |
0:cd5404401c2f | 417 | rc = aws_iot_mqtt_internal_wait_for_read(pClient, CONNACK, &connect_timer); |
peyo |
0:cd5404401c2f | 418 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 419 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 420 | } |
peyo |
0:cd5404401c2f | 421 | |
peyo |
0:cd5404401c2f | 422 | /* Received CONNACK, check the return code */ |
peyo |
0:cd5404401c2f | 423 | rc = _aws_iot_mqtt_deserialize_connack((unsigned char *) &sessionPresent, &connack_rc, pClient->clientData.readBuf, |
peyo |
0:cd5404401c2f | 424 | pClient->clientData.readBufSize); |
peyo |
0:cd5404401c2f | 425 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 426 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 427 | } |
peyo |
0:cd5404401c2f | 428 | |
peyo |
0:cd5404401c2f | 429 | if(MQTT_CONNACK_CONNECTION_ACCEPTED != connack_rc) { |
peyo |
0:cd5404401c2f | 430 | FUNC_EXIT_RC(connack_rc); |
peyo |
0:cd5404401c2f | 431 | } |
peyo |
0:cd5404401c2f | 432 | |
peyo |
0:cd5404401c2f | 433 | pClient->clientStatus.isPingOutstanding = false; |
peyo |
0:cd5404401c2f | 434 | countdown_sec(&pClient->pingTimer, pClient->clientData.keepAliveInterval); |
peyo |
0:cd5404401c2f | 435 | |
peyo |
0:cd5404401c2f | 436 | FUNC_EXIT_RC(SUCCESS); |
peyo |
0:cd5404401c2f | 437 | } |
peyo |
0:cd5404401c2f | 438 | |
peyo |
0:cd5404401c2f | 439 | /** |
peyo |
0:cd5404401c2f | 440 | * @brief MQTT Connection Function |
peyo |
0:cd5404401c2f | 441 | * |
peyo |
0:cd5404401c2f | 442 | * Called to establish an MQTT connection with the AWS IoT Service |
peyo |
0:cd5404401c2f | 443 | * This is the outer function which does the validations and calls the internal connect above |
peyo |
0:cd5404401c2f | 444 | * to perform the actual operation. It is also responsible for client state changes |
peyo |
0:cd5404401c2f | 445 | * |
peyo |
0:cd5404401c2f | 446 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 447 | * @param pConnectParams Pointer to MQTT connection parameters |
peyo |
0:cd5404401c2f | 448 | * |
peyo |
0:cd5404401c2f | 449 | * @return An IoT Error Type defining successful/failed connection |
peyo |
0:cd5404401c2f | 450 | */ |
peyo |
0:cd5404401c2f | 451 | IoT_Error_t aws_iot_mqtt_connect(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pConnectParams) { |
peyo |
0:cd5404401c2f | 452 | IoT_Error_t rc, disconRc; |
peyo |
0:cd5404401c2f | 453 | ClientState clientState; |
peyo |
0:cd5404401c2f | 454 | |
peyo |
0:cd5404401c2f | 455 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 456 | |
peyo |
0:cd5404401c2f | 457 | if(NULL == pClient) { |
peyo |
0:cd5404401c2f | 458 | FUNC_EXIT_RC(NULL_VALUE_ERROR); |
peyo |
0:cd5404401c2f | 459 | } |
peyo |
0:cd5404401c2f | 460 | |
peyo |
0:cd5404401c2f | 461 | clientState = aws_iot_mqtt_get_client_state(pClient); |
peyo |
0:cd5404401c2f | 462 | |
peyo |
0:cd5404401c2f | 463 | if(false == _aws_iot_mqtt_is_client_state_valid_for_connect(clientState)) { |
peyo |
0:cd5404401c2f | 464 | /* Don't send connect packet again if we are already connected |
peyo |
0:cd5404401c2f | 465 | * or in the process of connecting/disconnecting */ |
peyo |
0:cd5404401c2f | 466 | FUNC_EXIT_RC(NETWORK_ALREADY_CONNECTED_ERROR); |
peyo |
0:cd5404401c2f | 467 | } |
peyo |
0:cd5404401c2f | 468 | |
peyo |
0:cd5404401c2f | 469 | aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_CONNECTING); |
peyo |
0:cd5404401c2f | 470 | |
peyo |
0:cd5404401c2f | 471 | rc = _aws_iot_mqtt_internal_connect(pClient, pConnectParams); |
peyo |
0:cd5404401c2f | 472 | |
peyo |
0:cd5404401c2f | 473 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 474 | pClient->networkStack.disconnect(&(pClient->networkStack)); |
peyo |
0:cd5404401c2f | 475 | disconRc = pClient->networkStack.destroy(&(pClient->networkStack)); |
peyo |
0:cd5404401c2f | 476 | aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTING, CLIENT_STATE_DISCONNECTED_ERROR); |
peyo |
0:cd5404401c2f | 477 | } else { |
peyo |
0:cd5404401c2f | 478 | aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTING, CLIENT_STATE_CONNECTED_IDLE); |
peyo |
0:cd5404401c2f | 479 | } |
peyo |
0:cd5404401c2f | 480 | |
peyo |
0:cd5404401c2f | 481 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 482 | } |
peyo |
0:cd5404401c2f | 483 | |
peyo |
0:cd5404401c2f | 484 | /** |
peyo |
0:cd5404401c2f | 485 | * @brief Disconnect an MQTT Connection |
peyo |
0:cd5404401c2f | 486 | * |
peyo |
0:cd5404401c2f | 487 | * Called to send a disconnect message to the broker. |
peyo |
0:cd5404401c2f | 488 | * This is the internal function which is called by the disconnect API to perform the operation. |
peyo |
0:cd5404401c2f | 489 | * Not meant to be called directly as it doesn't do validations or client state changes |
peyo |
0:cd5404401c2f | 490 | * |
peyo |
0:cd5404401c2f | 491 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 492 | * |
peyo |
0:cd5404401c2f | 493 | * @return An IoT Error Type defining successful/failed send of the disconnect control packet. |
peyo |
0:cd5404401c2f | 494 | */ |
peyo |
0:cd5404401c2f | 495 | IoT_Error_t _aws_iot_mqtt_internal_disconnect(AWS_IoT_Client *pClient) { |
peyo |
0:cd5404401c2f | 496 | /* We might wait for incomplete incoming publishes to complete */ |
peyo |
0:cd5404401c2f | 497 | TimerAWS timer; |
peyo |
0:cd5404401c2f | 498 | size_t serialized_len = 0; |
peyo |
0:cd5404401c2f | 499 | IoT_Error_t rc; |
peyo |
0:cd5404401c2f | 500 | |
peyo |
0:cd5404401c2f | 501 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 502 | |
peyo |
0:cd5404401c2f | 503 | rc = aws_iot_mqtt_internal_serialize_zero(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, |
peyo |
0:cd5404401c2f | 504 | DISCONNECT, |
peyo |
0:cd5404401c2f | 505 | &serialized_len); |
peyo |
0:cd5404401c2f | 506 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 507 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 508 | } |
peyo |
0:cd5404401c2f | 509 | |
peyo |
0:cd5404401c2f | 510 | init_timer(&timer); |
peyo |
0:cd5404401c2f | 511 | countdown_ms(&timer, pClient->clientData.commandTimeoutMs); |
peyo |
0:cd5404401c2f | 512 | |
peyo |
0:cd5404401c2f | 513 | /* send the disconnect packet */ |
peyo |
0:cd5404401c2f | 514 | if(serialized_len > 0) { |
peyo |
0:cd5404401c2f | 515 | rc = aws_iot_mqtt_internal_send_packet(pClient, serialized_len, &timer); |
peyo |
0:cd5404401c2f | 516 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 517 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 518 | } |
peyo |
0:cd5404401c2f | 519 | } |
peyo |
0:cd5404401c2f | 520 | |
peyo |
0:cd5404401c2f | 521 | /* Clean network stack */ |
peyo |
0:cd5404401c2f | 522 | pClient->networkStack.disconnect(&(pClient->networkStack)); |
peyo |
0:cd5404401c2f | 523 | rc = pClient->networkStack.destroy(&(pClient->networkStack)); |
peyo |
0:cd5404401c2f | 524 | if(0 != rc) { |
peyo |
0:cd5404401c2f | 525 | /* TLS Destroy failed, return error */ |
peyo |
0:cd5404401c2f | 526 | FUNC_EXIT_RC(FAILURE); |
peyo |
0:cd5404401c2f | 527 | } |
peyo |
0:cd5404401c2f | 528 | |
peyo |
0:cd5404401c2f | 529 | FUNC_EXIT_RC(SUCCESS); |
peyo |
0:cd5404401c2f | 530 | } |
peyo |
0:cd5404401c2f | 531 | |
peyo |
0:cd5404401c2f | 532 | /** |
peyo |
0:cd5404401c2f | 533 | * @brief Disconnect an MQTT Connection |
peyo |
0:cd5404401c2f | 534 | * |
peyo |
0:cd5404401c2f | 535 | * Called to send a disconnect message to the broker. |
peyo |
0:cd5404401c2f | 536 | * This is the outer function which does the validations and calls the internal disconnect above |
peyo |
0:cd5404401c2f | 537 | * to perform the actual operation. It is also responsible for client state changes |
peyo |
0:cd5404401c2f | 538 | * |
peyo |
0:cd5404401c2f | 539 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 540 | * |
peyo |
0:cd5404401c2f | 541 | * @return An IoT Error Type defining successful/failed send of the disconnect control packet. |
peyo |
0:cd5404401c2f | 542 | */ |
peyo |
0:cd5404401c2f | 543 | IoT_Error_t aws_iot_mqtt_disconnect(AWS_IoT_Client *pClient) { |
peyo |
0:cd5404401c2f | 544 | ClientState clientState; |
peyo |
0:cd5404401c2f | 545 | IoT_Error_t rc; |
peyo |
0:cd5404401c2f | 546 | |
peyo |
0:cd5404401c2f | 547 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 548 | |
peyo |
0:cd5404401c2f | 549 | if(NULL == pClient) { |
peyo |
0:cd5404401c2f | 550 | FUNC_EXIT_RC(NULL_VALUE_ERROR); |
peyo |
0:cd5404401c2f | 551 | } |
peyo |
0:cd5404401c2f | 552 | |
peyo |
0:cd5404401c2f | 553 | clientState = aws_iot_mqtt_get_client_state(pClient); |
peyo |
0:cd5404401c2f | 554 | if(!aws_iot_mqtt_is_client_connected(pClient)) { |
peyo |
0:cd5404401c2f | 555 | /* Network is already disconnected. Do nothing */ |
peyo |
0:cd5404401c2f | 556 | FUNC_EXIT_RC(NETWORK_DISCONNECTED_ERROR); |
peyo |
0:cd5404401c2f | 557 | } |
peyo |
0:cd5404401c2f | 558 | |
peyo |
0:cd5404401c2f | 559 | rc = aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_DISCONNECTING); |
peyo |
0:cd5404401c2f | 560 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 561 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 562 | } |
peyo |
0:cd5404401c2f | 563 | |
peyo |
0:cd5404401c2f | 564 | rc = _aws_iot_mqtt_internal_disconnect(pClient); |
peyo |
0:cd5404401c2f | 565 | |
peyo |
0:cd5404401c2f | 566 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 567 | pClient->clientStatus.clientState = clientState; |
peyo |
0:cd5404401c2f | 568 | } else { |
peyo |
0:cd5404401c2f | 569 | /* If called from Keepalive, this gets set to CLIENT_STATE_DISCONNECTED_ERROR */ |
peyo |
0:cd5404401c2f | 570 | pClient->clientStatus.clientState = CLIENT_STATE_DISCONNECTED_MANUALLY; |
peyo |
0:cd5404401c2f | 571 | } |
peyo |
0:cd5404401c2f | 572 | |
peyo |
0:cd5404401c2f | 573 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 574 | } |
peyo |
0:cd5404401c2f | 575 | |
peyo |
0:cd5404401c2f | 576 | /** |
peyo |
0:cd5404401c2f | 577 | * @brief MQTT Manual Re-Connection Function |
peyo |
0:cd5404401c2f | 578 | * |
peyo |
0:cd5404401c2f | 579 | * Called to establish an MQTT connection with the AWS IoT Service |
peyo |
0:cd5404401c2f | 580 | * using parameters from the last time a connection was attempted |
peyo |
0:cd5404401c2f | 581 | * Use after disconnect to start the reconnect process manually |
peyo |
0:cd5404401c2f | 582 | * Makes only one reconnect attempt. Sets the client state to |
peyo |
0:cd5404401c2f | 583 | * pending reconnect in case of failure |
peyo |
0:cd5404401c2f | 584 | * |
peyo |
0:cd5404401c2f | 585 | * @param pClient Reference to the IoT Client |
peyo |
0:cd5404401c2f | 586 | * |
peyo |
0:cd5404401c2f | 587 | * @return An IoT Error Type defining successful/failed connection |
peyo |
0:cd5404401c2f | 588 | */ |
peyo |
0:cd5404401c2f | 589 | IoT_Error_t aws_iot_mqtt_attempt_reconnect(AWS_IoT_Client *pClient) { |
peyo |
0:cd5404401c2f | 590 | IoT_Error_t rc; |
peyo |
0:cd5404401c2f | 591 | |
peyo |
0:cd5404401c2f | 592 | FUNC_ENTRY; |
peyo |
0:cd5404401c2f | 593 | |
peyo |
0:cd5404401c2f | 594 | if(NULL == pClient) { |
peyo |
0:cd5404401c2f | 595 | FUNC_EXIT_RC(NULL_VALUE_ERROR); |
peyo |
0:cd5404401c2f | 596 | } |
peyo |
0:cd5404401c2f | 597 | |
peyo |
0:cd5404401c2f | 598 | if(aws_iot_mqtt_is_client_connected(pClient)) { |
peyo |
0:cd5404401c2f | 599 | FUNC_EXIT_RC(NETWORK_ALREADY_CONNECTED_ERROR); |
peyo |
0:cd5404401c2f | 600 | } |
peyo |
0:cd5404401c2f | 601 | |
peyo |
0:cd5404401c2f | 602 | /* Ignoring return code. failures expected if network is disconnected */ |
peyo |
0:cd5404401c2f | 603 | rc = aws_iot_mqtt_connect(pClient, NULL); |
peyo |
0:cd5404401c2f | 604 | |
peyo |
0:cd5404401c2f | 605 | /* If still disconnected handle disconnect */ |
peyo |
0:cd5404401c2f | 606 | if(CLIENT_STATE_CONNECTED_IDLE != aws_iot_mqtt_get_client_state(pClient)) { |
peyo |
0:cd5404401c2f | 607 | aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_DISCONNECTED_ERROR, CLIENT_STATE_PENDING_RECONNECT); |
peyo |
0:cd5404401c2f | 608 | FUNC_EXIT_RC(NETWORK_ATTEMPTING_RECONNECT); |
peyo |
0:cd5404401c2f | 609 | } |
peyo |
0:cd5404401c2f | 610 | |
peyo |
0:cd5404401c2f | 611 | rc = aws_iot_mqtt_resubscribe(pClient); |
peyo |
0:cd5404401c2f | 612 | if(SUCCESS != rc) { |
peyo |
0:cd5404401c2f | 613 | FUNC_EXIT_RC(rc); |
peyo |
0:cd5404401c2f | 614 | } |
peyo |
0:cd5404401c2f | 615 | |
peyo |
0:cd5404401c2f | 616 | FUNC_EXIT_RC(NETWORK_RECONNECTED); |
peyo |
0:cd5404401c2f | 617 | } |
peyo |
0:cd5404401c2f | 618 | |
peyo |
0:cd5404401c2f | 619 | #ifdef __cplusplus |
peyo |
0:cd5404401c2f | 620 | } |
peyo |
0:cd5404401c2f | 621 | #endif |