Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of AWS-test by
aws_iot_mqtt_client_connect.cpp
00001 /* 00002 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"). 00005 * You may not use this file except in compliance with the License. 00006 * A copy of the License is located at 00007 * 00008 * http://aws.amazon.com/apache2.0 00009 * 00010 * or in the "license" file accompanying this file. This file is distributed 00011 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 00012 * express or implied. See the License for the specific language governing 00013 * permissions and limitations under the License. 00014 */ 00015 00016 // Based on Eclipse Paho. 00017 /******************************************************************************* 00018 * Copyright (c) 2014 IBM Corp. 00019 * 00020 * All rights reserved. This program and the accompanying materials 00021 * are made available under the terms of the Eclipse Public License v1.0 00022 * and Eclipse Distribution License v1.0 which accompany this distribution. 00023 * 00024 * The Eclipse Public License is available at 00025 * http://www.eclipse.org/legal/epl-v10.html 00026 * and the Eclipse Distribution License is available at 00027 * http://www.eclipse.org/org/documents/edl-v10.php. 00028 * 00029 * Contributors: 00030 * Ian Craggs - initial API and implementation and/or initial documentation 00031 *******************************************************************************/ 00032 00033 /** 00034 * @file aws_iot_mqtt_client_connect.c 00035 * @brief MQTT client connect API definition and related functions 00036 */ 00037 00038 #ifdef __cplusplus 00039 extern "C" { 00040 #endif 00041 00042 #include <aws_iot_mqtt_client.h> 00043 #include "aws_iot_mqtt_client_interface.h" 00044 #include "aws_iot_mqtt_client_common_internal.h" 00045 00046 typedef union { 00047 uint8_t all; /**< all connect flags */ 00048 #if defined(REVERSED) 00049 struct 00050 { 00051 unsigned int username : 1; /**< 3.1 user name */ 00052 unsigned int password : 1; /**< 3.1 password */ 00053 unsigned int willRetain : 1; /**< will retain setting */ 00054 unsigned int willQoS : 2; /**< will QoS value */ 00055 unsigned int will : 1; /**< will flag */ 00056 unsigned int cleansession : 1; /**< clean session flag */ 00057 unsigned int : 1; /**< unused */ 00058 } bits; 00059 #else 00060 struct { 00061 unsigned int : 1; 00062 /**< unused */ 00063 unsigned int cleansession : 1; 00064 /**< cleansession flag */ 00065 unsigned int will : 1; 00066 /**< will flag */ 00067 unsigned int willQoS : 2; 00068 /**< will QoS value */ 00069 unsigned int willRetain : 1; 00070 /**< will retain setting */ 00071 unsigned int password : 1; 00072 /**< 3.1 password */ 00073 unsigned int username : 1; /**< 3.1 user name */ 00074 } bits; 00075 #endif 00076 } MQTT_Connect_Header_Flags; 00077 /**< connect flags byte */ 00078 00079 typedef union { 00080 uint8_t all; /**< all connack flags */ 00081 #if defined(REVERSED) 00082 struct 00083 { 00084 unsigned int sessionpresent : 1; /**< session present flag */ 00085 unsigned int : 7; /**< unused */ 00086 } bits; 00087 #else 00088 struct { 00089 unsigned int : 7; 00090 /**< unused */ 00091 unsigned int sessionpresent : 1; /**< session present flag */ 00092 } bits; 00093 #endif 00094 } MQTT_Connack_Header_Flags; 00095 /**< connack flags byte */ 00096 00097 typedef enum { 00098 CONNACK_CONNECTION_ACCEPTED = 0, 00099 CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR = 1, 00100 CONNACK_IDENTIFIER_REJECTED_ERROR = 2, 00101 CONNACK_SERVER_UNAVAILABLE_ERROR = 3, 00102 CONNACK_BAD_USERDATA_ERROR = 4, 00103 CONNACK_NOT_AUTHORIZED_ERROR = 5 00104 } MQTT_Connack_Return_Codes; /**< Connect request response codes from server */ 00105 00106 00107 /** 00108 * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. 00109 * @param options the options to be used to build the connect packet 00110 * @param the length of buffer needed to contain the serialized version of the packet 00111 * @return IoT_Error_t indicating function execution status 00112 */ 00113 static uint32_t _aws_iot_get_connect_packet_length(IoT_Client_Connect_Params *pConnectParams) { 00114 uint32_t len; 00115 /* Enable when adding further MQTT versions */ 00116 /*size_t len = 0; 00117 switch(pConnectParams->MQTTVersion) { 00118 case MQTT_3_1_1: 00119 len = 10; 00120 break; 00121 }*/ 00122 FUNC_ENTRY; 00123 00124 len = 10; // Len = 10 for MQTT_3_1_1 00125 len = len + pConnectParams->clientIDLen + 2; 00126 00127 if(pConnectParams->isWillMsgPresent) { 00128 len = len + pConnectParams->will.topicNameLen + 2 + pConnectParams->will.msgLen + 2; 00129 } 00130 00131 if(NULL != pConnectParams->pUsername) { 00132 len = len + pConnectParams->usernameLen + 2; 00133 } 00134 00135 if(NULL != pConnectParams->pPassword) { 00136 len = len + pConnectParams->passwordLen + 2; 00137 } 00138 00139 FUNC_EXIT_RC(len); 00140 } 00141 00142 /** 00143 * Serializes the connect options into the buffer. 00144 * @param buf the buffer into which the packet will be serialized 00145 * @param len the length in bytes of the supplied buffer 00146 * @param options the options to be used to build the connect packet 00147 * @param serialized length 00148 * @return IoT_Error_t indicating function execution status 00149 */ 00150 static IoT_Error_t _aws_iot_mqtt_serialize_connect(unsigned char *pTxBuf, size_t txBufLen, 00151 IoT_Client_Connect_Params *pConnectParams, 00152 size_t *pSerializedLen) { 00153 unsigned char *ptr; 00154 uint32_t len; 00155 IoT_Error_t rc; 00156 MQTTHeader header = {0}; 00157 MQTT_Connect_Header_Flags flags = {0}; 00158 00159 FUNC_ENTRY; 00160 00161 if(NULL == pTxBuf || NULL == pConnectParams || NULL == pSerializedLen || 00162 (NULL == pConnectParams->pClientID && 0 != pConnectParams->clientIDLen) || 00163 (NULL != pConnectParams->pClientID && 0 == pConnectParams->clientIDLen)) { 00164 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00165 } 00166 00167 /* Check needed here before we start writing to the Tx buffer */ 00168 switch(pConnectParams->MQTTVersion) { 00169 case MQTT_3_1_1: 00170 break; 00171 default: 00172 return MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; 00173 } 00174 00175 ptr = pTxBuf; 00176 len = _aws_iot_get_connect_packet_length(pConnectParams); 00177 if(aws_iot_mqtt_internal_get_final_packet_length_from_remaining_length(len) > txBufLen) { 00178 FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); 00179 } 00180 00181 rc = aws_iot_mqtt_internal_init_header(&header, CONNECT, QOS0, 0, 0); 00182 if(IOT_SUCCESS != rc) { 00183 FUNC_EXIT_RC(rc); 00184 } 00185 00186 aws_iot_mqtt_internal_write_char(&ptr, header.byte); /* write header */ 00187 00188 ptr += aws_iot_mqtt_internal_write_len_to_buffer(ptr, len); /* write remaining length */ 00189 00190 // Enable if adding support for more versions 00191 //if(MQTT_3_1_1 == pConnectParams->MQTTVersion) { 00192 aws_iot_mqtt_internal_write_utf8_string(&ptr, "MQTT", 4); 00193 aws_iot_mqtt_internal_write_char(&ptr, (unsigned char) pConnectParams->MQTTVersion); 00194 //} 00195 00196 flags.all = 0; 00197 flags.bits.cleansession = (pConnectParams->isCleanSession) ? 1 : 0; 00198 flags.bits.will = (pConnectParams->isWillMsgPresent) ? 1 : 0; 00199 if(flags.bits.will) { 00200 flags.bits.willQoS = pConnectParams->will.qos; 00201 flags.bits.willRetain = (pConnectParams->will.isRetained) ? 1 : 0; 00202 } 00203 00204 if(pConnectParams->pUsername) { 00205 flags.bits.username = 1; 00206 } 00207 00208 if(pConnectParams->pPassword) { 00209 flags.bits.password = 1; 00210 } 00211 00212 aws_iot_mqtt_internal_write_char(&ptr, flags.all); 00213 aws_iot_mqtt_internal_write_uint_16(&ptr, pConnectParams->keepAliveIntervalInSec); 00214 00215 /* If the code have passed the check for incorrect values above, no client id was passed as argument */ 00216 if(NULL == pConnectParams->pClientID) { 00217 aws_iot_mqtt_internal_write_uint_16(&ptr, 0); 00218 } else { 00219 aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pClientID, pConnectParams->clientIDLen); 00220 } 00221 00222 if(pConnectParams->isWillMsgPresent) { 00223 aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pTopicName, 00224 pConnectParams->will.topicNameLen); 00225 aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->will.pMessage, pConnectParams->will.msgLen); 00226 } 00227 00228 if(flags.bits.username) { 00229 aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pUsername, pConnectParams->usernameLen); 00230 } 00231 00232 if(flags.bits.password) { 00233 aws_iot_mqtt_internal_write_utf8_string(&ptr, pConnectParams->pPassword, pConnectParams->passwordLen); 00234 } 00235 00236 *pSerializedLen = (size_t) (ptr - pTxBuf); 00237 00238 FUNC_EXIT_RC(IOT_SUCCESS); 00239 } 00240 00241 /** 00242 * Deserializes the supplied (wire) buffer into connack data - return code 00243 * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) 00244 * @param connack_rc returned integer value of the connack return code 00245 * @param buf the raw buffer data, of the correct length determined by the remaining length field 00246 * @param buflen the length in bytes of the data in the supplied buffer 00247 * @return IoT_Error_t indicating function execution status 00248 */ 00249 static IoT_Error_t _aws_iot_mqtt_deserialize_connack(unsigned char *pSessionPresent, IoT_Error_t *pConnackRc, 00250 unsigned char *pRxBuf, size_t rxBufLen) { 00251 unsigned char *curdata, *enddata; 00252 unsigned char connack_rc_char; 00253 uint32_t decodedLen, readBytesLen; 00254 IoT_Error_t rc; 00255 MQTT_Connack_Header_Flags flags = {0}; 00256 MQTTHeader header = {0}; 00257 00258 FUNC_ENTRY; 00259 00260 if(NULL == pSessionPresent || NULL == pConnackRc || NULL == pRxBuf) { 00261 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00262 } 00263 00264 /* CONNACK header size is fixed at two bytes for fixed and 2 bytes for variable, 00265 * using that as minimum size 00266 * MQTT v3.1.1 Specification 3.2.1 */ 00267 if(4 > rxBufLen) { 00268 FUNC_EXIT_RC(MQTT_RX_BUFFER_TOO_SHORT_ERROR); 00269 } 00270 00271 curdata = pRxBuf; 00272 enddata = NULL; 00273 decodedLen = 0; 00274 readBytesLen = 0; 00275 00276 header.byte = aws_iot_mqtt_internal_read_char(&curdata); 00277 if(CONNACK != header.bits.type) { 00278 FUNC_EXIT_RC(IOT_FAILURE); 00279 } 00280 00281 /* read remaining length */ 00282 rc = aws_iot_mqtt_internal_decode_remaining_length_from_buffer(curdata, &decodedLen, &readBytesLen); 00283 if(IOT_SUCCESS != rc) { 00284 FUNC_EXIT_RC(rc); 00285 } 00286 00287 /* CONNACK remaining length should always be 2 as per MQTT 3.1.1 spec */ 00288 curdata += (readBytesLen); 00289 enddata = curdata + decodedLen; 00290 if(2 != (enddata - curdata)) { 00291 FUNC_EXIT_RC(MQTT_DECODE_REMAINING_LENGTH_ERROR); 00292 } 00293 00294 flags.all = aws_iot_mqtt_internal_read_char(&curdata); 00295 *pSessionPresent = flags.bits.sessionpresent; 00296 connack_rc_char = aws_iot_mqtt_internal_read_char(&curdata); 00297 switch(connack_rc_char) { 00298 case CONNACK_CONNECTION_ACCEPTED: 00299 *pConnackRc = MQTT_CONNACK_CONNECTION_ACCEPTED; 00300 break; 00301 case CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR: 00302 *pConnackRc = MQTT_CONNACK_UNACCEPTABLE_PROTOCOL_VERSION_ERROR; 00303 break; 00304 case CONNACK_IDENTIFIER_REJECTED_ERROR: 00305 *pConnackRc = MQTT_CONNACK_IDENTIFIER_REJECTED_ERROR; 00306 break; 00307 case CONNACK_SERVER_UNAVAILABLE_ERROR: 00308 *pConnackRc = MQTT_CONNACK_SERVER_UNAVAILABLE_ERROR; 00309 break; 00310 case CONNACK_BAD_USERDATA_ERROR: 00311 *pConnackRc = MQTT_CONNACK_BAD_USERDATA_ERROR; 00312 break; 00313 case CONNACK_NOT_AUTHORIZED_ERROR: 00314 *pConnackRc = MQTT_CONNACK_NOT_AUTHORIZED_ERROR; 00315 break; 00316 default: 00317 *pConnackRc = MQTT_CONNACK_UNKNOWN_ERROR; 00318 break; 00319 } 00320 00321 FUNC_EXIT_RC(IOT_SUCCESS); 00322 } 00323 00324 /** 00325 * @brief Check if client state is valid for a connect request 00326 * 00327 * Called to check if client state is valid for a connect request 00328 * @param pClient Reference to the IoT Client 00329 * 00330 * @return bool true = state is valid, false = not valid 00331 */ 00332 static bool _aws_iot_mqtt_is_client_state_valid_for_connect(ClientState clientState) { 00333 bool isValid = false; 00334 00335 switch(clientState) { 00336 case CLIENT_STATE_INVALID: 00337 isValid = false; 00338 break; 00339 case CLIENT_STATE_INITIALIZED: 00340 isValid = true; 00341 break; 00342 case CLIENT_STATE_CONNECTING: 00343 case CLIENT_STATE_CONNECTED_IDLE: 00344 case CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS: 00345 case CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS: 00346 case CLIENT_STATE_CONNECTED_SUBSCRIBE_IN_PROGRESS: 00347 case CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS: 00348 case CLIENT_STATE_CONNECTED_RESUBSCRIBE_IN_PROGRESS: 00349 case CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN: 00350 case CLIENT_STATE_DISCONNECTING: 00351 isValid = false; 00352 break; 00353 case CLIENT_STATE_DISCONNECTED_ERROR: 00354 case CLIENT_STATE_DISCONNECTED_MANUALLY: 00355 case CLIENT_STATE_PENDING_RECONNECT: 00356 isValid = true; 00357 break; 00358 default: 00359 break; 00360 } 00361 00362 return isValid; 00363 } 00364 00365 /** 00366 * @brief MQTT Connection Function 00367 * 00368 * Called to establish an MQTT connection with the AWS IoT Service 00369 * This is the internal function which is called by the connect API to perform the operation. 00370 * Not meant to be called directly as it doesn't do validations or client state changes 00371 * 00372 * @param pClient Reference to the IoT Client 00373 * @param pConnectParams Pointer to MQTT connection parameters 00374 * 00375 * @return An IoT Error Type defining successful/failed connection 00376 */ 00377 static IoT_Error_t _aws_iot_mqtt_internal_connect(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pConnectParams) { 00378 TimerAWS connect_timer; 00379 IoT_Error_t connack_rc = IOT_FAILURE; 00380 char sessionPresent = 0; 00381 size_t len = 0; 00382 IoT_Error_t rc = IOT_FAILURE; 00383 00384 FUNC_ENTRY; 00385 00386 if(NULL != pConnectParams) { 00387 /* override default options if new options were supplied */ 00388 rc = aws_iot_mqtt_set_connect_params(pClient, pConnectParams); 00389 if(IOT_SUCCESS != rc) { 00390 FUNC_EXIT_RC(MQTT_CONNECTION_ERROR); 00391 } 00392 } 00393 00394 rc = pClient->networkStack.connect(&(pClient->networkStack), NULL); 00395 if(IOT_SUCCESS != rc) { 00396 /* TLS Connect failed, return error */ 00397 FUNC_EXIT_RC(rc); 00398 } 00399 00400 init_timer(&connect_timer); 00401 countdown_ms(&connect_timer, pClient->clientData.commandTimeoutMs); 00402 00403 pClient->clientData.keepAliveInterval = pClient->clientData.options.keepAliveIntervalInSec; 00404 rc = _aws_iot_mqtt_serialize_connect(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, 00405 &(pClient->clientData.options), &len); 00406 if(IOT_SUCCESS != rc || 0 >= len) { 00407 FUNC_EXIT_RC(rc); 00408 } 00409 00410 /* send the connect packet */ 00411 rc = aws_iot_mqtt_internal_send_packet(pClient, len, &connect_timer); 00412 if(IOT_SUCCESS != rc) { 00413 FUNC_EXIT_RC(rc); 00414 } 00415 00416 /* this will be a blocking call, wait for the CONNACK */ 00417 rc = aws_iot_mqtt_internal_wait_for_read(pClient, CONNACK, &connect_timer); 00418 if(IOT_SUCCESS != rc) { 00419 FUNC_EXIT_RC(rc); 00420 } 00421 00422 /* Received CONNACK, check the return code */ 00423 rc = _aws_iot_mqtt_deserialize_connack((unsigned char *) &sessionPresent, &connack_rc, pClient->clientData.readBuf, 00424 pClient->clientData.readBufSize); 00425 if(IOT_SUCCESS != rc) { 00426 FUNC_EXIT_RC(rc); 00427 } 00428 00429 if(MQTT_CONNACK_CONNECTION_ACCEPTED != connack_rc) { 00430 FUNC_EXIT_RC(connack_rc); 00431 } 00432 00433 pClient->clientStatus.isPingOutstanding = false; 00434 countdown_sec(&pClient->pingTimer, pClient->clientData.keepAliveInterval); 00435 00436 FUNC_EXIT_RC(IOT_SUCCESS); 00437 } 00438 00439 /** 00440 * @brief MQTT Connection Function 00441 * 00442 * Called to establish an MQTT connection with the AWS IoT Service 00443 * This is the outer function which does the validations and calls the internal connect above 00444 * to perform the actual operation. It is also responsible for client state changes 00445 * 00446 * @param pClient Reference to the IoT Client 00447 * @param pConnectParams Pointer to MQTT connection parameters 00448 * 00449 * @return An IoT Error Type defining successful/failed connection 00450 */ 00451 IoT_Error_t aws_iot_mqtt_connect(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pConnectParams) { 00452 IoT_Error_t rc, disconRc; 00453 ClientState clientState; 00454 00455 FUNC_ENTRY; 00456 00457 if(NULL == pClient) { 00458 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00459 } 00460 00461 clientState = aws_iot_mqtt_get_client_state(pClient); 00462 00463 if(false == _aws_iot_mqtt_is_client_state_valid_for_connect(clientState)) { 00464 /* Don't send connect packet again if we are already connected 00465 * or in the process of connecting/disconnecting */ 00466 FUNC_EXIT_RC(NETWORK_ALREADY_CONNECTED_ERROR); 00467 } 00468 00469 aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_CONNECTING); 00470 00471 rc = _aws_iot_mqtt_internal_connect(pClient, pConnectParams); 00472 00473 if(IOT_SUCCESS != rc) { 00474 pClient->networkStack.disconnect(&(pClient->networkStack)); 00475 disconRc = pClient->networkStack.destroy(&(pClient->networkStack)); 00476 aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTING, CLIENT_STATE_DISCONNECTED_ERROR); 00477 } else { 00478 aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_CONNECTING, CLIENT_STATE_CONNECTED_IDLE); 00479 } 00480 00481 FUNC_EXIT_RC(rc); 00482 } 00483 00484 /** 00485 * @brief Disconnect an MQTT Connection 00486 * 00487 * Called to send a disconnect message to the broker. 00488 * This is the internal function which is called by the disconnect API to perform the operation. 00489 * Not meant to be called directly as it doesn't do validations or client state changes 00490 * 00491 * @param pClient Reference to the IoT Client 00492 * 00493 * @return An IoT Error Type defining successful/failed send of the disconnect control packet. 00494 */ 00495 IoT_Error_t _aws_iot_mqtt_internal_disconnect(AWS_IoT_Client *pClient) { 00496 /* We might wait for incomplete incoming publishes to complete */ 00497 TimerAWS timer; 00498 size_t serialized_len = 0; 00499 IoT_Error_t rc; 00500 00501 FUNC_ENTRY; 00502 00503 rc = aws_iot_mqtt_internal_serialize_zero(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, 00504 DISCONNECT, 00505 &serialized_len); 00506 if(IOT_SUCCESS != rc) { 00507 FUNC_EXIT_RC(rc); 00508 } 00509 00510 init_timer(&timer); 00511 countdown_ms(&timer, pClient->clientData.commandTimeoutMs); 00512 00513 /* send the disconnect packet */ 00514 if(serialized_len > 0) { 00515 rc = aws_iot_mqtt_internal_send_packet(pClient, serialized_len, &timer); 00516 if(IOT_SUCCESS != rc) { 00517 FUNC_EXIT_RC(rc); 00518 } 00519 } 00520 00521 /* Clean network stack */ 00522 pClient->networkStack.disconnect(&(pClient->networkStack)); 00523 rc = pClient->networkStack.destroy(&(pClient->networkStack)); 00524 if(0 != rc) { 00525 /* TLS Destroy failed, return error */ 00526 FUNC_EXIT_RC(IOT_FAILURE); 00527 } 00528 00529 FUNC_EXIT_RC(IOT_SUCCESS); 00530 } 00531 00532 /** 00533 * @brief Disconnect an MQTT Connection 00534 * 00535 * Called to send a disconnect message to the broker. 00536 * This is the outer function which does the validations and calls the internal disconnect above 00537 * to perform the actual operation. It is also responsible for client state changes 00538 * 00539 * @param pClient Reference to the IoT Client 00540 * 00541 * @return An IoT Error Type defining successful/failed send of the disconnect control packet. 00542 */ 00543 IoT_Error_t aws_iot_mqtt_disconnect(AWS_IoT_Client *pClient) { 00544 ClientState clientState; 00545 IoT_Error_t rc; 00546 00547 FUNC_ENTRY; 00548 00549 if(NULL == pClient) { 00550 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00551 } 00552 00553 clientState = aws_iot_mqtt_get_client_state(pClient); 00554 if(!aws_iot_mqtt_is_client_connected(pClient)) { 00555 /* Network is already disconnected. Do nothing */ 00556 FUNC_EXIT_RC(NETWORK_DISCONNECTED_ERROR); 00557 } 00558 00559 rc = aws_iot_mqtt_set_client_state(pClient, clientState, CLIENT_STATE_DISCONNECTING); 00560 if(IOT_SUCCESS != rc) { 00561 FUNC_EXIT_RC(rc); 00562 } 00563 00564 rc = _aws_iot_mqtt_internal_disconnect(pClient); 00565 00566 if(IOT_SUCCESS != rc) { 00567 pClient->clientStatus.clientState = clientState; 00568 } else { 00569 /* If called from Keepalive, this gets set to CLIENT_STATE_DISCONNECTED_ERROR */ 00570 pClient->clientStatus.clientState = CLIENT_STATE_DISCONNECTED_MANUALLY; 00571 } 00572 00573 FUNC_EXIT_RC(rc); 00574 } 00575 00576 /** 00577 * @brief MQTT Manual Re-Connection Function 00578 * 00579 * Called to establish an MQTT connection with the AWS IoT Service 00580 * using parameters from the last time a connection was attempted 00581 * Use after disconnect to start the reconnect process manually 00582 * Makes only one reconnect attempt. Sets the client state to 00583 * pending reconnect in case of failure 00584 * 00585 * @param pClient Reference to the IoT Client 00586 * 00587 * @return An IoT Error Type defining successful/failed connection 00588 */ 00589 IoT_Error_t aws_iot_mqtt_attempt_reconnect(AWS_IoT_Client *pClient) { 00590 IoT_Error_t rc; 00591 00592 FUNC_ENTRY; 00593 00594 if(NULL == pClient) { 00595 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00596 } 00597 00598 if(aws_iot_mqtt_is_client_connected(pClient)) { 00599 FUNC_EXIT_RC(NETWORK_ALREADY_CONNECTED_ERROR); 00600 } 00601 00602 /* Ignoring return code. failures expected if network is disconnected */ 00603 rc = aws_iot_mqtt_connect(pClient, NULL); 00604 00605 /* If still disconnected handle disconnect */ 00606 if(CLIENT_STATE_CONNECTED_IDLE != aws_iot_mqtt_get_client_state(pClient)) { 00607 aws_iot_mqtt_set_client_state(pClient, CLIENT_STATE_DISCONNECTED_ERROR, CLIENT_STATE_PENDING_RECONNECT); 00608 FUNC_EXIT_RC(NETWORK_ATTEMPTING_RECONNECT); 00609 } 00610 00611 rc = aws_iot_mqtt_resubscribe(pClient); 00612 if(IOT_SUCCESS != rc) { 00613 FUNC_EXIT_RC(rc); 00614 } 00615 00616 FUNC_EXIT_RC(NETWORK_RECONNECTED); 00617 } 00618 00619 #ifdef __cplusplus 00620 } 00621 #endif
Generated on Tue Jul 12 2022 11:16:37 by
 1.7.2
 1.7.2 
    