sipvoipprovider/svphold/src/svpholdcontext.cpp
branchRCL_3
changeset 22 d38647835c2e
parent 0 a4daefaec16c
equal deleted inserted replaced
21:f742655b05bf 22:d38647835c2e
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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:  Base class for session context
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include    <s32mem.h>
       
    20 #include    <in_sock.h>
       
    21 #include    <in_pkt.h>
       
    22 #include    <badesca.h>
       
    23 #include    <mcesession.h>
       
    24 #include    <mcemanager.h>
       
    25 #include    <mcetransactiondatacontainer.h>
       
    26 #include    <mcertpsource.h>
       
    27 #include    <mcertpsink.h>
       
    28 #include    <mcemediastream.h>
       
    29 #include    <mceaudiostream.h>
       
    30 
       
    31 #include    <sdpcodecstringpool.h>
       
    32 #include    <sdpcodecstringconstants.h>
       
    33 #include    <sdpdocument.h>
       
    34 #include    <sdpconnectionfield.h>
       
    35 #include    "svpholdcontext.h"
       
    36 #include    "svpholdoutstate.h"
       
    37 #include    "svpholdinestablishingstate.h"
       
    38 #include    "svpholdoutestablishingstate.h"
       
    39 #include    "svpholdinstate.h"
       
    40 #include    "svpholdconnectedstate.h"
       
    41 #include    "svpholddhstate.h"
       
    42 #include    "svpholdcontroller.h"
       
    43 #include    "svpholdmediahandler.h"
       
    44 #include    "svpholdattributehandler.h"
       
    45 #include    "svpholdobserver.h"
       
    46 #include    "svplogger.h"
       
    47 #include    "svpaudioutility.h"
       
    48 #include    "svpsipconsts.h"
       
    49 
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // CSVPHoldContext::CSVPHoldContext
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 CSVPHoldContext::CSVPHoldContext( TMceTransactionDataContainer& aContainer,
       
    56                                   TBool aIsMobileOriginated ) :
       
    57         iStates( NULL ),
       
    58         iObserver( NULL ),
       
    59         iCurrentState( NULL ),
       
    60         iHoldRequest( ESVPNoType ),
       
    61         iSession( NULL ),
       
    62         iOutgoing( ETrue ),
       
    63         iAttributeHandler( NULL ),
       
    64         iMediaHandler( NULL ),
       
    65         iFirstAttempt( ETrue ),
       
    66         iRemoteRequestNotProcessed( ETrue ),
       
    67         iContainer( aContainer ),
       
    68         iAllowAudioHandling( EFalse ),
       
    69         iResponseStatusCode( KErrNotFound ),
       
    70         iForceHoldOccured( EFalse ),
       
    71         iTimedOut( EFalse ),
       
    72         iRollBack( EFalse ),
       
    73         iHoldFail( EFalse ),
       
    74         iResumeFail( EFalse ),
       
    75         iMuted( EFalse ),
       
    76         iCrossOver( EFalse ),
       
    77         iCallRequest( EFalse )
       
    78     {
       
    79     iIsMobileOriginated = aIsMobileOriginated;
       
    80     }
       
    81 
       
    82 // ---------------------------------------------------------------------------
       
    83 // CSVPHoldContext::ConstructL
       
    84 // ---------------------------------------------------------------------------
       
    85 //
       
    86 void CSVPHoldContext::ConstructL( CMceSession& aSession,
       
    87                                   MSVPHoldObserver* aObserver )
       
    88     {
       
    89     SVPDEBUG1( "CSVPHoldContext::ConstructL In" );
       
    90 
       
    91     iObserver = aObserver;
       
    92     // Create the states in the state array.
       
    93     InitializeStateArrayL();
       
    94     iAttributeHandler = CSVPHoldAttributeHandler::NewL();
       
    95     iMediaHandler = CSVPHoldMediaHandler::NewL();
       
    96     
       
    97     SetSessionObject( &aSession );
       
    98     
       
    99     // Initialize connected state to current state. Note, that it is not
       
   100     // applied yet.
       
   101     SetCurrentStateL( *this, KSVPHoldConnectedStateIndex );
       
   102     SetAudioHandlingAllowed( ETrue );
       
   103         
       
   104     SVPDEBUG1( "CSVPHoldContext::ConstructL Done" );
       
   105     }
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // CSVPHoldContext::NewL
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 CSVPHoldContext* CSVPHoldContext::NewL( 
       
   112                             CMceSession& aSession,
       
   113                             TMceTransactionDataContainer& aContainer,
       
   114                             MSVPHoldObserver* aObserver,
       
   115                             TBool aIsMobileOriginated )
       
   116     {    
       
   117     CSVPHoldContext* self = new ( ELeave ) CSVPHoldContext( aContainer,
       
   118                                                             aIsMobileOriginated );
       
   119     
       
   120     CleanupStack::PushL( self );
       
   121     self->ConstructL( aSession, aObserver );
       
   122     CleanupStack::Pop( self );
       
   123 
       
   124     return self;
       
   125     }
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // CSVPHoldContext::IsStateTransitionAccepted
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 TBool CSVPHoldContext::
       
   132 IsStateTransitionAccepted( const TSVPHoldStateIndex aStateIndex )
       
   133     {
       
   134     TSVPHoldStateIndex current = CurrentState();
       
   135     switch( current )
       
   136         {
       
   137         case KErrNotFound:
       
   138             {
       
   139             // Only connected state can be the first one.
       
   140             if ( KSVPHoldConnectedStateIndex == aStateIndex )
       
   141                 {
       
   142                 return ETrue;
       
   143                 }
       
   144             else
       
   145                 {
       
   146                 return EFalse;
       
   147                 }
       
   148             }
       
   149 
       
   150         case KSVPHoldConnectedStateIndex:
       
   151         case KSVPHoldInStateIndex:
       
   152         case KSVPHoldDHStateIndex:
       
   153             { 
       
   154             // From main states transitions to in or out establishing
       
   155             // states are accepted.
       
   156             if ( KSVPHoldEstablishingStateIndex  == aStateIndex )
       
   157                 {
       
   158                 return ETrue;
       
   159                 }
       
   160             else
       
   161                 {
       
   162                 return EFalse;
       
   163                 }
       
   164             }
       
   165         
       
   166         case KSVPHoldOutStateIndex:
       
   167             {
       
   168             // From hold out state transitions to in and out establishing
       
   169             // and connected states are accepted.
       
   170             if ( KSVPHoldEstablishingStateIndex  == aStateIndex ||
       
   171                  KSVPHoldConnectedStateIndex  == aStateIndex )
       
   172                 {
       
   173                 return ETrue;
       
   174                 }
       
   175             else
       
   176                 {
       
   177                 return EFalse;
       
   178                 }
       
   179             }
       
   180         
       
   181         case KSVPHoldEstablishingStateIndex:
       
   182             {
       
   183             // From establishing states transitions to main states
       
   184             // are accepted.
       
   185             if ( KSVPHoldEstablishingStateIndex == aStateIndex ||
       
   186                  KSVPHoldConnectedStateIndex  == aStateIndex ||
       
   187                  KSVPHoldOutStateIndex == aStateIndex ||
       
   188                  KSVPHoldInStateIndex == aStateIndex ||
       
   189                  KSVPHoldDHStateIndex == aStateIndex )
       
   190                 {
       
   191                 return ETrue;
       
   192                 }
       
   193             else
       
   194                 {
       
   195                 return EFalse;
       
   196                 }
       
   197             }
       
   198             
       
   199         default:
       
   200             {
       
   201             // Should not come here, since all the states are handled
       
   202             SVPDEBUG1( "CSVPHoldContext::IsStateTransitionAccepted - Error" );
       
   203             
       
   204             return EFalse;
       
   205             }
       
   206         }
       
   207     }
       
   208 
       
   209 // ---------------------------------------------------------------------------
       
   210 // CSVPHoldContext::~CSVPHoldContext
       
   211 // ---------------------------------------------------------------------------   
       
   212 //
       
   213 CSVPHoldContext::~CSVPHoldContext()
       
   214     {
       
   215     SVPDEBUG1( "CSVPHoldContext::~CSVPHoldContext - In" );
       
   216     if ( iStates )
       
   217         {
       
   218         iStates->ResetAndDestroy();
       
   219         iStates->Close();
       
   220         delete iStates;
       
   221         }
       
   222 
       
   223     delete iAttributeHandler;
       
   224     delete iMediaHandler;
       
   225     
       
   226     SVPDEBUG1( "CSVPHoldContext::~CSVPHoldContext - Done" );
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // CSVPHoldContext::InitializeStateArrayL
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 void CSVPHoldContext::InitializeStateArrayL()
       
   234     {
       
   235     // Create state array
       
   236     iStates = new ( ELeave ) RPointerArray< CSVPHoldStateBase >
       
   237                                                 ( KSVPHoldStateArraySize );
       
   238     // States are created here:
       
   239 
       
   240     // Connected state
       
   241     CSVPHoldConnectedState* connectedState =
       
   242                     CSVPHoldConnectedState::NewLC();
       
   243     User::LeaveIfError( iStates->Insert( connectedState,
       
   244                                          KSVPHoldConnectedStateIndex ) );
       
   245     CleanupStack::Pop( connectedState );
       
   246 
       
   247     // Establishing state initialized to outgoing (MO hold)
       
   248     CSVPHoldOutEstablishingState* outEstState =
       
   249                     CSVPHoldOutEstablishingState::NewLC();
       
   250     User::LeaveIfError( iStates->Insert( outEstState,
       
   251                                          KSVPHoldEstablishingStateIndex ) );
       
   252     CleanupStack::Pop( outEstState );
       
   253 
       
   254     // Outgoing state (MO hold)
       
   255     CSVPHoldOutState* outState =
       
   256                     CSVPHoldOutState::NewLC();
       
   257     User::LeaveIfError( iStates->Insert( outState,
       
   258                                          KSVPHoldOutStateIndex ) );
       
   259     CleanupStack::Pop( outState );
       
   260         
       
   261     // Incoming state (MT hold)
       
   262     CSVPHoldInState* inState =
       
   263                     CSVPHoldInState::NewLC();
       
   264     User::LeaveIfError( iStates->Insert( inState,
       
   265                                          KSVPHoldInStateIndex ) );
       
   266     CleanupStack::Pop( inState );
       
   267     
       
   268     // Doublehold state (MO & MT simultaneous hold)
       
   269     CSVPHoldDHState* dhState =
       
   270                     CSVPHoldDHState::NewLC();
       
   271     User::LeaveIfError( iStates->Insert( dhState,
       
   272                                          KSVPHoldDHStateIndex ) );
       
   273     CleanupStack::Pop( dhState );
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------------------------
       
   277 // CSVPHoldContext::SetCurrentStateL
       
   278 // ---------------------------------------------------------------------------
       
   279 //
       
   280 void CSVPHoldContext::SetCurrentStateL( CSVPHoldContext& aContext,
       
   281                                         TSVPHoldStateIndex aStateIndex )
       
   282     {
       
   283     // Check that the transition is valid:
       
   284     if ( !IsStateTransitionAccepted( aStateIndex ) )
       
   285         {
       
   286         SVPDEBUG2( "CSVPHoldContext::SetCurrentStateL - State error, New: %i",
       
   287                     aStateIndex );
       
   288 
       
   289         User::Leave( KErrSVPHoldStateError );
       
   290         }        
       
   291     else
       
   292         {
       
   293         SVPDEBUG2( "CSVPHoldContext::SetCurrentStateL - Set state from %i",
       
   294                     CurrentState() );
       
   295          
       
   296         SVPDEBUG2( "CSVPHoldContext::SetCurrentStateL - Set state to %i",
       
   297                     aStateIndex );
       
   298 
       
   299         iCurrentState = ( *iStates )[ aStateIndex ];
       
   300         iCurrentState->Enter( aContext );
       
   301         iAllowAudioHandling = ETrue;
       
   302         }
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------------------------
       
   306 // CSVPHoldContext::CurrentState
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 TSVPHoldStateIndex CSVPHoldContext::CurrentState() const
       
   310    {
       
   311    return iStates->Find( iCurrentState );
       
   312    }
       
   313 
       
   314 // ---------------------------------------------------------------------------
       
   315 // CSVPHoldContext::ApplyCurrentStateL
       
   316 // ---------------------------------------------------------------------------
       
   317 //
       
   318 void CSVPHoldContext::ApplyCurrentStateL( CMceSession* aSession,
       
   319                     TSVPHoldDesiredTransition aTransition )
       
   320     {
       
   321     SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL IN" )
       
   322     
       
   323     // Set back to false, because new hold/resume attemp starts
       
   324     iRollBack = EFalse;
       
   325     
       
   326     SetSessionObject( aSession );
       
   327     if ( ToEstablishing() && FirstAttempt() )
       
   328         {
       
   329         SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL - New request" )
       
   330         
       
   331         iHoldRequest = RequestType( aTransition );
       
   332         UpdateEstablishingStateL();
       
   333         }
       
   334 
       
   335     if ( ESVPHoldIncoming == aTransition )
       
   336         {
       
   337         SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL - Remote request" )
       
   338         
       
   339         iHoldRequest = RequestType( aTransition );        
       
   340         SetRemoteRequestNotProcessed( ETrue );
       
   341         iCurrentState->ApplyL( *this );
       
   342         }
       
   343     
       
   344     else
       
   345         {
       
   346         SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL - Local request" )
       
   347         
       
   348         iHoldRequest = RequestType( aTransition );
       
   349         if ( ESVPLocalResume == iHoldRequest )
       
   350             {
       
   351             SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL - Enable oldway hold" );
       
   352             
       
   353             // establish Old way hold support 
       
   354             aSession->SetModifierL( KMceMediaDirection, 
       
   355                                     KMceMediaDirectionWithAddress );
       
   356             }
       
   357             
       
   358         iCurrentState->ApplyL( *this );
       
   359         }
       
   360         
       
   361     SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL OUT" )
       
   362     }
       
   363 
       
   364 // ---------------------------------------------------------------------------
       
   365 // CSVPHoldContext::ApplyCurrentStateL
       
   366 // ---------------------------------------------------------------------------
       
   367 //
       
   368 void CSVPHoldContext::ApplyCurrentStateL()
       
   369     {
       
   370     if ( KSVPHoldEstablishingStateIndex == CurrentState() )
       
   371         {
       
   372         SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL2" );
       
   373         iCurrentState->ApplyL( *this );
       
   374         }
       
   375     else
       
   376         {
       
   377         SVPDEBUG1( "CSVPHoldContext::ApplyCurrentStateL2 - State error" );
       
   378         User::Leave( KErrSVPHoldStateError );
       
   379         }
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // CSVPHoldContext::SetSessionObject
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 void CSVPHoldContext::SetSessionObject( CMceSession* aSession )
       
   387     {
       
   388     iSession = aSession;
       
   389     }
       
   390 
       
   391 // ---------------------------------------------------------------------------
       
   392 // CSVPHoldContext::SessionObject
       
   393 // ---------------------------------------------------------------------------
       
   394 //
       
   395 CMceSession* CSVPHoldContext::SessionObject()
       
   396     {
       
   397     return iSession;
       
   398     }
       
   399 
       
   400 // ---------------------------------------------------------------------------
       
   401 // CSVPHoldContext::HoldRequest
       
   402 // ---------------------------------------------------------------------------
       
   403 //
       
   404 TSVPHoldRequestType CSVPHoldContext::HoldRequest()
       
   405     {
       
   406     return iHoldRequest;
       
   407     }
       
   408 
       
   409 
       
   410 // ---------------------------------------------------------------------------
       
   411 // CSVPHoldContext::IsRemoteRequest
       
   412 // ---------------------------------------------------------------------------
       
   413 //
       
   414 TBool CSVPHoldContext::IsRemoteRequest()
       
   415     {
       
   416     TSVPHoldRequestType request = HoldRequest();
       
   417     if ( ESVPRemoteHold == request || ESVPRemoteResume == request ||
       
   418          ESVPRemoteDoubleHold == request ||
       
   419          ESVPRemoteDoubleHoldResume == request )
       
   420         {
       
   421         return ETrue;
       
   422         }
       
   423     else
       
   424         {
       
   425         return EFalse;
       
   426         }
       
   427     }
       
   428 
       
   429 // ---------------------------------------------------------------------------
       
   430 // CSVPHoldContext::HoldEvent
       
   431 // ---------------------------------------------------------------------------
       
   432 //
       
   433 MCCPCallObserver::TCCPCallEvent CSVPHoldContext::HoldEvent()
       
   434     {
       
   435     return iHoldEvent;
       
   436     }
       
   437 
       
   438 // ---------------------------------------------------------------------------
       
   439 // CSVPHoldContext::SetFirstAttempt
       
   440 // ---------------------------------------------------------------------------
       
   441 //
       
   442 void CSVPHoldContext::SetFirstAttempt( TBool aValue )
       
   443     {
       
   444     iFirstAttempt = aValue;
       
   445     }
       
   446     
       
   447 // ---------------------------------------------------------------------------
       
   448 // CSVPHoldContext::FirstAttempt
       
   449 // ---------------------------------------------------------------------------
       
   450 //
       
   451 TBool CSVPHoldContext::FirstAttempt()
       
   452     {
       
   453     return iFirstAttempt;
       
   454     }
       
   455 
       
   456     
       
   457 // ---------------------------------------------------------------------------
       
   458 // CSVPHoldContext::SetRemoteRequestNotProcessed
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 void CSVPHoldContext::SetRemoteRequestNotProcessed( TBool aValue )
       
   462     {
       
   463     iRemoteRequestNotProcessed = aValue;
       
   464     }
       
   465     
       
   466 // ---------------------------------------------------------------------------
       
   467 // CSVPHoldContext::RemoteRequestNotProcessed
       
   468 // ---------------------------------------------------------------------------
       
   469 //
       
   470 TBool CSVPHoldContext::RemoteRequestNotProcessed()
       
   471     {
       
   472     return iRemoteRequestNotProcessed;
       
   473     }
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // CSVPHoldContext::SetAudioHandlingAllowed
       
   477 // ---------------------------------------------------------------------------
       
   478 //
       
   479 void CSVPHoldContext::SetAudioHandlingAllowed( TBool aValue )
       
   480     {
       
   481     iAllowAudioHandling = aValue;
       
   482     }
       
   483     
       
   484 // ---------------------------------------------------------------------------
       
   485 // CSVPHoldContext::AudioHandlingAllowed
       
   486 // ---------------------------------------------------------------------------
       
   487 //
       
   488 TBool CSVPHoldContext::AudioHandlingAllowed()
       
   489     {
       
   490     return iAllowAudioHandling;
       
   491     }
       
   492 
       
   493 // ---------------------------------------------------------------------------
       
   494 // CSVPHoldContext::CheckOldwayHoldL
       
   495 // ---------------------------------------------------------------------------
       
   496 //
       
   497 TSVPHoldRequestType CSVPHoldContext::
       
   498 CheckOldwayHoldL( CMceSession& aSession,
       
   499                   TSVPHoldRequestType aPresumedRequest )
       
   500     {
       
   501     SVPDEBUG1( "CSVPHoldContext::CheckOldwayHoldL" );
       
   502     
       
   503     TBool oldWayHold = EFalse;    
       
   504     const RPointerArray< CMceMediaStream >& mediaStreams = aSession.Streams();
       
   505         
       
   506     for ( TInt i = 0; i < mediaStreams.Count(); i++ )
       
   507         {
       
   508         CMceAudioStream* stream = 
       
   509             static_cast< CMceAudioStream* >( mediaStreams[ i ] );
       
   510         
       
   511         if ( !SVPAudioUtility::IsDownlinkStream( *stream ) )
       
   512             {
       
   513             if ( !stream->IsEnabled() )
       
   514                 {
       
   515                 oldWayHold = ETrue;
       
   516                 }
       
   517             }
       
   518 
       
   519         else if ( stream->BoundStream() )
       
   520             {
       
   521             CMceMediaStream& boundStream = stream->BoundStreamL();
       
   522             if ( !boundStream.IsEnabled() )
       
   523                 {
       
   524                 oldWayHold = ETrue;
       
   525                 }
       
   526             }
       
   527         }
       
   528     
       
   529     if ( !oldWayHold )
       
   530         {
       
   531         // Oldway hold not in offer
       
   532         SVPDEBUG1( "CSVPHoldContext::CheckOldwayHoldL - Direction only" );
       
   533         return ESVPNoType;
       
   534         }
       
   535         
       
   536     else
       
   537         {
       
   538         // Oldway hold used in offer
       
   539         SVPDEBUG1( "CSVPHoldContext::CheckOldwayHoldL - Oldway hold ON" );
       
   540         TUint modValue = KMceMediaDirectionWithAddress;
       
   541         TMceSessionModifier modifier = KMceMediaDirection;
       
   542         aSession.SetModifierL( modifier, modValue );
       
   543         return aPresumedRequest;
       
   544         }
       
   545     }
       
   546 
       
   547     
       
   548 // ---------------------------------------------------------------------------
       
   549 // CSVPHoldContext::HoldObserver
       
   550 // ---------------------------------------------------------------------------
       
   551 //
       
   552 MSVPHoldObserver& CSVPHoldContext::HoldObserver()
       
   553     {
       
   554     return *iObserver;
       
   555     }
       
   556         
       
   557 // ---------------------------------------------------------------------------
       
   558 // CSVPHoldContext::AttributeHandler
       
   559 // ---------------------------------------------------------------------------
       
   560 //
       
   561 CSVPHoldAttributeHandler& CSVPHoldContext::AttributeHandler()
       
   562     {
       
   563     return *iAttributeHandler;
       
   564     }
       
   565 
       
   566 // ---------------------------------------------------------------------------
       
   567 // CSVPHoldContext::MediaHandler
       
   568 // ---------------------------------------------------------------------------
       
   569 //
       
   570 CSVPHoldMediaHandler& CSVPHoldContext::MediaHandler()
       
   571     {
       
   572     return *iMediaHandler;
       
   573     }
       
   574 
       
   575 // ---------------------------------------------------------------------------
       
   576 // CSVPHoldContext::SolveRequestL
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 TSVPHoldRequestType 
       
   580 CSVPHoldContext::SolveRequestL( CMceSession& aSession,
       
   581                                 MDesC8Array* aAttributeLines,
       
   582                                 TBool aCheckOldwayHold )
       
   583     { 
       
   584     SVPDEBUG1( "CSVPHoldContext::SolveRequestL IN" )
       
   585     
       
   586     TSVPHoldRequestType presumedRequest = HoldRequest();
       
   587     TInt attributeIndex =
       
   588         iAttributeHandler->FindDirectionAttribute( aAttributeLines );
       
   589 
       
   590     SVPDEBUG2( "CSVPHoldContext::SolveRequestL - attributeIndex = %i",
       
   591         attributeIndex )
       
   592     SVPDEBUG2( "CSVPHoldContext::SolveRequestL - presumedRequest = %i",
       
   593         presumedRequest )
       
   594     
       
   595     // Match Current state, attributeIndex and presumedRequest
       
   596     TSVPHoldRequestType realizedRequest = 
       
   597         SolveRequestType( attributeIndex, presumedRequest );
       
   598     
       
   599     SVPDEBUG2( "CSVPHoldContext::SolveRequestL - realizedRequest = %i",
       
   600         realizedRequest )
       
   601     
       
   602     if ( ESVPNoType == realizedRequest && aCheckOldwayHold )
       
   603         {
       
   604         SVPDEBUG1( "CSVPHoldContext::SolveRequestL - Check oldway hold" )
       
   605         
       
   606         realizedRequest = CheckOldwayHoldL( aSession, presumedRequest );
       
   607                                             
       
   608         SVPDEBUG2( "CSVPHoldContext::SolveRequestL - if:realizedRequest = %i",
       
   609             realizedRequest )
       
   610         }
       
   611                 
       
   612     return realizedRequest;
       
   613     }
       
   614 
       
   615 // ---------------------------------------------------------------------------
       
   616 // CSVPHoldContext::SolveRequestTypeL
       
   617 // Solves type of incoming request and returns accepted request type
       
   618 // ---------------------------------------------------------------------------
       
   619 //
       
   620 TSVPHoldRequestType 
       
   621 CSVPHoldContext::SolveRequestType( TInt aAttributeIndex,
       
   622                                    TSVPHoldRequestType aPresumedRequest )
       
   623     {
       
   624     SVPDEBUG1( "CSVPHoldContext::SolveRequestType - Type is" );
       
   625     
       
   626     switch ( aPresumedRequest )
       
   627         {
       
   628         case ESVPRemoteHold:
       
   629             {
       
   630             // From connected state, MT hold requests:
       
   631             SVPDEBUG1( "    ESVPRemoteHold" );
       
   632             if ( KSVPHoldSendonlyIndex == aAttributeIndex ||
       
   633                  KSVPHoldInactiveIndex == aAttributeIndex )
       
   634                 {
       
   635                 // Incoming hold
       
   636                 return ESVPRemoteHold; 
       
   637                 }
       
   638 
       
   639             else
       
   640                 {
       
   641                 SVPDEBUG1( "    ESVPNoType" );
       
   642                 return ESVPNoType;
       
   643                 }
       
   644             }
       
   645         
       
   646         case ESVPRemoteResume:
       
   647             {            
       
   648             SVPDEBUG1( "    ESVPRemoteResume" );
       
   649             if ( KSVPHoldSendrecvIndex == aAttributeIndex ||
       
   650                  KErrNotFound == aAttributeIndex )
       
   651                 {
       
   652                 // Incoming resume
       
   653                 return ESVPRemoteResume; 
       
   654                 }
       
   655                                 
       
   656             else
       
   657                 {
       
   658                 SVPDEBUG1( "    ESVPNoType" );
       
   659                 return ESVPNoType;
       
   660                 }                
       
   661             }
       
   662         
       
   663         case ESVPRemoteDoubleHold:
       
   664             {
       
   665             SVPDEBUG1( "    ESVPRemoteDoubleHold" );
       
   666             if ( KSVPHoldInactiveIndex == aAttributeIndex )
       
   667                 {
       
   668                 // Incoming doublehold
       
   669                 return ESVPRemoteDoubleHold;
       
   670                 }
       
   671 
       
   672             else
       
   673                 {
       
   674                 SVPDEBUG1( "    ESVPNoType" );
       
   675                 return ESVPNoType;
       
   676                 }
       
   677             }
       
   678         
       
   679         case ESVPRemoteDoubleHoldResume:
       
   680             {
       
   681             SVPDEBUG1( "    ESVPRemoteDHResume" );
       
   682             if ( KSVPHoldRecvonlyIndex == aAttributeIndex ||
       
   683                  KSVPHoldSendrecvIndex == aAttributeIndex )
       
   684                 {
       
   685                 // Incoming doublehold resume
       
   686                 return ESVPRemoteDoubleHoldResume;
       
   687                 }
       
   688 
       
   689             else
       
   690                 {
       
   691                 SVPDEBUG1( "    ESVPNoType" );
       
   692                 return ESVPNoType;
       
   693                 }
       
   694             }
       
   695         
       
   696         
       
   697         // -fallthtrough
       
   698         case ESVPLocalHold:
       
   699         case ESVPLocalResume:
       
   700         case ESVPLocalDoubleHold:
       
   701         case ESVPLocalDoubleHoldResume:
       
   702         default:
       
   703             {
       
   704             // Local actions not handled here:
       
   705             SVPDEBUG1( "CSVPHoldContext::SolveRequestType - Default" );            
       
   706             return ESVPNoType;
       
   707             }
       
   708         }
       
   709     }
       
   710 
       
   711 // ---------------------------------------------------------------------------
       
   712 // CSVPHoldContext::ToEstablishing
       
   713 // Solves if the next state should be establishing state
       
   714 // ---------------------------------------------------------------------------
       
   715 //
       
   716 TBool CSVPHoldContext::ToEstablishing()
       
   717     {
       
   718     if ( KSVPHoldEstablishingStateIndex != CurrentState() )
       
   719         {
       
   720         SVPDEBUG1( "CSVPHoldContext::ToEstablishing TRUE" )
       
   721         
       
   722         return ETrue;
       
   723         }
       
   724     else
       
   725         {
       
   726         SVPDEBUG1( "CSVPHoldContext::ToEstablishing FALSE" )
       
   727         
       
   728         return EFalse;
       
   729         }
       
   730     }
       
   731     
       
   732 // ---------------------------------------------------------------------------
       
   733 // CSVPHoldContext::RequestType
       
   734 // Solves request type based on current state and external request and
       
   735 // direction of request
       
   736 // ---------------------------------------------------------------------------
       
   737 //
       
   738 TSVPHoldRequestType 
       
   739 CSVPHoldContext::RequestType( TSVPHoldDesiredTransition aTransition )
       
   740     {
       
   741     // switch-case structure has no breaks because every case has return.
       
   742     switch ( aTransition )
       
   743         {
       
   744         case ESVPHoldToHold:
       
   745             {
       
   746             return RequestToHold();
       
   747             }
       
   748         
       
   749         case ESVPHoldToResume:
       
   750             {
       
   751             return RequestToResume();
       
   752             }
       
   753         
       
   754         case ESVPHoldIncoming:
       
   755             {
       
   756             return RequestIncoming();
       
   757             }
       
   758             
       
   759         default:
       
   760             {
       
   761             SVPDEBUG1( "CSVPHoldContext::RequestType - no transition!" );
       
   762 
       
   763             return ESVPNoType;
       
   764             }
       
   765         }
       
   766     }
       
   767 
       
   768 
       
   769 // ---------------------------------------------------------------------------
       
   770 // CSVPHoldContext::RequestToHold
       
   771 // Solves request type for local hold
       
   772 // ---------------------------------------------------------------------------
       
   773 //
       
   774 TSVPHoldRequestType CSVPHoldContext::RequestToHold()
       
   775     {
       
   776     SVPDEBUG1( "CSVPHoldContext::RequestToHold" );
       
   777         
       
   778     TSVPHoldStateIndex current = CurrentState();
       
   779     iOutgoing = ETrue;
       
   780     iHoldEvent = MCCPCallObserver::ECCPLocalHold;
       
   781 
       
   782     if ( KSVPHoldConnectedStateIndex == current )
       
   783         {
       
   784         return ESVPLocalHold;
       
   785         }
       
   786 
       
   787     else if ( KSVPHoldInStateIndex == current )
       
   788         {
       
   789         return ESVPLocalDoubleHold;
       
   790         }
       
   791 
       
   792     else
       
   793         {
       
   794         SVPDEBUG2( "CSVPHoldContext::RequestToHold - error(ToHold), %i",
       
   795                     current );
       
   796 
       
   797         return ESVPNoType;
       
   798         }    
       
   799     }
       
   800     
       
   801     
       
   802 // ---------------------------------------------------------------------------
       
   803 // CSVPHoldContext::RequestToResume
       
   804 // Solves request type for local resume
       
   805 // ---------------------------------------------------------------------------
       
   806 //
       
   807 TSVPHoldRequestType CSVPHoldContext::RequestToResume()
       
   808     {
       
   809     SVPDEBUG1( "CSVPHoldContext::RequestToResume" );
       
   810     
       
   811     TSVPHoldStateIndex current = CurrentState();
       
   812     iOutgoing = ETrue;
       
   813     iHoldEvent = MCCPCallObserver::ECCPLocalResume;
       
   814     if ( KSVPHoldOutStateIndex == current )
       
   815         {
       
   816         return ESVPLocalResume;
       
   817         }
       
   818         
       
   819     else if ( KSVPHoldDHStateIndex == current )
       
   820         {
       
   821         return ESVPLocalDoubleHoldResume;
       
   822         }
       
   823         
       
   824     else
       
   825         {
       
   826         SVPDEBUG2( "CSVPHoldContext::RequestToResume - error(ToResume), %i",
       
   827                     current );
       
   828 
       
   829         return ESVPNoType;
       
   830         }    
       
   831     }
       
   832     
       
   833     
       
   834 // ---------------------------------------------------------------------------
       
   835 // CSVPHoldContext::RequestIncoming
       
   836 // Solves request type for incoming request
       
   837 // ---------------------------------------------------------------------------
       
   838 //
       
   839 TSVPHoldRequestType CSVPHoldContext::RequestIncoming()
       
   840     {
       
   841     SVPDEBUG1( "CSVPHoldContext::RequestIncoming: Incoming" )
       
   842 
       
   843     // In this case return value stands for the most probable request:
       
   844     const TSVPHoldStateIndex current = CurrentState();
       
   845     SVPDEBUG2( "CSVPHoldContext::RequestIncoming - current = %i",
       
   846                 current );    
       
   847     
       
   848     iOutgoing = EFalse;
       
   849     if ( KSVPHoldConnectedStateIndex == current )
       
   850         {
       
   851         iHoldEvent = MCCPCallObserver::ECCPRemoteHold;
       
   852         return ESVPRemoteHold;
       
   853         }
       
   854         
       
   855     else if ( KSVPHoldInStateIndex == current )
       
   856         {
       
   857         iHoldEvent = MCCPCallObserver::ECCPRemoteResume;
       
   858         return ESVPRemoteResume;
       
   859         }
       
   860 
       
   861     else if ( KSVPHoldOutStateIndex == current )
       
   862         {
       
   863         iHoldEvent = MCCPCallObserver::ECCPRemoteHold;
       
   864         return ESVPRemoteDoubleHold;
       
   865         }
       
   866 
       
   867     else if ( KSVPHoldDHStateIndex == current )
       
   868         {
       
   869         iHoldEvent = MCCPCallObserver::ECCPRemoteResume;
       
   870         return ESVPRemoteDoubleHoldResume;
       
   871         }
       
   872         
       
   873     else
       
   874         {
       
   875         SVPDEBUG2( "CSVPHoldContext::RequestIncoming - error(Incoming), %i",
       
   876                     current );
       
   877 
       
   878         return ESVPNoType;
       
   879         }    
       
   880     }
       
   881     
       
   882 
       
   883 // ---------------------------------------------------------------------------
       
   884 // CSVPHoldContext::UpdateEstablishingStateL
       
   885 // Updates correct establishing state to state array
       
   886 // ---------------------------------------------------------------------------
       
   887 //
       
   888 void CSVPHoldContext::UpdateEstablishingStateL()
       
   889     {
       
   890     TBool outEstablishingActive =
       
   891             ( *iStates )[ KSVPHoldEstablishingStateIndex ]->
       
   892                                 IsOutEstablishingStateActive();
       
   893     
       
   894     if ( iOutgoing && !outEstablishingActive )
       
   895         {
       
   896         // OutEstablishingState is needed to state array
       
   897         delete ( *iStates )[ KSVPHoldEstablishingStateIndex ];
       
   898         iStates->Remove( KSVPHoldEstablishingStateIndex );
       
   899 
       
   900         CSVPHoldOutEstablishingState* outEstState =
       
   901                         CSVPHoldOutEstablishingState::NewLC();
       
   902                         
       
   903         User::LeaveIfError( iStates->Insert( outEstState,
       
   904                                              KSVPHoldEstablishingStateIndex ) );
       
   905         CleanupStack::Pop( outEstState );
       
   906 
       
   907         SVPDEBUG1( "CSVPHoldContext::UpdateEstablishingStateL - Outgoing" );
       
   908         }
       
   909         
       
   910     else if ( !iOutgoing && outEstablishingActive )
       
   911         {
       
   912         // InEstablishingState is needed to state array
       
   913         delete ( *iStates )[ KSVPHoldEstablishingStateIndex ];
       
   914         iStates->Remove( KSVPHoldEstablishingStateIndex );
       
   915 
       
   916         CSVPHoldInEstablishingState* inEstState =
       
   917                         CSVPHoldInEstablishingState::NewLC();
       
   918                         
       
   919         User::LeaveIfError( iStates->Insert( inEstState,
       
   920                                              KSVPHoldEstablishingStateIndex ) );
       
   921         CleanupStack::Pop( inEstState );
       
   922 
       
   923         SVPDEBUG1( "CSVPHoldContext::UpdateEstablishingStateL - Incoming" );
       
   924         }
       
   925         
       
   926     else
       
   927         {
       
   928         SVPDEBUG1( "CSVPHoldContext::UpdateEstablishingStateL - No update needed" );
       
   929         }
       
   930     }
       
   931 
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 // CSVPHoldContext::SetResponseStatusCode
       
   935 // Sets response status code
       
   936 // ---------------------------------------------------------------------------
       
   937 //
       
   938 void CSVPHoldContext::SetResponseStatusCode( TInt aStatusCode )
       
   939     {
       
   940     iResponseStatusCode = aStatusCode;
       
   941     }
       
   942     
       
   943     
       
   944 // ---------------------------------------------------------------------------
       
   945 // CSVPHoldContext::ResponseStatusCode
       
   946 // Gets response status code
       
   947 // ---------------------------------------------------------------------------
       
   948 //
       
   949 TInt CSVPHoldContext::ResponseStatusCode()
       
   950     {
       
   951     return iResponseStatusCode;
       
   952     }
       
   953 
       
   954 
       
   955 // ---------------------------------------------------------------------------
       
   956 // CSVPHoldContext::SetForceHold
       
   957 // Sets force hold flag value
       
   958 // ---------------------------------------------------------------------------
       
   959 //
       
   960 void CSVPHoldContext::SetForceHold( TBool aForceHold )
       
   961     {
       
   962     iForceHoldOccured = aForceHold;
       
   963     }
       
   964  
       
   965     
       
   966 // ---------------------------------------------------------------------------
       
   967 // CSVPHoldContext::ForceHoldOccured
       
   968 // Gets force hold flag value
       
   969 // ---------------------------------------------------------------------------
       
   970 //
       
   971 TBool CSVPHoldContext::ForceHoldOccured()
       
   972     {
       
   973     return iForceHoldOccured;
       
   974     }
       
   975 
       
   976 
       
   977 // ---------------------------------------------------------------------------
       
   978 // CSVPHoldContext::SpecialResponseHandling
       
   979 // Sets force hold flag value 
       
   980 // ---------------------------------------------------------------------------
       
   981 //
       
   982 TBool CSVPHoldContext::
       
   983 SpecialResponseHandling( TSVPHoldStateIndex& aNextState )
       
   984     {
       
   985     SVPDEBUG2( "CSVPHoldContext::SpecialResponseHandling - Code is %d ", 
       
   986                 ResponseStatusCode() );
       
   987 
       
   988     if ( KErrNotFound == ResponseStatusCode() && !iTimedOut )
       
   989         {
       
   990         SVPDEBUG1( "CSVPHoldContext::SpecialResponseHandling - Not needed" );
       
   991         return EFalse;
       
   992         }
       
   993         
       
   994     if ( iTimedOut )
       
   995         {
       
   996         // No response to request received
       
   997         SVPDEBUG1( "CSVPHoldContext::SpecialResponseHandling - Timed Out" );
       
   998 
       
   999         RollBack( aNextState );
       
  1000         iTimedOut = EFalse;
       
  1001         return ETrue;
       
  1002         }
       
  1003     
       
  1004     if ( KSVPOKVal == ResponseStatusCode() && iCallRequest )
       
  1005         {
       
  1006         SVPDEBUG1( "CSVPHoldContext::SpecialResponseHandling - Forced" );
       
  1007         RollBack( aNextState );
       
  1008         iTimedOut = EFalse;
       
  1009         return ETrue;
       
  1010         }
       
  1011         
       
  1012     else if ( KSVPBadRequestVal <= ResponseStatusCode() )
       
  1013         {
       
  1014         // Need to roll back to previous state and inform client
       
  1015         SVPDEBUG1( "CSVPHoldContext::SpecialResponseHandling - Request failure" );
       
  1016         RollBack( aNextState );
       
  1017         iTimedOut = EFalse;
       
  1018         return ETrue;
       
  1019         }
       
  1020     else
       
  1021         {
       
  1022         SVPDEBUG1( "CSVPHoldContext::SpecialResponseHandling - N/A" );
       
  1023         }
       
  1024         
       
  1025     return ETrue;   
       
  1026     }
       
  1027 
       
  1028 // ---------------------------------------------------------------------------
       
  1029 // CSVPHoldContext::TimedOut
       
  1030 // Sets force hold flag value
       
  1031 // ---------------------------------------------------------------------------
       
  1032 //
       
  1033 void CSVPHoldContext::TimedOut()
       
  1034     {
       
  1035     iTimedOut = ETrue;
       
  1036     }
       
  1037 
       
  1038 // ---------------------------------------------------------------------------
       
  1039 // CSVPHoldContext::HoldRolledBack
       
  1040 // Sets force hold flag value
       
  1041 // ---------------------------------------------------------------------------
       
  1042 //
       
  1043 TBool CSVPHoldContext::HoldRolledBack()
       
  1044     {
       
  1045     return iRollBack;
       
  1046     }
       
  1047 
       
  1048 // ---------------------------------------------------------------------------
       
  1049 // CSVPHoldContext::CrossOver
       
  1050 // Sets crossover situation on/off
       
  1051 // ---------------------------------------------------------------------------
       
  1052 //
       
  1053 void CSVPHoldContext::CrossOver( TBool aActive )
       
  1054     {
       
  1055     iCrossOver = aActive;
       
  1056     }
       
  1057 
       
  1058 // ---------------------------------------------------------------------------
       
  1059 // CSVPHoldContext::ResumeFailed
       
  1060 // Returns resume failed flag value
       
  1061 // ---------------------------------------------------------------------------
       
  1062 //
       
  1063 TBool CSVPHoldContext::ResumeFailed()
       
  1064     {
       
  1065     return iResumeFail;
       
  1066     }
       
  1067 
       
  1068 // ---------------------------------------------------------------------------
       
  1069 // CSVPHoldContext::HoldFailed
       
  1070 // Returns hold failed flag value
       
  1071 // ---------------------------------------------------------------------------
       
  1072 //
       
  1073 TBool CSVPHoldContext::HoldFailed()
       
  1074     {
       
  1075     if ( iHoldFail )
       
  1076         {
       
  1077         iHoldFail = EFalse;
       
  1078         return ETrue;        
       
  1079         }
       
  1080     else
       
  1081         {
       
  1082         return EFalse;
       
  1083         }
       
  1084     }
       
  1085 
       
  1086 // ---------------------------------------------------------------------------
       
  1087 // CSVPHoldContext::IsMobileOriginated
       
  1088 // Returns IsMobileOriginated -flag value
       
  1089 // ---------------------------------------------------------------------------
       
  1090 //
       
  1091 TBool CSVPHoldContext::IsMobileOriginated()
       
  1092     {
       
  1093     return iIsMobileOriginated;
       
  1094     }
       
  1095     
       
  1096 // ---------------------------------------------------------------------------
       
  1097 // CSVPHoldContext::Muted
       
  1098 // ---------------------------------------------------------------------------
       
  1099 //
       
  1100 void CSVPHoldContext::Muted( TBool aMuted )
       
  1101     {
       
  1102     iMuted = aMuted;
       
  1103     }
       
  1104     
       
  1105 // ---------------------------------------------------------------------------
       
  1106 // CSVPHoldContext::Muted
       
  1107 // ---------------------------------------------------------------------------
       
  1108 //
       
  1109 TBool CSVPHoldContext::Muted()
       
  1110     {
       
  1111     return iMuted;
       
  1112     }    
       
  1113     
       
  1114 // ---------------------------------------------------------------------------
       
  1115 // CSVPHoldContext::SetCallRequestFailed
       
  1116 // ---------------------------------------------------------------------------
       
  1117 //
       
  1118 void CSVPHoldContext::SetCallRequestFailed( TBool aCallRequest )
       
  1119     {
       
  1120     iCallRequest = aCallRequest;
       
  1121     }
       
  1122 
       
  1123 // ---------------------------------------------------------------------------
       
  1124 // CSVPHoldContext::CallRequestFailed
       
  1125 // ---------------------------------------------------------------------------
       
  1126 //
       
  1127 TBool CSVPHoldContext::CallRequestFailed()
       
  1128     {
       
  1129     return iCallRequest;
       
  1130     }
       
  1131 
       
  1132 // ---------------------------------------------------------------------------
       
  1133 // CSVPHoldContext::FallBack
       
  1134 // Rolls hold session state to its previous state
       
  1135 // ---------------------------------------------------------------------------
       
  1136 //
       
  1137 void CSVPHoldContext::RollBack( TSVPHoldStateIndex& aNextState )
       
  1138     {
       
  1139     SVPDEBUG1( "CSVPHoldContext::RollBack" );
       
  1140     iRollBack = ETrue;
       
  1141     switch ( HoldRequest() )
       
  1142         {
       
  1143         // in local hold request fail, not inform client until MCE session 
       
  1144         // state is back to connected state.
       
  1145         case ESVPLocalHold:
       
  1146             {
       
  1147             SVPDEBUG1( "CSVPHoldContext - Local Hold failed" );
       
  1148             aNextState = KSVPHoldConnectedStateIndex;
       
  1149             iHoldFail = ETrue;
       
  1150             if ( !iCrossOver )
       
  1151                 {
       
  1152                 HoldObserver().HoldRequestFailed();
       
  1153                 }
       
  1154             break;
       
  1155             }
       
  1156         
       
  1157         case ESVPLocalDoubleHold:
       
  1158             {
       
  1159             SVPDEBUG1( "CSVPHoldContext - Local DoubleHold failed" );
       
  1160             aNextState = KSVPHoldInStateIndex;
       
  1161             iHoldFail = ETrue;
       
  1162             if ( !iCrossOver )
       
  1163                 {
       
  1164                 HoldObserver().HoldRequestFailed();
       
  1165                 }
       
  1166             break;
       
  1167             }
       
  1168         
       
  1169         // Resume request fail can be informed immediately to client because
       
  1170         // session will be terminated.
       
  1171         case ESVPLocalResume:
       
  1172             {
       
  1173             SVPDEBUG1( "CSVPHoldContext - Local Resume failed" );
       
  1174             iResumeFail = ETrue;
       
  1175             aNextState = KSVPHoldOutStateIndex;
       
  1176             if ( !iCrossOver )
       
  1177                 {
       
  1178                 HoldObserver().ResumeRequestFailed();
       
  1179                 }
       
  1180             break;
       
  1181             }
       
  1182         
       
  1183         case ESVPLocalDoubleHoldResume:
       
  1184             {
       
  1185             SVPDEBUG1( "CSVPHoldContext - Local DoubleHold Resume failed" );
       
  1186             iResumeFail = ETrue;
       
  1187             aNextState = KSVPHoldDHStateIndex;
       
  1188             if ( !iCrossOver )
       
  1189                 {
       
  1190                 HoldObserver().ResumeRequestFailed();
       
  1191                 }
       
  1192             break;
       
  1193             }
       
  1194         
       
  1195         case ESVPRemoteResume:
       
  1196             {
       
  1197             SVPDEBUG1( "CSVPHoldContext - Remote Resume failed" );
       
  1198             aNextState = KSVPHoldInStateIndex;
       
  1199             break;
       
  1200             }
       
  1201             
       
  1202         default:
       
  1203             {
       
  1204             SVPDEBUG1( "CSVPHoldContext - Local DoubleHold Resume failed" );
       
  1205             break;
       
  1206             }
       
  1207         }    
       
  1208     }
       
  1209 
       
  1210 
       
  1211 
       
  1212 
       
  1213 //  End of File