linklayerprotocols/tundriver/te_tundriver/src/te_TcpSslTestEngine.cpp
branchRCL_3
changeset 75 c1029e558ef5
parent 67 bb2423252ea3
child 76 27c54f8619d4
equal deleted inserted replaced
67:bb2423252ea3 75:c1029e558ef5
     1 /*
       
     2  * te_TcpSslTestEngine.cpp
       
     3  *
       
     4  *  Created on: Jan 28, 2010
       
     5  *      Author: GUNAGI
       
     6  */
       
     7 
       
     8 
       
     9 #include "te_TcpSslTestEngine.h"
       
    10 #include <commdbconnpref.h>
       
    11 
       
    12 // Send buffer size
       
    13 const TInt KSendBufferSize = 512;
       
    14 // Receive buffer size
       
    15 const TInt KReceiveBufferSize = 256;
       
    16 // Maximum number of connection attempts
       
    17 const TInt KMaxAttempts = 200;
       
    18 // KYes Size
       
    19 const TInt KYesSize = 3;
       
    20 // KMessage Size
       
    21 const TInt KMessageSize = 35;
       
    22 // KNullDesC Size
       
    23 const TInt KNullDesCSize = 0;
       
    24 // Key header
       
    25 const TInt KeyHeader = 0x400;
       
    26 //const TInt KeyHeader = 0x04;
       
    27 // Delay
       
    28 const TInt KDelay = 100000;
       
    29 
       
    30 _LIT(KYes,"Yes");
       
    31 _LIT(KInputFile, "C:\\t_secdlg_in.dat");
       
    32 _LIT(KOutputFile, "C:\\t_secdlg_out.dat");
       
    33 _LIT(KMessage, "Passphrase of the imported key file");
       
    34 //_LIT(KMessage, "1234");
       
    35 
       
    36 // HTTP messages
       
    37 _LIT8(KSimpleGet, "GET ");
       
    38 _LIT8(KNewLine, "\r\n"); 
       
    39 _LIT8(KHeader, "Connection: close\r\nUser-Agent: SSL_TEST\r\nAccept-Encoding:\r\nAccept: */*");
       
    40 
       
    41 // Progress messages
       
    42 _LIT(KConnnectedMessage, "\nConnecting to %S:%d%S\n");
       
    43 _LIT(KSecureConnnectingMessage, "\nMaking secure connection");
       
    44 _LIT(KGettingPageMessage, "\nRequesting web page");
       
    45 _LIT(KReceivingMessage,"\nReceiving server response");
       
    46 _LIT(KCipherSuiteInUseMessage,"\nCipher suite in use: %S");
       
    47 _LIT(KProtocolMessage, "\nProtocol used in connection: %S");
       
    48 _LIT(KReceivedMessage,"\nReceived server response\n");
       
    49 _LIT(KCompleteMessage,"\nTransaction complete: bytes recieved %d");
       
    50 _LIT(KFileErrorMessage,"\nError in writing data to file");
       
    51 _LIT(KCancelledMessage,"\nConnection closed");
       
    52 _LIT(KFailSocketMessage,"\nFailed to open socket: %d");
       
    53 
       
    54 // State reporting messages
       
    55 _LIT( KStateErrESocketConnected1, "\nError in state connecting socket: %d\n" );
       
    56 _LIT( KStateErrESocketConnected, "\nError in state ESocketConnected: %d\n" );
       
    57 _LIT( KStateErrESettingCiphers, "\nError in state ESettingCiphers: %d\n" );
       
    58 _LIT( KStateErrSecureConnected, "\nError in state ESecureConnected: %d\n" );
       
    59 _LIT( KStateErrGetRequestSent, "\nError in state EGetRequestSent: %d\n" );
       
    60 _LIT( KStateErrEDataReceived, "\nError in state EDataReceived: %d\n" );
       
    61 
       
    62 // Panic code
       
    63 _LIT( KTcpSslEnginePanic, "TCPSSL-ENGINE");
       
    64 
       
    65 //
       
    66 // CTcpSslTestEngine
       
    67 //
       
    68 
       
    69 CTcpSslTestEngine* CTcpSslTestEngine::NewL()
       
    70     {
       
    71     CTcpSslTestEngine* self = new(ELeave) CTcpSslTestEngine;
       
    72     CleanupStack::PushL( self );
       
    73     self->ConstructL();
       
    74     CleanupStack::Pop();        
       
    75     return self;
       
    76     }
       
    77 
       
    78 // Constructor should also call the parent constructor to set the priority
       
    79 // of the active object.
       
    80 CTcpSslTestEngine::CTcpSslTestEngine() 
       
    81 : CActive(0), iSndBuffer(0,0), iRcvBuffer(0,0)
       
    82             {
       
    83             }
       
    84 
       
    85 CTcpSslTestEngine::~CTcpSslTestEngine()
       
    86     {
       
    87     // Cancel any outstanding request- this cleans up
       
    88     // resources created during a connection
       
    89     //Cancel(); 
       
    90     ConnectionClosed();
       
    91     // Clean up engine's permanent resources
       
    92     delete (void*)iSndBuffer.Ptr();
       
    93     delete (void*)iRcvBuffer.Ptr();
       
    94     iTimer.Close();
       
    95     iSocketServ.Close();
       
    96     }
       
    97 
       
    98 void CTcpSslTestEngine::ConstructL()
       
    99     {
       
   100     iSndBuffer.Set((TUint8*)User::AllocL(KSendBufferSize),0,KSendBufferSize);
       
   101     iRcvBuffer.Set((TUint8*)User::AllocL(KReceiveBufferSize),0,KReceiveBufferSize);
       
   102     // Connect the socket server
       
   103     User::LeaveIfError( iSocketServ.Connect()); 
       
   104     // Create a local timer
       
   105     User::LeaveIfError( iTimer.CreateLocal());
       
   106     // Set initial state
       
   107     iRunState = ESocketConnected;
       
   108     iInUse = EFalse;
       
   109 
       
   110     CActiveScheduler::Add( this );
       
   111 
       
   112     }
       
   113 
       
   114 void CTcpSslTestEngine::ConnectL(const TConnectSettings& aConnectSettings)
       
   115     {
       
   116     iConnectSettings = &aConnectSettings;
       
   117 
       
   118     // Set initial values for flags & buffers
       
   119     iSuccess = ETrue;
       
   120     iInUse = ETrue;
       
   121     iRunState = ESocketConnected;
       
   122     iSndBuffer.SetLength( 0 );
       
   123     iRcvBuffer.SetLength( 0 );
       
   124     iTotalBytesRead = 0;
       
   125 
       
   126     TRequestStatus status;
       
   127     RConnection rCon;
       
   128     TInt ret = rCon.Open(iSocketServ);
       
   129     iConsole->Printf(_L("Connection open with = %d\n"), ret);
       
   130 
       
   131     TCommDbConnPref commDbPref;
       
   132     commDbPref.SetIapId(12);
       
   133     commDbPref.SetBearerSet(KCommDbBearerVirtual);
       
   134     commDbPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   135 
       
   136     rCon.Start(commDbPref, status);
       
   137     User::WaitForRequest(status);
       
   138 
       
   139     // Interpret server address
       
   140     if (iInetAddr.Input(iConnectSettings->iAddress) != KErrNone)
       
   141         // Success if already in dotted-decimal format
       
   142         {
       
   143         // Connect to a host resolver (for DNS resolution) - happens sychronously
       
   144         //User::LeaveIfError( iHostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp, rCon ));
       
   145         // Try to resolve symbolic name
       
   146         //TNameEntry nameEntry;
       
   147         //User::LeaveIfError (iHostResolver.GetByName( iConnectSettings->iAddress, nameEntry ));
       
   148         //TSockAddr sockAddr = nameEntry().iAddr;
       
   149         //iInetAddr = iInetAddr.Cast( sockAddr );
       
   150         //iHostResolver.Close();
       
   151         }
       
   152 
       
   153     // Store other connection parameters
       
   154     iInetAddr.SetPort( iConnectSettings->iPortNum );
       
   155 
       
   156     /*   RSocketServ SockServ;
       
   157      SockServ.Connect();
       
   158 
       
   159      TInt err(0);
       
   160      TInt ret = rCon.Open(SockServ);
       
   161      iConsole->Printf(_L("Connection open with = %d\n"), ret);*/
       
   162 
       
   163 
       
   164     // Open a TCP socket
       
   165     ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon );
       
   166 
       
   167     if(ret != KErrNone)
       
   168         {
       
   169         iConsole->Printf(KStateErrESocketConnected1, ret);  
       
   170         }
       
   171     else
       
   172         {
       
   173 
       
   174         User::LeaveIfError(ret);
       
   175         }
       
   176 
       
   177 
       
   178     // Connect to the server, asynchronously
       
   179     iSocket.Connect( iInetAddr, iStatus );  
       
   180     SetActive();
       
   181     CActiveScheduler::Start();
       
   182 
       
   183     // Print status
       
   184     iConsole->Printf(KConnnectedMessage, 
       
   185             &iConnectSettings->iAddress, 
       
   186             iConnectSettings->iPortNum, 
       
   187             &iConnectSettings->iPage ); 
       
   188     }
       
   189 
       
   190 void CTcpSslTestEngine::SetConsole( CConsoleBase& aConsole )
       
   191     {
       
   192     iConsole = &aConsole;
       
   193     }
       
   194 
       
   195 void CTcpSslTestEngine::SetOutputFile( RFile& aOutputFile )
       
   196     {
       
   197     iOutputFile = &aOutputFile;
       
   198     }
       
   199 
       
   200 void CTcpSslTestEngine::Initialize()
       
   201     {
       
   202 
       
   203     }
       
   204 TBool CTcpSslTestEngine::InUse()
       
   205     {
       
   206     return iInUse;
       
   207     }
       
   208 
       
   209 void CTcpSslTestEngine::RunL()
       
   210     {
       
   211     //The Test App that uses the tls module should check the status prior to continuing.
       
   212     //Detailed error checking need to be added in the Test App.
       
   213     if (iStatus.Int() != KErrNone ) 
       
   214         {
       
   215         switch ( iStatus.Int() )
       
   216             {
       
   217             case KErrCouldNotConnect:
       
   218                 {
       
   219                 _LIT( errmsg, "Failed to connect. error code : %d" );
       
   220                 iConsole->Printf(errmsg, iStatus.Int());
       
   221                 //User::Panic(KTcpSslEnginePanic,iStatus.Int());
       
   222                 break;
       
   223                 }
       
   224             default:
       
   225                 {
       
   226                 iRunState =  EConnectionClosed;
       
   227                 _LIT( errmsg, "Error encountered. error code : %d" );
       
   228                 iConsole->Printf(errmsg, iStatus.Int());
       
   229                 break;
       
   230                 }
       
   231             }
       
   232         }
       
   233 
       
   234     switch ( iRunState )
       
   235         {
       
   236         case ESocketConnected:
       
   237             MakePageRequestL();
       
   238             break;
       
   239 
       
   240         case EGetRequestSent:
       
   241             GetServerResponseL();
       
   242             break;
       
   243 
       
   244         case EDataReceived:
       
   245             ReadServerResponseL();
       
   246             break;
       
   247 
       
   248         case EConnectionClosed:
       
   249             ConnectionClosed();
       
   250             break;
       
   251 
       
   252         default:
       
   253             break;
       
   254         } // end switch
       
   255     }
       
   256 
       
   257 TInt CTcpSslTestEngine::RunError( TInt aError )
       
   258     {
       
   259     // Panic prevents looping
       
   260     __ASSERT_ALWAYS(iRunState != EConnectionClosed, 
       
   261             User::Panic(KTcpSslEnginePanic,0));
       
   262 
       
   263     // do a switch on the state to get the right err message
       
   264     switch (iRunState)
       
   265         {
       
   266         case ESocketConnected:
       
   267             iConsole->Printf(KStateErrESocketConnected, aError );
       
   268             break;
       
   269         case ESettingCiphers:
       
   270             iConsole->Printf(KStateErrESettingCiphers, aError );
       
   271             break;
       
   272         case ESecureConnected:
       
   273             iConsole->Printf(KStateErrSecureConnected, aError);
       
   274             break;
       
   275         case EGetRequestSent:
       
   276             iConsole->Printf(KStateErrGetRequestSent, aError);
       
   277             break;
       
   278         case EDataReceived:
       
   279             iConsole->Printf(KStateErrEDataReceived, aError);
       
   280             break;
       
   281         default:
       
   282             break;
       
   283         }
       
   284 
       
   285     iRunState = EConnectionClosed;
       
   286     iSuccess = EFalse;
       
   287     iTimer.After( iStatus, KDelay );
       
   288     SetActive();
       
   289 
       
   290     return KErrNone;
       
   291     }
       
   292 
       
   293 void CTcpSslTestEngine::DoCancel()
       
   294     {
       
   295     iConsole->Printf(KCancelledMessage);
       
   296     ConnectionClosed();
       
   297     }
       
   298 
       
   299 void CTcpSslTestEngine::MakePageRequestL()
       
   300     {
       
   301 
       
   302     // if connection failed, reconnect
       
   303     if(iStatus.Int() != KErrNone)
       
   304         {
       
   305         if(++iCounter >= KMaxAttempts)
       
   306             {
       
   307             User::Leave(iStatus.Int());
       
   308             }
       
   309 
       
   310         iRunState = ESocketConnected;
       
   311         iSocket.CancelAll();
       
   312         iSocket.Close();
       
   313 
       
   314         RConnection rCon;
       
   315         TInt ret = rCon.Open(iSocketServ);
       
   316         iConsole->Printf(_L("Connection open with = %d\n"), ret);
       
   317 
       
   318         TRequestStatus status;
       
   319 
       
   320         TCommDbConnPref commDbPref;
       
   321         commDbPref.SetIapId(12);
       
   322         commDbPref.SetBearerSet(KCommDbBearerVirtual);
       
   323         commDbPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   324 
       
   325         rCon.Start(commDbPref, status);
       
   326         User::WaitForRequest(status);
       
   327         // Open a TCP socket
       
   328         ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon );
       
   329 
       
   330         while(KErrNone != ret)
       
   331             {       
       
   332             iConsole->Printf(KFailSocketMessage, ret);          
       
   333             ret = iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, rCon );
       
   334             }
       
   335 
       
   336 
       
   337         // Connect to the server, asynchronously
       
   338         iSocket.Connect( iInetAddr, iStatus );  
       
   339         SetActive();
       
   340 
       
   341         // Print status
       
   342         iConsole->Printf(KConnnectedMessage, 
       
   343                 &iConnectSettings->iAddress, 
       
   344                 iConnectSettings->iPortNum, 
       
   345                 &iConnectSettings->iPage ); 
       
   346 
       
   347         return;
       
   348         }
       
   349 
       
   350     iCounter = 0;
       
   351     iConsole->Printf(KGettingPageMessage);
       
   352 
       
   353     // Create a GET request 
       
   354     _LIT8(KUrl1, "https://");
       
   355     _LIT8(KUrl2, ":443/index.html HTTP/1.0\r\n");
       
   356     iSndBuffer+=KSimpleGet;
       
   357     iSndBuffer+=KUrl1;
       
   358     iSndBuffer+=hostIpAddress;
       
   359     iSndBuffer+=KUrl2;
       
   360     iSndBuffer+=KNewLine;   
       
   361     iSndBuffer+=KHeader;
       
   362 
       
   363     // Send the request
       
   364     iRunState = EGetRequestSent;
       
   365     iSocket.Send( iSndBuffer, NULL, iStatus, iBytesSent );
       
   366     SetActive();
       
   367     }
       
   368 
       
   369 void CTcpSslTestEngine::GetServerResponseL()       
       
   370     {
       
   371     // The get request has been sent, can now try and receive the data
       
   372     User::LeaveIfError(iStatus.Int());
       
   373     iConsole->Printf(KReceivingMessage);
       
   374 
       
   375     // Read asynchonously-returns when buffer full
       
   376     iRunState = EDataReceived;
       
   377     iSocket.RecvOneOrMore( iRcvBuffer, NULL, iStatus );
       
   378     SetActive();
       
   379     }
       
   380 
       
   381 void CTcpSslTestEngine::ReadServerResponseL()
       
   382     {
       
   383     // Any error other than KErrEof means the test is a failure
       
   384     if (iStatus!=KErrEof) User::LeaveIfError(iStatus.Int());
       
   385     iConsole->Printf(KReceivedMessage);
       
   386     TBuf<512> temp;
       
   387     temp.Copy(iRcvBuffer);
       
   388     iConsole->Printf(temp);
       
   389 
       
   390     // Put the received data in the output file & reset the receive buffer
       
   391     iTotalBytesRead += iRcvBuffer.Length();
       
   392 
       
   393     // Case 1: error is KErrEof (message complete) or no data received, so stop
       
   394     if ( ( iStatus==KErrEof ) || ( iRcvBuffer.Length() == 0 ) )
       
   395         {
       
   396         iConsole->Printf(KCompleteMessage, iTotalBytesRead);
       
   397         // Close the socket neatly
       
   398         iRunState = EConnectionClosed;
       
   399         iTimer.After( iStatus, KDelay );
       
   400         SetActive();
       
   401         return; 
       
   402         }
       
   403 
       
   404     // Case 2: there's more data to get from the server
       
   405     iRcvBuffer.SetLength( 0 );
       
   406     iRunState = EDataReceived;
       
   407     iSocket.RecvOneOrMore( iRcvBuffer, NULL, iStatus );
       
   408     SetActive(); 
       
   409     }
       
   410 
       
   411 void CTcpSslTestEngine::ConnectionClosed()
       
   412     {
       
   413     if (!iInUse) return;
       
   414     // Clean up
       
   415     //iHostResolver.Close();
       
   416     iSocket.CancelAll();
       
   417     iSocket.Close();
       
   418 
       
   419     // Close the output file
       
   420     //iOutputFile->Close();
       
   421 
       
   422     // Wait here for an unload of the ssl.dll to make sure that a session is not
       
   423     // reconnected next time. 
       
   424     User::After( KDelay );
       
   425     iInUse = EFalse;
       
   426     SetActive();
       
   427     CActiveScheduler::Stop();
       
   428     }