callcontinuity/vcc/src/cvccdirector.cpp
branchRCL_3
changeset 22 d38647835c2e
equal deleted inserted replaced
21:f742655b05bf 22:d38647835c2e
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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:   Handles all common logic for VCC proxy and handles sessions.
       
    15 *
       
    16 */
       
    17 
       
    18 //cleanup stack operations
       
    19 #include <mccpssobserver.h>
       
    20 #include <spnotifychange.h>
       
    21 #include <spsettings.h>
       
    22 #include <spentry.h>
       
    23 #include <spproperty.h>
       
    24 
       
    25 #include "vcchotrigger.h"
       
    26 #include "cvccdirector.h"
       
    27 #include "cvccconferencecall.h"
       
    28 #include "cvccperformer.h"
       
    29 #include "vccengpspropertylistener.h"
       
    30 #include "vccsubscribekeys.h"
       
    31 #include "vccsettingsreader.h"
       
    32 #include "vccdefinitions.h"
       
    33 #include "rubydebug.h"
       
    34 #include "cvccdtmfprovider.h"
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // CVccDirector::CVccDirector
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 CVccDirector::CVccDirector(): 
       
    41 	iImplementationUid( KVCCImplementationUid )
       
    42 	
       
    43     {
       
    44     RUBY_DEBUG_BLOCK( "CVccDirector::CVccDirector" );
       
    45     }
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 // CVccDirector::PointerArrayCleanup
       
    49 // ---------------------------------------------------------------------------
       
    50 //
       
    51 void CVccDirector::PointerArrayCleanup( TAny* aArray )
       
    52     {
       
    53     static_cast<RPointerArray<CConvergedCallProvider>*>( aArray )->ResetAndDestroy();
       
    54     static_cast<RPointerArray<CConvergedCallProvider>*>( aArray )->Close();
       
    55     }
       
    56 
       
    57 // ---------------------------------------------------------------------------
       
    58 // CVccDirector::ConstructL
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 void CVccDirector::ConstructL()
       
    62     {
       
    63     RUBY_DEBUG_BLOCKL( "CVccDirector::ConstructL" );
       
    64 
       
    65     FillCallProviderArrayL();
       
    66     
       
    67     // Create the HO-trigger and connect to the wlan network
       
    68     iHoTrigger = CVccHoTrigger::NewL();
       
    69     
       
    70 	iPropListener = CVccEngPsPropertyListener::NewL( KPSVccPropertyCategory, 
       
    71             KVccPropKeyHoRequest );
       
    72 	RUBY_DEBUG0( "- Called CVccEngPsPropertyListener::NewL" );
       
    73 	iPropListener->AddObserverL( *this );
       
    74 	RUBY_DEBUG0( "- Called iPropListener->AddObserverL" );
       
    75 	iPropListener->Start();
       
    76 	RUBY_DEBUG0( "- Called iPropListener->Start()" );
       
    77 	
       
    78 	//notifies about the changes to SP table
       
    79 	iSpNotifier = CSPNotifyChange::NewL( *this );
       
    80 	//start service provider table notifier
       
    81     StartSpNotifierL();
       
    82     
       
    83 	//link states
       
    84   	iStateInit.LinkState(iStateCalling);
       
    85   	iStateCalling.LinkState(iStateReleasing, iStateInit, iStateFailing );
       
    86   	iStateReleasing.LinkState(iStateInit);
       
    87   	iStateFailing.LinkState( iStateInit );
       
    88   	
       
    89   	iHoKeyValue = KErrNotFound;
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // CVccDirector::NewL
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 CVccDirector* CVccDirector::NewL()
       
    97     {
       
    98     RUBY_DEBUG_BLOCKL( "CVccDirector::NewL" );
       
    99     CVccDirector* self = new ( ELeave ) CVccDirector();
       
   100     CleanupStack::PushL( self );
       
   101     self->ConstructL();
       
   102     CleanupStack::Pop( self );
       
   103     return self;
       
   104     }
       
   105 
       
   106 // ---------------------------------------------------------------------------
       
   107 // CVccDirector::~CVccDirector
       
   108 // ---------------------------------------------------------------------------
       
   109 //
       
   110 CVccDirector::~CVccDirector()
       
   111     {
       
   112     RUBY_DEBUG0( "CVccDirector::~CVccDirector() - ENTER" );
       
   113 
       
   114     delete iConference;
       
   115     iProviders.ResetAndDestroy();
       
   116     iProviders.Close();
       
   117     iPerfArray.ResetAndDestroy();
       
   118     iPerfArray.Close();
       
   119     iInitialisedPlugins.Close();
       
   120     delete iPropListener;
       
   121     
       
   122     if( iSpNotifier )
       
   123     	{
       
   124     	iSpNotifier->Cancel();
       
   125     	}
       
   126    	delete iSpNotifier;
       
   127     
       
   128     delete iHoTrigger;
       
   129     delete iDtmfProvider;
       
   130     REComSession::FinalClose();
       
   131     
       
   132     RUBY_DEBUG0( "CVccDirector::~CVccDirector() - EXIT" );
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // CVccDirector::FillCallProviderArrrayL
       
   137 // ---------------------------------------------------------------------------
       
   138 //
       
   139 void CVccDirector::FillCallProviderArrayL()
       
   140 	{
       
   141     //no supplementary services
       
   142     //creating cs and sipvoipproviders
       
   143     
       
   144     //List implementations
       
   145 
       
   146     RImplInfoPtrArray implementations;
       
   147     TCleanupItem arrayCleanup( PointerArrayCleanup, &implementations );
       
   148     CleanupStack::PushL( arrayCleanup );
       
   149 
       
   150     CConvergedCallProvider::ListImplementationsL( implementations );
       
   151  
       
   152     for( TInt i = 0; i<implementations.Count(); i++ )
       
   153         {
       
   154         RUBY_DEBUG1( "- for loop counter value: %d", i );
       
   155         CImplementationInformation *info = implementations[i];
       
   156         if ( IsVccOwnedPlugin ( info->ImplementationUid().iUid ) )
       
   157             {
       
   158             CConvergedCallProvider* provider =
       
   159                 CConvergedCallProvider::NewL( info->ImplementationUid() );
       
   160             CleanupStack::PushL( provider );
       
   161            
       
   162             User::LeaveIfError( iProviders.Append( provider ) );
       
   163             
       
   164             CleanupStack::Pop( provider ); //aProvider
       
   165             }
       
   166         }
       
   167     
       
   168     CleanupStack::PopAndDestroy();//implementations
       
   169 	}
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // CVccDirector::IsVccOwnedPlugin
       
   173 // Checks is the given call provider plugin used by VCC 
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 TBool CVccDirector::IsVccOwnedPlugin( TInt aPluginId )
       
   177 	{
       
   178 	if( aPluginId == KSipVoipCallProviderPlugId || 
       
   179 		aPluginId == KCSCallProviderPlugId	)
       
   180 			return ETrue;
       
   181 	
       
   182 	return EFalse;
       
   183 	}
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 // CVccDirector::InitializeL
       
   187 // Tries to initialize all call provider plugins used by VCC.
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 void CVccDirector::InitializeL( const MCCPObserver& aMonitor,
       
   191                                   const MCCPSsObserver& aSsObserver )
       
   192     {
       
   193     RUBY_DEBUG_BLOCKL( "CVccDirector::InitializeL" );
       
   194     
       
   195     if ( iProviders.Count() == 0 )
       
   196     	{
       
   197     	User::Leave( KErrNotFound );
       
   198     	}
       
   199 	
       
   200     iMandatoryPluginFailedError = KErrNone;
       
   201 
       
   202     //MT: setting CVccDirector as observer to plugin
       
   203     Initialize( *this, aSsObserver );
       
   204 
       
   205     // Leave if mandatory plugins failed
       
   206     User::LeaveIfError( iMandatoryPluginFailedError );
       
   207 
       
   208     // save CCP monitor ; CCCEPluginMCCPObserver
       
   209     const MCCPCSObserver& obs = static_cast<const MCCPCSObserver&>( aMonitor );
       
   210     iCCPObserver = const_cast<MCCPCSObserver*>(&obs);
       
   211 
       
   212     const MCCPSsObserver& ssObs = static_cast<const MCCPSsObserver&>( aSsObserver );
       
   213     iCCPSsObserver = const_cast<MCCPSsObserver*>(&ssObs);
       
   214     
       
   215     }
       
   216 
       
   217 // ---------------------------------------------------------------------------
       
   218 // CVccDirector::InitializeL
       
   219 // Tries to initialize call provider plugins VCC uses. 
       
   220 // Informs if  failure.
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 TBool CVccDirector::Initialize( const MCCPObserver& aMonitor,
       
   224         const MCCPSsObserver& aSsObserver )
       
   225 	{
       
   226     RUBY_DEBUG_BLOCK( "CVccDirector::Initialize" );
       
   227    
       
   228     TBool initSucceeded = ETrue;
       
   229 	
       
   230 	for ( TInt i = 0; i < iProviders.Count() ; i++)
       
   231         {
       
   232         TUid pluginUid = iProviders[ i ]->Uid();
       
   233         RUBY_DEBUG1( "starting to initialize plugin index= %d", i );
       
   234     	
       
   235         TRAPD( err, InitializeL( aMonitor, aSsObserver, *(iProviders[ i ]) ) );
       
   236         RUBY_DEBUG1( "initialization err = %d", err );
       
   237         if ( KErrNone != err && KCSCallProviderPlugId == pluginUid.iUid ) // CS plugin mandatory
       
   238             {
       
   239             RUBY_DEBUG0( "-- Mandatory VCC plugin initialization FAILED" );    
       
   240             initSucceeded = EFalse; 
       
   241             iMandatoryPluginFailedError = err;
       
   242             }
       
   243         else
       
   244             {
       
   245             switch( err )
       
   246                 {
       
   247                 case KErrNone:
       
   248                     iInitialisedPlugins.Append(  pluginUid.iUid );
       
   249                     //fall-through
       
   250                 case KErrAlreadyExists:
       
   251                     RUBY_DEBUG0( "-- VCC plugin initialization OK" );
       
   252                     break;
       
   253                 default:
       
   254                     RUBY_DEBUG0( "-- VCC plugin initialization FAILED" );
       
   255                     initSucceeded = EFalse;
       
   256                     break;
       
   257                 }
       
   258             }
       
   259         }
       
   260 	
       
   261 	RUBY_DEBUG1( "-- VCC plugin nbr of initialized plugins:%d",
       
   262 			iInitialisedPlugins.Count() );
       
   263 	return initSucceeded; 
       
   264     }
       
   265 
       
   266 // ---------------------------------------------------------------------------
       
   267 // CVccDirector::InitializeL
       
   268 // Finds from the VCC settings the service id that should be used with the 
       
   269 // given plugin. Uses the service id to initialize plugin.
       
   270 // ---------------------------------------------------------------------------
       
   271 //
       
   272 void CVccDirector::InitializeL( const MCCPObserver& aMonitor,
       
   273         const MCCPSsObserver& aSsObserver, CConvergedCallProvider& aPlugin )
       
   274 	{
       
   275     RUBY_DEBUG_BLOCKL( "CVccDirector::InitializeL" );
       
   276 	TInt serviceId = VccSettingsReader::ServiceIdL( aPlugin.Uid().iUid );
       
   277 	RUBY_DEBUG1( "Initialize plugin with serviceId = %d", serviceId );	   
       
   278     
       
   279 	User::LeaveIfError( serviceId );
       
   280 	
       
   281 	aPlugin.InitializeL( serviceId, aMonitor, 
       
   282 			aSsObserver );
       
   283 	}
       
   284 
       
   285 // ---------------------------------------------------------------------------
       
   286 // CVccDirector::NewCallL
       
   287 // ---------------------------------------------------------------------------
       
   288 //
       
   289 MCCPCall* CVccDirector::NewCallL(
       
   290                             const CCCPCallParameters& aParameters,
       
   291                             const TDesC& aRecipient,
       
   292                             const MCCPCallObserver& aObserver )
       
   293     {
       
   294     RUBY_DEBUG_BLOCKL( "CVccDirector::NewCallL" );
       
   295 
       
   296     // Check call type and translate it into domain type
       
   297     CVccPerformer* perf;
       
   298     TBool csOriginated = EFalse;
       
   299     
       
   300     if( aParameters.CallType() == CCPCall::ECallTypeCSVoice )
       
   301         {
       
   302         RUBY_DEBUG0("CS Call");
       
   303         iHoTrigger->SetCurrentDomainType( CVccHoTrigger::ECallDomainTypeCS );
       
   304         csOriginated = ETrue;
       
   305         iHoTrigger->ReadHoAllowedWhenCsOriginatedSettingL();
       
   306         }
       
   307     else
       
   308         {
       
   309         RUBY_DEBUG0("PS Call");
       
   310         iHoTrigger->SetCurrentDomainType( CVccHoTrigger::ECallDomainTypePS );
       
   311         }
       
   312     
       
   313     perf = CVccPerformer::NewL( iProviders, 
       
   314                                 iStateInit, 
       
   315                                 *iHoTrigger, 
       
   316                                 csOriginated );
       
   317     CleanupStack::PushL( perf );
       
   318     User::LeaveIfError( iPerfArray.Append( perf ) ); 
       
   319     CleanupStack::Pop( perf ); // perf
       
   320     return perf->CreatePrimaryCallL( aParameters, aRecipient, aObserver );
       
   321     }
       
   322 
       
   323 // ---------------------------------------------------------------------------
       
   324 // Releases call
       
   325 // ---------------------------------------------------------------------------
       
   326 //
       
   327 TInt CVccDirector::ReleaseCall( MCCPCall& aCall )
       
   328     {
       
   329     RUBY_DEBUG_BLOCK( "CVccDirector::ReleaseCall" );
       
   330     TInt err = KErrNotFound;
       
   331     //Go through the performer array to see which performer should be deleted.
       
   332     for( TInt i = 0; i < iPerfArray.Count(); i++ )
       
   333     	{
       
   334     	if( iPerfArray[i] == &aCall )
       
   335     		{
       
   336             err = iPerfArray[ i ]->ReleaseCall( aCall ); 
       
   337             iPerfArray[ i ]->ReleaseSecondaryCallLeg();
       
   338             delete iPerfArray[ i ];
       
   339             iPerfArray.Remove( i );
       
   340             iPerfArray.Compress();
       
   341             break;
       
   342     		}
       
   343     	}
       
   344     if( iPerfArray.Count() == 0 )
       
   345         {
       
   346         //make it possible to initiate HOs in new call
       
   347         iHoTrigger->ManualHoCallReleased();
       
   348         iHoTrigger->HoAllowed();
       
   349         iHoTrigger->Stop();
       
   350         }
       
   351     //If iHoKeyValue it means that PropertyChanged function has been visited
       
   352     //i.e. handover should be made. Non-active calls need to be released
       
   353     //before handover can be made.
       
   354     if ( iHoKeyValue >= KErrNone )
       
   355         {
       
   356         TRAP( err, PropertyChangedL( KPSVccPropertyCategory, 
       
   357                             KVccPropKeyHoRequest, 
       
   358                             iHoKeyValue ) );
       
   359         }
       
   360     
       
   361     return err;
       
   362     }
       
   363 
       
   364 // ---------------------------------------------------------------------------
       
   365 // Releases emergency call
       
   366 // ---------------------------------------------------------------------------
       
   367 //
       
   368 TInt CVccDirector::ReleaseEmergencyCall( MCCPEmergencyCall& aCall )
       
   369     {
       
   370     RUBY_DEBUG_BLOCK( "CVccDirector::ReleaseEmergencyCall" );
       
   371     for( TInt i = 0; i < iProviders.Count() ; i++)
       
   372            {
       
   373            TUid pluginUid = iProviders[ i ]->Uid();
       
   374            if (pluginUid.iUid == KCSCallProviderPlugId )
       
   375                {
       
   376                RUBY_DEBUG0( "CS Plugin found" ); 
       
   377                return iProviders[i]->ReleaseEmergencyCall( aCall );
       
   378                }
       
   379            }
       
   380     
       
   381     return KErrNotFound;
       
   382     }
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // Releases conference call
       
   386 // ---------------------------------------------------------------------------
       
   387 //
       
   388 TInt CVccDirector::ReleaseConferenceCall( MCCPConferenceCall& /*aCall*/ )
       
   389     {
       
   390     RUBY_DEBUG_BLOCK( "CVccDirector::ReleaseConferenceCall" );
       
   391     
       
   392     iConference->ReleaseConference();
       
   393     delete iConference;
       
   394     iConference = NULL;
       
   395     iHoTrigger->HoAllowed();
       
   396     if( iPerfArray.Count() > 0 )
       
   397     	{
       
   398     	for( TInt i = 0; i < iPerfArray.Count(); i++ )
       
   399     		{
       
   400     		iPerfArray[i]->ConferenceEnded();
       
   401     		}
       
   402     	}
       
   403     return KErrNone;
       
   404     }
       
   405 
       
   406 // ---------------------------------------------------------------------------
       
   407 // CVccDirector::Uid
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 const TUid& CVccDirector::Uid() const
       
   411     {
       
   412     RUBY_DEBUG_BLOCK( "CVccDirector::Uid" );
       
   413     return iImplementationUid;
       
   414     }
       
   415 
       
   416 // from ConvergedCallProvider
       
   417 
       
   418 // ---------------------------------------------------------------------------
       
   419 // CVccDirector::NewEmergencySessionL
       
   420 // ---------------------------------------------------------------------------
       
   421 //
       
   422 MCCPEmergencyCall* CVccDirector::NewEmergencyCallL(
       
   423     const TUint32 aServiceId,
       
   424     const TDesC&  aAddress,
       
   425     const MCCPCallObserver& aObserver )
       
   426     {
       
   427     RUBY_DEBUG_BLOCKL( "CVccDirector::NewEmergencyCallL" );
       
   428     for( TInt i = 0; i < iProviders.Count() ; i++)
       
   429         {
       
   430         TUid pluginUid = iProviders[ i ]->Uid();
       
   431         if (pluginUid.iUid == KCSCallProviderPlugId )
       
   432             {
       
   433             RUBY_DEBUG0( "CS Plugin found" ); 
       
   434             return iProviders[i]->NewEmergencyCallL( aServiceId, aAddress, aObserver );
       
   435             }
       
   436         }
       
   437     return NULL;
       
   438     }
       
   439 
       
   440 // ---------------------------------------------------------------------------
       
   441 // CVccDirector::NewConferenceL
       
   442 // ---------------------------------------------------------------------------
       
   443 //
       
   444 MCCPConferenceCall* CVccDirector::NewConferenceL(
       
   445         const TUint32 aServiceId,
       
   446         const MCCPConferenceCallObserver& aObserver )
       
   447     {
       
   448     RUBY_DEBUG_BLOCKL( "CVccDirector::NewConferenceL" );
       
   449     
       
   450     if ( !iConference )
       
   451         {
       
   452         iConference = CVccConferenceCall::NewL( aServiceId, aObserver, iPerfArray );
       
   453         }
       
   454     else
       
   455         {
       
   456         iConference->AddObserverL( aObserver );
       
   457         }
       
   458 
       
   459     iHoTrigger->HoNotAllowedL();
       
   460     return iConference;
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // CVccDirector::Caps
       
   465 // ---------------------------------------------------------------------------
       
   466 //
       
   467 TUint32 CVccDirector::Caps() const
       
   468     {
       
   469     RUBY_DEBUG_BLOCK( "CVccDirector::Caps()" );
       
   470     return 0;
       
   471     }
       
   472 
       
   473 // ---------------------------------------------------------------------------
       
   474 // CVccDirector::DTMFProvider
       
   475 // ---------------------------------------------------------------------------
       
   476 //
       
   477 MCCPDTMFProvider* CVccDirector::DTMFProviderL(
       
   478                                            const MCCPDTMFObserver& aObserver )
       
   479     {
       
   480     RUBY_DEBUG_BLOCKL( "CVccDirector::DTMFProviderL" );
       
   481     if( !iDtmfProvider )
       
   482         {
       
   483         iDtmfProvider = CVccDtmfProvider::NewL( iProviders, aObserver, *this );
       
   484         }
       
   485     return iDtmfProvider; 
       
   486     }
       
   487 
       
   488 
       
   489 // ---------------------------------------------------------------------------
       
   490 // CVccDirector::ExtensionProvider
       
   491 // ---------------------------------------------------------------------------
       
   492 //
       
   493 MCCPExtensionProvider* CVccDirector::ExtensionProviderL(
       
   494                                 const MCCPExtensionObserver& /*aObserver*/ )
       
   495     {
       
   496     RUBY_DEBUG_BLOCKL( "CVccDirector::ExtensionProviderL" );
       
   497     return NULL;
       
   498     }
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 // CVccDirector::AddObserverL
       
   502 // ---------------------------------------------------------------------------
       
   503 //
       
   504 void CVccDirector::AddObserverL( const MCCPDTMFObserver& aObserver )
       
   505     {
       
   506     RUBY_DEBUG_BLOCKL( "CVccDirector::AddObserverL" );
       
   507     if(iDtmfProvider)
       
   508         {
       
   509         iDtmfProvider->AddObserverL(aObserver);
       
   510         }
       
   511     }
       
   512 
       
   513 // ---------------------------------------------------------------------------
       
   514 // CVccDirector::RemoveObserver
       
   515 // ---------------------------------------------------------------------------
       
   516 //
       
   517 TInt CVccDirector::RemoveObserver( const MCCPDTMFObserver& aObserver )
       
   518     {
       
   519     RUBY_DEBUG_BLOCK( "CVccDirector::RemoveObserver" );
       
   520     if(iDtmfProvider)
       
   521         {
       
   522         return iDtmfProvider->RemoveObserver(aObserver);
       
   523         }
       
   524     return KErrNotFound;
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------------------------
       
   528 // CVccDirector::GetLifeTime
       
   529 // ---------------------------------------------------------------------------
       
   530 //
       
   531 TBool CVccDirector::GetLifeTime( TDes8& aLifeTimeInfo )
       
   532     {
       
   533     for( TInt i = 0; i < iProviders.Count(); i++ )
       
   534         {
       
   535         if( iProviders[ i ]->GetLifeTime( aLifeTimeInfo ) )
       
   536             {
       
   537             return ETrue;
       
   538             }
       
   539         }
       
   540     return EFalse;
       
   541     }
       
   542     
       
   543 // ---------------------------------------------------------------------------
       
   544 // CVccDirector::GetCSInfo
       
   545 // ---------------------------------------------------------------------------
       
   546 //
       
   547 TBool CVccDirector::GetCSInfo( CSInfo& aCSInfo )
       
   548     {
       
   549     RUBY_DEBUG_BLOCK( "CVccDirector::GetCSInfo" );
       
   550     for( TInt i = 0; i < iProviders.Count(); i++ )
       
   551         {
       
   552         if( iProviders[ i ]->GetCSInfo( aCSInfo ) )
       
   553             {
       
   554             return ETrue;
       
   555             }
       
   556         }
       
   557     return EFalse;
       
   558     }
       
   559 
       
   560 // ---------------------------------------------------------------------------
       
   561 // CVccDirector::CPPObserver()
       
   562 // ---------------------------------------------------------------------------
       
   563 //
       
   564 const MCCPCSObserver* CVccDirector::CPPObserver() const
       
   565     {
       
   566     RUBY_DEBUG_BLOCK( "CVccDirector::CPPObserver" );
       
   567     return iCCPObserver;
       
   568     }
       
   569 
       
   570 // ---------------------------------------------------------------------------
       
   571 // CVccDirector::ErrorOccurred
       
   572 // ---------------------------------------------------------------------------
       
   573 //
       
   574 void CVccDirector::ErrorOccurred( const TCCPError /*aError*/ )
       
   575     {
       
   576     RUBY_DEBUG_BLOCK( "CVccDirector::ErrorOccurred" );
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // CVccDirector::IncomingCall
       
   581 // Transfer call
       
   582 // ---------------------------------------------------------------------------
       
   583 //
       
   584 void CVccDirector::IncomingCall( MCCPCall* /*aCall*/, MCCPCall& /*aTempCall*/ )
       
   585     {
       
   586     RUBY_DEBUG_BLOCK( "CVccDirector::IncomingCall" );
       
   587     }
       
   588 
       
   589 // ---------------------------------------------------------------------------
       
   590 // CVccDirector::IncomingCall
       
   591 // 
       
   592 // ---------------------------------------------------------------------------
       
   593 //
       
   594 void CVccDirector::IncomingCall( MCCPCall* aCall )
       
   595     {
       
   596     TRAP_IGNORE( IncomingCallL( aCall ) );
       
   597     }
       
   598 
       
   599 // ---------------------------------------------------------------------------
       
   600 // CVccDirector::IncomingCallL
       
   601 // 
       
   602 // ---------------------------------------------------------------------------
       
   603 //
       
   604 void CVccDirector::IncomingCallL( MCCPCall* aCall )
       
   605     {
       
   606     RUBY_DEBUG_BLOCK( "CVccDirector::IncomingCallL" );
       
   607 
       
   608     RUBY_DEBUG1( "CVccDirector::IncomingCallL - array count: %d", iPerfArray.Count() );
       
   609     TBool csOriginated = EFalse;
       
   610     if( aCall->Parameters().CallType() == CCPCall::ECallTypeCSVoice )
       
   611         {
       
   612         RUBY_DEBUG0("incoming CS Call");
       
   613         iHoTrigger->SetCurrentDomainType( CVccHoTrigger::ECallDomainTypeCS );
       
   614         csOriginated = ETrue;
       
   615         iHoTrigger->ReadHoAllowedWhenCsOriginatedSettingL();
       
   616         
       
   617         }
       
   618     
       
   619     else
       
   620         {
       
   621         RUBY_DEBUG0("incoming PS Call");
       
   622         iHoTrigger->SetCurrentDomainType( CVccHoTrigger::ECallDomainTypePS );
       
   623         }
       
   624     
       
   625     //Create 1 performer for each call
       
   626     
       
   627     CVccPerformer* perf = CVccPerformer::NewL( iProviders, 
       
   628                                                iStateInit, 
       
   629                                                *iHoTrigger,
       
   630                                                csOriginated );
       
   631     CleanupStack::PushL( perf );
       
   632     User::LeaveIfError( iPerfArray.Append( perf ) );
       
   633 	CleanupStack::Pop( perf ); //perf
       
   634     perf->IncomingCall( aCall );
       
   635  	iCCPObserver->IncomingCall( perf );
       
   636     }
       
   637 
       
   638 // ---------------------------------------------------------------------------
       
   639 // CVccDirector::CallCreated
       
   640 // ---------------------------------------------------------------------------
       
   641 //
       
   642 void CVccDirector::CallCreated( MCCPCall* /*aNewTransferCall*/,
       
   643                               MCCPCall* /*aOriginator*/,
       
   644                               TBool /*aAttented*/ )
       
   645     {
       
   646     RUBY_DEBUG_BLOCK( "CVccDirector::CallCreated" );
       
   647     }
       
   648 
       
   649 // ---------------------------------------------------------------------------
       
   650 // CVccDirector::DataPortName
       
   651 // ---------------------------------------------------------------------------
       
   652 //
       
   653 void CVccDirector::DataPortName( TName& aPortName )
       
   654     {
       
   655     RUBY_DEBUG_BLOCK( "CVccDirector::DataPortName" );
       
   656     iCCPObserver->DataPortName( aPortName );
       
   657     }
       
   658 
       
   659 // -----------------------------------------------------------------------------
       
   660 //  Gets called when PS key is changed
       
   661 // -----------------------------------------------------------------------------
       
   662 //
       
   663 void CVccDirector::PropertyChangedL( const TUid /*aCategoryId*/, 
       
   664                                     const TUint aKeyId,
       
   665                                     const TInt aValue )	
       
   666     {
       
   667     RUBY_DEBUG_BLOCKL( "CVccDirector::PropertyChangedL" );
       
   668     // Go through the performer array to see which call is in active state.
       
   669     // HO is done for the active call. Other calls are dropped.
       
   670     if (aKeyId == KVccPropKeyHoRequest && 
       
   671     	( aValue == EVccManualStartCsToPsHoRequest ||
       
   672     	  aValue == EVccAutomaticStartCsToPsHoRequest ||
       
   673           aValue == EVccManualStartPsToCsHoRequest ||
       
   674           aValue == EVccAutomaticStartPsToCsHoRequest ||
       
   675           aValue == EVccAutomaticStartPsToCsHoRequestIfSingleCall ||
       
   676           aValue == EVccAutomaticStartCsToPsHoRequestIfSingleCall ) )
       
   677 		{
       
   678 			// If manual handover is initiated during active call, automatic 
       
   679 			// handovers are no longer done during the ongoing call
       
   680 			// ==> stopping HoTrigger
       
   681 			if ( aValue == EVccManualStartCsToPsHoRequest || 
       
   682              	aValue == EVccManualStartPsToCsHoRequest )
       
   683 				{
       
   684 				iHoTrigger->ManualHoCallStarted();
       
   685 				}
       
   686 		//Check state of call and handover when possible
       
   687         SwitchL( aValue );
       
   688 		
       
   689 	    }//if
       
   690 		
       
   691 	else if (aKeyId == KVccPropKeyHoStatus)
       
   692 		{
       
   693 		RUBY_DEBUG0( "CVccDirector::PropertyChangedL -- no handover" );
       
   694 		iHoKeyValue = KErrNotFound;	
       
   695 		}//else-if
       
   696 
       
   697     }
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // Callback function for service settings table observer.
       
   701 // Service provider settings table was changed.  
       
   702 // Only VCC service changes are notified
       
   703 // -----------------------------------------------------------------------------
       
   704 //
       
   705 void CVccDirector::HandleNotifyChange( TServiceId /*aServiceId*/ )
       
   706     {
       
   707     RUBY_DEBUG_BLOCK( "CVccDirector::HandleNotifyChange" );
       
   708     
       
   709     if( !IsPluginInitialized())
       
   710     	RetryInitialization();
       
   711     }
       
   712 
       
   713 // -----------------------------------------------------------------------------
       
   714 // HandleError event recieved from service provider settings table observer
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 void CVccDirector::HandleError( TInt /*aError*/ )
       
   718    {
       
   719    RUBY_DEBUG_BLOCK( "CVccDirector::HandleError" );
       
   720    }
       
   721 
       
   722 // -----------------------------------------------------------------------------
       
   723 // Get call type of the call and return it.
       
   724 // -----------------------------------------------------------------------------
       
   725 //
       
   726 TInt CVccDirector::CurrentCallTypeForDTMF()
       
   727     {
       
   728     RUBY_DEBUG_BLOCK( "CVccDirector::CurrentCallTypeForDTMF" );
       
   729     TInt ret = KErrNotFound;
       
   730     
       
   731     for( TInt i = 0; i < iPerfArray.Count(); i++ )
       
   732         {
       
   733         if( iPerfArray[i]->PrimaryCall()->State() == 
       
   734             MCCPCallObserver::ECCPStateDialling ||
       
   735             iPerfArray[i]->PrimaryCall()->State() == 
       
   736             MCCPCallObserver::ECCPStateConnecting ||
       
   737             iPerfArray[i]->PrimaryCall()->State() == 
       
   738             MCCPCallObserver::ECCPStateConnected )
       
   739             {
       
   740             ret = (TInt) iPerfArray[i]->PrimaryCall()->Parameters().CallType();
       
   741             break;
       
   742             }
       
   743         }
       
   744     return ret;
       
   745     }
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // Get call type of the call and and fetch that call provider and
       
   749 // return it.
       
   750 // -----------------------------------------------------------------------------
       
   751 //
       
   752 CConvergedCallProvider* CVccDirector::GetProvider()
       
   753     {
       
   754     CConvergedCallProvider* ret = NULL;
       
   755     
       
   756     //if no performers in array, all calls have been disconnected
       
   757     //and current call must be emergency call -> return CS provider
       
   758     if( iPerfArray.Count() > 0 )
       
   759         {
       
   760         for( TInt i = 0; i < iPerfArray.Count(); i++ )
       
   761             {
       
   762             if( iPerfArray[i]->PrimaryCall()->State() == 
       
   763                 MCCPCallObserver::ECCPStateDialling ||
       
   764                 iPerfArray[i]->PrimaryCall()->State() == 
       
   765                 MCCPCallObserver::ECCPStateConnecting ||
       
   766                 iPerfArray[i]->PrimaryCall()->State() == 
       
   767                 MCCPCallObserver::ECCPStateConnected )
       
   768                 {
       
   769                 if( iPerfArray[ i ]->PrimaryCall()->Parameters().CallType() == 
       
   770                                                CCPCall::ECallTypePS )
       
   771                     {
       
   772                     ret = &iPerfArray[i]->PsProvider();
       
   773                     break;
       
   774                     }
       
   775                 else
       
   776                     {
       
   777                     ret = &iPerfArray[i]->CsProvider();
       
   778                     break;
       
   779                     }
       
   780                 }
       
   781             }
       
   782         }
       
   783     else
       
   784         {
       
   785         for( TInt i = 0; i < iProviders.Count(); i++ )
       
   786             {
       
   787             TUid pluginUid = iProviders[ i ]->Uid();
       
   788             if( pluginUid.iUid == KCSCallProviderPlugId )
       
   789                 {
       
   790                 ret = iProviders[ i ];
       
   791                 }
       
   792             }
       
   793         }
       
   794     return ret;
       
   795     }
       
   796 
       
   797 // -----------------------------------------------------------------------------
       
   798 //  Checks state of calls and acts accordingly
       
   799 //  Anything else except Waiting or connected - hangup
       
   800 //  Waiting - reject
       
   801 //  Connected - handover
       
   802 // -----------------------------------------------------------------------------
       
   803 //
       
   804 void CVccDirector::SwitchL( const TInt aValue )
       
   805     {
       
   806     RUBY_DEBUG_BLOCKL( "CVccDirector::SwitchL" );
       
   807     //if there is only 1 performer in the array it means that handover can be
       
   808     //made with that performer. If there are more performers it meas that it
       
   809     //is multicall situation and non-active calls need to be released before
       
   810     //handover.
       
   811     //This function is called as many times as there are performers. See 
       
   812     //ReleaseCall!
       
   813     if (iPerfArray.Count() > 1 )
       
   814         {
       
   815         if( aValue == EVccAutomaticStartCsToPsHoRequestIfSingleCall || 
       
   816             aValue == EVccAutomaticStartPsToCsHoRequestIfSingleCall )
       
   817             {
       
   818             return;
       
   819             }
       
   820         //Check that the connected call is capable to make handover (ie. it is
       
   821         //PS call and the direction of HO is PS to CS and vica verse).
       
   822 	    for( TInt i = 0; i < iPerfArray.Count(); i++ )
       
   823 	    	{
       
   824 	    	//call is connected
       
   825 	    	if( iPerfArray[i]->PrimaryCall()->State() == MCCPCallObserver::ECCPStateConnected )
       
   826 	    		{
       
   827 	    		//cs call and the direction is ps to cs. no ho, return
       
   828 	    		if( iPerfArray[i]->PrimaryCall()->Parameters().CallType() ==
       
   829 	    		        CCPCall::ECallTypeCSVoice &&
       
   830 	    		        ( aValue == EVccManualStartPsToCsHoRequest 
       
   831 	    				|| aValue == EVccAutomaticStartPsToCsHoRequest ) )
       
   832 	    			{
       
   833 	    			iHoKeyValue = KErrNotFound;
       
   834 	    			return;
       
   835 	    			}
       
   836 	    		//ps call and the direction is cs to ps. no ho, return
       
   837 	    		else if( iPerfArray[i]->PrimaryCall()->Parameters().CallType() ==
       
   838 	    		        CCPCall::ECallTypePS && 
       
   839 						( aValue == EVccManualStartCsToPsHoRequest 
       
   840 	    				|| aValue == EVccAutomaticStartCsToPsHoRequest ) )
       
   841 	    			{
       
   842 	    			iHoKeyValue = KErrNotFound;
       
   843 	    			return;
       
   844 	    			}
       
   845 	    		}
       
   846 	    	}
       
   847 	    //It is now ok to hangup/reject non-active calls and make handover.
       
   848         for( TInt i = 0; i < iPerfArray.Count(); i++)
       
   849             {
       
   850             if ( (iPerfArray[i]->PrimaryCall()->State() == MCCPCallObserver::ECCPStateRinging) ||
       
   851                   iPerfArray[i]->PrimaryCall()->State() == MCCPCallObserver::ECCPStateConnecting   )
       
   852                 {
       
   853                 RUBY_DEBUG0( "CVccDirector::SwitchL - Reject");
       
   854                 User::LeaveIfError( iPerfArray[i]->Reject() );
       
   855                 iHoKeyValue = aValue;
       
   856                 break;
       
   857                 }
       
   858             
       
   859             else if (iPerfArray[i]->PrimaryCall()->State() != MCCPCallObserver::ECCPStateConnected)
       
   860                 {
       
   861                 RUBY_DEBUG0( "CVccDirector::SwitchL - Hangup");
       
   862                 User::LeaveIfError( iPerfArray[i]->HangUp() );
       
   863                 iHoKeyValue = aValue;
       
   864                 break;
       
   865                 }
       
   866             } //for             
       
   867         } //if
       
   868     else
       
   869         {
       
   870         iPerfArray[0]->SwitchL(aValue);
       
   871         iHoKeyValue = KErrNotFound;
       
   872 
       
   873         }//else
       
   874     }
       
   875 
       
   876 // -----------------------------------------------------------------------------
       
   877 // Checks are the plugins vcc uses initialised
       
   878 // -----------------------------------------------------------------------------
       
   879 //
       
   880 TBool CVccDirector::IsPluginInitialized()
       
   881 	{
       
   882 	RUBY_DEBUG_BLOCK( "CVccDirector::IsPluginInitialized" );
       
   883 	
       
   884 	if( iProviders.Count() == 0 )
       
   885 		return EFalse;
       
   886 		
       
   887 	TBool initialised = ETrue;
       
   888 	for( TInt i = 0; i < iProviders.Count() ; i++)
       
   889 		{
       
   890 		TUid pluginUid = iProviders[ i ]->Uid();
       
   891 		
       
   892 		TInt found = iInitialisedPlugins.Find( pluginUid.iUid );
       
   893 		if( found == KErrNotFound )	
       
   894 			{
       
   895 			initialised = EFalse;
       
   896 			break;
       
   897 			}
       
   898 		}
       
   899 	
       
   900 	RUBY_DEBUG1( "-- IsPluginInitialised:%d", initialised );
       
   901 	return initialised;
       
   902 	}
       
   903 
       
   904 // -----------------------------------------------------------------------------
       
   905 // Starts settings provider table observer.
       
   906 // Director is notified about the change in VCC settings. 
       
   907 // -----------------------------------------------------------------------------
       
   908 //
       
   909 void CVccDirector::StartSpNotifierL()
       
   910 	{
       
   911 	RUBY_DEBUG_BLOCKL( "CVccDirector::StartSpNotifierL" );
       
   912 	__ASSERT_DEBUG(iSpNotifier, User::Leave( KErrNotFound ));
       
   913 	
       
   914 
       
   915 	RIdArray array;
       
   916 	CleanupClosePushL( array );
       
   917 
       
   918 	
       
   919 	iSpNotifier->NotifyChangeL( array );
       
   920 	
       
   921 	CleanupStack::PopAndDestroy( &array );
       
   922 	}
       
   923 
       
   924 // -----------------------------------------------------------------------------
       
   925 // Stops settings provider table observer.
       
   926 // -----------------------------------------------------------------------------
       
   927 //
       
   928 void CVccDirector::StopSpNotifierL()
       
   929 	{
       
   930 	RUBY_DEBUG_BLOCK( "CVccDirector::StopSpNotifierL" );
       
   931 	__ASSERT_DEBUG( iSpNotifier, User::Leave( KErrNotFound ) );
       
   932 	iSpNotifier->NotifyChangeCancel();
       
   933 	}
       
   934 
       
   935 // -----------------------------------------------------------------------------
       
   936 // Tries to initialize the call provider plugins that were not 
       
   937 // initialized the first time because of missing settings.
       
   938 // -----------------------------------------------------------------------------
       
   939 //
       
   940 void CVccDirector::RetryInitialization()
       
   941 	{
       
   942 	RUBY_DEBUG_BLOCK( "CVccDirector::ReTryInitializationL" );
       
   943 	Initialize( *this, *iCCPSsObserver );
       
   944 	}
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // 
       
   948 // -----------------------------------------------------------------------------
       
   949 //
       
   950 void CVccDirector::MoCallCreated( MCCPCall& aCall )
       
   951     {
       
   952     RUBY_DEBUG_BLOCK( "CVccDirector::MoCallCreated" );
       
   953     
       
   954     RUBY_DEBUG1( "CVccDirector::MoCallCreated - array count: %d", iPerfArray.Count() );
       
   955     TBool csOriginated = EFalse;
       
   956     if( aCall.Parameters().CallType() == CCPCall::ECallTypeCSVoice )
       
   957         {
       
   958         csOriginated = ETrue;
       
   959         iHoTrigger->ReadHoAllowedWhenCsOriginatedSettingL();
       
   960             
       
   961         }
       
   962     //Create 1 performer for each call
       
   963         
       
   964     CVccPerformer* perf = CVccPerformer::NewL( iProviders, 
       
   965                                                iStateInit, 
       
   966                                                *iHoTrigger,
       
   967                                                csOriginated );
       
   968     CleanupStack::PushL( perf );
       
   969     User::LeaveIfError( iPerfArray.Append( perf ) );
       
   970     CleanupStack::Pop( perf ); //perf
       
   971     perf->MoCall( &aCall );
       
   972     iCCPObserver->MoCallCreated( *perf );
       
   973     }
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // 
       
   977 // -----------------------------------------------------------------------------
       
   978 //
       
   979 void CVccDirector::ConferenceCallCreated( MCCPConferenceCall& aConferenceCall )
       
   980     {
       
   981     RUBY_DEBUG_BLOCK( "CVccDirector::ConferenceCallCreated" );
       
   982     if ( !iConference )
       
   983         {
       
   984         TInt err( KErrNone );
       
   985         TRAP( err, CreateConferenceL( aConferenceCall ) );
       
   986         if( KErrNone == err )
       
   987            {
       
   988            TRAP_IGNORE( iHoTrigger->HoNotAllowedL() );
       
   989            iCCPObserver->ConferenceCallCreated( *iConference );  
       
   990            }
       
   991         else
       
   992            {
       
   993            RUBY_DEBUG1( "CVccDirector::Conference call creation failed - error: %d", err );
       
   994            }
       
   995         }
       
   996     }
       
   997 
       
   998 // -----------------------------------------------------------------------------
       
   999 // CVccDirector::CreateConferenceL
       
  1000 //
       
  1001 // -----------------------------------------------------------------------------
       
  1002 //
       
  1003 void CVccDirector::CreateConferenceL( MCCPConferenceCall& aConferenceCall )
       
  1004     {
       
  1005     RUBY_DEBUG_BLOCK( "CVccDirector::CreateConferenceL" );
       
  1006     iConference = CVccConferenceCall::NewL( aConferenceCall, iPerfArray );
       
  1007     aConferenceCall.AddObserverL( *iConference );
       
  1008     }