diff -r 8d540f55e491 -r 425d8f4f7fa5 linklayerprotocols/tundriver/te_tundriver/src/te_TcpSslTestEngine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linklayerprotocols/tundriver/te_tundriver/src/te_TcpSslTestEngine.cpp Wed Sep 15 00:18:51 2010 +0300 @@ -0,0 +1,428 @@ +/* + * te_TcpSslTestEngine.cpp + * + * Created on: Jan 28, 2010 + * Author: GUNAGI + */ + + +#include "te_TcpSslTestEngine.h" +#include + +// Send buffer size +const TInt KSendBufferSize = 512; +// Receive buffer size +const TInt KReceiveBufferSize = 256; +// Maximum number of connection attempts +const TInt KMaxAttempts = 200; +// KYes Size +const TInt KYesSize = 3; +// KMessage Size +const TInt KMessageSize = 35; +// KNullDesC Size +const TInt KNullDesCSize = 0; +// Key header +const TInt KeyHeader = 0x400; +//const TInt KeyHeader = 0x04; +// Delay +const TInt KDelay = 100000; + +_LIT(KYes,"Yes"); +_LIT(KInputFile, "C:\\t_secdlg_in.dat"); +_LIT(KOutputFile, "C:\\t_secdlg_out.dat"); +_LIT(KMessage, "Passphrase of the imported key file"); +//_LIT(KMessage, "1234"); + +// HTTP messages +_LIT8(KSimpleGet, "GET "); +_LIT8(KNewLine, "\r\n"); +_LIT8(KHeader, "Connection: close\r\nUser-Agent: SSL_TEST\r\nAccept-Encoding:\r\nAccept: */*"); + +// Progress messages +_LIT(KConnnectedMessage, "\nConnecting to %S:%d%S\n"); +_LIT(KSecureConnnectingMessage, "\nMaking secure connection"); +_LIT(KGettingPageMessage, "\nRequesting web page"); +_LIT(KReceivingMessage,"\nReceiving server response"); +_LIT(KCipherSuiteInUseMessage,"\nCipher suite in use: %S"); +_LIT(KProtocolMessage, "\nProtocol used in connection: %S"); +_LIT(KReceivedMessage,"\nReceived server response\n"); +_LIT(KCompleteMessage,"\nTransaction complete: bytes recieved %d"); +_LIT(KFileErrorMessage,"\nError in writing data to file"); +_LIT(KCancelledMessage,"\nConnection closed"); +_LIT(KFailSocketMessage,"\nFailed to open socket: %d"); + +// State reporting messages +_LIT( KStateErrESocketConnected1, "\nError in state connecting socket: %d\n" ); +_LIT( KStateErrESocketConnected, "\nError in state ESocketConnected: %d\n" ); +_LIT( KStateErrESettingCiphers, "\nError in state ESettingCiphers: %d\n" ); +_LIT( KStateErrSecureConnected, "\nError in state ESecureConnected: %d\n" ); +_LIT( KStateErrGetRequestSent, "\nError in state EGetRequestSent: %d\n" ); +_LIT( KStateErrEDataReceived, "\nError in state EDataReceived: %d\n" ); + +// Panic code +_LIT( KTcpSslEnginePanic, "TCPSSL-ENGINE"); + +// +// CTcpSslTestEngine +// + +CTcpSslTestEngine* CTcpSslTestEngine::NewL() + { + CTcpSslTestEngine* self = new(ELeave) CTcpSslTestEngine; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Constructor should also call the parent constructor to set the priority +// of the active object. +CTcpSslTestEngine::CTcpSslTestEngine() +: CActive(0), iSndBuffer(0,0), iRcvBuffer(0,0) + { + } + +CTcpSslTestEngine::~CTcpSslTestEngine() + { + // Cancel any outstanding request- this cleans up + // resources created during a connection + //Cancel(); + ConnectionClosed(); + // Clean up engine's permanent resources + delete (void*)iSndBuffer.Ptr(); + delete (void*)iRcvBuffer.Ptr(); + iTimer.Close(); + iSocketServ.Close(); + } + +void CTcpSslTestEngine::ConstructL() + { + iSndBuffer.Set((TUint8*)User::AllocL(KSendBufferSize),0,KSendBufferSize); + iRcvBuffer.Set((TUint8*)User::AllocL(KReceiveBufferSize),0,KReceiveBufferSize); + // Connect the socket server + User::LeaveIfError( iSocketServ.Connect()); + // Create a local timer + User::LeaveIfError( iTimer.CreateLocal()); + // Set initial state + iRunState = ESocketConnected; + iInUse = EFalse; + + CActiveScheduler::Add( this ); + + } + +void CTcpSslTestEngine::ConnectL(const TConnectSettings& aConnectSettings) + { + iConnectSettings = &aConnectSettings; + + // Set initial values for flags & buffers + iSuccess = ETrue; + iInUse = ETrue; + iRunState = ESocketConnected; + iSndBuffer.SetLength( 0 ); + iRcvBuffer.SetLength( 0 ); + iTotalBytesRead = 0; + + TRequestStatus status; + RConnection rCon; + TInt ret = rCon.Open(iSocketServ); + iConsole->Printf(_L("Connection open with = %d\n"), ret); + + TCommDbConnPref commDbPref; + commDbPref.SetIapId(12); + commDbPref.SetBearerSet(KCommDbBearerVirtual); + commDbPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); + + rCon.Start(commDbPref, status); + User::WaitForRequest(status); + + // Interpret server address + if (iInetAddr.Input(iConnectSettings->iAddress) != KErrNone) + // Success if already in dotted-decimal format + { + // Connect to a host resolver (for DNS resolution) - happens sychronously + //User::LeaveIfError( iHostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp, rCon )); + // Try to resolve symbolic name + //TNameEntry nameEntry; + //User::LeaveIfError (iHostResolver.GetByName( iConnectSettings->iAddress, nameEntry )); + //TSockAddr sockAddr = nameEntry().iAddr; + //iInetAddr = iInetAddr.Cast( sockAddr ); + //iHostResolver.Close(); + } + + // Store other connection parameters + iInetAddr.SetPort( iConnectSettings->iPortNum ); + + /* RSocketServ SockServ; + SockServ.Connect(); + + TInt err(0); + TInt ret = rCon.Open(SockServ); + iConsole->Printf(_L("Connection open with = %d\n"), ret);*/ + + + // Open a TCP socket + ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon ); + + if(ret != KErrNone) + { + iConsole->Printf(KStateErrESocketConnected1, ret); + } + else + { + + User::LeaveIfError(ret); + } + + + // Connect to the server, asynchronously + iSocket.Connect( iInetAddr, iStatus ); + SetActive(); + CActiveScheduler::Start(); + + // Print status + iConsole->Printf(KConnnectedMessage, + &iConnectSettings->iAddress, + iConnectSettings->iPortNum, + &iConnectSettings->iPage ); + } + +void CTcpSslTestEngine::SetConsole( CConsoleBase& aConsole ) + { + iConsole = &aConsole; + } + +void CTcpSslTestEngine::SetOutputFile( RFile& aOutputFile ) + { + iOutputFile = &aOutputFile; + } + +void CTcpSslTestEngine::Initialize() + { + + } +TBool CTcpSslTestEngine::InUse() + { + return iInUse; + } + +void CTcpSslTestEngine::RunL() + { + //The Test App that uses the tls module should check the status prior to continuing. + //Detailed error checking need to be added in the Test App. + if (iStatus.Int() != KErrNone ) + { + switch ( iStatus.Int() ) + { + case KErrCouldNotConnect: + { + _LIT( errmsg, "Failed to connect. error code : %d" ); + iConsole->Printf(errmsg, iStatus.Int()); + //User::Panic(KTcpSslEnginePanic,iStatus.Int()); + break; + } + default: + { + iRunState = EConnectionClosed; + _LIT( errmsg, "Error encountered. error code : %d" ); + iConsole->Printf(errmsg, iStatus.Int()); + break; + } + } + } + + switch ( iRunState ) + { + case ESocketConnected: + MakePageRequestL(); + break; + + case EGetRequestSent: + GetServerResponseL(); + break; + + case EDataReceived: + ReadServerResponseL(); + break; + + case EConnectionClosed: + ConnectionClosed(); + break; + + default: + break; + } // end switch + } + +TInt CTcpSslTestEngine::RunError( TInt aError ) + { + // Panic prevents looping + __ASSERT_ALWAYS(iRunState != EConnectionClosed, + User::Panic(KTcpSslEnginePanic,0)); + + // do a switch on the state to get the right err message + switch (iRunState) + { + case ESocketConnected: + iConsole->Printf(KStateErrESocketConnected, aError ); + break; + case ESettingCiphers: + iConsole->Printf(KStateErrESettingCiphers, aError ); + break; + case ESecureConnected: + iConsole->Printf(KStateErrSecureConnected, aError); + break; + case EGetRequestSent: + iConsole->Printf(KStateErrGetRequestSent, aError); + break; + case EDataReceived: + iConsole->Printf(KStateErrEDataReceived, aError); + break; + default: + break; + } + + iRunState = EConnectionClosed; + iSuccess = EFalse; + iTimer.After( iStatus, KDelay ); + SetActive(); + + return KErrNone; + } + +void CTcpSslTestEngine::DoCancel() + { + iConsole->Printf(KCancelledMessage); + ConnectionClosed(); + } + +void CTcpSslTestEngine::MakePageRequestL() + { + + // if connection failed, reconnect + if(iStatus.Int() != KErrNone) + { + if(++iCounter >= KMaxAttempts) + { + User::Leave(iStatus.Int()); + } + + iRunState = ESocketConnected; + iSocket.CancelAll(); + iSocket.Close(); + + RConnection rCon; + TInt ret = rCon.Open(iSocketServ); + iConsole->Printf(_L("Connection open with = %d\n"), ret); + + TRequestStatus status; + + TCommDbConnPref commDbPref; + commDbPref.SetIapId(12); + commDbPref.SetBearerSet(KCommDbBearerVirtual); + commDbPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt); + + rCon.Start(commDbPref, status); + User::WaitForRequest(status); + // Open a TCP socket + ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon ); + + while(KErrNone != ret) + { + iConsole->Printf(KFailSocketMessage, ret); + ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon ); + } + + + // Connect to the server, asynchronously + iSocket.Connect( iInetAddr, iStatus ); + SetActive(); + + // Print status + iConsole->Printf(KConnnectedMessage, + &iConnectSettings->iAddress, + iConnectSettings->iPortNum, + &iConnectSettings->iPage ); + + return; + } + + iCounter = 0; + iConsole->Printf(KGettingPageMessage); + + // Create a GET request + _LIT8(KUrl1, "https://"); + _LIT8(KUrl2, ":443/index.html HTTP/1.0\r\n"); + iSndBuffer+=KSimpleGet; + iSndBuffer+=KUrl1; + iSndBuffer+=hostIpAddress; + iSndBuffer+=KUrl2; + iSndBuffer+=KNewLine; + iSndBuffer+=KHeader; + + // Send the request + iRunState = EGetRequestSent; + iSocket.Send( iSndBuffer, NULL, iStatus, iBytesSent ); + SetActive(); + } + +void CTcpSslTestEngine::GetServerResponseL() + { + // The get request has been sent, can now try and receive the data + User::LeaveIfError(iStatus.Int()); + iConsole->Printf(KReceivingMessage); + + // Read asynchonously-returns when buffer full + iRunState = EDataReceived; + iSocket.RecvOneOrMore( iRcvBuffer, NULL, iStatus ); + SetActive(); + } + +void CTcpSslTestEngine::ReadServerResponseL() + { + // Any error other than KErrEof means the test is a failure + if (iStatus!=KErrEof) User::LeaveIfError(iStatus.Int()); + iConsole->Printf(KReceivedMessage); + TBuf<512> temp; + temp.Copy(iRcvBuffer); + iConsole->Printf(temp); + + // Put the received data in the output file & reset the receive buffer + iTotalBytesRead += iRcvBuffer.Length(); + + // Case 1: error is KErrEof (message complete) or no data received, so stop + if ( ( iStatus==KErrEof ) || ( iRcvBuffer.Length() == 0 ) ) + { + iConsole->Printf(KCompleteMessage, iTotalBytesRead); + // Close the socket neatly + iRunState = EConnectionClosed; + iTimer.After( iStatus, KDelay ); + SetActive(); + return; + } + + // Case 2: there's more data to get from the server + iRcvBuffer.SetLength( 0 ); + iRunState = EDataReceived; + iSocket.RecvOneOrMore( iRcvBuffer, NULL, iStatus ); + SetActive(); + } + +void CTcpSslTestEngine::ConnectionClosed() + { + if (!iInUse) return; + // Clean up + //iHostResolver.Close(); + iSocket.CancelAll(); + iSocket.Close(); + + // Close the output file + //iOutputFile->Close(); + + // Wait here for an unload of the ssl.dll to make sure that a session is not + // reconnected next time. + User::After( KDelay ); + iInUse = EFalse; + SetActive(); + CActiveScheduler::Stop(); + }