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.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 * Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation 00031 *******************************************************************************/ 00032 00033 /** 00034 * @file aws_iot_mqtt_client.c 00035 * @brief MQTT client API definitions 00036 */ 00037 00038 #ifdef __cplusplus 00039 extern "C" { 00040 #endif 00041 00042 #include "aws_iot_log.h" 00043 #include "aws_iot_mqtt_client_interface.h" 00044 00045 #ifdef _ENABLE_THREAD_SUPPORT_ 00046 #include "threads_interface.h" 00047 #endif 00048 00049 const IoT_Client_Init_Params iotClientInitParamsDefault = IoT_Client_Init_Params_initializer; 00050 const IoT_MQTT_Will_Options iotMqttWillOptionsDefault = IoT_MQTT_Will_Options_Initializer; 00051 const IoT_Client_Connect_Params iotClientConnectParamsDefault = IoT_Client_Connect_Params_initializer; 00052 00053 ClientState aws_iot_mqtt_get_client_state(AWS_IoT_Client *pClient) { 00054 FUNC_ENTRY; 00055 if(NULL == pClient) { 00056 return CLIENT_STATE_INVALID; 00057 } 00058 00059 FUNC_EXIT_RC(pClient->clientStatus.clientState); 00060 } 00061 00062 #ifdef _ENABLE_THREAD_SUPPORT_ 00063 IoT_Error_t aws_iot_mqtt_client_lock_mutex(AWS_IoT_Client *pClient, IoT_Mutex_t *pMutex) { 00064 FUNC_ENTRY; 00065 IoT_Error_t threadRc = IOT_FAILURE; 00066 00067 if(NULL == pClient || NULL == pMutex){ 00068 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00069 } 00070 00071 if(false == pClient->clientData.isBlockOnThreadLockEnabled) { 00072 threadRc = aws_iot_thread_mutex_trylock(pMutex); 00073 } else { 00074 threadRc = aws_iot_thread_mutex_lock(pMutex); 00075 /* Should never return Error because the above request blocks until lock is obtained */ 00076 } 00077 00078 if(IOT_SUCCESS != threadRc) { 00079 FUNC_EXIT_RC(threadRc); 00080 } 00081 00082 FUNC_EXIT_RC(IOT_SUCCESS); 00083 } 00084 00085 IoT_Error_t aws_iot_mqtt_client_unlock_mutex(AWS_IoT_Client *pClient, IoT_Mutex_t *pMutex) { 00086 if(NULL == pClient || NULL == pMutex) { 00087 return NULL_VALUE_ERROR; 00088 } 00089 IOT_UNUSED(pClient); 00090 return aws_iot_thread_mutex_unlock(pMutex); 00091 } 00092 #endif 00093 00094 IoT_Error_t aws_iot_mqtt_set_client_state(AWS_IoT_Client *pClient, ClientState expectedCurrentState, 00095 ClientState newState) { 00096 IoT_Error_t rc; 00097 #ifdef _ENABLE_THREAD_SUPPORT_ 00098 IoT_Error_t threadRc = IOT_FAILURE; 00099 #endif 00100 00101 FUNC_ENTRY; 00102 if(NULL == pClient) { 00103 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00104 } 00105 00106 #ifdef _ENABLE_THREAD_SUPPORT_ 00107 rc = aws_iot_mqtt_client_lock_mutex(pClient, &(pClient->clientData.state_change_mutex)); 00108 if(IOT_SUCCESS != rc) { 00109 return rc; 00110 } 00111 #endif 00112 if(expectedCurrentState == aws_iot_mqtt_get_client_state(pClient)) { 00113 pClient->clientStatus.clientState = newState; 00114 rc = IOT_SUCCESS; 00115 } else { 00116 rc = MQTT_UNEXPECTED_CLIENT_STATE_ERROR; 00117 } 00118 00119 #ifdef _ENABLE_THREAD_SUPPORT_ 00120 threadRc = aws_iot_mqtt_client_unlock_mutex(pClient, &(pClient->clientData.state_change_mutex)); 00121 if(IOT_SUCCESS == rc && IOT_SUCCESS != threadRc) { 00122 rc = threadRc; 00123 } 00124 #endif 00125 00126 FUNC_EXIT_RC(rc); 00127 } 00128 00129 IoT_Error_t aws_iot_mqtt_set_connect_params(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pNewConnectParams) { 00130 FUNC_ENTRY; 00131 if(NULL == pClient || NULL == pNewConnectParams) { 00132 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00133 } 00134 00135 pClient->clientData.options.isWillMsgPresent = pNewConnectParams->isWillMsgPresent; 00136 pClient->clientData.options.MQTTVersion = pNewConnectParams->MQTTVersion; 00137 pClient->clientData.options.pClientID = pNewConnectParams->pClientID; 00138 pClient->clientData.options.clientIDLen = pNewConnectParams->clientIDLen; 00139 pClient->clientData.options.pUsername = pNewConnectParams->pUsername; 00140 pClient->clientData.options.usernameLen = pNewConnectParams->usernameLen; 00141 pClient->clientData.options.pPassword = pNewConnectParams->pUsername; 00142 pClient->clientData.options.passwordLen = pNewConnectParams->passwordLen; 00143 pClient->clientData.options.will.pTopicName = pNewConnectParams->will.pTopicName; 00144 pClient->clientData.options.will.topicNameLen = pNewConnectParams->will.topicNameLen; 00145 pClient->clientData.options.will.pMessage = pNewConnectParams->will.pMessage; 00146 pClient->clientData.options.will.msgLen = pNewConnectParams->will.msgLen; 00147 pClient->clientData.options.will.qos = pNewConnectParams->will.qos; 00148 pClient->clientData.options.will.isRetained = pNewConnectParams->will.isRetained; 00149 pClient->clientData.options.keepAliveIntervalInSec = pNewConnectParams->keepAliveIntervalInSec; 00150 pClient->clientData.options.isCleanSession = pNewConnectParams->isCleanSession; 00151 00152 FUNC_EXIT_RC(IOT_SUCCESS); 00153 } 00154 00155 IoT_Error_t aws_iot_mqtt_init(AWS_IoT_Client *pClient, IoT_Client_Init_Params *pInitParams) { 00156 uint32_t i; 00157 IoT_Error_t rc; 00158 IoT_Client_Connect_Params default_options = IoT_Client_Connect_Params_initializer; 00159 00160 FUNC_ENTRY; 00161 00162 if(NULL == pClient || NULL == pInitParams || NULL == pInitParams->pHostURL || 0 == pInitParams->port /*|| 00163 NULL == pInitParams->pRootCALocation || NULL == pInitParams->pDevicePrivateKeyLocation || 00164 NULL == pInitParams->pDeviceCertLocation*/) { 00165 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00166 } 00167 00168 for(i = 0; i < AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS; ++i) { 00169 pClient->clientData.messageHandlers[i].topicName = NULL; 00170 pClient->clientData.messageHandlers[i].pApplicationHandler = NULL; 00171 pClient->clientData.messageHandlers[i].pApplicationHandlerData = NULL; 00172 pClient->clientData.messageHandlers[i].qos = QOS0; 00173 } 00174 00175 pClient->clientData.packetTimeoutMs = pInitParams->mqttPacketTimeout_ms; 00176 pClient->clientData.commandTimeoutMs = pInitParams->mqttCommandTimeout_ms; 00177 pClient->clientData.writeBufSize = AWS_IOT_MQTT_TX_BUF_LEN; 00178 pClient->clientData.readBufSize = AWS_IOT_MQTT_RX_BUF_LEN; 00179 pClient->clientData.counterNetworkDisconnected = 0; 00180 pClient->clientData.disconnectHandler = pInitParams->disconnectHandler; 00181 pClient->clientData.disconnectHandlerData = pInitParams->disconnectHandlerData; 00182 pClient->clientData.nextPacketId = 1; 00183 00184 /* Initialize default connection options */ 00185 rc = aws_iot_mqtt_set_connect_params(pClient, &default_options); 00186 if(IOT_SUCCESS != rc) { 00187 FUNC_EXIT_RC(rc); 00188 } 00189 00190 #ifdef _ENABLE_THREAD_SUPPORT_ 00191 pClient->clientData.isBlockOnThreadLockEnabled = pInitParams->isBlockOnThreadLockEnabled; 00192 rc = aws_iot_thread_mutex_init(&(pClient->clientData.state_change_mutex)); 00193 if(IOT_SUCCESS != rc) { 00194 FUNC_EXIT_RC(rc); 00195 } 00196 rc = aws_iot_thread_mutex_init(&(pClient->clientData.tls_read_mutex)); 00197 if(IOT_SUCCESS != rc) { 00198 FUNC_EXIT_RC(rc); 00199 } 00200 rc = aws_iot_thread_mutex_init(&(pClient->clientData.tls_write_mutex)); 00201 if(IOT_SUCCESS != rc) { 00202 FUNC_EXIT_RC(rc); 00203 } 00204 #endif 00205 00206 pClient->clientStatus.isPingOutstanding = 0; 00207 pClient->clientStatus.isAutoReconnectEnabled = pInitParams->enableAutoReconnect; 00208 00209 rc = iot_tls_init(&(pClient->networkStack), pInitParams->pRootCALocation, pInitParams->pDeviceCertLocation, 00210 pInitParams->pDevicePrivateKeyLocation, pInitParams->pHostURL, pInitParams->port, 00211 pInitParams->tlsHandshakeTimeout_ms, pInitParams->isSSLHostnameVerify); 00212 00213 if(IOT_SUCCESS != rc) { 00214 pClient->clientStatus.clientState = CLIENT_STATE_INVALID; 00215 FUNC_EXIT_RC(rc); 00216 } 00217 00218 init_timer(&(pClient->pingTimer)); 00219 init_timer(&(pClient->reconnectDelayTimer)); 00220 00221 pClient->clientStatus.clientState = CLIENT_STATE_INITIALIZED; 00222 00223 FUNC_EXIT_RC(IOT_SUCCESS); 00224 } 00225 00226 uint16_t aws_iot_mqtt_get_next_packet_id(AWS_IoT_Client *pClient) { 00227 return pClient->clientData.nextPacketId = (uint16_t) ((MAX_PACKET_ID == pClient->clientData.nextPacketId) ? 1 : ( 00228 pClient->clientData.nextPacketId + 1)); 00229 } 00230 00231 bool aws_iot_mqtt_is_client_connected(AWS_IoT_Client *pClient) { 00232 bool isConnected; 00233 00234 FUNC_ENTRY; 00235 00236 if(NULL == pClient) { 00237 IOT_WARN(" Client is null! "); 00238 FUNC_EXIT_RC(false); 00239 } 00240 00241 switch(pClient->clientStatus.clientState) { 00242 case CLIENT_STATE_INVALID: 00243 case CLIENT_STATE_INITIALIZED: 00244 case CLIENT_STATE_CONNECTING: 00245 isConnected = false; 00246 break; 00247 case CLIENT_STATE_CONNECTED_IDLE: 00248 case CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS: 00249 case CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS: 00250 case CLIENT_STATE_CONNECTED_SUBSCRIBE_IN_PROGRESS: 00251 case CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS: 00252 case CLIENT_STATE_CONNECTED_RESUBSCRIBE_IN_PROGRESS: 00253 case CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN: 00254 isConnected = true; 00255 break; 00256 case CLIENT_STATE_DISCONNECTING: 00257 case CLIENT_STATE_DISCONNECTED_ERROR: 00258 case CLIENT_STATE_DISCONNECTED_MANUALLY: 00259 case CLIENT_STATE_PENDING_RECONNECT: 00260 default: 00261 isConnected = false; 00262 break; 00263 } 00264 00265 FUNC_EXIT_RC(isConnected); 00266 } 00267 00268 bool aws_iot_is_autoreconnect_enabled(AWS_IoT_Client *pClient) { 00269 FUNC_ENTRY; 00270 if(NULL == pClient) { 00271 IOT_WARN(" Client is null! "); 00272 FUNC_EXIT_RC(false); 00273 } 00274 00275 FUNC_EXIT_RC(pClient->clientStatus.isAutoReconnectEnabled); 00276 } 00277 00278 IoT_Error_t aws_iot_mqtt_autoreconnect_set_status(AWS_IoT_Client *pClient, bool newStatus) { 00279 FUNC_ENTRY; 00280 if(NULL == pClient) { 00281 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00282 } 00283 pClient->clientStatus.isAutoReconnectEnabled = newStatus; 00284 FUNC_EXIT_RC(IOT_SUCCESS); 00285 } 00286 00287 IoT_Error_t aws_iot_mqtt_set_disconnect_handler(AWS_IoT_Client *pClient, iot_disconnect_handler pDisconnectHandler, 00288 void *pDisconnectHandlerData) { 00289 FUNC_ENTRY; 00290 if(NULL == pClient || NULL == pDisconnectHandler) { 00291 FUNC_EXIT_RC(NULL_VALUE_ERROR); 00292 } 00293 00294 pClient->clientData.disconnectHandler = pDisconnectHandler; 00295 pClient->clientData.disconnectHandlerData = pDisconnectHandlerData; 00296 FUNC_EXIT_RC(IOT_SUCCESS); 00297 } 00298 00299 uint32_t aws_iot_mqtt_get_network_disconnected_count(AWS_IoT_Client *pClient) { 00300 return pClient->clientData.counterNetworkDisconnected; 00301 } 00302 00303 void aws_iot_mqtt_reset_network_disconnected_count(AWS_IoT_Client *pClient) { 00304 pClient->clientData.counterNetworkDisconnected = 0; 00305 } 00306 00307 #ifdef __cplusplus 00308 } 00309 #endif 00310
Generated on Tue Jul 12 2022 11:16:37 by
