diff -r 000000000000 -r ff3b6d0fd310 phoneclientserver/phoneserver/Src/CommandHandler/Commandhandler_Aiw/CPhSrvComHandRequestManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneclientserver/phoneserver/Src/CommandHandler/Commandhandler_Aiw/CPhSrvComHandRequestManager.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,376 @@ +/* +* Copyright (c) 2003-2004 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: Command Handler Request Manager. +* +*/ + + + +// INCLUDES +#include "CPhSrvComHandRequestManager.h" +#include "CPhSrvComHandRequest.h" +#include "CPhSrvSubSessionBase.h" +#include "PhSrvUtils.h" +#include "CPhSrvServer.h" +#include "MPhSrvEmergencyNumberManager.h" + + +// CONSTANTS + +// The size of the Notification manager storage. +const TInt KPhSrvComHandManagerPendingCallGranularity = 4; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::CPhSrvComHandRequestManager +// +// Constructor. +// ----------------------------------------------------------------------------- +// +CPhSrvComHandRequestManager::CPhSrvComHandRequestManager( + CPhSrvServer& aServer ) +: iServer( aServer ) + { + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::~CPhSrvComHandRequestManager +// +// Destructor. +// ----------------------------------------------------------------------------- +// +CPhSrvComHandRequestManager::~CPhSrvComHandRequestManager() + { + if ( iOutstandingComHandRequests ) + { + iOutstandingComHandRequests->ResetAndDestroy(); + iOutstandingComHandRequests->Close(); + + delete iOutstandingComHandRequests; + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::ConstructL +// +// Complete construction. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::ConstructL() + { + iOutstandingComHandRequests = new ( ELeave ) RPointerArray< + CPhSrvComHandRequest >( KPhSrvComHandManagerPendingCallGranularity ); + + CPhSrvComHandRequest* emergencyRequest = CPhSrvComHandRequest::NewL(); + CleanupStack::PushL( emergencyRequest ); + User::LeaveIfError( + iOutstandingComHandRequests->Append( emergencyRequest ) ); + CleanupStack::Pop(); // emergencyRequest + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::NegotiatorRequestL +// +// Initiate a command handler request - called by the external command handler +// interface. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::NegotiatorRequestL( + const RMessage2& aMessage, + const TPhCltComHandCommandParameters& aParams, + CPhSrvSubSessionBase& aSubSession ) + { + // If we have no registered initiator then we can't perform the request. + if ( !iComHandInitiator ) + { + User::Leave( KErrNotReady ); + } + + // If the request is DTMF stop, it is handled as emergency request. + TBool isDtmfCancel = + ( + ( aParams.iCommandHandlerCommand == EPhCltCommandVts ) && + ( aParams.iDtmfAction == EPhCltDtmfStop ) + ); + + // If the request is dial and the number is emergencynumber, it is + // handled as emergency request. + TBool isEmergencyCall = + ( aParams.iCommandHandlerCommand == EPhCltCommandAtd ); + + if( isEmergencyCall ) + { + isEmergencyCall = iServer.EmergencyNumberManagerL(). + EmergencyNumberManagerIsEmergencyNumberL( + ( TDes16& ) aParams.iTelNumber, + EPhCltEmergencyNumberQueryModeNormal ); + } + + // Panic if this is not the only request from this subsession. + if ( RequestAlreadyExists( aSubSession ) ) + { + // Cancel all ongoing requests first. + NegotiatorRequestCancel( aSubSession ); + + PhoneServerUtils::PanicClient( + EPhoneServerPanicTooManyRequestsOngoing, + aMessage ); + } + + // Normal request handling, request is ok. + else + { + CPhSrvComHandRequest* temp = NULL; + + // Emergency request handling. + if ( ( isDtmfCancel || isEmergencyCall ) && + ( *iOutstandingComHandRequests )[0]->SubSessionHandle() == 0 ) + { + ( *iOutstandingComHandRequests )[0]->UpdateEmergencyRequest( + aMessage, + aParams, + aSubSession.SubSessionUniqueHandle() ); + temp = ( *iOutstandingComHandRequests )[0]; + } + else + { + // Create pending request + CPhSrvComHandRequest* request = CPhSrvComHandRequest::NewLC( + aMessage, + aParams, + aSubSession.SubSessionUniqueHandle() ); + + User::LeaveIfError( + iOutstandingComHandRequests->Append( request ) ); + CleanupStack::Pop( request ); + temp = request; + } + + // Now see if the command handler notifier (initiator) is ready + if ( iComHandInitiator->InitiatorIsReadyToPerformRequest() ) + { + // Ask the call initiator to perform the request + // (basically completes the phone app engine's outstanding + // ComHand Notifier request). + iComHandInitiator->InitiatorMakeAsynchronousComHandRequest( + aParams ); + + iActiveRequest = temp; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::NegotiatorRequestCancel +// +// Cancel a pending command handler request. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::NegotiatorRequestCancel( + CPhSrvSubSessionBase& aSubSession ) + { + // Obtain the subsessions handle + const TInt handle = aSubSession.SubSessionUniqueHandle(); + + // Now look for any pending requests that match. + const TInt count = iOutstandingComHandRequests->Count(); + for( TInt i = 0; i < count; i++ ) + { + CPhSrvComHandRequest* entry = ( *iOutstandingComHandRequests )[i]; + if ( entry->SubSessionHandle() == handle ) + { + if ( entry == iActiveRequest ) + { + // This request is active, so inform that it is deleted. + iActiveRequest = NULL; + } + + // Found matching entry, so cancel it and clean up + if ( i == 0 ) // 0 stands for emergency request + { + entry->Cancel(); + entry->ClearEmergencyRequest(); + } + else + { + iOutstandingComHandRequests->Remove( i ); + entry->Cancel(); + delete entry; + } + } + } + UpdateQueue(); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL +// +// Updates the negotiator so that it knows if the notifier +// session is able to perform the request. +// Does not leave. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL( + MPhSrvComHandInitiator& aInitiator ) + { + // There mustn't already be a command handler initiator, or the existing + // initiator must be the same as the new one (otherwise, panic). + __ASSERT_ALWAYS( !iComHandInitiator || &aInitiator == iComHandInitiator, + PhoneServerUtils::Panic( + EPhoneServerPanicExistingComHandInitiatorFault ) ); + + // Update our pointer + iComHandInitiator = &aInitiator; + + UpdateQueue(); + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::SetNegotiatorReadyRequestCancel +// +// Indicates that the initiator is no longer available. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::SetNegotiatorReadyRequestCancel( + MPhSrvComHandInitiator& aInitiator ) + { + if ( iComHandInitiator && iComHandInitiator == &aInitiator ) + { + iComHandInitiator = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::SetNegotiatorAttemptedRequestResponseValue +// +// Handle a response from the phone app engine - this is the +// result of attempting to perform a command handler request +// (based upon a previous clients external command handler request). +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::SetNegotiatorAttemptedRequestResponseValue( + TPhCltPhoneResults aResult ) + { + // Handle response event only if there is request that waits response. + if ( iActiveRequest ) + { + // Get the first item in the list - this is the oldest, and has the + // details of the command handler request we had previously initiated. + CPhSrvComHandRequest* head = NULL; + if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 ) + { + head = ( *iOutstandingComHandRequests )[0]; + } + else + { + head = ( *iOutstandingComHandRequests )[1]; + } + // Complete the request so that the external command handler client + // knows the result of the request attempt + head->InformOfComHandRequestAttemptResult( aResult ); + + // Delete the pending request (now that it's been processed) and tidy + // up + if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 ) + { + ( *iOutstandingComHandRequests )[0]->ClearEmergencyRequest(); + } + else + { + iOutstandingComHandRequests->Remove( 1 ); + delete head; + } + + // Reset the iActiveRequest variable. + iActiveRequest = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::UpdateQueue +// +// Update the request queue. +// ----------------------------------------------------------------------------- +// +void CPhSrvComHandRequestManager::UpdateQueue() + { + // If we have no registered initiator then we do nothing here. + if ( iComHandInitiator ) + { + // If we have more than one item in the queue, then we + // try and fire of the next item here. + if ( iComHandInitiator->InitiatorIsReadyToPerformRequest() && + ( iOutstandingComHandRequests->Count() > 1 || + ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 ) ) + { + // Get the request at the top of the list (head of the queue) + CPhSrvComHandRequest* head = NULL; + if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 ) + { + head = ( *iOutstandingComHandRequests )[0]; + } + else + { + head = ( *iOutstandingComHandRequests )[1]; + } + + iComHandInitiator->InitiatorMakeAsynchronousComHandRequest( + head->ComHandParameters() ); + + iActiveRequest = head; + } + } + } + + +// ----------------------------------------------------------------------------- +// CPhSrvComHandRequestManager::RequestAlreadyExists +// +// Check whether there already is request(s) for the subsession given as +// parameter. +// ----------------------------------------------------------------------------- +// +TBool CPhSrvComHandRequestManager::RequestAlreadyExists( + CPhSrvSubSessionBase& aSubSession ) + { + TBool isThereRequest = EFalse; + + // Obtain the subsessions handle + const TInt handle = aSubSession.SubSessionUniqueHandle(); + + // Look for any pending requests that match the handle. + const TInt count = iOutstandingComHandRequests->Count(); + TInt i = 0; + for( i = 0; i < count; i++ ) + { + CPhSrvComHandRequest* entry = + ( *iOutstandingComHandRequests )[i]; + if ( entry->SubSessionHandle() == handle ) + { + isThereRequest = ETrue; + } + } + return isThereRequest; + } + +// End of File