phoneclientserver/phoneserver/Src/CommandHandler/CommandHandler_NoAiw/CPhSrvComHandRequestManager.cpp
changeset 46 2fa1fa551b0b
parent 42 35488577e233
child 48 78df25012fda
equal deleted inserted replaced
42:35488577e233 46:2fa1fa551b0b
     1 /*
       
     2 * Copyright (c) 2003-2004 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Command Handler Request Manager.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include "cphsrvcomhandrequestmanager.h" 
       
    22 #include "cphsrvcomhandrequest.h" 
       
    23 #include "cphsrvsubsessionbase.h" 
       
    24 #include "phsrvutils.h" 
       
    25 #include "cphsrvserver.h" 
       
    26 #include "mphsrvemergencynumbermanager.h" 
       
    27 
       
    28 
       
    29 // CONSTANTS
       
    30 
       
    31 // The size of the Notification manager storage.
       
    32 const TInt KPhSrvComHandManagerPendingCallGranularity = 4;
       
    33 
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CPhSrvComHandRequestManager::CPhSrvComHandRequestManager
       
    39 // 
       
    40 // Constructor.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CPhSrvComHandRequestManager::CPhSrvComHandRequestManager( 
       
    44     CPhSrvServer& aServer )
       
    45 :   iServer( aServer )
       
    46     {
       
    47     }
       
    48 
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CPhSrvComHandRequestManager::~CPhSrvComHandRequestManager
       
    52 // 
       
    53 // Destructor.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CPhSrvComHandRequestManager::~CPhSrvComHandRequestManager()
       
    57     {
       
    58     if ( iOutstandingComHandRequests )
       
    59         {
       
    60         iOutstandingComHandRequests->ResetAndDestroy();
       
    61         iOutstandingComHandRequests->Close();
       
    62 
       
    63         delete iOutstandingComHandRequests;
       
    64         }
       
    65     }
       
    66 
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CPhSrvComHandRequestManager::ConstructL
       
    70 // 
       
    71 // Complete construction.
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 void CPhSrvComHandRequestManager::ConstructL()
       
    75     {
       
    76     iOutstandingComHandRequests = new ( ELeave ) RPointerArray< 
       
    77         CPhSrvComHandRequest >( KPhSrvComHandManagerPendingCallGranularity );
       
    78 
       
    79     CPhSrvComHandRequest* emergencyRequest = CPhSrvComHandRequest::NewL();
       
    80     CleanupStack::PushL( emergencyRequest );
       
    81     User::LeaveIfError( 
       
    82         iOutstandingComHandRequests->Append( emergencyRequest ) );
       
    83     CleanupStack::Pop(); // emergencyRequest
       
    84     }
       
    85 
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CPhSrvComHandRequestManager::NegotiatorRequestL
       
    89 // 
       
    90 // Initiate a command handler request - called by the external command handler
       
    91 // interface.
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 void CPhSrvComHandRequestManager::NegotiatorRequestL( 
       
    95     const RMessage2& aMessage, 
       
    96     const TPhCltComHandCommandParameters& aParams, 
       
    97     CPhSrvSubSessionBase& aSubSession )
       
    98     {
       
    99     // If we have no registered initiator then we can't perform the request.
       
   100     if ( !iComHandInitiator )
       
   101         {
       
   102         User::Leave( KErrNotReady );
       
   103         }
       
   104 
       
   105     // If the request is DTMF stop, it is handled as emergency request.
       
   106     TBool isDtmfCancel = 
       
   107         ( 
       
   108             ( aParams.iCommandHandlerCommand == EPhCltCommandVts ) &&
       
   109             ( aParams.iDtmfAction == EPhCltDtmfStop ) 
       
   110         );
       
   111 
       
   112     // If the request is dial and the number is emergencynumber, it is
       
   113     // handled as emergency request.
       
   114     TBool isEmergencyCall = 
       
   115         ( aParams.iCommandHandlerCommand == EPhCltCommandAtd );
       
   116     if( isEmergencyCall )
       
   117         {
       
   118         isEmergencyCall = iServer.EmergencyNumberManagerL().
       
   119         EmergencyNumberManagerIsEmergencyNumberL(
       
   120             ( TDes16& ) aParams.iDialData.iTelNumber, 
       
   121             EPhCltEmergencyNumberQueryModeNormal );
       
   122         }
       
   123 
       
   124     // Panic if this is not the only request from this subsession.
       
   125     if ( RequestAlreadyExists( aSubSession ) )
       
   126         {
       
   127         // Cancel all ongoing requests first.
       
   128         NegotiatorRequestCancel( aSubSession );
       
   129 
       
   130         PhoneServerUtils::PanicClient( 
       
   131             EPhoneServerPanicTooManyRequestsOngoing,
       
   132             aMessage );
       
   133         }
       
   134 
       
   135     // Normal request handling, request is ok.
       
   136     else
       
   137         {
       
   138         CPhSrvComHandRequest* temp = NULL;
       
   139 
       
   140         // Emergency request handling.
       
   141         if ( ( isDtmfCancel || isEmergencyCall ) && 
       
   142              ( *iOutstandingComHandRequests )[0]->SubSessionHandle() == 0 )
       
   143             {
       
   144             ( *iOutstandingComHandRequests )[0]->UpdateEmergencyRequest( 
       
   145                 aMessage, 
       
   146                 aParams,
       
   147                 aSubSession.SubSessionUniqueHandle() );
       
   148             temp = ( *iOutstandingComHandRequests )[0];
       
   149             }
       
   150         else
       
   151             {
       
   152             // Create pending request
       
   153             CPhSrvComHandRequest* request = CPhSrvComHandRequest::NewLC( 
       
   154                 aMessage, 
       
   155                 aParams,
       
   156                 aSubSession.SubSessionUniqueHandle() );
       
   157 
       
   158             User::LeaveIfError( 
       
   159                 iOutstandingComHandRequests->Append( request ) );
       
   160             CleanupStack::Pop( request );
       
   161             temp = request;
       
   162             }
       
   163 
       
   164         // Now see if the command handler notifier (initiator) is ready 
       
   165         if ( iComHandInitiator->InitiatorIsReadyToPerformRequest() )
       
   166             {
       
   167             // Ask the call initiator to perform the request 
       
   168             // (basically completes the phone app engine's outstanding 
       
   169             // ComHand Notifier request).
       
   170             iComHandInitiator->InitiatorMakeAsynchronousComHandRequest( 
       
   171                 aParams );
       
   172 
       
   173             iActiveRequest = temp;
       
   174             }
       
   175         }
       
   176     }
       
   177 
       
   178 
       
   179 // -----------------------------------------------------------------------------
       
   180 // CPhSrvComHandRequestManager::NegotiatorRequestCancel
       
   181 // 
       
   182 // Cancel a pending command handler request.
       
   183 // -----------------------------------------------------------------------------
       
   184 //
       
   185 void CPhSrvComHandRequestManager::NegotiatorRequestCancel( 
       
   186     CPhSrvSubSessionBase& aSubSession )
       
   187     {
       
   188     // Obtain the subsessions handle
       
   189     const TInt handle = aSubSession.SubSessionUniqueHandle();
       
   190 
       
   191     // Now look for any pending requests that match.
       
   192     const TInt count = iOutstandingComHandRequests->Count();
       
   193     for( TInt i = 0; i < count; i++ )
       
   194         {
       
   195         CPhSrvComHandRequest* entry = ( *iOutstandingComHandRequests )[i];
       
   196         if ( entry->SubSessionHandle() == handle )
       
   197             {
       
   198             if ( entry == iActiveRequest )
       
   199                 {
       
   200                 // This request is active, so inform that it is deleted.
       
   201                 iActiveRequest = NULL;
       
   202                 }
       
   203 
       
   204             // Found matching entry, so cancel it and clean up
       
   205             if ( i == 0 ) // 0 stands for emergency request
       
   206                 {
       
   207                 entry->Cancel();
       
   208                 entry->ClearEmergencyRequest();
       
   209                 }
       
   210             else
       
   211                 {
       
   212                 iOutstandingComHandRequests->Remove( i );
       
   213                 entry->Cancel();
       
   214                 delete entry;
       
   215                 }
       
   216             }
       
   217         }
       
   218     UpdateQueue();
       
   219     }
       
   220 
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL
       
   224 // 
       
   225 // Updates the negotiator so that it knows if the notifier
       
   226 // session is able to perform the request.
       
   227 // Does not leave.
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void CPhSrvComHandRequestManager::SetNegotiatorReadyRequestL(
       
   231     MPhSrvComHandInitiator& aInitiator )
       
   232     {
       
   233     // There mustn't already be a command handler initiator, or the existing 
       
   234     // initiator must be the same as the new one (otherwise, panic).
       
   235     __ASSERT_ALWAYS( !iComHandInitiator || &aInitiator == iComHandInitiator, 
       
   236         PhoneServerUtils::Panic( 
       
   237         EPhoneServerPanicExistingComHandInitiatorFault ) );
       
   238 
       
   239     // Update our pointer
       
   240     iComHandInitiator = &aInitiator;
       
   241 
       
   242     UpdateQueue();
       
   243     }
       
   244 
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // CPhSrvComHandRequestManager::SetNegotiatorReadyRequestCancel
       
   248 // 
       
   249 // Indicates that the initiator is no longer available.
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 void CPhSrvComHandRequestManager::SetNegotiatorReadyRequestCancel( 
       
   253     MPhSrvComHandInitiator& aInitiator )
       
   254     {
       
   255     if ( iComHandInitiator && iComHandInitiator == &aInitiator )
       
   256         {
       
   257         iComHandInitiator = NULL;
       
   258         }
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // CPhSrvComHandRequestManager::SetNegotiatorAttemptedRequestResponseValue
       
   263 // 
       
   264 // Handle a response from the phone app engine - this is the 
       
   265 // result of attempting to perform a command handler request 
       
   266 // (based upon a previous clients external command handler request).
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 void CPhSrvComHandRequestManager::SetNegotiatorAttemptedRequestResponseValue( 
       
   270     TPhCltPhoneResults aResult )
       
   271     {
       
   272     // Handle response event only if there is request that waits response.
       
   273     if ( iActiveRequest )
       
   274         {
       
   275         // Get the first item in the list - this is the oldest, and has the
       
   276         // details of the command handler request we had previously initiated.
       
   277         CPhSrvComHandRequest* head = NULL;
       
   278         if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 )
       
   279             {
       
   280             head = ( *iOutstandingComHandRequests )[0];
       
   281             }
       
   282         else
       
   283             {
       
   284             head = ( *iOutstandingComHandRequests )[1];
       
   285             }
       
   286         // Complete the request so that the external command handler client 
       
   287         // knows the result of the request attempt
       
   288         head->InformOfComHandRequestAttemptResult( aResult );
       
   289 
       
   290         // Delete the pending request (now that it's been processed) and tidy
       
   291         // up
       
   292         if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 )
       
   293             {
       
   294             ( *iOutstandingComHandRequests )[0]->ClearEmergencyRequest();
       
   295             }
       
   296         else
       
   297             {
       
   298             iOutstandingComHandRequests->Remove( 1 );
       
   299             delete head;
       
   300             }
       
   301 
       
   302         // Reset the iActiveRequest variable.
       
   303         iActiveRequest = NULL;
       
   304         }
       
   305     }
       
   306 
       
   307 
       
   308 // -----------------------------------------------------------------------------
       
   309 // CPhSrvComHandRequestManager::UpdateQueue
       
   310 // 
       
   311 // Update the request queue.
       
   312 // -----------------------------------------------------------------------------
       
   313 //
       
   314 void CPhSrvComHandRequestManager::UpdateQueue()
       
   315     {
       
   316     // If we have no registered initiator then we do nothing here.
       
   317     if ( iComHandInitiator )
       
   318         {
       
   319         // If we have more than one item in the queue, then we
       
   320         // try and fire of the next item here.
       
   321         if ( iComHandInitiator->InitiatorIsReadyToPerformRequest() && 
       
   322             ( iOutstandingComHandRequests->Count() > 1 ||
       
   323             ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 ) )
       
   324             {
       
   325             // Get the request at the top of the list (head of the queue)
       
   326             CPhSrvComHandRequest* head = NULL;
       
   327             if ( ( *iOutstandingComHandRequests )[0]->SubSessionHandle() != 0 )
       
   328                 {
       
   329                 head = ( *iOutstandingComHandRequests )[0];
       
   330                 }
       
   331             else
       
   332                 {
       
   333                 head = ( *iOutstandingComHandRequests )[1];
       
   334                 }
       
   335 
       
   336             iComHandInitiator->InitiatorMakeAsynchronousComHandRequest(
       
   337                 head->ComHandParameters() );
       
   338 
       
   339             iActiveRequest = head;
       
   340             }
       
   341         }
       
   342     }
       
   343 
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CPhSrvComHandRequestManager::RequestAlreadyExists
       
   347 // 
       
   348 // Check whether there already is request(s) for the subsession given as 
       
   349 // parameter.
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 TBool CPhSrvComHandRequestManager::RequestAlreadyExists( 
       
   353     CPhSrvSubSessionBase& aSubSession )
       
   354     {
       
   355     TBool isThereRequest = EFalse;
       
   356 
       
   357     // Obtain the subsessions handle
       
   358     const TInt handle = aSubSession.SubSessionUniqueHandle();
       
   359 
       
   360     // Look for any pending requests that match the handle.
       
   361     const TInt count = iOutstandingComHandRequests->Count();
       
   362     TInt i = 0;
       
   363     for( i = 0; i < count; i++ )
       
   364         {
       
   365         CPhSrvComHandRequest* entry = 
       
   366             ( *iOutstandingComHandRequests )[i];
       
   367         if ( entry->SubSessionHandle() == handle )
       
   368             {
       
   369             isThereRequest = ETrue;
       
   370             }
       
   371         }
       
   372     return isThereRequest;
       
   373     }
       
   374 
       
   375 // End of File