--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/convergedcallengine/cce/src/ccceplugin.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,680 @@
+/*
+* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Handles plugin
+*
+*/
+
+
+// INCLUDE FILES
+#include <badesca.h>
+#include "ccceplugin.h"
+#include "cconvergedcallprovider.h"
+#include "cccelogger.h"
+#include "cccecallcontainer.h"
+#include "cccetransfercontroller.h"
+#include "mccpcall.h"
+#include "mccpcscall.h"
+#include "mcceobserver.h"
+#include "cccecall.h"
+#include "mccecallobserver.h"
+#include "ccceconferencecall.h"
+
+#include "mccpplugindeathobserver.h"
+#include "mccpssobserver.h"
+#include "mccessobserver.h"
+#include "mccptransferprovider.h"
+#include "tccecallindex.h"
+
+#include <featmgr.h>
+#include "mccpdtmfprovider.h"
+
+
+
+// ======== MEMBER FUNCTIONS ========
+// -----------------------------------------------------------------------------
+// NewL()
+// -----------------------------------------------------------------------------
+//
+CCCEPlugin* CCCEPlugin::NewL( const TUid& aPluginUID,
+ MCCEObserver& aObserver,
+ CCCECallContainer& aCallContainer,
+ MCCPPluginDeathObserver& aDeathObserver,
+ CCCETransferController& aTransferController )
+ {
+ CCCEPlugin* self = new (ELeave) CCCEPlugin( aPluginUID,
+ aObserver,
+ aCallContainer,
+ aDeathObserver,
+ aTransferController );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCCEPluginManager()
+// -----------------------------------------------------------------------------
+//
+CCCEPlugin::CCCEPlugin( const TUid& aPluginUID,
+ MCCEObserver& aObserver,
+ CCCECallContainer& aCallContainer,
+ MCCPPluginDeathObserver& aDeathObserver,
+ CCCETransferController& aTransferController )
+ : iObserver( aObserver ),
+ iCallContainer( aCallContainer ),
+ iTransferController( aTransferController ),
+ iDeathObserver( aDeathObserver ),
+ iPluginId( aPluginUID ),
+ iReleaseWhenIdle( ETrue )
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CCCEPlugin::ConstructL()
+ {
+ FeatureManager::InitializeLibL();
+
+ iPlugin = CConvergedCallProvider::NewL( iPluginId );
+
+ if(iPlugin)
+ {
+ CCELOGSTRING("CCCEPlugin::GetPluginL: Initialize" );
+ iPlugin->InitializeL( *this, *this );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ~CCCEPluginManager()
+// -----------------------------------------------------------------------------
+//
+CCCEPlugin::~CCCEPlugin()
+ {
+ delete iPlugin;
+ FeatureManager::UnInitializeLib();
+ }
+
+// -----------------------------------------------------------------------------
+// Dtmf
+// -----------------------------------------------------------------------------
+//
+MCCPDTMFProvider& CCCEPlugin::GetDtmfProviderL(
+ const MCCPDTMFObserver& aObserver )
+ {
+ if( !iDtmfProvider )
+ {
+ iDtmfProvider = iPlugin->DTMFProviderL( aObserver );
+
+ if( !iDtmfProvider )
+ {
+ CCELOGSTRING("CCCEPlugin::GetDtmfProviderL: Plugin does not support dtmf, leaving with KErrNotSupported" );
+ // maybe api should be changed to leave with error code instead of returning null
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+ return *iDtmfProvider;
+ }
+
+// -----------------------------------------------------------------------------
+// Return protocol interface object of wanted type.
+// -----------------------------------------------------------------------------
+//
+CConvergedCallProvider* CCCEPlugin::GetPluginL() const
+ {
+ return iPlugin;
+ }
+
+// -----------------------------------------------------------------------------
+// Primary emergency call objects are created construct time
+// -----------------------------------------------------------------------------
+//
+void CCCEPlugin::InitialiseEmergencyCallL(MCCPCallObserver& aEmergencyCallObserver)
+ {
+ iEmergencyCall =
+ iPlugin->NewEmergencyCallL( 0, KNullDesC, aEmergencyCallObserver );
+ }
+
+// -----------------------------------------------------------------------------
+// Get emergency call handle.
+// -----------------------------------------------------------------------------
+//
+MCCPEmergencyCall* CCCEPlugin::GetEmergencyCall() const
+ {
+ return iEmergencyCall;
+ }
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::Type()
+// ---------------------------------------------------------------------------
+//
+TUid CCCEPlugin::Type() const
+ {
+ return iPluginId;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns ETrue if plugin can be relesed if idle
+// ---------------------------------------------------------------------------
+//
+TBool CCCEPlugin::ReleaseWhenIdle()
+ {
+ return iReleaseWhenIdle;
+ }
+
+// ---------------------------------------------------------------------------
+// Set ETrue if plugin should stay permanently in memory
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::SetReleaseWhenIdle(TBool aReleaseWhenIdle )
+ {
+ iReleaseWhenIdle = aReleaseWhenIdle;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPCSObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::MoCallCreated( MCCPCall& aCall )
+ {
+ CCELOGSTRING("CCCEPlugin::MoCallCreated" );
+
+ TBool callAllowed = EFalse;
+
+ //CCELOGSTRING2(" cceparams->iCallType = %d", aCall->Parameters().CallType() );
+
+ callAllowed = ( IsCallAllowed() >= 0 );
+
+
+ CCCECall* call = NULL;
+ if( callAllowed )
+ {
+ call = iCallContainer.GetNextFreeCall();
+ }
+
+ if( call )
+ {
+ TRAPD( error,
+ call->SetConvergedCallL( &aCall, iPluginId ) );
+
+ // set observer for the passed call
+ TRAP_IGNORE( aCall.AddObserverL(*call) );
+
+ // Error handling
+ if( error )
+ {
+ CCELOGSTRING(
+ "CCCEPlugin::MoCallCreated:Canceled" );
+ aCall.Cancel();
+ call->Release();
+ }
+ else
+ {
+ CCELOGSTRING(
+ "CCCEPlugin::MoCallCreated:Forwarded" );
+ // Sets new call index. Normally the call itself
+ // sets the value, but in the case when external client has
+ // created the call we need to set it here, because
+ // the call is already ongoing.
+ call->SetNewCallIndex();
+ iObserver.MOCallCreated( *call );
+ }
+
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::MoCallCreated:Error, CCECall not found" );
+ aCall.Cancel();
+ iCallContainer.ReleaseCall( aCall, iPluginId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPCSObserver
+// CCCEPlugin::DataPortName()
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::DataPortName( TName& aPortName )
+ {
+ CCELOGSTRING( "CCCEPlugin::DataPortName" );
+ iObserver.DataPortName( aPortName );
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPCSObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::ConferenceCallCreated( MCCPConferenceCall& aConferenceCall )
+ {
+ CCELOGSTRING("CCCEPlugin::ConferenceCallCreated IN" );
+ if( !iCallContainer.ConferenceCall().SetOngoingConferenceCall(
+ aConferenceCall, iPluginId ) )
+ {
+ iObserver.ConferenceCallCreated( iCallContainer.ConferenceCall() );
+ }
+ else
+ {
+ iPlugin->ReleaseConferenceCall( aConferenceCall );
+ }
+
+ CCELOGSTRING("CCCEPlugin::ConferenceCallCreated OUT" );
+ }
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::IsCallAllowed()
+// ---------------------------------------------------------------------------
+//
+TInt CCCEPlugin::IsCallAllowed() const
+ {
+ CCCECall* call;
+ TInt activeNonConferenceCalls = 0;
+ CCPCall::TCallState callState;
+
+ for( TInt i = 0; i < KCCECallObjects; i++ )
+ {
+ call = iCallContainer.GetCall( i );
+
+ if( call->IsInUse() &&
+ !iCallContainer.ConferenceCall().IsPartOfConference( *call ) )
+ {
+ callState = call->State();
+
+ CCELOGSTRING2( "CCCEPlugin::IsCallAllowed:Active call found: State = %d",
+ callState );
+
+ switch( callState )
+ {
+ case CCPCall::EStateQueued:
+ case CCPCall::EStateRinging:
+ case CCPCall::EStateConnecting:
+ {
+ CCELOGSTRING( "CCCEPlugin::IsCallAllowed: KErrGeneral" );
+ // No other calls allowed
+ }
+ return KErrGeneral;
+ case CCPCall::EStateDialling:
+ {
+ // Dialling -> Cancel it
+ // Telephone UI spec: chapter 3.1.4
+ call->HangUp();
+ }
+ break;
+ case CCPCall::EStateDisconnecting:
+ {
+ // Disconnecting -> do nothing
+ }
+ break;
+ default:
+ {
+ // Active/Hold -> Call can be on waiting state
+ activeNonConferenceCalls++;
+ }
+ break;
+ }
+
+ if( activeNonConferenceCalls >= KCCEMaxNumberOfCalls )
+ {
+ CCELOGSTRING( "CCCEPlugin::IsCallAllowed: KErrOverflow" );
+ return KErrOverflow;
+ }
+
+ }
+ }
+ // In addition to checks made here call should not be allowed
+ // when emergency call is ongoing. This is done in
+ // CCCECallContainer::GetNextFreeCall()
+
+ CCELOGSTRING( "CCCEPlugin::IsCallAllowed: ETrue" );
+ return activeNonConferenceCalls;
+ }
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::IsDataCallAllowed()
+// ---------------------------------------------------------------------------
+//
+TBool CCCEPlugin::IsDataCallAllowed() const
+ {
+ CCELOGSTRING( "CCCEPlugin::IsDataCallAllowed()" );
+ CCCECall* call = NULL;
+ TInt callCount = 0;
+ CCPCall::TCallState callState;
+ for( TInt i = 0; i < KCCECallObjects; i++ )
+ {
+ call = iCallContainer.GetCall( i );
+ callState = call->State();
+ if( CCPCall::EStateIdle != callState &&
+ !iCallContainer.ConferenceCall().IsPartOfConference( *call ) )
+ {
+ callCount++;
+ }
+ }
+
+ if( iCallContainer.ConferenceCall().State() !=
+ MCCEConferenceCallObserver::ECCEConferenceIdle )
+ {
+ callCount++;
+ }
+
+ // In addition to checks made here call should not be allowed
+ // when emergency call is ongoing. This is done in
+ // CCCECallContainer::GetNextFreeCall()
+
+ CCELOGSTRING2( "CCCEPlugin::IsDataCallAllowed() callCount=%d", callCount );
+ // Data call cannot be allowed if there is three or more calls ongoing
+ return ( callCount < KCCEMaxNumberOfCalls );
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::ErrorOccurred( const TCCPError aError )
+ {
+ CCELOGSTRING2("CCCEPlugin::ErrorOccurred: Error = %d", aError );
+
+ switch (aError)
+ {
+ case ECCPIncomingCallFailed:
+ {
+ if( iReleaseWhenIdle )
+ {
+ iDeathObserver.CCPPluginInitialisationFailed(iPluginId, aError);
+ }
+ }
+ break;
+ case ECCPRegistrationFailed:
+ {
+ iDeathObserver.CCPPluginInitialisationFailed(iPluginId, aError);
+ }
+ break;
+ default:
+ {
+ CCELOGSTRING("CCCEPlugin::ErrorOccurred: Default");
+ }
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::IncomingCall( MCCPCall* aCall, MCCPCall& aTempCall )
+ {
+ CCELOGSTRING("CCCEPlugin::IncomingCall():IN");
+ CCELOGSTRING3(" originalcall: aTempCall=0x%x transfercall: aCall=0x%x", &aTempCall, aCall );
+
+ if( !aCall || aCall == &aTempCall )
+ {
+ CCELOGSTRING("CCCEPlugin::IncomingCall(MCCPCall*,MCCPCall&) - Error: Invalid parameters!");
+ return;
+ }
+
+ iTransferController.TransferCallIncoming( aCall, &aTempCall );
+ CCELOGSTRING("CCCEPlugin::IncomingCall():OUT");
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::IncomingCall( MCCPCall* aCall )
+ {
+ CCELOGSTRING( "CCCEPlugin::IncomingCall" );
+
+ if( !aCall )
+ {
+ CCELOGSTRING("CCCEPlugin::IncomingCall(MCCPCall*) - Error: incoming call pointer was null!");
+ return;
+ }
+
+ CCCECall* call = NULL;
+ TInt nonConferenceCalls = IsCallAllowed();
+
+ if( nonConferenceCalls >= 0 )
+ {
+ call = iCallContainer.GetNextFreeCall();
+ }
+
+ if( call )
+ {
+ TRAPD( error,
+ call->SetConvergedCallL( aCall, iPluginId ) );
+
+ // Order call to ringing state
+ // Requires no active calls and conference call must be idle
+ if( nonConferenceCalls == 0 &&
+ iCallContainer.ConferenceCall().State() ==
+ MCCEConferenceCallObserver::ECCEConferenceIdle )
+ {
+ CCELOGSTRING( "CCCEPlugin::IncomingCall:No active calls" );
+ error = aCall->Ringing();
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::IncomingCall:One active call" );
+ error = aCall->Queue();
+ }
+
+ // Error handling
+ if( error )
+ {
+ CCELOGSTRING2( "CCCEPlugin::IncomingCall: Error = %d", error );
+ aCall->Reject();
+ call->Release();
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::IncomingCall:No errors occurred-> inform phoneengine" );
+ iObserver.IncomingCall( *call );
+ }
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::IncomingCall:Error, CCECall not found" );
+ aCall->Reject();
+ iCallContainer.ReleaseCall( *aCall, iPluginId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MCCPObserver
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::CallCreated( MCCPCall* aNewTransferCall,
+ MCCPCall* aOriginator,
+ TBool aAttented )
+ {
+ CCELOGSTRING2("CCCEPlugin::CallCreated():IN aAttended=%d",aAttented);
+ CCELOGSTRING3(" TransferCall: aNewTransferCall=0x%x OriginalCall: aOriginator=0x%x",
+ aNewTransferCall, aOriginator );
+
+ if ( !aNewTransferCall || aNewTransferCall == aOriginator )
+ {
+ CCELOGSTRING("CCCETransferController::HandleTransferRequest() Error: Invalid parameters!");
+ return;
+ }
+
+ if ( aAttented )
+ {
+ iTransferController.HandleRemoteTransferRequest( aNewTransferCall,
+ aOriginator, aAttented );
+ }
+ else
+ {
+ TInt nonConferenceCalls = IsCallAllowed();
+
+ if ( nonConferenceCalls == 0 || nonConferenceCalls == 1 )
+ {
+ iTransferController.HandleRemoteTransferRequest( aNewTransferCall,
+ aOriginator, aAttented );
+ }
+ else
+ {
+ // Reject unattended transfer
+ CCELOGSTRING( "CCCEPlugin::CallCreated(): reject transfer" );
+ CCCECall* originator = iCallContainer.GetCall( aOriginator );
+ TRAP_IGNORE( aOriginator->TransferProviderL(*originator)->AcceptTransfer(EFalse) );
+ iCallContainer.ReleaseCall( *aNewTransferCall );
+ }
+ }
+
+ CCELOGSTRING( "CCCEPlugin::CallCreated():OUT" );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::BarringEventOccurred
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::BarringEventOccurred( const MCCPSsObserver::TCCPSsBarringEvent aBarringEvent )
+ {
+ CCELOGSTRING2("CCCEPlugin::BarringEventOccurred():IN event=%d",aBarringEvent );
+
+ if( iCallContainer.SsObserver() )
+ {
+ // one to one mapping at the moment can be casted directly, change if mapping gets out of sync
+ iCallContainer.SsObserver()->BarringEventOccurred(
+ (MCCESsObserver::TCCESsBarringEvent)aBarringEvent );
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::BarringEventOccurred: Event ignored no observer is set!" );
+ }
+
+ CCELOGSTRING( "CCCEPlugin::BarringEventOccurred:OUT" );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::CLIEventOccurred
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::CLIEventOccurred( const MCCPSsObserver::TCCPSsCLIEvent aCallLineEvent )
+ {
+ CCELOGSTRING2("CCCEPlugin::CLIEventOccurred():IN event=%d",aCallLineEvent );
+
+ if( iCallContainer.SsObserver() )
+ {
+ // one to one mapping at the moment can be casted directly, change if mapping gets out of sync
+ iCallContainer.SsObserver()->CLIEventOccurred(
+ (MCCESsObserver::TCCESsCLIEvent)aCallLineEvent );
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::CLIEventOccurred: Event ignored no observer is set!" );
+ }
+
+ CCELOGSTRING( "CCCEPlugin::CLIEventOccurred:OUT" );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::BarringEventOccurred
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::CallForwardEventOccurred(
+ const MCCPSsObserver::TCCPSsCallForwardEvent aCallForwardEvent,
+ const TDesC& aRemoteAddress )
+ {
+ CCELOGSTRING2("CCCEPlugin::CallForwardEventOccurred():IN event=%d",aCallForwardEvent );
+
+ if( iCallContainer.SsObserver() )
+ {
+ // one to one mapping at the moment can be casted directly, change if mapping gets out of sync
+ iCallContainer.SsObserver()->CallForwardEventOccurred(
+ (MCCESsObserver::TCCESsCallForwardEvent)aCallForwardEvent,
+ aRemoteAddress );
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::CallForwardEventOccurred: Event ignored no observer is set!" );
+ }
+
+ CCELOGSTRING( "CCCEPlugin::CallForwardEventOccurred:OUT" );
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::CallCugEventOccurred
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::CallCugEventOccurred( const MCCPSsObserver::TCCPSsCugEvent aCugEvent )
+ {
+ CCELOGSTRING2("CCCEPlugin::CallCugEventOccurred():IN event=%d",aCugEvent );
+
+ if( iCallContainer.SsObserver() )
+ {
+ // one to one mapping at the moment can be casted directly, change if mapping gets out of sync
+ iCallContainer.SsObserver()->CallCugEventOccurred(
+ (MCCESsObserver::TCCESsCugEvent)aCugEvent );
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::CallCugEventOccurred: Event ignored no observer is set!" );
+ }
+
+ CCELOGSTRING( "CCCEPlugin::CallCugEventOccurred:OUT" );
+ }
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::NotifyCurrentActiveALSLine
+// ---------------------------------------------------------------------------
+//
+void CCCEPlugin::NotifyCurrentActiveALSLine( TInt aLine )
+ {
+ CCELOGSTRING2("CCCEPlugin::NotifyCurrentActiveALSLine():IN line=%d",aLine );
+
+ if( iCallContainer.SsObserver() )
+ {
+ iCallContainer.SsObserver()->NotifyCurrentActiveALSLine(aLine);
+ }
+ else
+ {
+ CCELOGSTRING( "CCCEPlugin::NotifyCurrentActiveALSLine: Event ignored no observer is set!" );
+ }
+
+ CCELOGSTRING( "CCCEPlugin::NotifyCurrentActiveALSLine():OUT" );
+ }
+
+// ---------------------------------------------------------------------------
+// CCCEPlugin::IsCsPlugin
+// ---------------------------------------------------------------------------
+//
+TBool CCCEPlugin::IsCsPlugin( MCCPCall& aCall )
+ {
+ TBool isCsPlugin( EFalse );
+ if ( FeatureManager::FeatureSupported( KFeatureIdFfVoiceCallContinuity ) )
+ {
+ if ( aCall.Parameters().CallType() != CCPCall::ECallTypePS )
+ {
+ isCsPlugin = ETrue;
+ }
+ }
+ else
+ {
+ if( iPluginId == KCSProviderUid )
+ {
+ isCsPlugin = ETrue;
+ }
+ }
+ return isCsPlugin;
+ }
+
+// end of file