convergedcallengine/csplugin/src/cspconferencecall.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:15:03 +0100
branchRCL_3
changeset 20 987c9837762f
parent 0 ff3b6d0fd310
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* 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 <etelmm.h>
#include <etel.h>
#include <mccpcall.h>

#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<MCCPConferenceCallObserver::TCCPConferenceCallState>(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<MCCPConferenceCallObserver::TCCPConferenceCallState>(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<MCCPCall>& 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