IMPSengine/engsrv/src/impscspsession.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2004 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: Session for IMPS.
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    <e32base.h>
       
    22 #include    <e32math.h>
       
    23 #include    "impsserver.h"
       
    24 #include    "impssession.h"
       
    25 #include    "impssubsession.h"
       
    26 #include    "impscspsession.h"
       
    27 #include    "impsfields.h"
       
    28 #include    "impsutils.h"
       
    29 #include    "impserrors.h"
       
    30 #include    "impstimer.h"
       
    31 #include    "impssendreceive.h"
       
    32 #include    "impsservices.h"
       
    33 #include    "impscommonenums.h"
       
    34 #include    "impssdatautils.h"
       
    35 #include    "impsmessageinterpreterapi.h"
       
    36 #include    "impsdataaccessor.h"
       
    37 #include    "impsdigestbytes.h"
       
    38 #include    "impsvariant.h"
       
    39 #include    "impsalivemanager.h"
       
    40 #include    "impsactivecirmonitor.h"
       
    41 #include    "ImpsVariantAPI.h"
       
    42 #include    "impstidqueue.h"
       
    43 #include    "impsactivecirmonitor.h"
       
    44 
       
    45 #ifdef LOCAL_IMPS
       
    46 #ifndef _FAKE_RESPONSE
       
    47 #define _FAKE_RESPONSE
       
    48 #endif
       
    49 #endif
       
    50 
       
    51 #ifdef _FAKE_RESPONSE
       
    52 #include    "impssrvtestutils.h"
       
    53 #endif
       
    54 
       
    55 // MACROS
       
    56 #ifndef _DEBUG
       
    57 #define _NO_IMPS_LOGGING_
       
    58 #endif
       
    59 
       
    60 // CONSTANTS
       
    61 // Adative polling policy time increment
       
    62 const TInt KImpsPollIncrement = 10;
       
    63 
       
    64 // ================= MEMBER FUNCTIONS =======================
       
    65 
       
    66 CImpsCSPSession::CImpsCSPSession( CImpsServer& aServer,
       
    67                                   TImpsSrvSettings& aSettings,
       
    68                                   RFs& aFs,
       
    69                                   CImpsVariant& aVariant,
       
    70                                   TImpsCspVersion aVer ):
       
    71         iServer( aServer ),
       
    72         iCSPVersion( aVer ),
       
    73         iFs( aFs ),
       
    74         iVariant( aVariant ),
       
    75         iTransactionList( _FOFF( CTransaction, iLink ) ), //lint !e413
       
    76         iRequestList( _FOFF( CReq, iLink ) ), //lint !e413
       
    77         iCSPState( EImpsCSPIdle ),
       
    78         iPendingLogout( EFalse ),
       
    79         iAliveMgr( NULL ),
       
    80         iPollTime( KImpsPollTime ),
       
    81         iPollWasRequested( EFalse ),
       
    82         iUserId( NULL ),
       
    83         iIntStatus ( EInternal_NOT_LOGGED ),
       
    84         iMultiTrans( KImpsMultiTrans ),
       
    85         iNegoExpiry( ),
       
    86         iCirManager( NULL ),
       
    87         iLogoutTID( KNullDesC ),
       
    88         iConAllowed( ETrue ),
       
    89         iPendingAlive( EFalse ),
       
    90         iSAP( NULL ),
       
    91         iIAP( 0 ),
       
    92         iPollState( EImpsPollNone ),
       
    93         iPollInResume( 0 ),
       
    94         iPendingPDP( EImpsPDPPendNone ),    // PDP:
       
    95         iPendPDPLogout ( EFalse ), // PDP:
       
    96         iTidSapHistory( NULL ),
       
    97         iTidCliHistory( NULL ),
       
    98         iTcpCIRError( EFalse ),
       
    99         iCancelLogin ( EFalse )
       
   100     {
       
   101     iCSPSessionId = KNullDesC;
       
   102     iLogCID = KNullDesC;
       
   103     iTempTid = KNullDesC;
       
   104     iTempTid2 = KNullDesC;
       
   105     iMsg = EImpsMessageNone;
       
   106     iLoginPhase = 1;
       
   107     iKey1 = NULL;
       
   108     iKey2 = NULL;
       
   109     iSettings = aSettings;
       
   110     }
       
   111 
       
   112 // Create and start a new server.
       
   113 
       
   114 CImpsCSPSession* CImpsCSPSession::NewL( CImpsServer& aServer,
       
   115                                         TImpsSrvSettings& aSettings,
       
   116                                         RFs& aFs,
       
   117                                         CImpsVariant& aVariant,
       
   118                                         TImpsCspVersion aVer )
       
   119     {
       
   120 #ifndef _NO_IMPS_LOGGING_
       
   121     if ( aVer == EImpsCspVersion11 )
       
   122         {
       
   123         CImpsClientLogger::Log( _L( "CSPSession: NewL rel200542.2+ WV 1.1" ) );
       
   124         }
       
   125     else
       
   126         {
       
   127         CImpsClientLogger::Log( _L( "CSPSession: NewL rel200542.2+ WV 1.2" ) );
       
   128         }
       
   129 #endif
       
   130 
       
   131     CImpsCSPSession* self = new ( ELeave ) CImpsCSPSession( aServer,
       
   132                                                             aSettings, aFs, aVariant, aVer );
       
   133     CleanupStack::PushL( self );
       
   134     self->ConstructL();
       
   135     CleanupStack::Pop();
       
   136     return self;
       
   137     }
       
   138 
       
   139 CImpsCSPSession::~CImpsCSPSession()
       
   140     {
       
   141 #ifndef _NO_IMPS_LOGGING_
       
   142     CImpsClientLogger::Log( _L( "CSPSession: DESTRUCTOR csp=%d **" ), ( TInt )this );
       
   143 #endif
       
   144     // deallocate all memory
       
   145     DeleteTransactions();
       
   146     DeleteRequests();
       
   147 
       
   148     delete iTransportOut;
       
   149 
       
   150     delete iCirManager;
       
   151     delete iReceiver2;
       
   152     delete iAllMessages;
       
   153     delete iRcv;
       
   154     delete iSnd;
       
   155 
       
   156     delete iIdleTimer;
       
   157     delete iAliveMgr;
       
   158 
       
   159     delete iSendQ;
       
   160 
       
   161     delete iTCPAddr;
       
   162     delete iLogPwd;
       
   163     delete iLogTid;
       
   164     delete iKey1;
       
   165     delete iKey2;
       
   166     delete iUserId;
       
   167 
       
   168     delete iSAP;
       
   169 
       
   170     if ( iDecoder )
       
   171         {
       
   172         iDecoder->Destroy();
       
   173         }
       
   174     if ( iEncoder )
       
   175         {
       
   176         iEncoder->Destroy();
       
   177         }
       
   178 
       
   179     delete iPDPIdleTimer;
       
   180     delete iPDPOpenTimer;
       
   181     delete iTidSapHistory;
       
   182     delete iTidCliHistory;
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CImpsCSPSession::Destroy()
       
   187 // -----------------------------------------------------------------------------
       
   188 void CImpsCSPSession::Destroy()
       
   189     {
       
   190 #ifndef _NO_IMPS_LOGGING_
       
   191     CImpsClientLogger::Log( _L( "CSPSession: Destroy csp=%d" ), ( TInt )this );
       
   192 #endif
       
   193     // You MUST delete ip-cir entity before conn-manager entity.
       
   194     // refer to ImpsIpCirWatcherApi.h.
       
   195     delete iCirManager;
       
   196     iCirManager = NULL;
       
   197     iReceiver2->Destroy();
       
   198     delete iReceiver2;
       
   199     iReceiver2 = NULL;
       
   200     }
       
   201 
       
   202 // -----------------------------------------------------------------------------
       
   203 // CImpsCSPSession::ConstructL()
       
   204 // -----------------------------------------------------------------------------
       
   205 void CImpsCSPSession::ConstructL()
       
   206     {
       
   207 #ifndef _NO_IMPS_LOGGING_
       
   208     CImpsClientLogger::Log( _L( "CSPSession: ConstructL begins csp=%d **" ), ( TInt )this );
       
   209 #endif
       
   210 
       
   211     iTransportOut = CBufFlat::NewL( KImpsStreamSize / 2 );
       
   212     iTransportOut->ResizeL( KImpsStreamSize );
       
   213 
       
   214     iDecoder = NewDecoderL( this );
       
   215     iEncoder = NewEncoderL();
       
   216 
       
   217     iTidSapHistory = CImpsTidQueue::NewL();
       
   218     iTidCliHistory = CImpsTidQueue::NewL();
       
   219 
       
   220     iSnd = CImpsFields::NewL();
       
   221     iRcv = CImpsFields::NewL();
       
   222     iIdleTimer = new ( ELeave ) CImpsIdleTimer( *this, CActive::EPriorityStandard );
       
   223     iPDPIdleTimer = new ( ELeave ) CImpsPDPIdleTimer( *this, CActive::EPriorityStandard );
       
   224     iPDPOpenTimer = new ( ELeave ) CImpsPDPOpenTimer( *this, CActive::EPriorityStandard );
       
   225     iAliveMgr = CImpsAliveManager::NewL( *this );
       
   226 
       
   227     iSendQ = new ( ELeave ) CImpsSendQueued( * this, CActive::EPriorityStandard );
       
   228 
       
   229     // Just initialize undefined address
       
   230     iTCPAddr = HBufC::NewL( 1 );
       
   231     *iTCPAddr = KNullDesC;
       
   232 
       
   233     TPtrC8 myMime = iEncoder->MimeType();
       
   234     iReceiver2 = CImpsSendReceive2::NewL(
       
   235                      iFs, *this, *iTransportOut, myMime );
       
   236 
       
   237 #ifndef _NO_IMPS_LOGGING_
       
   238     CImpsClientLogger::Log( _L( "CSPSession:ConstructL ends" ) );
       
   239 #endif
       
   240     }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CImpsCSPSession::CloseAll()
       
   244 // CImpsServer::CloseEngine calls this. TransportStatus handles the callback.
       
   245 // -----------------------------------------------------------------------------
       
   246 void CImpsCSPSession::CloseAll( )
       
   247     {
       
   248 #ifndef _NO_IMPS_LOGGING_
       
   249     CImpsClientLogger::Log( _L( "CSPSession: CloseAll %d csp=%d" ), ( TInt )this );
       
   250 #endif
       
   251 
       
   252     NewState( EImpsCSPShuttingDown );
       
   253 
       
   254     if ( iIdleTimer )
       
   255         {
       
   256         iIdleTimer->Stop( );
       
   257         }
       
   258     iPollState = EImpsPollNone;
       
   259 #ifndef _NO_IMPS_LOGGING_
       
   260     CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
   261 #endif
       
   262 
       
   263     if ( iAliveMgr )
       
   264         {
       
   265         iAliveMgr->StopTimer( );
       
   266         }
       
   267 
       
   268     if ( iSendQ )
       
   269         {
       
   270         iSendQ->Cancel( );
       
   271         }
       
   272 
       
   273     if ( iCirManager )
       
   274         {
       
   275         iCirManager->CloseCh( 0xF );
       
   276         delete iCirManager;
       
   277         iCirManager = NULL;
       
   278         }
       
   279 
       
   280     // Close the transport
       
   281     if ( iReceiver2 )
       
   282         {
       
   283         iReceiver2->CloseTr( );
       
   284         }
       
   285     // TransportStatus handles rest of shut down activities
       
   286     }
       
   287 
       
   288 
       
   289 // -----------------------------------------------------------------------------
       
   290 // CImpsCSPSession::ClosePDP
       
   291 // called by - CImpsPDPIdleTimer
       
   292 // ClosePDP method needed to close PDP-context.
       
   293 // -----------------------------------------------------------------------------
       
   294 void CImpsCSPSession::ClosePDP()
       
   295     {
       
   296 #ifndef _NO_IMPS_LOGGING_
       
   297     CImpsClientLogger::Log( _L( "CSPSession: ClosePDP" ) );
       
   298 #endif
       
   299 
       
   300     if ( iPollState != EImpsPollCIR )
       
   301         {
       
   302 #ifndef _NO_IMPS_LOGGING_
       
   303         CImpsClientLogger::Log( _L( "CSPSession: ClosePDP IGNORED iPollState = %d****" ),
       
   304                                 iPollState );
       
   305 #endif
       
   306         return;
       
   307         }
       
   308     if ( IsPDPIdle() )
       
   309         {
       
   310 #ifndef _NO_IMPS_LOGGING_
       
   311         CImpsClientLogger::Log( _L( "CSPSession: ClosePDP PDP already IDLE ****" ) );
       
   312 #endif
       
   313         if ( iCSPState == EImpsCSPOnLineIdleEnd )
       
   314             {
       
   315 #ifndef _NO_IMPS_LOGGING_
       
   316             CImpsClientLogger::Log( _L( "CSPSession: ClosePDP -> EImpsPDPPendClose" ) );
       
   317 #endif
       
   318             // set pending close request if PDP is opening
       
   319             iPendingPDP = EImpsPDPPendClose;
       
   320             }
       
   321         return;
       
   322         }
       
   323 
       
   324     NewState( EImpsCSPOnLineIdleStart );
       
   325 
       
   326     // This does not close WAP-SMS-CIR
       
   327     if ( iCirManager )
       
   328         {
       
   329         iCirManager->CloseCh( 0xF );
       
   330         delete iCirManager;
       
   331         iCirManager = NULL;
       
   332         }
       
   333 
       
   334     // Close the transport
       
   335     if ( iReceiver2 )
       
   336         {
       
   337         iReceiver2->ClosePDP( );
       
   338         }
       
   339     // TransportStatus handles rest of shut down activities
       
   340     }
       
   341 
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CImpsCSPSession::OpenPDP
       
   345 // Called by LogoutL, SendAliveL, SendDataL, TransportStatus, SendAllQueued
       
   346 // Called by CIRMessageL directly and by the CImpsPDPTimer class too.
       
   347 // OpenPDP method needed to re-open PDP-context
       
   348 // -----------------------------------------------------------------------------
       
   349 TInt CImpsCSPSession::OpenPDP()
       
   350     {
       
   351 #ifndef _NO_IMPS_LOGGING_
       
   352     CImpsClientLogger::Log( _L( "CSPSession: OpenPDP" ) );
       
   353 #endif
       
   354     if ( !IsPDPIdle() )
       
   355         {
       
   356         // Nothing to do
       
   357 #ifndef _NO_IMPS_LOGGING_
       
   358         CImpsClientLogger::Log( _L( "CSPSession: OpenPDP IGNORED - not idle" ) );
       
   359 #endif
       
   360         return KErrAlreadyExists;
       
   361         }
       
   362     else if ( iCSPState == EImpsCSPOnLineIdleEnd )
       
   363         {
       
   364         // already opening
       
   365 #ifndef _NO_IMPS_LOGGING_
       
   366         CImpsClientLogger::Log( _L( "CSPSession: OpenPDP IGNORED - EImpsCSPOnLineIdleEnd" ) );
       
   367 #endif
       
   368         return KErrNotReady;
       
   369         }
       
   370     else if ( iCSPState == EImpsCSPOnLineIdleStart )
       
   371         {
       
   372 #ifndef _NO_IMPS_LOGGING_
       
   373         CImpsClientLogger::Log( _L( "CSPSession: OpenPDP -> EImpsPDPPendOpen" ) );
       
   374 #endif
       
   375         iPendingPDP = EImpsPDPPendOpen;
       
   376         return KErrNone;
       
   377         }
       
   378 
       
   379     NewState( EImpsCSPOnLineIdleEnd );
       
   380     TRAPD( errx, iReceiver2->OpenPDPL( SAP(), iIAP ) );
       
   381     if ( errx )
       
   382         {
       
   383         NewState( EImpsCSPOnLineIdle );
       
   384         // Does not matter which error code is returned. Used in Logout only
       
   385         // to start internal logout routines.
       
   386 #ifndef _NO_IMPS_LOGGING_
       
   387         CImpsClientLogger::Log( _L( "CSPSession: err: openpdp E1 ****" ) );
       
   388 #endif
       
   389         return KErrGeneral;
       
   390         }
       
   391     return KErrNone;
       
   392     // TransportStatus/transportError handles rest of open activities
       
   393     }
       
   394 
       
   395 // -----------------------------------------------------------------------------
       
   396 // CImpsCSPSession::LoginL
       
   397 // -----------------------------------------------------------------------------
       
   398 TPtrC CImpsCSPSession::LoginL(
       
   399     const TDesC& aUser,
       
   400     const TDesC& aPassword,
       
   401     const TDesC& aClientId,
       
   402     const TDesC& aSAP,
       
   403     TUint32 aAP,
       
   404     const TDesC& aKey1,
       
   405     const TDesC& aKey2,
       
   406     TTime aLoginExpiry,
       
   407     TBool aReactive )
       
   408     {
       
   409 #ifndef _NO_IMPS_LOGGING_
       
   410     CImpsClientLogger::Log( _L( "CSPSession: LoginL state=%d csp=%d" ), iCSPState, ( TInt )this );
       
   411 #endif
       
   412 
       
   413     // AOL Login
       
   414     if ( aKey1.Length() && aKey2.Length() )
       
   415         {
       
   416         // this should be the case anyway
       
   417         iSettings.iFourWayLogin = ETrue;
       
   418         delete iKey1;
       
   419         iKey1 = NULL;
       
   420         iKey1 = aKey1.AllocL();
       
   421         delete iKey2;
       
   422         iKey2 = NULL;
       
   423         iKey2 = aKey2.AllocL();
       
   424         }
       
   425     TPtrC tid ( KNullDesC );
       
   426 
       
   427     delete iSAP;
       
   428     iSAP = NULL;
       
   429     iSAP = aSAP.AllocL();
       
   430     iIAP = aAP;
       
   431 
       
   432     iPendingAlive = EFalse;
       
   433 #ifndef _NO_IMPS_LOGGING_
       
   434     CImpsClientLogger::Log( _L( "CSPSession: iPendingAlive->F" ) );
       
   435 #endif
       
   436 
       
   437     if ( iCSPState >= EImpsCSPLogged )
       
   438         {
       
   439 #ifndef _NO_IMPS_LOGGING_
       
   440         CImpsClientLogger::Log( _L( "CSPSession: err: Login when logged ***" ) );
       
   441 #endif
       
   442         User::Leave( KImpsErrorAlreadyLogged );
       
   443         }
       
   444     else if ( iCSPState == EImpsCSPDisconnecting )
       
   445         {
       
   446 #ifndef _NO_IMPS_LOGGING_
       
   447         CImpsClientLogger::Log( _L( "CSPSession: err: Login when CSP logging out ***" ) );
       
   448 #endif
       
   449         User::Leave(  KErrNotReady );
       
   450         }
       
   451     // Check that no active CSP session exists
       
   452     // This should not happen before login
       
   453     else if ( iReceiver2->NbrOfPending() >= KImpsMaxPending ||
       
   454               iCSPState == EImpsCSPLogging )
       
   455         {
       
   456 #ifndef _NO_IMPS_LOGGING_
       
   457         CImpsClientLogger::Log( _L( "CSPSession: err: Login when busy ***" ) );
       
   458 #endif
       
   459         User::Leave( KErrNotReady );
       
   460         }
       
   461     // Close old connections if any in re-login case (wrong psw first time e.g.)
       
   462     // The pending logout response is handled above, not here.
       
   463     else if ( iReceiver2->isConnected() )
       
   464         {
       
   465         // These are for re-login without logout after an error response
       
   466         NewState( EImpsCSPIdle );
       
   467         iPollState = EImpsPollNone;
       
   468 #ifndef _NO_IMPS_LOGGING_
       
   469         CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
   470         CImpsClientLogger::Log( _L( "CSPSession: err: transport was connected ***" ) );
       
   471 #endif
       
   472         iAliveMgr->StopTimer();
       
   473         iSendQ->Cancel();
       
   474         iIntStatus = EInternal_NOT_LOGGED;
       
   475         iReceiver2->CloseTr();
       
   476         User::Leave( KErrNotReady );
       
   477         }
       
   478 
       
   479     // aPassword cannot be NULL
       
   480     delete iLogPwd;
       
   481     iLogPwd = NULL;
       
   482     delete iUserId;
       
   483     iUserId = NULL;
       
   484     iLogPwd = aPassword.AllocL();
       
   485     iUserId = aUser.AllocL();
       
   486     iLogCID = aClientId;
       
   487     iLogoutTID = KNullDesC;
       
   488     iNegoExpiry = aLoginExpiry;
       
   489     iReactive = aReactive;
       
   490     TImpsSrvUtils::InitializeServices( iServices, iReactive );
       
   491 
       
   492     // Make a login request
       
   493     iSnd->Reset();
       
   494     tid.Set( GenerateTid() );
       
   495     iSnd->SetTidL( tid );
       
   496     iSnd->SetMessageType( EImpsLoginReq );
       
   497     // Session type is OUTBAND
       
   498     iSnd->SetSessionTypeL( EImpsOutband );
       
   499 
       
   500     TImpsDataAccessor myAccess( iSnd );
       
   501     CImpsKey* myKey = CImpsKey::NewLC();    // <<< myKey
       
   502 
       
   503     iAliveTime = iSettings.iAliveTime;
       
   504 
       
   505     if ( iSettings.iFourWayLogin == EFalse )
       
   506         {
       
   507         TImpsSDataUtils::CreateLoginReqL(
       
   508             myKey,
       
   509             &myAccess,
       
   510             aUser,
       
   511             iLogCID,
       
   512             LogPwd(),
       
   513             GenerateCookie(),
       
   514             iAliveTime );
       
   515         // set this, that response goes to the right place
       
   516         iLoginPhase = 2;
       
   517         }
       
   518     else
       
   519         {
       
   520         TImpsDigestSchema aSchema = EImpsMD5;
       
   521         TImpsSDataUtils::CreateLoginReqPhaseOneL(
       
   522             myKey,
       
   523             &myAccess,
       
   524             aUser,
       
   525             iLogCID,
       
   526             aSchema,
       
   527             GenerateCookie(),
       
   528             iAliveTime );
       
   529         // just to be sure
       
   530         iLoginPhase = 1;
       
   531         }
       
   532 
       
   533     // Add TImpsTransactionMode now
       
   534     myKey->Reset();
       
   535     TImpsSDataUtils::AddValuesFromArrayL(
       
   536         myKey,
       
   537         KTransModeElements,
       
   538         sizeof( KTransModeElements ) /
       
   539         sizeof( KTransModeElements[0] ) );
       
   540     myAccess.StoreIntegerL( myKey, EImpsRequest );
       
   541     CleanupStack::PopAndDestroy( 1 );   // >>> myKey
       
   542 
       
   543     // Save login id for error handling purposes
       
   544     iTempTid2 = tid;
       
   545 
       
   546     // Set WV version
       
   547     iSnd->SetCspVersion( iCSPVersion );
       
   548 
       
   549     // Encode login request
       
   550     iEncoder->EncodeMessageL( myAccess, *iTransportOut );
       
   551     iLastSent = EImpsLoginReq;
       
   552 
       
   553     delete iLogTid;
       
   554     iLogTid = NULL;
       
   555     iLogTid = tid.AllocL();
       
   556 
       
   557     // This does not leave immediately if network is not available
       
   558     NewState( EImpsCSPLogging );
       
   559     TRAPD( errx, iReceiver2->OpenL( tid, iSettings.iXmlLog, aSAP, aAP ) );
       
   560     if ( errx )
       
   561         {
       
   562         // In rare situations the previous call may leave
       
   563         NewState( EImpsCSPIdle );
       
   564         User::Leave( errx );
       
   565         }
       
   566 
       
   567     // iReceiver callback handles the rest of the login method.
       
   568     // This handles interrupted logout request as well as shut down interrupt
       
   569 
       
   570     iMsg = EImpsMessageNone;
       
   571 
       
   572     return tid;
       
   573     }
       
   574 
       
   575 // -----------------------------------------------------------------------------
       
   576 // CImpsCSPSession::LogoutL
       
   577 // Notice that subsession class prevents calling this in certain
       
   578 // situations, if not iLogged or not pending login operation.
       
   579 // Therefore shut down situation is not handled here.
       
   580 // -----------------------------------------------------------------------------
       
   581 TPtrC CImpsCSPSession::LogoutL( TBool aCancel )
       
   582     {
       
   583 #ifndef _NO_IMPS_LOGGING_
       
   584     CImpsClientLogger::Log( _L( "CSPSession: LogoutL state=%d cancel=%d csp=%d" ), iCSPState,
       
   585                             aCancel, ( TInt )this );
       
   586 #endif
       
   587 
       
   588     if ( iCSPState == EImpsCSPIdle )
       
   589         {
       
   590 #ifndef _NO_IMPS_LOGGING_
       
   591         CImpsClientLogger::Log( _L( "CSPSession: LogoutL LEAVES KImpsErrorNotLogged" ) );
       
   592 #endif
       
   593         iPendingPDP = EImpsPDPPendNone;
       
   594         iPendPDPLogout = EFalse;
       
   595         User::Leave( KImpsErrorNotLogged );
       
   596         }
       
   597 
       
   598     if ( iCancelLogin && aCancel )
       
   599         {
       
   600         // cancel login already requested!
       
   601         return TPtrC();
       
   602         }
       
   603 
       
   604     // Make a logout request (encode)
       
   605     TPtrC tid;
       
   606     tid.Set( GenerateTid() );
       
   607     iLogoutTID = tid;
       
   608     // Use iLogoutTID when loggin out later after PDP-open
       
   609     // Check if PDP is closed and start to re-open it here (Logout)
       
   610     if ( IsPDPIdle() )
       
   611         {
       
   612         // check this flag when PDP has been re-opened
       
   613         iPendPDPLogout = ETrue;
       
   614         if ( iCSPState == EImpsCSPOnLineIdle )
       
   615             {
       
   616             // E1: error handling; return boolean to speed up error handling
       
   617             // E2: fix:
       
   618             if ( OpenPDP() )
       
   619                 {
       
   620 #ifndef _NO_IMPS_LOGGING_
       
   621                 CImpsClientLogger::Log( _L( "CSPSession: err: Ex2 OpenPDP FAILS ****" ) );
       
   622 #endif
       
   623                 DoLogout();
       
   624                 }
       
   625             return tid;
       
   626             }
       
   627         }
       
   628 
       
   629     if ( iCSPState != EImpsCSPLogging )
       
   630         {
       
   631         // Clear buffers from old stuff
       
   632         DeleteRequests();
       
   633         DeleteTransactions();
       
   634         // Send Logout primitive and set state to EImpsCSPDisconnecting.
       
   635         TRAPD( errx, DoSendLogoutL( tid ) );
       
   636         if ( errx )
       
   637             {
       
   638 #ifndef _NO_IMPS_LOGGING_
       
   639             CImpsClientLogger::Log( _L( "CSPSession: DoSendLogoutL error %d ***" ), errx );
       
   640 #endif
       
   641             // Do logout routines immediately if transport gives an error
       
   642             DoLogout();
       
   643             // The following error code is handled in a special way in
       
   644             // client session classes.
       
   645             User::Leave( KImpsErrorTerminalOffLine );
       
   646             }
       
   647         }
       
   648     else // LoggingIn
       
   649         {
       
   650         if ( !aCancel )
       
   651             {
       
   652             iPendingLogout = ETrue;
       
   653 #ifndef _NO_IMPS_LOGGING_
       
   654             CImpsClientLogger::Log( _L( "CSPSession: iPendingLogout->TRUE ***" ) );
       
   655 #endif
       
   656             }
       
   657         else
       
   658             {
       
   659             iCancelLogin = ETrue;
       
   660 #ifndef _NO_IMPS_LOGGING_
       
   661             CImpsClientLogger::Log( _L( "CSPSession: iCancelLogin->TRUE ***" ) );
       
   662 #endif
       
   663             }
       
   664         // Logout must not ever fail so this must not leave.
       
   665         StartLoginCancel( );
       
   666         }
       
   667 
       
   668     return tid;
       
   669     }
       
   670 
       
   671 // -----------------------------------------------------------------------------
       
   672 // CImpsCSPSession::CirMessageL
       
   673 // -----------------------------------------------------------------------------
       
   674 void CImpsCSPSession::CirMessageL(
       
   675     const TDesC8& aCookie )
       
   676     {
       
   677 #ifndef _NO_IMPS_LOGGING_
       
   678     CImpsClientLogger::Log( _L( "CSPSession: CirMessageL csp=%d" ), ( TInt )this );
       
   679 #endif
       
   680 
       
   681     // if CIR is not negotiated then ignore
       
   682     if ( ( iSettings.iUDPWAPCIR != 2 && iSettings.iSMSWAPCIR != 2 &&
       
   683            iSettings.iTCPSCIR != 2 && iSettings.iUDPSCIR != 2 ) ||
       
   684          !IsNegotiated() )
       
   685         {
       
   686 #ifndef _NO_IMPS_LOGGING_
       
   687         CImpsClientLogger::Log( _L( "CSPSession: CirMessage IGNORED" ) );
       
   688 #endif
       
   689         return;
       
   690         }
       
   691 
       
   692     // check session cookie but not CSP-version.
       
   693     // CIR syntax: WVCI <CSP-version> <Session-cookie>
       
   694 
       
   695     TPtrC8 cookie = aCookie.Left( 4 );
       
   696     if ( cookie.CompareF( _L8( "WVCI" ) ) )
       
   697         {
       
   698 #ifndef _NO_IMPS_LOGGING_
       
   699         CImpsClientLogger::Log( _L( "CSPSession: CirMessage SYNTAX ERROR" ) );
       
   700 #endif
       
   701         User::Leave( KErrArgument );
       
   702         }
       
   703 
       
   704     cookie.Set( aCookie );
       
   705     // Find if the cookie exists in this push body
       
   706     if ( cookie.Find( iCookie8 ) == KErrNotFound )
       
   707         {
       
   708 #ifndef _NO_IMPS_LOGGING_
       
   709         CImpsClientLogger::Log( _L( "CSPSession: CirMessage COOKIE ERROR" ) );
       
   710 #endif
       
   711         User::Leave( KImpsErrorUnauthorized );
       
   712         }
       
   713 
       
   714     // reset PDP idle timer when CIR received
       
   715     iPDPIdleTimer->Reset();
       
   716 
       
   717     // If PDP-context is idle or shutting down then set pending open request.
       
   718     if ( IsPDPIdle() )
       
   719         {
       
   720         if ( iCSPState == EImpsCSPOnLineIdle ||
       
   721              iCSPState == EImpsCSPOnLineIdleStart )
       
   722             {
       
   723             iPendingPDP = EImpsPDPPendOpen;
       
   724             }
       
   725         if ( !iPollInResume )
       
   726             {
       
   727             iPollInResume = 1;
       
   728 #ifndef _NO_IMPS_LOGGING_
       
   729             CImpsClientLogger::Log( _L( "CSPSession: iPollInResume %d" ),
       
   730                                     iPollInResume );
       
   731 #endif
       
   732             }
       
   733         // This is a fix for cases when GPRS bearer event has not been received
       
   734 #ifndef _NO_IMPS_LOGGING_
       
   735         CImpsClientLogger::Log( _L( "CSPSession: CIR -> openPDP ****" ) );
       
   736 #endif
       
   737         OpenPDP();
       
   738         iPDPOpenTimer->Start( KImpsPDPRetryOpenTime );
       
   739         }
       
   740 
       
   741     // Send the actual Poll message
       
   742     else if ( iIntStatus == EInternal_ON_LINE )  // && !PDPIdle
       
   743         {
       
   744         TRAPD( errPoll, SendPollL() );
       
   745         if ( errPoll && !iPollInResume )
       
   746             {
       
   747             iPollInResume = 1;
       
   748 #ifndef _NO_IMPS_LOGGING_
       
   749             CImpsClientLogger::Log( _L( "CSPSession: iPollInResume %d" ), iPollInResume );
       
   750 #endif
       
   751             }
       
   752         }
       
   753     else  // NOT ON_LINE && !PDPIdle
       
   754         {
       
   755         // WAP SMS CIR causes OFF-LINE and therefore has to wait ON-LINE
       
   756         iPollState = EImpsPollPending;
       
   757 #ifndef _NO_IMPS_LOGGING_
       
   758         CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
   759 #endif
       
   760         }
       
   761     }
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // CImpsCSPSession::SendDataL
       
   765 // -----------------------------------------------------------------------------
       
   766 TPtrC CImpsCSPSession::SendDataL(
       
   767     CImpsFields* aFields, TInt aExpiry, TBool& aOwnerCh )
       
   768     {
       
   769 
       
   770 #ifndef _NO_IMPS_LOGGING_
       
   771     CImpsClientLogger::Log( _L( "CSPSession: SendDataL begins csp=%d" ), ( TInt )this );
       
   772 #endif
       
   773 
       
   774     // reset PDP idle timer
       
   775     iPDPIdleTimer->Reset();
       
   776 
       
   777     aOwnerCh = EFalse;
       
   778 
       
   779     // generate TID
       
   780     CImpsFields* fields = aFields;
       
   781     TPtrC tid;
       
   782     tid.Set( GenerateTid() );
       
   783     fields->SetTidL( tid );
       
   784     // Insert CSP Session-id
       
   785     fields->SetSessionIdL( iCSPSessionId );
       
   786     // Session-type
       
   787     fields->SetSessionTypeL( EImpsInband );
       
   788 
       
   789     TImpsDataAccessor myAccess( fields );
       
   790     CImpsKey* myKey = CImpsKey::NewLC();    // <<< myKey
       
   791 
       
   792     // Add TImpsTransactionMode now
       
   793     myKey->Reset();
       
   794     TImpsSDataUtils::AddValuesFromArrayL(
       
   795         myKey,
       
   796         KTransModeElements,
       
   797         sizeof( KTransModeElements ) /
       
   798         sizeof( KTransModeElements[0] ) );
       
   799     myAccess.StoreIntegerL( myKey, EImpsRequest );
       
   800 
       
   801     // API supports deliver method and thus do not overwrite it here anymore
       
   802 
       
   803     CleanupStack::PopAndDestroy( 1 );   // >>> myKey
       
   804 
       
   805     // We have to check if queued messages exist
       
   806     TBool queuedMsg = EFalse;
       
   807     queuedMsg = RequestExist();
       
   808 
       
   809     // if PDP-idle then queue request + start to open PDP
       
   810     TInt nbrPend = iReceiver2->NbrOfPending();
       
   811     if ( nbrPend >= KImpsMaxPending ||
       
   812          iIntStatus != EInternal_ON_LINE ||
       
   813          iTr >= iMultiTrans ||
       
   814          queuedMsg ||
       
   815          IsPDPIdle() )
       
   816         {
       
   817         // Transport adapter is busy so queue the request
       
   818         QueueClientRequestL( fields, aExpiry );
       
   819         aOwnerCh = ETrue;
       
   820         if ( iCSPState == EImpsCSPOnLineIdle )
       
   821             {
       
   822             // Try to open PDP only once, don't start open PDP timer.
       
   823             // The request will expiry if this fails anyway and it's
       
   824             // a task of application to retry sending of this message.
       
   825             OpenPDP( );
       
   826             }
       
   827         else if ( iCSPState == EImpsCSPOnLineIdleStart ||
       
   828                   iCSPState == EImpsCSPOnLineIdle )
       
   829             {
       
   830             iPendingPDP = EImpsPDPPendOpen;
       
   831 
       
   832             /* Notice:
       
   833              Thus CImpsConnManager DLL
       
   834              does not give bearer event for GPRS resume in all situations
       
   835              it is better to try to open the connection always.
       
   836             */
       
   837             OpenPDP();
       
   838             }
       
   839 
       
   840         else if ( queuedMsg )
       
   841             {
       
   842             // This must not leave because of the error is not message specific
       
   843             SendAllQueued();
       
   844             }
       
   845         }
       
   846     else
       
   847         {
       
   848         // Message sending should be possible without PDP open
       
   849         DoSendSingleL(
       
   850             &myAccess, tid, ( TImpsMessageType ) fields->MessageType() );
       
   851         }
       
   852 
       
   853 #ifndef _NO_IMPS_LOGGING_
       
   854     CImpsClientLogger::Log( _L( "CSPSession: SendData ends" ) );
       
   855 #endif
       
   856 
       
   857     return tid;
       
   858     }
       
   859 
       
   860 // -----------------------------------------------------------------------------
       
   861 // CImpsCSPSession::TransportResponseL
       
   862 // -----------------------------------------------------------------------------
       
   863 void CImpsCSPSession::TransportResponseL( HBufC8** aDataPtr )
       
   864     {
       
   865 #ifndef _NO_IMPS_LOGGING_
       
   866     CImpsClientLogger::Log( _L( "CSPSession: TransportResponseL csp=%d" ), ( TInt )this );
       
   867 #endif
       
   868 
       
   869     HBufC8* rawData = *aDataPtr;
       
   870 
       
   871     // reset PDP idle timer
       
   872     iPDPIdleTimer->Reset();
       
   873 
       
   874     SendAllQueued();
       
   875 
       
   876     TInt myError = KErrNone;
       
   877     // Handle pending logout here
       
   878     if ( iPendingLogout || iCancelLogin )
       
   879         {
       
   880         DoPendingLogout();
       
   881         return;
       
   882         }
       
   883 
       
   884     if ( rawData == NULL || rawData->Des().Length() == 0 )
       
   885         {
       
   886         // SAP did not send anything in the response
       
   887         iLastReceived = 0;
       
   888         // Increase adaptive polling time if necessary
       
   889         if ( iLastSent == EImpsPolling )
       
   890             {
       
   891             IncreasePollTime();
       
   892             }
       
   893         return;
       
   894         }
       
   895 
       
   896     if ( iLastSent != EImpsKeepAliveReq )
       
   897         {
       
   898         // Reset poll timer
       
   899         ResetPollTime();
       
   900         }
       
   901 
       
   902     if ( iRcv )
       
   903         {
       
   904         iRcv->Reset();
       
   905         }
       
   906     else
       
   907         {
       
   908         // QueueTidL may have leaved and this is NULL
       
   909         iRcv = CImpsFields::NewL();
       
   910         }
       
   911 
       
   912     CImpsDataAccessor* myAccess = CImpsDataAccessor::NewLC( iRcv ); // <<<
       
   913 
       
   914     TInt retCode = KErrNone;
       
   915 
       
   916 // ----------- NORMAL CASE -------------------------
       
   917 #ifndef _FAKE_RESPONSE
       
   918 
       
   919 #ifndef _NO_IMPS_LOGGING_
       
   920     CImpsClientLogger::Log( _L( "CSPSession: Gonna to call Decode" ) );
       
   921 #endif
       
   922     // Decode to iRcv
       
   923     iDecoder->DecodeMessageL( *myAccess, aDataPtr );
       
   924     retCode = iRcv->ResponseStatusL();
       
   925     // Decode errors cancel this method and error are
       
   926     // reported to client by expiry timers.
       
   927 
       
   928 #ifndef _NO_IMPS_LOGGING_
       
   929     CImpsClientLogger::Log( _L( "CSPSession: Decoded status = %d" ), iRcv->Status() );
       
   930     CImpsClientLogger::Log( _L( "CSPSession: Decoded ResponseStatus = %d" ),
       
   931                             retCode );
       
   932 #endif
       
   933 
       
   934 // ----------- NORMAL CASE ENDS -------------------------
       
   935 
       
   936 // ----------- TEST CASE -------------------------
       
   937 #endif  // ifndef _FAKE_RESPONSE
       
   938 
       
   939 #ifdef _FAKE_RESPONSE
       
   940     TImpsSrvTestUtils tests( *this, iFs );
       
   941     tests.MakeFakeResponseL( myAccess, aDataPtr );
       
   942 #endif
       
   943 // ----------- TEST CASE ENDS -------------------------
       
   944 
       
   945     // Message successfully received from SAP
       
   946     // Session-id check
       
   947     if ( iRcv->SessionTypeL() == EImpsInband )
       
   948         {
       
   949         TPtrC sesId = iRcv->SessionIdL();
       
   950         // This is case sensitive
       
   951         if ( sesId.Length( ) > 0 && sesId.Compare( iCSPSessionId ) )
       
   952             {
       
   953             // Invalid session id
       
   954             User::Leave( KImpsErrorSID );
       
   955             }
       
   956         }
       
   957 
       
   958     // KeepAlive handling
       
   959     iAliveMgr->CheckResp( retCode );
       
   960 
       
   961     // ---------------------------------
       
   962     // check if multiTrans messages
       
   963     // ---------------------------------
       
   964     TInt trs = myAccess->NbrOfTransactionsL( );
       
   965     if ( trs < 1 )
       
   966         {
       
   967         // If no transaction content then it is handled as encode error
       
   968         myError = KImpsErrorDecode;
       
   969         }
       
   970     else if ( trs == 1 )
       
   971         {
       
   972         // regular case, one transaction content in a transport messages
       
   973         // Update internal data structure (CImpsFields)
       
   974 #ifndef _FAKE_RESPONSE
       
   975         if ( !( myAccess->GetTransactionL( 0, NULL ) ) )
       
   976             {
       
   977             // internal error
       
   978             myError = KErrCorrupt;
       
   979             }
       
   980 #endif
       
   981         }
       
   982 
       
   983     // ----------------------------------
       
   984     // checking multiTrans messages ends
       
   985     // ----------------------------------
       
   986 
       
   987     // If error then stop further progress of transport response
       
   988     if ( myError )
       
   989         {
       
   990         User::Leave( myError );
       
   991         }
       
   992 
       
   993     // Check if PollRequest was requested in incoming transport message
       
   994     if ( iRcv->PollL() )
       
   995         {
       
   996         iPollWasRequested = ETrue;
       
   997 #ifndef _NO_IMPS_LOGGING_
       
   998         CImpsClientLogger::Log( _L( "CSPSession: iPollWasRequested->T in msg" ) );
       
   999 #endif
       
  1000         }
       
  1001     else
       
  1002         {
       
  1003         iPollWasRequested = EFalse;
       
  1004 #ifndef _NO_IMPS_LOGGING_
       
  1005         CImpsClientLogger::Log( _L( "CSPSession: iPollWasRequested->F in msg" ) );
       
  1006 #endif
       
  1007         }
       
  1008 
       
  1009     if ( trs > 1 )
       
  1010         {
       
  1011         delete iAllMessages;
       
  1012         iAllMessages = iRcv;
       
  1013         iRcv = CImpsFields::NewL();
       
  1014         }
       
  1015     else
       
  1016         {
       
  1017         // paranoid about memory leaks
       
  1018         delete iAllMessages;
       
  1019         iAllMessages = NULL;
       
  1020         }
       
  1021 
       
  1022     // ---------------------------------
       
  1023     // Send each new message to sessions
       
  1024     // ---------------------------------
       
  1025     for ( TInt i = 0; i < trs; i ++ )
       
  1026         {
       
  1027 
       
  1028         if ( trs == 1 )
       
  1029             {
       
  1030             // No need for split
       
  1031             }
       
  1032         else
       
  1033             {
       
  1034             // Data accessor points to the original iRcv (allMessages)
       
  1035             iRcv->Reset();
       
  1036 #ifndef _NO_IMPS_LOGGING_
       
  1037             CImpsClientLogger::Log( _L( "CSPSession: MULTI-TRANS nbr=%d" ), i );
       
  1038 #endif
       
  1039             if ( !( myAccess->GetTransactionL( i, iRcv ) ) )
       
  1040                 {
       
  1041 #ifndef _NO_IMPS_LOGGING_
       
  1042                 CImpsClientLogger::Log( _L( "CSPSession: Error with MultiTrans" ) );
       
  1043 #endif
       
  1044                 // error, continue
       
  1045                 continue;
       
  1046                 }
       
  1047             }
       
  1048 
       
  1049         iLastReceived = iRcv->MessageType();
       
  1050 
       
  1051 #ifndef _NO_IMPS_LOGGING_
       
  1052         CImpsClientLogger::Log( _L( "CSPSession: TransportResponse msg = 0x%x" ),
       
  1053                                 iLastReceived );
       
  1054 #endif
       
  1055 
       
  1056         // Check if csp Session startup routines needed
       
  1057         // TID is case sensitive
       
  1058         if ( ( iCSPState == EImpsCSPLogging || iCSPState == EImpsCSPNegotiation ) &&
       
  1059              ( iRcv->MessageType() == EImpsLoginRes ||
       
  1060                iRcv->MessageType() == EImpsClientCapabilityRes ||
       
  1061                iRcv->MessageType() == EImpsServiceRes ||
       
  1062                ( iRcv->MessageType() == EImpsStatus &&
       
  1063                  !iRcv->TidL().Compare( iTempTid2 ) ) ) )
       
  1064             {
       
  1065             SessionStartupL( iRcv );
       
  1066             }
       
  1067         // Sent events to all sub-sessions interested in this type of event
       
  1068         // This also handles login-resposes and removes the login-req from
       
  1069         // queues.
       
  1070         if ( iRcv->MessageType() != 0 &&
       
  1071              iRcv->MessageType() != EImpsClientCapabilityRes &&
       
  1072              iRcv->MessageType() != EImpsServiceRes &&
       
  1073              iLoginPhase != 2 )
       
  1074             {
       
  1075             RouteMessageL();
       
  1076             }
       
  1077         }  // for
       
  1078 
       
  1079     // CIR-error-flag check in WV 1.2.
       
  1080     // WV 1.1 messages returns always EFalse.
       
  1081     // Check this flag only if TCP/IP CIR channel is negotiated.
       
  1082     if ( !iTcpCIRError && iSettings.TCPSCIR() == 2 && IsLogged() )
       
  1083         {
       
  1084         // Close and re-open TCP/IP CIR if CIR flag is on.
       
  1085         TInt erx = KErrNone;
       
  1086         TRAP( erx, iTcpCIRError = TImpsSDataUtils::GetCIRL( myAccess ) );
       
  1087         // iTcpCIRError is reset in CirChOpened()
       
  1088         if ( iTcpCIRError )
       
  1089             {
       
  1090             if ( iCirManager )
       
  1091                 {
       
  1092                 iCirManager->CloseCh( KImpsCirTcp );
       
  1093                 }
       
  1094             TRAP( erx, DoStartIpCIRL() );
       
  1095             }
       
  1096         }
       
  1097 
       
  1098     CleanupStack::PopAndDestroy( 1 );   // >>> myAccess
       
  1099 
       
  1100     delete iAllMessages;
       
  1101     iAllMessages = NULL;
       
  1102 
       
  1103     SendAllQueued();
       
  1104 
       
  1105 #ifndef _NO_IMPS_LOGGING_
       
  1106     CImpsClientLogger::Log( _L( "CSPSession: TransportResponse ends" ) );
       
  1107 #endif
       
  1108 
       
  1109     }
       
  1110 
       
  1111 // -----------------------------------------------------------------------------
       
  1112 // CImpsCSPSession::TransportErrorL
       
  1113 // -----------------------------------------------------------------------------
       
  1114 void CImpsCSPSession::TransportErrorL(
       
  1115     const TDesC& aTID,
       
  1116     TInt aError )
       
  1117     {
       
  1118 #ifndef _NO_IMPS_LOGGING_
       
  1119     CImpsClientLogger::Log( _L( "CSPSession: TransportError err=%d tid=%S csp=%d" ), aError, &aTID, ( TInt )this );
       
  1120 #endif
       
  1121 
       
  1122     TImpsCSPState origCSP = iCSPState;
       
  1123     // reset PDP idle timer
       
  1124     iPDPIdleTimer->Reset();
       
  1125 
       
  1126     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1127 
       
  1128 
       
  1129     // Handle pending logout here
       
  1130     // CSP destroyer is started finally
       
  1131     if ( iPendingLogout || iCancelLogin )
       
  1132         {
       
  1133         NewState( EImpsCSPDisconnecting );
       
  1134         DoPendingLogout();
       
  1135         return;
       
  1136         }
       
  1137 
       
  1138     // Do not let the PDP start up again if it has just shut down.
       
  1139     if ( origCSP == EImpsCSPOnLineIdleEnd && aTID.Length() == 0 &&
       
  1140          aError == KImpsErrorNoIAP )
       
  1141         {
       
  1142 #ifndef _NO_IMPS_LOGGING_
       
  1143         CImpsClientLogger::Log( _L( "CSPSession: DON'T START UP PDP AGAIN ****" ) );
       
  1144 #endif
       
  1145         if ( iPollState > EImpsPollAdaptive )
       
  1146             {
       
  1147             iPollState = EImpsPollCIR;
       
  1148 #ifndef _NO_IMPS_LOGGING_
       
  1149             CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  1150 #endif
       
  1151             }
       
  1152         ResetPollTime();
       
  1153         iPendingAlive = EFalse;
       
  1154 #ifndef _NO_IMPS_LOGGING_
       
  1155         CImpsClientLogger::Log( _L( "CSPSession: iPendingAlive->F" ) );
       
  1156 #endif
       
  1157         NewState( EImpsCSPOnLineIdle );
       
  1158 
       
  1159         // KeepAlive handling
       
  1160         iAliveMgr->CheckError( aTID );
       
  1161 
       
  1162         // Discard all the current requests
       
  1163         // We change the error code for UI.
       
  1164         // First we have to check if there is Logout request so that
       
  1165         // it is completed with OK status!
       
  1166         if ( LogoutTID().Length() )
       
  1167             {
       
  1168 #ifndef _NO_IMPS_LOGGING_
       
  1169             CImpsClientLogger::Log( _L( "CSPSession: Err: Discard logout ****" ) );
       
  1170 #endif
       
  1171             // This is for normal logout response error, i.e. no pending logout nor login-cancel.
       
  1172             iServer.DiscardLogout( LogoutTID(), csp );
       
  1173             DoLogout();
       
  1174             }
       
  1175         iServer.DiscardRequests( EImpsEventAll, KImpsErrorBearerSuspended, csp, this );
       
  1176         return;
       
  1177         }
       
  1178 
       
  1179     // Let's call this to be sure that new messages are sent
       
  1180     SendAllQueued();
       
  1181 
       
  1182     // Reset poll timer to resume from error case
       
  1183     ResetPollTime();
       
  1184 
       
  1185     TInt myErr = KErrNone;
       
  1186 
       
  1187     if ( iRcv )
       
  1188         {
       
  1189         iRcv->Reset();
       
  1190         }
       
  1191     else
       
  1192         {
       
  1193         // QueueTidL may have leaved and this is NULL
       
  1194         iRcv = CImpsFields::NewL();
       
  1195         }
       
  1196 
       
  1197     // This ensures that login gets a response in 4-way login later phase
       
  1198     if ( origCSP == EImpsCSPLogging && !LogTid().CompareF( aTID ) )
       
  1199         {
       
  1200 #ifndef _NO_IMPS_LOGGING_
       
  1201         CImpsClientLogger::Log( _L( "CSPSession: Special LogTid ****" ) );
       
  1202 #endif
       
  1203         // Route response to a requestion client and later below do logout.
       
  1204         iRcv->SetTidL( LogTid() );
       
  1205         }
       
  1206     else
       
  1207         {
       
  1208         iRcv->SetTidL( aTID );
       
  1209         }
       
  1210     iRcv->SetMessageType( EImpsStatus );
       
  1211     iRcv->SetStatus( aError );
       
  1212     TRAP( myErr, RouteMessageL( ) );
       
  1213 
       
  1214     // KeepAlive handling
       
  1215     iAliveMgr->CheckError( aTID );
       
  1216 
       
  1217     if ( origCSP == EImpsCSPLogging )
       
  1218         {
       
  1219 #ifndef _NO_IMPS_LOGGING_
       
  1220         CImpsClientLogger::Log( _L( "CSPSession: err: Ex ****" ) );
       
  1221 #endif
       
  1222         DoLogout();
       
  1223         }
       
  1224     // If RouteMessage has not done internal logout then let's do it here
       
  1225     else if ( origCSP == EImpsCSPDisconnecting )
       
  1226         {
       
  1227 #ifndef _NO_IMPS_LOGGING_
       
  1228         CImpsClientLogger::Log( _L( "CSPSession: err: E6 ****" ) );
       
  1229 #endif
       
  1230         // Message type is used in subsession to prevent sending logout event twice
       
  1231         iServer.DiscardLogout( iLogoutTID, csp );
       
  1232         DoLogout();
       
  1233         }
       
  1234 
       
  1235     return;
       
  1236     }
       
  1237 
       
  1238 // -----------------------------------------------------------------------------
       
  1239 // CImpsCSPSession::RouteMessageL
       
  1240 // -----------------------------------------------------------------------------
       
  1241 void CImpsCSPSession::RouteMessageL(  )
       
  1242     {
       
  1243 #ifndef _NO_IMPS_LOGGING_
       
  1244     CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL begins csp=%d" ), ( TInt )this );
       
  1245 #endif
       
  1246 
       
  1247     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1248 
       
  1249     // *****************************************************
       
  1250     // First check keep alive reponses
       
  1251     // *****************************************************
       
  1252 
       
  1253     TInt32 resstatus = iRcv->ResponseStatusL();
       
  1254 
       
  1255     // KeepAlive time may be reset on fly
       
  1256     if ( iRcv->MessageType() == EImpsKeepAliveRes )
       
  1257         {
       
  1258         if ( resstatus != KImpsStatusOk )
       
  1259             {
       
  1260 #ifndef _NO_IMPS_LOGGING_
       
  1261             CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL ends 1" ) );
       
  1262 #endif
       
  1263             return;
       
  1264             }
       
  1265         // get new KeepAlive time if any
       
  1266         TInt newTime = 0;
       
  1267         TImpsDataAccessor myAc( iRcv );
       
  1268         if ( TImpsSDataUtils::GetKeepAliveL( &myAc, newTime ) )
       
  1269             {
       
  1270             iAliveTime = newTime;
       
  1271             iAliveMgr->StartTimer( iAliveTime );
       
  1272 #ifndef _NO_IMPS_LOGGING_
       
  1273             CImpsClientLogger::Log( _L( "Server: new AliveTime %d" ), iAliveTime );
       
  1274 #endif
       
  1275             }
       
  1276         // Keep alive response does not cause events to clients
       
  1277 #ifndef _NO_IMPS_LOGGING_
       
  1278         CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL ends 2" ) );
       
  1279 #endif
       
  1280         return;
       
  1281         }
       
  1282 
       
  1283     // *************************************************************
       
  1284     // Ignore informational messages from server status code 100-199
       
  1285     // *************************************************************
       
  1286     if ( resstatus >= 100 && resstatus < 200 )
       
  1287         {
       
  1288         iTr--;
       
  1289 #ifndef _NO_IMPS_LOGGING_
       
  1290         CImpsClientLogger::Log( _L( "CSPSession: 100-200 iTr = %d" ), iTr );
       
  1291         CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL ends 3" ) );
       
  1292 #endif
       
  1293         return;
       
  1294         }
       
  1295 
       
  1296     // *************************************************************
       
  1297     // Harmonize WV 1.1 and WV 1.2 logout responses
       
  1298     // *************************************************************
       
  1299     TImpsLogoutTrans logoutRsp = IsLogoutResp( iRcv );
       
  1300 
       
  1301     // *****************************************************
       
  1302     // Handle regular request
       
  1303     // *****************************************************
       
  1304 
       
  1305     // Check requests
       
  1306     TBool someFound = EFalse;
       
  1307     TBool notOrphan = EFalse;
       
  1308     TInt error = 0;
       
  1309     // The following sends logout reponse to a requesting client
       
  1310     TRAP( error, iServer.CheckRequestsL ( iRcv, someFound, csp ) );
       
  1311 
       
  1312     if ( someFound )
       
  1313         {
       
  1314         // Message was response to our request, login phase has not
       
  1315         // increased this counter, that's why if statement here
       
  1316         TrMinus();
       
  1317         }
       
  1318     else if ( iRcv->MessageType() != EImpsDisconnect )
       
  1319         {
       
  1320         // Check that SAP initiated TID is not sent to clients already.
       
  1321         if ( ValidateTid( ETrue ) )
       
  1322             {
       
  1323             // Notifications check.
       
  1324             notOrphan = iServer.CheckNotifications( iRcv, csp );
       
  1325             }
       
  1326         }
       
  1327 
       
  1328     // Check error that means cancelled CSP session
       
  1329     // notice: fullfill the list of serious erros
       
  1330     if ( logoutRsp != EImpsLogoutNone  ||
       
  1331          resstatus == 600 || resstatus == 601 || resstatus == 604 )
       
  1332         {
       
  1333         TInt myOpId = 0;
       
  1334         if ( logoutRsp == EImpsLogoutSAP )
       
  1335             {
       
  1336             // Detect SAP initiated logout. disconnect primitive and
       
  1337             // TID not matching to our own logout TID.
       
  1338             myOpId = KImpsNullId;
       
  1339             }
       
  1340         // Both logout callback events and Status change events
       
  1341         // are sent here in logout.
       
  1342         DoLogoutNow( myOpId );
       
  1343 #ifndef _NO_IMPS_LOGGING_
       
  1344         CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL ends 4" ) );
       
  1345 #endif
       
  1346         return;
       
  1347         }
       
  1348 
       
  1349     // No reason to do this:
       
  1350     // if ( someFound ) notOrphan = ETrue;
       
  1351 
       
  1352     // If the message was not a response to our TID then it was SAP originated
       
  1353     // Update pending transaction queue
       
  1354     if ( ( iRcv->MessageType() != EImpsDisconnect ) &&
       
  1355          ( iRcv->MessageType() != EImpsMessageNone ) &&
       
  1356          ( iRcv->MessageType() != EImpsStatus ) &&
       
  1357          ( !someFound )
       
  1358        )
       
  1359         {
       
  1360         // Make SAP response to wait actions
       
  1361         QueueTidL( !notOrphan );
       
  1362         }
       
  1363 
       
  1364 #ifndef _NO_IMPS_LOGGING_
       
  1365     CImpsClientLogger::Log( _L( "CSPSession: RouteMessageL ends 5" ) );
       
  1366 #endif
       
  1367     }
       
  1368 
       
  1369 // -----------------------------------------------------------------------------
       
  1370 // CImpsCSPSession::GetNextMessageL
       
  1371 // Called by SendReceive2
       
  1372 // -----------------------------------------------------------------------------
       
  1373 void CImpsCSPSession::GetNextMessageL( )
       
  1374     {
       
  1375 
       
  1376 #ifndef _NO_IMPS_LOGGING_
       
  1377     CImpsClientLogger::Log( _L( "CSPSession: GetNextMessageL begins" ) );
       
  1378 #endif
       
  1379 
       
  1380     // Use this to generate response for SAP intiated transactions
       
  1381     iSnd->Reset();
       
  1382 
       
  1383     // Rejected, nothing to send
       
  1384     if ( !IsLogged() )
       
  1385         {
       
  1386         return;
       
  1387         }
       
  1388 
       
  1389     // Send next buffered user request if any
       
  1390     // search. Not immediately, but via active object scheduler
       
  1391     SendAllQueued();
       
  1392 
       
  1393     iLastSent = 0;
       
  1394     return;
       
  1395     }
       
  1396 
       
  1397 // -----------------------------------------------------------------------------
       
  1398 // CImpsCSPSession::CheckExpiry
       
  1399 // -----------------------------------------------------------------------------
       
  1400 void CImpsCSPSession::CheckExpiry(
       
  1401     TImpsEventType aType, const TTime aExpiry  )
       
  1402     {
       
  1403 #ifndef _NO_IMPS_LOGGING_
       
  1404     CImpsClientLogger::Log( _L( "CSPSession: CheckExpiry begins" ) );
       
  1405 #endif
       
  1406 
       
  1407     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1408 
       
  1409     // Login negotiation phase is a special case.
       
  1410     // Access timer handles that.
       
  1411     // Because of there may be messages not initiated by
       
  1412     // API methods, server must check special time-out variable iNegoExpiry.
       
  1413     // Internal iRequestList cannot be used for that purpose
       
  1414     // because of requests are deleted after transport has
       
  1415     // got them succesfully, but we are not satisfied until get response.
       
  1416 
       
  1417     if ( IsLogged() && !IsNegotiated() && iNegoExpiry < aExpiry )
       
  1418         {
       
  1419         // Expired negotiation in session startup negotiation
       
  1420         TInt errorCode = KErrTimedOut;
       
  1421         switch ( iMsg )
       
  1422             {
       
  1423             case EImpsClientCapabilityReq:
       
  1424                 errorCode = KImpsErrorCapabilities;
       
  1425                 break;
       
  1426             case EImpsServiceReq:
       
  1427                 errorCode = KImpsErrorServices;
       
  1428                 break;
       
  1429             default:
       
  1430                 break;
       
  1431             }
       
  1432         iServer.SendErrorEvent( EImpsEventServerLogin, errorCode, 0, csp );
       
  1433         // goto to NOT_LOGGED
       
  1434         DoLogout();
       
  1435         }
       
  1436     else if ( iCSPState == EImpsCSPDisconnecting && iNegoExpiry < aExpiry )
       
  1437         {
       
  1438         if ( iCancelLogin || iPendingLogout )
       
  1439             {
       
  1440             DoPendingLogout();
       
  1441             }
       
  1442         else
       
  1443             {
       
  1444             iServer.DiscardLogout( LogoutTID(), csp );
       
  1445             // goto to NOT_LOGGED
       
  1446             DoLogout();
       
  1447             }
       
  1448         }
       
  1449     else if ( iCSPState == EImpsCSPLogging && iNegoExpiry < aExpiry )
       
  1450         {
       
  1451 #ifndef _NO_IMPS_LOGGING_
       
  1452         CImpsClientLogger::Log( _L( "CSPSession: CheckExpiry in EImpsCSPLogging ***" ) );
       
  1453 #endif
       
  1454         iServer.DiscardRequests( aType, aExpiry, csp, this );
       
  1455         DoLogout();
       
  1456         }
       
  1457     else
       
  1458         {
       
  1459         // Regular mode.
       
  1460         // Go through all sessions (each having an own request list)
       
  1461         // The following ends up calling CancelTrans and there
       
  1462         // we can check if login or logout is expired and change the
       
  1463         // iCSPState.
       
  1464         iServer.DiscardRequests( aType, aExpiry, csp, this );
       
  1465         }
       
  1466     }
       
  1467 
       
  1468 // -----------------------------------------------------------------------------
       
  1469 // CImpsCSPSession::SessionStartupL
       
  1470 // -----------------------------------------------------------------------------
       
  1471 void CImpsCSPSession::SessionStartupL( CImpsFields* aFields )
       
  1472     {
       
  1473 #ifndef _NO_IMPS_LOGGING_
       
  1474     CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL begins csp=%d" ), ( TInt )this );
       
  1475 #endif
       
  1476 
       
  1477     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1478     TInt errx = KErrNone;
       
  1479     TrMinus();
       
  1480 
       
  1481     // check if error for 2-way login
       
  1482     if ( ( !IsLogged() ) &&
       
  1483          (
       
  1484              aFields->MessageType() == EImpsLoginRes ||
       
  1485              aFields->MessageType() == EImpsStatus ) &&
       
  1486          aFields->ResponseStatusL() != KImpsStatusOk &&
       
  1487          !iSettings.iFourWayLogin
       
  1488        )
       
  1489         {
       
  1490         // RouteMessageL handles errors if iLoginPhase != 2
       
  1491         // iLoginPhase starts from 2 in 2-way login
       
  1492         // See LoginL method
       
  1493         NewState( EImpsCSPIdle );
       
  1494         iReceiver2->CloseTr();
       
  1495         return;
       
  1496         }
       
  1497 
       
  1498     // Login response, 4-way login phase one
       
  1499     // *************************************
       
  1500     if ( aFields->MessageType() == EImpsLoginRes &&
       
  1501          aFields->Status() == KErrNone &&
       
  1502          ( aFields->ResponseStatusL() == KImpsStatusOk ||
       
  1503            aFields->ResponseStatusL() == 401 ) &&
       
  1504          iLoginPhase == 1 )
       
  1505         {
       
  1506 #ifndef _NO_IMPS_LOGGING_
       
  1507         CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL 4-login phase one" ) );
       
  1508 #endif
       
  1509         iLoginPhase++;
       
  1510         TRAP( errx, HandleLoginResponseL( aFields ) );
       
  1511         if ( errx )
       
  1512             {
       
  1513             iServer.DiscardRequest( LogTid(), EImpsEventServerLogin, errx, csp );
       
  1514             NewState( EImpsCSPIdle );
       
  1515             }
       
  1516         return;
       
  1517         }   // LOGIN RESPONSE1
       
  1518 
       
  1519     // Login response, 4-way login phase two or 2-way login
       
  1520     // ****************************************************
       
  1521     // save session id if received
       
  1522     if ( aFields->MessageType() == EImpsLoginRes &&
       
  1523          aFields->Status() == KErrNone &&
       
  1524          aFields->ResponseStatusL() == KImpsStatusOk &&
       
  1525          iLoginPhase == 2 )
       
  1526         {
       
  1527         iLoginPhase++;
       
  1528 #ifndef _NO_IMPS_LOGGING_
       
  1529         CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL 4-login phase two" ) );
       
  1530 #endif
       
  1531         TImpsDataAccessor myAc( aFields );
       
  1532 
       
  1533         TPtrC newId;
       
  1534         TImpsSDataUtils::GetLoginSessionIDL( &myAc, newId );
       
  1535         // protect us against illegal data from SAP
       
  1536         if ( newId.Length() > KImpsMaxSID )
       
  1537             {
       
  1538             User::Leave( KErrCorrupt );
       
  1539             }
       
  1540         iCSPSessionId = newId;
       
  1541 
       
  1542         // get TimeToLive
       
  1543         TInt newTime( 0 );
       
  1544         if ( TImpsSDataUtils::GetKeepAliveL( &myAc, newTime ) )
       
  1545             {
       
  1546             iAliveTime = newTime;
       
  1547             }
       
  1548 
       
  1549         NewState( EImpsCSPLogged );
       
  1550         // This is next message to be sent
       
  1551         iMsg = EImpsClientCapabilityReq;
       
  1552 
       
  1553         // KeepAlive timer started when logged in
       
  1554         iAliveMgr->StartTimer( iAliveTime );
       
  1555         // Start polling timer with a static value to be sure that
       
  1556         // something is received if SAP happened to send an empty response.
       
  1557         // After capability negotiation a proper value is set for polling timer.
       
  1558         iPollState = EImpsPollAdaptive;
       
  1559         iIdleTimer->Start( iSettings.iMaxPollTime );
       
  1560 #ifndef _NO_IMPS_LOGGING_
       
  1561         CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  1562         CImpsClientLogger::Log( _L( "CSPSession: PollTime %d" ), iSettings.iMaxPollTime );
       
  1563         CImpsClientLogger::Log( _L( "CSPSession: AliveTime %d" ), iAliveTime );
       
  1564 #endif
       
  1565 
       
  1566         // Let's send Client Capability request
       
  1567         TRAP( errx, DoSendClientCapabilityReqL() );
       
  1568         if ( errx )
       
  1569             {
       
  1570             TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1571             iServer.SendErrorEvent( EImpsEventServerLogin,
       
  1572                                     KImpsErrorCapabilities, 0, csp );
       
  1573             }
       
  1574         return;
       
  1575         }   // LOGIN RESPONSE
       
  1576 
       
  1577 
       
  1578     // Client capability response
       
  1579     // ***************************
       
  1580     if ( aFields->MessageType() == EImpsClientCapabilityRes &&
       
  1581          aFields->Status() == KErrNone &&
       
  1582          IsLogged() )
       
  1583         {
       
  1584 #ifndef _NO_IMPS_LOGGING_
       
  1585         CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL ClientCapabality" ) );
       
  1586 #endif
       
  1587         TRAP( errx, HandleClientCapabilityResL ( aFields ) );
       
  1588         if ( errx )
       
  1589             {
       
  1590             TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1591             iServer.SendErrorEvent( EImpsEventServerLogin, KImpsErrorCapabilities, 0, csp );
       
  1592             NewState( EImpsCSPLogged );
       
  1593             }
       
  1594         // Let's send Service Negotiation request
       
  1595         TRAP( errx, DoSendServiceNegotiationReqL () );
       
  1596         if ( errx )
       
  1597             {
       
  1598             TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1599             iServer.SendErrorEvent( EImpsEventServerLogin, KImpsErrorServices, 0, csp );
       
  1600             NewState( EImpsCSPLogged );
       
  1601             }
       
  1602         return;
       
  1603         }
       
  1604 
       
  1605     // Service Negotiation response
       
  1606     // ****************************
       
  1607     if ( aFields->MessageType() == EImpsServiceRes &&
       
  1608          aFields->Status() == KErrNone &&
       
  1609          IsLogged() )
       
  1610         {
       
  1611 
       
  1612 #ifndef _NO_IMPS_LOGGING_
       
  1613         CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL ServiceRes" ) );
       
  1614 #endif
       
  1615         iTempTid2 = KNullDesC;
       
  1616 
       
  1617         if ( aFields->MessageType() == EImpsServiceRes )
       
  1618             {
       
  1619             TImpsDataAccessor myAccess( aFields );
       
  1620             // Calculate agreed features and functions
       
  1621             TImpsSrvUtils::DiscardServicesL(
       
  1622                 &myAccess,
       
  1623                 &iServices );
       
  1624             }
       
  1625 
       
  1626         // WV engine state in ON_LINE now
       
  1627         iIntStatus = EInternal_ON_LINE;
       
  1628         NewState( EImpsCSPOnLine );
       
  1629         iMsg = EImpsMessageNone;
       
  1630 
       
  1631 #ifndef _NO_IMPS_LOGGING_
       
  1632         CImpsClientLogger::Log( _L( "CSPSession: status ON_LINE" ) );
       
  1633 #endif
       
  1634         // Send events to clients
       
  1635         iServer.TransportStatus( EInternal_ON_LINE, this );
       
  1636 
       
  1637         // Start PDP idle time if WAP-SMS-CIR is negotiated as only CIR channel.
       
  1638         if ( iSettings.iSMSWAPCIR == 2 ||
       
  1639              iSettings.iUDPWAPCIR == 2 ||
       
  1640              iSettings.iTCPSCIR == 2 ||
       
  1641              iSettings.iUDPSCIR == 2 )
       
  1642             {
       
  1643             // goto CIR-polling-mode
       
  1644             iPollState = EImpsPollCIR;
       
  1645             iPollTime = iSettings.CIRModePollTime();
       
  1646             iIdleTimer->Start( iPollTime );
       
  1647 #ifndef _NO_IMPS_LOGGING_
       
  1648             CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  1649             CImpsClientLogger::Log( _L( "CSPSession: iPollTime %d" ), iPollTime );
       
  1650 #endif
       
  1651             }
       
  1652         if ( iSettings.iSMSWAPCIR == 2 )
       
  1653             {
       
  1654             // PDP Idle timer closes PDP-context
       
  1655             iPDPIdleTimer->Start( iSettings.PDPExpiryTime() );
       
  1656             }
       
  1657 
       
  1658         TInt errxy = KErrNone;
       
  1659         TRAP( errxy, DoStartIpCIRL() );
       
  1660         }
       
  1661 
       
  1662     // Error handling in negotiation phase AND FOR 4-WAY-LOGIN
       
  1663     // ********************************************************
       
  1664     if ( ( aFields->Status() != KErrNone ) ||
       
  1665          ( aFields->ResponseStatusL() != KImpsStatusOk &&
       
  1666            aFields->ResponseStatusL() != 0 ) )
       
  1667         {
       
  1668         TInt errorCode = KErrNone;
       
  1669 #ifndef _NO_IMPS_LOGGING_
       
  1670         CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL Error handling %d" ), iMsg );
       
  1671 #endif
       
  1672         switch ( iMsg )
       
  1673             {
       
  1674             case EImpsClientCapabilityReq:
       
  1675                 errorCode = KImpsErrorCapabilities;
       
  1676                 break;
       
  1677             case EImpsServiceReq:
       
  1678                 errorCode = KImpsErrorServices;
       
  1679                 break;
       
  1680             default:
       
  1681                 break;
       
  1682             }
       
  1683         if ( errorCode )
       
  1684             {
       
  1685             TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  1686             iServer.SendErrorEvent( EImpsEventServerLogin, errorCode, 0, csp );
       
  1687             // We assume that an application will call logout in this case
       
  1688             // and thus we do not close PDP here.
       
  1689             }
       
  1690         else
       
  1691             {
       
  1692             // RouteMessageL handles errors if iLoginPhase != 2
       
  1693             NewState( EImpsCSPIdle );
       
  1694             // routeMessaegL does not close PDP context so let't do it now
       
  1695             iReceiver2->CloseTr();
       
  1696             }
       
  1697         }
       
  1698 #ifndef _NO_IMPS_LOGGING_
       
  1699     CImpsClientLogger::Log( _L( "CSPSession: SessionStartupL ends" ) );
       
  1700 #endif
       
  1701     }
       
  1702 
       
  1703 // -----------------------------------------------------------------------------
       
  1704 // CImpsCSPSession::DoSendClientCapabilityReqL
       
  1705 // -----------------------------------------------------------------------------
       
  1706 void CImpsCSPSession::DoSendClientCapabilityReqL ()
       
  1707     {
       
  1708     CImpsFields* tempFields = CImpsFields::NewL();
       
  1709     CleanupStack::PushL( tempFields );  // <<< tempFields
       
  1710     tempFields->SetMessageType( EImpsClientCapabilityReq );
       
  1711     tempFields->SetSessionTypeL( EImpsInband );
       
  1712     iTempTid2 = GenerateTid();
       
  1713     TImpsDataAccessor myAccess( tempFields );
       
  1714 
       
  1715     iMultiTrans = iSettings.iMultiTrans;
       
  1716     iPollTime = iSettings.iPollTime;
       
  1717 
       
  1718 #ifndef _NO_IMPS_LOGGING_
       
  1719     CImpsClientLogger::Log( _L( "CSPSession: MaxParserSize=%d" ), iSettings.MaximumParserSize() );
       
  1720     CImpsClientLogger::Log( _L( "CSPSession: MaxMessageSize=%d" ), iSettings.MaximumMessageSize() );
       
  1721 #endif
       
  1722 
       
  1723     TImpsSDataUtils::CreateClientCapabilityReqL(
       
  1724         &myAccess,
       
  1725         iCSPSessionId,
       
  1726         iTempTid2,
       
  1727         iLogCID,
       
  1728         iMultiTrans,
       
  1729         iPollTime,
       
  1730         iSettings );
       
  1731     // Put Client Capability request into queue to wait sending
       
  1732     // Do not copy but add this instance.
       
  1733     // Negotiation phase expiry time is saved in iNegoExpiry so does not
       
  1734     // matter what we set here.
       
  1735     iMsg = EImpsClientCapabilityReq;
       
  1736     QueueClientRequestL( tempFields, 0, EFalse );
       
  1737     SendAllQueued();
       
  1738     CleanupStack::Pop( 1 ); // tempFields  >>>
       
  1739     iNegoExpiry = iServer.ExpiryTime( EImpsEventServerLogin );
       
  1740     NewState( EImpsCSPNegotiation );
       
  1741     }
       
  1742 
       
  1743 // -----------------------------------------------------------------------------
       
  1744 // CImpsCSPSession::DoSendServiceNegotiationReqL
       
  1745 // -----------------------------------------------------------------------------
       
  1746 void CImpsCSPSession::DoSendServiceNegotiationReqL()
       
  1747     {
       
  1748     iMsg = EImpsServiceReq;
       
  1749     CImpsFields* tempFields = CImpsFields::NewL();
       
  1750     CleanupStack::PushL( tempFields );      // <<< tempfields
       
  1751     tempFields->SetMessageType( EImpsServiceReq );
       
  1752     tempFields->SetSessionTypeL( EImpsInband );
       
  1753     iTempTid2 = GenerateTid();
       
  1754     TImpsDataAccessor myAcc( tempFields );
       
  1755 
       
  1756     // Initialize the iServices again (in case of re-login)
       
  1757     TImpsSrvUtils::InitializeServices( iServices, iReactive );
       
  1758     TImpsSDataUtils::CreateServiceRequestL(
       
  1759         &myAcc,
       
  1760         iServices,
       
  1761         iCSPSessionId,
       
  1762         iTempTid2,
       
  1763         iLogCID,
       
  1764         iReactive );
       
  1765 
       
  1766     // Put Service Negotiation request into queue to wait sending.
       
  1767     // Negotiation phase expiry time is saved in iNegoExpiry so does not
       
  1768     // matter what we set here.
       
  1769     QueueClientRequestL( tempFields, 0, EFalse );
       
  1770     SendAllQueued();
       
  1771     CleanupStack::Pop( 1 );         // >>> tempFields
       
  1772     iNegoExpiry = iServer.ExpiryTime( EImpsEventServerLogin );
       
  1773     NewState( EImpsCSPNegotiation );
       
  1774     }
       
  1775 
       
  1776 // -----------------------------------------------------------------------------
       
  1777 // CImpsCSPSession::HandleLoginResponseL
       
  1778 // -----------------------------------------------------------------------------
       
  1779 void CImpsCSPSession::HandleLoginResponseL ( CImpsFields* aFields )
       
  1780     {
       
  1781     // protect us against illegal data from SAP
       
  1782     TImpsDataAccessor myAc( aFields );
       
  1783 
       
  1784     TPtrC newId;
       
  1785     TImpsSDataUtils::GetLoginSessionIDL( &myAc, newId );
       
  1786     if ( newId.Length() > KImpsMaxSID )
       
  1787         {
       
  1788         User::Leave( KErrCorrupt );
       
  1789         }
       
  1790     iCSPSessionId = newId;
       
  1791 
       
  1792     TDesC8* nonce = NULL;
       
  1793     CImpsKey* myKey = CImpsKey::NewLC();
       
  1794     myKey->AddL( EImpsKeySession );
       
  1795     myKey->AddL( EImpsKeyTransaction );
       
  1796     myKey->AddL( EImpsKeyTransactionContent );
       
  1797     myKey->AddL( EImpsKeyLogin_Response );
       
  1798     myKey->AddL( EImpsKeyDigestSchema );
       
  1799     TInt schema;
       
  1800     TBool sendPwd = myAc.RestoreIntegerL( myKey, schema );
       
  1801     if ( sendPwd )
       
  1802         {
       
  1803         if ( schema == EImpsPWD )
       
  1804             {
       
  1805             // Now we have to send the PWD
       
  1806             sendPwd = ETrue;
       
  1807             }
       
  1808         else
       
  1809             sendPwd = EFalse;
       
  1810         }
       
  1811     myKey->PopL();
       
  1812     myKey->AddL( EImpsKeyNonce );
       
  1813     ( void )myAc.RestoreDesc8L( myKey, nonce );
       
  1814     TInt newTime( 0 );
       
  1815     if ( TImpsSDataUtils::GetKeepAliveL( &myAc, newTime ) )
       
  1816         {
       
  1817         iAliveTime = newTime;
       
  1818         }
       
  1819 
       
  1820     TImpsSDataUtils::SetResultStatusL( myKey, &myAc, KImpsStatusOk );
       
  1821 
       
  1822     CleanupStack::PopAndDestroy( 1 );
       
  1823     CImpsFields* tempFields = CImpsFields::NewL();
       
  1824     CleanupStack::PushL( tempFields );
       
  1825     tempFields->SetMessageType( EImpsLoginReq );
       
  1826     iTempTid2 = LogTid();
       
  1827 
       
  1828     TImpsDataAccessor myAcc( tempFields );
       
  1829 
       
  1830     TImpsSDataUtils::CreateLoginReqPhaseTwoL(
       
  1831         sendPwd,
       
  1832         &myAcc,
       
  1833         iCSPSessionId,
       
  1834         LogTid(),
       
  1835         UserId(),
       
  1836         iLogCID,
       
  1837         LogPwd(),
       
  1838         nonce,
       
  1839         iCookie,
       
  1840         iAliveTime,
       
  1841         iKey1,
       
  1842         iKey2 );
       
  1843 
       
  1844     iMsg = EImpsMessageNone;
       
  1845 
       
  1846     // Send 2nd login phase request
       
  1847     // Login expiry time is saved in iNegoExpiry so no need to calculate it here.
       
  1848     QueueClientRequestL( tempFields, 0, EFalse );
       
  1849     SendAllQueued();
       
  1850 
       
  1851     CleanupStack::Pop( 1 );
       
  1852     delete iKey1; // not needed anymore
       
  1853     iKey1 = NULL;
       
  1854     delete iKey2; // not needed anymore
       
  1855     iKey2 = NULL;
       
  1856     }
       
  1857 
       
  1858 // -----------------------------------------------------------------------------
       
  1859 // CImpsCSPSession::HandleClientCapabilityResL
       
  1860 // -----------------------------------------------------------------------------
       
  1861 void CImpsCSPSession::HandleClientCapabilityResL ( CImpsFields* aFields )
       
  1862     {
       
  1863     iTempTid2 = KNullDesC;
       
  1864 
       
  1865     TImpsDataAccessor myAccess( aFields );
       
  1866     CImpsKey* myKey = CImpsKey::NewLC();   // <<< myKey
       
  1867 
       
  1868     const TImpsContent* myContent = KClientCapabilityResElements;
       
  1869     TImpsSDataUtils::AddValuesFromArrayL(
       
  1870         myKey,
       
  1871         myContent,
       
  1872         sizeof( KClientCapabilityResElements ) /
       
  1873         sizeof( KClientCapabilityResElements[0] ) );
       
  1874 
       
  1875 
       
  1876     // WV CSP versions are not fully compatible
       
  1877     if ( iCSPVersion == EImpsCspVersion11 )
       
  1878         {
       
  1879         // WV 1.1 code
       
  1880         // CapabilityList element
       
  1881         myKey->AddL( CREATEKEY( EImpsKeyCapabilityList, 0 ) );
       
  1882 
       
  1883         // We are interested in supported CIR methods, TCP/IP CIR addresses
       
  1884         // and polltime.
       
  1885         // SupportedBearer is ignored because of we support HTTP only.´
       
  1886         // WV 1.1 specific ClientID is ignored too.
       
  1887         // AcceptedContentType not in a response based on
       
  1888         // Corrigenda Catalog for WV ver 1.1
       
  1889         }
       
  1890     else
       
  1891         {
       
  1892         // WV 1.2 code
       
  1893         // AgreedCapabilityList element
       
  1894         myKey->AddL( CREATEKEY( EImpsKeyAgreedCapabilityList, 0 ) );
       
  1895 
       
  1896         // We are interested in supported CIR methods, TCP/IP CIR addresses
       
  1897         // and polltime.
       
  1898         // SupportedBearer is ignored because of we support HTTP only.
       
  1899         // CIRURL is ignored too because of it is for HTTP CIR binding only
       
  1900         // that is not supported by this sw.
       
  1901         // <!ELEMENT AgreedCapabilityList
       
  1902         //   (SupportedBearer*, SupportedCIRMethod*, TCPAddress?, TCPPort?,
       
  1903         //   ServerPollMin?, CIRURL?)>
       
  1904         }
       
  1905 
       
  1906     // ServerPollMin
       
  1907     myKey->AddL( CREATEKEY( EImpsKeyServerPollMin, 0 ) );
       
  1908     TInt myInt;
       
  1909     if ( myAccess.RestoreIntegerL( myKey, myInt ) )
       
  1910         {
       
  1911         if ( myInt > iPollTime )
       
  1912             {
       
  1913             iPollTime = myInt;
       
  1914             }
       
  1915         }
       
  1916     // Save new minimum polling time value in settings
       
  1917     iSettings.iPollTime = iPollTime;
       
  1918 
       
  1919     // Reset polling timer, ServerPollMin is optional, but if we do not get
       
  1920     // new value then we start to us our own suggestion
       
  1921     iPollState = EImpsPollAdaptive;
       
  1922 #ifndef _NO_IMPS_LOGGING_
       
  1923     CImpsClientLogger::Log( _L( "CSPSession: PollTime %d" ), iPollTime );
       
  1924     CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  1925 #endif
       
  1926     iIdleTimer->Start( iPollTime );
       
  1927 
       
  1928     // MultiTrans response
       
  1929     myKey->ReplaceLastL( CREATEKEY( EImpsKeyMultiTrans, 0 ) );
       
  1930     if ( myAccess.RestoreIntegerL( myKey, myInt ) )
       
  1931         {
       
  1932         iMultiTrans = myInt;
       
  1933 #ifndef _NO_IMPS_LOGGING_
       
  1934         CImpsClientLogger::Log( _L( "CSPSession: new iMultiTrans %d" ), iMultiTrans );
       
  1935 #endif
       
  1936         }
       
  1937 
       
  1938     myKey->PopL();
       
  1939 
       
  1940     // SupportedCIRMethod update
       
  1941     iSettings.SetCirBindingsL( &myAccess, myKey );
       
  1942 
       
  1943     // TCPAddress
       
  1944     TDesC* myPtr;
       
  1945     myKey->AddL( CREATEKEY( EImpsKeyTCPAddress, 0 ) );
       
  1946     if ( myAccess.RestoreDescL( myKey, myPtr ) )
       
  1947         {
       
  1948         HBufC* newAttrib = myPtr->AllocL();
       
  1949         delete iTCPAddr;
       
  1950         iTCPAddr = newAttrib;
       
  1951         }
       
  1952 
       
  1953     // TCPPort
       
  1954     myKey->ReplaceLastL( CREATEKEY( EImpsKeyTCPPort, 0 ) );
       
  1955     if ( myAccess.RestoreIntegerL( myKey, myInt ) )
       
  1956         {
       
  1957         iTCPPort = ( TUint )myInt;
       
  1958         }
       
  1959 
       
  1960     CleanupStack::PopAndDestroy( 1 );   // >>> mKey
       
  1961     }
       
  1962 
       
  1963 // -----------------------------------------------------------------------------
       
  1964 // CImpsCSPSession::SendPollL
       
  1965 // -----------------------------------------------------------------------------
       
  1966 void CImpsCSPSession::SendPollL()
       
  1967     {
       
  1968 #ifndef _NO_IMPS_LOGGING_
       
  1969     CImpsClientLogger::Log( _L( "CSPSession: SendPollL csp=%d" ), ( TInt )this );
       
  1970 #endif
       
  1971 
       
  1972     TInt orig = iPollInResume;
       
  1973     iPollInResume = 0;
       
  1974 
       
  1975     if ( iIntStatus != EInternal_ON_LINE || IsPDPIdle() )
       
  1976         {
       
  1977 #ifndef _NO_IMPS_LOGGING_
       
  1978         CImpsClientLogger::Log( _L( "CSPSession: SendPollL IGNORED" ) );
       
  1979 #endif
       
  1980         iPollInResume = 2;
       
  1981         User::Leave( KErrNotReady );
       
  1982         }
       
  1983 
       
  1984     // Create Poll request
       
  1985     iSnd->Reset();
       
  1986     iSnd->SetSessionTypeL( EImpsInband );
       
  1987     iSnd->SetMessageType( EImpsPolling );
       
  1988     iSnd->SetSessionIdL( iCSPSessionId );
       
  1989     CImpsDataAccessor* myAccess = CImpsDataAccessor::NewLC( iSnd ); // <<<
       
  1990     CImpsKey* myKey = CImpsKey::NewLC(); // <<<
       
  1991     // Add TImpsTransactionMode now
       
  1992     myKey->Reset();
       
  1993     TImpsSDataUtils::AddValuesFromArrayL(
       
  1994         myKey,
       
  1995         KTransModeElements,
       
  1996         sizeof( KTransModeElements ) /
       
  1997         sizeof( KTransModeElements[0] ) );
       
  1998     myAccess->StoreIntegerL( myKey, EImpsRequest );
       
  1999     myKey->Reset();
       
  2000     TImpsSDataUtils::AddValuesFromArrayL(
       
  2001         myKey,
       
  2002         KTransContentElements,
       
  2003         sizeof( KTransContentElements ) /
       
  2004         sizeof( KTransContentElements[0] ) );
       
  2005     myKey->AddL( CREATEKEY( EImpsKeyPolling_Request, 0 ) );
       
  2006     myAccess->StoreEmptyL( myKey );
       
  2007 
       
  2008     // Send
       
  2009     iTempTid = KNullDesC;
       
  2010     iSnd->SetTidL( iTempTid );
       
  2011 
       
  2012     iPollWasRequested = EFalse;
       
  2013 #ifndef _NO_IMPS_LOGGING_
       
  2014     CImpsClientLogger::Log( _L( "CSPSession: iPollWasRequested->F in SendPollL" ) );
       
  2015 #endif
       
  2016 
       
  2017     if ( orig >= 1 )
       
  2018         {
       
  2019         iPollInResume = 2;
       
  2020         }
       
  2021     DoSendSingleL( myAccess, iTempTid, EImpsPolling, KImpsPollTO );
       
  2022     iPollInResume = 0;
       
  2023 
       
  2024     CleanupStack::PopAndDestroy( 2 );   // >> myKey, myAccess
       
  2025     }
       
  2026 
       
  2027 
       
  2028 // -----------------------------------------------------------------------------
       
  2029 // CImpsCSPSession::SendAliveL
       
  2030 // -----------------------------------------------------------------------------
       
  2031 TPtrC CImpsCSPSession::SendAliveL( )
       
  2032     {
       
  2033     return DoSendAliveL();
       
  2034     }
       
  2035 
       
  2036 // -----------------------------------------------------------------------------
       
  2037 // CImpsCSPSession::SendAliveInResume
       
  2038 // -----------------------------------------------------------------------------
       
  2039 void CImpsCSPSession::SendAliveInResume( )
       
  2040     {
       
  2041 #ifndef _NO_IMPS_LOGGING_
       
  2042     CImpsClientLogger::Log( _L( "CSPSession: SendAliveInResume iPendingAlive->T" ) );
       
  2043 #endif
       
  2044     iPendingAlive = ETrue;
       
  2045     }
       
  2046 
       
  2047 // -----------------------------------------------------------------------------
       
  2048 // CImpsCSPSession::DoSendAliveL
       
  2049 // -----------------------------------------------------------------------------
       
  2050 TPtrC CImpsCSPSession::DoSendAliveL( )
       
  2051     {
       
  2052 #ifndef _NO_IMPS_LOGGING_
       
  2053     CImpsClientLogger::Log( _L( "CSPSession: DoSendAliveL csp=%d" ), ( TInt )this );
       
  2054 #endif
       
  2055 
       
  2056     // send poll request. Do not update Transaction queue
       
  2057     iSnd->Reset();
       
  2058     iSnd->SetSessionTypeL( EImpsInband );
       
  2059     iSnd->SetMessageType( EImpsKeepAliveReq );
       
  2060     iSnd->SetSessionIdL( iCSPSessionId );
       
  2061 
       
  2062     // Set TID
       
  2063     TPtrC tid;
       
  2064     tid.Set( GenerateTid() );
       
  2065     iSnd->SetTidL( tid );
       
  2066 
       
  2067     // Add KeepAlive
       
  2068     CImpsDataAccessor* myAc = CImpsDataAccessor::NewLC( iSnd ); // <<< myAc
       
  2069     CImpsKey* myk = CImpsKey::NewLC();    // <<< myk
       
  2070     TImpsSDataUtils::AddValuesFromArrayL(
       
  2071         myk,
       
  2072         KKeepAliveReq,
       
  2073         sizeof( KKeepAliveReq ) /
       
  2074         sizeof( KKeepAliveReq[0] ) );
       
  2075     myAc->StoreEmptyL( myk );
       
  2076     // Add Transaction mode
       
  2077     myk->Reset();
       
  2078     TImpsSDataUtils::AddValuesFromArrayL(
       
  2079         myk,
       
  2080         KTransModeElements,
       
  2081         sizeof( KTransModeElements ) /
       
  2082         sizeof( KTransModeElements[0] ) );
       
  2083     myAc->StoreIntegerL( myk, EImpsRequest );
       
  2084 
       
  2085     if ( IsPDPIdle() )  // PDP idle-> start to open
       
  2086         {
       
  2087         iPendingAlive = ETrue;
       
  2088 #ifndef _NO_IMPS_LOGGING_
       
  2089         CImpsClientLogger::Log( _L( "CSPSession: iPendingAlive->T" ) );
       
  2090 #endif
       
  2091         if ( iCSPState == EImpsCSPOnLineIdle )
       
  2092             {
       
  2093             OpenPDP();
       
  2094             }
       
  2095         else if ( iCSPState == EImpsCSPOnLineIdleStart )
       
  2096             {
       
  2097             iPendingPDP = EImpsPDPPendOpen;
       
  2098             }
       
  2099 #ifndef _NO_IMPS_LOGGING_
       
  2100         CImpsClientLogger::Log( _L( "CSPSession: DoSendAliveL POSTPONED ***" ) );
       
  2101 #endif
       
  2102         }
       
  2103     else if ( iIntStatus != EInternal_ON_LINE )
       
  2104         {
       
  2105 #ifndef _NO_IMPS_LOGGING_
       
  2106         CImpsClientLogger::Log( _L( "CSPSession: DoSendAliveL IGNORED" ) );
       
  2107 #endif
       
  2108         iSnd->Reset();
       
  2109         User::Leave( KImpsGeneralError );
       
  2110         }
       
  2111     else
       
  2112         {
       
  2113         DoSendSingleL( myAc, iTempTid, EImpsKeepAliveReq, KImpsKeepATO );
       
  2114         iPendingAlive = EFalse;
       
  2115 #ifndef _NO_IMPS_LOGGING_
       
  2116         CImpsClientLogger::Log( _L( "CSPSession: iPendingAlive->F" ) );
       
  2117 #endif
       
  2118         }
       
  2119 
       
  2120     CleanupStack::PopAndDestroy( 2 );   // >>> myk myAc
       
  2121 
       
  2122     return iTempTid;
       
  2123     }
       
  2124 
       
  2125 
       
  2126 // -----------------------------------------------------------------------------
       
  2127 // CImpsCSPSession::SendAllQueued
       
  2128 // -----------------------------------------------------------------------------
       
  2129 void CImpsCSPSession::SendAllQueued()
       
  2130     {
       
  2131     // Actually this does not send all messages at once but one by one.
       
  2132     // iSendQ calls DoSendAllQueued that calls (in most cases)
       
  2133     // this again and so on until no more valid messages found!
       
  2134     // DoSendAllQueued handles SAP initiated requests in same way.
       
  2135     if ( RequestExist() || SapReqExist() || iPendingAlive ||
       
  2136          iPollState == EImpsPollExtWait || iPollInResume == 1 ||
       
  2137          iPollWasRequested )
       
  2138         {
       
  2139         if ( !IsPDPIdle() )
       
  2140             {
       
  2141             iSendQ->Send();
       
  2142             }
       
  2143         else if ( iCSPState == EImpsCSPOnLineIdle )
       
  2144             {
       
  2145             iPollState = EImpsPollCIR;
       
  2146 #ifndef _NO_IMPS_LOGGING_
       
  2147             CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  2148 #endif
       
  2149             }
       
  2150         }
       
  2151     }
       
  2152 
       
  2153 // -----------------------------------------------------------------------------
       
  2154 // CImpsCSPSession::CreateSapResponse
       
  2155 // -----------------------------------------------------------------------------
       
  2156 TImpsSAPResStatus CImpsCSPSession::CreateSapResponse()
       
  2157     {
       
  2158 #ifndef _NO_IMPS_LOGGING_
       
  2159     CImpsClientLogger::Log( _L( "CSPSession: CreateSapResponse begins csp=%d" ), ( TInt )this );
       
  2160 #endif
       
  2161 
       
  2162     TImpsSAPResStatus ret( EImpsSAPNone );
       
  2163     TInt err = KErrNone;
       
  2164     // Check if pending SAP initiated CSP transactions exists
       
  2165     TDblQueIter<CTransaction> iter2 ( iTransactionList );
       
  2166     iter2.SetToFirst();
       
  2167     if ( iter2 )
       
  2168         {
       
  2169         ret = EImpsSAPMore;
       
  2170         CTransaction* trans = iter2;
       
  2171         // Get first
       
  2172         iter2++;
       
  2173         CImpsFields* fields = trans->iFields;
       
  2174         TInt messageType = fields->MessageType();
       
  2175 
       
  2176         // Try to get actual message type
       
  2177         if ( messageType == EImpsPureData )
       
  2178             {
       
  2179             TRAP( err, TImpsDataAccessor temp ( fields );
       
  2180                   messageType = TImpsSDataUtils::GetPureMessageTypeL( &temp ) );
       
  2181             }
       
  2182 
       
  2183 #ifndef _NO_IMPS_LOGGING_
       
  2184         CImpsClientLogger::Log( _L( "CSPSession: CreateSapResponse messageType=%x" ), messageType );
       
  2185 #endif
       
  2186         // Here we have a list of supported push messages, i.e.
       
  2187         // SAP initiated transactions.
       
  2188         // Other pushed messages are not supported!
       
  2189         // Notice: add new methods as needed
       
  2190         // Disconnect is a special case handled before this method call
       
  2191         if ( messageType == EImpsNewMessage ||
       
  2192              messageType == EImpsLeaveGroupRes ||
       
  2193              messageType == EImpsInviteUserReq ||
       
  2194              messageType == EImpsInviteRes ||
       
  2195              messageType == EImpsCancelInviteUserReq ||
       
  2196              messageType == EImpsPresenceNotification ||
       
  2197              messageType == EImpsGroupChangeNotice ||
       
  2198              messageType == EImpsPresenceAuthReq ||
       
  2199              messageType == EImpsDeliveryReportReq
       
  2200            )
       
  2201             {
       
  2202             // This also tries to send a SAP initiated transaction response once immediately
       
  2203             TRAP( err, DoMakeSapResponseL( trans ) );
       
  2204             if ( !err )
       
  2205                 {
       
  2206                 iPollInResume = 0;
       
  2207                 }
       
  2208             // Last request handled.
       
  2209             if ( !iter2 )
       
  2210                 {
       
  2211                 ret = EImpsSAPLast;
       
  2212                 iPollInResume = 0;
       
  2213 
       
  2214                 // All the WV servers do not work according to WV specs and they seems to need
       
  2215                 // to get a Poll request instead for SAP initiated transactions, therefore the
       
  2216                 // extra polling is needed.
       
  2217                 err = KErrNone;
       
  2218                 TBool polli ( EFalse );
       
  2219                 TRAP( err, polli = fields->PollL() )
       
  2220                 if ( polli )
       
  2221                     {
       
  2222                     iPollWasRequested = ETrue;
       
  2223 #ifndef _NO_IMPS_LOGGING_
       
  2224                     CImpsClientLogger::Log( _L( "CSPSession: iPollWasRequested->T in CreateSapResponse" ) );
       
  2225 #endif
       
  2226                     }
       
  2227                 }
       
  2228 
       
  2229 #ifndef _NO_IMPS_LOGGING_
       
  2230             if ( err )
       
  2231                 {
       
  2232                 CImpsClientLogger::Log( _L( "CSPSession: DoMakeSapResponseL ERROR %d" ), err );
       
  2233                 }
       
  2234 
       
  2235 #endif
       
  2236             }
       
  2237 
       
  2238         // Transaction is deleted. If the response has failed the WV server should send
       
  2239         // the transaction again. Timer limit is not implemented in terminal side here.
       
  2240         trans->Destroy();
       
  2241 
       
  2242         } // if (iter2)
       
  2243 #ifndef _NO_IMPS_LOGGING_
       
  2244     CImpsClientLogger::Log( _L( "CSPSession: CreateSapResponse returns %d" ), ret );
       
  2245 #endif
       
  2246     return ret;
       
  2247     }
       
  2248 
       
  2249 // -----------------------------------------------------------------------------
       
  2250 // CImpsCSPSession::DoSendAllQueuedL
       
  2251 // -----------------------------------------------------------------------------
       
  2252 void CImpsCSPSession::DoSendAllQueuedL()
       
  2253     {
       
  2254 
       
  2255     TInt errx = KErrNone;
       
  2256 
       
  2257     // Handle login phase specials first
       
  2258     // ---------------------------------
       
  2259     if ( iLoginPhase != 2 )
       
  2260         {
       
  2261         if ( !IsLogged() || !iReceiver2->isConnected() ||
       
  2262              ( iReceiver2->NbrOfPending() >= KImpsMaxPending ) ||
       
  2263              IsPDPIdle() ) // no reason to try if PDP is not open
       
  2264             {
       
  2265 #ifndef _NO_IMPS_LOGGING_
       
  2266             CImpsClientLogger::Log( _L( "CSPSession: DoSendAllQueuedL IGNORED" ) );
       
  2267 #endif
       
  2268             return;
       
  2269             }
       
  2270         }
       
  2271 
       
  2272     // Pending Alive messages and pending Poll messages
       
  2273     // -------------------------------------------------
       
  2274     if ( iPendingAlive )
       
  2275         {
       
  2276         // Pending Alive overrides pending Poll
       
  2277         iPendingAlive = EFalse;
       
  2278 #ifndef _NO_IMPS_LOGGING_
       
  2279         CImpsClientLogger::Log( _L( "CSPSession: iPendingAlive->F" ) );
       
  2280 #endif
       
  2281         iPollInResume = 0;
       
  2282         iAliveMgr->SendKeepAlive( EFalse );
       
  2283         SendAllQueued();
       
  2284         return;
       
  2285         }
       
  2286     else if ( iPollState == EImpsPollExtWait )
       
  2287         {
       
  2288         iPollState = EImpsPollCIR;
       
  2289         iPollTime = iSettings.CIRModePollTime();
       
  2290         iIdleTimer->Start( iPollTime );
       
  2291 #ifndef _NO_IMPS_LOGGING_
       
  2292         CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  2293         CImpsClientLogger::Log( _L( "CSPSession: iPollTime %d" ), iPollTime );
       
  2294 #endif
       
  2295         errx = KErrNone;
       
  2296         TRAP( errx, SendPollL() );
       
  2297         // If Polling fails then try again
       
  2298         if ( errx && !iPollInResume )
       
  2299             {
       
  2300             iPollInResume = 1;
       
  2301 #ifndef _NO_IMPS_LOGGING_
       
  2302             CImpsClientLogger::Log( _L( "CSPSession: iPollInResume %d" ), iPollInResume );
       
  2303 #endif
       
  2304             }
       
  2305 
       
  2306         SendAllQueued();
       
  2307         return;
       
  2308         }
       
  2309 
       
  2310     // Reqular cases
       
  2311     // --------------------------
       
  2312     CReq* request = NULL;
       
  2313 
       
  2314     if ( iTr < iMultiTrans )
       
  2315         {
       
  2316         // Try to send terminal initiated request
       
  2317         request = GiveNextRequestL();
       
  2318 
       
  2319         // Block messages in negotiation phase
       
  2320         if ( request && request->iFields )
       
  2321             {
       
  2322             TInt msgType = request->iFields->MessageType();
       
  2323             if ( iIntStatus != EInternal_ON_LINE &&
       
  2324                  ( msgType != EImpsKeepAliveReq &&
       
  2325                    msgType != EImpsClientCapabilityReq &&
       
  2326                    msgType != EImpsServiceReq &&
       
  2327                    msgType != EImpsLoginReq &&
       
  2328                    msgType != EImpsLogoutReq ) )
       
  2329 
       
  2330                 {
       
  2331                 request = NULL;
       
  2332                 }
       
  2333             }
       
  2334 
       
  2335         if ( request )
       
  2336             {
       
  2337             iPollInResume = 0;
       
  2338             // Send next buffered user request if any
       
  2339             // search. Not immediately, but via active object scheduler
       
  2340             SendAllQueued();
       
  2341 
       
  2342             CImpsFields* fields = request->iFields;
       
  2343             errx = KErrNone;
       
  2344             TRAP( errx, DoSendNextBufferedL( fields ) );
       
  2345             // Delete the client request
       
  2346             request->Destroy();
       
  2347             } // if request
       
  2348         }
       
  2349 
       
  2350     if ( !request )
       
  2351         {
       
  2352         // Check if SAP initiated message instead of terminal initiated one.
       
  2353         // This sends data and calls SendAllQueued if needed.
       
  2354         // comment: SAP responses should not exists in PDP-idle state
       
  2355 
       
  2356         // CreateSapResponse not only create the response but also tries to send it..
       
  2357         TImpsSAPResStatus sapr = CreateSapResponse();
       
  2358         if ( ( sapr != EImpsSAPMore ) &&
       
  2359              ( iPollWasRequested || iPollInResume == 1 ) &&
       
  2360              ( IsLogged() ) )
       
  2361             {
       
  2362             errx = KErrNone;
       
  2363             // If Poll fails then re-try polling when GPRS resumes
       
  2364             TRAP( errx, SendPollL() );
       
  2365             if ( errx && !iPollInResume )
       
  2366                 {
       
  2367                 iPollInResume = 1;
       
  2368 #ifndef _NO_IMPS_LOGGING_
       
  2369                 CImpsClientLogger::Log( _L( "CSPSession: err: iPollInResume %d" ), iPollInResume );
       
  2370 #endif
       
  2371                 }
       
  2372             }
       
  2373         else if ( sapr == EImpsSAPMore )
       
  2374             {
       
  2375             SendAllQueued();
       
  2376             }
       
  2377         }
       
  2378     }
       
  2379 
       
  2380 // -----------------------------------------------------------------------------
       
  2381 // CImpsCSPSession::CancelTrans
       
  2382 // client subsession calls this when request expires
       
  2383 // -----------------------------------------------------------------------------
       
  2384 void CImpsCSPSession::CancelTrans( const TDesC& aTID )
       
  2385     {
       
  2386     DeleteRequest( aTID );
       
  2387     // CancelTrans does not cause callback.
       
  2388     iReceiver2->CancelTrans( aTID );
       
  2389     TrMinus();
       
  2390     // Check if login-req expires and change CSP state
       
  2391     if ( iCSPState == EImpsCSPLogging && !aTID.Compare( LogTid() ) )
       
  2392         {
       
  2393         NewState( EImpsCSPIdle );
       
  2394         CancelData();
       
  2395         }
       
  2396 
       
  2397     SendAllQueued();
       
  2398     }
       
  2399 
       
  2400 // -----------------------------------------------------------------------------
       
  2401 // CImpsCSPSession::GenerateTid
       
  2402 // -----------------------------------------------------------------------------
       
  2403 TPtrC CImpsCSPSession::GenerateTid( )
       
  2404     {
       
  2405     // iCounter++;
       
  2406     // TInt tidNbr = iCounter;
       
  2407     TInt tidNbr = iServer.TidSeed();
       
  2408     iTempTid = KNullDesC;
       
  2409     iTempTid = _L( "nok" );
       
  2410     iTempTid.AppendFormat( _L( "%d" ), tidNbr  );
       
  2411     return iTempTid;
       
  2412     }
       
  2413 
       
  2414 // -----------------------------------------------------------------------------
       
  2415 // CImpsCSPSession::GenerateCookie
       
  2416 // -----------------------------------------------------------------------------
       
  2417 TPtrC CImpsCSPSession::GenerateCookie( )
       
  2418     {
       
  2419     TTime myTime;
       
  2420     myTime.HomeTime();
       
  2421     const TInt64& seed = myTime.Int64();
       
  2422     TUint low = I64LOW( seed );
       
  2423     TUint high = I64HIGH( seed );
       
  2424     TInt64 seed2 MAKE_TINT64( high, low );
       
  2425     iCookie = KNullDesC;
       
  2426     iCookie = _L( "wv:nokia." );
       
  2427 #ifndef _FAKE_RESPONSE
       
  2428     TInt tidNbr = Math::Rand( seed2 );
       
  2429     iCookie.AppendFormat( _L( "%d" ), tidNbr  );
       
  2430 #else
       
  2431     iCookie.AppendFormat( _L( "%d" ), 12345  );
       
  2432 #endif
       
  2433     // copy to 8-bit buffer for CIR
       
  2434     iCookie8.Copy( iCookie );
       
  2435     return iCookie;
       
  2436     }
       
  2437 
       
  2438 // -----------------------------------------------------------------------------
       
  2439 // CImpsCSPSession::DoLogout
       
  2440 // -----------------------------------------------------------------------------
       
  2441 void CImpsCSPSession::DoLogout( )
       
  2442     {
       
  2443 
       
  2444 #ifndef _NO_IMPS_LOGGING_
       
  2445     CImpsClientLogger::Log( _L( "CSPSession: DoLogout" ) );
       
  2446 #endif
       
  2447     DoLogoutNow( 0 );
       
  2448     }
       
  2449 
       
  2450 // -----------------------------------------------------------------------------
       
  2451 // CImpsCSPSession::DoLogoutNow
       
  2452 // -----------------------------------------------------------------------------
       
  2453 void CImpsCSPSession::DoLogoutNow( TInt aOpId )
       
  2454     {
       
  2455 #ifndef _NO_IMPS_LOGGING_
       
  2456     CImpsClientLogger::Log( _L( "CSPSession: DoLogoutNow opid=%d, log=%d csp=%d" ),
       
  2457                             aOpId, IsLogged(), ( TInt )this );
       
  2458 #endif
       
  2459 
       
  2460     // save old status for this method
       
  2461     TBool oldLogged = IsLogged();
       
  2462     TImpsCSPState oldState = iCSPState;
       
  2463     NewState( EImpsCSPIdle );
       
  2464 
       
  2465     iAliveMgr->StopTimer();
       
  2466     iIdleTimer->Stop();
       
  2467     // stop PDP idle timer in logout routines
       
  2468     iPDPIdleTimer->Stop( );
       
  2469     iPDPOpenTimer->Stop( );
       
  2470     iPollState = EImpsPollNone;
       
  2471     iPendingPDP = EImpsPDPPendNone;
       
  2472     iPendPDPLogout = EFalse;
       
  2473     iPollWasRequested = EFalse;
       
  2474 #ifndef _NO_IMPS_LOGGING_
       
  2475     CImpsClientLogger::Log( _L( "CSPSession: iPollState %d  iPollWasRequested->F in logout" ), iPollState );
       
  2476 #endif
       
  2477 
       
  2478     // Reset settings for further logins
       
  2479     ResetSession();
       
  2480 
       
  2481     iSendQ->Cancel();
       
  2482 
       
  2483     // Reset local variables
       
  2484     iIntStatus = EInternal_NOT_LOGGED;
       
  2485 
       
  2486 #ifndef _NO_IMPS_LOGGING_
       
  2487     CImpsClientLogger::Log( _L( "CSPSession: status NOT_LOGGED" ) );
       
  2488 #endif
       
  2489 
       
  2490     // Clean own queues
       
  2491     DeleteRequests();
       
  2492     DeleteTransactions();
       
  2493     iTidSapHistory->DeleteAll();
       
  2494     iTidCliHistory->DeleteAll();
       
  2495 
       
  2496     // Close ip cir
       
  2497 #ifndef _NO_IMPS_LOGGING_
       
  2498     CImpsClientLogger::Log( _L( "CSPSession: CLOSE IP-CIR CHANNEL" ) );
       
  2499 #endif
       
  2500     if ( iCirManager )
       
  2501         {
       
  2502         // Close all cir bindings
       
  2503         iCirManager->CloseCh( 0xF );
       
  2504         }
       
  2505 
       
  2506     // Cancel the HTTP transport in logout
       
  2507 #ifndef _NO_IMPS_LOGGING_
       
  2508     CImpsClientLogger::Log( _L( "CSPSession: CANCEL TRANSPORT IN DOLOGOUT" ) );
       
  2509 #endif
       
  2510     CancelData();
       
  2511 
       
  2512     // Clean server core and send logout and status events there.
       
  2513     // We first detect if this is really CSP disconnect situation.
       
  2514     TBool cspDisconnect = ( oldLogged || oldState == EImpsCSPDisconnecting ) ?
       
  2515                           ETrue : EFalse ;
       
  2516     iServer.DoLogoutSrv( aOpId, cspDisconnect, this );
       
  2517 
       
  2518     delete iSAP;
       
  2519     iSAP = NULL;
       
  2520     iIAP = 0;
       
  2521 
       
  2522 #ifndef _NO_IMPS_LOGGING_
       
  2523     CImpsClientLogger::Log( _L( "CSPSession: CLOSE TRANSPORT SOON..." ) );
       
  2524 #endif
       
  2525     if ( iReceiver2->Close2() == KErrCancel )
       
  2526         {
       
  2527         // Start to delete this session asynchronously
       
  2528         // if there is nothing to close.
       
  2529         iServer.TransportStatus(  EInternal_NO_IAP, this );
       
  2530         }
       
  2531     }
       
  2532 
       
  2533 // -----------------------------------------------------------------------------
       
  2534 // CImpsCSPSession::CancelData
       
  2535 // server CloseSession calls this
       
  2536 // -----------------------------------------------------------------------------
       
  2537 void CImpsCSPSession::CancelData( )
       
  2538     {
       
  2539 
       
  2540 #ifndef _NO_IMPS_LOGGING_
       
  2541     CImpsClientLogger::Log( _L( "CSPSession: CancelData csp=%d" ), ( TInt )this );
       
  2542 #endif
       
  2543     // Cancel the HTTP transport now, no callback
       
  2544     iReceiver2->Cancel();
       
  2545     // Must reset variables because if new Login request mey be
       
  2546     // received before WV Engine is shut down and CloseEngine() called.
       
  2547     }
       
  2548 
       
  2549 // -----------------------------------------------------------------------------
       
  2550 // CImpsCSPSession::QueueClientRequestL
       
  2551 // -----------------------------------------------------------------------------
       
  2552 void CImpsCSPSession::QueueClientRequestL(
       
  2553     CImpsFields* aFields,
       
  2554     TInt aExpiry,
       
  2555     TBool aLast )
       
  2556     {
       
  2557     // Check if subsession specific expiry time needed
       
  2558     CReq* req = new ( ELeave ) CReq( aFields );
       
  2559     if ( !aExpiry )
       
  2560         {
       
  2561         req->iExpiry = iServer.ExpiryTime( ( TImpsMessageType ) aFields->MessageType() );
       
  2562         }
       
  2563     else
       
  2564         {
       
  2565         req->iExpiry = iServer.ExpiryTime( aExpiry );
       
  2566         }
       
  2567 
       
  2568     // Put request into queue in a right place,
       
  2569     if ( aLast )
       
  2570         {
       
  2571         iRequestList.AddLast( *req );
       
  2572         }
       
  2573     else
       
  2574         {
       
  2575         iRequestList.AddFirst( *req );
       
  2576         }
       
  2577     }
       
  2578 
       
  2579 // -----------------------------------------------------------------------------
       
  2580 // CImpsCSPSession::QueueTidL
       
  2581 // This resets iRcv!
       
  2582 // -----------------------------------------------------------------------------
       
  2583 void CImpsCSPSession::QueueTidL( TBool aOrphan )
       
  2584     {
       
  2585 
       
  2586     if ( !ValidateTid( EFalse ) )
       
  2587         {
       
  2588         // TID is already responded to SAP
       
  2589         return;
       
  2590         }
       
  2591 
       
  2592     TPtrC tid;
       
  2593     TImpsDataAccessor myAccess( iRcv );
       
  2594     TImpsDataUtils::GetTransactionIDL( &myAccess, tid );
       
  2595 
       
  2596     if ( tid.Length() > 0 )
       
  2597         {
       
  2598 
       
  2599         // Add new Sap initiated transaction to queue
       
  2600         CTransaction* trans = new ( ELeave ) CTransaction(
       
  2601             aOrphan,
       
  2602             tid,                    // tid
       
  2603             iRcv->SessionIdL(),     // session-id
       
  2604             ( TImpsMessageType ) iRcv->MessageType(),
       
  2605             iRcv );
       
  2606 
       
  2607 #ifndef _NO_IMPS_LOGGING_
       
  2608         CImpsClientLogger::Log( _L( "CSPSession: QUEUE SAP TID=%S csp=%d" ),
       
  2609                                 &( trans->iTID ), ( TInt )this ); //lint !e525
       
  2610 #endif
       
  2611 
       
  2612         iTransactionList.AddLast( *trans );
       
  2613         iRcv = NULL;
       
  2614         iRcv = CImpsFields::NewL();
       
  2615         iRcv->Reset();
       
  2616         }
       
  2617     }
       
  2618 
       
  2619 // -----------------------------------------------------------------------------
       
  2620 // CImpsCSPSession::ValidateTid
       
  2621 // Validate SAP initiated TID
       
  2622 // -----------------------------------------------------------------------------
       
  2623 TBool CImpsCSPSession::ValidateTid( TBool aClientHistory )
       
  2624     {
       
  2625 
       
  2626     // The requesting entity may resend the request message using the same
       
  2627     // transaction identifier. The responding entity should
       
  2628     // guarantee that the requested operation or data is carried out only once,
       
  2629     // even if multiple request messages with the same transaction identifier
       
  2630     // are received.
       
  2631 
       
  2632     // Check that TID has not already sent to clients or has not responded to SAP.
       
  2633 
       
  2634     TPtrC tid;
       
  2635     TImpsDataAccessor myAccess( iRcv );
       
  2636     TInt errx = KErrNone;
       
  2637     TRAP( errx, TImpsDataUtils::GetTransactionIDL( &myAccess, tid ) );
       
  2638 
       
  2639     if ( tid.Length() > 0 )
       
  2640         {
       
  2641         if ( aClientHistory && iTidCliHistory->TidFound( tid ) )
       
  2642             {
       
  2643             // TID has sent to clients
       
  2644 #ifndef _NO_IMPS_LOGGING_
       
  2645             CImpsClientLogger::Log( _L( "CSPSession: already received TID=%S ***" ), &tid );
       
  2646 #endif
       
  2647             return EFalse;
       
  2648             }
       
  2649         else if ( aClientHistory /* && !iTidCliHistory->TidFound( tid )*/ )
       
  2650             {
       
  2651             // Save TId into client history
       
  2652             iTidCliHistory->Add( tid );
       
  2653             }
       
  2654         else if ( !aClientHistory && iTidSapHistory->TidFound( tid ) )
       
  2655             {
       
  2656             // TID has already responded to SAP
       
  2657             // TID-SAP-history has been updated when the transport response is sent
       
  2658             // successfully to SAP (i.e. no transport error)
       
  2659 #ifndef _NO_IMPS_LOGGING_
       
  2660             CImpsClientLogger::Log( _L( "CSPSession: already responded TID=%S ***" ), &tid );
       
  2661 #endif
       
  2662             return EFalse;
       
  2663             }
       
  2664         }
       
  2665     return ETrue;
       
  2666     }
       
  2667 
       
  2668 // -----------------------------------------------------------------------------
       
  2669 // CImpsCSPSession::DiscardTid
       
  2670 // -----------------------------------------------------------------------------
       
  2671 void CImpsCSPSession::DiscardTid( const TDesC& aTid )
       
  2672     {
       
  2673     // Delete buffered transaction
       
  2674     TDblQueIter<CTransaction> rIter( iTransactionList );
       
  2675     rIter.SetToFirst();
       
  2676     while ( rIter )
       
  2677         {
       
  2678         CTransaction* trans = rIter;
       
  2679         rIter++;
       
  2680         if ( !trans->iTID.Compare( aTid ) )
       
  2681             {
       
  2682 #ifndef _NO_IMPS_LOGGING_
       
  2683             CImpsClientLogger::Log( _L( "CSPSession: DiscardTid deletes a request " ) );
       
  2684 #endif
       
  2685             trans->Destroy();
       
  2686             return;
       
  2687             }
       
  2688         }
       
  2689     }
       
  2690 
       
  2691 // -----------------------------------------------------------------------------
       
  2692 // CImpsCSPSession::DeleteTransactions
       
  2693 // -----------------------------------------------------------------------------
       
  2694 void CImpsCSPSession::DeleteTransactions()
       
  2695     {
       
  2696     // Delete all buffered transactions
       
  2697     TDblQueIter<CTransaction> rIter( iTransactionList );
       
  2698 
       
  2699     rIter.SetToFirst();
       
  2700 
       
  2701     while ( rIter )
       
  2702         {
       
  2703         CTransaction* trans = rIter;
       
  2704         rIter++;
       
  2705         trans->Destroy();
       
  2706         }
       
  2707     }
       
  2708 
       
  2709 // -----------------------------------------------------------------------------
       
  2710 // CImpsCSPSession::DeleteRequests
       
  2711 // -----------------------------------------------------------------------------
       
  2712 void CImpsCSPSession::DeleteRequests()
       
  2713     {
       
  2714 #ifndef _NO_IMPS_LOGGING_
       
  2715     CImpsClientLogger::Log( _L( "CSPSession: DeleteRequests csp=%d" ), ( TInt )this );
       
  2716 #endif
       
  2717     // Delete all buffered transaction requests
       
  2718     TDblQueIter<CReq> rIter( iRequestList );
       
  2719     rIter.SetToFirst();
       
  2720 
       
  2721     while ( rIter )
       
  2722         {
       
  2723         CReq* req = rIter;
       
  2724         rIter++;
       
  2725         req->Destroy();
       
  2726         }
       
  2727     }
       
  2728 
       
  2729 // -----------------------------------------------------------------------------
       
  2730 // CImpsCSPSession::DeleteRequest
       
  2731 // -----------------------------------------------------------------------------
       
  2732 void CImpsCSPSession::DeleteRequest( const TDesC& aTID )
       
  2733     {
       
  2734 #ifndef _NO_IMPS_LOGGING_
       
  2735     CImpsClientLogger::Log( _L( "CSPSession: DeleteRequest tid=%S csp=%d" ), &aTID, ( TInt )this );
       
  2736 #endif
       
  2737     // Delete buffered transaction request
       
  2738     TInt errx = KErrNone;
       
  2739     TPtrC p( KNullDesC );
       
  2740 
       
  2741     TDblQueIter<CReq> rIter( iRequestList );
       
  2742     rIter.SetToFirst();
       
  2743 
       
  2744     while ( rIter )
       
  2745         {
       
  2746         CReq* req = rIter;
       
  2747         rIter++;
       
  2748         TRAP( errx, p.Set( req->iFields->TidL() ) );
       
  2749         if ( !p.Compare( aTID ) )
       
  2750             {
       
  2751 #ifndef _NO_IMPS_LOGGING_
       
  2752             CImpsClientLogger::Log( _L( "CSPSession: DeleteRequest MATCH tid=%S csp=%d" ), &aTID, ( TInt )this );
       
  2753 #endif
       
  2754             req->Destroy();
       
  2755 
       
  2756             }
       
  2757         }
       
  2758     }
       
  2759 
       
  2760 // -----------------------------------------------------------------------------
       
  2761 // CImpsCSPSession::RequestExist
       
  2762 // -----------------------------------------------------------------------------
       
  2763 TBool CImpsCSPSession::RequestExist()
       
  2764     {
       
  2765     // Check buffered transactions
       
  2766     TDblQueIter<CReq> rIter( iRequestList );
       
  2767 
       
  2768     rIter.SetToFirst();
       
  2769 
       
  2770     if ( rIter )
       
  2771         {
       
  2772         return ETrue;
       
  2773         }
       
  2774     return EFalse;
       
  2775     }
       
  2776 
       
  2777 // -----------------------------------------------------------------------------
       
  2778 // CImpsCSPSession::SapReqExist
       
  2779 // -----------------------------------------------------------------------------
       
  2780 TBool CImpsCSPSession::SapReqExist()
       
  2781     {
       
  2782     TDblQueIter<CTransaction> iter2 ( iTransactionList );
       
  2783     iter2.SetToFirst();
       
  2784     if ( iter2 )
       
  2785         {
       
  2786         return ETrue;
       
  2787         }
       
  2788     return EFalse;
       
  2789     }
       
  2790 
       
  2791 // -----------------------------------------------------------------------------
       
  2792 // CImpsCSPSession::DoSendNextBufferedL
       
  2793 // -----------------------------------------------------------------------------
       
  2794 void CImpsCSPSession::DoSendNextBufferedL( CImpsFields* aFields )
       
  2795     {
       
  2796     TImpsDataAccessor myAccess( aFields );
       
  2797     TRAPD( err, DoSendSingleL( &myAccess, aFields->TidL(),
       
  2798                                ( TImpsMessageType )aFields->MessageType() ) );
       
  2799     if ( err )
       
  2800         {
       
  2801         //  send an error event
       
  2802 #ifndef _NO_IMPS_LOGGING_
       
  2803         CImpsClientLogger::Log( _L( "CSPSession: DoSendSingleL ERROR=%d csp=%d" ), err, ( TInt )this );
       
  2804 #endif
       
  2805         iSnd->Reset();
       
  2806         iSnd->SetStatus( err );
       
  2807         iSnd->SetTidL( aFields->TidL() );
       
  2808         TBool someFound;
       
  2809         // This sends error event to the right client session
       
  2810         TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  2811         iServer.CheckRequestsL( iSnd, someFound, csp );
       
  2812         }
       
  2813     }
       
  2814 
       
  2815 // ---------------------------------------------------------
       
  2816 // CImpsCSPSession::TransportStatus
       
  2817 // ---------------------------------------------------------
       
  2818 //
       
  2819 void CImpsCSPSession::TransportStatus(
       
  2820     EImpsInternalStatus aConnectionState )
       
  2821     {
       
  2822 
       
  2823 #ifndef _NO_IMPS_LOGGING_
       
  2824     CImpsClientLogger::Log( _L( "CSPSession: TransportStatus=%d old=%d state=%d csp=%d" ),
       
  2825                             ( TInt ) aConnectionState, iIntStatus, iCSPState, ( TInt )this );
       
  2826 #endif
       
  2827 
       
  2828     TInt errx = KErrNone;
       
  2829     TRAP( errx, DoTransportStatusL ( aConnectionState ) );
       
  2830 
       
  2831 #ifndef _NO_IMPS_LOGGING_
       
  2832     CImpsClientLogger::Log( _L( "CSPSession: TransportStatus ends" ) );
       
  2833 #endif
       
  2834 
       
  2835     }
       
  2836 
       
  2837 // ---------------------------------------------------------
       
  2838 // CImpsCSPSession::DoTransportStatusL
       
  2839 // ---------------------------------------------------------
       
  2840 //
       
  2841 void CImpsCSPSession::DoTransportStatusL(
       
  2842     EImpsInternalStatus aConnectionState )
       
  2843     {
       
  2844     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  2845     EImpsInternalStatus oldStatus = iIntStatus;
       
  2846 
       
  2847     // If there is pending logout request then the login is cancelled and
       
  2848     // logout performed immediately.
       
  2849     if ( iPendingLogout || iCancelLogin )
       
  2850         {
       
  2851 #ifndef _NO_IMPS_LOGGING_
       
  2852         CImpsClientLogger::Log( _L( "CSPSession: err: ex3 iPendingLogout->F *****" ) );
       
  2853 #endif
       
  2854         iPendingLogout = EFalse;
       
  2855         if ( iCSPState == EImpsCSPLogging )
       
  2856             {
       
  2857             // This sends first a login response
       
  2858             iServer.DiscardRequest( LogTid(), EImpsEventServerLogin, KErrCancel, csp );
       
  2859             // Special case where login is cancelled
       
  2860             if ( aConnectionState == EInternal_NO_IAP )
       
  2861                 {
       
  2862                 iServer.DiscardLogout( LogoutTID(), csp );
       
  2863                 // below rest of activities are done
       
  2864                 }
       
  2865             }
       
  2866         }
       
  2867 
       
  2868     // *********************************************
       
  2869     // PDP idle situations handled first
       
  2870     if ( IsPDPIdle() )
       
  2871         {
       
  2872         if ( aConnectionState == EInternal_NO_IAP )
       
  2873             {
       
  2874             NewState( EImpsCSPOnLineIdle );
       
  2875             // In a rare situation there is pending PDP open request
       
  2876             // received when PDP is closing down.
       
  2877             if ( iPendingPDP == EImpsPDPPendOpen )
       
  2878                 {
       
  2879 #ifndef _NO_IMPS_LOGGING_
       
  2880                 CImpsClientLogger::Log( _L( "CSPSession: iPendingLogout->F in NO_IAP ***" ) );
       
  2881 #endif
       
  2882                 iPendingPDP = EImpsPDPPendNone;
       
  2883                 OpenPDP();
       
  2884                 }
       
  2885             return;
       
  2886             }
       
  2887         else if ( aConnectionState == EInternal_IAP_OPEN )
       
  2888             {
       
  2889             // PDP re-open completes here.
       
  2890             NewState( EImpsCSPOnLine );
       
  2891             if ( iPendingPDP == EImpsPDPPendOpen )
       
  2892                 {
       
  2893                 iPendingPDP = EImpsPDPPendNone;
       
  2894                 }
       
  2895             // pending logout if PDP-context has been opened for Logout msg
       
  2896             if ( iPendPDPLogout )
       
  2897                 {
       
  2898                 iPendPDPLogout = EFalse;
       
  2899                 iPendingPDP = EImpsPDPPendNone;
       
  2900                 TRAPD( errx, DoSendLogoutL( LogoutTID() ) );
       
  2901                 if ( errx )
       
  2902                     {
       
  2903                     // E5: Typically Bearer Suspended error with bad luck
       
  2904 #ifndef _NO_IMPS_LOGGING_
       
  2905                     CImpsClientLogger::Log( _L( "CSPSession: err: E5 ****" ) );
       
  2906 #endif
       
  2907                     DoLogout();
       
  2908                     }
       
  2909                 }
       
  2910             else
       
  2911                 {
       
  2912                 // Send all queued reqular requests to transport
       
  2913 #ifndef _NO_IMPS_LOGGING_
       
  2914                 CImpsClientLogger::Log( _L( "CSPSession: Normal PDP open ***" ) );
       
  2915 #endif
       
  2916                 iPollInResume = 1;
       
  2917                 // *********************************************************
       
  2918                 // Notice: we assume that GPRS is resumed in this case even
       
  2919                 // if ConnManager DLL cannot provide us such an information
       
  2920                 // in all cases.
       
  2921                 iIntStatus = EInternal_ON_LINE;
       
  2922 #ifndef _NO_IMPS_LOGGING_
       
  2923                 CImpsClientLogger::Log( _L( "CSPSession: status ON_LINE" ) );
       
  2924 #endif
       
  2925                 // start ip-cir-channels if not running
       
  2926                 TInt errxy = KErrNone;
       
  2927                 TRAP( errxy, DoStartIpCIRL() );
       
  2928                 }
       
  2929             // Send all queued requests to transport
       
  2930             SendAllQueued();
       
  2931             }
       
  2932         }
       
  2933 
       
  2934     // *********************************************
       
  2935     // NO PDP IDLE STARTS HERE
       
  2936     else if ( aConnectionState == EInternal_ON_LINE && IsNegotiated() )
       
  2937         {
       
  2938         iIntStatus = EInternal_ON_LINE;
       
  2939         // we assume that old messages are in a bit heaven
       
  2940         iTr = 0;
       
  2941 #ifndef _NO_IMPS_LOGGING_
       
  2942         CImpsClientLogger::Log( _L( "CSPSession: status ON_LINE" ) );
       
  2943 #endif
       
  2944         if ( iPollState == EImpsPollPending )
       
  2945             {
       
  2946             iPollState = EImpsPollExtWait;
       
  2947 #ifndef _NO_IMPS_LOGGING_
       
  2948             CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  2949 #endif
       
  2950             }
       
  2951 
       
  2952         // This makes poll to be sent if no other requests
       
  2953         iPollInResume = 1;
       
  2954 
       
  2955         // pending logout if PDP-context has been opened for Logout msg
       
  2956         if ( iPendPDPLogout )
       
  2957             {
       
  2958             iPendPDPLogout = EFalse;
       
  2959             DoSendLogoutL( LogoutTID() );
       
  2960             }
       
  2961         else
       
  2962             {
       
  2963             SendAllQueued();
       
  2964             // start ip-cir-channels if not running
       
  2965             TInt errxy = KErrNone;
       
  2966             TRAP( errxy, DoStartIpCIRL() );
       
  2967             }
       
  2968         }
       
  2969     else if ( aConnectionState == EInternal_ON_LINE && !IsNegotiated() )
       
  2970         {
       
  2971         iIntStatus = EInternal_NOT_LOGGED;
       
  2972 #ifndef _NO_IMPS_LOGGING_
       
  2973         CImpsClientLogger::Log( _L( "CSPSession: status NOT_LOGGED" ) );
       
  2974 #endif
       
  2975         if ( IsLogged() )
       
  2976             {
       
  2977             // Rare situation where GPRS resume is taken place in negotiation phase.
       
  2978             // iAliveMgr->SendKeepAlive( EFalse );
       
  2979             SendAllQueued();
       
  2980             }
       
  2981         }
       
  2982     else if ( aConnectionState == EInternal_OFF_LINE &&
       
  2983               oldStatus == EInternal_ON_LINE )
       
  2984         {
       
  2985         iIntStatus = EInternal_OFF_LINE;
       
  2986 #ifndef _NO_IMPS_LOGGING_
       
  2987         CImpsClientLogger::Log( _L( "CSPSession: status OFF_LINE" ) );
       
  2988 #endif
       
  2989         }
       
  2990     else if ( iCSPState == EImpsCSPLogging &&
       
  2991               ( aConnectionState == EInternal_NO_IAP ||
       
  2992                 aConnectionState == EInternal_NO_IAP_AUTH ) )
       
  2993         {
       
  2994         // Discard request immediately in this case
       
  2995         // This sends first a login response
       
  2996 #ifndef _NO_IMPS_LOGGING_
       
  2997         CImpsClientLogger::Log( _L( "CSPSession: err: Login cancelled" ) );
       
  2998 #endif
       
  2999         TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  3000         iServer.DiscardRequest( LogTid(), EImpsEventServerLogin, KImpsErrorBearerSuspended, csp );
       
  3001         DoLogout();
       
  3002         }
       
  3003     else if ( aConnectionState == EInternal_NO_IAP )
       
  3004         {
       
  3005         if ( IsNegotiated() )
       
  3006             {
       
  3007             // Check if no WAP SMS CIR negotiated then do logout.
       
  3008             // Otherwise close PDP connection only
       
  3009             if ( iSettings.iSMSWAPCIR == 2 )   // WAP CIR
       
  3010                 {
       
  3011 #ifndef _NO_IMPS_LOGGING_
       
  3012                 CImpsClientLogger::Log( _L( "CSPSession: err: PDP LOST SMS-CIR ***" ) );
       
  3013 #endif
       
  3014                 NewState( EImpsCSPOnLineIdle );
       
  3015                 if ( iPendingPDP == EImpsPDPPendClose )
       
  3016                     {
       
  3017                     iPendingPDP = EImpsPDPPendNone;
       
  3018                     ClosePDP();
       
  3019                     }
       
  3020                 return;
       
  3021                 }
       
  3022             else  // no WAP CIR
       
  3023                 {
       
  3024 #ifndef _NO_IMPS_LOGGING_
       
  3025                 CImpsClientLogger::Log( _L( "CSPSession: err: PDP LOST NO-SMS-CIR ***" ) );
       
  3026 #endif
       
  3027                 DoLogout();
       
  3028                 }
       
  3029             }
       
  3030         else
       
  3031             {
       
  3032 #ifndef _NO_IMPS_LOGGING_
       
  3033             CImpsClientLogger::Log( _L( "CSPSession: err: PDP LOST NOT-NEGOTIATED ***" ) );
       
  3034 #endif
       
  3035             if ( !IsLogged() )
       
  3036                 {
       
  3037                 iIntStatus = EInternal_NOT_LOGGED;
       
  3038                 // This causes DoLogout call from CImpsServer.
       
  3039                 iServer.TransportStatus( EInternal_NO_IAP, this );
       
  3040                 NewState( EImpsCSPIdle );
       
  3041                 return;
       
  3042                 }
       
  3043             else
       
  3044                 // PDP can be lost in negotiation phase. Then we do internal
       
  3045                 // logout.
       
  3046                 {
       
  3047 #ifndef _NO_IMPS_LOGGING_
       
  3048                 CImpsClientLogger::Log( _L( "CSPSession: LOGGED BUT NOT-NEGOTIATED -> Logout ***" ) );
       
  3049 #endif
       
  3050                 DoLogout();
       
  3051                 }
       
  3052             }
       
  3053         }
       
  3054     else if ( aConnectionState == EInternal_NO_IAP_AUTH )
       
  3055         {
       
  3056         // Handle authorative bearer-lost situation here and
       
  3057         // make CSP logout
       
  3058 #ifndef _NO_IMPS_LOGGING_
       
  3059         CImpsClientLogger::Log( _L( "CSPSession: NO_IAP_AUTH ***" ) );
       
  3060 #endif
       
  3061         iIntStatus = EInternal_NOT_LOGGED;
       
  3062         DoLogout();
       
  3063         }
       
  3064 
       
  3065     // Call server's TransportStatus only if this is a state change from
       
  3066     // LOGGED->NOT_LOGGED.
       
  3067     // NOT_LOGGED event clears the client session CSP identification data and
       
  3068     // thus it must not be called in vain..
       
  3069     if ( iIntStatus == EInternal_NOT_LOGGED && oldStatus != EInternal_NOT_LOGGED )
       
  3070         {
       
  3071         iServer.TransportStatus( iIntStatus, this );
       
  3072         }
       
  3073     }
       
  3074 
       
  3075 // ---------------------------------------------------------
       
  3076 // CImpsCSPSession::CirChOpened
       
  3077 // ---------------------------------------------------------
       
  3078 //
       
  3079 void CImpsCSPSession::CirChOpened( )
       
  3080     {
       
  3081 #ifndef _NO_IMPS_LOGGING_
       
  3082     CImpsClientLogger::Log( _L( "CSPSession: CirChOpened" ) );
       
  3083 #endif
       
  3084     iTcpCIRError = EFalse;
       
  3085     }
       
  3086 
       
  3087 // ---------------------------------------------------------
       
  3088 // CImpsCSPSession::CirChError
       
  3089 // ---------------------------------------------------------
       
  3090 //
       
  3091 void CImpsCSPSession::CirChError( )
       
  3092     {
       
  3093 #ifndef _NO_IMPS_LOGGING_
       
  3094     CImpsClientLogger::Log( _L( "CSPSession: CirChError csp=%d" ), ( TInt )this );
       
  3095 #endif
       
  3096     delete iCirManager;
       
  3097     iCirManager = NULL;
       
  3098     // start poll mode again
       
  3099     if ( IsLogged() )
       
  3100         {
       
  3101         iPollTime = iSettings.iPollTime;
       
  3102         iPollState = EImpsPollAdaptive;
       
  3103         iIdleTimer->Start( iPollTime );
       
  3104         iPDPIdleTimer->Stop();
       
  3105 #ifndef _NO_IMPS_LOGGING_
       
  3106         CImpsClientLogger::Log( _L( "CSPSession: iPollState %d" ), iPollState );
       
  3107         CImpsClientLogger::Log( _L( "CSPSession: iPollTime %d" ), iPollTime );
       
  3108 #endif
       
  3109         }
       
  3110     }
       
  3111 
       
  3112 // ---------------------------------------------------------
       
  3113 // CImpsCSPSession::SetConnAllowed
       
  3114 // ---------------------------------------------------------
       
  3115 //
       
  3116 void CImpsCSPSession::SetConnAllowed( TBool aParam )
       
  3117     {
       
  3118 #ifndef _NO_IMPS_LOGGING_
       
  3119     CImpsClientLogger::Log( _L( "CSPSession: SetConnAllowed %d" ), aParam );
       
  3120 #endif
       
  3121     iConAllowed = aParam;
       
  3122     // Logout CSP session on behalf of user if terminal connection is not allowed.
       
  3123     if ( !aParam )
       
  3124         {
       
  3125         // It's important that data channel is started to close first and after
       
  3126         // that internal CSP disconnect is done.
       
  3127         iReceiver2->CloseTr( );
       
  3128         DoLogout( );
       
  3129         }
       
  3130     }
       
  3131 
       
  3132 // ---------------------------------------------------------
       
  3133 // CImpsCSPSession::DoSendSingleL
       
  3134 // aAc connot be null
       
  3135 // ---------------------------------------------------------
       
  3136 //
       
  3137 void CImpsCSPSession::DoSendSingleL(
       
  3138     MImpsDataAccessor* aAc,
       
  3139     const TDesC& aTID,
       
  3140     TImpsMessageType aMsgType,
       
  3141     TInt aExpiryTime )
       
  3142     {
       
  3143 #ifndef _NO_IMPS_LOGGING_
       
  3144     CImpsClientLogger::Log( _L( "CSPSession: DoSendSingle messagetype = 0x%x csp=%d" ),
       
  3145                             aMsgType, ( TInt )this );
       
  3146 #endif
       
  3147 
       
  3148     // Set the WV 1.2 version if needed, WV 1.1 is the default
       
  3149     if ( iCSPVersion == EImpsCspVersion12 )
       
  3150         {
       
  3151         CImpsFields* f = aAc->GetImpsFields();
       
  3152         f->SetCspVersion( EImpsCspVersion12 );
       
  3153         }
       
  3154 
       
  3155     // Encode the message
       
  3156     iEncoder->EncodeMessageL( *aAc, *iTransportOut );
       
  3157 
       
  3158     // Send to the transport module
       
  3159 #ifndef _NO_IMPS_LOGGING_
       
  3160     CImpsClientLogger::Log( _L( "CSPSession: DoSendSingle message encoded = 0x%x" ), aMsgType );
       
  3161 #endif
       
  3162 
       
  3163     // reset PDP idle timer
       
  3164     iPDPIdleTimer->Reset();
       
  3165 
       
  3166     iReceiver2->SendAndWaitL( aTID, aExpiryTime );
       
  3167     iLastSent = aMsgType;
       
  3168 
       
  3169     // Notice: Maintain this list of non terminal originated
       
  3170     // transactions, send by terminal to SAP.
       
  3171     if ( !( aMsgType == EImpsPolling || aMsgType == EImpsKeepAliveReq ||
       
  3172             aMsgType == EImpsStatus  || aMsgType == EImpsMessageDelivered ) )
       
  3173         {
       
  3174         iTr++;
       
  3175 #ifndef _NO_IMPS_LOGGING_
       
  3176         CImpsClientLogger::Log( _L( "CSPSession: DoSendSingle iTr = %d" ), iTr );
       
  3177 #endif
       
  3178         }
       
  3179     // Anything except Poll and KeepAlive request resets Poll Timer.
       
  3180     if ( !( aMsgType == EImpsPolling || aMsgType == EImpsKeepAliveReq ) )
       
  3181         {
       
  3182         ResetPollTime( );
       
  3183         }
       
  3184 
       
  3185 #ifdef _FAKE_RESPONSE
       
  3186     iTestMsgTid = aTID;
       
  3187 #endif
       
  3188     }
       
  3189 // -----------------------------------------------------------------------------
       
  3190 // CImpsCSPSession::DoSendLogoutL
       
  3191 // -----------------------------------------------------------------------------
       
  3192 void CImpsCSPSession::DoSendLogoutL( const TDesC& aTID )
       
  3193     {
       
  3194 #ifndef _NO_IMPS_LOGGING_
       
  3195     CImpsClientLogger::Log( _L( "CSPSession: DoSendLogoutL csp=%d" ), ( TInt )this );
       
  3196 #endif
       
  3197 
       
  3198     // Check if the transport is halted
       
  3199     if ( iReceiver2->NbrOfPending() >= KImpsMaxPending )
       
  3200         {
       
  3201         User::Leave( KErrInUse );
       
  3202         }
       
  3203 
       
  3204     NewState( EImpsCSPDisconnecting );
       
  3205     // Set expiry time for logout.
       
  3206     // In case of Login-csncel expiry time is not overwritten, but it
       
  3207     // is the original login expiry time.
       
  3208     // Otherwise clint session would expire first and the user client would get
       
  3209     // normal time-out error, but we want that the user gets OK response.
       
  3210     if ( !iCancelLogin )
       
  3211         {
       
  3212         iNegoExpiry = iServer.ExpiryTime( EImpsEventServerLogin );
       
  3213         }
       
  3214 
       
  3215     // Make a logout request (encode)
       
  3216     iSnd->Reset();
       
  3217 
       
  3218     // Insert CSP Session-id
       
  3219     iSnd->SetSessionIdL( iCSPSessionId );
       
  3220     iSnd->SetTidL( aTID );
       
  3221     iSnd->SetMessageType( EImpsLogoutReq );
       
  3222 
       
  3223     // Session type is inband
       
  3224     iSnd->SetSessionTypeL( EImpsInband );
       
  3225 
       
  3226     TImpsDataAccessor myAc( iSnd );
       
  3227     CImpsKey* myKey = CImpsKey::NewLC();    // <<< myKey
       
  3228 
       
  3229     // Add TImpsTransactionMode
       
  3230     TImpsSDataUtils::AddValuesFromArrayL(
       
  3231         myKey,
       
  3232         KTransModeElements,
       
  3233         sizeof( KTransModeElements ) /
       
  3234         sizeof( KTransModeElements[0] ) );
       
  3235     myAc.StoreIntegerL( myKey, EImpsRequest );
       
  3236     myKey->Reset();
       
  3237     TImpsSDataUtils::AddValuesFromArrayL(
       
  3238         myKey,
       
  3239         KTransContentElements,
       
  3240         sizeof( KTransContentElements ) /
       
  3241         sizeof( KTransContentElements[0] ) );
       
  3242     myKey->AddL( CREATEKEY( EImpsKeyLogout_Request, 0 ) );
       
  3243     myAc.StoreEmptyL( myKey );
       
  3244 
       
  3245     CleanupStack::PopAndDestroy( 1 );   // >>> myKey
       
  3246 
       
  3247     DoSendSingleL( &myAc, aTID, EImpsLogoutReq );
       
  3248     }
       
  3249 
       
  3250 // -----------------------------------------------------------------------------
       
  3251 // CImpsCSPSession::DoMakeSapResponseL
       
  3252 // -----------------------------------------------------------------------------
       
  3253 //
       
  3254 void CImpsCSPSession::DoMakeSapResponseL( CTransaction* aTrans )
       
  3255     {
       
  3256     TPtrC tid;
       
  3257     CImpsFields* fields = aTrans->iFields;
       
  3258     tid.Set( aTrans->iTID );
       
  3259     TInt messageType = fields->MessageType();
       
  3260 
       
  3261     TInt responseType = EImpsStatus;
       
  3262     // Copy values from the new message to a response
       
  3263     iSnd->Reset();
       
  3264     iSnd->SetSessionIdL( fields->SessionIdL() );
       
  3265     iSnd->SetTidL( fields->TidL() );
       
  3266     iSnd->SetSessionTypeL( EImpsInband );
       
  3267 
       
  3268 #ifndef _NO_IMPS_LOGGING_
       
  3269     TPtrC tid2;
       
  3270     tid2.Set( fields->TidL() );
       
  3271     CImpsClientLogger::Log( _L( "CSPSession: MakeSAPresp SAP TID=%S" ), &( tid2 ) );//lint !e525
       
  3272 #endif
       
  3273 
       
  3274     CImpsDataAccessor* myAccess = CImpsDataAccessor::NewL( iSnd );
       
  3275     CleanupStack::PushL( myAccess );    // << myAccess
       
  3276     CImpsKey* myKey = CImpsKey::NewLC();  // <<< myKey
       
  3277 
       
  3278     CImpsDataAccessor* myAcRcv = CImpsDataAccessor::NewL( fields );
       
  3279     CleanupStack::PushL( myAcRcv );    // << myAcRcv
       
  3280 
       
  3281     TPtrC myId;
       
  3282 
       
  3283     switch ( messageType )
       
  3284         {
       
  3285         case EImpsNewMessage:
       
  3286             responseType = EImpsMessageDelivered;
       
  3287             iSnd->SetMessageType( responseType );
       
  3288             // Get messageId from received message
       
  3289             TImpsSDataUtils::GetNewMessageIdL( myKey, myAcRcv, myId );
       
  3290             // ... and copy data to outgoing response
       
  3291             TImpsSDataUtils::SetMessageDeliveredIdL(
       
  3292                 myKey, myAccess, myId );
       
  3293             break;
       
  3294         default:
       
  3295             iSnd->SetMessageType( responseType );
       
  3296             TImpsSDataUtils::SetResultStatusL( myKey, myAccess, KImpsStatusOk );
       
  3297             break;
       
  3298         }
       
  3299 
       
  3300     CleanupStack::PopAndDestroy( 1 );   // >> myAcRcv
       
  3301 
       
  3302     // Add TImpsTransactionMode now
       
  3303     myKey->Reset();
       
  3304     TImpsSDataUtils::AddValuesFromArrayL(
       
  3305         myKey,
       
  3306         KTransModeElements,
       
  3307         sizeof( KTransModeElements ) /
       
  3308         sizeof( KTransModeElements[0] ) );
       
  3309     myAccess->StoreIntegerL( myKey, EImpsResponse );
       
  3310     CleanupStack::PopAndDestroy( 1 );   // >>> myKey
       
  3311 
       
  3312     // -------------------------------------------
       
  3313     // Handle orphan message
       
  3314     if ( aTrans->iOrphan )
       
  3315         {
       
  3316         TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  3317         TRAPD( errx, iServer.HandleOrphanL( aTrans->iFields, csp ) );
       
  3318         if ( !errx )
       
  3319             {
       
  3320             // ownership of the msg is in CImpsServer now
       
  3321             aTrans->iFields = NULL;
       
  3322             }
       
  3323         }
       
  3324     // -------------------------------------------
       
  3325 
       
  3326     // DoSendSingleL leaves if GPRS suspended,
       
  3327     // so don't delete entry too early
       
  3328     DoSendSingleL( myAccess, tid, ( TImpsMessageType )responseType );
       
  3329 
       
  3330 
       
  3331     // Save TID into tid-sap-history so that we so not send the response twicw
       
  3332     // even if SAP would send the transaction multiple times.
       
  3333     iTidSapHistory->Add( tid );
       
  3334 
       
  3335     CleanupStack::PopAndDestroy( 1 );   // >> myAccess
       
  3336     }
       
  3337 
       
  3338 // -----------------------------------------------------------------------------
       
  3339 // CImpsCSPSession::DoStartIpCIRL
       
  3340 // -----------------------------------------------------------------------------
       
  3341 //
       
  3342 void CImpsCSPSession::DoStartIpCIRL()
       
  3343     {
       
  3344     // Start ip-cir-watcher
       
  3345     if ( iVariant.IsFeatureSupportedL( EIpCirStandalone ) &&
       
  3346          iSettings.iTCPSCIR == 2 || iSettings.iUDPSCIR == 2 )
       
  3347         {
       
  3348         // Check which CIR bindings are negotiated for CSP session
       
  3349         TUint ipChannels = 0;
       
  3350         if ( iSettings.iTCPSCIR == 2 )
       
  3351             {
       
  3352             ipChannels = KImpsCirTcp;
       
  3353             }
       
  3354         if ( iSettings.iUDPSCIR == 2 )
       
  3355             {
       
  3356             ipChannels = ipChannels | KImpsCirUdp;
       
  3357             }
       
  3358 #ifndef _NO_IMPS_LOGGING_
       
  3359         CImpsClientLogger::Log( _L( "CSPSession: Starting ip-cir-watcher %d" ),
       
  3360                                 ipChannels );
       
  3361 #endif
       
  3362         iCSPSessionId8.Copy( iCSPSessionId );
       
  3363         if ( !iCirManager )
       
  3364             {
       
  3365             iCirManager = CImpsCirManager::NewL( *this,
       
  3366                                                  CActive::EPriorityStandard );
       
  3367             }
       
  3368         iCirManager->OpenChL( ipChannels, iReceiver2->ConnManagerHandleL(),
       
  3369                               iTCPPort, *iTCPAddr, iCSPSessionId8 );
       
  3370         }
       
  3371     }
       
  3372 
       
  3373 // -----------------------------------------------------------------------------
       
  3374 // CImpsCSPSession::IncreasePollTime
       
  3375 // -----------------------------------------------------------------------------
       
  3376 //
       
  3377 void CImpsCSPSession::IncreasePollTime()
       
  3378     {
       
  3379     // Increase poll timer. Two modes; CIR Mode and other modes.
       
  3380     if ( iPollState == EImpsPollCIR )
       
  3381         {
       
  3382         ResetPollTime();
       
  3383         }
       
  3384     else if ( iPollTime < iSettings.iMaxPollTime && iIdleTimer->IsActive() )
       
  3385         {
       
  3386         iPollTime += KImpsPollIncrement;
       
  3387         iIdleTimer->Start( iPollTime );
       
  3388 #ifndef _NO_IMPS_LOGGING_
       
  3389         CImpsClientLogger::Log( _L( "CSPSession: PollTime increased to %d" ), iPollTime );
       
  3390 #endif
       
  3391         }
       
  3392     }
       
  3393 
       
  3394 // -----------------------------------------------------------------------------
       
  3395 // CImpsCSPSession::ResetPollTime
       
  3396 // -----------------------------------------------------------------------------
       
  3397 //
       
  3398 void CImpsCSPSession::ResetPollTime()
       
  3399     {
       
  3400     // Reset poll timer. Two modes; CIR Mode and other modes.
       
  3401     if ( iPollState == EImpsPollCIR )
       
  3402         {
       
  3403         if ( iPollTime != iSettings.CIRModePollTime() )
       
  3404             {
       
  3405             iPollTime = iSettings.CIRModePollTime();
       
  3406             iIdleTimer->Start( iPollTime );
       
  3407 #ifndef _NO_IMPS_LOGGING_
       
  3408             CImpsClientLogger::Log( _L( "CSPSession: PollTime reset %d" ), iPollTime );
       
  3409 #endif
       
  3410             }
       
  3411         }
       
  3412     else if ( iPollTime > iSettings.iPollTime && iIdleTimer->IsActive() )
       
  3413         {
       
  3414         iPollTime = iSettings.iPollTime;
       
  3415         iIdleTimer->Start( iPollTime );
       
  3416 #ifndef _NO_IMPS_LOGGING_
       
  3417         CImpsClientLogger::Log( _L( "CSPSession: PollTime reset %d" ), iPollTime );
       
  3418 #endif
       
  3419         }
       
  3420     }
       
  3421 
       
  3422 // -----------------------------------------------------------------------------
       
  3423 // CImpsCSPSession::IsLogged
       
  3424 // -----------------------------------------------------------------------------
       
  3425 //
       
  3426 TBool CImpsCSPSession::IsLogged(  )
       
  3427     {
       
  3428     return DoIsLogged();
       
  3429     }
       
  3430 
       
  3431 // -----------------------------------------------------------------------------
       
  3432 // CImpsCSPSession::IsPendingLogin
       
  3433 // -----------------------------------------------------------------------------
       
  3434 //
       
  3435 TBool CImpsCSPSession::IsPendingLogin()
       
  3436     {
       
  3437     return iCSPState == EImpsCSPLogging ? ETrue : EFalse;
       
  3438     }
       
  3439 
       
  3440 // -----------------------------------------------------------------------------
       
  3441 // CImpsCSPSession::IsNegotiated
       
  3442 // -----------------------------------------------------------------------------
       
  3443 //
       
  3444 TBool CImpsCSPSession::IsNegotiated(  )
       
  3445     {
       
  3446     return DoIsNegotiated();
       
  3447     }
       
  3448 
       
  3449 // -----------------------------------------------------------------------------
       
  3450 // CImpsCSPSession::Servicses
       
  3451 // -----------------------------------------------------------------------------
       
  3452 //
       
  3453 TImpsServices* CImpsCSPSession::Services(  )
       
  3454     {
       
  3455     return &iServices;  //lint !e1536 this pointer must be used with care
       
  3456     }
       
  3457 
       
  3458 // -----------------------------------------------------------------------------
       
  3459 // CImpsCSPSession::IsShuttingDown
       
  3460 // -----------------------------------------------------------------------------
       
  3461 //
       
  3462 TBool CImpsCSPSession::IsShuttingDown(  )
       
  3463     {
       
  3464     return DoIsShuttingDown();
       
  3465     }
       
  3466 
       
  3467 // -----------------------------------------------------------------------------
       
  3468 // CImpsCSPSession::IsLogging
       
  3469 // -----------------------------------------------------------------------------
       
  3470 //
       
  3471 TBool CImpsCSPSession::IsLogging(  )
       
  3472     {
       
  3473     return DoIsLogging();
       
  3474     }
       
  3475 
       
  3476 // -----------------------------------------------------------------------------
       
  3477 // CImpsCSPSession::UserId
       
  3478 // -----------------------------------------------------------------------------
       
  3479 //
       
  3480 TPtrC CImpsCSPSession::UserId(  )
       
  3481     {
       
  3482     return DoUserId();
       
  3483     }
       
  3484 
       
  3485 // -----------------------------------------------------------------------------
       
  3486 // CImpsCSPSession::SAP
       
  3487 // -----------------------------------------------------------------------------
       
  3488 //
       
  3489 TPtrC CImpsCSPSession::SAP(  )
       
  3490     {
       
  3491     return DoSAP();
       
  3492     }
       
  3493 
       
  3494 // -----------------------------------------------------------------------------
       
  3495 // CImpsCSPSession::SID
       
  3496 // -----------------------------------------------------------------------------
       
  3497 //
       
  3498 TPtrC CImpsCSPSession::SID(  )
       
  3499     {
       
  3500     return iCSPSessionId;
       
  3501     }
       
  3502 
       
  3503 // -----------------------------------------------------------------------------
       
  3504 // CImpsCSPSession::Password
       
  3505 // -----------------------------------------------------------------------------
       
  3506 //
       
  3507 TPtrC CImpsCSPSession::Password(  )
       
  3508     {
       
  3509     return LogPwd();
       
  3510     }
       
  3511 
       
  3512 // -----------------------------------------------------------------------------
       
  3513 // CImpsCSPSession::GiveNextRequestL
       
  3514 // -----------------------------------------------------------------------------
       
  3515 CReq* CImpsCSPSession::GiveNextRequestL()
       
  3516     {
       
  3517 
       
  3518 #ifndef _NO_IMPS_LOGGING_
       
  3519     CImpsClientLogger::Log( _L( "CSPSession: GiveNextRequestL begins" ) );
       
  3520 #endif
       
  3521     // If logginOff then this should be logout request
       
  3522     TDblQueIter<CReq> iter ( iRequestList );
       
  3523     iter.SetToFirst();
       
  3524 
       
  3525     while ( iter )
       
  3526         {
       
  3527         CReq* request = iter;
       
  3528         // Get first and check if it is expired
       
  3529         iter++;
       
  3530 
       
  3531         TTime myTime;
       
  3532         myTime.HomeTime();
       
  3533         if ( request->iExpiry < myTime )
       
  3534             {
       
  3535             // session is asked to discard request from its structures
       
  3536             // Check TID match
       
  3537 #ifndef _NO_IMPS_LOGGING_
       
  3538             CImpsClientLogger::Log( _L( "Server: EXPIRED entry to be removed" ) );
       
  3539 #endif
       
  3540             TImpsMessageType msgType = ( TImpsMessageType ) request->iFields->MessageType();
       
  3541             TImpsEventType myType = impsService( &iVariant, msgType );
       
  3542             // expired request is destroyed in client sessions too.
       
  3543             TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  3544             iServer.DiscardRequest( request->iFields->TidL(), myType, KErrTimedOut, csp );
       
  3545 
       
  3546             // expired entry is deleted
       
  3547             request->Destroy();
       
  3548             TrMinus();
       
  3549 
       
  3550             // We want to push new messages from queued
       
  3551             SendAllQueued();
       
  3552 
       
  3553             }  // expired
       
  3554         else
       
  3555             {
       
  3556             return request;
       
  3557             }
       
  3558         }
       
  3559 
       
  3560     return ( CReq* )NULL;
       
  3561     }
       
  3562 
       
  3563 
       
  3564 // -----------------------------------------------------------------------------
       
  3565 // CImpsCSPSession::NewState
       
  3566 // -----------------------------------------------------------------------------
       
  3567 void CImpsCSPSession::NewState( TImpsCSPState aNew )
       
  3568     {
       
  3569 #ifndef _NO_IMPS_LOGGING_
       
  3570     CImpsClientLogger::Log( _L( "CSPSession: NewState old=%d new=%d csp=%d" ),
       
  3571                             iCSPState, aNew, ( TInt )this );
       
  3572 #endif
       
  3573     // In  EImpsCSPDisconnecting iLogTid is still needed fore cancel-login
       
  3574     if ( iCSPState >= EImpsCSPLogging && aNew < EImpsCSPDisconnecting )
       
  3575         {
       
  3576         delete iLogTid;
       
  3577         iLogTid = NULL;
       
  3578         }
       
  3579     if ( aNew == EImpsCSPIdle )
       
  3580         {
       
  3581         iTr = 0;
       
  3582         iCookie = KNullDesC;
       
  3583         iCookie8 = KNullDesC8;
       
  3584         iCSPSessionId = KNullDesC;
       
  3585         iCSPSessionId8 = KNullDesC8;
       
  3586         iLoginPhase = 1;
       
  3587         }
       
  3588     else if ( aNew <= EImpsCSPOnLine )
       
  3589         {
       
  3590         // PDP is opened sucessfully or CSP login not done or logging out.
       
  3591         iPDPOpenTimer->Stop();
       
  3592         }
       
  3593     iCSPState = aNew;
       
  3594     }
       
  3595 
       
  3596 
       
  3597 // -----------------------------------------------------------------------------
       
  3598 // CImpsCSPSession::TrMinus
       
  3599 // -----------------------------------------------------------------------------
       
  3600 void CImpsCSPSession::TrMinus()
       
  3601     {
       
  3602     if ( iTr > 0 )
       
  3603         {
       
  3604         iTr--;
       
  3605         }
       
  3606 #ifndef _NO_IMPS_LOGGING_
       
  3607     CImpsClientLogger::Log( _L( "CSPSession: iTr=%d csp=%d" ), iTr, ( TInt )this );
       
  3608 #endif
       
  3609     }
       
  3610 
       
  3611 
       
  3612 // -----------------------------------------------------------------------------
       
  3613 // CImpsCSPSession::ResetSession
       
  3614 // -----------------------------------------------------------------------------
       
  3615 void CImpsCSPSession::ResetSession()
       
  3616     {
       
  3617 #ifndef _NO_IMPS_LOGGING_
       
  3618     CImpsClientLogger::Log( _L( "CSPSession: ResetSession csp=%d" ), ( TInt )this );
       
  3619 #endif
       
  3620     // This is not needed since CSP session entity is not re-cycled?
       
  3621     iSettings.iUDPWAPCIR = 1;
       
  3622     iSettings.iSMSWAPCIR = 1;
       
  3623     iSettings.iTCPSCIR = 1;
       
  3624     iSettings.iUDPSCIR = 1;
       
  3625     iSettings.iPollTime = KImpsPollTime;
       
  3626     }
       
  3627 
       
  3628 
       
  3629 // -----------------------------------------------------------------------------
       
  3630 // CImpsCSPSession::MaxParserSize
       
  3631 // -----------------------------------------------------------------------------
       
  3632 TInt CImpsCSPSession::MaxParserSize()
       
  3633     {
       
  3634     return iServer.Settings()->MaximumParserSize();
       
  3635     }
       
  3636 
       
  3637 // -----------------------------------------------------------------------------
       
  3638 // CImpsCSPSession::MaxParserSize
       
  3639 // -----------------------------------------------------------------------------
       
  3640 TInt CImpsCSPSession::MaxMessageSize()
       
  3641     {
       
  3642     return iServer.Settings()->MaximumMessageSize();
       
  3643     }
       
  3644 
       
  3645 // -----------------------------------------------------------------------------
       
  3646 // CTransaction::CTransaction
       
  3647 // -----------------------------------------------------------------------------
       
  3648 
       
  3649 CTransaction::CTransaction(
       
  3650     TBool aOrphan,
       
  3651     const TDesC& aTID,
       
  3652     const TDesC& aSessionId,
       
  3653     TImpsMessageType aMessageType,
       
  3654     CImpsFields* aFields ) :
       
  3655         iMessageType( aMessageType ),
       
  3656         iFields ( aFields ),
       
  3657         iOrphan ( aOrphan )
       
  3658     {
       
  3659     iTID = aTID;
       
  3660     iSessionId = aSessionId;
       
  3661     }
       
  3662 
       
  3663 CTransaction::~CTransaction()
       
  3664     {
       
  3665 
       
  3666     } //lint !e1540 iFields freed in Destroy
       
  3667 
       
  3668 void CTransaction::Destroy()
       
  3669     {
       
  3670     iLink.Deque();
       
  3671     delete iFields;
       
  3672     iFields = NULL;
       
  3673     delete this;
       
  3674     }
       
  3675 
       
  3676 
       
  3677 // -----------------------------------------------------------------------------
       
  3678 // CReq::CReq
       
  3679 // -----------------------------------------------------------------------------
       
  3680 
       
  3681 CReq::CReq( CImpsFields* aFields ) :
       
  3682         iFields( aFields )
       
  3683     {}
       
  3684 
       
  3685 CReq::~CReq()
       
  3686     {
       
  3687 
       
  3688     }   //lint !e1540 iFields freed in Destroy
       
  3689 
       
  3690 void CReq::Destroy()
       
  3691     {
       
  3692     delete iFields;
       
  3693     iFields = NULL;
       
  3694     iLink.Deque();
       
  3695     delete this;
       
  3696     }
       
  3697 
       
  3698 // -----------------------------------------------------------------------------
       
  3699 // CImpsCSPSession::IsLogoutResp()
       
  3700 // aFields must not be NULL
       
  3701 // -----------------------------------------------------------------------------
       
  3702 TImpsLogoutTrans CImpsCSPSession::IsLogoutResp( CImpsFields* aFields )
       
  3703     {
       
  3704     TImpsLogoutTrans ret = EImpsLogoutNone;
       
  3705 
       
  3706     // set pointers to received TID and to current pending Logout-request TID
       
  3707     TPtrC recId;
       
  3708     TPtrC logoutTid;
       
  3709     logoutTid.Set( LogoutTID() );
       
  3710     TRAPD( errxy, recId.Set( aFields->TidL() ) );
       
  3711     if ( errxy )
       
  3712         {
       
  3713         return ret;
       
  3714         }
       
  3715 
       
  3716     // Check if current logout transaction TID matches with received message.
       
  3717     if ( iCSPState == EImpsCSPDisconnecting &&
       
  3718          !logoutTid.Length() || ( logoutTid.Length() && !recId.Compare( logoutTid  ) ) )  // NOTE
       
  3719         {
       
  3720         if ( aFields->MessageType() == EImpsDisconnect )
       
  3721             {
       
  3722             // WV 1.1 logout response
       
  3723             ret = EImpsLogoutTerminal;
       
  3724             }
       
  3725         else if ( aFields->MessageType() == EImpsStatus )
       
  3726             {
       
  3727             // WV 1.2 logout response
       
  3728             ret = EImpsLogoutTerminal;
       
  3729             }
       
  3730         }
       
  3731     else if ( aFields->MessageType() == EImpsDisconnect )
       
  3732         {
       
  3733         // SAP initiated CSP disconnect
       
  3734         ret = EImpsLogoutSAP;
       
  3735         }
       
  3736 #ifndef _NO_IMPS_LOGGING_
       
  3737     CImpsClientLogger::Log( _L( "CSPSession: IsLogoutResp returns %d csp=%d" ),
       
  3738                             ret, ( TInt )this );
       
  3739 #endif
       
  3740     return ret;
       
  3741     }
       
  3742 
       
  3743 // -----------------------------------------------------------------------------
       
  3744 // CImpsCSPSession::StartLoginCancel()
       
  3745 // -----------------------------------------------------------------------------
       
  3746 void CImpsCSPSession::StartLoginCancel( )
       
  3747     {
       
  3748     // Cancel login transaction, either login+logout or login+cancelLogin.
       
  3749     // DoPendingLogout() is called later to complete the client requests.
       
  3750     if ( iReceiver2->CancelLoginTrans( LogTid() ) )
       
  3751         {
       
  3752         // Generate CSP Logout transaction
       
  3753         // Clear buffers from old stuff
       
  3754         DeleteRequests();
       
  3755         DeleteTransactions();
       
  3756         // Send Logout primitive and set state to EImpsCSPDisconnecting.
       
  3757         TRAPD( errx, DoSendLogoutL( LogoutTID() ) );
       
  3758         if ( errx )
       
  3759             {
       
  3760 #ifndef _NO_IMPS_LOGGING_
       
  3761             CImpsClientLogger::Log( _L( "CSPSession: DoSendLogoutL 2 error %d ***" ), errx );
       
  3762 #endif
       
  3763             }
       
  3764         else
       
  3765             {
       
  3766             // If CSP Logout transaction is sent then we wait TransportResponseL or
       
  3767             // TransportErrorL callback methods to be called later.
       
  3768             return;
       
  3769             }
       
  3770         }
       
  3771     // Start to send events to clients if CSP Disconnect transaction is not sent.
       
  3772     DoPendingLogout();
       
  3773     }
       
  3774 
       
  3775 // -----------------------------------------------------------------------------
       
  3776 // CImpsCSPSession::DoPendingLogout()
       
  3777 // -----------------------------------------------------------------------------
       
  3778 void CImpsCSPSession::DoPendingLogout( )
       
  3779     {
       
  3780 #ifndef _NO_IMPS_LOGGING_
       
  3781     CImpsClientLogger::Log( _L( "CSPSession: DoPendingLogout ***" ) );
       
  3782 #endif
       
  3783     // Send critical response events to client sessions and start to logout
       
  3784     // internally this CSP session entity.
       
  3785     TImpsSessIdent csp( iCSPSessionId, DoSAP(), DoUserId() );
       
  3786     if ( iPendingLogout )
       
  3787         {
       
  3788         // Send login response for pending request first
       
  3789         iServer.DiscardRequest( LogTid(), EImpsEventServerLogin, KErrCancel, csp );
       
  3790         // Send logout response, that is always successful
       
  3791         iServer.DiscardLogout( LogoutTID(), csp );
       
  3792         }
       
  3793 
       
  3794     if ( iCancelLogin  )
       
  3795         {
       
  3796         // Send cancel-login response to client
       
  3797         iServer.DiscardRequest( LogTid(), EImpsEventServerLogin, KErrNone, csp );
       
  3798         }
       
  3799 
       
  3800     iPendingLogout = EFalse;
       
  3801     iCancelLogin = EFalse;
       
  3802     DoLogout();
       
  3803     }
       
  3804 
       
  3805 //  End of File