IMPSengine/ImpsIpCirWatcher/ImpsTcpIpCirWatcher/src/TcpCirWatcher.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Tcp CirWatcher
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <ecom/ecom.h>
       
    22 #include <f32file.h>
       
    23 #ifdef _DEBUG
       
    24 #include <flogger.h>
       
    25 #endif
       
    26 #include <msgconnmanagerapi.h>
       
    27 #include <msgbearerObscallback.h>
       
    28 #include "TcpCirWatcher.h"
       
    29 #include "CirWatcherDefines.h"
       
    30 #include "TcpCirWatcherTimer.h"
       
    31 
       
    32 // ================= MEMBER FUNCTIONS =======================
       
    33 //
       
    34 
       
    35 
       
    36 // ----------------------------------------------------------
       
    37 // CTcpCirWatcher::CTcpCirWatcher
       
    38 //
       
    39 // ----------------------------------------------------------
       
    40 //
       
    41 CTcpCirWatcher::CTcpCirWatcher( const TInt aPingInterval,
       
    42                                 MImpsCirReceiver& aCirReceiver,
       
    43                                 MMsgConnManager& aConnManager ) :
       
    44         iPingInterval( aPingInterval ),
       
    45         iCirReceiver( aCirReceiver ),
       
    46         iConnectionManager( aConnManager ),
       
    47         iClientRequestPending( EFalse ),
       
    48         iWatcherStatus( EImpsCIRWatcherIdle ),
       
    49         iLastGoodWatcherStatus( EImpsCIRWatcherUnknown )
       
    50 
       
    51     {
       
    52     }
       
    53 
       
    54 // ----------------------------------------------------------
       
    55 // CTcpCirWatcher::FinishConstructL
       
    56 //
       
    57 // ----------------------------------------------------------
       
    58 //
       
    59 CTcpCirWatcher* CTcpCirWatcher::NewL( TTcpWatcherParameters* aParameters )
       
    60     {
       
    61     CTcpCirWatcher* self = new ( ELeave ) CTcpCirWatcher( aParameters->iPingInterval,
       
    62                                                           aParameters->iCirReceiver,
       
    63                                                           aParameters->iConnManager );
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop();
       
    67     return self;
       
    68     }
       
    69 
       
    70 // ----------------------------------------------------------
       
    71 // CImpsConnectionMonitor::ConstructL
       
    72 //
       
    73 // ----------------------------------------------------------
       
    74 //
       
    75 void CTcpCirWatcher::ConstructL()
       
    76     {
       
    77 #ifdef _DEBUG
       
    78     DeleteLogFileL();
       
    79 #endif
       
    80     iWatcherTimer = CTcpCirWatcherTimer::NewL( this );
       
    81     CActiveScheduler::Add( this );
       
    82     }
       
    83 
       
    84 // ----------------------------------------------------
       
    85 // CTcpCirWatcher::~CTcpCirWatcher
       
    86 // Destructor
       
    87 // ----------------------------------------------------
       
    88 //
       
    89 CTcpCirWatcher::~CTcpCirWatcher()
       
    90     {
       
    91 #ifdef _DEBUG
       
    92     WriteToLog( _L8( "CTcpCirWatcher::~CTcpCirWatcher()" ) );
       
    93 #endif
       
    94     Cancel();
       
    95     delete iPacket;
       
    96     delete iWatcherTimer;
       
    97     delete iCSPSessionID;
       
    98     delete iSocketSendBuffer;
       
    99     delete iAddressBuffer;
       
   100     iTCPCIRSocket.Close();
       
   101 #ifdef _DEBUG
       
   102     WriteToLog( _L8( "  Destructor ended" ) );
       
   103 #endif
       
   104     }
       
   105 
       
   106 // ----------------------------------------------------------
       
   107 // CTcpCirWatcher::DeleteLogFileL()
       
   108 //
       
   109 // ----------------------------------------------------------
       
   110 //
       
   111 void CTcpCirWatcher::DeleteLogFileL()
       
   112     {
       
   113     RFs session;
       
   114     User::LeaveIfError( session.Connect() );
       
   115     CFileMan* manager = CFileMan::NewL( session );
       
   116     manager->Delete( _L( "C:\\Logs\\ImpsTcpWatcher\\*.*" ) );
       
   117     session.Close();
       
   118     delete manager;
       
   119     manager = NULL;
       
   120     }
       
   121 
       
   122 // ----------------------------------------------------
       
   123 // CTcpCirWatcher::SetPingInterval
       
   124 //
       
   125 // ----------------------------------------------------
       
   126 //
       
   127 void CTcpCirWatcher::SetPingInterval( const TInt aPingInterval )
       
   128     {
       
   129 #ifdef _DEBUG
       
   130     WriteToLog( _L8( "CTcpCirWatcher::SetPingInterval()  Interval: %d" ), aPingInterval );
       
   131 #endif
       
   132     if ( aPingInterval > 0 )
       
   133         iPingInterval = aPingInterval;
       
   134     }
       
   135 
       
   136 // ----------------------------------------------------
       
   137 // CTcpCirWatcher::StartTCPWatcherL
       
   138 //
       
   139 // ----------------------------------------------------
       
   140 //
       
   141 void CTcpCirWatcher::StartTCPWatcherL( TRequestStatus& aStatus,
       
   142                                        const TUint aServerPort,
       
   143                                        const TDesC& aServerAddress,
       
   144                                        const TDesC8& aCSPSessionID )
       
   145     {
       
   146 #ifdef _DEBUG
       
   147     HBufC8* id = HBufC8::NewL( aCSPSessionID.Length() );
       
   148     TPtr8 idPtr( id->Des() );
       
   149     idPtr.Copy( aCSPSessionID );
       
   150     TBuf8<200> eightBuf;
       
   151     eightBuf.Copy( aServerAddress );
       
   152     WriteToLog( _L8( "CTcpCirWatcher::StartTCPWatcher()" ) );
       
   153     WriteToLog( _L8( "  Server:     %S" ), &eightBuf );
       
   154     WriteToLog( _L8( "  Port:       %d" ), aServerPort );
       
   155     WriteToLog( _L8( "  Session ID: %S" ), &idPtr );
       
   156     delete id;
       
   157     id = NULL;
       
   158 #endif
       
   159     aStatus = KRequestPending;
       
   160     iClientStatus = &aStatus;
       
   161     if ( iWatcherStatus == EImpsCIRWatcherIdle )
       
   162         {
       
   163         Reset();
       
   164         SetConnectionDetailsL( aServerAddress, aCSPSessionID, aServerPort );
       
   165         if ( iConnectionManager.Status() )
       
   166             {
       
   167             iClientRequestPending = ETrue;
       
   168             iConnectionManager.AddEventSubscriberL( this );
       
   169             //Might be DNS name, must make sure we get an IP address
       
   170             User::LeaveIfError( iHostResolver.Open( iConnectionManager.SocketSession(),
       
   171                                                     KAfInet, KProtocolInetUdp,
       
   172                                                     iConnectionManager.Connection() ) );
       
   173             iHostResolver.GetByName( *iAddressBuffer, iHostAddressDnsEntry, iStatus );
       
   174             iWatcherStatus = EImpsCIRWatcherAwaitingDNS;
       
   175             SetActive();
       
   176 #ifdef _DEBUG
       
   177             WriteToLog( _L8( "  Waiting for host resolver to complete" ) );
       
   178 #endif
       
   179             }
       
   180         else
       
   181             {
       
   182 #ifdef _DEBUG
       
   183             WriteToLog( _L8( "  Bearer is not ready, complete with KErrCouldNotConnect." ) );
       
   184 #endif
       
   185             User::RequestComplete( iClientStatus, KErrCouldNotConnect );
       
   186             }
       
   187         }
       
   188     else
       
   189         {
       
   190 #ifdef _DEBUG
       
   191         WriteToLog( _L8( "  Watcher is not ready, complete with KErrNotReady." ) );
       
   192 #endif
       
   193         User::RequestComplete( iClientStatus, KErrNotReady );
       
   194         }
       
   195     }
       
   196 
       
   197 // ----------------------------------------------------
       
   198 // CTcpCirWatcher::SetConnectionDetails
       
   199 //
       
   200 // ----------------------------------------------------
       
   201 //
       
   202 void CTcpCirWatcher::SetConnectionDetailsL( const TDesC& aServerAddress,
       
   203                                             const TDesC8& aCSPSessionID,
       
   204                                             const TUint aServerPort )
       
   205     {
       
   206 #ifdef _DEBUG
       
   207     WriteToLog( _L8( "CTcpCirWatcher::SetConnectionDetails" ) );
       
   208 #endif
       
   209     iServerPort = aServerPort;
       
   210     iCSPSessionID = HBufC8::NewL( aCSPSessionID.Length() );
       
   211     iCSPSessionID->Des().Copy( aCSPSessionID );
       
   212     iAddressBuffer = HBufC::NewL( aServerAddress.Length() );
       
   213     iAddressBuffer->Des().Copy( aServerAddress );
       
   214     }
       
   215 
       
   216 
       
   217 // ---------------------------------------------------------
       
   218 // CTcpCirWatcher::Reset
       
   219 //
       
   220 // ---------------------------------------------------------
       
   221 //
       
   222 void CTcpCirWatcher::Reset()
       
   223     {
       
   224 #ifdef _DEBUG
       
   225     WriteToLog( _L8( "CTcpCirWatcher::Reset()" ) );
       
   226 #endif
       
   227     delete iCSPSessionID;
       
   228     iCSPSessionID = NULL;
       
   229     delete iAddressBuffer;
       
   230     iAddressBuffer = NULL;
       
   231     iPingRetries = 0;
       
   232     iConnRetries = 0;
       
   233     }
       
   234 
       
   235 // ----------------------------------------------------
       
   236 // CTcpCirWatcher::StopTCPWatcher
       
   237 // Destructor
       
   238 // ----------------------------------------------------
       
   239 //
       
   240 void CTcpCirWatcher::StopTCPWatcher()
       
   241     {
       
   242 #ifdef _DEBUG
       
   243     WriteToLog( _L8( "StopTCPWatcher()" ) );
       
   244 #endif
       
   245     if ( iWatcherStatus == EImpsCIRWatcherAwaitingDNS )
       
   246         {
       
   247 #ifdef _DEBUG
       
   248         WriteToLog( _L8( "  Status is EImpsCIRWatcherAwaitingDNS, cancel resolver" ) );
       
   249 #endif
       
   250         iHostResolver.Cancel();
       
   251         //If the client requests another start inside the scheduler
       
   252         //loop that completes the previous Start() request, the second
       
   253         //request will fail with KErrNotReady, since this component must
       
   254         //wait for the host resolver to return in RunL(). The method will
       
   255         //alter the state of this component to EImpsCIRWatcherIdle.
       
   256         //iClientRequestPending = EFalse;
       
   257         //iWatcherStatus = EImpsCIRWatcherStopping;
       
   258         //User::RequestComplete( iClientStatus, KErrCancel );
       
   259 #ifdef _DEBUG
       
   260         WriteToLog( _L8( "  Resolver cancelled, request not completed" ) );
       
   261 #endif
       
   262         }
       
   263     else
       
   264         {
       
   265         if ( iWatcherStatus != KImpsCIRWatcherStopping &&
       
   266              iWatcherStatus != EImpsCIRWatcherIdle )
       
   267             {
       
   268             iWatcherTimer->Cancel();
       
   269             if ( iConnectionManager.NumberOfActiveConns() > 0 )
       
   270                 {
       
   271 
       
   272                 // Socket Connection is getting disconnected and closed when Ending the PacketDataConnection
       
   273                 // if active connection is not exists not required to cancel.
       
   274                 iTCPCIRSocket.CancelAll();
       
   275                 }
       
   276             if ( iClientRequestPending &&
       
   277                  ( iWatcherStatus == EImpsCIRWatcherConnectingTCPSocket ||
       
   278                    iWatcherStatus == EImpsCIRWatcherSendingHELOMessage ||
       
   279                    iWatcherStatus == EImpsCIRWatcherReceivingHELOResponse ) )
       
   280                 {
       
   281 #ifdef _DEBUG
       
   282                 WriteToLog( _L8( "  A request is pending, complete with KErrCancel" ) );
       
   283 #endif
       
   284                 User::RequestComplete( iClientStatus, KErrCancel );
       
   285                 iWatcherStatus = EImpsCIRWatcherIdle;
       
   286                 }
       
   287             else
       
   288                 iWatcherStatus = EImpsCIRWatcherStopping;
       
   289             iConnectionManager.RemoveEventSubscriber( this );
       
   290             }
       
   291         else
       
   292             {
       
   293 #ifdef _DEBUG
       
   294             WriteToLog( _L8( "  Status is %d" ), iWatcherStatus );
       
   295 #endif
       
   296             }
       
   297         }
       
   298     }
       
   299 
       
   300 // ----------------------------------------------------
       
   301 // CTcpCirWatcher::WatcherStatus
       
   302 //
       
   303 // ----------------------------------------------------
       
   304 //
       
   305 TUint CTcpCirWatcher::WatcherStatus() const
       
   306     {
       
   307 #ifdef _DEBUG
       
   308     WriteToLog( _L8( "CTcpCirWatcher::WatcherStatus()" ) );
       
   309 #endif
       
   310     return iWatcherStatus;
       
   311     }
       
   312 
       
   313 #ifdef _DEBUG
       
   314 
       
   315 // ----------------------------------------------------
       
   316 // CTcpCirWatcher::WriteToLog
       
   317 //
       
   318 // ----------------------------------------------------
       
   319 //
       
   320 void CTcpCirWatcher::WriteToLog( TRefByValue<const TDesC8> aFmt, ... )
       
   321     {
       
   322     VA_LIST list;
       
   323     VA_START( list, aFmt );
       
   324     TBuf8<KTcpLogBufferMaxSize> buf;
       
   325     buf.FormatList( aFmt, list );
       
   326     RFileLogger::Write( KTcpLogDir, KTcpWatcherLogFile, EFileLoggingModeAppend, buf );
       
   327     }
       
   328 
       
   329 #endif
       
   330 
       
   331 // ---------------------------------------------------------
       
   332 // CTcpCirWatcher::WaitForHELOResponse
       
   333 //
       
   334 // ---------------------------------------------------------
       
   335 //
       
   336 void CTcpCirWatcher::WaitForHELOResponse()
       
   337     {
       
   338 #ifdef _DEBUG
       
   339     WriteToLog( _L8( "CTcpCirWatcher::WaitForHELOResponse()" ) );
       
   340 #endif
       
   341     iSocketReceiveBuffer.Zero();
       
   342     iStatus = KRequestPending;
       
   343     iWatcherStatus = EImpsCIRWatcherReceivingHELOResponse;
       
   344     iTCPCIRSocket.RecvOneOrMore( iSocketReceiveBuffer, 0, iStatus, iRecvLength );
       
   345     iWatcherTimer->ActivateTimer( 10000000, KWaitForHELOResponse );
       
   346     SetActive();
       
   347     }
       
   348 
       
   349 // ---------------------------------------------------------
       
   350 // CTcpCirWatcher::ConnectTCPSocket
       
   351 //
       
   352 // ---------------------------------------------------------
       
   353 //
       
   354 void CTcpCirWatcher::ConnectTCPSocketL()
       
   355     {
       
   356 #ifdef _DEBUG
       
   357     WriteToLog( _L8( "CTcpCirWatcher::ConnectTCPSocket()  iConnRetries: %d" ), iConnRetries );
       
   358 #endif
       
   359     iWatcherStatus = EImpsCIRWatcherConnectingTCPSocket;
       
   360     User::LeaveIfError( iTCPCIRSocket.Open( iConnectionManager.SocketSession(),
       
   361                                             KAfInet, KSockStream, KProtocolInetTcp,
       
   362                                             iConnectionManager.Connection() ) );
       
   363     if ( iConnRetries < KMaxNumberOfConnAttempts )
       
   364         {
       
   365         iTCPCIRSocket.Connect( iSocketAddress, iStatus );
       
   366         iConnRetries++;
       
   367         SetActive();
       
   368         iWatcherTimer->ActivateTimer( 20000000, KWaitForFirstConnectAttempt );
       
   369         }
       
   370     else
       
   371         {
       
   372         iTCPCIRSocket.Close();
       
   373         iCirReceiver.HandleErrorL( KErrCouldNotConnect, EImpsTcpCir );
       
   374         iWatcherStatus = EImpsCIRWatcherIdle;
       
   375         iConnectionManager.RemoveEventSubscriber( this );
       
   376 #ifdef _DEBUG
       
   377         WriteToLog( _L8( "  Connect retry limit encountered, stop." ) );
       
   378 #endif
       
   379         }
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------
       
   383 // CTcpCirWatcher::SendHELOMessageL
       
   384 //
       
   385 // ---------------------------------------------------------
       
   386 //
       
   387 void CTcpCirWatcher::SendHELOMessageL()
       
   388     {
       
   389 #ifdef _DEBUG
       
   390     WriteToLog( _L8( "CTcpCirWatcher::SendHELOMessageL()" ) );
       
   391 #endif
       
   392     iWatcherStatus = EImpsCIRWatcherSendingHELOMessage;
       
   393     delete iSocketSendBuffer;
       
   394     iSocketSendBuffer = NULL;
       
   395     iSocketSendBuffer = HBufC8::NewL( 7 + iCSPSessionID->Length() );
       
   396     iSocketSendBuffer->Des().Copy( KHELOMessage );
       
   397     iSocketSendBuffer->Des().Append( *iCSPSessionID );
       
   398     iSocketSendBuffer->Des().Append( KMessageTermination );
       
   399     iStatus = KRequestPending;
       
   400     iTCPCIRSocket.Write( iSocketSendBuffer->Des(), iStatus );
       
   401     iWatcherTimer->ActivateTimer( 10000000, KWaitForHELOSendAttempt );
       
   402     SetActive();
       
   403     }
       
   404 
       
   405 // ---------------------------------------------------------
       
   406 // CTcpCirWatcher::SendPing
       
   407 //
       
   408 // ---------------------------------------------------------
       
   409 //
       
   410 void CTcpCirWatcher::SendPingL()
       
   411     {
       
   412 #ifdef _DEBUG
       
   413     WriteToLog( _L8( "CTcpCirWatcher::SendPing()  iPingRetries: %d/%d" ), iPingRetries, KMaxNumberOfPingAttempts );
       
   414 #endif
       
   415     if ( iPingRetries < KMaxNumberOfPingAttempts )
       
   416         {
       
   417         iWatcherStatus = EImpsCIRWatcherSendingPINGRequest;
       
   418         iTCPCIRSocket.Write( KImpsPingData, iStatus );
       
   419         iPingRetries++;
       
   420         SetActive();
       
   421         }
       
   422     else
       
   423         {
       
   424         //The server is down, close the socket and report error
       
   425         iTCPCIRSocket.Close();
       
   426         iCirReceiver.HandleErrorL( KErrDisconnected, EImpsTcpCir );
       
   427         iWatcherStatus = EImpsCIRWatcherIdle;
       
   428         iConnectionManager.RemoveEventSubscriber( this );
       
   429 #ifdef _DEBUG
       
   430         WriteToLog( _L8( "  Ping retry limit encountered, stop." ) );
       
   431 #endif
       
   432         }
       
   433     }
       
   434 
       
   435 // ---------------------------------------------------------
       
   436 // CTcpCirWatcher::RunL
       
   437 //
       
   438 // ---------------------------------------------------------
       
   439 //
       
   440 void CTcpCirWatcher::RunL()
       
   441     {
       
   442 #ifdef _DEBUG
       
   443     WriteToLog( _L8( "CTcpCirWatcher::RunL(), iStatus: %d" ), iStatus );
       
   444 #endif
       
   445     iWatcherTimer->Cancel();
       
   446     switch ( iWatcherStatus )
       
   447         {
       
   448         case EImpsCIRWatcherAwaitingDNS:
       
   449             if ( iStatus == KErrNone )
       
   450                 {
       
   451                 iSocketAddress = TInetAddr( iHostAddressDnsEntry().iAddr );
       
   452 #ifdef _DEBUG
       
   453                 TBuf<200> buffer;
       
   454                 TBuf8<200> eightBuffer;
       
   455                 iSocketAddress.Output( buffer );
       
   456                 eightBuffer.Copy( buffer );
       
   457                 WriteToLog( _L8( "  IP address resolved (%S), starting to connect." ), &eightBuffer );
       
   458 #endif
       
   459                 iSocketAddress.SetPort( iServerPort );
       
   460                 iHostResolver.Close();
       
   461                 ConnectTCPSocketL();
       
   462                 }
       
   463             else
       
   464                 {
       
   465 #ifdef _DEBUG
       
   466                 WriteToLog( _L8( "  IP address resolving failed, complete with %d." ), iStatus.Int() );
       
   467 #endif
       
   468                 iConnectionManager.RemoveEventSubscriber( this );
       
   469                 User::RequestComplete( iClientStatus, iStatus.Int() );
       
   470                 iWatcherStatus = EImpsCIRWatcherIdle;
       
   471                 }
       
   472             break;
       
   473         default:
       
   474             if ( iStatus == KErrNone )
       
   475                 HandleRequestCompletionL();
       
   476             else
       
   477                 HandleErrorL( iStatus.Int() );
       
   478         }
       
   479     }
       
   480 
       
   481 // ---------------------------------------------------------
       
   482 // CTcpCirWatcher::HandleRequestCompletionL
       
   483 //
       
   484 // ---------------------------------------------------------
       
   485 //
       
   486 void CTcpCirWatcher::HandleRequestCompletionL()
       
   487     {
       
   488     switch ( iWatcherStatus )
       
   489         {
       
   490         case EImpsCIRWatcherConnectingTCPSocket:
       
   491 #ifdef _DEBUG
       
   492             WriteToLog( _L8( "  TCP Socket is connected, starting to send HELO." ) );
       
   493 #endif
       
   494             iConnRetries = 0;
       
   495             SendHELOMessageL();
       
   496             break;
       
   497         case EImpsCIRWatcherSendingHELOMessage:
       
   498 #ifdef _DEBUG
       
   499             WriteToLog( _L8( "  HELO Message sent, waiting for response." ) );
       
   500 #endif
       
   501             WaitForHELOResponse();
       
   502             break;
       
   503         case EImpsCIRWatcherReceivingHELOResponse:
       
   504 #ifdef _DEBUG
       
   505             WriteToLog( _L8( "  Server responded with the message: %S" ), &iSocketReceiveBuffer );
       
   506 #endif
       
   507             if ( iClientRequestPending )
       
   508                 {
       
   509 #ifdef _DEBUG
       
   510                 WriteToLog( _L8( "  Completing request & starting to PING the server in %d second intervals." ), iPingInterval );
       
   511 #endif
       
   512                 User::RequestComplete( iClientStatus, KErrNone );
       
   513                 iClientRequestPending = EFalse;
       
   514                 }
       
   515             WaitForNextPing();
       
   516             break;
       
   517         case EImpsCIRWatcherSendingPINGRequest:
       
   518 #ifdef _DEBUG
       
   519             WriteToLog( _L8( "  Ping sent succesfully, wait for response" ) );
       
   520 #endif
       
   521             iWatcherStatus = EImpsCIRWatcherWaitingPINGResponse;
       
   522             iWatcherTimer->ActivateTimer( 5000000, KWaitForPingReply );
       
   523             ReceiveFromSocket();
       
   524             break;
       
   525         case EImpsCIRWatcherWaitingPINGResponse:
       
   526 #ifdef _DEBUG
       
   527             WriteToLog( _L8( "  Server responded to ping with the message: %S" ), &iSocketReceiveBuffer );
       
   528 #endif
       
   529             if ( iSocketReceiveBuffer.Find( KImpsPingResponseWVCI ) == 0 )
       
   530                 ReportCirL();
       
   531             else if ( iSocketReceiveBuffer.Find( KImpsPingResponseOK ) == 0 )
       
   532 #ifdef _DEBUG
       
   533                 WriteToLog( _L8( "  Server is OK." ) )
       
   534 #endif
       
   535                 ;
       
   536             else
       
   537                 //Should this case include a reset/closure of the connection?
       
   538                 //Clearly the received data does not comply to any of
       
   539                 //the rules set by the OMA IMPS specification.
       
   540 #ifdef _DEBUG
       
   541                 WriteToLog( _L8( "  Do not talk to me like that.. learn some manners!" ) );
       
   542 #endif
       
   543             ;
       
   544             iPingRetries = 0;
       
   545             WaitForNextPing();
       
   546             break;
       
   547         case KImpsCIRWatcherReceivingFromSocket:
       
   548 #ifdef _DEBUG
       
   549             WriteToLog( _L8( "  Server sent: %S" ), &iSocketReceiveBuffer );
       
   550 #endif
       
   551             if ( iSocketReceiveBuffer.Find( KImpsPingResponseWVCI ) == 0 )
       
   552                 ReportCirL();
       
   553             if ( iWatcherStatus == KImpsCIRWatcherReceivingFromSocket )
       
   554                 WaitForNextPing();
       
   555             break;
       
   556         default:
       
   557 #ifdef _DEBUG
       
   558             WriteToLog( _L8( "  Default case, something's wrong." ) );
       
   559 #endif
       
   560             break;
       
   561         }
       
   562     }
       
   563 
       
   564 // ---------------------------------------------------------
       
   565 // CTcpCirWatcher::HandleErrorL
       
   566 //
       
   567 // ---------------------------------------------------------
       
   568 //
       
   569 void CTcpCirWatcher::HandleErrorL( const TInt aError )
       
   570     {
       
   571 #ifdef _DEBUG
       
   572     WriteToLog( _L8( "  CTcpCirWatcher::HandleErrorL(), error: %d  iWatcherStatus: %d" ), aError, iWatcherStatus );
       
   573 #endif
       
   574     switch ( iWatcherStatus )
       
   575         {
       
   576         case EImpsCIRWatcherConnectingTCPSocket:
       
   577         case EImpsCIRWatcherSendingHELOMessage:
       
   578         case EImpsCIRWatcherReceivingHELOResponse:
       
   579 #ifdef _DEBUG
       
   580             WriteToLog( _L8( "    Error when establishing connection to CIR Server: %d  Client pending: %d" ), iStatus.Int(), iClientRequestPending );
       
   581 #endif
       
   582             if ( iClientRequestPending )
       
   583                 {
       
   584                 iCompletionCode = iStatus == KErrCancel ? iCompletionCode : aError;
       
   585                 CompleteWithError( iCompletionCode );
       
   586                 }
       
   587             else
       
   588                 iWatcherTimer->ActivateTimer( 10000000, KWaitForNextConnectAttempt );
       
   589             break;
       
   590         case EImpsCIRWatcherReceivingFromSocket:
       
   591             if ( aError == KErrCancel )
       
   592                 {
       
   593 #ifdef _DEBUG
       
   594                 WriteToLog( _L8( "    Time to send the next ping request" )  );
       
   595 #endif
       
   596                 SendPingL();
       
   597                 }
       
   598             else
       
   599                 {
       
   600 #ifdef _DEBUG
       
   601                 WriteToLog( _L8( "    Socket read returned with error" )  );
       
   602 #endif
       
   603                 DetermineSocketStateL( aError );
       
   604                 }
       
   605             break;
       
   606         case EImpsCIRWatcherSendingPINGRequest:
       
   607 #ifdef _DEBUG
       
   608             WriteToLog( _L8( "  Error when sending PING: %d, try again." ), aError );
       
   609 #endif
       
   610             SendPingL();
       
   611             break;
       
   612         case EImpsCIRWatcherWaitingPINGResponse:
       
   613 #ifdef _DEBUG
       
   614             WriteToLog( _L8( "  Error when receiving PING response: %d, check socket state" ), aError );
       
   615 #endif
       
   616             DetermineSocketStateL( aError );
       
   617             break;
       
   618         case EImpsCIRWatcherStopping:
       
   619             //Client has called StopTCPWatcher()
       
   620             if ( iStatus == KErrCancel )
       
   621                 {
       
   622 #ifdef _DEBUG
       
   623                 WriteToLog( _L8( "  Watcher shutdown requested" )  );
       
   624 #endif
       
   625                 if ( iClientRequestPending )
       
   626                     {
       
   627 #ifdef _DEBUG
       
   628                     WriteToLog( _L8( "  A request is pending, complete" )  );
       
   629 #endif
       
   630                     User::RequestComplete( iClientStatus, KErrCancel );
       
   631                     }
       
   632                 iTCPCIRSocket.Close();
       
   633                 iHostResolver.Close();
       
   634                 iWatcherStatus = EImpsCIRWatcherIdle;
       
   635                 }
       
   636             break;
       
   637         default:
       
   638 #ifdef _DEBUG
       
   639             WriteToLog( _L8( "  Default case, do nothing" ), aError );
       
   640 #endif
       
   641             break;
       
   642         }
       
   643     }
       
   644 
       
   645 // ---------------------------------------------------------
       
   646 // CTcpCirWatcher::DetermineSocketStateL
       
   647 // NOTE: Close()s the current socket and opens a new one in
       
   648 // each case. The aError parameter is used only for debug info.
       
   649 // Change this feature if needed, since for instance a socket
       
   650 // receive operation may fail/time out, in which case the socket
       
   651 // is most probably still as good as new. Closing a perfectly
       
   652 // good socket should not consume resources that prodigiously.
       
   653 // That might not, however, be the most elegant solution, but it
       
   654 // works fine just the same...
       
   655 // ---------------------------------------------------------
       
   656 //
       
   657 void CTcpCirWatcher::DetermineSocketStateL( const TInt aError )
       
   658     {
       
   659 #ifdef _DEBUG
       
   660     WriteToLog( _L8( "    CTcpCirWatcher::DetermineSocketStateL()" )  );
       
   661     switch ( aError )
       
   662         {
       
   663             //The socket has been closed for some reason, try to connect again
       
   664         case KErrEof:
       
   665         case KErrDisconnected:
       
   666             WriteToLog( _L8( "    The socket was disconnected, re-open." )  );
       
   667             break;
       
   668             //Something seriously wrong, close the socket & open a new one
       
   669         case KErrNotReady:
       
   670             WriteToLog( _L8( "    Socket cannot be re-used anymore, close & re-open." )  );
       
   671             break;
       
   672             //Something timed out.
       
   673         case KErrTimedOut:
       
   674             WriteToLog( _L8( "    Socket operation timed out, close & re-open." )  );
       
   675             break;
       
   676         case KErrConnectionTerminated:
       
   677             WriteToLog( _L8( "    Socket Connection Terminated (Received KErrConnectionTerminated (-17210) )" )  );
       
   678             break;
       
   679         default:
       
   680             WriteToLog( _L8( "    Default case - Error: %d" ), aError  );
       
   681             break;
       
   682         }
       
   683 #endif
       
   684     if ( aError == KErrConnectionTerminated )
       
   685         {
       
   686         // KErrConnectionTerminated = -17210 is declared in es_sock.h
       
   687         // Received this error when ending the packed data connection. in this case not required to connect again.
       
   688         // if received in other situations other than EndPacketDataConnection, may need to connect again
       
   689         iTCPCIRSocket.Close();
       
   690 #ifdef _DEBUG
       
   691         WriteToLog( _L8( "Received Socket Connection Terminated Error - Closed the Socket Connection " )  );
       
   692 #endif
       
   693         }
       
   694     else
       
   695         {
       
   696         iTCPCIRSocket.Close();
       
   697         ConnectTCPSocketL();
       
   698         }
       
   699     }
       
   700 
       
   701 // ---------------------------------------------------------
       
   702 // CTcpCirWatcher::WaitForNextPing
       
   703 //
       
   704 // ---------------------------------------------------------
       
   705 //
       
   706 void CTcpCirWatcher::WaitForNextPing()
       
   707     {
       
   708 #ifdef _DEBUG
       
   709     WriteToLog( _L8( "CTcpCirWatcher::WaitForNextPing()" ) );
       
   710 #endif
       
   711     iWatcherTimer->ActivateTimer( iPingInterval * 1000000, KWaitForNextPing );
       
   712     iWatcherStatus = EImpsCIRWatcherReceivingFromSocket;
       
   713     ReceiveFromSocket();
       
   714     }
       
   715 
       
   716 // ---------------------------------------------------------
       
   717 // CTcpCirWatcher::CheckAddressValidity
       
   718 //
       
   719 // ---------------------------------------------------------
       
   720 //
       
   721 TBool CTcpCirWatcher::CheckAddressValidity()
       
   722     {
       
   723 #ifdef _DEBUG
       
   724     WriteToLog( _L8( "CTcpCirWatcher::CheckAddressValidity()" ) );
       
   725 #endif
       
   726     TInetAddr destination;
       
   727     iTCPCIRSocket.RemoteName( destination );
       
   728     if ( destination == iSocketAddress )
       
   729         return ETrue;
       
   730     else return EFalse;
       
   731     }
       
   732 
       
   733 // ---------------------------------------------------------
       
   734 // CTcpCirWatcher::ReportCirL
       
   735 //
       
   736 // ---------------------------------------------------------
       
   737 //
       
   738 void CTcpCirWatcher::ReportCirL()
       
   739     {
       
   740 #ifdef _DEBUG
       
   741     WriteToLog( _L8( "CTcpCirWatcher::ReportCirL()" ) );
       
   742 #endif
       
   743     //Just a precaution: if the address has changed somewhere
       
   744     //along the line, our connection has been hijacked...
       
   745     //Though any serious attacker would probably spoof the IP
       
   746     //address, but it doesn't hurt to try.
       
   747     if ( CheckAddressValidity() )
       
   748         iCirReceiver.CirReceivedL( iSocketReceiveBuffer, EImpsTcpCir );
       
   749     else
       
   750         {
       
   751 #ifdef _DEBUG
       
   752         WriteToLog( _L8( "  Wrong address, something's wrong. Close & report error" ) );
       
   753 #endif
       
   754         iTCPCIRSocket.Close();
       
   755         iWatcherStatus = EImpsCIRWatcherIdle;
       
   756         iCirReceiver.HandleErrorL( KErrAbort, EImpsTcpCir );
       
   757         }
       
   758     }
       
   759 
       
   760 // ---------------------------------------------------------
       
   761 // CTcpCirWatcher::ReceiveFromSocket
       
   762 //
       
   763 // ---------------------------------------------------------
       
   764 //
       
   765 void CTcpCirWatcher::ReceiveFromSocket()
       
   766     {
       
   767 #ifdef _DEBUG
       
   768     WriteToLog( _L8( "CTcpCirWatcher::ReceiveFromSocket()" ) );
       
   769 #endif
       
   770     TUint flags = 0;
       
   771     iSocketReceiveBuffer.Zero();
       
   772     iStatus = KRequestPending;
       
   773     iTCPCIRSocket.RecvOneOrMore( iSocketReceiveBuffer, flags, iStatus, iRecvLength );
       
   774     SetActive();
       
   775     }
       
   776 
       
   777 // ----------------------------------------------------
       
   778 // CTcpCirWatcher::CompleteWithError
       
   779 //
       
   780 // ----------------------------------------------------
       
   781 //
       
   782 void CTcpCirWatcher::CompleteWithError( const TInt aError )
       
   783     {
       
   784 #ifdef _DEBUG
       
   785     WriteToLog( _L8( "CTcpCirWatcher::CompleteWithError()" ) );
       
   786 #endif
       
   787     iWatcherTimer->Cancel();
       
   788     User::RequestComplete( iClientStatus, aError );
       
   789     iConnectionManager.RemoveEventSubscriber( this );
       
   790     iWatcherStatus = EImpsCIRWatcherIdle;
       
   791     }
       
   792 
       
   793 // ----------------------------------------------------
       
   794 // CTcpCirWatcher::HandleTimerEventL
       
   795 //
       
   796 // ----------------------------------------------------
       
   797 //
       
   798 void CTcpCirWatcher::HandleTimerEventL( const TUint aExpiredRequest )
       
   799     {
       
   800 #ifdef _DEBUG
       
   801     WriteToLog( _L8( "CTcpCirWatcher::HandleTimerEventL()" ) );
       
   802 #endif
       
   803     switch ( aExpiredRequest )
       
   804         {
       
   805         case KWaitForFirstConnectAttempt:
       
   806 #ifdef _DEBUG
       
   807             WriteToLog( _L8( "  Socket connect timed out, complete with KErrTimedOut" ) );
       
   808 #endif
       
   809             iCompletionCode = KErrTimedOut;
       
   810             iTCPCIRSocket.CancelConnect();
       
   811             break;
       
   812 #ifdef _DEBUG
       
   813         case KWaitForNextPing:
       
   814             //This will return in RunL() with KErrCancel
       
   815             WriteToLog( _L8( "  Socket read timed out, time to send the next ping" ) );
       
   816             iTCPCIRSocket.CancelRecv();
       
   817             break;
       
   818         case KWaitForPingReply:
       
   819             //This will return in RunL() with KErrCancel
       
   820             WriteToLog( _L8( "  Server didn't reply to ping, try again" ) );
       
   821             iTCPCIRSocket.CancelRecv();
       
   822             break;
       
   823 #else
       
   824         case KWaitForNextPing:
       
   825         case KWaitForPingReply:
       
   826             //This will return in RunL() with KErrCancel
       
   827             iTCPCIRSocket.CancelRecv();
       
   828             break;
       
   829 #endif
       
   830         case KWaitForHELOResponse:
       
   831             //The server didn't reply to the HELO response
       
   832 #ifdef _DEBUG
       
   833             WriteToLog( _L8( "  Server didn't reply to HELO request, quit." ) );
       
   834 #endif
       
   835             iTCPCIRSocket.CancelRecv();
       
   836             break;
       
   837         case KWaitForHELOSendAttempt:
       
   838             //Socket server is fooked...
       
   839 #ifdef _DEBUG
       
   840             WriteToLog( _L8( "  Socket server didn't reply, quit." ) );
       
   841 #endif
       
   842             iTCPCIRSocket.CancelWrite();
       
   843             break;
       
   844         case KWaitForNextConnectAttempt:
       
   845             ConnectTCPSocketL();
       
   846             break;
       
   847         default:
       
   848 #ifdef _DEBUG
       
   849             WriteToLog( _L8( "  Default case" ) );
       
   850 #endif
       
   851             break;
       
   852         }
       
   853     }
       
   854 
       
   855 // ---------------------------------------------------------
       
   856 // CTcpCirWatcher::DoCancel
       
   857 //
       
   858 // ---------------------------------------------------------
       
   859 //
       
   860 void CTcpCirWatcher::DoCancel()
       
   861     {
       
   862 #ifdef _DEBUG
       
   863     WriteToLog( _L8( "CTcpCirWatcher::DoCancel()  Status: %d" ), iWatcherStatus );
       
   864 #endif
       
   865     iWatcherTimer->Cancel();
       
   866     switch ( iWatcherStatus )
       
   867         {
       
   868         case EImpsCIRWatcherConnectingTCPSocket:
       
   869         case EImpsCIRWatcherSendingHELOMessage:
       
   870         case EImpsCIRWatcherReceivingHELOResponse:
       
   871 #ifdef _DEBUG
       
   872             WriteToLog( _L8( "    Cancelling all socket operations" ) );
       
   873 #endif
       
   874             iTCPCIRSocket.CancelAll();
       
   875             iWatcherStatus = EImpsCIRWatcherIdle;
       
   876             break;
       
   877         case EImpsCIRWatcherBearerSuspended:
       
   878             iTCPCIRSocket.CancelAll();
       
   879             break;
       
   880         default:
       
   881 #ifdef _DEBUG
       
   882             WriteToLog( _L8( "    Default case, cancels all socket operations." ) );
       
   883 #endif
       
   884             iTCPCIRSocket.CancelAll();
       
   885             break;
       
   886         }
       
   887     }
       
   888 
       
   889 // ---------------------------------------------------------
       
   890 // CTcpCirWatcher::HandleBearerSuspension
       
   891 //
       
   892 // ---------------------------------------------------------
       
   893 //
       
   894 void CTcpCirWatcher::HandleBearerSuspension()
       
   895     {
       
   896 #ifdef _DEBUG
       
   897     WriteToLog( _L8( "CTcpCirWatcher::HandleBearerSuspension()" ) );
       
   898 #endif
       
   899     iLastGoodWatcherStatus = iWatcherStatus;
       
   900     iWatcherStatus = EImpsCIRWatcherBearerSuspended;
       
   901     Cancel();
       
   902     iWatcherTimer->Cancel();
       
   903     switch ( iLastGoodWatcherStatus )
       
   904         {
       
   905         case EImpsCIRWatcherConnectingTCPSocket:
       
   906         case EImpsCIRWatcherSendingHELOMessage:
       
   907         case EImpsCIRWatcherReceivingHELOResponse:
       
   908             //If we're connecting & client is pending, complete with error
       
   909             if ( iClientRequestPending )
       
   910                 {
       
   911                 User::RequestComplete( iClientStatus, KErrCouldNotConnect );
       
   912                 iLastGoodWatcherStatus = EImpsCIRWatcherUnknown;
       
   913                 }
       
   914             break;
       
   915         default:
       
   916 #ifdef _DEBUG
       
   917             WriteToLog( _L8( "   Default case." ) );
       
   918 #endif
       
   919             break;
       
   920         }
       
   921     }
       
   922 
       
   923 // ---------------------------------------------------------
       
   924 // CTcpCirWatcher::HandleBearerActivationLL
       
   925 //
       
   926 // ---------------------------------------------------------
       
   927 //
       
   928 void CTcpCirWatcher::HandleBearerActivationL()
       
   929     {
       
   930 #ifdef _DEBUG
       
   931     WriteToLog( _L8( "CTcpCirWatcher::HandleBearerActivationL()" ) );
       
   932 #endif
       
   933     iWatcherStatus = iLastGoodWatcherStatus;
       
   934     switch ( iWatcherStatus )
       
   935         {
       
   936         case EImpsCIRWatcherUnknown:
       
   937 #ifdef _DEBUG
       
   938             WriteToLog( _L8( "   No active CIR channel exists, ignore." ) );
       
   939 #endif
       
   940             iWatcherStatus = EImpsCIRWatcherIdle;
       
   941             break;
       
   942         case EImpsCIRWatcherSendingPINGRequest:
       
   943         case EImpsCIRWatcherWaitingPINGResponse:
       
   944         case KImpsCIRWatcherReceivingFromSocket:
       
   945 #ifdef _DEBUG
       
   946             WriteToLog( _L8( "   Last good state was sending a request, send another." ) );
       
   947 #endif
       
   948             SendPingL();
       
   949             break;
       
   950         case EImpsCIRWatcherConnectingTCPSocket:
       
   951 #ifdef _DEBUG
       
   952             WriteToLog( _L8( "   Last good state was opening a socket, re-open." ) );
       
   953 #endif
       
   954             iTCPCIRSocket.Close();
       
   955             ConnectTCPSocketL();
       
   956             break;
       
   957         default:
       
   958 #ifdef _DEBUG
       
   959             WriteToLog( _L8( "   Default case." ) );
       
   960 #endif
       
   961             break;
       
   962         }
       
   963     }
       
   964 
       
   965 // ---------------------------------------------------------
       
   966 // CTcpCirWatcher::HandleBearerEventL
       
   967 //
       
   968 // ---------------------------------------------------------
       
   969 //
       
   970 void CTcpCirWatcher::HandleBearerEventL( TBool aIsAuthClose, TMsgBearerEvent aBearerEvent )
       
   971     {
       
   972 #ifdef _DEBUG
       
   973     WriteToLog( _L8( "CTcpCirWatcher::HandleBearerEventL()  Event: %d  AuthClose: %d" ),
       
   974                 aBearerEvent, aIsAuthClose );
       
   975 #endif
       
   976     switch ( aBearerEvent )
       
   977         {
       
   978         case EMsgBearerSuspended:
       
   979 #ifdef _DEBUG
       
   980             WriteToLog( _L8( "   Bearer suspended - State: %d" ), iWatcherStatus );
       
   981 #endif
       
   982             //Do nothing if already in suspend state
       
   983             if ( iWatcherStatus != EImpsCIRWatcherBearerSuspended )
       
   984                 HandleBearerSuspension();
       
   985             break;
       
   986         case EMsgBearerActive:
       
   987 #ifdef _DEBUG
       
   988             WriteToLog( _L8( "   Bearer activated - State: %d." ), iWatcherStatus );
       
   989 #endif
       
   990             //Act only if in suspend state
       
   991             if ( iWatcherStatus == EImpsCIRWatcherBearerSuspended )
       
   992                 HandleBearerActivationL();
       
   993             break;
       
   994         case EMsgBearerLost:
       
   995 #ifdef _DEBUG
       
   996             WriteToLog( _L8( "   Bearer lost, call it a day." ) );
       
   997 #endif
       
   998             Cancel();
       
   999             iWatcherStatus = EImpsCIRWatcherIdle;
       
  1000             iCirReceiver.HandleErrorL( EMsgBearerLost, EImpsTcpCir );
       
  1001             break;
       
  1002         default:
       
  1003 #ifdef _DEBUG
       
  1004             WriteToLog( _L8( "   Default case, shouldn't be here..." ) );
       
  1005 #endif
       
  1006             break;
       
  1007         }
       
  1008     }
       
  1009 
       
  1010 
       
  1011 // End of File