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