Jeon byungchul
/
aws-iot-example
this is fork and i will modify for STM32
Fork of AWS-test by
Embed:
(wiki syntax)
Show/hide line numbers
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