this is fork and i will modify for STM32

Fork of AWS-test by Pierre-Marie Ancèle

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aws_iot_mqtt_client.cpp Source File

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