DTsy warnings fixed.
// Copyright (c) 2006-2009 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:
//
//INCLUDE FILES
#include "cmmconferencecalltsy.h"
#include "cmmphonetsy.h"
#include "cmmtsyreqhandlestore.h"
#include "MmTsy_numberOfSlots.h"
#include "CMmCommonStaticUtility.h"
#include "cmmconferencecallgsmwcdmaext.h"
#include "cmmvoicecalltsy.h"
#include "cmmcallgsmwcdmaext.h"
#include "cmmcalllist.h"
#include "cmmmessagemanagerbase.h"
#include <ctsy/serviceapi/gsmerror.h>
#include <etelmmerr.h> // etel error codes
// ======== MEMBER FUNCTIONS ========
CMmConferenceCallTsy::CMmConferenceCallTsy():
iReqHandleType(EMultimodeConferenceCallReqHandleUnknown)
{
}
CMmConferenceCallTsy* CMmConferenceCallTsy::NewL(
CMmPhoneTsy* aMmPhone )
{
CMmConferenceCallTsy* conferenceCallTsy = NULL;
if ( aMmPhone != NULL )
{
conferenceCallTsy = new (ELeave) CMmConferenceCallTsy();
CleanupClosePushL( *conferenceCallTsy );
conferenceCallTsy->iMmPhone = aMmPhone;
conferenceCallTsy->ConstructL();
CleanupStack::Pop();
}
return conferenceCallTsy;
}
void CMmConferenceCallTsy::ConstructL()
{
#ifdef REQHANDLE_TIMER
//create req handle store
iTsyReqHandleStore = CMmTsyReqHandleStore::NewL( this, iMmPhone,
EMultimodeConferenceCallMaxNumOfRequests, iConferenceCallReqHandles );
#else
//create req handle store
iTsyReqHandleStore = CMmTsyReqHandleStore::NewL(
EMultimodeConferenceCallMaxNumOfRequests, iConferenceCallReqHandles );
#endif
//Create conference call extension
iMmConferenceCallExtInterface =
CMmConferenceCallGsmWcdmaExt::NewL( this );
//Initialise internal attributes...
ResetAttributes();
//Check if conference call creation is already possible. If possible,
//capabilities are updated by the extension.
CheckConferenceCapability();
//register conference call tsy in the message manager
iMmPhone->MessageManager()->RegisterTsyObject(
CMmMessageManagerBase::EConferenceCallTsy, this );
}
CMmConferenceCallTsy::~CMmConferenceCallTsy()
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::~CMmConferenceCallTsy");
if ( iMmPhone )
{
// deregister tsy object from message manager
iMmPhone->MessageManager()->DeregisterTsyObject(this);
//set phone tsy's pointer to CC object to NULL
iMmPhone->SetConferenceCall( NULL );
}
//if conference is active, close all calls that are part of the conference
//call. send request using transaction id 0x00.
if ( RMobileConferenceCall::EConferenceIdle != iStatus )
{
//We can't do nothing if release request fails here, because CC
//sub-session is closing down.
TInt trapError = KErrNone;
TRAP( trapError,
iMmConferenceCallExtInterface->HangUpL( iStatus );
);
}
if ( iTsyReqHandleStore )
{
delete iTsyReqHandleStore;
}
//delete conference call extensions
if ( iMmConferenceCallExtInterface )
{
delete iMmConferenceCallExtInterface;
}
iMmConferenceCallExtInterface = NULL;
iMmPhone = NULL;
iTsyReqHandleStore = NULL;
iRetCaps = NULL;
iRetStatus = NULL;
iRetConferenceEventCallName = NULL;
iRetConferenceEvent = NULL;
iConnectedCall = NULL;
iHoldCall = NULL;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::OpenNewObjectByNameL
// This method is not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CTelObject* CMmConferenceCallTsy::OpenNewObjectByNameL(
const TDesC& )
{
User::Leave( KErrNotSupported );
//lint -e{527} "unreachable code"
return NULL;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::OpenNewObjectL
// This method is not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CTelObject* CMmConferenceCallTsy::OpenNewObjectL(
TDes& )
{
User::Leave( KErrNotSupported );
return NULL;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::ExtFunc
// Dispatches extension function requests. All functions that are not
// part of the core function set, are routed via the ExtFunc method.
// At the beginning of this method, packaged pointers are unpacked. Then
// the correct function is selected using the IPC number.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::ExtFunc(
const TTsyReqHandle aTsyReqHandle,
const TInt aIpc,
const TDataPackage& aPackage )
{
TInt ret( KErrNone );
TInt trapError( KErrNone );
// Ensure the ReqHandleType is unset.
// This will detect cases where this method indirectly calls itself
// (e.g. servicing a client call that causes a self-reposting notification to complete and thus repost).
// Such cases are not supported because iReqHandleType is in the context of this class instance,
// not this request, and we don't want the values set by the inner request and the outer request
// interfering with each other.
__ASSERT_DEBUG(iReqHandleType==EMultimodeConferenceCallReqHandleUnknown, User::Invariant());
//Original code continues here.
TRAP( trapError, ret = DoExtFuncL( aTsyReqHandle, aIpc, aPackage ); );
if ( trapError != KErrNone )
{
//error handling. Object cannot be created.
ReqCompleted( 0, trapError );
}
//if return value is not KErrNone
else if ( ret != KErrNone )
{
//Complete request with this error value
ReqCompleted( aTsyReqHandle, ret );
}
//save request handle
if ( EMultimodeConferenceCallReqHandleUnknown != iReqHandleType )
{
#ifdef REQHANDLE_TIMER
SetTypeOfResponse ( iReqHandleType, aTsyReqHandle );
#else
iTsyReqHandleStore->SetTsyReqHandle( iReqHandleType, aTsyReqHandle );
#endif
// We've finished with this value now. Clear it so it doesn't leak
// up to any other instances of this method down the call stack
iReqHandleType = EMultimodeConferenceCallReqHandleUnknown;
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::DoExtFuncL
// ExtFunc is called by the server when it has a "extended",
// i.e. non-core ETel request for the TSY. To process a request handle,
// request type and request data are passed to the TSY.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::DoExtFuncL(
const TTsyReqHandle aTsyReqHandle,
const TInt aIpc,
const TDataPackage& aPackage )
{
TFLOGSTRING3("TSY: CMmConferenceCallTsy::DoExtFuncL.\n \t\t\t IPC:%d\n \t\t\t Handle:%d",
aIpc, aTsyReqHandle);
TInt ret( KErrNotSupported );
TAny* dataPtr = aPackage.Ptr1();
// The request data has to extracted from TDataPackage and the TAny*
// pointers have to be "cast" to the expected request data type
switch( aIpc )
{
case EMobileConferenceCallGetCaps:
ret = GetCaps( aTsyReqHandle,
reinterpret_cast<TUint32*>( dataPtr ) );
break;
case EMobileConferenceCallNotifyCapsChange:
ret = NotifyCapsChange( reinterpret_cast<TUint32*>( dataPtr ) );
break;
case EMobileConferenceCallCreateConference:
ret = CreateConferenceL( aTsyReqHandle );
break;
case EMobileConferenceCallAddCall:
ret = AddCallL( aTsyReqHandle,
reinterpret_cast<TName*>( aPackage.Des1u() ) );
break;
case EMobileConferenceCallSwap:
ret = SwapL( aTsyReqHandle );
break;
case EMobileConferenceCallHangUp:
ret = HangUpL( aTsyReqHandle );
break;
case EMobileConferenceCallEnumerateCalls:
ret = EnumerateCalls( aTsyReqHandle,
reinterpret_cast<TInt*>( dataPtr ) );
break;
case EMobileConferenceCallGetMobileCallInfo:
ret = GetMobileCallInfo( aTsyReqHandle,
reinterpret_cast<TInt*>( dataPtr ),
aPackage.Des2n() );
break;
case EMobileConferenceCallGetConferenceStatus:
ret = GetConferenceStatus( aTsyReqHandle,
reinterpret_cast<RMobileConferenceCall::TMobileConferenceStatus*>(
dataPtr ) );
break;
case EMobileConferenceCallNotifyConferenceStatusChange:
ret = NotifyConferenceStatusChange(
reinterpret_cast<RMobileConferenceCall::TMobileConferenceStatus*>(
dataPtr ) );
break;
case EMobileConferenceCallNotifyConferenceEvent:
ret = NotifyConferenceEvent(
reinterpret_cast<RMobileConferenceCall::TMobileConferenceEvent*>(
dataPtr ), reinterpret_cast<TName*>( aPackage.Des2u() ) );
break;
default:
ret = KErrNotSupported;
break;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::ReqModeL
// ReqModeL is called from the server's CTelObject::ReqAnalyserL
// in order to check the type of request it has.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CTelObject::TReqMode CMmConferenceCallTsy::ReqModeL(
const TInt aIpc )
{
CTelObject::TReqMode ret( 0 ); // default return value
switch ( aIpc )
{
// No Flow Control
// All disabled
// TSYs wishing to implement their own buffering algorithm will place
// all requests in this category.
// This category will also be used by the RecoverDataPort request that
// must be passed to the TSY to indicate that it may use the
// communications port after a loan.
//Get methods that do not use DOS and return immediately.
//Flow control not required.
case EMobileConferenceCallGetCaps:
case EMobileConferenceCallGetMobileCallInfo:
case EMobileConferenceCallGetConferenceStatus:
//Other methods that do not use DOS and return immediately.
//Flow control not required.
case EMobileConferenceCallEnumerateCalls:
//Methods that can propably take a long time and cannot therefore be
//flow controlled. Solution: All these methods must check req handle
//table before handling the request. In case that the request table
//indicates that same method has been called and has not been
//completed, the method should return KErrServerBusy.
case EMobileConferenceCallHangUp:
break;
// Flow Controlled Services
// KReqModeFlowControlObeyed
// Commands that change the state of the phone, e.g. clearing the AoC
// counter; are commands that TSY should only deal with one at a time.
//Voice call related methods that should be handled only
//one at the time.
case EMobileConferenceCallCreateConference:
case EMobileConferenceCallSwap:
case EMobileConferenceCallAddCall:
ret = KReqModeFlowControlObeyed;
break;
// ReqModePostImmediately
// Requests that notify a client about a change of state, where the
// TSY needs to distinguish between different clients.
//*******************************************************************
// (TAN) DO NOT USE THIS if not absolutely certain how to handle the
// corresponding method in TSY. Differs from all other situations!!!
//********************************************************************
//ret=KReqModeRePostImmediately;
// KReqModeMultipleCompletionEnabled
// (a) commands that may take some time, but which the TSY can handle
// more than one of concurrently, or
// (b) notifications that the TSY does not wish to be re-posted
// immediately, so the server does no buffering.
//ret=KReqModeMultipleCompletionEnabled;
// KReqModeMultipleCompletionEnabled | KReqModeFlowControlObeyed
// A command that may take some time and which the TSY can only deal
// with one at a time.
//case EEtelCallSetFaxSettings:
// ret = KReqModeMultipleCompletionEnabled |
// KReqModeFlowControlObeyed;
// break;
//Notifications
//KReqModeMultipleCompletionEnabled | ReqModePostImmediately
//Requests that notify a client about a change of state.
//Since these requests do not require the issuing of any modem
//commands, they do not have to obey flow control.
//The TSY never gets more than one of these outstanding per CTelObject
case EMobileConferenceCallNotifyCapsChange:
case EMobileConferenceCallNotifyConferenceStatusChange:
case EMobileConferenceCallNotifyConferenceEvent:
ret = KReqModeMultipleCompletionEnabled |
KReqModeRePostImmediately;
break;
//Cancel Requests
//It is not necessary to include the Cancel methods in ReqModeL at all
//The ETel server never calls ReqModeL with a Cancel IPC.
// Other variations of return values are unusable
default:
// Unknown or invalid Call IPC
User::Leave( KErrNotSupported );
break;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NumberOfSlotsL
// NumberOfSlotsL is called by the server when it is registering a
// new NOTIFICATION. It enables the TSY to tell the server
// how many buffer slots to allocate for "repost immediately" notifications
// that may trigger before clients collect them.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NumberOfSlotsL(
const TInt aIpc )
{
// There is a buffer in the ETel server for each type of NOTIFICATION and
// the size of the buffer is determined by the TSY. When the ETel server
// discovers that a request is "repost immediately" it will ask the TSY
// how big a buffer it wants by calling CTelObject::NumberOfSlotsL( ).
//
// It is up to the TSY developer's judgement how many buffer slots this
// method returns for each notification. If there is a danger that a
// particular notification could trigger frequently and in rapid
// succession (e.g. call group change notification) then at least 10 or 20
// slots may be required. For a notification that triggers rarely, perhaps
// 1 or 2 slots is enough.
//
// So if the ETel server has stored a few occurrences of a particular
// notification, when client subsequently calls that notification request,
// the ETel server will complete the client's request with the saved data.
TInt numberOfSlots = 1;
switch ( aIpc )
{
case EMobileConferenceCallNotifyCapsChange:
numberOfSlots = KMmConferenceCallCapsChangeSlots;
break;
case EMobileConferenceCallNotifyConferenceStatusChange:
numberOfSlots = KMmConferenceCallStatusChangeSlots;
break;
case EMobileConferenceCallNotifyConferenceEvent:
numberOfSlots = KMmConferenceCallEventSlots;
break;
default:
// Unknown or invalid Call IPC
User::Leave( KErrNotSupported );
break;
}
return numberOfSlots;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CancelService
// CancelService is called by the server when it is
// "cleaning-up" any still outstanding asynchronous requests before closing
// a client's sub-session. This will happen if a client closes its R-class
// handle without cancelling outstanding asynchronous requests. Only
// Mobile API requests are handled here.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::CancelService(
const TInt aIpc,
const TTsyReqHandle aTsyReqHandle )
{
//When the clients close their sub-sessions (eg. by calling RPhone::Close)
//they may not have cancelled all their outstanding asynchronous requests
//before closing. It is up to the ETel server to clean up in this
//situation, so the server will find the list of outstanding requests
//related to that sub-session object and pass these outstanding IPC req.
//numbers, one at a time, to the CancelService function in the TSY.
TInt ret( KErrNone );
switch( aIpc )
{
//TSY has started a request and it is not possible to then cancel
//this request. The best thing for the TSY to do in this case is
//to proceed as though the Cancel never happened. The server's call
//to the TSY cancel function will return synchronously. The TSY then
//continues to wait for the original acknowledgement and when it
//receives it, the TSY will complete the original request.
case EMobileConferenceCallCreateConference:
case EMobileConferenceCallAddCall:
case EMobileConferenceCallSwap:
case EMobileConferenceCallHangUp:
break;
//Cancel methods that are not supported
//case XXX
// ret = KErrNotSupported;
// break;
//Notification Cancels, no special requirements.
case EMobileConferenceCallNotifyCapsChange:
ret = NotifyCapsChangeCancel( aTsyReqHandle );
break;
case EMobileConferenceCallNotifyConferenceStatusChange:
ret = NotifyConferenceStatusChangeCancel( aTsyReqHandle );
break;
case EMobileConferenceCallNotifyConferenceEvent:
ret = NotifyConferenceEventCancel( aTsyReqHandle );
break;
//Everything is taken care in the method implementation.
//Just direct the request to the method.
//case
// none
//Default case
default:
ret = KErrNotFound;
break;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::Init
// Initialisation method that is called from ETel Server.
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::Init()
{
// None
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::RegisterNotification
// RegisterNotification is called when the server recognises
// that this notification is being posted for the first time on this
// sub-session object. It enables the TSY to "turn on" any regular
// notification messages that it may receive from DOS. Currently does not
// really do anything but returns KErrNone to ETel server in case of known
// notification request type.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::RegisterNotification(
const TInt aIpc )
{
TInt ret( KErrNotSupported );
switch( aIpc )
{
case EMobileConferenceCallNotifyCapsChange:
case EMobileConferenceCallNotifyConferenceStatusChange:
case EMobileConferenceCallNotifyConferenceEvent:
ret = KErrNone;
break;
default:
// Unknown or invalid IPC
ret = KErrNotSupported;
break;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::DeregisterNotification
// DeregisterNotification is called when the server recognises
// that this notification will not be posted again because the last client
// to have a handle on this sub-session object has just closed the handle.
// It enables the TSY to "turn off" any regular notification messages that
// it may receive from DOS. Currently does not really do anything but returns
// KErrNone to ETel server in case of known notification request type.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::DeregisterNotification(
const TInt aIpc )
{
TInt ret( KErrNotSupported );
switch( aIpc )
{
case EMobileConferenceCallNotifyCapsChange:
case EMobileConferenceCallNotifyConferenceStatusChange:
case EMobileConferenceCallNotifyConferenceEvent:
ret = KErrNone;
break;
default:
// Unknown or invalid IPC
ret = KErrNotSupported;
break;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::GetCaps
// This method returns the current capabilities of the conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::GetCaps(
const TTsyReqHandle aTsyReqHandle,
TUint32* aCaps )
{
//Conference caps
*aCaps = iConferenceCaps;
//Complete the request
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyCapsChange
// This method allows clients to be notified when the conference
// call capabilities change.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyCapsChange(
TUint32* aCaps )
{
//save pointer where to copy the changed value
iRetCaps = aCaps;
//save req handle type
iReqHandleType = EMultimodeConferenceCallCapsChangeNotification;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyCapsChangeCancel
// Cancels an outstanding asynchronous NotifyCapsChange request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyCapsChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
//set pointer to NULL
iRetCaps = NULL;
//reset req handle
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallCapsChangeNotification );
//Complete request
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteNotifyCapsChange
// Completes NotifyCapsChange request when capabilities change.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteNotifyCapsChange(
TUint32 aCaps )
{
//update internal capabilities
iConferenceCaps = aCaps;
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallCapsChangeNotification );
//if req handle was found
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
//copy conference caps to requested location
*iRetCaps = iConferenceCaps;
//complete request
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CreateConferenceL
// Allows clients to create the initial conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::CreateConferenceL(
const TTsyReqHandle aTsyReqHandle )
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::CreateConferenceL");
//Store call object with status connected
iConnectedCall =
iMmPhone->CallList()->GetMmCallByStatus( RMobileCall::EStatusConnected );
//Store call object with status hold
iHoldCall =
iMmPhone->CallList()->GetMmCallByStatus( RMobileCall::EStatusHold );
//Let extension try to create conference call
TInt ret = iMmConferenceCallExtInterface->CreateConferenceL( iStatus );
if ( ret != KErrNone )
{
//request failed.
ReqCompleted( aTsyReqHandle, ret );
}
else
{
//save req handle type
iReqHandleType = EMultimodeConferenceCallCreateConference;
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteCreateConference
// Complete creation of conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteCreateConference(
TInt aResult )
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::CompleteCreateConference");
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallCreateConference );
//if req handle was available
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
//complete caps after successfully creating conference
if ( KErrNone == aResult )
{
//hangup and swap are now possible
iConferenceCaps = RMobileConferenceCall::KCapsSwap |
RMobileConferenceCall::KCapsHangUp;
//set flag telling that caps have changed
iCapsChanged = ETrue;
if( iConnectedCall && iHoldCall )
{
TName connectedCall = iConnectedCall->CallName();
TName holdCall = iHoldCall->CallName();
if( connectedCall.Length() != 0 && holdCall.Length() != 0 )
{
// Create object including call names
// wich were first ones in conference
TName callsInConference;
callsInConference.Zero();
callsInConference.Append( connectedCall );
callsInConference.Append( KDelimiter );
callsInConference.Append( holdCall );
//Complete event
CompleteNotifyConferenceEvent( callsInConference,
RMobileConferenceCall::EConferenceBuilt );
}
}
}
//complete request
ReqCompleted( reqHandle, aResult );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::AddCallL
// Adds the single voice call specified by the aCallName parameter
// to an existing conference call
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::AddCallL(
const TTsyReqHandle aTsyReqHandle,
const TName* aCallName )
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::AddCallL");
//set return value to KErrNotFound
TInt ret( KErrNotFound );
//copy the name of the call to be added, will be used when request is
//later completed
iAddCallName = *aCallName;
//start adding a call to conference call
ret = iMmConferenceCallExtInterface->AddCallL(
&iAddCallName, iStatus, iMmPhone->CallList() );
if ( ret != KErrNone )
{
//request failed, complete with error value
ReqCompleted( aTsyReqHandle, ret );
}
else
{
// Store the request handle
iReqHandleType = EMultimodeConferenceCallAddCall;
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteAddCall
// Complete addition of a new call to the conference call
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteAddCall(
TInt aResult )
{
TFLOGSTRING2("TSY: CMmConferenceCallTsy::CompleteAddCall, Result: %d", aResult );
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallAddCall );
//successful case, call added to the conference call.
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
if ( (KErrNone == aResult) && (iAddCallName.Length() > 0) )
{
TFLOGSTRING("TSY: AddCall succeeded. AddCall request completed");
//notify call added using the call name received with AddCall
//request
CompleteNotifyConferenceEvent( iAddCallName,
RMobileConferenceCall::EConferenceCallAdded );
//Name of the call to be added to Conference call
iAddCallName.Zero();
RemoveNonParticipatingCall();
}
else
{
//something special is needed here to handle a case where
//CompleteAddCall fails
TFLOGSTRING("TSY: AddCall failed");
TFLOGSTRING2("TSY: # of CC participants: %d", iNumOfCallsInConferenceCall );
if ( 2 == iNumOfCallsInConferenceCall )
{
TFLOGSTRING("TSY: FIX FOR A ADDCALL & MT RELEASE CASE");
CMmCallTsy* mmCall = NULL;
CMmCallList* callList = iMmPhone->CallList();
CMmCallGsmWcdmaExt* mmCallGsmWcdmaExt = NULL;
RMobileCall::TMobileCallStatus status( RMobileCall::EStatusIdle );
//now check all calls
for ( TInt i = 0; i < callList->GetNumberOfObjects(); i++ )
{
mmCall = callList->GetMmCallByIndex(i);
status = mmCall->MobileCallStatus();
TFLOGSTRING2("TSY: Handling call, Call ID: %d", mmCall->CallId() );
if ( status == RMobileCall::EStatusHold ||
status == RMobileCall::EStatusConnected )
{
TFLOGSTRING("TSY: Status was Held or Connected, reconstructing capabilities");
// Fetch the active call extension
mmCallGsmWcdmaExt = static_cast<CMmCallGsmWcdmaExt*>(
mmCall->ActiveCallExtension() )
;
//set caps to be added;
TUint32 caps = RMobileCall::KCapsHangUp
| RMobileCall::KCapsJoin
| RMobileCall::KCapsTransfer
| RMobileCall::KCapsSwap;
//add Join caps
mmCallGsmWcdmaExt->AddGSMCallCaps( caps );
//complete caps change notification
mmCall->CompleteNotifyMobileCallCapsChange( KErrNone );
}
}
//Clear conference call
//Check if conference call is possible to build
CheckConferenceCapability();
//rebuild capabilities of individual calls
}
else
{
TFLOGSTRING("TSY: normal AddCall failure");
}
}
ReqCompleted( reqHandle, aResult );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::RemoveNonParticipatingCall()
// Removes call wich is not participant in conference
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::RemoveNonParticipatingCall()
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::RemoveNonParticipatingCall");
RMobileCall::TMobileCallStatus statusOfCallsInConference(
RMobileCall::EStatusConnected);
CMmCallTsy* mmCall = NULL;
CMmCallList* callList = iMmPhone->CallList();
RMobileCall::TMobileCallStatus status (RMobileCall::EStatusIdle);
TInt numberOfCallInConference(0);
TBool callReleased = EFalse;
TFLOGSTRING2("TSY: Conference status: %d", iStatus);
if ( iStatus == RMobileConferenceCall::EConferenceHold )
{
statusOfCallsInConference = RMobileCall::EStatusHold;
}
//now check all calls
for ( TInt c = 0; c < callList->GetNumberOfObjects(); c++ )
{
mmCall = callList->GetMmCallByIndex(c);
status = mmCall->MobileCallStatus();
if ( mmCall->IsPartOfConference() &&
status != statusOfCallsInConference )
{
//send removed event
CompleteNotifyConferenceEvent(
mmCall->CallName(),
RMobileConferenceCall::EConferenceCallRemoved );
TFLOGSTRING("TSY: Call removed from conference." );
}
else if ( status == statusOfCallsInConference )
{
numberOfCallInConference++;
}
if ( mmCall->IsRemoteReleasedCall() )
{
TFLOGSTRING("TSY: One call is remote released");
callReleased = ETrue;
}
}
if ( numberOfCallInConference == 2 &&
iNumOfCallsInConferenceCall == 3 && callReleased )
{
iNumOfCallsInConferenceCall--;
TFLOGSTRING("TSY: number of calls in conference decremented");
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::SwapL
// Allows a client to switch a conference call between "Active" and
// "Hold" states.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::SwapL(
const TTsyReqHandle aTsyReqHandle )
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::SwapL");
//direct request to extension
TInt ret = iMmConferenceCallExtInterface->SwapL(
iStatus, iMmPhone->CallList() );
if ( ret != KErrNone )
{
//complete request with error value
ReqCompleted( aTsyReqHandle, ret );
}
else
{
// Store the request handle
iReqHandleType = EMultimodeConferenceCallSwap;
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteSwap
// Complete the ongoing swap request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteSwap(
TInt aResult )
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::CompleteSwap");
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallSwap );
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
#ifdef USING_CTSY_DISPATCHER
if (aResult == KErrNone) // Conference event should only be completed if swap was successful
{
#endif // USING_CTSY_DISPATCHER
TName emptyBuf;
emptyBuf.Zero();
CompleteNotifyConferenceEvent( emptyBuf,
RMobileConferenceCall::EConferenceSwapped );
#ifdef USING_CTSY_DISPATCHER
}
#endif // USING_CTSY_DISPATCHER
//complete request
ReqCompleted( reqHandle, aResult );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::HangUpL
// Terminates the whole conference call (all calls participating in the
// conference call)
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::HangUpL(
const TTsyReqHandle aTsyReqHandle )
{
TInt ret( KErrServerBusy );
// Check if request handle already exists
TTsyReqHandle conferenceCallHangUpHandle = iTsyReqHandleStore->
GetTsyReqHandle( EMultimodeConferenceCallHangUp );
if ( conferenceCallHangUpHandle != EMultimodeConferenceCallReqHandleUnknown )
{
ReqCompleted( aTsyReqHandle, ret );
}
else
{
//Close all calls that are part of the conference call. Held call
//is not released if there is one...
ret = iMmConferenceCallExtInterface->HangUpL( iStatus );
//if request failed
if ( ret != KErrNone )
{
//complete request with error value
ReqCompleted( aTsyReqHandle, ret );
}
else
{
//save last request type
iReqHandleType = EMultimodeConferenceCallHangUp;
}
}
//Reset pointer
iHoldCall = NULL;
//Reset pointer
iConnectedCall = NULL;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteHangUp
// Completes call hangup.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteHangUp(
TInt aResult )
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallHangUp );
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
// ignore KErrGsmReleaseByUser, which means that the call ended
// because the local user released the call, and must be treated
// as a normal return code from the LTSY
TInt ret = ( (aResult == KErrGsmReleaseByUser) ? KErrNone : aResult );
//complete request
ReqCompleted( reqHandle, ret );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::EnumerateCalls
// This method returns the number of calls that are currently
// part of the conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::EnumerateCalls(
const TTsyReqHandle aTsyReqHandle,
TInt* aCount )
{
*aCount = iNumOfCallsInConferenceCall;
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::GetMobileCallInfo
// This method returns a current snapshot of the call
// information associated with the call specified by the aIndex parameter.
// NOTE! Conference call has to be in active state (Held or Active) before
// this method can return anything. Idle conference call is not considered
// to contain any calls.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::GetMobileCallInfo(
const TTsyReqHandle aTsyReqHandle,
TInt* aIndex,
TDes8* aCallInfo )
{
TInt ret( KErrNotReady );
if ( RMobileConferenceCall::EConferenceIdle != iStatus )
{
//Let extension get the information
ret = iMmConferenceCallExtInterface->GetMobileCallInfo(
aIndex, aCallInfo, iMmPhone->CallList(), iStatus );
}
ReqCompleted( aTsyReqHandle, ret );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::GetConferenceStatus
// Allows clients to retrieve the current status of the conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::GetConferenceStatus(
const TTsyReqHandle aTsyReqHandle,
RMobileConferenceCall::TMobileConferenceStatus* aStatus )
{
TFLOGSTRING2("TSY: CMmConferenceCallTsy::GetConferenceStatus. iStatus:%d", iStatus );
*aStatus = iStatus;
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::Status
// This function returns conference call status. For internal use.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
RMobileConferenceCall::TMobileConferenceStatus CMmConferenceCallTsy::Status() const
{
//return conference call status
return iStatus;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyConferenceStatusChange
// Allows clients to be notified of a change in the status of a
// conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyConferenceStatusChange(
RMobileConferenceCall::TMobileConferenceStatus* aStatus )
{
iRetStatus = aStatus;
iReqHandleType = EMultimodeConferenceCallStatusChangeNotification;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyConferenceStatusChangeCancel
// Cancels an outstanding asynchronous NotifyConferenceStatusChange request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyConferenceStatusChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetStatus = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallStatusChangeNotification );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteNotifyConferenceStatusChange
// Completes conference status change notification. Extension
// should already have updated status so this method retrieves the new
// status from the extension and does the actions required by new and old
// statuses.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteNotifyConferenceStatusChange()
{
TBool conferenceStatusChanged( EFalse );
RMobileConferenceCall::TMobileConferenceStatus oldStatus = iStatus;
TFLOGSTRING2("TSY: CMmConferenceCallTsy::CompleteNotifyConferenceStatusChange. oldStatus:%d", oldStatus );
iMmConferenceCallExtInterface->GetNewStatus( &iStatus );
switch( iStatus )
{
//new status is EConferenceIdle
case RMobileConferenceCall::EConferenceIdle:
//This might be caused by HangUp
CompleteHangUp( KErrNone );
//caps have changed
iCapsChanged = ETrue;
//status has changed
conferenceStatusChanged = ETrue;
//reset internal attributes
ResetAttributes();
break;
//new status is EConferenceActive
case RMobileConferenceCall::EConferenceActive:
// if previous status was EConferenceIdle
if ( oldStatus == RMobileConferenceCall::EConferenceIdle )
{
//is CreateConference request pending
if ( iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeConferenceCallCreateConference ) > 0 )
{
//CreateConference handling
CompleteCreateConference( KErrNone );
}
//status has changed
conferenceStatusChanged = ETrue;
}
//if previous state was EConferenceHold
else if ( oldStatus == RMobileConferenceCall::EConferenceHold )
{
//is AddCall request pending
if ( iTsyReqHandleStore->
GetTsyReqHandle( EMultimodeConferenceCallAddCall ) > 0 )
{
//AddCall handling
CompleteAddCall ( KErrNone );
}
//is Swap request pending.
else if ( iTsyReqHandleStore->
GetTsyReqHandle( EMultimodeConferenceCallSwap ) > 0 )
{
//resuming held conference call.
CompleteSwap ( KErrNone );
}
//status has changed
conferenceStatusChanged = ETrue;
}
break;
//new status is EConferenceHold
case RMobileConferenceCall::EConferenceHold:
//Complete Swap
CompleteSwap ( KErrNone );
//status has changed
conferenceStatusChanged = ETrue;
break;
default:
//nothing to do
break;
}
//get TSY req handle.
TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeConferenceCallStatusChangeNotification );
if ( ( EMultimodeConferenceCallReqHandleUnknown != reqHandle ) &&
conferenceStatusChanged )
{
TFLOGSTRING2("TSY: CMmConferenceCallTsy::CompleteNotifyConferenceStatusChange. Cur. iStatus:%d", iStatus );
//reset req handle.
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallStatusChangeNotification );
*iRetStatus = iStatus;
ReqCompleted( reqHandle, KErrNone );
}
if ( iCapsChanged )
{
//if conference caps are not 0, notify it
if ( 0 != iConferenceCaps )
{
CompleteNotifyCapsChange( iConferenceCaps );
}
else
{
//Otherwise we still have to check that is Conference creation
//now possible
CheckConferenceCapability();
//If CreateConference is now possible, iConferenceCaps is not 0.
//Completion has already been done.
if ( 0 == iConferenceCaps )
{
//Otherwise we have to complete the caps change with 0 value.
CompleteNotifyCapsChange( iConferenceCaps );
}
}
iCapsChanged = EFalse;
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyConferenceEvent
// Allows a client to be notified when a conference call event occurs.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyConferenceEvent(
RMobileConferenceCall::TMobileConferenceEvent* aEvent,
TName* aCallName )
{
iRetConferenceEventCallName = aCallName;
iRetConferenceEvent = aEvent;
iReqHandleType = EMultimodeConferenceCallConferenceEventNotification;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NotifyConferenceEventCancel
// Cancels an outstanding asynchronous NotifyConferenceEvent request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NotifyConferenceEventCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetConferenceEventCallName = NULL;
iRetConferenceEvent = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallConferenceEventNotification );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CompleteNotifyConferenceEvent
// Completes conference event notification.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CompleteNotifyConferenceEvent(
const TName& aName,
RMobileConferenceCall::TMobileConferenceEvent aEvent )
{
TFLOGSTRING2("TSY: CMmConferenceCallTsy::CompleteNotifyConferenceEvent.aEvent:%d", aEvent );
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeConferenceCallConferenceEventNotification );
//if req handle was set
if ( EMultimodeConferenceCallReqHandleUnknown != reqHandle )
{
//copy name of the call to which the event happened to the requested
//address
iRetConferenceEventCallName->Copy( aName );
//copy event to the requested address
*iRetConferenceEvent = aEvent;
ReqCompleted( reqHandle, KErrNone );
}
//if event was add
if ( aEvent == RMobileConferenceCall::EConferenceCallAdded )
{
// inform the call object that it is now part of the conference
CMmCallTsy* addedCall = iMmPhone->CallList()-> GetMmCallByName(
&aName );
if ( addedCall )
{
addedCall->SetPartOfConference( ETrue );
}
//increment iNumOfCallsInConferenceCall
iNumOfCallsInConferenceCall++;
}
//if event was removed
else if ( aEvent == RMobileConferenceCall::EConferenceCallRemoved )
{
// inform the call object that it is not part of the conference anymore
CMmCallTsy* removedCall = iMmPhone->CallList()->GetMmCallByName(
&aName );
if ( removedCall )
{
removedCall->SetPartOfConference( EFalse );
}
//decrement iNumOfCallsInConferenceCall
iNumOfCallsInConferenceCall--;
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::IsGoOneToOneSupported
// Checks if given call can be splitted from the conference call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmConferenceCallTsy::IsGoOneToOneSupported(
TInt aCallId )
{
TBool supported( EFalse );
//The action is only valid if the MS is in GSM mode, the selected call
//is a voice call and it is a member of an ongoing conference call.
TInt ret = iMmConferenceCallExtInterface->IsGoOneToOneSupported(
aCallId, iStatus, iMmPhone->CallList() );
if ( KErrNone == ret )
{
//GoOneToOne is supported to this call
supported = ETrue;
}
return supported;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::GetActiveConferenceCallExtension
// Returns a pointer to the active conference call extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmConferenceCallExtInterface* CMmConferenceCallTsy::GetActiveConferenceCallExtension()
{
return iMmConferenceCallExtInterface;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::SetActiveConferenceCallExtension
// Sets active Conference call extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::SetActiveConferenceCallExtension(
CMmConferenceCallExtInterface* aMmConferenceCallExt )
{
// Used if active conference call extension pointer is NULL
TInt ret( KErrGeneral );
//if not null
if ( aMmConferenceCallExt )
{
//set pointer
iMmConferenceCallExtInterface = aMmConferenceCallExt;
ret = KErrNone;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CheckConferenceCapability
// Checks if conference call creation is possible. The request
// is directed to the active extension which can make the decision.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CheckConferenceCapability()
{
//Let extension decide if conference call creation is possible.
iMmConferenceCallExtInterface->CheckConferenceCapability(
iStatus, iMmPhone->CallList() );
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::NumberOfCallsInConference
// This method returns the number of calls that are currently part of
// the conference call. For internal use.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmConferenceCallTsy::NumberOfCallsInConference() const
{
return iNumOfCallsInConferenceCall;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::ServiceRequested
// Returns ETrue if this service is pending on conference call object
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmConferenceCallTsy::ServiceRequested(
CMmConferenceCallTsy::TConferenceCallRequestTypes aReqType )
{
TBool ret( EFalse );
//if req handle is found from req handle store
if ( CMmConferenceCallTsy::EMultimodeConferenceCallReqHandleUnknown !=
iTsyReqHandleStore->GetTsyReqHandle( aReqType ) )
{
//set value to ETrue -> request is pending
ret = ETrue;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::CallStatusChanged
// After the status of a single call has changed, extension decides if
// the status of the conference call should be changed as well.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::CallStatusChanged(
RMobileCall::TMobileCallStatus aNewStatus,
TInt aCallId )
{
// only releasing, holding and connecting a call can cause a change
// of conference status
if ( ( RMobileCall::EStatusIdle == aNewStatus ) ||
( RMobileCall::EStatusHold == aNewStatus ) ||
( RMobileCall::EStatusConnected == aNewStatus ) )
{
TBool conferenceStatusChanged = iMmConferenceCallExtInterface->
CallStatusChanged( aNewStatus, aCallId );
if ( conferenceStatusChanged )
{
CompleteNotifyConferenceStatusChange();
}
}
//conference call creation might be possible, check it.
CheckConferenceCapability();
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::Phone
// Returns pointer to the Multimode Phone object. For internal use.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmPhoneTsy* CMmConferenceCallTsy::Phone()
{
return iMmPhone;
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::ResetAttributes
// Resets internal attributes of Conference call object. Calls also protocol
// extension to do the same.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::ResetAttributes()
{
TFLOGSTRING("TSY: CMmConferenceCallTsy::ResetAttributes." );
//Name of the call to be added to Conference call
iAddCallName.Zero();
//Conference call capabilities
iConferenceCaps = 0;
//Number of calls in conference call
iNumOfCallsInConferenceCall = 0;
//Conference call status
iStatus = RMobileConferenceCall::EConferenceIdle;
//Reset pointer
iHoldCall = NULL;
//Reset pointer
iConnectedCall = NULL;
if ( 0 != iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeConferenceCallAddCall ) )
{
TInt error = CMmCommonStaticUtility::EpocErrorCode(
KErrEtelCallNotActive, KErrMMEtelCallTerminated );
CompleteAddCall( error );
}
if ( 0 != iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeConferenceCallCreateConference ) )
{
TInt error = CMmCommonStaticUtility::EpocErrorCode(
KErrEtelCallNotActive, KErrMMEtelCallTerminated );
CompleteCreateConference( error );
}
if ( 0 != iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeConferenceCallSwap ) )
{
TInt error = CMmCommonStaticUtility::EpocErrorCode(
KErrEtelCallNotActive, KErrMMEtelCallTerminated );
CompleteSwap( error );
}
//Direct reset also to the extension
iMmConferenceCallExtInterface->ResetAttributes();
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::Caps
// This function returns conference call capabilities. For internal use.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TUint32 CMmConferenceCallTsy::Caps() const
{
//return conference call caps
return iConferenceCaps;
}
#ifdef REQHANDLE_TIMER
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::SetTypeOfResponse
// Sets the type of response for a given Handle. Automatic
// mode includes an automatic response in case of no response
// from the DOS in a specified time
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::SetTypeOfResponse(
const TInt aReqHandleType,
const TTsyReqHandle aTsyReqHandle )
{
TInt timeOut( 0 );
switch ( aReqHandleType )
{
case EMultimodeConferenceCallCreateConference:
timeOut = KMmConferenceCallCreateConferenceTimeOut;
break;
case EMultimodeConferenceCallAddCall:
timeOut = KMmConferenceCallAddCallTimeOut;
break;
case EMultimodeConferenceCallSwap:
timeOut = KMmConferenceCallSwapTimeOut;
break;
case EMultimodeConferenceCallHangUp:
timeOut = KMmConferenceCallHangUpTimeOut;
break;
//Can't use timer:
// - all notifications
//case EMultimodeConferenceCallStatusChangeNotification:
//case EMultimodeConferenceCallCapsChangeNotification:
//case EMultimodeConferenceCallConferenceEventNotification:
default:
iTsyReqHandleStore->SetTsyReqHandle(
aReqHandleType, aTsyReqHandle );
break;
}
//if timeout is requested
if ( timeOut > 0 )
{
//set time out
iTsyReqHandleStore->SetTsyReqHandle(
aReqHandleType, aTsyReqHandle, timeOut );
}
}
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::Complete
// Completes the request due timer expiration.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::Complete(
TInt aReqHandleType,
TInt aError )
{
//All possible TSY req handle types of Conference call are listed in the
//switch case below.
switch( aReqHandleType )
{
case EMultimodeConferenceCallCreateConference:
CompleteCreateConference( aError );
break;
case EMultimodeConferenceCallAddCall:
CompleteAddCall( aError );
break;
case EMultimodeConferenceCallSwap:
CompleteSwap( aError );
break;
case EMultimodeConferenceCallHangUp:
CompleteHangUp( aError );
break;
//Can't use timer:
// - all notifications
//case EMultimodeConferenceCallStatusChangeNotification:
//case EMultimodeConferenceCallCapsChangeNotification:
//case EMultimodeConferenceCallConferenceEventNotification:
default:
ReqCompleted( iTsyReqHandleStore->ResetTsyReqHandle(
aReqHandleType ), aError );
break;
}
}
#endif // REQHANDLE_TIMER
#ifdef TF_LOGGING_ENABLED
// ---------------------------------------------------------------------------
// CMmConferenceCallTsy::ReqCompleted
// Overrides CTelObject::ReqCompleted for test logging purposes.
// It prints the aTsyReqHandle and aError variable in the log file and then
// calls CTelObject::ReqCompleted.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmConferenceCallTsy::ReqCompleted(
const TTsyReqHandle aTsyReqHandle,
const TInt aError )
{
TFLOGSTRING3("TSY: CMmConferenceCallTsy::Request Completed. \n\t\t\tHandle:%d\n\t\t\t Error:%d",
aTsyReqHandle, aError);
//call original ReqCompleted from CTelObject
CTelObject::ReqCompleted( aTsyReqHandle, aError );
}
#endif // TF_LOGGING_ENABLED
// End of File