/** * @brief MQTT Connection Function * * Called to establish an MQTT connection with the AWS IoT Service * This is the internal function which is called by the connect API to perform the operation. * Not meant to be called directly as it doesn't do validations or client state changes * * @param pClient Reference to the IoT Client * @param pConnectParams Pointer to MQTT connection parameters * * @return An IoT Error Type defining successful/failed connection */ static IoT_Error_t _aws_iot_mqtt_internal_connect(AWS_IoT_Client *pClient, IoT_Client_Connect_Params *pConnectParams) { Timer connect_timer; IoT_Error_t connack_rc = FAILURE; char sessionPresent = 0; size_t len = 0; IoT_Error_t rc = FAILURE; FUNC_ENTRY; if(NULL != pConnectParams) { /* override default options if new options were supplied */ rc = aws_iot_mqtt_set_connect_params(pClient, pConnectParams); if(SUCCESS != rc) { FUNC_EXIT_RC(MQTT_CONNECTION_ERROR); } } rc = pClient->networkStack.connect(&(pClient->networkStack), NULL); if(SUCCESS != rc) { /* TLS Connect failed, return error */ FUNC_EXIT_RC(rc); } init_timer(&connect_timer); countdown_ms(&connect_timer, pClient->clientData.commandTimeoutMs); pClient->clientData.keepAliveInterval = pClient->clientData.options.keepAliveIntervalInSec; rc = _aws_iot_mqtt_serialize_connect(pClient->clientData.writeBuf, pClient->clientData.writeBufSize, &(pClient->clientData.options), &len); if(SUCCESS != rc || 0 >= len) { FUNC_EXIT_RC(rc); } /* send the connect packet */ rc = aws_iot_mqtt_internal_send_packet(pClient, len, &connect_timer); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } /* this will be a blocking call, wait for the CONNACK */ rc = aws_iot_mqtt_internal_wait_for_read(pClient, CONNACK, &connect_timer); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } /* Received CONNACK, check the return code */ rc = _aws_iot_mqtt_deserialize_connack((unsigned char *) &sessionPresent, &connack_rc, pClient->clientData.readBuf, pClient->clientData.readBufSize); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } if(MQTT_CONNACK_CONNECTION_ACCEPTED != connack_rc) { FUNC_EXIT_RC(connack_rc); } pClient->clientStatus.isPingOutstanding = false; countdown_sec(&pClient->pingTimer, pClient->clientData.keepAliveInterval); FUNC_EXIT_RC(SUCCESS); }
IoT_Error_t aws_iot_mqtt_init(AWS_IoT_Client *pClient, IoT_Client_Init_Params *pInitParams) { uint32_t i; IoT_Error_t rc; IoT_Client_Connect_Params default_options = IoT_Client_Connect_Params_initializer; FUNC_ENTRY; if(NULL == pClient || NULL == pInitParams || NULL == pInitParams->pHostURL || 0 == pInitParams->port || NULL == pInitParams->pRootCALocation || NULL == pInitParams->pDevicePrivateKeyLocation || NULL == pInitParams->pDeviceCertLocation) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } for(i = 0; i < AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS; ++i) { pClient->clientData.messageHandlers[i].topicName = NULL; pClient->clientData.messageHandlers[i].pApplicationHandler = NULL; pClient->clientData.messageHandlers[i].pApplicationHandlerData = NULL; pClient->clientData.messageHandlers[i].qos = QOS0; } pClient->clientData.packetTimeoutMs = pInitParams->mqttPacketTimeout_ms; pClient->clientData.commandTimeoutMs = pInitParams->mqttCommandTimeout_ms; pClient->clientData.writeBufSize = AWS_IOT_MQTT_TX_BUF_LEN; pClient->clientData.readBufSize = AWS_IOT_MQTT_RX_BUF_LEN; pClient->clientData.counterNetworkDisconnected = 0; pClient->clientData.disconnectHandler = pInitParams->disconnectHandler; pClient->clientData.disconnectHandlerData = pInitParams->disconnectHandlerData; pClient->clientData.nextPacketId = 1; /* Initialize default connection options */ rc = aws_iot_mqtt_set_connect_params(pClient, &default_options); if(AWS_SUCCESS != rc) { FUNC_EXIT_RC(rc); } #ifdef _ENABLE_THREAD_SUPPORT_ pClient->clientData.isBlockOnThreadLockEnabled = pInitParams->isBlockOnThreadLockEnabled; rc = aws_iot_thread_mutex_init(&(pClient->clientData.state_change_mutex)); if(AWS_SUCCESS != rc) { FUNC_EXIT_RC(rc); } rc = aws_iot_thread_mutex_init(&(pClient->clientData.tls_read_mutex)); if(AWS_SUCCESS != rc) { FUNC_EXIT_RC(rc); } rc = aws_iot_thread_mutex_init(&(pClient->clientData.tls_write_mutex)); if(AWS_SUCCESS != rc) { FUNC_EXIT_RC(rc); } #endif pClient->clientStatus.isPingOutstanding = 0; pClient->clientStatus.isAutoReconnectEnabled = pInitParams->enableAutoReconnect; rc = iot_tls_init(&(pClient->networkStack), pInitParams->pRootCALocation, pInitParams->pDeviceCertLocation, pInitParams->pDevicePrivateKeyLocation, pInitParams->pHostURL, pInitParams->port, pInitParams->tlsHandshakeTimeout_ms, pInitParams->isSSLHostnameVerify); if(AWS_SUCCESS != rc) { pClient->clientStatus.clientState = CLIENT_STATE_INVALID; FUNC_EXIT_RC(rc); } init_timer(&(pClient->pingTimer)); init_timer(&(pClient->reconnectDelayTimer)); pClient->clientStatus.clientState = CLIENT_STATE_INITIALIZED; FUNC_EXIT_RC(AWS_SUCCESS); }