diff -r 7d48bed6ce0c -r 987c9837762f convergedcallengine/csplugin/src/cspconferencecall.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convergedcallengine/csplugin/src/cspconferencecall.cpp Wed Sep 01 12:15:03 2010 +0100 @@ -0,0 +1,623 @@ +/* +* Copyright (c) 2007 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: Implements class CSPConferenceCall which provides call functionality +* +*/ + + + +#include +#include +#include + +#include "cspconferencecall.h" +#include "cspvoicecall.h" +#include "cspetelconferencecallrequester.h" +#include "cspetelconferenceeventmonitor.h" +#include "cspetelconferencestatusmonitor.h" +#include "cspetelconferencecapsmonitor.h" +#include "mcspcallinformation.h" +#include "csplogger.h" +#include "csppanic.pan" +#include "cspconsts.h" + + +// --------------------------------------------------------------------------- +// CSPConferenceCall::NewL +// --------------------------------------------------------------------------- +// +CSPConferenceCall* CSPConferenceCall::NewL( + RMobilePhone& aPhone, + MCSPCallInformation& aCallInfo, + TUint32 aServiceId ) + { + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::NewL()"); + + CSPConferenceCall* self = new ( ELeave ) CSPConferenceCall( aPhone, + aCallInfo, aServiceId ); + CleanupStack::PushL( self ); + self->ConstructL( ); + CleanupStack::Pop( self ); + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::NewL() end"); + return self; + } + +// --------------------------------------------------------ß------------------- +// CSPConferenceCall::~CSPConferenceCall +// --------------------------------------------------------------------------- +// +CSPConferenceCall::~CSPConferenceCall() + { + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::~CSPConferenceCall() start"); + iObservers.Close(); + + delete iCallStatusMonitor; + delete iCallEventMonitor; + delete iCallCapsMonitor; + delete iRequester; + iCall.Close(); + + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::~CSPConferenceCall() end"); + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::NotifyEvent +// Conference event forwarding. +// This way Added, Removed and Split events are notified. +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::NotifyEvent( + MCCPConferenceCallObserver::TCCPConferenceCallEvent aEvent, + TName& aCallName ) + { + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::NotifyEvent < %d", aEvent ); + + CSPCall* call = iCallInfo.FindCall( aCallName ); + TInt count = iObservers.Count(); + for ( TInt i = 0; i < count; i++ ) + { + MCCPConferenceCallObserver *obs = iObservers[i]; + if ( obs ) + { + obs->ConferenceCallEventOccurred( aEvent, call ); + } + } + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::NotifyEvent > %d", aEvent ); + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::NotifyEvent +// Conference event forwarding in case of Terminated, Built or Swapped events. +// These events are not call specific. +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::NotifyEvent( + MCCPConferenceCallObserver::TCCPConferenceCallEvent aEvent ) + { + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::NotifyEvent < %d", aEvent ); + + TInt count = iObservers.Count(); + for ( TInt i = 0; i < count; i++ ) + { + MCCPConferenceCallObserver *obs = iObservers[i]; + if ( obs ) + { + obs->ConferenceCallEventOccurred( aEvent, NULL ); + } + } + + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::NotifyEvent > %d", aEvent ); + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::NotifyStateChanged +// Conference state change forwarding +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::NotifyStateChange( + MCSPConferenceStatusObserver::TCSPConferenceState aStatus ) + { + CSPLOGSTRING3( CSPINT, "CSPConferenceCall::NotifyStateChange %d this: %x", aStatus, + this ); + iCallState = static_cast(aStatus); + if ( aStatus == MCSPConferenceStatusObserver::ECSPConferenceIdle ) + { + iCallCountForAddCall = 0; + } + else + { + if ( iCallCountForAddCall == 1 ) + { + iCallCountForAddCall++; + } + } + + TInt count = iObservers.Count(); + for ( TInt i = 0; i < count; i++ ) + { + MCCPConferenceCallObserver *obs = iObservers[i]; + if ( obs ) + { + obs->ConferenceCallStateChanged( + static_cast(aStatus) ); + } + } + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::ConferenceCapsChanged +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::ConferenceCapsChanged( TUint32 aCaps ) + { + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::ConferenceCapsChanged %b", aCaps ); + + TInt count = iObservers.Count(); + for ( TInt i = 0; i < count; i++ ) + { + MCCPConferenceCallObserver *obs = iObservers[i]; + if ( obs ) + { + obs->ConferenceCallCapsChanged( + (MCCPConferenceCallObserver::TCCPConferenceCallCaps) aCaps ); + } + } + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::NotifyConferenceError +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::NotifyConferenceError( TCCPConferenceCallError aErr ) + { + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::NotifyConferenceError < %d", aErr ); + + TInt count = iObservers.Count(); + for ( TInt i = 0; i < count; i++ ) + { + MCCPConferenceCallObserver *obs = iObservers[i]; + if ( obs ) + { + obs->ErrorOccurred( aErr ); + } + } + + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::NotifyConferenceError > %d", aErr ); + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::AddCall +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::AddCallL( MCCPCall* aCall ) + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::AddCallL " ); + + TInt err(KErrNone); + + if ( aCall ) + { + iCallCountForAddCall++; + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::AddCallL calls added %d", + iCallCountForAddCall ); + + if ( iCallCountForAddCall < 2 ) + { + CSPLOGSTRING2( CSPINT, + "CSPConferenceCall::AddCallL DO NOTHING SINCE CALL COUNT IS %d", iCallCountForAddCall ); + } + else if ( iCallCountForAddCall == 2 ) + { + err = iRequester->MakeRequest( + CSPEtelConferenceCallRequester:: + EConferenceRequestTypeCreateConference ); + } + else if ( iCallCountForAddCall > 2 ) + { + CSPLOGSTRING( CSPINT, "CSPConferenceCall::AddCall cast call"); + CSPCall* cspCall = static_cast< CSPCall* > ( aCall ); + + iAddedCallName.Zero(); + cspCall->CallName( iAddedCallName ); + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::AddCall n=%S", &iAddedCallName ); + err = iRequester->MakeAddCallRequest( iAddedCallName ); + CSPLOGSTRING2( CSPINT, + "CSPConferenceCall::AddCallL result %d", err); + } + } + else + { + CSPLOGSTRING( CSPERROR, + "CSPConferenceCall::AddCallL Invalid argument, call NULL" ); + + err = KErrArgument; + } + + CSPLOGSTRING2( CSPINT, "CSPConferenceCall::AddCallL returning %d", err); + + User::LeaveIfError( err ); + + CSPLOGSTRING( CSPINT, "CSPConferenceCall::AddCallL OK" ); + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::RemoveCallL +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::RemoveCallL( MCCPCall* aCall ) + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::RemoveCallL " ); + if ( aCall ) + { + User::LeaveIfError( aCall->HangUp() ); + CSPLOGSTRING( CSPINT, "CSPConferenceCall::RemoveCallL Hangup request sent" ); + } + else + { + CSPLOGSTRING( CSPERROR, "CSPConferenceCall::RemoveCallL Invalid argument" ); + User::Leave( KErrArgument ); + } + + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::RemoveCallL end" ); + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::CallCount +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::CallCount( ) const + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::CallCount" ); + TInt callCount(0); + TInt err = iCall.EnumerateCalls( callCount ); + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::CallCount end" ); + return callCount; + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::GoOneToOneL +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::GoOneToOneL( MCCPCall& aCall ) + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::GoOneToOneL " ); + + if ( aCall.Parameters().CallType() == CCPCall::ECallTypeCSVoice ) + { + CSPVoiceCall& voiceCall = static_cast< CSPVoiceCall& > ( aCall ); + TInt err = voiceCall.GoOneToOne(); + CSPLOGSTRING2( CSPREQIN, "CSPConferenceCall::GoOneToOneL Request %d", + err ); + User::LeaveIfError( err ); + } + else + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::GoOneToOneL ERROR NOT VOICE CALL" ); + User::Leave( KErrNotSupported ); + } + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::GoOneToOneL end" ); + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::ServiceId +// --------------------------------------------------------------------------- +// +TUint32 CSPConferenceCall::ServiceId() const + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::ServiceId " ); + return iServiceId; + } + +// --------------------------------------------------------------------------- +// From class MCCPCall +// CSPConferenceCall::HangUp +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::HangUp() + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::HangUp " ); + TInt err(KErrNone); + + err = iRequester->MakeRequest( + CSPEtelConferenceCallRequester::EConferenceRequestTypeHangup ); + if ( err ) + { + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::HangUp error %d", err ); + } + + return err; + } + +// --------------------------------------------------------------------------- +// From class MCCPCall +// CSPConferenceCall::Hold +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::Hold() + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::Hold call" ); + + TInt err( KErrNone ); + + if ( iCallState == MCCPConferenceCallObserver::ECCPConferenceActive ) + { + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::Hold > RMobileConferenceCall::Hold" ); + + err = iRequester->MakeRequest( + CSPEtelConferenceCallRequester::EConferenceRequestTypeHold ); + if ( err != KErrNone ) + { + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::Hold error: %d", + err ); + } + } + else + { + CSPLOGSTRING2( CSPERROR, + "CSPConferenceCall::Hold : invalid state %d", + iCallState ); + err = KErrNotReady; + } + + + return err; + } + +// --------------------------------------------------------------------------- +// From class MCCPCall +// CSPConferenceCall::Resume +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::Resume() + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::Resume " ); + + TInt err( KErrNone ); + + if ( iCallState == MCCPConferenceCallObserver::ECCPConferenceHold ) + { + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::Resume " ); + err = iRequester->MakeRequest( + CSPEtelConferenceCallRequester::EConferenceRequestTypeResume ); + if ( KErrNone != err ) + { + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::Resume Error %d", + err ); + } + + } + else + { + CSPLOGSTRING2( CSPERROR, + "CSPConferenceCall::Resume : invalid state %d", + iCallState ); + err = KErrNotReady; + } + + return err; + } + +// --------------------------------------------------------------------------- +// From class MCCPCall +// CSPConferenceCall::Swap +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::Swap() + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::Swap " ); + TInt err(KErrNone); + + if ( iCallState == MCCPConferenceCallObserver::ECCPConferenceActive + || iCallState == MCCPConferenceCallObserver::ECCPConferenceHold ) + { + err = iRequester->MakeRequest( + CSPEtelConferenceCallRequester::EConferenceRequestTypeSwap ); + if ( err != KErrNone ) + { + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::Swap Request error: %d", err ); + } + } + else + { + err = KErrNotReady; + CSPLOGSTRING2( CSPERROR, + "CSPConferenceCall::Swap Invalid state %d", + iCallState ); + } + + return err; + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::CurrentCallsToConferenceL +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::CurrentCallsToConferenceL() + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::CurrentCallsToConferenceL " ); + iRequester->MakeRequest( + CSPEtelConferenceCallRequester::EConferenceRequestTypeCreateConference ); + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::CurrentCallsToConferenceL end" ); + } + +// --------------------------------------------------------------------------- +// From class MCCPConferenceCall +// CSPConferenceCall::GetCallArray +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::GetCallArray( RPointerArray& aCallArray ) + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::GetCallArray" ); + // Reset array in case + aCallArray.Reset(); + TInt err( KErrNone ); + + RMobileCall::TMobileCallInfoV3 callInfo; + RMobileCall::TMobileCallInfoV3Pckg callInfoPck( callInfo ); + + TInt callCount = CallCount(); + CSPCall* call; + + // Resolve call objects that are part of the conference + for ( int i = 0; i < callCount; i++ ) + { + err = iCall.GetMobileCallInfo( i, callInfoPck ); + + if ( KErrNone == err ) + { + // Find call by call name + call = iCallInfo.FindCall( callInfo.iCallName); + if ( call ) + { + err = aCallArray.Append( call ); + } + else + { + err = KErrNotFound; + } + } + CSPLOGSTRING2( CSPERROR, "CSPConferenceCall::GetCallArray err: %d", err ); + } + + CSPLOGSTRING( CSPREQOUT, "CSPConferenceCall::GetCallArray end"); + return err; + } + +// --------------------------------------------------------------------------- +// Adds observer. +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::AddObserverL( const MCCPConferenceCallObserver& aObserver ) + { + if ( iObservers.Find( &aObserver ) == KErrNotFound ) + { + iObservers.Append( &aObserver ); + } + } + +// --------------------------------------------------------------------------- +// Removes given observer. +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::RemoveObserver( const MCCPConferenceCallObserver& aObserver ) + { + CSPLOGSTRING( CSPREQIN, "CSPConferenceCall::RemoveObserver " ); + TInt found = iObservers.Find( &aObserver ); + if ( found != KErrNotFound ) + { + iObservers.Remove( found ); + return KErrNone; + } + + return found; + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::GetConferenceCallState +// --------------------------------------------------------------------------- +// +TInt CSPConferenceCall::GetConferenceCallState( + MCCPConferenceCallObserver::TCCPConferenceCallState& aState ) + { + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::GetConferenceCallState()"); + RMobileConferenceCall::TMobileConferenceStatus status; + TInt err = iCall.GetConferenceStatus( status ); + + switch( status ) + { + case RMobileConferenceCall::EConferenceIdle: + { + aState = MCCPConferenceCallObserver::ECCPConferenceIdle; + break; + } + case RMobileConferenceCall::EConferenceActive: + { + aState = MCCPConferenceCallObserver::ECCPConferenceActive; + break; + } + case RMobileConferenceCall::EConferenceHold: + { + aState = MCCPConferenceCallObserver::ECCPConferenceHold; + break; + } + default: + break; + } + + return err; + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::CSPConferenceCall +// --------------------------------------------------------------------------- +// +CSPConferenceCall::CSPConferenceCall( RMobilePhone& aPhone, + MCSPCallInformation& aCallInfo, + TUint32 aServiceId ) : + iPhone( aPhone ), + iRequester( NULL ), + iCallInfo( aCallInfo ), + iServiceId( aServiceId ) + { + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::CSPConferenceCall()"); + } + +// --------------------------------------------------------------------------- +// CSPConferenceCall::ConstructL +// Constructing CSPConferenceCall for MT call. +// --------------------------------------------------------------------------- +// +void CSPConferenceCall::ConstructL( ) + { + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::ConstructL() start"); + User::LeaveIfError( iCall.Open(iPhone) ); + + iCall.EnumerateCalls( iCallCountForAddCall ); + CSPLOGSTRING2(CSPERROR, "CSPConferenceCall::Initialize() Call count : %d", + iCallCountForAddCall ); + + MCCPConferenceCallObserver::TCCPConferenceCallState conferenceState; + TInt err = GetConferenceCallState( conferenceState ); + + if ( KErrNone == err ) + { + iCallState = conferenceState; + CSPLOGSTRING2(CSPINT, "CSPConferenceCall::Initialize() State : %d", iCallState ); + } + else + { + iCallState = MCCPConferenceCallObserver::ECCPConferenceIdle; + CSPLOGSTRING2(CSPERROR, + "CSPConferenceCall::Initialize() state fetching error %d", err ); + } + + // Start Etel monitors + iCallEventMonitor = CSPEtelConferenceEventMonitor::NewL( *this, iCall ); + iCallEventMonitor->StartMonitoring(); + iCallStatusMonitor = CSPEtelConferenceStatusMonitor::NewL( *this, iCall ); + iCallStatusMonitor->StartMonitoring(); + iCallCapsMonitor = CSPEtelConferenceCapsMonitor::NewL( *this, iCall ); + iCallCapsMonitor->StartMonitoring(); + + iRequester = CSPEtelConferenceCallRequester::NewL( *this, iCall ); + CSPLOGSTRING(CSPOBJECT, "CSPConferenceCall::ConstructL() end"); + } + +// End of file