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