realtimenetprots/sipfw/ClientResolver/Resolver/src/CSIPClientResolver.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CSIPClientResolver.cpp
       
    15 // Part of       : SIP Client Resolver
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDES
       
    22 #include "CSIPClientResolver.h"
       
    23 #include "sdpcodecstringpool.h"
       
    24 #include "siprequest.h"
       
    25 #include "sipresponse.h"
       
    26 #include "CSIPClientData.h"
       
    27 #include "CSIPClientDataParser.h"
       
    28 #include "CSipLaunchingStrategies.h"
       
    29 #include "CleanupResetAndDestroy.h"
       
    30 #include "SipResolvedClient.h"
       
    31 #include "TSipClient.h"
       
    32 #include "SIPCRLogs.h"
       
    33 #include <e32math.h>
       
    34 #include "CSIPClientResolver2.h"
       
    35 
       
    36 _LIT(KWorkerThreadName, "SIPClientResolverWorker");
       
    37 
       
    38 
       
    39 // ----------------------------------------------------------------------------
       
    40 // CSIPClientResolver::NewLC
       
    41 // ----------------------------------------------------------------------------
       
    42 //
       
    43 EXPORT_C CSIPClientResolver* CSIPClientResolver::NewL ()
       
    44     {
       
    45     CSIPClientResolver* self = new( ELeave ) CSIPClientResolver;
       
    46     CleanupStack::PushL( self );
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop (self);
       
    49     return self;
       
    50     }
       
    51     
       
    52 // ----------------------------------------------------------------------------
       
    53 // CSIPClientResolver::CSIPClientResolver
       
    54 // ----------------------------------------------------------------------------
       
    55 //
       
    56 CSIPClientResolver::CSIPClientResolver()
       
    57     : CActive( CActive::EPriorityStandard )
       
    58     {
       
    59     CActiveScheduler::Add( this );
       
    60     }
       
    61 
       
    62 // ----------------------------------------------------------------------------
       
    63 // CSIPClientResolver::ConstructL
       
    64 // ----------------------------------------------------------------------------
       
    65 //
       
    66 void CSIPClientResolver::ConstructL()
       
    67     {
       
    68     SdpCodecStringPool::OpenL();
       
    69     iECom = &(REComSession::OpenL());
       
    70 
       
    71     // Create XML parser for SIP client data
       
    72     iClientDataParser = CSIPClientDataParser::NewL();
       
    73 
       
    74     // Create arrays
       
    75     iRegistry = new( ELeave )RPointerArray< CSIPClientData >;
       
    76 
       
    77     // Fill implementations registry
       
    78     ListImplementationsL();
       
    79 
       
    80     // Create strategies
       
    81     iLaunchingStrategies = CSipLaunchingStrategies::NewL( *this );
       
    82 
       
    83     // Request notification from ECom when plugin registry changes
       
    84     NotifyOnChange();
       
    85     }
       
    86     
       
    87 // ----------------------------------------------------------------------------
       
    88 // CSIPClientResolver::~CSIPClientResolver
       
    89 // ----------------------------------------------------------------------------
       
    90 //
       
    91 EXPORT_C CSIPClientResolver::~CSIPClientResolver ()
       
    92     {
       
    93     delete iTmpPluginCaps;
       
    94     Cancel();
       
    95     delete iLaunchingStrategies;
       
    96     RemoveRegistry();
       
    97     delete iClientDataParser;
       
    98     if (iECom)
       
    99         {
       
   100         iECom->Close();
       
   101         }
       
   102     REComSession::FinalClose();
       
   103     SdpCodecStringPool::Close();
       
   104     }
       
   105 
       
   106 // ----------------------------------------------------------------------------
       
   107 // CSIPClientResolver::FindUidL
       
   108 // ----------------------------------------------------------------------------
       
   109 //
       
   110 EXPORT_C CSIPResponse* CSIPClientResolver::FindUidL(
       
   111     const CSIPRequest& aRequest,
       
   112     RArray< TSipClient >& aUids )
       
   113     {
       
   114     SIP_CR_STR_LOG("CSIPClientResolver::FindUidL", aRequest.Method().DesC())
       
   115 
       
   116     CSIPRequest& request = const_cast<CSIPRequest&>( aRequest );
       
   117  	CSIPClientResolver2* clientresolver2 = NULL;
       
   118  	clientresolver2 = CSIPClientResolver2::NewLC(request);
       
   119     RefreshClientDataL();
       
   120     RArray< TUid > uids;
       
   121     CleanupClosePushL( uids );
       
   122     CopyAllUidsL ( uids );
       
   123     CSIPResponse* response = 
       
   124         iLaunchingStrategies->ApplyL( request, uids, *clientresolver2 );
       
   125     if( !response )
       
   126         {
       
   127         if ( !( clientresolver2 && 
       
   128         	    clientresolver2->GetSipClientDataL( aUids ) ) )
       
   129         	{
       
   130         	TInt uidCount = uids.Count();
       
   131         	for( TInt i = 0; i < uidCount; i++ )
       
   132             	{
       
   133             	MSipClient* client = GetByUID( uids[i] );
       
   134             	if( client )
       
   135                 	{
       
   136                 	TSipClient tmp( client->ClientUid(), 
       
   137                 					client->AllowStarting(), 
       
   138                                 	client->RomBased() );
       
   139                 	aUids.AppendL( tmp );
       
   140                 	}
       
   141             	}
       
   142         	}
       
   143         }
       
   144     else
       
   145         {
       
   146         SIP_CR_INT_LOG("CSIPClientResolver::FindUidL returns response",
       
   147                        response->ResponseCode())
       
   148         }    
       
   149 	CleanupStack::PopAndDestroy(1); // uids
       
   150 	CleanupStack::PopAndDestroy( clientresolver2 );
       
   151 	
       
   152 	for (TInt i=0; i < aUids.Count(); i++)
       
   153 	    {
       
   154 	    SIP_CR_INT_LOG("CSIPClientResolver::FindUidL matching client", 
       
   155 	                   aUids[i].Uid().iUid)
       
   156 	    }
       
   157 	
       
   158 	return response;
       
   159 	}
       
   160 	
       
   161 // ----------------------------------------------------------------------------
       
   162 // CSIPClientResolver::RefreshClientDataL
       
   163 // ----------------------------------------------------------------------------
       
   164 //
       
   165 void CSIPClientResolver::RefreshClientDataL()
       
   166     {
       
   167     TInt err = KErrNone;
       
   168     TInt count = iRegistry->Count();
       
   169     for( TInt i = count-1; i >= 0; i-- )
       
   170         {
       
   171         CSIPClientData* client = (*iRegistry)[ i ];
       
   172         if( client->HasDynamicCapabilities() )
       
   173             {
       
   174             CSIPClientData* clone = client->CloneWithoutCapabilitiesLC();
       
   175             TRAP( err, ReloadClientDataL( *clone ) );
       
   176             if( err == KErrNone )
       
   177                 {
       
   178                 // Replace with the new client data
       
   179                 (*iRegistry)[ i ] = clone;
       
   180                 CleanupStack::Pop( clone );                
       
   181                 }
       
   182             else if( err == KErrNoMemory )
       
   183                 {
       
   184                 User::Leave( err );
       
   185                 }
       
   186             else
       
   187                 {
       
   188                 // Remove the invalid client
       
   189                 iRegistry->Remove( i );
       
   190                 CleanupStack::PopAndDestroy( clone );
       
   191                 }
       
   192             delete client;
       
   193             }
       
   194         }    
       
   195     }	
       
   196 
       
   197 // ----------------------------------------------------------------------------
       
   198 // CSIPClientResolver::GetByUID
       
   199 // ----------------------------------------------------------------------------
       
   200 //
       
   201 MSipClient* CSIPClientResolver::GetByUID( const TUid& aUid ) const
       
   202     {
       
   203     TInt count = iRegistry->Count();
       
   204     for( TInt i = 0; i < count; i++ )
       
   205         {
       
   206         MSipClient* client = (*iRegistry)[ i ];
       
   207         if( client->ClientUid() == aUid )
       
   208             {
       
   209             return client;
       
   210             }
       
   211         }
       
   212 	return NULL;
       
   213     }
       
   214 
       
   215 // ----------------------------------------------------------------------------
       
   216 // CSIPClientResolver::DoCancel
       
   217 // ----------------------------------------------------------------------------
       
   218 //
       
   219 void CSIPClientResolver::DoCancel()
       
   220     {
       
   221     iECom->CancelNotifyOnChange( iStatus );	
       
   222     }
       
   223 
       
   224 // ----------------------------------------------------------------------------
       
   225 // CSIPClientResolver::RunL
       
   226 // ----------------------------------------------------------------------------
       
   227 //
       
   228 void CSIPClientResolver::RunL()
       
   229     {
       
   230     // Update implementations registry, fail silently
       
   231     TRAP_IGNORE( ListImplementationsL() )
       
   232 
       
   233     // Request further notification from ECom when plugin registry changes
       
   234     NotifyOnChange();
       
   235     }
       
   236 
       
   237 // ----------------------------------------------------------------------------
       
   238 // CSIPClientResolver::ListImplementationsL
       
   239 // ----------------------------------------------------------------------------
       
   240 //
       
   241 void CSIPClientResolver::ListImplementationsL()
       
   242     {
       
   243     // Create a temporary array to avoid destroying 
       
   244     // an existing registry if we run out of memory
       
   245     RPointerArray< CSIPClientData >* tmpRegistry =
       
   246             new( ELeave ) RPointerArray< CSIPClientData >;
       
   247     CleanupStack::PushL( TCleanupItem( ResetAndDestroy, tmpRegistry ) );
       
   248 
       
   249     // ROM clients
       
   250     TEComResolverParams romResolverParams;
       
   251 	RImplInfoPtrArray romClients;
       
   252 	REComSession::ListImplementationsL( KSIPResolvedClientIFUid,
       
   253 	                                    romResolverParams,
       
   254 	                                    KRomOnlyResolverUid,
       
   255 	                                    romClients );
       
   256     CleanupResetAndDestroyPushL( romClients );  
       
   257     ConvertClientDataL( romClients, *tmpRegistry, ETrue );
       
   258     SIP_CR_INT_LOG("ROM-based plug-ins count", romClients.Count())
       
   259    
       
   260     // RAM clients     
       
   261 	RImplInfoPtrArray allClients;
       
   262 	REComSession::ListImplementationsL( KSIPResolvedClientIFUid, allClients );
       
   263     CleanupResetAndDestroyPushL( allClients );
       
   264     SIP_CR_INT_LOG("All plug-ins count", allClients.Count())
       
   265     RemoveDuplicates( romClients, allClients );
       
   266     ConvertClientDataL( allClients, *tmpRegistry, EFalse );
       
   267     
       
   268     CleanupStack::PopAndDestroy( 1 ); // allClients
       
   269     CleanupStack::PopAndDestroy( 1 ); // romClients
       
   270 
       
   271     RemoveRegistry();
       
   272     delete iRegistry;
       
   273     iRegistry = tmpRegistry;
       
   274     CleanupStack::Pop( 1 ); // tmpRegistry
       
   275     }
       
   276 
       
   277 // ----------------------------------------------------------------------------
       
   278 // CSIPClientResolver::RemoveRegistry
       
   279 // ----------------------------------------------------------------------------
       
   280 //
       
   281 void CSIPClientResolver::RemoveRegistry()
       
   282     {
       
   283     if( iRegistry )
       
   284         {
       
   285         iRegistry->ResetAndDestroy();
       
   286         delete iRegistry;
       
   287         iRegistry = NULL;
       
   288         }
       
   289     }
       
   290 
       
   291 // ----------------------------------------------------------------------------
       
   292 // CSIPClientResolver::NotifyOnChange
       
   293 // ----------------------------------------------------------------------------
       
   294 //
       
   295 void CSIPClientResolver::NotifyOnChange()
       
   296     {
       
   297     iECom->NotifyOnChange( iStatus );
       
   298     SetActive();
       
   299     }
       
   300 
       
   301 // ----------------------------------------------------------------------------
       
   302 // CSIPClientResolver::CopyAllUidsL
       
   303 // ----------------------------------------------------------------------------
       
   304 //
       
   305 void CSIPClientResolver::CopyAllUidsL ( RArray< TUid >& aUids )
       
   306     {
       
   307     TInt count = iRegistry->Count();
       
   308     for( TInt i = 0; i < count; i++ )
       
   309         {
       
   310         MSipClient* client = (*iRegistry)[ i ];
       
   311         aUids.AppendL( client->ClientUid() );	
       
   312         }
       
   313     }
       
   314   
       
   315 // ----------------------------------------------------------------------------
       
   316 // CSIPClientResolver::ConvertClientDataL
       
   317 // ----------------------------------------------------------------------------
       
   318 //
       
   319 void CSIPClientResolver::ConvertClientDataL(
       
   320     const RImplInfoPtrArray& aImplInfo,
       
   321     RPointerArray< CSIPClientData >& aRegistry,
       
   322     TBool aRomClient )
       
   323     {
       
   324     TInt err = KErrNone;
       
   325     TInt clientCount = aImplInfo.Count();
       
   326     for( TInt i = 0; i < clientCount; i++ )
       
   327         {
       
   328         // Ignore clients with invalid data
       
   329         CImplementationInformation* info = aImplInfo[ i ];
       
   330         TRAP( err, AddClientDataL( aRegistry, *info, aRomClient ) );
       
   331 
       
   332         SIP_CR_STR_LOG("Plug-in with 'default_data'", info->DataType())
       
   333         SIP_CR_INT_LOG("Plug-in status", err)
       
   334         
       
   335         if( err == KErrNoMemory )
       
   336             {
       
   337             User::Leave( err );
       
   338             }
       
   339         }      
       
   340     }
       
   341 
       
   342 // ----------------------------------------------------------------------------
       
   343 // CSIPClientResolver::AddClientDataL
       
   344 // ----------------------------------------------------------------------------
       
   345 //
       
   346 void CSIPClientResolver::AddClientDataL( 
       
   347     RPointerArray< CSIPClientData >& aRegistry,
       
   348     CImplementationInformation& aInfo, 
       
   349     TBool aRomClient )
       
   350     {
       
   351 	TLex8 lex( aInfo.DataType() );
       
   352     TUint32 uidValue( 0 );
       
   353     User::LeaveIfError( lex.Val( uidValue, EHex ) );
       
   354     TUid clientUid;
       
   355     clientUid.iUid = uidValue;     
       
   356     const TBool romBased = ( aRomClient && aInfo.RomBased() );
       
   357     TPtrC8 xml( aInfo.OpaqueData() );
       
   358     const TBool dynamicCaps = ( xml.Length() == 0 );
       
   359     
       
   360     CSIPClientData* clientData = 
       
   361         CSIPClientData::NewLC( aInfo.ImplementationUid(), clientUid,
       
   362                                romBased, dynamicCaps );    
       
   363     if ( !dynamicCaps )
       
   364         {
       
   365         // XML specified in resource-file.
       
   366         iClientDataParser->ParseL( clientData, xml );
       
   367         }
       
   368     aRegistry.AppendL( clientData );
       
   369     CleanupStack::Pop( clientData );
       
   370     }
       
   371     
       
   372 // ----------------------------------------------------------------------------
       
   373 // CSIPClientResolver::ReloadClientDataL
       
   374 // ----------------------------------------------------------------------------
       
   375 // 
       
   376 void CSIPClientResolver::ReloadClientDataL( CSIPClientData& aClientData )
       
   377     {
       
   378     iTmpImplementationUid = aClientData.ImplementationUid();
       
   379     CreateWorkerThreadL();
       
   380     iClientDataParser->ParseL( &aClientData, *iTmpPluginCaps );
       
   381     delete iTmpPluginCaps;
       
   382     iTmpPluginCaps = NULL;
       
   383     }
       
   384 
       
   385 // ----------------------------------------------------------------------------
       
   386 // CSIPClientResolver::RemoveDuplicates
       
   387 // ----------------------------------------------------------------------------
       
   388 //
       
   389 void CSIPClientResolver::RemoveDuplicates( 
       
   390     const RImplInfoPtrArray& aRomInfo,
       
   391     RImplInfoPtrArray& aAllInfo )
       
   392     {
       
   393     TInt romInfoCount = aRomInfo.Count();
       
   394     for( TInt i=0; i<romInfoCount; i++ )
       
   395         {
       
   396         for( TInt j=aAllInfo.Count()-1; j>=0; j-- )
       
   397             {
       
   398             CImplementationInformation* info = aAllInfo[j];
       
   399             if( info->ImplementationUid() == aRomInfo[i]->ImplementationUid() )
       
   400                 {
       
   401                 aAllInfo.Remove( j );
       
   402                 delete info;
       
   403                 }
       
   404             }
       
   405         }
       
   406     }
       
   407 
       
   408 // ----------------------------------------------------------------------------
       
   409 // CSIPClientResolver::ResetAndDestroy
       
   410 // ----------------------------------------------------------------------------
       
   411 //
       
   412 void CSIPClientResolver::ResetAndDestroy( TAny* anArray )
       
   413     {
       
   414     RPointerArray< CSIPClientData >* array =
       
   415         reinterpret_cast<RPointerArray< CSIPClientData >*>( anArray );
       
   416     if (array)
       
   417         {
       
   418         array->ResetAndDestroy();
       
   419         delete array;
       
   420         }
       
   421     }
       
   422     
       
   423 // ----------------------------------------------------------------------------
       
   424 // CSIPClientResolver::CreateWorkerThreadL
       
   425 // ----------------------------------------------------------------------------
       
   426 //   
       
   427 void CSIPClientResolver::CreateWorkerThreadL()
       
   428     {
       
   429     TName threadName(KWorkerThreadName);
       
   430     // Append a random number to make the name unique
       
   431     const TInt KThreadIdWidth = 10;
       
   432     threadName.AppendNumFixedWidthUC(Math::Random(), EHex, KThreadIdWidth);
       
   433     RThread thread;
       
   434     TInt err = thread.Create(threadName,
       
   435                              WorkerThreadFunction,
       
   436                              KDefaultStackSize,
       
   437                              NULL, // Use the same heap as the main thread
       
   438                              this);
       
   439     User::LeaveIfError(err);
       
   440     TRequestStatus status;
       
   441     thread.Logon(status);
       
   442     thread.Resume();
       
   443     User::WaitForRequest(status);
       
   444     TExitType exitType = thread.ExitType();
       
   445     thread.Close();
       
   446     if (exitType == EExitPanic)
       
   447         {
       
   448         User::Leave(KErrGeneral);
       
   449         }
       
   450     User::LeaveIfError(status.Int());
       
   451     }
       
   452 
       
   453 // ----------------------------------------------------------------------------
       
   454 // CSIPClientResolver::WorkerThreadFunction
       
   455 // ----------------------------------------------------------------------------
       
   456 //     
       
   457 TInt CSIPClientResolver::WorkerThreadFunction(TAny* aPtr)
       
   458     {
       
   459     CSIPClientResolver* self = 
       
   460         reinterpret_cast<CSIPClientResolver*>(aPtr);
       
   461     TInt err = KErrNoMemory;
       
   462     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   463     if (cleanupStack)
       
   464         {
       
   465         TRAP(err, self->ReadPluginCapsL());
       
   466         REComSession::FinalClose(); // Needed for each thread separately
       
   467         }
       
   468     delete cleanupStack;
       
   469     return err;
       
   470     }
       
   471     
       
   472 // ----------------------------------------------------------------------------
       
   473 // CSIPClientResolver::ReadPluginCapsL
       
   474 // ----------------------------------------------------------------------------
       
   475 //  
       
   476 void CSIPClientResolver::ReadPluginCapsL()
       
   477     {
       
   478     CSIPResolvedClient* plugin = 
       
   479         reinterpret_cast< CSIPResolvedClient* >( 
       
   480             REComSession::CreateImplementationL( 
       
   481                 iTmpImplementationUid, 
       
   482                 _FOFF( CSIPResolvedClient, iInstanceKey ) ) );
       
   483     CleanupStack::PushL( plugin );
       
   484     HBufC8* capsBuf = plugin->Capabilities().AllocL();
       
   485     CleanupStack::PopAndDestroy( plugin );
       
   486     delete iTmpPluginCaps;
       
   487     iTmpPluginCaps = capsBuf;
       
   488     }
       
   489 
       
   490 // End of File
       
   491