IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params)
{
	if (pNetwork == NULL)
		return NULL_VALUE_ERROR;

	IoT_Error_t ret_val = AWS_FAILURE;

	if (params != NULL) {
		Populate_ConnectParams(pNetwork, params->pRootCALocation,
				       params->pDeviceCertLocation,
				       params->pDevicePrivateKeyLocation,
				       params->pDestinationURL,
				       params->DestinationPort,
				       params->timeout_ms,
				       params->ServerVerificationFlag);
	}

	pNetwork->my_socket = Create_TCPSocket();
	if (-1 == pNetwork->my_socket) {
		ret_val = TCP_CONNECTION_ERROR;
		return ret_val;
	}

	ret_val = Connect_TCPSocket(pNetwork->my_socket,
				    pNetwork->tlsConnectParams.pDestinationURL,
				    pNetwork->tlsConnectParams.DestinationPort);
	if (AWS_SUCCESS != ret_val) {
		Close_TCPSocket(&pNetwork->my_socket);
		return ret_val;
	}
	tls_cfg.flags = TLS_USE_CLIENT_CERT;
	tls_cfg.tls.client.client_cert = (unsigned char *)
		pNetwork->tlsConnectParams.pDeviceCertLocation;
	tls_cfg.tls.client.client_cert_size =
		strlen(pNetwork->tlsConnectParams.pDeviceCertLocation);
	tls_cfg.tls.client.client_key = (unsigned char *)
		pNetwork->tlsConnectParams.pDevicePrivateKeyLocation;
	tls_cfg.tls.client.client_key_size =
		strlen(pNetwork->tlsConnectParams.pDevicePrivateKeyLocation);
	tls_cfg.tls.client.ca_cert =
		(unsigned char *)pNetwork->tlsConnectParams.pRootCALocation;
	tls_cfg.tls.client.ca_cert_size =
		strlen(pNetwork->tlsConnectParams.pRootCALocation);

	ret_val = tls_session_init(&tls_handle, pNetwork->my_socket, &tls_cfg);
	if (AWS_SUCCESS != ret_val)
		Close_TCPSocket(&pNetwork->my_socket);
	return ret_val;
}
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params)
{
	if (pNetwork == NULL)
		return NULL_VALUE_ERROR;

	IoT_Error_t ret_val = AWS_FAILURE;

	if (params != NULL) {
		Populate_ConnectParams(pNetwork, params->pRootCALocation,
				       params->pDeviceCertLocation,
				       params->pDevicePrivateKeyLocation,
				       params->pDestinationURL,
				       params->DestinationPort,
				       params->timeout_ms,
				       params->ServerVerificationFlag);
	}

	pNetwork->my_socket = Create_TCPSocket();
	if (-1 == pNetwork->my_socket) {
		ret_val = TCP_CONNECTION_ERROR;
		return ret_val;
	}

	ret_val = Connect_TCPSocket(pNetwork->my_socket,
				    pNetwork->tlsConnectParams.pDestinationURL,
				    pNetwork->tlsConnectParams.DestinationPort);
	if (AWS_SUCCESS != ret_val) {
		Close_TCPSocket(&pNetwork->my_socket);
		return ret_val;
	}
	memset(&tls_hd, 0, sizeof(tls_hd));
	ret_val = wm_tls_client_open(&tls_hd,
	 (wm_tls_cert_t *) pNetwork->tlsConnectParams.pRootCALocation,
	 (wm_tls_cert_t *) pNetwork->tlsConnectParams.pDeviceCertLocation,
	 (wm_tls_key_t *) pNetwork->tlsConnectParams.pDevicePrivateKeyLocation,
	 pNetwork->my_socket);
	if (ret_val != WM_SUCCESS)
		goto out;

	return WM_SUCCESS;
out:
	wm_tls_client_close(&tls_hd);
	Close_TCPSocket(&pNetwork->my_socket);
	return -WM_FAIL;

}
int iot_tls_connect(Network *pNetwork, TLSConnectParams params) {

	IoT_Error_t ret_val = NONE_ERROR;
	int connect_status = 0;

	server_TCPSocket = Create_TCPSocket();
	if(-1 == server_TCPSocket){
		ret_val = TCP_SETUP_ERROR;
		return ret_val;
	}

	if (!SSL_CTX_load_verify_locations(pSSLContext, params.pRootCALocation, NULL)) {
		ERROR(" Root CA Loading error");
		ret_val = SSL_CERT_ERROR;
	}

	if (!SSL_CTX_use_certificate_file(pSSLContext, params.pDeviceCertLocation, SSL_FILETYPE_PEM)) {
		ERROR(" Device Certificate Loading error");
		ret_val = SSL_CERT_ERROR;
	}

	if(1 != SSL_CTX_use_PrivateKey_file(pSSLContext, params.pDevicePrivateKeyLocation, SSL_FILETYPE_PEM)){
		ERROR(" Device Private Key Loading error");
		ret_val = SSL_CERT_ERROR;
	}
	if(params.ServerVerificationFlag){
		SSL_CTX_set_verify(pSSLContext, SSL_VERIFY_PEER, tls_server_certificate_verify);
	}
	else{
		SSL_CTX_set_verify(pSSLContext, SSL_VERIFY_PEER, NULL);
	}

	pSSLHandle = SSL_new(pSSLContext);

	pDestinationURL = params.pDestinationURL;
	ret_val = Connect_TCPSocket(server_TCPSocket, params.pDestinationURL, params.DestinationPort);
	if(NONE_ERROR != ret_val){
		ERROR(" TCP Connection error");
		return ret_val;
	}

	SSL_set_fd(pSSLHandle, server_TCPSocket);

	if(ret_val == NONE_ERROR){
		ret_val = setSocketToNonBlocking(server_TCPSocket);
		if(ret_val != NONE_ERROR){
			ERROR(" Unable to set the socket to Non-Blocking");
		}
	}

	if(NONE_ERROR == ret_val){
		ret_val = ConnectOrTimeoutOrExitOnError(pSSLHandle, params.timeout_ms);
		if(X509_V_OK != SSL_get_verify_result(pSSLHandle)){
			ERROR(" Server Certificate Verification failed");
			ret_val = SSL_CONNECT_ERROR;
		}
		else{
			// ensure you have a valid certificate returned, otherwise no certificate exchange happened
			if(NULL == SSL_get_peer_certificate(pSSLHandle)){
				ERROR(" No certificate exchange happened");
				ret_val = SSL_CONNECT_ERROR;
			}
		}
	}
	return ret_val;
}