IMPSengine/engsrv/src/impsserver.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2002-2006 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: Classes for IM server and Conn.
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    <e32math.h>
       
    23 #include    <ecom/ecom.h>
       
    24 #include    "impsserver.h"
       
    25 #include    "impssession.h"
       
    26 #include    "impssubsession.h"
       
    27 #include    "impsfields.h"
       
    28 #include    "impsutils.h"
       
    29 #include    "impserrors.h"
       
    30 #include    "impstimer.h"
       
    31 #include    "impsservices.h"
       
    32 #include    "impscommonenums.h"
       
    33 #include    "impssdatautils.h"
       
    34 #include    "impsmessageinterpreterapi.h"
       
    35 #include    "ImpsVariantAPI.h"
       
    36 #include    "impscspsession.h"
       
    37 #include    "impsorphans.h"
       
    38 #include    "impstoffobserver.h"
       
    39 #include    "WVEngineInternalCRKeys.h"
       
    40 
       
    41 
       
    42 #include    "impsserversecuritypolicy.h"
       
    43 
       
    44 
       
    45 // MACROS
       
    46 #ifndef _DEBUG
       
    47 #define _NO_IMPS_LOGGING_
       
    48 #endif
       
    49 
       
    50 // CONSTANTS
       
    51 // Shutdown idle wait time in seconds
       
    52 const TInt KImpsShutdownTime = 0;
       
    53 // Overhead estimate for XML message : total - transaction content
       
    54 const TInt KImpsBufOverhead = 100;
       
    55 
       
    56 // ================= MEMBER FUNCTIONS =======================
       
    57 
       
    58 void CImpsScheduler::Error( TInt anError ) const
       
    59     {
       
    60     // This is just for compiler to avoid warning
       
    61     TInt err = anError;
       
    62 #ifndef _NO_IMPS_LOGGING_
       
    63     CImpsClientLogger::Log( _L( "Scheduler: error=%d" ), anError );
       
    64 #endif
       
    65     // This is just for another compiler to avoid warning
       
    66     anError = err;
       
    67     }
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // CLASS CImpsConn
       
    71 // -----------------------------------------------------------------------------
       
    72 CImpsConn::CImpsConn( MImpsCSPSession* aSess ) :
       
    73         iSess( aSess ), iRemover( NULL )
       
    74     {}
       
    75 
       
    76 CImpsConn::~CImpsConn()
       
    77     {
       
    78 
       
    79     }   //lint !e1540 iSess freed in Destroy
       
    80 
       
    81 // Two-phased constructor.
       
    82 CImpsConn* CImpsConn::NewL( MImpsCSPSession* aSess, CImpsServer& aServer )
       
    83     {
       
    84     CImpsConn* self = new ( ELeave ) CImpsConn( aSess );
       
    85     CleanupStack::PushL( self );
       
    86     self->ConstructL( aServer );
       
    87     CleanupStack::Pop();
       
    88     return self;
       
    89     }
       
    90 
       
    91 // Two-phased constructor.
       
    92 // It creates an active object to destroy CSP session asynchronously later.
       
    93 // It's better to create it now to avoid OOM errors in CSP closing.
       
    94 void CImpsConn::ConstructL( CImpsServer& aServer )
       
    95     {
       
    96     iRemover = new ( ELeave ) CImpsCSPDestroyer(
       
    97         aServer, *iSess, CActive::EPriorityUserInput + 1 );
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CImpsConn::Destroy
       
   102 // -----------------------------------------------------------------------------
       
   103 void CImpsConn::Destroy()
       
   104     {
       
   105     iRemover->Cancel();
       
   106     delete iRemover;
       
   107     iSess->Destroy();
       
   108     delete ( CImpsCSPSession* )iSess;
       
   109     iSess = NULL;
       
   110     iLink.Deque();
       
   111     delete this;
       
   112     }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CImpsConn::Sess
       
   116 // -----------------------------------------------------------------------------
       
   117 MImpsCSPSession* CImpsConn::Sess()
       
   118     {
       
   119     return iSess;
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CImpsConn::DeleteCSPAsynch
       
   124 // -----------------------------------------------------------------------------
       
   125 void CImpsConn::DeleteCSPAsynch()
       
   126     {
       
   127     // iRemover cannot be NULL since it's created in contructor
       
   128     if ( iRemover->IsActive() )
       
   129         {
       
   130         // asynchronous request already runnig, nothing to do
       
   131         return;
       
   132         }
       
   133     iRemover->DeleteCSPAsynch( );
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CImpsConn::MatchCSP
       
   138 // -----------------------------------------------------------------------------
       
   139 TBool CImpsConn::MatchCSP( TImpsSessIdent aCSP )
       
   140     {
       
   141     if ( ( aCSP.UserId().Compare( iSess->UserId() ) ) ||
       
   142          ( aCSP.SAP().Compare( iSess->SAP() ) ) )
       
   143         // Notice: no need for this
       
   144         // ( aCSP.SID().Length() && aCSP.SID().Compare( iSess->SID() )))
       
   145         {
       
   146         return EFalse;
       
   147         }
       
   148     return ETrue;
       
   149     }
       
   150 
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CLASS CImpsCSPDestroyer
       
   154 // -----------------------------------------------------------------------------
       
   155 CImpsCSPDestroyer::CImpsCSPDestroyer(
       
   156     CImpsServer& aServer, MImpsCSPSession& aSess, TInt aPriority )
       
   157         : CActive( aPriority ),
       
   158         iServer( aServer ),
       
   159         iSess( aSess ),
       
   160         iCanceled ( EFalse )
       
   161     {
       
   162     // Add this to the scheduler
       
   163     CActiveScheduler::Add( this );
       
   164     }
       
   165 
       
   166 CImpsCSPDestroyer::~CImpsCSPDestroyer()
       
   167     {
       
   168     Cancel();
       
   169     }
       
   170 
       
   171 // -----------------------------------------------------------------------------
       
   172 // CImpsCSPDestroyer::DeleteCSPAsynch
       
   173 // -----------------------------------------------------------------------------
       
   174 void CImpsCSPDestroyer::DeleteCSPAsynch(  )
       
   175     {
       
   176 #ifndef _NO_IMPS_LOGGING_
       
   177     CImpsClientLogger::Log( _L( "CImpsCSPDestroyer: DeleteCSPAsynch" ) );
       
   178 #endif
       
   179     // This yields the control to the server thread active scheduler
       
   180     if ( !IsActive() )
       
   181         {
       
   182         iStatus = KRequestPending;
       
   183         SetActive();
       
   184         iCanceled = EFalse;
       
   185         TRequestStatus* s = &iStatus;
       
   186         User::RequestComplete( s, KErrNone );
       
   187         }
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CImpsCSPDestroyer::DoCancel
       
   192 // -----------------------------------------------------------------------------
       
   193 void CImpsCSPDestroyer::DoCancel()
       
   194     {
       
   195     iCanceled = ETrue;
       
   196     }
       
   197 
       
   198 // -----------------------------------------------------------------------------
       
   199 // CImpsCSPDestroyer::RunL
       
   200 // -----------------------------------------------------------------------------
       
   201 void CImpsCSPDestroyer::RunL()
       
   202     {
       
   203 #ifndef _NO_IMPS_LOGGING_
       
   204     CImpsClientLogger::Log( _L( "CImpsCSPDestroyer: RunL" ) );
       
   205 #endif
       
   206     if ( iCanceled || iStatus.Int() != KErrNone )
       
   207         {
       
   208         return;
       
   209         }
       
   210     // Trigger a server thread to send a queued message
       
   211     iServer.DeleteCSP( &iSess );
       
   212     // It is extremely important that after the previous call this
       
   213     // method does nothing since DeleteCSP actully deletes the
       
   214     // current entity if this class!
       
   215 #ifndef _NO_IMPS_LOGGING_
       
   216     CImpsClientLogger::Log( _L( "CImpsCSPDestroyer: RunL ends" ) );
       
   217 #endif
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CLASS CImpsServer
       
   222 // -----------------------------------------------------------------------------
       
   223 CImpsServer::CImpsServer()
       
   224         : CPolicyServer( EPriorityUserInput /*EPriorityHigh*/, KImpsServerPolicy ),
       
   225         iFs(),
       
   226         iSettings( ),
       
   227         iConAllowed( ETrue ),
       
   228         iCSPVersion( EImpsCspVersion11 ),
       
   229         iOperation( EImpsSrvNone ),
       
   230         iOrphans( NULL ),
       
   231         iCSPList( _FOFF( CImpsConn, iLink ) ), //lint !e413,
       
   232         iObserver( NULL ),
       
   233         iExpiryInterval( 0 )
       
   234     {
       
   235     }
       
   236 
       
   237 // Create and start a new server.
       
   238 
       
   239 CImpsServer* CImpsServer::New()
       
   240     {
       
   241 #ifndef _NO_IMPS_LOGGING_
       
   242     CImpsClientLogger::Log( _L( "Server: rel200614.4+" ) );
       
   243 #endif
       
   244 
       
   245     CImpsServer* server = new CImpsServer();
       
   246     if ( server )
       
   247         {
       
   248         if ( server->Start( KImpsServerName ) != KErrNone )
       
   249             {
       
   250             delete server;
       
   251             server = NULL;
       
   252             }
       
   253         }
       
   254 
       
   255 #ifdef _DEBUG
       
   256     if ( server && server->iFs.Connect() )
       
   257         {
       
   258         delete server;
       
   259         server = NULL;
       
   260         }
       
   261 #endif // _DEBUG               
       
   262 
       
   263     return server;
       
   264     }
       
   265 
       
   266 CImpsServer::~CImpsServer()
       
   267     {
       
   268     // deallocate all memory
       
   269 
       
   270     delete iSnd;
       
   271     delete iShutTimer;
       
   272     delete iExpiryTimer;
       
   273 
       
   274     delete iContainerIndex;
       
   275     delete iVariant;
       
   276     delete iOrphans;
       
   277     delete iObserver;
       
   278 
       
   279 #ifdef _DEBUG
       
   280     // close file session
       
   281     iFs.Close();
       
   282 #endif // _DEBUG      
       
   283     }
       
   284 
       
   285 // -----------------------------------------------------------------------------
       
   286 // CImpsServer::ConstructL()
       
   287 // -----------------------------------------------------------------------------
       
   288 void CImpsServer::ConstructL()
       
   289     {
       
   290 #ifndef _NO_IMPS_LOGGING_
       
   291     CImpsClientLogger::Log( _L( "Server:ConstructL begins" ) );
       
   292 #endif
       
   293 
       
   294     iContainerIndex = CObjectConIx::NewL();
       
   295 
       
   296     // Read static settings, use defaults if ini file not exist
       
   297     iSettings.ReadStaticSettings();
       
   298 #ifdef _DEBUG
       
   299     TInt errx = KErrNone;
       
   300     TRAP( errx, iSettings.ReadIniFileL( iFs ) );
       
   301 #endif
       
   302 
       
   303     iVariant = CImpsVariant::NewLC( );
       
   304     CleanupStack::Pop( ); // >> iVariant
       
   305 
       
   306     iSnd = CImpsFields::NewL();
       
   307     iShutTimer = new ( ELeave ) CImpsShutdownTimer( *this,
       
   308                                                     CActive::EPriorityUserInput + 1 );
       
   309     iExpiryTimer = new ( ELeave ) CImpsExpiryTimer( *this,
       
   310                                                     EImpsEventAll, CActive::EPriorityStandard );
       
   311 
       
   312     // Get the supported WV CSP version for all sessions
       
   313     GetCSPVersion();
       
   314 
       
   315     // local variation
       
   316     //----------------------------
       
   317     if ( iVariant->IsFeatureSupportedL( EImLauncher ) )
       
   318         {
       
   319         iOrphans = CImpsOrphans::NewL();
       
   320         }
       
   321     //----------------------------
       
   322 
       
   323     // Check terminal off line state
       
   324     iObserver = CImpsTOffObserver::NewL( *this );
       
   325     if ( !iObserver->CheckConnAllowed() )
       
   326         {
       
   327         SetConnAllowed( EFalse );
       
   328         }
       
   329 
       
   330 #ifndef _NO_IMPS_LOGGING_
       
   331     CImpsClientLogger::Log( _L( "Server:ConstructL ends" ) );
       
   332 #endif
       
   333 
       
   334     }
       
   335 
       
   336 // -----------------------------------------------------------------------------
       
   337 // CImpsServer::NewSessionL()
       
   338 // -----------------------------------------------------------------------------
       
   339 CSession2* CImpsServer::NewSessionL(
       
   340     const TVersion &aVersion, const RMessage2& aMessage ) const
       
   341     {
       
   342     // check that we're the right version
       
   343     TVersion v( KImpsServMajorVersionNumber,
       
   344                 KImpsServMinorVersionNumber,
       
   345                 KImpsServBuildVersionNumber );
       
   346     if ( !User::QueryVersionSupported( v, aVersion ) )
       
   347         {
       
   348         User::Leave( KErrNotSupported );
       
   349         }
       
   350 
       
   351     if ( iOperation == EImpsSrvShuttingDown )
       
   352         {
       
   353 #ifndef _NO_IMPS_LOGGING_
       
   354         CImpsClientLogger::Log( _L( "Server: NewSessionL in shut down ***" ) );
       
   355 #endif
       
   356         User::Leave( KImpsErrorShuttingDown );
       
   357         }
       
   358 
       
   359     StopTimer();
       
   360 
       
   361 #ifndef _NO_IMPS_LOGGING_
       
   362     CImpsClientLogger::Log( _L( "Server: NewSessionL ends" ) );
       
   363 #endif
       
   364 
       
   365     // make a new session
       
   366     RMessage2 msg = aMessage;
       
   367     return new( ELeave ) CImpsSession( msg );
       
   368     }
       
   369 
       
   370 // -----------------------------------------------------------------------------
       
   371 // CImpsServer::CloseSession()
       
   372 // -----------------------------------------------------------------------------
       
   373 void CImpsServer::CloseSession( TImpsSessIdent aCSP, TBool aComplete )
       
   374     {
       
   375 
       
   376 #ifndef _NO_IMPS_LOGGING_
       
   377     TInt temp1 = NbrSessions( ETrue );
       
   378     TInt temp2 = NbrSessions( EFalse );
       
   379     CImpsClientLogger::Log( _L( "Server: CloseSession nbrses=%d-%d aComplete=%d" ), temp1, temp2, aComplete );
       
   380 #endif
       
   381 
       
   382     // CServer2 calls CImpsSession's desctrutor if its consctrutor fails
       
   383     // but in that case NbrSessions() method does not see the failed entity.
       
   384     // Thus in case of failed session creation the limit is 0, otherwise 1,
       
   385     // i.e. the last client session to be closed starts the shut down timer.
       
   386     TInt limit = aComplete ? 1 : 0;
       
   387     MImpsCSPSession* ses = GetCSP( aCSP, ETrue );
       
   388     if ( !ses )
       
   389         {
       
   390         // If the last client session and no CSP sessions
       
   391         // then start final count down
       
   392         if ( NbrSessions( EFalse ) <= limit )
       
   393             {
       
   394             // There is nobody listening to expiry events
       
   395             iExpiryTimer->Stop( );
       
   396             if ( !NbrCSPs() )
       
   397                 {
       
   398                 // start the final count down
       
   399                 iOperation = EImpsSrvFinish;
       
   400                 iShutTimer->Start( KImpsShutdownTime );
       
   401                 }
       
   402             }
       
   403         return;
       
   404         }
       
   405 
       
   406     // This is very last client session for the CSP connection.
       
   407     // Disconnect CSP session on behalf of applications in this case.
       
   408     TInt myCount = NbrSessions( EFalse, aCSP );
       
   409     if ( myCount == 1 )
       
   410         {
       
   411         TRAPD( errx, ( void )ses->LogoutL( EFalse ) );
       
   412         if ( !errx )
       
   413             {
       
   414             return;
       
   415             }
       
   416         }
       
   417 
       
   418     }
       
   419 
       
   420 // -----------------------------------------------------------------------------
       
   421 // CImpsServer::ThreadStart()
       
   422 // -----------------------------------------------------------------------------
       
   423 EXPORT_C TInt CImpsServer::ThreadStart( TImpsSignal& aSignal )
       
   424     {
       
   425     // naming the server thread after the server helps to debug panics
       
   426     RThread().RenameMe( KImpsServerExe );
       
   427 
       
   428     TInt err = KErrNone;
       
   429 #ifndef _NO_IMPS_LOGGING_
       
   430     CImpsClientLogger::Log( _L( "Server: ThreadStart begins" ) );
       
   431     CImpsClientLogger::Log( _L( "Server: aSignal.iRate = %x" ), aSignal.iRate );
       
   432 #endif
       
   433     __UHEAP_MARK;
       
   434 
       
   435     CTrapCleanup* cleanup = NULL;
       
   436     CImpsScheduler* scheduler = NULL;
       
   437     CImpsServer* server = NULL;
       
   438     cleanup = CTrapCleanup::New();
       
   439 
       
   440 #ifdef _DEBUG
       
   441     TInt rate = aSignal.iRate;
       
   442     if ( rate > 0 )
       
   443         {
       
   444         TRAP( err, __UHEAP_SETFAIL( RHeap::EFailNext, rate ) );
       
   445         }
       
   446 #endif
       
   447 
       
   448     scheduler = new CImpsScheduler;
       
   449 
       
   450     if ( cleanup && scheduler )
       
   451         {
       
   452         CImpsScheduler::Install( scheduler );
       
   453         server = CImpsServer::New();      // adds server in scheduler
       
   454         }
       
   455 
       
   456     if ( !cleanup || !scheduler || !server )
       
   457         {
       
   458         err = KErrNoMemory;
       
   459         }
       
   460     else
       
   461         {
       
   462         TRAP( err, server->ConstructL() );
       
   463         }
       
   464 
       
   465     if ( err )
       
   466         {
       
   467 #ifndef _NO_IMPS_LOGGING_
       
   468         CImpsClientLogger::Log( _L( "Server:ConstructL failed = %d" ), err );
       
   469 #endif
       
   470         delete server;      //lint !e644 initialization ok
       
   471         delete cleanup;     //lint !e644 initialization ok
       
   472         delete scheduler;   //lint !e644 initialization ok
       
   473         }
       
   474 
       
   475     // signal that we've started
       
   476     RProcess::Rendezvous( err );
       
   477 
       
   478     // start fielding requests from clients
       
   479     if ( err == KErrNone )
       
   480         {
       
   481         CImpsScheduler::Start();
       
   482 
       
   483         // comes here when server shuts down
       
   484 
       
   485 #ifndef _NO_IMPS_LOGGING_
       
   486         CImpsClientLogger::Log( _L( "Server: Scheduler is STOPPED" ) );
       
   487 #endif
       
   488         delete server;      //lint !e644 initialization ok
       
   489         delete scheduler;   //lint !e644 initialization ok
       
   490         delete cleanup;     //lint !e644 initialization ok
       
   491         }
       
   492 
       
   493 #ifdef _DEBUG
       
   494     if ( rate > 0 )
       
   495         {
       
   496         TInt err2 = KErrNone;
       
   497         TRAP( err2, __UHEAP_SETFAIL( RHeap::ENone, 0 ) );
       
   498         }
       
   499 #ifndef _NO_IMPS_LOGGING_
       
   500     CImpsClientLogger::Log( _L( "Server: MEM TEST begins" ) );
       
   501 #endif
       
   502     __UHEAP_MARKEND;
       
   503 #ifndef _NO_IMPS_LOGGING_
       
   504     CImpsClientLogger::Log( _L( "Server: MEM TEST OK" ) );
       
   505 #endif
       
   506 #endif
       
   507 
       
   508     return( err );
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CImpsServer::LoginL
       
   513 // -----------------------------------------------------------------------------
       
   514 TPtrC CImpsServer::LoginL(
       
   515     const TDesC& aUser,
       
   516     const TDesC& aPassword,
       
   517     const TDesC& aClientId,
       
   518     const TDesC& aSAP,
       
   519     TUint32 aAP,
       
   520     const TDesC& aKey1,
       
   521     const TDesC& aKey2,
       
   522     CImpsSubSession* /*aSub*/,
       
   523     const TTime aLoginExpiry,
       
   524     TBool aReactive )
       
   525     {
       
   526 #ifndef _NO_IMPS_LOGGING_
       
   527     CImpsClientLogger::Log( _L( "Server: LoginL" ) );
       
   528 #endif
       
   529 
       
   530     if ( iOperation == EImpsSrvShuttingDown )
       
   531         {
       
   532         User::Leave( KImpsErrorShuttingDown );
       
   533         }
       
   534 
       
   535     // multi: check if CSP already exists, otherwise create a new CSP session
       
   536     TImpsSessIdent csp( KNullDesC, aSAP, aUser );
       
   537     MImpsCSPSession* ses = GetCSP( csp, EFalse );
       
   538     // multi: Check if another client is logging with this CSP session
       
   539     if ( ses && ses->IsLogging() )
       
   540         {
       
   541 #ifndef _NO_IMPS_LOGGING_
       
   542         CImpsClientLogger::Log( _L( "Server: CSP is logging ****" ) );
       
   543 #endif
       
   544         }
       
   545     else if ( !ses  )
       
   546         {
       
   547         ses = NewCSPL( csp, iCSPVersion );
       
   548         }
       
   549 
       
   550     // Before starting actual transport data transfer we start expiry timer
       
   551     SetExpiryTimer( 0, ETrue );
       
   552 
       
   553     // This leaves if already logged or if performing logging currently
       
   554     // Certain error types means that CSP sessions is already doing something,
       
   555     // rest of the error codes means that initialization has been failed and
       
   556     // thus the entity has to deleted
       
   557     TPtrC p( KNullDesC );
       
   558     TRAPD( errx, p.Set( ses->LoginL( aUser, aPassword, aClientId, aSAP, aAP,
       
   559                                      aKey1, aKey2, aLoginExpiry, aReactive ) ) );
       
   560     if ( errx )
       
   561         {
       
   562         // These are means that CSP entity is running and in use, don't delete it yet.
       
   563         if ( errx != KErrNotReady && errx != KImpsErrorAlreadyLogged )
       
   564             {
       
   565             DeleteCSPAsynch( ses );
       
   566             }
       
   567         User::Leave( errx );
       
   568         }
       
   569     return p;
       
   570     }
       
   571 
       
   572 // -----------------------------------------------------------------------------
       
   573 // CImpsServer::LogoutL
       
   574 // -----------------------------------------------------------------------------
       
   575 TPtrC CImpsServer::LogoutL(
       
   576     TBool aCancel,
       
   577     TImpsSessIdent aCSP )
       
   578     {
       
   579 #ifndef _NO_IMPS_LOGGING_
       
   580     CImpsClientLogger::Log( _L( "Server: LogoutL" ) );
       
   581 #endif
       
   582 
       
   583     // Just leave if other client sessions use still this CSP session
       
   584     // or if server is shutting down.
       
   585     // KImpsErrorTerminalOffLine is handled in a special way in a client session class.
       
   586     // That's because of Logout should not fail if sessions existed.
       
   587     //
       
   588     if ( NbrSessions( ETrue, aCSP ) > 1 ||
       
   589          iOperation == EImpsSrvShuttingDown )
       
   590         {
       
   591 #ifndef _NO_IMPS_LOGGING_
       
   592         CImpsClientLogger::Log( _L( "Server: LogoutL LEAVES 1 KImpsErrorTerminalOffLine  ***" ) );
       
   593 #endif
       
   594         User::Leave( KImpsErrorTerminalOffLine );
       
   595         }
       
   596 
       
   597     // Leave also if there is no CSP session or CSP session state is improper
       
   598     MImpsCSPSession* ses = GetCSP( aCSP, EFalse );
       
   599     if ( !ses || ( !IsLogged( aCSP, NULL ) && !IsPendingLogin( aCSP ) ) )
       
   600         {
       
   601         // The following is not needed:
       
   602         //   Send error messages for existing requests
       
   603         //   DiscardRequests( EImpsEventAll, KImpsErrorNotLogged, aCSP );
       
   604         // This error code is handled in a special way in a sub-session.
       
   605 #ifndef _NO_IMPS_LOGGING_
       
   606         CImpsClientLogger::Log( _L( "Server: LogoutL LEAVES 2 KImpsErrorTerminalOffLine  ***" ) );
       
   607 #endif
       
   608         User::Leave( KImpsErrorTerminalOffLine );
       
   609         }
       
   610 
       
   611     // Be 100% sure that expiry timer is running
       
   612     if ( !iExpiryTimer->IsActive() )
       
   613         {
       
   614         TInt expiryInterval = iSettings.iAccessExp;
       
   615         iExpiryTimer->Start( expiryInterval / 2 );
       
   616         }
       
   617 
       
   618     return ses->LogoutL( aCancel );
       
   619     }
       
   620 
       
   621 // -----------------------------------------------------------------------------
       
   622 // CImpsServer::CirMessageL
       
   623 // -----------------------------------------------------------------------------
       
   624 void CImpsServer::CirMessageL(
       
   625     const TDesC8& aCookie )
       
   626     {
       
   627 #ifndef _NO_IMPS_LOGGING_
       
   628     CImpsClientLogger::Log( _L( "Server: CirMessageL" ) );
       
   629 #endif
       
   630 
       
   631     // Call Session
       
   632 
       
   633     // multi: scan all sessions until session cookie matches
       
   634     TDblQueIter<CImpsConn> rIter( iCSPList );
       
   635     rIter.SetToFirst();
       
   636     while ( rIter )
       
   637         {
       
   638         CImpsConn* conn = rIter;
       
   639         rIter++;
       
   640         TRAPD( errx, conn->Sess()->CirMessageL( aCookie ) );
       
   641         if ( !errx )
       
   642             {
       
   643             // If no error then the CSP session was a right one
       
   644             break;
       
   645             }
       
   646         }
       
   647     }
       
   648 
       
   649 // -----------------------------------------------------------------------------
       
   650 // CImpsServer::SendDataL
       
   651 // aSession MUST NOT be NULL
       
   652 // -----------------------------------------------------------------------------
       
   653 TPtrC CImpsServer::SendDataL(
       
   654     CImpsSubSession* aSession, TImpsSessIdent aCSP )
       
   655     {
       
   656 
       
   657 #ifndef _NO_IMPS_LOGGING_
       
   658     CImpsClientLogger::Log( _L( "Server: SendDataL begins" ) );
       
   659 #endif
       
   660 
       
   661     // multi:
       
   662     MImpsCSPSession* ses = GetCSP( aCSP, EFalse );
       
   663     if ( !ses )
       
   664         {
       
   665         User::Leave( KImpsErrorNotLogged );
       
   666         }
       
   667 
       
   668     TInt expiryTime = aSession->ExpiryTime();
       
   669 
       
   670     // iSnd is for own creations, but this is created in a session
       
   671     CImpsFields* fields = NULL;
       
   672     fields = aSession->ImpsFields();
       
   673 
       
   674     __ASSERT_DEBUG( fields, User::Panic( KImpsPanicCategory, EImpsCorrupted ) );
       
   675 
       
   676     TBool ownerCh( EFalse );
       
   677     TPtrC ptr = ses->SendDataL( fields, expiryTime, ownerCh );
       
   678     if ( ownerCh )
       
   679         {
       
   680         // Transport adapter is busy so the request is queued and
       
   681         // data owner is changed
       
   682         aSession->NewFieldsL();
       
   683         }
       
   684     return ptr;
       
   685     }
       
   686 
       
   687 // -----------------------------------------------------------------------------
       
   688 // CImpsServer::StopTimer
       
   689 // -----------------------------------------------------------------------------
       
   690 void CImpsServer::StopTimer() const
       
   691     {
       
   692     iShutTimer->Stop();
       
   693     }
       
   694 
       
   695 // -----------------------------------------------------------------------------
       
   696 // CImpsServer::CheckRequestsL
       
   697 // -----------------------------------------------------------------------------
       
   698 void CImpsServer::CheckRequestsL(
       
   699     CImpsFields* aFields,
       
   700     TBool& aFound,
       
   701     TImpsSessIdent aCSP )
       
   702     {
       
   703 
       
   704 #ifndef _NO_IMPS_LOGGING_
       
   705     CImpsClientLogger::Log( _L( "Server: CheckRequests begins " ) );
       
   706 #endif
       
   707 
       
   708     aFound = EFalse;
       
   709 
       
   710     // Block some message types for push message, not MO CSP transactions,
       
   711     // to speed up performance
       
   712     // Notice: update list as needed
       
   713     TInt messageType = aFields->MessageType();
       
   714     if ( messageType == EImpsNewMessage ||
       
   715          messageType == EImpsDeliveryReportReq ||
       
   716          // This may be requested or SAP initiated
       
   717          // so, don't do that :messageType == EImpsLeaveGroupRes ||
       
   718          messageType == EImpsInviteUserReq ||
       
   719          messageType == EImpsInviteRes ||
       
   720          messageType == EImpsCancelInviteUserReq ||
       
   721          messageType == EImpsPresenceNotification ||
       
   722          messageType == EImpsGroupChangeNotice )
       
   723         {
       
   724 #ifndef _NO_IMPS_LOGGING_
       
   725         CImpsClientLogger::Log( _L( "Server: CheckRequests cancelled" ) );
       
   726 #endif
       
   727         return;
       
   728         }
       
   729 
       
   730     // Go through all sessions (each having an own request list)
       
   731 
       
   732     iSessionIter.SetToFirst();
       
   733     TInt myOpId = 0;
       
   734     TImpsServRequest reqType = EImpsServNone;
       
   735     TImpsMessageType msgType = EImpsMessageNone;
       
   736 
       
   737     TUint subHandle = 0;
       
   738 
       
   739     // Check TID match
       
   740     while ( iSessionIter )
       
   741         {
       
   742         CSession2* session = iSessionIter;
       
   743         iSessionIter++;
       
   744         // return handle of matching subsession and give it as parameter
       
   745         subHandle = ( ( CImpsSession* )session )->CheckRequests( aFields->TidL(),
       
   746                                                                  myOpId, reqType, msgType, aCSP );
       
   747         if ( subHandle )
       
   748             {
       
   749             // Do not delete request until corresponding event is sent.
       
   750             // If event sending fails then expiration will take place later.
       
   751             ( ( CImpsSession* )session )->SendEvent(
       
   752                 aFields, myOpId, reqType, msgType, subHandle );
       
   753 
       
   754             ( ( CImpsSession* )session )->DeleteRequest( myOpId, subHandle );
       
   755             aFound = ETrue;
       
   756             // multi: do not stop searching because of there may be
       
   757             // multiple login requests with the same TID.
       
   758             // break;
       
   759             }
       
   760         }
       
   761     }
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // CImpsServer::CheckNotifications
       
   765 // -----------------------------------------------------------------------------
       
   766 TBool CImpsServer::CheckNotifications(
       
   767     CImpsFields* aFields,
       
   768     TImpsSessIdent aCSP )
       
   769     {
       
   770 
       
   771 #ifndef _NO_IMPS_LOGGING_
       
   772     CImpsClientLogger::Log( _L( "Server: CheckNotifications begins" ) );
       
   773 #endif
       
   774 
       
   775     // Check if IM message max size is exceeded
       
   776     if ( aFields->MessageType() == EImpsNewMessage &&
       
   777          aFields->Size() > iSettings.MaximumMessageSize() )
       
   778         {
       
   779 #ifndef _NO_IMPS_LOGGING_
       
   780         CImpsClientLogger::Log( _L( "Server: error: IM Message max size exceeded ***" ) );
       
   781 #endif
       
   782         // This is not saved in an orphan queue either
       
   783         return ETrue;
       
   784         }
       
   785 
       
   786     TBool retVal( EFalse );
       
   787     // Go through all sessions
       
   788     iSessionIter.SetToFirst();
       
   789     // Check notification events
       
   790     while ( iSessionIter )
       
   791         {
       
   792         CSession2* session = iSessionIter;
       
   793         iSessionIter++;
       
   794         if ( ( ( CImpsSession* )session )->CheckNotifications( aFields, aCSP ) )
       
   795             {
       
   796             retVal = ETrue;
       
   797             }
       
   798         }
       
   799     return retVal;
       
   800     }
       
   801 
       
   802 // -----------------------------------------------------------------------------
       
   803 // CImpsServer::CheckExpiryL
       
   804 // -----------------------------------------------------------------------------
       
   805 void CImpsServer::CheckExpiryL(
       
   806     TImpsEventType aType, TTime aExpiry  )
       
   807     {
       
   808     if ( iOrphans )
       
   809         {
       
   810         TInt errx = KErrNone;
       
   811         TRAP( errx, iOrphans->CheckExpiryL() );
       
   812         }
       
   813     // multi: check all csp sessions
       
   814     TDblQueIter<CImpsConn> rIter( iCSPList );
       
   815     rIter.SetToFirst();
       
   816     while ( rIter )
       
   817         {
       
   818         CImpsConn* conn = rIter;
       
   819         rIter++;
       
   820         conn->Sess()->CheckExpiry(  aType, aExpiry );
       
   821         }
       
   822     }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CImpsServer::CheckExpiryL
       
   826 // -----------------------------------------------------------------------------
       
   827 void CImpsServer::CheckExpiryL(
       
   828     TImpsEventType aType  )
       
   829     {
       
   830 #ifndef _NO_IMPS_LOGGING_
       
   831     CImpsClientLogger::Log( _L( "Server: CheckExpiryL begins" ) );
       
   832 #endif
       
   833     TTime myExpiry;
       
   834     myExpiry.HomeTime();
       
   835     CheckExpiryL( aType, myExpiry );
       
   836     }
       
   837 
       
   838 // -----------------------------------------------------------------------------
       
   839 // CImpsServer::DiscardRequests
       
   840 // -----------------------------------------------------------------------------
       
   841 void CImpsServer::DiscardRequests( TImpsEventType aType, TTime aExpiry,
       
   842                                    TImpsSessIdent aCSP, MImpsCSPSession* aSess )
       
   843     {
       
   844     iSessionIter.SetToFirst();
       
   845     while ( iSessionIter )
       
   846         {
       
   847         CSession2* session = iSessionIter;
       
   848         iSessionIter++;
       
   849         ( ( CImpsSession* )session )->DiscardRequests(
       
   850             aExpiry,
       
   851             aType,
       
   852             aCSP, aSess );
       
   853         }
       
   854     }
       
   855 
       
   856 // -----------------------------------------------------------------------------
       
   857 // CImpsServer::DiscardRequests
       
   858 // -----------------------------------------------------------------------------
       
   859 void CImpsServer::DiscardRequests( TImpsEventType aType, TInt aError,
       
   860                                    TImpsSessIdent aCSP, MImpsCSPSession* aSess )
       
   861     {
       
   862     iSessionIter.SetToFirst();
       
   863     while ( iSessionIter )
       
   864         {
       
   865         CSession2* session = iSessionIter;
       
   866         iSessionIter++;
       
   867         ( ( CImpsSession* )session )->DiscardRequests(
       
   868             aError,
       
   869             aType,
       
   870             aCSP,
       
   871             aSess );
       
   872         }
       
   873     }
       
   874 
       
   875 // -----------------------------------------------------------------------------
       
   876 // CImpsServer::DiscardLogout
       
   877 // -----------------------------------------------------------------------------
       
   878 void CImpsServer::DiscardLogout(
       
   879     const TDesC& aTID,
       
   880     TImpsSessIdent aCSP )
       
   881     {
       
   882 #ifndef _NO_IMPS_LOGGING_
       
   883     CImpsClientLogger::Log( _L( "Server: DiscardLogoutL begins" ) );
       
   884 #endif
       
   885     TUint subHandle = 0;
       
   886     // This is a special case to handle logout error
       
   887     // Check TID match
       
   888     iSessionIter.SetToFirst();
       
   889     while ( iSessionIter )
       
   890         {
       
   891         CSession2* session = iSessionIter;
       
   892         iSessionIter++;
       
   893         TInt myHit = 0;     // opId
       
   894         // output params
       
   895         TImpsServRequest reqType = EImpsServNone;
       
   896         TImpsMessageType msgType = EImpsMessageNone;
       
   897 
       
   898         // return handle of matching subsession and give it as parameter
       
   899         subHandle = ( ( CImpsSession* )session )->CheckRequests( aTID,
       
   900                                                                  myHit, reqType, msgType, aCSP );
       
   901         // call SendLogoutevent
       
   902         if ( subHandle )
       
   903             {
       
   904             // Send event to client
       
   905             ( ( CImpsSession* )session )->SendLogoutEvent(
       
   906                 KErrNone, myHit, NULL, subHandle );
       
   907 
       
   908             // Delete client request after successful event sending
       
   909             ( ( CImpsSession* )session )->DeleteRequest( myHit, subHandle );
       
   910             break;
       
   911             }
       
   912         }
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CImpsServer::HandleOrphanL
       
   917 // -----------------------------------------------------------------------------
       
   918 void CImpsServer::HandleOrphanL( CImpsFields* aFields, TImpsSessIdent aCSP )
       
   919     {
       
   920 #ifndef _NO_IMPS_LOGGING_
       
   921     CImpsClientLogger::Log( _L( "Server: HandleOrphanL" ) );
       
   922 #endif
       
   923     if ( iOrphans )
       
   924         {
       
   925         // CSP identification
       
   926         iOrphans->NewOrphanL( aFields, aCSP );
       
   927         }
       
   928     else
       
   929         {
       
   930         User::Leave( KErrNotSupported );
       
   931         }
       
   932     }
       
   933 
       
   934 // -----------------------------------------------------------------------------
       
   935 // CImpsServer::NextOrphanLC
       
   936 // -----------------------------------------------------------------------------
       
   937 CImpsFields* CImpsServer::NextOrphanLC( const TDesC& aCID,
       
   938                                         TImpsEventType aServiceType,
       
   939                                         TImpsSessIdent aCSP )
       
   940     {
       
   941 #ifndef _NO_IMPS_LOGGING_
       
   942     CImpsClientLogger::Log( _L( "Server: NextOrphanL" ) );
       
   943 #endif
       
   944     if ( !iOrphans )
       
   945         {
       
   946         return NULL;
       
   947         }
       
   948     // CSP session and application id identification
       
   949     return iOrphans->NextOrphanLC( aCID, aServiceType, aCSP );
       
   950     }
       
   951 
       
   952 // -----------------------------------------------------------------------------
       
   953 // CImpsServer::HandleAllOrphans
       
   954 // -----------------------------------------------------------------------------
       
   955 void CImpsServer::HandleAllOrphans( )
       
   956     {
       
   957 #ifndef _NO_IMPS_LOGGING_
       
   958     CImpsClientLogger::Log( _L( "Server: HandleAllOrphans" ) );
       
   959 #endif
       
   960     if ( !iOrphans )
       
   961         {
       
   962         return;
       
   963         }
       
   964     // loop each session
       
   965     iSessionIter.SetToFirst();
       
   966     while ( iSessionIter )
       
   967         {
       
   968         CSession2* session = iSessionIter;
       
   969         iSessionIter++;
       
   970         ( ( CImpsSession* )session )->HandleAllOrphans();
       
   971         }
       
   972     }
       
   973 
       
   974 // -----------------------------------------------------------------------------
       
   975 // CImpsServer::IsLogged
       
   976 // -----------------------------------------------------------------------------
       
   977 TBool CImpsServer::IsLogged( TImpsSessIdent aCSP, TPtrC* aPsw )
       
   978     {
       
   979     MImpsCSPSession* csp = GetCSP( aCSP, EFalse );
       
   980     TBool ret =  ( csp ? csp->IsLogged() : EFalse );
       
   981     if ( ret && aPsw )
       
   982         {
       
   983         aPsw->Set( csp->Password() );
       
   984         }
       
   985     return ret;
       
   986     }
       
   987 
       
   988 // -----------------------------------------------------------------------------
       
   989 // CImpsServer::SID()
       
   990 // -----------------------------------------------------------------------------
       
   991 TPtrC CImpsServer::SID( TImpsSessIdent aCSP )
       
   992     {
       
   993     if ( aCSP.IsZero() )
       
   994         {
       
   995         return TPtrC();
       
   996         }
       
   997     else
       
   998         {
       
   999         MImpsCSPSession* csp = GetCSP( aCSP, EFalse );
       
  1000         return ( csp ? csp->SID() : TPtrC() );
       
  1001         }
       
  1002     }
       
  1003 
       
  1004 // -----------------------------------------------------------------------------
       
  1005 // CImpsServer::GetCSP
       
  1006 // -----------------------------------------------------------------------------
       
  1007 MImpsCSPSession* CImpsServer::GetCSP( TImpsSessIdent aCSP, TBool aAll )
       
  1008     {
       
  1009     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1010     rIter.SetToFirst();
       
  1011     while ( rIter )
       
  1012         {
       
  1013         CImpsConn* conn = rIter;
       
  1014         rIter++;
       
  1015         if ( conn->MatchCSP( aCSP ) )
       
  1016             {
       
  1017             if ( ( !aAll && !conn->Sess()->IsShuttingDown() ) ||
       
  1018                  ( aAll ) )
       
  1019                 {
       
  1020                 return conn->Sess();
       
  1021                 }
       
  1022             }
       
  1023         }
       
  1024     return NULL;
       
  1025     }
       
  1026 
       
  1027 // -----------------------------------------------------------------------------
       
  1028 // CImpsServer::NewCSPL
       
  1029 // -----------------------------------------------------------------------------
       
  1030 MImpsCSPSession* CImpsServer::NewCSPL( TImpsSessIdent /*aCSP*/, TImpsCspVersion aVer )
       
  1031     {
       
  1032 #ifndef _NO_IMPS_LOGGING_
       
  1033     CImpsClientLogger::Log( _L( "Server: NewCSPL" ) );
       
  1034 #endif
       
  1035     CImpsCSPSession* ses = CImpsCSPSession::NewL( *this,
       
  1036                                                   iSettings, iFs, *iVariant, aVer );
       
  1037     CleanupStack::PushL( ses );
       
  1038     CImpsConn* conn = CImpsConn::NewL( ses, *this );
       
  1039     iCSPList.AddLast( *conn );
       
  1040     CleanupStack::Pop( 1 );
       
  1041     return ses;
       
  1042     }
       
  1043 
       
  1044 // -----------------------------------------------------------------------------
       
  1045 // CImpsServer::DeleteCSP
       
  1046 // -----------------------------------------------------------------------------
       
  1047 void CImpsServer::DeleteCSP( MImpsCSPSession* aSess )
       
  1048     {
       
  1049 #ifndef _NO_IMPS_LOGGING_
       
  1050     CImpsClientLogger::Log( _L( "Server: DeleteCSP" ) );
       
  1051 #endif
       
  1052     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1053     rIter.SetToFirst();
       
  1054     while ( rIter )
       
  1055         {
       
  1056         CImpsConn* conn = rIter;
       
  1057         rIter++;
       
  1058         if ( conn->Sess() == aSess )
       
  1059             {
       
  1060             conn->Destroy();
       
  1061             break;
       
  1062             }
       
  1063         }
       
  1064     // Check also if all the client sessions are closed and if this is the
       
  1065     // last CSP session. Then start final count down.
       
  1066     if ( !NbrSessions( EFalse ) && !NbrCSPs() )
       
  1067         {
       
  1068         iOperation = EImpsSrvFinish;
       
  1069         iShutTimer->Start( KImpsShutdownTime );
       
  1070         }
       
  1071     }
       
  1072 
       
  1073 // -----------------------------------------------------------------------------
       
  1074 // CImpsServer::DeleteCSPAsynch
       
  1075 // -----------------------------------------------------------------------------
       
  1076 void CImpsServer::DeleteCSPAsynch( MImpsCSPSession* aSess )
       
  1077     {
       
  1078 #ifndef _NO_IMPS_LOGGING_
       
  1079     CImpsClientLogger::Log( _L( "Server: DeleteCSPAsynch" ) );
       
  1080 #endif
       
  1081     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1082     rIter.SetToFirst();
       
  1083     while ( rIter )
       
  1084         {
       
  1085         CImpsConn* conn = rIter;
       
  1086         rIter++;
       
  1087         if ( conn->Sess() == aSess )
       
  1088             {
       
  1089             conn->DeleteCSPAsynch();
       
  1090             return;
       
  1091             }
       
  1092         }
       
  1093     }
       
  1094 
       
  1095 // -----------------------------------------------------------------------------
       
  1096 // CImpsServer::CloseAllCSPs
       
  1097 // -----------------------------------------------------------------------------
       
  1098 void CImpsServer::CloseAllCSPs()
       
  1099     {
       
  1100 #ifndef _NO_IMPS_LOGGING_
       
  1101     CImpsClientLogger::Log( _L( "Server: CloseAllCSPs" ) );
       
  1102 #endif
       
  1103     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1104     rIter.SetToFirst();
       
  1105     while ( rIter )
       
  1106         {
       
  1107         CImpsConn* conn = rIter;
       
  1108         rIter++;
       
  1109         conn->Sess()->DoLogout();
       
  1110         }
       
  1111     }
       
  1112 
       
  1113 // -----------------------------------------------------------------------------
       
  1114 // CImpsServer::NbrCSPs
       
  1115 // -----------------------------------------------------------------------------
       
  1116 TInt CImpsServer::NbrCSPs( )
       
  1117     {
       
  1118     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1119     rIter.SetToFirst();
       
  1120     TInt count = 0;
       
  1121     while ( rIter )
       
  1122         {
       
  1123         rIter++;
       
  1124         count++;
       
  1125         }
       
  1126     return count;
       
  1127     }
       
  1128 
       
  1129 // -----------------------------------------------------------------------------
       
  1130 // CImpsServer::NbrSessions
       
  1131 // -----------------------------------------------------------------------------
       
  1132 TInt CImpsServer::NbrSessions( TBool aIgnoreCIR )
       
  1133     {
       
  1134     iSessionIter.SetToFirst();
       
  1135     TInt myRet = 0;
       
  1136 
       
  1137     // Check TID match
       
  1138     while ( iSessionIter )
       
  1139         {
       
  1140         if ( aIgnoreCIR )
       
  1141             {
       
  1142             CSession2* session = iSessionIter;
       
  1143             iSessionIter++;
       
  1144             if ( !( ( CImpsSession* )session )->IsCIRWatcherSession() )
       
  1145                 {
       
  1146                 myRet++;
       
  1147                 }
       
  1148             }
       
  1149         else
       
  1150             {
       
  1151             iSessionIter++;
       
  1152             myRet++;
       
  1153             }
       
  1154         }
       
  1155     return myRet;
       
  1156 
       
  1157     }
       
  1158 
       
  1159 // -----------------------------------------------------------------------------
       
  1160 // CImpsServer::NbrSessions
       
  1161 // -----------------------------------------------------------------------------
       
  1162 TInt CImpsServer::NbrSessions( TBool aIgnoreCIR, TImpsSessIdent aCSP )
       
  1163     {
       
  1164     iSessionIter.SetToFirst();
       
  1165     TInt myRet = 0;
       
  1166 
       
  1167     // Check TID match
       
  1168     while ( iSessionIter )
       
  1169         {
       
  1170         CSession2* session = iSessionIter;
       
  1171         iSessionIter++;
       
  1172         if ( aIgnoreCIR )
       
  1173             {
       
  1174             if ( ( ( CImpsSession* )session )->MatchSession( aCSP ) &&
       
  1175                  !( ( CImpsSession* )session )->IsCIRWatcherSession() )
       
  1176                 {
       
  1177                 myRet++;
       
  1178                 }
       
  1179             }
       
  1180         else if ( ( ( CImpsSession* )session )->MatchSession( aCSP ) )
       
  1181             {
       
  1182             myRet++;
       
  1183             }
       
  1184         }
       
  1185     return myRet;
       
  1186 
       
  1187     }
       
  1188 
       
  1189 // -----------------------------------------------------------------------------
       
  1190 // CImpsServer::CancelTrans
       
  1191 // -----------------------------------------------------------------------------
       
  1192 void CImpsServer::CancelTrans( const TDesC& aTID, TImpsSessIdent aCSP )
       
  1193     {
       
  1194     MImpsCSPSession* sess = GetCSP( aCSP, EFalse );
       
  1195     CancelTrans( aTID, sess );
       
  1196     }
       
  1197 
       
  1198 // -----------------------------------------------------------------------------
       
  1199 // CImpsServer::CancelTrans
       
  1200 // -----------------------------------------------------------------------------
       
  1201 void CImpsServer::CancelTrans( const TDesC& aTID, MImpsCSPSession* aSess )
       
  1202     {
       
  1203     if ( aSess )
       
  1204         {
       
  1205         aSess->CancelTrans( aTID );
       
  1206         }
       
  1207     }
       
  1208 
       
  1209 // -----------------------------------------------------------------------------
       
  1210 // CImpsServer::DoLogoutSrv
       
  1211 // -----------------------------------------------------------------------------
       
  1212 void CImpsServer::DoLogoutSrv( TInt aInt, TBool aCSPDis,
       
  1213                                MImpsCSPSession* aSess )
       
  1214     {
       
  1215     // aSess is never NULL
       
  1216     TImpsSessIdent csp( KNullDesC, aSess->SAP(), aSess->UserId() );
       
  1217     DoLogoutNow( NULL, aInt, aCSPDis, csp );
       
  1218     }
       
  1219 
       
  1220 // -----------------------------------------------------------------------------
       
  1221 // CImpsServer::DoLogoutNow
       
  1222 // -----------------------------------------------------------------------------
       
  1223 void CImpsServer::DoLogoutNow( CImpsSubSession* aSub,
       
  1224                                TInt aOpId, TBool aCSPDis,
       
  1225                                TImpsSessIdent aCSP )
       
  1226     {
       
  1227 
       
  1228 #ifndef _NO_IMPS_LOGGING_
       
  1229     CImpsClientLogger::Log( _L( "Server: DoLogoutNow subses=%d opid=%d dis=%d" ),
       
  1230                             aSub, aOpId, aCSPDis );
       
  1231 #endif
       
  1232 
       
  1233     iExpiryTimer->Stop();
       
  1234 
       
  1235     // Clean all pending requests from all sessions
       
  1236     // Logout response must have beed delivered
       
  1237     iSessionIter.SetToFirst();
       
  1238     // Delete requests from the corresponding client sessions only.
       
  1239     while ( iSessionIter )
       
  1240         {
       
  1241         CSession2* session = iSessionIter;
       
  1242         iSessionIter++;
       
  1243         ( ( CImpsSession* )session )->DeleteAllRequests( &aCSP );
       
  1244         }
       
  1245 
       
  1246     // Call logout callback methods only if CSP did exist.
       
  1247     if ( aCSPDis )
       
  1248         {
       
  1249         // send the appropriate opid to the requesting client
       
  1250         SendLogoutEvents( aSub, aOpId, aCSP );
       
  1251         }
       
  1252 
       
  1253     // Send not_logged state events. This also cleans WV CSP SID in client sessions
       
  1254     // belonging to the CSP session.
       
  1255     SendStatusEvents( EInternal_NOT_LOGGED, aCSP );
       
  1256 
       
  1257     // If no sessions then start countdown
       
  1258     if ( !NbrSessions( EFalse ) && !NbrCSPs() )
       
  1259         {
       
  1260         iOperation = EImpsSrvFinish;
       
  1261         iShutTimer->Start( KImpsShutdownTime );
       
  1262         }
       
  1263     }
       
  1264 
       
  1265 // -----------------------------------------------------------------------------
       
  1266 // CImpsServer::IsPendingLogin
       
  1267 // -----------------------------------------------------------------------------
       
  1268 TBool CImpsServer::IsPendingLogin( TImpsSessIdent aCSP )
       
  1269     {
       
  1270     MImpsCSPSession* csp = GetCSP( aCSP, EFalse );
       
  1271     return ( csp ? csp->IsPendingLogin() : EFalse );
       
  1272     }
       
  1273 
       
  1274 // -----------------------------------------------------------------------------
       
  1275 // CImpsServer::ExpiryTime
       
  1276 // Generate default expiry time
       
  1277 // -----------------------------------------------------------------------------
       
  1278 TTime CImpsServer::ExpiryTime( TImpsMessageType aMsgType )
       
  1279     {
       
  1280     TImpsEventType srv = impsService( iVariant, aMsgType );
       
  1281     return ExpiryTime( srv );
       
  1282     }
       
  1283 
       
  1284 // -----------------------------------------------------------------------------
       
  1285 // CImpsServer::ExpiryTime
       
  1286 // Generate default expiry time
       
  1287 // -----------------------------------------------------------------------------
       
  1288 TTime CImpsServer::ExpiryTime( TImpsEventType aSrv )
       
  1289     {
       
  1290     TInt extra = ExpirySeconds( aSrv );
       
  1291     return ExpiryTime( extra );
       
  1292     }
       
  1293 
       
  1294 // ---------------------------------------------------------
       
  1295 // CImpsServer::ExpiryTime
       
  1296 // ---------------------------------------------------------
       
  1297 TTime CImpsServer::ExpiryTime( TInt aExpiry )
       
  1298     {
       
  1299     TTime time;        // time in microseconds since 0AD nominal Gregorian
       
  1300     time.HomeTime();   // set time to now
       
  1301     // add expiry seconds to the time
       
  1302     TTimeIntervalSeconds expirySeconds( aExpiry );
       
  1303     time += expirySeconds;
       
  1304     return time;
       
  1305     }
       
  1306 
       
  1307 // -----------------------------------------------------------------------------
       
  1308 // CImpsServer::ExpirySeconds
       
  1309 // Generate default expiry time
       
  1310 // -----------------------------------------------------------------------------
       
  1311 TInt CImpsServer::ExpirySeconds( TImpsEventType aSrv )
       
  1312     {
       
  1313     TInt extra = 0;
       
  1314 
       
  1315     switch ( aSrv )
       
  1316         {
       
  1317         case EImpsEventServerLogin:
       
  1318         case EImpsEventNone:        // used for PollRequest e.g.
       
  1319             extra = iSettings.iAccessExp;
       
  1320             break;
       
  1321         case EImpsEventMessage:
       
  1322             extra = iSettings.iImExp;
       
  1323             break;
       
  1324         case EImpsEventPresence:
       
  1325         case EImpsEventPresencePure:
       
  1326         case EImpsEventPure:
       
  1327             extra = iSettings.iPrExp;
       
  1328             break;
       
  1329         case EImpsEventGroup:
       
  1330             extra = iSettings.iGrExp;
       
  1331             break;
       
  1332         case EImpsEventCommon:
       
  1333             extra = iSettings.iFuExp;
       
  1334             break;
       
  1335         default:
       
  1336             break;
       
  1337         }
       
  1338 
       
  1339     return extra;
       
  1340     }
       
  1341 
       
  1342 // -----------------------------------------------------------------------------
       
  1343 // CImpsServer::SendStatusEvents
       
  1344 // -----------------------------------------------------------------------------
       
  1345 void CImpsServer::SendStatusEvents( EImpsInternalStatus aStatus,
       
  1346                                     TImpsSessIdent aCSP )
       
  1347     {
       
  1348 #ifndef _NO_IMPS_LOGGING_
       
  1349     CImpsClientLogger::Log( _L( "Server: SendStatusEvents begins" ) );
       
  1350 #endif
       
  1351 
       
  1352     iSessionIter.SetToFirst();
       
  1353 
       
  1354     // Scan thru sessions and send event if they have registered an
       
  1355     // status observer
       
  1356     while ( iSessionIter )
       
  1357         {
       
  1358         CSession2* session = iSessionIter;
       
  1359         iSessionIter++;
       
  1360         if ( ( ( CImpsSession* )session )->MatchSession( aCSP ) )
       
  1361             {
       
  1362             ( ( CImpsSession* )session )->SendEvent( aStatus );
       
  1363             }
       
  1364         }
       
  1365     }
       
  1366 
       
  1367 // ---------------------------------------------------------
       
  1368 // CImpsServer::TransportStatus
       
  1369 // ---------------------------------------------------------
       
  1370 //
       
  1371 void CImpsServer::TransportStatus(
       
  1372     EImpsInternalStatus aConnectionState,
       
  1373     MImpsCSPSession* aSess )
       
  1374     {
       
  1375 
       
  1376 #ifndef _NO_IMPS_LOGGING_
       
  1377     CImpsClientLogger::Log( _L( "Server: TransportStatus=%d" ),
       
  1378                             ( TInt ) aConnectionState );
       
  1379 #endif
       
  1380 
       
  1381     TInt errx = KErrNone;
       
  1382     TRAP( errx, DoTransportStatusL( aConnectionState, aSess ) );
       
  1383 
       
  1384 #ifndef _NO_IMPS_LOGGING_
       
  1385     CImpsClientLogger::Log( _L( "Server: TransportStatus ends" ) );
       
  1386 #endif
       
  1387 
       
  1388     }
       
  1389 
       
  1390 // ---------------------------------------------------------
       
  1391 // CImpsServer::DoTransportStatusL
       
  1392 // ---------------------------------------------------------
       
  1393 //
       
  1394 void CImpsServer::DoTransportStatusL(
       
  1395     EImpsInternalStatus aConnectionState,
       
  1396     MImpsCSPSession* aSess )
       
  1397     {
       
  1398     TImpsSessIdent csp( KNullDesC, aSess->SAP(), aSess->UserId() );
       
  1399     TInt nbrSes = NbrSessions( ETrue, csp );
       
  1400 
       
  1401     // Logout particular CSP session if there is no corresponding client-sessions.
       
  1402     if ( aConnectionState != EInternal_NO_IAP && !nbrSes )
       
  1403         {
       
  1404         aSess->LogoutL( EFalse );
       
  1405         return;
       
  1406         }
       
  1407     else if ( aConnectionState == EInternal_NO_IAP )
       
  1408         {
       
  1409         // start to delete CSP session asynchronously
       
  1410         DeleteCSPAsynch( aSess );
       
  1411         return;
       
  1412         }
       
  1413 
       
  1414     // Send status events only if the state has changed.
       
  1415     // OFF_LINE events are not send since client API does not support them.
       
  1416     if ( aConnectionState != EInternal_OFF_LINE )
       
  1417         {
       
  1418         SendStatusEvents( aConnectionState, csp );
       
  1419         }
       
  1420     }
       
  1421 
       
  1422 // ---------------------------------------------------------
       
  1423 // CImpsServer::BufferSize
       
  1424 // ---------------------------------------------------------
       
  1425 //
       
  1426 TInt CImpsServer::BufferSize( )
       
  1427     {
       
  1428     return iSettings.MaximumParserSize() - KImpsBufOverhead;
       
  1429     }
       
  1430 
       
  1431 // ---------------------------------------------------------
       
  1432 // CImpsServer::SetConnAllowed
       
  1433 // ---------------------------------------------------------
       
  1434 //
       
  1435 void CImpsServer::SetConnAllowed( TBool aParam )
       
  1436     {
       
  1437 #ifndef _NO_IMPS_LOGGING_
       
  1438     CImpsClientLogger::Log( _L( "Server: SetConnAllowed %d" ), aParam );
       
  1439 #endif
       
  1440     iConAllowed = aParam;
       
  1441     // Logout internally all CSP sessions if connection not allowed
       
  1442     TDblQueIter<CImpsConn> rIter( iCSPList );
       
  1443     rIter.SetToFirst();
       
  1444     while ( rIter )
       
  1445         {
       
  1446         CImpsConn* conn = rIter;
       
  1447         rIter++;
       
  1448         conn->Sess()->SetConnAllowed( aParam );
       
  1449         }
       
  1450     }
       
  1451 
       
  1452 // -----------------------------------------------------------------------------
       
  1453 // CImpsServer::SendErrorEvent
       
  1454 // -----------------------------------------------------------------------------
       
  1455 //
       
  1456 void CImpsServer::SendErrorEvent(
       
  1457     TImpsEventType aType,
       
  1458     TInt aCode,
       
  1459     TInt aOpId,
       
  1460     TImpsSessIdent aCSP )
       
  1461     {
       
  1462 
       
  1463 #ifndef _NO_IMPS_LOGGING_
       
  1464     CImpsClientLogger::Log( _L( "Server: SendErrorEvent begins" ) );
       
  1465 #endif
       
  1466     // Create error event
       
  1467     iSnd->Reset();
       
  1468     iSnd->SetStatus( aCode );
       
  1469 
       
  1470     // Search proper session type for an error not response for
       
  1471     // a client request.
       
  1472     iSessionIter.SetToFirst();
       
  1473     while ( iSessionIter )
       
  1474         {
       
  1475         CSession2* session = iSessionIter;
       
  1476         iSessionIter++;
       
  1477         if ( ( ( CImpsSession* )session )->Types( ) && aType &&
       
  1478              ( ( CImpsSession* )session )->MatchSession( aCSP ) )
       
  1479             {
       
  1480             // Send event to client
       
  1481             ( ( CImpsSession* )session )->SendEvent(
       
  1482                 iSnd,
       
  1483                 aOpId,
       
  1484                 EImpsServNone,
       
  1485                 EImpsMessageNone,
       
  1486                 0 );
       
  1487             }
       
  1488         }
       
  1489     }
       
  1490 
       
  1491 // -----------------------------------------------------------------------------
       
  1492 // CImpsServer::NewContainerL
       
  1493 // -----------------------------------------------------------------------------
       
  1494 //
       
  1495 CObjectCon* CImpsServer::NewContainerL()
       
  1496     {
       
  1497     return iContainerIndex->CreateL();
       
  1498     }
       
  1499 
       
  1500 // -----------------------------------------------------------------------------
       
  1501 // CImpsServer::RemoveContainer
       
  1502 // -----------------------------------------------------------------------------
       
  1503 //
       
  1504 void CImpsServer::RemoveContainer( CObjectCon* aCon )
       
  1505     {
       
  1506     iContainerIndex->Remove( aCon );
       
  1507     }
       
  1508 
       
  1509 
       
  1510 // -----------------------------------------------------------------------------
       
  1511 // CImpsServer::DiscardRequest
       
  1512 // -----------------------------------------------------------------------------
       
  1513 //
       
  1514 void CImpsServer::DiscardRequest(
       
  1515     const TDesC& aTid, TImpsEventType aType, TInt aCode,
       
  1516     TImpsSessIdent aCSP )
       
  1517     {
       
  1518 #ifndef _NO_IMPS_LOGGING_
       
  1519     CImpsClientLogger::Log( _L( "Server: DiscardRequest code=%d" ), aCode );
       
  1520 #endif
       
  1521 
       
  1522     iSessionIter.SetToFirst();
       
  1523     while ( iSessionIter )
       
  1524         {
       
  1525         CSession2* session = iSessionIter;
       
  1526         iSessionIter++;
       
  1527         if ( ( ( CImpsSession* )session )->DiscardRequest(
       
  1528                  aTid, aType, aCode, aCSP ) )
       
  1529             {
       
  1530             break;
       
  1531             }
       
  1532         }
       
  1533     }
       
  1534 
       
  1535 // -----------------------------------------------------------------------------
       
  1536 // CImpsServer::SendLogoutEvents
       
  1537 // -----------------------------------------------------------------------------
       
  1538 //
       
  1539 void CImpsServer::SendLogoutEvents( CImpsSubSession* aSub, TInt aOpId,
       
  1540                                     TImpsSessIdent aCSP )
       
  1541     {
       
  1542 #ifndef _NO_IMPS_LOGGING_
       
  1543     CImpsClientLogger::Log( _L( "Server: SendLogoutEvents" ) );
       
  1544 #endif
       
  1545     iSessionIter.SetToFirst();
       
  1546     while ( iSessionIter )
       
  1547         {
       
  1548         CSession2* session = iSessionIter;
       
  1549         iSessionIter++;
       
  1550         if ( ( ( CImpsSession* )session )->MatchSession( aCSP ) )
       
  1551             {
       
  1552             ( ( CImpsSession* )session )->SendLogoutEvent(
       
  1553                 KErrNone, aOpId, aSub, 0 );
       
  1554             }
       
  1555         }
       
  1556     }
       
  1557 
       
  1558 // -----------------------------------------------------------------------------
       
  1559 // CImpsServer::DoShutDown
       
  1560 // -----------------------------------------------------------------------------
       
  1561 //
       
  1562 void CImpsServer::DoShutDown()
       
  1563     {
       
  1564 #ifndef _NO_IMPS_LOGGING_
       
  1565     CImpsClientLogger::Log( _L( "Server: DoShutDown begins" ) );
       
  1566 #endif
       
  1567     StopTimer();
       
  1568     if ( iOrphans )
       
  1569         {
       
  1570         iOrphans->Stop();
       
  1571         }
       
  1572 
       
  1573     // Free ECOM plugins
       
  1574     REComSession::FinalClose();
       
  1575 
       
  1576 #ifndef _NO_IMPS_LOGGING_
       
  1577     CImpsClientLogger::Log( _L( "Server: DoShutDown ends" ) );
       
  1578 #endif
       
  1579     CImpsScheduler::Stop();
       
  1580     }
       
  1581 
       
  1582 // -----------------------------------------------------------------------------
       
  1583 // CImpsServer::IsNegotiated
       
  1584 // -----------------------------------------------------------------------------
       
  1585 //
       
  1586 TBool CImpsServer::IsNegotiated( TImpsSessIdent aCSP )
       
  1587     {
       
  1588     MImpsCSPSession* csp = GetCSP( aCSP, EFalse );
       
  1589     if ( !csp )
       
  1590         {
       
  1591         return EFalse;
       
  1592         }
       
  1593     return csp->IsNegotiated();
       
  1594     }
       
  1595 
       
  1596 // -----------------------------------------------------------------------------
       
  1597 // CImpsServer::Services
       
  1598 // -----------------------------------------------------------------------------
       
  1599 //
       
  1600 TImpsServices* CImpsServer::Services( TImpsSessIdent aCSP )
       
  1601     {
       
  1602     MImpsCSPSession* csp = GetCSP( aCSP, EFalse );
       
  1603     if ( !csp )
       
  1604         {
       
  1605         return NULL;
       
  1606         }
       
  1607     return csp->Services();
       
  1608     }
       
  1609 
       
  1610 // -----------------------------------------------------------------------------
       
  1611 // CImpsServer::TidSeed
       
  1612 // -----------------------------------------------------------------------------
       
  1613 //
       
  1614 TInt CImpsServer::TidSeed()
       
  1615     {
       
  1616     ++iSeed;
       
  1617     if ( iSeed == KMaxTInt )
       
  1618         {
       
  1619         iSeed = 0;
       
  1620         }
       
  1621     return iSeed;
       
  1622     }
       
  1623 
       
  1624 // -----------------------------------------------------------------------------
       
  1625 // CImpsServer::LogoutAll
       
  1626 // -----------------------------------------------------------------------------
       
  1627 //
       
  1628 void CImpsServer::LogoutAll()
       
  1629     {
       
  1630     // Set server state as SHUTTING_DOWN
       
  1631     iOperation = EImpsSrvShuttingDown;
       
  1632 
       
  1633     // Send SHUTTING_DOWN events to clients
       
  1634     iSessionIter.SetToFirst();
       
  1635 
       
  1636     // Check TID match
       
  1637     while ( iSessionIter )
       
  1638         {
       
  1639         CSession2* session = iSessionIter;
       
  1640         iSessionIter++;
       
  1641         ( ( CImpsSession* )session )->SendEvent( EInternal_SHUTTING_DOWN );
       
  1642         }
       
  1643 
       
  1644     // Search each CSP session logged in and logout them
       
  1645     CloseAllCSPs();
       
  1646     }
       
  1647 
       
  1648 // -----------------------------------------------------------------------------
       
  1649 // CImpsServer::CustomSecurityCheckL
       
  1650 // This is used for connect request only
       
  1651 // -----------------------------------------------------------------------------
       
  1652 //
       
  1653 
       
  1654 CPolicyServer::TCustomResult CImpsServer::CustomSecurityCheckL(
       
  1655     const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/ )
       
  1656     {
       
  1657     CPolicyServer::TCustomResult test;
       
  1658     if ( aMsg.HasCapability( ECapabilityNetworkServices ) )
       
  1659         {
       
  1660         test = EPass;
       
  1661         }
       
  1662     else
       
  1663         {
       
  1664         test = EFail;
       
  1665         }
       
  1666 #ifndef _NO_IMPS_LOGGING_
       
  1667     CImpsClientLogger::Log( _L( "Server: CustomSecurityCheckL returns %d" ), test );
       
  1668 #endif
       
  1669     return test;
       
  1670     }
       
  1671 
       
  1672 
       
  1673 // -----------------------------------------------------------------------------
       
  1674 // CImpsServer::GetCSPVersion
       
  1675 // -----------------------------------------------------------------------------
       
  1676 //
       
  1677 void CImpsServer::GetCSPVersion()
       
  1678     {
       
  1679     // Get supported CSP WV version in the terminal.
       
  1680     // Default is 1.1 version, thus only 1.2 needs to be handled here
       
  1681     TReal ver ( 0 );
       
  1682     TRAPD( errx, ver = TImpsDataUtils::GetCenRepRealValueL(
       
  1683                            KCRUIDWVEngineVariation, KWVEngineCspVersion ) );
       
  1684     if ( !errx && ver == 1.2 )
       
  1685         {
       
  1686         iCSPVersion = EImpsCspVersion12;
       
  1687         }
       
  1688     }
       
  1689 
       
  1690 // -----------------------------------------------------------------------------
       
  1691 // CImpsServer::SetExpiryTimer
       
  1692 // -----------------------------------------------------------------------------
       
  1693 //
       
  1694 void CImpsServer::SetExpiryTimer( TInt aExpiry, TBool aInit )
       
  1695     {
       
  1696     // search the minimum value from Cent Rep values
       
  1697     TInt expiryInterval = iSettings.iAccessExp;
       
  1698     if ( iSettings.iFuExp < expiryInterval )
       
  1699         {
       
  1700         expiryInterval = iSettings.iFuExp;
       
  1701         }
       
  1702     if ( iSettings.iGrExp < expiryInterval )
       
  1703         {
       
  1704         expiryInterval = iSettings.iGrExp;
       
  1705         }
       
  1706     if ( iSettings.iImExp < expiryInterval )
       
  1707         {
       
  1708         expiryInterval = iSettings.iImExp;
       
  1709         }
       
  1710     if ( iSettings.iPrExp < expiryInterval )
       
  1711         {
       
  1712         expiryInterval = iSettings.iPrExp;
       
  1713         }
       
  1714     // Then compare the given value and select minimum
       
  1715     if ( aExpiry )
       
  1716         {
       
  1717         if ( aExpiry < expiryInterval )
       
  1718             {
       
  1719             expiryInterval = aExpiry;
       
  1720             }
       
  1721         }
       
  1722     if ( !iExpiryInterval || iExpiryInterval > expiryInterval )
       
  1723         {
       
  1724         iExpiryInterval = expiryInterval;
       
  1725         }
       
  1726     if ( aInit && !iExpiryTimer->IsActive() )
       
  1727         {
       
  1728         // Add 1 so that it can alwayd be divided.
       
  1729         iExpiryTimer->Start( ( iExpiryInterval + 1 ) / 2 );
       
  1730         }
       
  1731     }
       
  1732 
       
  1733 // -----------------------------------------------------------------------------
       
  1734 // CImpsServer::ResetExpiryTimer
       
  1735 // -----------------------------------------------------------------------------
       
  1736 //
       
  1737 void CImpsServer::ResetExpiryTimer( TInt aExpiry )
       
  1738     {
       
  1739     if ( aExpiry >= iExpiryInterval )
       
  1740         {
       
  1741         // no need to change the value
       
  1742         return;
       
  1743         }
       
  1744 
       
  1745     TInt expiryInterval = 0;
       
  1746     // Do not start expiry timer if it is not runnig.
       
  1747     if ( iExpiryTimer->IsActive() )
       
  1748         {
       
  1749         // Search minimum expiry time from sub-sessions
       
  1750         TInt exp = 0;
       
  1751         while ( iSessionIter )
       
  1752             {
       
  1753             CSession2* session = iSessionIter;
       
  1754             iSessionIter++;
       
  1755             exp = ( ( CImpsSession* )session )->ExpiryTime( );
       
  1756             if ( ( exp && exp < expiryInterval ) || !expiryInterval )
       
  1757                 {
       
  1758                 expiryInterval = exp;
       
  1759                 }
       
  1760             }
       
  1761         SetExpiryTimer( expiryInterval, EFalse );
       
  1762         }
       
  1763     }
       
  1764 
       
  1765 // ================= OTHER EXPORTED FUNCTIONS ==============
       
  1766 
       
  1767 // -----------------------------------------------------------------------------
       
  1768 // ThreadFunction()
       
  1769 // Needed only in WINS build
       
  1770 // -----------------------------------------------------------------------------
       
  1771 
       
  1772 #ifdef __WINS__
       
  1773 
       
  1774 EXPORT_C TInt ThreadFunction( TAny* aThreadParams )
       
  1775     {
       
  1776     // increase dll's user count so it can't get unloaded when the client application
       
  1777     // terminates
       
  1778 
       
  1779     RLibrary lib;
       
  1780     lib.Load( KImpsLibName ); //
       
  1781 
       
  1782     return CImpsServer::ThreadStart( *( TImpsSignal* )aThreadParams );
       
  1783     }
       
  1784 
       
  1785 #endif
       
  1786 
       
  1787 
       
  1788 
       
  1789 
       
  1790 
       
  1791 
       
  1792 //  End of File