sipvoipprovider/src/svpcontroller.cpp
branchRCL_3
changeset 22 d38647835c2e
equal deleted inserted replaced
21:f742655b05bf 22:d38647835c2e
       
     1 /*
       
     2 * Copyright (c) 2006-2009 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:  Handles all common logic for SVP and handles sessions.        
       
    15 *
       
    16 */
       
    17 
       
    18 #include <mcevideostream.h>
       
    19 #include <mceaudiocodec.h>
       
    20 #include <mcemediasink.h>
       
    21 #include <mcemediasource.h>
       
    22 #include <mceevent.h>
       
    23 #include <mcesession.h>
       
    24 #include <mceinrefer.h>
       
    25 #include <mcesecuresession.h>
       
    26 #include <mcertpsource.h>
       
    27 #include <mccpdtmfobserver.h>
       
    28 #include <sipstrings.h>
       
    29 #include <sipstrconsts.h>
       
    30 
       
    31 #include <crcseprofileentry.h>
       
    32 #include <crcseprofileregistry.h>
       
    33 
       
    34 #include <wlantrafficstreamparameters.h> // CWlanMgmtClient
       
    35 #include <ccpdefs.h>
       
    36 #include <featdiscovery.h>
       
    37 
       
    38 #include "svpcontroller.h"
       
    39 #include "svpmosession.h"
       
    40 #include "svpmtsession.h"
       
    41 #include "svplogger.h"
       
    42 #include "svptimer.h"
       
    43 #include "svputility.h"
       
    44 #include "svpholdcontext.h"
       
    45 #include "svpholdcontroller.h"
       
    46 #include "svpcleanupresetanddestroy.h"
       
    47 #include "svpaudioutility.h"
       
    48 #include "svpsipconsts.h"
       
    49 #include "svpemergencyiapprovider.h"
       
    50 #include "svprtpobserver.h"
       
    51 #include "svpsettings.h"
       
    52 #include "svptransferstatecontext.h"
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // CSVPController::CSVPController
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 CSVPController::CSVPController() : iSessionUpdateOngoing( EFalse )
       
    59     {
       
    60     
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CSVPController::ConstructL
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 void CSVPController::ConstructL()
       
    68     {
       
    69     SVPDEBUG1( "CSVPController::ConstructL In" )
       
    70     
       
    71     iIncomingReferCallIndex = KErrNotFound;
       
    72     iHoldCallIndex = KErrNotFound;
       
    73     iSuppServices = CSVPSupplementaryServices::NewL();
       
    74     iSVPUtility = CSVPUtility::NewL();
       
    75     iRtpObserver = CSVPRtpObserver::NewL();
       
    76     TBool wlanSupported = CFeatureDiscovery::IsFeatureSupportedL( KFeatureIdProtocolWlan );
       
    77 #ifndef __WINS__
       
    78     if ( wlanSupported )
       
    79         {
       
    80         iWlanMgmt = CWlanMgmtClient::NewL();
       
    81         }
       
    82 #endif // __WINS__
       
    83 
       
    84     SVPDEBUG1( "CSVPController::ConstructL Out" )
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // CSVPController::NewL
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 CSVPController* CSVPController::NewL()
       
    92     {
       
    93     CSVPController* self = new ( ELeave ) CSVPController();
       
    94     CleanupStack::PushL( self );
       
    95     self->ConstructL();
       
    96     CleanupStack::Pop( self );
       
    97     return self;
       
    98     }
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // CSVPController::~CSVPController
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 CSVPController::~CSVPController()
       
   105     {
       
   106     SVPDEBUG1( "CSVPController::~CSVPController In" )
       
   107     
       
   108 #ifndef __WINS__
       
   109     delete iWlanMgmt;
       
   110 #endif // __WINS__
       
   111 
       
   112     delete iSVPUtility;
       
   113     
       
   114     // clean array that contains SVP sessions.
       
   115     iSessionArray.ResetAndDestroy();
       
   116     iSessionArray.Close();
       
   117     
       
   118     // SVP emergency session
       
   119     delete iEmergencySession;
       
   120  
       
   121     iEmergencyProfileIds.Close();
       
   122     iEmergencyIapIds.Close();
       
   123     
       
   124     delete iSuppServices;
       
   125     delete iMceManager;
       
   126     delete iRtpObserver;
       
   127     
       
   128     delete iDtmfString;
       
   129     
       
   130     SVPDEBUG1( "CSVPController::~CSVPController Out" )
       
   131     }
       
   132 
       
   133 // ---------------------------------------------------------------------------
       
   134 // CSVPController::InitializeL 
       
   135 // ---------------------------------------------------------------------------
       
   136 //
       
   137 void CSVPController::InitializeL( const TUint32 aServiceId,
       
   138 		  					      const MCCPObserver& aMonitor, 
       
   139 		                          const MCCPSsObserver& aSsObserver )
       
   140     {
       
   141     
       
   142     SVPDEBUG2( "CSVPController::InitializeL serviceId = %d", aServiceId )
       
   143     
       
   144     SVPDEBUG2( "CSVPController::InitializeL iCCPMonitor: 0x%x", iCCPMonitor )
       
   145     
       
   146     //Find callprovider plugin uid that should be used when registering to MCE
       
   147     TInt ccpUid = SvpSettings::IntPropertyL( aServiceId, 
       
   148 										EPropertyCallProviderPluginId );
       
   149     SVPDEBUG2( "CSVPController::InitializeL callproviderpluginuid=%d", ccpUid )
       
   150 
       
   151     // See CConvergedCallProvider API documentation. If already called,
       
   152     // leave with KErrAlreadyExists.
       
   153     __ASSERT_ALWAYS( !iCCPMonitor, User::Leave( KErrAlreadyExists ) );
       
   154     __ASSERT_ALWAYS( !iCCPSsObserver, User::Leave( KErrAlreadyExists ) );
       
   155     __ASSERT_ALWAYS( iSVPUtility, User::Leave( KErrNotReady ) );
       
   156     __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrNotReady ) );
       
   157     
       
   158     // save CCP monitor 
       
   159     iCCPMonitor = const_cast< MCCPObserver* >( &aMonitor );
       
   160      
       
   161     // save CCP Supplementary Services observer
       
   162     iCCPSsObserver = const_cast< MCCPSsObserver* >( &aSsObserver );
       
   163     
       
   164     // get terminal type and wlan mac address, needed for user agent header
       
   165     iSVPUtility->GetTerminalTypeL( iTerminalType );
       
   166     iSVPUtility->GetWlanMACAddressL( iWlanMacAddress );
       
   167     
       
   168     TUid uid = { ccpUid };
       
   169     // create Mce Manager, establishes connection to Mce server
       
   170     iMceManager = CMceManager::NewL( uid, &iContainer );
       
   171     
       
   172     // set observers for asynchronous events
       
   173     iMceManager->SetSessionObserver( this );
       
   174     iMceManager->SetInSessionObserver( this );
       
   175     iMceManager->SetInReferObserver( this );
       
   176     iMceManager->SetReferObserver( this );
       
   177     iMceManager->SetMediaObserver( this );
       
   178     iMceManager->SetEventObserver( this );
       
   179     iMceManager->SetDtmfObserver( this );
       
   180     iMceManager->SetRtpObserver( iRtpObserver );
       
   181     
       
   182     iTrafficStreamCreated = EFalse;
       
   183     
       
   184     SVPDEBUG1( "CSVPController::InitializeL Out" )
       
   185     } 
       
   186 
       
   187 // ---------------------------------------------------------------------------
       
   188 // CSVPController::InitializeL 
       
   189 // ---------------------------------------------------------------------------
       
   190 //
       
   191 void CSVPController::InitializeL( const MCCPObserver& aMonitor,
       
   192                                   const MCCPSsObserver& aSsObserver )
       
   193     {
       
   194     SVPDEBUG2( "CSVPController::InitializeL iCCPMonitor: 0x%x", iCCPMonitor )
       
   195     SVPDEBUG2( "CSVPController::InitializeL iCCPSsObserver: 0x%x", iCCPSsObserver )
       
   196     
       
   197     // See CConvergedCallProvider API documentation. If already called,
       
   198     // leave with KErrAlreadyExists.
       
   199     __ASSERT_ALWAYS( !iCCPMonitor, User::Leave( KErrAlreadyExists ) );
       
   200     __ASSERT_ALWAYS( !iCCPSsObserver, User::Leave( KErrAlreadyExists ) );
       
   201     __ASSERT_ALWAYS( iSVPUtility, User::Leave( KErrNotReady ) );
       
   202     __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrNotReady ) );
       
   203     
       
   204     // save CCP monitor 
       
   205     iCCPMonitor = const_cast< MCCPObserver* >( &aMonitor );
       
   206     
       
   207     // save CCP Supplementary Services observer
       
   208     iCCPSsObserver = const_cast< MCCPSsObserver* >( &aSsObserver );
       
   209 
       
   210     // get terminal type and wlan mac address, needed for user agent header
       
   211     iSVPUtility->GetTerminalTypeL( iTerminalType );
       
   212     iSVPUtility->GetWlanMACAddressL( iWlanMacAddress );
       
   213     
       
   214     // create Mce Manager, establishes connection to Mce server
       
   215     iMceManager = CMceManager::NewL( KSVPImplementationUid, &iContainer );
       
   216     
       
   217     // set observers for asynchronous events
       
   218     iMceManager->SetSessionObserver( this );
       
   219     iMceManager->SetInSessionObserver( this );
       
   220     iMceManager->SetInReferObserver( this );
       
   221     iMceManager->SetReferObserver( this );
       
   222     iMceManager->SetMediaObserver( this );
       
   223     iMceManager->SetEventObserver( this );
       
   224     iMceManager->SetDtmfObserver( this );
       
   225     iMceManager->SetRtpObserver( iRtpObserver );
       
   226     
       
   227     iTrafficStreamCreated = EFalse;
       
   228 
       
   229     SVPDEBUG1( "CSVPController::InitializeL Out" )
       
   230     }
       
   231     
       
   232 // ---------------------------------------------------------------------------
       
   233 // CSVPController::NewCallL
       
   234 // ---------------------------------------------------------------------------
       
   235 // 
       
   236 MCCPCall* CSVPController::NewCallL( 
       
   237                             const CCCPCallParameters& aParameters,
       
   238                             const TDesC& aRecipient,
       
   239                             const MCCPCallObserver& aObserver )
       
   240     {
       
   241     SVPDEBUG1( "CSVPController::NewCallL In" )
       
   242    
       
   243     __ASSERT_ALWAYS( &aParameters, User::Leave( KErrArgument ) );
       
   244     __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) );
       
   245     __ASSERT_ALWAYS( &aObserver, User::Leave( KErrArgument ) );
       
   246  
       
   247 #ifndef __WINS__
       
   248     // Preliminary Call Admission Control implementation, run only if no stream yet open
       
   249     if ( !iTrafficStreamCreated )
       
   250         {
       
   251         SVPDEBUG1( "CSVPController::NewCallL - Creating WLAN traffic stream.." )
       
   252 
       
   253         TRequestStatus requestStatus;
       
   254         TUint streamId = 0;
       
   255         TWlanTrafficStreamParameters streamParams( KSVPWlanTrafficStreamParamUserPriority );
       
   256         TWlanTrafficStreamStatus streamStatus = EWlanTrafficStreamStatusActive;
       
   257 
       
   258         // Disabling WLAN traffic stream automation and get stream status
       
   259         iWlanMgmt->CreateTrafficStream( requestStatus, streamParams, streamId, streamStatus );
       
   260         User::WaitForRequest( requestStatus );
       
   261         
       
   262         // Save traffic stream ID, needed for stream deletion
       
   263         iTrafficStreamId = streamId;
       
   264 
       
   265         if ( EWlanTrafficStreamStatusInactiveNoBandwidth == streamStatus )
       
   266             {
       
   267             SVPDEBUG1( "CSVPController::NewCallL - No bandwidth in traffic stream, leaving with ECCPErrorNetworkBusy" )        
       
   268 
       
   269             // Enabling WLAN traffic stream automation back by deleting used stream
       
   270             iWlanMgmt->DeleteTrafficStream( requestStatus, iTrafficStreamId );
       
   271             User::WaitForRequest( requestStatus );
       
   272             
       
   273             TCCPError err = ECCPErrorNetworkBusy;
       
   274             User::Leave( err );
       
   275             }
       
   276         SVPDEBUG1( "CSVPController::NewCallL - WLAN traffic stream created, continuing with NewCallL" )
       
   277 
       
   278         iTrafficStreamCreated = ETrue;
       
   279         }
       
   280     else
       
   281         {
       
   282         SVPDEBUG1( "CSVPController::NewCallL - WLAN traffic stream already created, continuing with NewCallL" )
       
   283         ;
       
   284         }
       
   285 #endif // __WINS__
       
   286     
       
   287     SVPDEBUG2( "CSVPController::NewCallL aRecipient length = %d", aRecipient.Length() )
       
   288     SVPDEBUG2( "CSVPController::NewCallL aRecipient = %S", &aRecipient )
       
   289     SVPDEBUG2( "CSVPController::NewCallL Serviceid = %d", aParameters.ServiceId() )
       
   290 
       
   291     // Prepare and remove possible DTMF suffix
       
   292     HBufC* parsedRecipient = NULL;
       
   293     parsedRecipient = ParseRecipientDtmfSuffixL( aRecipient );
       
   294   
       
   295     // "convert" recpient to 8-bit format
       
   296     HBufC8* recipient = HBufC8::NewLC( parsedRecipient->Length() ); // CS:1
       
   297     TPtr8 temp = recipient->Des();
       
   298     temp.Copy( *parsedRecipient );
       
   299 
       
   300     // Pointer to parsedRecipient no longer needed
       
   301     delete parsedRecipient;
       
   302     parsedRecipient = NULL;
       
   303     
       
   304     // fetch SIP profile ID from VoIP profiles
       
   305     RPointerArray< CRCSEProfileEntry > entryArray;
       
   306     CleanupResetAndDestroy<
       
   307         RPointerArray<CRCSEProfileEntry> >::PushL( entryArray ); //CS:2
       
   308     
       
   309     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:3
       
   310     
       
   311     // take service id to local variable
       
   312     TUint32 serviceId = aParameters.ServiceId();
       
   313     
       
   314     // Get VoIP profile by service id
       
   315     reg->FindByServiceIdL( serviceId, entryArray );
       
   316     __ASSERT_ALWAYS( entryArray.Count(), User::Leave( KErrArgument ) );
       
   317     
       
   318     // Take first entry from array
       
   319     CRCSEProfileEntry* entry = entryArray[0];
       
   320     
       
   321     // create new session
       
   322     MCCPCall* moSessionTemp = CreateNewSessionL( *recipient, 
       
   323                                                  *entry, 
       
   324                                                  aParameters,
       
   325                                                  aObserver );
       
   326     
       
   327     CleanupStack::PopAndDestroy( 2, &entryArray ); // CS:1
       
   328     CleanupStack::PopAndDestroy( recipient ); // CS:0
       
   329     
       
   330     SVPDEBUG1( "CSVPController::NewCallL Out" )
       
   331     return moSessionTemp;
       
   332     }
       
   333 
       
   334 // ---------------------------------------------------------------------------
       
   335 // CSVPController::CreateNewSessionL
       
   336 // ---------------------------------------------------------------------------
       
   337 //
       
   338 MCCPCall* CSVPController::CreateNewSessionL( 
       
   339     TDesC8& aRecipient, 
       
   340     CRCSEProfileEntry& aVoipProfile, 
       
   341     const CCCPCallParameters& aParameters,
       
   342     const MCCPCallObserver& aObserver )
       
   343     {
       
   344     SVPDEBUG1( "CSVPController::CreateNewSessionL In" )
       
   345     
       
   346     // array for provisioned data
       
   347     CDesC8ArrayFlat* userAgentHeaders = new( ELeave ) CDesC8ArrayFlat( 4 );
       
   348     CleanupStack::PushL( userAgentHeaders ); // CS:1
       
   349     
       
   350     // variable for storing security status
       
   351     TUint32 securityStatus( 0 );
       
   352     
       
   353     // set provisioning data
       
   354     SVPDEBUG1( "CSVPController::CreateNewSessionL Set provisioning data..." )
       
   355     iSVPUtility->SetProvisioningDataL( aVoipProfile, 
       
   356                                        *userAgentHeaders,
       
   357                                        securityStatus,
       
   358                                        iTerminalType,
       
   359                                        iWlanMacAddress  );
       
   360     
       
   361     SVPDEBUG2( "CSVPController::CreateNewSessionL Security status: %d", securityStatus )
       
   362     SVPDEBUG2( "CSVPController::CreateNewSessionL UAHeaders count: %d", userAgentHeaders->Count() )
       
   363     
       
   364     // Creates a SVP Mo session 
       
   365     CSVPMoSession* moSessionTemp = CSVPMoSession::NewL( *iMceManager,
       
   366                                                         aRecipient,
       
   367                                                         aVoipProfile, 
       
   368                                                         aParameters,
       
   369                                                         iContainer,
       
   370                                                         *this,
       
   371                                                         *iSVPUtility,
       
   372                                                         *iRtpObserver,
       
   373                                                         securityStatus,
       
   374                                                         userAgentHeaders );
       
   375     CleanupStack::Pop( userAgentHeaders ); // CS:0, to member data
       
   376     CleanupStack::PushL( moSessionTemp ); // CS:1
       
   377     
       
   378     FinalizeSessionCreationL( moSessionTemp );
       
   379     
       
   380     // set CCP session observer to SVP session
       
   381     moSessionTemp->AddObserverL( aObserver );
       
   382     // set CCP supplementary services events observer to SVP session
       
   383     moSessionTemp->SetSsObserver( *iCCPSsObserver );
       
   384     
       
   385     CleanupStack::Pop( moSessionTemp ); // CS:0
       
   386     
       
   387     // session pointer is passed to CCP
       
   388     SVPDEBUG1( "CSVPController::CreateNewSessionL Out" )
       
   389     return moSessionTemp;
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------------------------
       
   393 // Releases call
       
   394 // ---------------------------------------------------------------------------
       
   395 // 
       
   396 TInt CSVPController::ReleaseCall( MCCPCall& aCall )
       
   397     {
       
   398     SVPDEBUG1( "CSVPController::ReleaseCall In" )
       
   399 
       
   400     TInt response = KErrNotFound;
       
   401 
       
   402     // To ensure correct value
       
   403     iIncomingReferCallIndex = KErrNotFound;
       
   404     iSessionUpdateOngoing = EFalse;
       
   405 
       
   406     for ( TInt i = 0; i < iSessionArray.Count(); i++ )
       
   407         {
       
   408         if ( iSessionArray[i] == &aCall )
       
   409             {
       
   410             if ( iDtmfStringSending )
       
   411                 {
       
   412                 SVPDEBUG1( "CSVPController::ReleaseCall - Abort DTMF Sending" )
       
   413                 
       
   414                 // send abort event
       
   415                 iSessionArray[i]->DtmfObserver().HandleDTMFEvent(
       
   416                        MCCPDTMFObserver::ECCPDtmfSequenceAbort,
       
   417                        KErrNone,
       
   418                        iDtmfStringLex.Peek() );
       
   419                 
       
   420                 SVPDEBUG1( "CSVPController::ReleaseCall - Complete DTMF" )
       
   421                 
       
   422                 // send sequence completed event
       
   423                 iSessionArray[i]->DtmfObserver().HandleDTMFEvent(
       
   424                     MCCPDTMFObserver::ECCPDtmfStringSendingCompleted,
       
   425                     KErrNone,
       
   426                     iDtmfStringLex.Peek() );
       
   427                 
       
   428                 // sequence complete, clear flags
       
   429                 iDtmfStringSending = EFalse;
       
   430                 iFirstDtmfSent = EFalse;
       
   431                 
       
   432                 delete iDtmfString;
       
   433                 iDtmfString = NULL;
       
   434                 }
       
   435             iSessionArray[i]->Release();
       
   436             response = KErrNone;
       
   437             }
       
   438         }
       
   439 
       
   440 #ifndef __WINS__
       
   441     // Preliminary Call Admission Control implementation, delete only if created in NewCallL 
       
   442     if ( iTrafficStreamCreated )
       
   443         {
       
   444         SVPDEBUG1( "CSVPController::ReleaseCall - Deleting WLAN traffic stream" )
       
   445 
       
   446         TRequestStatus requestStatus;
       
   447 
       
   448         // Enabling WLAN traffic stream automation back by deleting used stream
       
   449         iWlanMgmt->DeleteTrafficStream( requestStatus, iTrafficStreamId );
       
   450         User::WaitForRequest( requestStatus );
       
   451         
       
   452         iTrafficStreamCreated = EFalse;
       
   453 
       
   454         SVPDEBUG1( "CSVPController::ReleaseCall - WLAN traffic stream deleted" )
       
   455         }
       
   456     else
       
   457         {
       
   458         SVPDEBUG1( "CSVPController::ReleaseCall - No WLAN traffic stream to delete" )
       
   459         ;
       
   460         }
       
   461 #endif // __WINS__
       
   462 
       
   463     SVPDEBUG1( "CSVPController::ReleaseCall Out" )
       
   464     return response;
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // Releases emergency call
       
   469 // ---------------------------------------------------------------------------
       
   470 // 
       
   471 TInt CSVPController::ReleaseEmergencyCall( MCCPEmergencyCall& /*aCall*/ )
       
   472     {
       
   473     SVPDEBUG1( "CSVPController::ReleaseEmergencyCall In" )
       
   474 
       
   475     // To ensure correct value next time
       
   476     iIncomingReferCallIndex = KErrNotFound;
       
   477     iSessionUpdateOngoing = EFalse;
       
   478 
       
   479     delete iEmergencySession;
       
   480     iEmergencySession = NULL;
       
   481     
       
   482     SVPDEBUG1( "CSVPController::ReleaseEmergencyCall Out" )
       
   483     return KErrNone;
       
   484     }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 // Releases conference call
       
   488 // ---------------------------------------------------------------------------
       
   489 // 
       
   490 TInt CSVPController::ReleaseConferenceCall( MCCPConferenceCall& /*aCall*/ )
       
   491     {
       
   492     SVPDEBUG1( "CSVPController::ReleaseConferenceCall In" )
       
   493     SVPDEBUG1( "CSVPController::ReleaseConferenceCall Out" )
       
   494     return KErrNotSupported;
       
   495     }
       
   496 
       
   497 // ---------------------------------------------------------------------------
       
   498 // CSVPController::RemoveFromArray
       
   499 // ---------------------------------------------------------------------------
       
   500 // 
       
   501 void CSVPController::RemoveFromArray( CSVPSessionBase& aSession )
       
   502     {
       
   503     SVPDEBUG1( "CSVPController::RemoveFromArray In" )
       
   504     
       
   505     // When Sessions destructor is called object be removed from array
       
   506     // manually after when data has been deleted.
       
   507     SVPDEBUG2( "CSVPController::RemoveFromArray aSession: 0x%x", &aSession )
       
   508     
       
   509     TInt index = FindSVPSession( aSession.Session() );  
       
   510     if ( KErrNotFound != index )
       
   511         {
       
   512         SVPDEBUG1( "CSVPController::RemoveFromArray Session found - removing" )
       
   513         iSessionArray.Remove( index );
       
   514         iSessionArray.Compress();
       
   515         }
       
   516     
       
   517     // Try also to remove it from RTCP observer. Ingore the return code, yet
       
   518     // again this is "just in case" thing.
       
   519     iRtpObserver->RemoveSessionFromObserving( &aSession );
       
   520     SVPDEBUG1( "CSVPController::RemoveFromArray Out" )
       
   521     }
       
   522 
       
   523 // ---------------------------------------------------------------------------
       
   524 // CSVPController::FindSVPSession
       
   525 // ---------------------------------------------------------------------------
       
   526 //
       
   527 TInt CSVPController::FindSVPSession( const CMceSession& aSession ) const
       
   528     {
       
   529     SVPDEBUG1( "CSVPController::FindSVPSession In" )
       
   530     
       
   531     TInt count = iSessionArray.Count();
       
   532     SVPDEBUG2( "CSVPController::FindSVPSession count = %d", count )
       
   533     
       
   534     while ( count )
       
   535         {
       
   536         count--;
       
   537         
       
   538         if (  &iSessionArray[count]->Session() == &aSession )
       
   539             {
       
   540             SVPDEBUG2( "CSVPController::FindSVPSession Out return: %d", count )
       
   541             return count;
       
   542             }
       
   543         }
       
   544     
       
   545     SVPDEBUG1( "CSVPController::FindSVPSession Out return: KErrNotFound" )
       
   546     return KErrNotFound;
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // CSVPController::Uid
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 const TUid& CSVPController::Uid() const
       
   554     {
       
   555     SVPDEBUG1( "CSVPController::Uid" )
       
   556     return KSVPImplementationUid; 
       
   557     }
       
   558 
       
   559 // ---------------------------------------------------------------------------
       
   560 // CSVPController::CreateNonSecureSessionL
       
   561 // ---------------------------------------------------------------------------
       
   562 // 
       
   563 void CSVPController::CreateNonSecureSessionL( TInt aSessionIndex )
       
   564     {
       
   565     SVPDEBUG1( "CSVPController::CreateNonSecureSessionL In" )
       
   566     
       
   567     // secure session failed -> create non secure Mo session
       
   568     static_cast< CSVPMoSession* >( iSessionArray[ aSessionIndex ] )->
       
   569             CreateNonSecureSessionL( *iMceManager );
       
   570     
       
   571     SVPDEBUG1( "CSVPController::CreateNonSecureSessionL Out" )
       
   572     }
       
   573 
       
   574 // ---------------------------------------------------------------------------
       
   575 // CSVPController::CheckIfSecureFailed
       
   576 // ---------------------------------------------------------------------------
       
   577 //    
       
   578 TBool CSVPController::CheckIfSecureFailed( TInt aStatusCode ) const
       
   579     {
       
   580     SVPDEBUG2( "CSVPController::CheckIfSecureFailed In, aStatusCode: %d", aStatusCode )
       
   581     
       
   582     // if secure fails with the following response codes
       
   583     // normal session is tried next
       
   584     if ( KSVPNotAcceptableHereVal == aStatusCode ||
       
   585          KSVPNotAcceptableVal == aStatusCode ||
       
   586          KSVPPreconditionFailureVal == aStatusCode ||
       
   587          KSVPMethodNotAllowedVal == aStatusCode )
       
   588         {
       
   589         SVPDEBUG1( "CSVPController::CheckIfSecureFailed Out ETrue" )
       
   590         return ETrue;
       
   591         }
       
   592     else
       
   593         {
       
   594         SVPDEBUG1( "CSVPController::CheckIfSecureFailed Out EFalse" )
       
   595         return EFalse;
       
   596         }
       
   597     }
       
   598 
       
   599 // ---------------------------------------------------------------------------
       
   600 // CSVPController::SessionStateChanged
       
   601 // ---------------------------------------------------------------------------
       
   602 // 
       
   603 void CSVPController::SessionStateChanged( CMceSession& aSession,
       
   604     TMceTransactionDataContainer* aContainer )
       
   605     {
       
   606     SVPDEBUG1( "CSVPController::SessionStateChanged In" )
       
   607     
       
   608     // Note, getting the status code may reset it in the container. So do it
       
   609     // only once and be sure that it stays as it should be.
       
   610     const TInt statusCode = aContainer->GetStatusCode();
       
   611     SVPDEBUG2( "CSVPController::SessionStateChanged statusCode: %d", statusCode )
       
   612     
       
   613     // check if this is emergency session
       
   614     if ( iEmergencySession )
       
   615         {
       
   616         SVPDEBUG1( "CSVPController::SessionStateChanged, emergency session" )
       
   617         
       
   618         if ( CMceSession::EEstablished == aSession.State() )
       
   619             {
       
   620             // Rest of the profiles not needed since session is established
       
   621             iEmergencyProfileIds.Reset();
       
   622             iEmergencyIapIds.Reset();
       
   623             }
       
   624         
       
   625         if ( CMceSession::EEstablished == aSession.State() &&
       
   626              iEmergencySession->HasHoldController() &&
       
   627              ( ( iEmergencySession->HoldController() ).HoldInProgress() ||
       
   628                ( iEmergencySession->HoldController() ).HoldRolledBack() ) )
       
   629             {
       
   630             // Handle hold
       
   631             TRAPD( error, iEmergencySession->HoldSessionStateChangedL( aSession ) )
       
   632             
       
   633             if ( error )
       
   634                 {
       
   635                 SVPDEBUG2( "CSVPController::SessionStateChanged, emergency session error %d", error )
       
   636                 }
       
   637             }
       
   638         else
       
   639             {
       
   640             iEmergencySession->SessionStateChanged( statusCode );
       
   641             }
       
   642         }
       
   643     else if ( iSessionUpdateOngoing )
       
   644         {
       
   645         // Non-hold session update, e.g. codec renegotiation ongoing; no actions
       
   646         // needed until MCE session state is established.
       
   647         SVPDEBUG1( "CSVPController::SessionStateChanged - MT Session Update" )
       
   648         
       
   649         if ( CMceSession::EEstablished == aSession.State() )
       
   650             {
       
   651             // Session update done (Ack received)
       
   652             iSessionUpdateOngoing = EFalse;
       
   653             SVPDEBUG1( "CSVPController::SessionStateChanged - MT Session Updated" )
       
   654             }
       
   655         }
       
   656     else
       
   657         {
       
   658         // fetch correct session
       
   659         const TInt ind = FindSVPSession( aSession );
       
   660         
       
   661         // KErrNone = status, status had to be error code
       
   662         if ( KErrNotFound != ind &&
       
   663              iSessionArray[ ind ]->SecurePreferred() &&
       
   664              CheckIfSecureFailed( statusCode ) ||
       
   665              CMceSession::ECancelling == aSession.State() )
       
   666             {
       
   667             SVPDEBUG1( "CSVPController::SessionStateChanged - Secure failed, trying normal session" )
       
   668             
       
   669             // trying normal session after secure session trial failed
       
   670             TRAPD( err, CreateNonSecureSessionL( ind ) );
       
   671             
       
   672             if ( err )
       
   673                 {
       
   674                 iSessionArray[ ind ]->GetCCPSessionObserver().
       
   675                     ErrorOccurred( ECCPRedirection, iSessionArray[ ind ] );
       
   676                 iSessionArray[ ind ]->GetCCPSessionObserver().
       
   677                     CallStateChanged( MCCPCallObserver::ECCPStateIdle,
       
   678                                       iSessionArray[ ind ]);
       
   679                 }
       
   680             }
       
   681         else if ( KErrNotFound != ind )
       
   682             {
       
   683             SVPDEBUG1( "CSVPController::SessionStateChanged - Session found" )
       
   684             
       
   685             CSVPSessionBase* session = iSessionArray[ ind ];
       
   686             
       
   687             if ( !session->CallId() &&
       
   688                  KSVPMultipleChoicesVal != statusCode &&
       
   689                  KSVPMovedPermanentlyVal != statusCode &&
       
   690                  KSVPMovedTemporarilyVal != statusCode )
       
   691                 {
       
   692                 // CallId not stored yet and not a 3XX case,
       
   693                 // check and store headers data.
       
   694                 CheckHeadersData( session, aContainer );
       
   695                 }
       
   696             
       
   697             if ( !session->SecurePreferred() )
       
   698                 {
       
   699                 session->ReleaseTempSecure();
       
   700                 }
       
   701             
       
   702             // Release attended transfer target session index 
       
   703             // if e.g. early stage session terminate
       
   704             if ( CMceSession::ETerminated == aSession.State() )
       
   705                 {
       
   706                 iHoldCallIndex = KErrNotFound;
       
   707                 }
       
   708             
       
   709             if ( CMceSession::EProceeding == aSession.State() )
       
   710                 {
       
   711                 SVPDEBUG1( "CSVPController::SessionStateChanged EProceeding" )
       
   712                 
       
   713                 if ( KErrNotFound != iHoldCallIndex && iSessionArray.Count() > 1 )
       
   714                     {
       
   715                     SVPDEBUG3( "CSVPController::SessionStateChanged, atte trans target, ind %d, iHCInd %d",
       
   716                                                 ind, iHoldCallIndex )
       
   717                     CheckCallEventToBeSent( session, iSessionArray[iHoldCallIndex] );
       
   718                     ExecCbIncomingCall( session, *iSessionArray[iHoldCallIndex] );
       
   719                     iHoldCallIndex = KErrNotFound;
       
   720                     }
       
   721                 else if ( session->HasHoldController() &&
       
   722                           ( session->HoldController() ).HoldInProgress() )
       
   723                     {
       
   724                     // Do nothing here; this only prevents wrong new call
       
   725                     // callback to CCP.
       
   726                     SVPDEBUG1( "CSVPController::SessionStateChanged - HoldInProgress" )
       
   727                     }
       
   728                 else if ( session->IsEmptyReInvite() )
       
   729                     {
       
   730                     SVPDEBUG1( "CSVPController::SessionStateChanged - Empty re-Invite handling ongoing" )
       
   731                     }
       
   732                 else if ( !session->IsIdle() )
       
   733                     {
       
   734                     SVPDEBUG1( "CSVPController::SessionStateChanged - NOP" )
       
   735                     }
       
   736                 else
       
   737                     {
       
   738                     SVPDEBUG1( "CSVPController::SessionStateChanged Incoming" )
       
   739                     ExecCbIncomingCall( session );
       
   740                     session->SessionStateChanged( statusCode );
       
   741                     }
       
   742                 }
       
   743             else if ( CMceSession::EEstablished == aSession.State() &&
       
   744                       session->HasHoldController() &&
       
   745                     ( ( session->HoldController() ).HoldInProgress() ||
       
   746                       ( session->HoldController() ).HoldRolledBack() ) )
       
   747                 {
       
   748                 SVPDEBUG1( "CSVPController::SessionStateChanged EEstablished & HoldController" )
       
   749                 
       
   750                 session->HandleSessionStateChanged( aSession );
       
   751                 }
       
   752             else if ( ( CMceSession::EEstablished == aSession.State() || 
       
   753                         CMceSession::ETerminated == aSession.State() ) &&
       
   754                         KErrNone != statusCode &&
       
   755                         KErrNotFound != iIncomingReferCallIndex &&
       
   756                         iIncomingReferCallIndex < iSessionArray.Count() &&
       
   757                         iSessionArray[ iIncomingReferCallIndex ]->IsIncomingTransfer() )
       
   758                 {
       
   759                 SVPDEBUG1( "CSVPController::SessionStateChanged transferor" )
       
   760                 
       
   761                 // Transferor sends notify to original when new session connected/failed.
       
   762                 // If secure is mandatory but path unsecure, attended transfer req must be rejected
       
   763                 if ( session->SecureMandatory() &&
       
   764                      CMceSession::EControlPathUnsecure == aSession.ControlPathSecurityLevel() &&
       
   765                      iSessionArray[ iIncomingReferCallIndex ]->IsAttended() )
       
   766                     {
       
   767                     iSessionArray[ iIncomingReferCallIndex ]->SendNotify( KSVPDeclineVal );
       
   768                     }
       
   769                 else
       
   770                     {
       
   771                     iSessionArray[ iIncomingReferCallIndex ]->SendNotify( statusCode );
       
   772                     }
       
   773 
       
   774                 if ( iSessionArray[ iIncomingReferCallIndex ]->IsAttended() )
       
   775                     {
       
   776                     // remotepartyinfo and/or secure status might have been changed,
       
   777                     // proper event will be sent later on.
       
   778                     CheckCallEventToBeSent( session, iSessionArray[iIncomingReferCallIndex] );
       
   779                     }
       
   780                 iIncomingReferCallIndex = KErrNotFound;
       
   781                 session->SessionStateChanged( statusCode );
       
   782                 }
       
   783             // 3xx Call forward handling
       
   784             else if ( KSVPMultipleChoicesVal == statusCode  ||
       
   785                       KSVPMovedPermanentlyVal == statusCode ||
       
   786                       KSVPMovedTemporarilyVal == statusCode )
       
   787                 {
       
   788                 HandleCallForward( statusCode, ind, aContainer );
       
   789                 }
       
   790             else
       
   791                 {
       
   792                 if ( ( aSession.State() == CMceSession::EOffering || 
       
   793                        aSession.State() == CMceSession::ETerminating ||
       
   794                        aSession.State() == CMceSession::ETerminated ) &&
       
   795                        iSessionArray[ ind ]->HasHoldController() &&
       
   796                        ( ( iSessionArray[ ind ]->HoldController() ).HoldInProgress() ||
       
   797                        ( iSessionArray[ ind ]->HoldController() ).HoldRolledBack() ) )
       
   798                     {
       
   799                     // Failed hold e.g. 408 response
       
   800                     SVPDEBUG1("CSVPController::SessionStateChanged()\
       
   801                     State change: Failed && HoldController");            
       
   802                     if ( 491 == statusCode )
       
   803                         {
       
   804                         SVPDEBUG1( 
       
   805                         "CSVPController::SessionStateChanged - UpdateFailed()" )
       
   806                         UpdateFailed( aSession, aContainer );
       
   807                         }
       
   808                     else if ( 100 <= statusCode && 200 > statusCode ) // Provisional response
       
   809                         {
       
   810                         // NOP
       
   811                         SVPDEBUG1( 
       
   812                         "CSVPController::SessionStateChanged - Provisional - NOP" )
       
   813                         }
       
   814                     else
       
   815                         {
       
   816                         iSessionArray[ ind ]->HandleSessionStateChanged( aSession );
       
   817                         session->SessionStateChanged( statusCode );                
       
   818                         }
       
   819                     }                
       
   820                 
       
   821                 else if ( session->HasHoldController() )
       
   822                     {
       
   823                     // MCE Session Refresh; no actions by the SVP
       
   824                     SVPDEBUG1( 
       
   825                     "CSVPController::SessionStateChanged - Session refresh" )
       
   826                     if ( CMceSession::ETerminating == aSession.State() ||
       
   827                          CMceSession::ETerminated == aSession.State() )
       
   828                         {
       
   829                         session->SessionStateChanged( statusCode );
       
   830                         }
       
   831                     }
       
   832                 else if ( !iFailed )
       
   833                     {
       
   834                     SVPDEBUG1( 
       
   835                     "CSVPController::SessionStateChanged - Not handled -> Notify session" )
       
   836                     session->SessionStateChanged( statusCode );
       
   837                     }                
       
   838                 else
       
   839                     {
       
   840                     // Failed() callback occurred before EEstablished state
       
   841                     // -> No action needed, session termination timer is set
       
   842                     }
       
   843                 }
       
   844             }
       
   845         else
       
   846             {
       
   847             SVPDEBUG1( "CSVPController::SessionStateChanged else" )
       
   848             }
       
   849         }
       
   850     
       
   851     SVPDEBUG1( "CSVPController::SessionStateChanged Out" )
       
   852     }
       
   853     
       
   854 // ---------------------------------------------------------------------------
       
   855 // CSVPController::SessionConnectionStateChanged
       
   856 // ---------------------------------------------------------------------------
       
   857 //  
       
   858 void CSVPController::SessionConnectionStateChanged(
       
   859                 CMceSession& aSession,
       
   860                 TBool aActive )
       
   861     {
       
   862     SVPDEBUG2("CSVPController::SessionConnectionStateChanged Active ETrue, Inactive EFalse: %d", aActive )
       
   863     
       
   864     if ( iEmergencySession )
       
   865         {
       
   866         iEmergencySession->SessionConnectionStateChanged( aSession, aActive );
       
   867         }
       
   868     }
       
   869     
       
   870 // ---------------------------------------------------------------------------
       
   871 // CSVPController::Failed
       
   872 // ---------------------------------------------------------------------------
       
   873 //
       
   874 #ifdef _DEBUG
       
   875 void CSVPController::Failed( CMceSession& aSession, TInt aError )
       
   876 #else
       
   877 void CSVPController::Failed( CMceSession& aSession, TInt /*aError*/ )
       
   878 #endif // _DEBUG
       
   879     {
       
   880     SVPDEBUG1("CSVPController::Failed In" )
       
   881     SVPDEBUG2("CSVPController::Failed With error code: %d", aError )
       
   882     
       
   883     TInt ind = FindSVPSession( aSession );
       
   884     
       
   885     if ( KErrNotFound != ind )
       
   886         {
       
   887         SVPDEBUG1("CSVPController::Failed() Session found")
       
   888         
       
   889         if ( &iSessionArray[ ind ]->GetCCPSessionObserver() )
       
   890             {
       
   891         	iSessionArray[ ind ]->GetCCPSessionObserver().
       
   892             	ErrorOccurred( ECCPErrorConnectionError, 
       
   893             	               iSessionArray[ ind ] );
       
   894         
       
   895         	// Actually MCE session state should always 
       
   896         	// be ETerminated when this method is 
       
   897         	// called; but check anyway:        
       
   898         	if ( CMceSession::ETerminated == aSession.State() )
       
   899         	    {
       
   900                 iFailed = ETrue;
       
   901         	    // start termination timer, needed for UI
       
   902         	    // to handle Disconnected-bubble   
       
   903         	    TRAP_IGNORE( iSessionArray[ ind ]->StartTimerL( 
       
   904         	            KSVPTerminatingTime, KSVPTerminationTimerExpired ) );
       
   905             
       
   906         	    iSessionArray[ ind ]->GetCCPSessionObserver().
       
   907         		    CallStateChanged( MCCPCallObserver::ECCPStateDisconnecting, 
       
   908         		                      iSessionArray[ ind ] );
       
   909             
       
   910         	    SVPDEBUG1("CSVPController::Failed() Session terminating");            
       
   911         	    }
       
   912             }
       
   913         else
       
   914             {
       
   915             iCCPMonitor->ErrorOccurred( MCCPObserver::ECCPIncomingCallFailed ); 
       
   916             }
       
   917         }
       
   918     else
       
   919         {
       
   920         SVPDEBUG1("CSVPController::Failed() Session not Found!!");
       
   921         }
       
   922     
       
   923     SVPDEBUG1("CSVPController::Failed Out" )
       
   924     }
       
   925 
       
   926 // ---------------------------------------------------------------------------
       
   927 // CSVPController::UpdateFailed
       
   928 // ---------------------------------------------------------------------------
       
   929 //
       
   930 void CSVPController::UpdateFailed(
       
   931     			CMceSession& aSession,
       
   932     			TMceTransactionDataContainer* aContainer )
       
   933     {
       
   934     SVPDEBUG1( "CSVPController::UpdateFailed In" )
       
   935     
       
   936     TInt ind = FindSVPSession( aSession );
       
   937     TInt statusCode = aContainer->GetStatusCode();
       
   938     
       
   939     SVPDEBUG2( "CSVPController::UpdateFailed statusCode: %d", statusCode )
       
   940     
       
   941     if ( KErrNotFound != ind )
       
   942         {
       
   943         iSessionArray[ ind ]->UpdateFailed( aSession, statusCode );
       
   944         }
       
   945     iSessionUpdateOngoing = EFalse;
       
   946     SVPDEBUG1( "CSVPController::UpdateFailed Out" )
       
   947     }
       
   948     
       
   949 // ---------------------------------------------------------------------------
       
   950 // CSVPController::EventStateChanged
       
   951 // ---------------------------------------------------------------------------
       
   952 //			
       
   953 void CSVPController::EventStateChanged(
       
   954     			CMceEvent& aEvent,
       
   955 				TMceTransactionDataContainer* aContainer )
       
   956     {
       
   957     SVPDEBUG1( "CSVPController:EventStateChanged In" )
       
   958     
       
   959     iContainer = *aContainer;
       
   960     TInt ind = FindSVPSession( *aEvent.AssociatedSession() );
       
   961     TInt statusCode = iContainer.GetStatusCode();
       
   962     
       
   963     SVPDEBUG2( "CSVPController:EventStateChanged statusCode: %d", statusCode )
       
   964 
       
   965     if ( KErrNotFound != ind )
       
   966         {
       
   967         SVPDEBUG2( "CSVPController::EventStateChanged ind = %d", ind )
       
   968         TInt err = iSessionArray[ ind ]->EventStateChanged( aEvent, statusCode );
       
   969         
       
   970         if ( KSVPOKVal == statusCode &&
       
   971              iSessionArray[ ind ]->IsAttended() &&
       
   972              KErrNone == err )
       
   973             {
       
   974             SVPDEBUG1( "CSVPController::EventStateChanged Atte transfer cont." )
       
   975             
       
   976             TRAP( err, CreateNewTransferSessionL( ind, ETrue ) );
       
   977             
       
   978             if ( err )
       
   979                 {
       
   980                 SVPDEBUG2( "CSVPController::EventStateChanged: err: %d", err )
       
   981                 }
       
   982             }
       
   983         }
       
   984     else
       
   985         {
       
   986         SVPDEBUG1( "CSVPController::EventStateChanged Session not Found!!" )
       
   987         }
       
   988 
       
   989     SVPDEBUG1("CSVPController:EventStateChanged OUT");
       
   990     }
       
   991     
       
   992 // ---------------------------------------------------------------------------
       
   993 // CSVPController::NotifyReceived
       
   994 // ---------------------------------------------------------------------------
       
   995 //
       
   996 void CSVPController::NotifyReceived(
       
   997 				CMceEvent& aEvent,
       
   998 				TMceTransactionDataContainer* aContainer )
       
   999     {
       
  1000     SVPDEBUG1( "CSVPController::NotifyReceived In" )
       
  1001     
       
  1002     TInt ind = FindSVPSession( *aEvent.AssociatedSession() );
       
  1003     
       
  1004     if ( KErrNotFound != ind )
       
  1005         {         
       
  1006         iSessionArray[ ind ]->NotifyReceived( aEvent, aContainer );
       
  1007         }
       
  1008     else
       
  1009         {
       
  1010         SVPDEBUG1( "CSVPController::NotifyReceived, session not found !" )
       
  1011         }
       
  1012 
       
  1013     SVPDEBUG1( "CSVPController::NotifyReceived Out" )
       
  1014     }
       
  1015 
       
  1016 // ---------------------------------------------------------------------------
       
  1017 // CSVPController::EventConnectionStateChanged
       
  1018 // ---------------------------------------------------------------------------
       
  1019 //			
       
  1020 void CSVPController:: EventConnectionStateChanged(
       
  1021                 CMceEvent& /*aEvent*/,
       
  1022                 TBool /*aActive*/ )
       
  1023     {
       
  1024     SVPDEBUG1( "CSVPController:: EventConnectionStateChanged In" )
       
  1025     SVPDEBUG1( "CSVPController:: EventConnectionStateChanged Out" )
       
  1026     }
       
  1027 
       
  1028 // ---------------------------------------------------------------------------
       
  1029 // CSVPController::Failed
       
  1030 // ---------------------------------------------------------------------------
       
  1031 //
       
  1032 #ifdef _DEBUG
       
  1033 void CSVPController::Failed( CMceEvent& /*aEvent*/, TInt aError )
       
  1034 #else
       
  1035 void CSVPController::Failed( CMceEvent& /*aEvent*/, TInt /*aError*/ )
       
  1036 #endif // _DEBUG
       
  1037     {
       
  1038     SVPDEBUG2("CSVPController::Failed Event failure, error: %d", aError )
       
  1039     }
       
  1040 
       
  1041 // ---------------------------------------------------------------------------
       
  1042 // CSVPController::IncomingSession
       
  1043 // ---------------------------------------------------------------------------
       
  1044 //
       
  1045 void CSVPController::IncomingSession(
       
  1046                 CMceInSession* aSession,
       
  1047 				TMceTransactionDataContainer* aContainer )
       
  1048     {
       
  1049     SVPDEBUG1( "CSVPController::IncomingSession In" )
       
  1050     SVPDEBUG2( "CSVPController::IncomingSession - status code: %d", aContainer->GetStatusCode() )
       
  1051     
       
  1052     if ( iEmergencySession )
       
  1053         {
       
  1054         SVPDEBUG1( "CSVPController::IncomingSession - ongoing emergency call - reject incoming call" )
       
  1055         TRAP_IGNORE( aSession->RejectL( KSVPBusyHereReason, KSVPBusyHereVal ) )
       
  1056         // Ownership of aSession is changed, delete it
       
  1057         delete aSession;
       
  1058         aSession = NULL;
       
  1059         return;
       
  1060         }
       
  1061     
       
  1062     // IncomingSessionHandlerL is used to handle possible leave 
       
  1063     SVPDEBUG1( "CSVPController::IncomingSession IncomingSessionHandlerL" )
       
  1064     TRAPD( err, IncomingSessionHandlerL( aSession, aContainer ) );
       
  1065     
       
  1066     if ( err )
       
  1067         {
       
  1068         SVPDEBUG2( "CSVPController::IncomingSession: err: %d", err )
       
  1069         
       
  1070         // RejectL must be called in case SVP needs to delete session.
       
  1071         // TRAP is used because of RejectL might contain a leaver.
       
  1072         switch ( err )
       
  1073             {
       
  1074             case KErrNotSupported:
       
  1075                 {
       
  1076                 TRAP( err, aSession->RejectL( KSVPCallTransactDoesNotExistReason,
       
  1077                         KSVPCallDoesNotExistVal ) );
       
  1078                 break;
       
  1079                 }
       
  1080             
       
  1081             case KSVPErrWrongMinSE:
       
  1082                 // NOP. Reject has been done as a result of call to
       
  1083                 // IncomingSessionHandlerL.
       
  1084                 break;
       
  1085             
       
  1086             case KSVPErrDnDRejection:
       
  1087                 {
       
  1088                 // Reject call because of Do not Disturb service active.
       
  1089                 TRAP( err, aSession->RejectL( KSVPBusyHereReason,
       
  1090                         KSVPBusyHereVal ) );
       
  1091                 break;
       
  1092                 }
       
  1093              
       
  1094              case KSVPErrAnonymousCallRejection:
       
  1095                 {
       
  1096                 // Reject call because of Anonymous Barring service active.
       
  1097                 TRAP( err, aSession->RejectL( KSVPNotAcceptableHereReason,
       
  1098                         KSVPNotAcceptableHereVal ) );
       
  1099                 break;
       
  1100                 }
       
  1101              
       
  1102              case KSVPErrCodecMismatch:
       
  1103                 {
       
  1104                 TRAP( err, aSession->RejectL( KSVPIncompatibleMediaFormatReason,
       
  1105                         KSVPNotAcceptableHereVal ) );
       
  1106                 break;
       
  1107                 }
       
  1108              
       
  1109              default:
       
  1110                 {
       
  1111                 // NOP.
       
  1112                 break;
       
  1113                 }
       
  1114             }
       
  1115         
       
  1116         if ( KErrNotFound == FindSVPSession( *aSession ) )
       
  1117             {
       
  1118             // Leave has occured before CSVPMtSession was created.
       
  1119             delete aSession;
       
  1120             }
       
  1121         else
       
  1122             {
       
  1123             SVPDEBUG1( "CSVPController::IncomingSession IncomingSessionHandlerL leave occurred" )
       
  1124             // clean up session 
       
  1125             TerminateSession( *aSession );
       
  1126             }
       
  1127         }
       
  1128     }
       
  1129 
       
  1130 // ---------------------------------------------------------------------------
       
  1131 // CSVPController::TerminateSession
       
  1132 // ---------------------------------------------------------------------------
       
  1133 //
       
  1134 void CSVPController::TerminateSession( CMceInSession& aSession ) 
       
  1135     {
       
  1136     SVPDEBUG1( "CSVPController::TerminateSession In" )
       
  1137     
       
  1138     // find correct session
       
  1139     TInt index =  FindSVPSession( aSession );
       
  1140     
       
  1141     if ( KErrNotFound != index )
       
  1142         {
       
  1143         CSVPSessionBase* tempBase = iSessionArray[ index ];
       
  1144         // remove session pointer from array and compress array
       
  1145         iSessionArray.Remove( index );
       
  1146         iSessionArray.Compress();
       
  1147         
       
  1148         // delete session  
       
  1149         delete tempBase;
       
  1150         tempBase = NULL;            
       
  1151         }
       
  1152             
       
  1153     SVPDEBUG1( "CSVPController::TerminateSession Out" )  
       
  1154     }
       
  1155 
       
  1156 // ---------------------------------------------------------------------------
       
  1157 // CSVPController::CheckMinSessionExpiresL
       
  1158 // ---------------------------------------------------------------------------
       
  1159 //
       
  1160 void CSVPController::CheckMinSessionExpiresL( CMceInSession& aSession,
       
  1161                                               CDesC8Array& aHeaders, 
       
  1162                                               TInt aMinSE  )
       
  1163     {
       
  1164     SVPDEBUG1( "CSVPController::CheckMinSessionExpiresL In" )
       
  1165     
       
  1166     TInt count = aHeaders.MdcaCount();
       
  1167     TUint32 sessionExpires = 0;
       
  1168     TInt error = KErrNone;
       
  1169     while ( count-- )  
       
  1170     	{
       
  1171         TPtrC8 tmpHeader = aHeaders.MdcaPoint( count );
       
  1172         if ( KErrNotFound != tmpHeader.Find( KSVPSessionExpires ) )
       
  1173             {
       
  1174             // "Session-Expires:" found
       
  1175             SVPDEBUG1( "CSVPController::CheckMinSEL: 'Session-Expires:' found" )
       
  1176             
       
  1177             TInt offset = tmpHeader.FindF( KSVPRefresher );
       
  1178             if ( KErrNotFound != offset )
       
  1179                 {
       
  1180                 tmpHeader.Set( tmpHeader.Left( offset ) );
       
  1181                 }
       
  1182             
       
  1183             TPtrC8 header;
       
  1184             header.Set( tmpHeader );
       
  1185             if ( header.FindF( KSVPCln ) )
       
  1186                 {
       
  1187                 // 5 digits should be enought for Min-SE
       
  1188                 // For example: "Min-SE: 1200" 
       
  1189                 TLex8 expires( header.Right( 5 ) ); 
       
  1190                 TInt digits = 0;
       
  1191                 while ( !expires.Eos() )
       
  1192                     {
       
  1193                     if ( expires.Peek().IsDigit() )
       
  1194                         {
       
  1195                         digits++; 
       
  1196                         }
       
  1197                     expires.Inc();
       
  1198                     }  
       
  1199                 TLex8 expiresVal( header.Right( digits ) );
       
  1200                 error = expiresVal.Val( sessionExpires, EDecimal );
       
  1201                 SVPDEBUG2(" CSVPController::CheckMinSEL sesExp: %d", sessionExpires )
       
  1202 
       
  1203                 if ( error || aMinSE > sessionExpires  )  
       
  1204                     {
       
  1205                     SVPDEBUG2(" CSVPController::CheckMinSEL reject, err: %d", error )
       
  1206                     CDesC8ArrayFlat* minSEHeader = 
       
  1207                         new ( ELeave ) CDesC8ArrayFlat( 1 );
       
  1208                     CleanupStack::PushL( minSEHeader ); // CS:0
       
  1209                         
       
  1210                     HBufC8* header = HBufC8::NewL( 
       
  1211                                  KSVPMinExpiresLenght + digits  );
       
  1212                     CleanupStack::PushL( header );  // CS:1
       
  1213                     
       
  1214                     header->Des().Copy( KSVPMinSessionExpires );
       
  1215                     header->Des().AppendNum( aMinSE );
       
  1216                     minSEHeader[ 0 ].AppendL( *header );
       
  1217                     CleanupStack::PopAndDestroy( header ); // CS:1
       
  1218                     
       
  1219                     aSession.RejectL( KSVPIntervalTooSmallReason,
       
  1220               		 			      KSVPSessionIntervalTooSmallVal,
       
  1221                                       minSEHeader );
       
  1222                     
       
  1223                     // ownership to Mce
       
  1224                     CleanupStack::Pop( minSEHeader ); // CS:0
       
  1225                     User::Leave( KSVPErrWrongMinSE );
       
  1226                     }
       
  1227                 }
       
  1228             }
       
  1229         }
       
  1230     
       
  1231     SVPDEBUG1( "CSVPController::CheckMinSessionExpiresL Out" )
       
  1232     }
       
  1233 
       
  1234 // ---------------------------------------------------------------------------
       
  1235 // CSVPController::FetchExpiresTime
       
  1236 // ---------------------------------------------------------------------------
       
  1237 //
       
  1238 void CSVPController::FetchExpiresTime( TUint32& aExpiresTime, 
       
  1239                                        CDesC8Array& aHeaders ) const
       
  1240     {
       
  1241     SVPDEBUG1( "CSVPController::FetchExpiresTime In" )
       
  1242     
       
  1243     TBool expiresTaken = EFalse;
       
  1244     for ( TInt i = 0; i < aHeaders.MdcaCount() && !expiresTaken; i++ )
       
  1245         {
       
  1246         TPtrC8 tmpHeader = aHeaders.MdcaPoint( i );
       
  1247         if ( KErrNotFound != tmpHeader.Find( KSVPExpiresHeader ) &&
       
  1248              KErrNotFound == tmpHeader.Find( KSVPSessionExpires ) )
       
  1249             {
       
  1250             // "Expires:" found
       
  1251             SVPDEBUG1(" CSVPController::FetchExpiresTimer: 'Expires:' found")
       
  1252 
       
  1253             TInt colonMark = tmpHeader.FindF( KSVPCln );
       
  1254            
       
  1255             if ( colonMark )
       
  1256                 {
       
  1257                 
       
  1258                 TLex8 expires( tmpHeader.Right( 5 ) ); // three digits max
       
  1259                 TInt digits = 0;
       
  1260                 while ( !expires.Eos() )
       
  1261                     {
       
  1262                     if ( expires.Peek().IsDigit() )
       
  1263                         {
       
  1264                         digits++; 
       
  1265                         }
       
  1266                     expires.Inc();
       
  1267                     }
       
  1268                 TLex8 expiresVal( tmpHeader.Right( digits ) );
       
  1269                 TInt error = expiresVal.Val( aExpiresTime, EDecimal );
       
  1270 
       
  1271                 if ( error )
       
  1272                     {
       
  1273                     SVPDEBUG2(" CSVPController::FetchExpiresTimer, set default value\
       
  1274                      Val error: %d", error );
       
  1275                     // if error occurred, set default time
       
  1276                     aExpiresTime = KSVPDefaultExpiresTime;
       
  1277                     expiresTaken = ETrue;
       
  1278                     } 
       
  1279                 else if ( KSVPDefaultExpiresTime < aExpiresTime )
       
  1280                     {
       
  1281                     aExpiresTime = KSVPDefaultExpiresTime;
       
  1282                     expiresTaken = ETrue;
       
  1283                     }
       
  1284                 else
       
  1285                     {
       
  1286                     SVPDEBUG2(" CSVPController::FetchExpiresTime: %d", aExpiresTime )
       
  1287                     expiresTaken = ETrue;
       
  1288                     }
       
  1289                 }                 
       
  1290             }
       
  1291         }
       
  1292     
       
  1293     SVPDEBUG1( "CSVPController::FetchExpiresTime Out" )
       
  1294     }
       
  1295 
       
  1296 // ---------------------------------------------------------------------------
       
  1297 // CSVPController::IncomingSessionHandlerL
       
  1298 // ---------------------------------------------------------------------------
       
  1299 //
       
  1300 void CSVPController::IncomingSessionHandlerL( CMceInSession* aSession,
       
  1301 			                    	TMceTransactionDataContainer* aContainer )
       
  1302     {
       
  1303     SVPDEBUG1( "CSVPController::IncomingSessionHandlerL In" )
       
  1304     
       
  1305     __ASSERT_ALWAYS( aSession, User::Leave( KErrArgument ) );
       
  1306     __ASSERT_ALWAYS( aContainer, User::Leave( KErrArgument ) );
       
  1307 
       
  1308     CDesC8Array* headers = aContainer->GetHeaders();
       
  1309     __ASSERT_ALWAYS( headers, User::Leave( KErrArgument ) );
       
  1310     CleanupStack::PushL( headers ); // CS:1
       
  1311 
       
  1312     IsTransferTargetCaseL( headers );
       
  1313     
       
  1314     // check if Require header contains precondition and that Supported header
       
  1315     // includes option tag 100rel, providing support for PRACK's
       
  1316     iPreconditions = IsPreconditionRequired( *headers );
       
  1317 
       
  1318     // Default expiration time (120 s) is set due IOP issue,
       
  1319 	// otherwise incoming call would continue eternity in some cases.
       
  1320     TUint32 expireTime = KSVPDefaultExpiresTime;
       
  1321     // check if expires header is present and update expiration time
       
  1322     FetchExpiresTime( expireTime, *headers );
       
  1323     
       
  1324     // mt session temp
       
  1325     CSVPMtSession* mtSessionTemp = NULL;
       
  1326     
       
  1327     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC();      // CS:2
       
  1328     
       
  1329     RPointerArray< CRCSEProfileEntry > voipProfiles;
       
  1330     CleanupResetAndDestroy< RPointerArray< CRCSEProfileEntry > >::PushL(
       
  1331         voipProfiles );                                             // CS:3
       
  1332     
       
  1333     reg->FindBySIPProfileIdL( aSession->Profile(), voipProfiles );
       
  1334     
       
  1335     // Take first profile from the array
       
  1336     const TUint32 voipProfileId = voipProfiles[ 0 ]->iId;
       
  1337     const TUint32 minSE = voipProfiles[ 0 ]->iSIPMinSE;
       
  1338     
       
  1339     CheckMinSessionExpiresL( *aSession, *headers, minSE );
       
  1340      
       
  1341     SVPDEBUG2("CSVPController::IncomingSessionHandlerL VoIP profile id: %d",
       
  1342         voipProfileId );
       
  1343              
       
  1344     // Take first profile from the array
       
  1345     const TUint32 serviceId = voipProfiles[ 0 ]->iServiceProviderId;
       
  1346     
       
  1347     SVPDEBUG2("CSVPController::IncomingSessionHandlerL Service id: %d",
       
  1348         serviceId );
       
  1349     
       
  1350     // create SIP and ProfileRegistry for profile handling
       
  1351     CSIP* sip = CSIP::NewLC( KSVPUid, *this );      // CS: 4
       
  1352     SVPDEBUG1( "CSVPController::IncomingSessionHandlerL sip CREATED" );
       
  1353     
       
  1354     CSIPProfileRegistry* sipProfileRegistry = 
       
  1355         CSIPProfileRegistry::NewLC( *sip, *this );  // CS: 5
       
  1356     
       
  1357     SVPDEBUG1( "CSVPController::IncomingSessionHandlerL\
       
  1358     profile registry CREATED" );
       
  1359     
       
  1360     // retrieve SIP profile by using sip profile id, note ownership transfer
       
  1361     CSIPProfile* profile = sipProfileRegistry->ProfileL( aSession->Profile() );
       
  1362     
       
  1363     // Get keep-alive timer value
       
  1364     TUint32 iapId = 0;
       
  1365     TBool found = EFalse;
       
  1366     TInt keepAliveValue;
       
  1367     
       
  1368     profile->GetParameter( KSIPAccessPointId, iapId );
       
  1369 
       
  1370     TRAPD( errKeepAlive, 
       
  1371         found = iSVPUtility->GetKeepAliveByIapIdL( iapId, keepAliveValue ) );
       
  1372     
       
  1373     SVPDEBUG3( "CSVPController::IncomingSessionHandlerL\
       
  1374                 GetKeepAliveByIapIdL: errKeepAlive = %d found = %d",
       
  1375                 errKeepAlive, found );
       
  1376      
       
  1377     if ( !found )
       
  1378         {
       
  1379         const TDesC8* aor;
       
  1380         profile->GetParameter( KSIPUserAor, aor );
       
  1381         TRAP( errKeepAlive, found = 
       
  1382             iSVPUtility->GetKeepAliveByAORL( *aor, keepAliveValue ) );
       
  1383         
       
  1384         SVPDEBUG3( "CSVPController::IncomingSessionHandlerL\
       
  1385                     GetKeepAliveByAORL: errKeepAlive = %d found = %d",
       
  1386                     errKeepAlive, found );
       
  1387         }
       
  1388     
       
  1389     delete profile;
       
  1390     CleanupStack::PopAndDestroy( 2, sip );          // CS:3
       
  1391     
       
  1392     CMceRtpSource* rtpSource = NULL;
       
  1393     
       
  1394     // modify codecs and codec settings if streams found
       
  1395     if ( aSession->Streams().Count() )
       
  1396         {
       
  1397       	const RPointerArray<CMceMediaStream>& streams = aSession->Streams();
       
  1398       	
       
  1399         SVPDEBUG2("CSVPController::IncomingSessionHandlerL Streamcount: %d",
       
  1400             streams.Count() );
       
  1401         
       
  1402         // disable rtp source and speaker sink so that audio is not on
       
  1403         // before session is up signalling-wise
       
  1404         for ( TInt i = 0; i < streams.Count(); )
       
  1405             {
       
  1406             SVPDEBUG1( "CSVPController::IncomingSessionHandlerL disabling" );
       
  1407             
       
  1408             CMceMediaStream* stream1 = streams[i];
       
  1409             
       
  1410             // if stream is not audio stream -> remove 
       
  1411             if ( KMceAudio != stream1->Type() )
       
  1412                 {
       
  1413                 aSession->RemoveStreamL( *streams[ i ] );
       
  1414                 }
       
  1415             else
       
  1416                 {
       
  1417                 // search for RTP source
       
  1418                 if ( stream1->Source() && 
       
  1419                      KMceRTPSource == stream1->Source()->Type() )
       
  1420                     {
       
  1421                     SVPDEBUG1(
       
  1422                         "CSVPController::IncomingSessionHandlerL\
       
  1423                          RTPSource found" );
       
  1424                     
       
  1425                 	rtpSource = static_cast<CMceRtpSource*>(
       
  1426                 	    stream1->Source() );
       
  1427                     }
       
  1428             
       
  1429                 SVPAudioUtility::DisableSpeakerSinkL( stream1->Sinks() );
       
  1430                 SVPAudioUtility::DisableMicSourceL( *stream1 );
       
  1431                 //remove all streams that not audio stream
       
  1432                 i++;
       
  1433                 }
       
  1434             }
       
  1435             
       
  1436         // sets MMF priorities and sets codec specific settings
       
  1437         CheckStreamsL( *voipProfiles[ 0 ], *aSession, keepAliveValue );
       
  1438         if ( rtpSource )
       
  1439             {
       
  1440             iSVPUtility->UpdateJitterBufferSizeL( *rtpSource );
       
  1441             }
       
  1442         
       
  1443         // create SVP Mt session    
       
  1444         mtSessionTemp = CSVPMtSession::NewL( aSession,
       
  1445                                              iContainer,
       
  1446                                              serviceId,
       
  1447                                              voipProfileId, 
       
  1448                                              *this, 
       
  1449                                              *iSVPUtility,
       
  1450                                              *iRtpObserver,
       
  1451                                              keepAliveValue,
       
  1452                                              iPreconditions );
       
  1453         
       
  1454         CleanupStack::PushL( mtSessionTemp );
       
  1455         FinalizeSessionCreationL( mtSessionTemp );
       
  1456         CleanupStack::Pop( mtSessionTemp );
       
  1457         }
       
  1458     else
       
  1459         {
       
  1460         SVPDEBUG1( "CSVPController::IncomingSessionHandlerL NO streams!" );
       
  1461         
       
  1462         // no streams found, handle streams like in Mo-case  
       
  1463         mtSessionTemp = CSVPMtSession::NewL( aSession,
       
  1464                                              iContainer,
       
  1465                                              serviceId,
       
  1466                                              voipProfileId, 
       
  1467                                              *this, 
       
  1468                                              *iSVPUtility,
       
  1469                                              *iRtpObserver,
       
  1470                                              keepAliveValue,
       
  1471                                              iPreconditions );
       
  1472         
       
  1473         CleanupStack::PushL( mtSessionTemp );
       
  1474         // construct audio streams 
       
  1475         mtSessionTemp->ConstructAudioStreamsL();
       
  1476         FinalizeSessionCreationL( mtSessionTemp );
       
  1477         CleanupStack::Pop( mtSessionTemp );
       
  1478         }
       
  1479     
       
  1480     CleanupStack::PopAndDestroy( 3, headers );                          // CS:0
       
  1481     
       
  1482     // set expires timer
       
  1483     if ( expireTime )
       
  1484         {
       
  1485         SVPDEBUG2( "CSVPController::IncomingSessionHandlerL expireTime: %i s.", expireTime );
       
  1486         mtSessionTemp->StartTimerL( KSVPMilliSecondCoefficient * expireTime,
       
  1487                                     KSVPExpiresTimeExpired );
       
  1488         }
       
  1489     
       
  1490     SVPDEBUG1( "CSVPController::IncomingSessionHandlerL Updating call" );
       
  1491     
       
  1492     aSession->UpdateL();
       
  1493     
       
  1494     SVPDEBUG2( "CSVPController::IncomingSessionHandlerL, Call state after update: %i",
       
  1495         aSession->State() );
       
  1496     
       
  1497     if ( CMceSession::EProceeding == aSession->State() )
       
  1498         {
       
  1499         const TInt ind = FindSVPSession( *aSession );
       
  1500         iCCPMonitor->IncomingCall( iSessionArray[ ind ] );
       
  1501         
       
  1502         SVPDEBUG1( "CSVPController::IncomingSessionHandlerL - EProceeding" );
       
  1503         
       
  1504         iSessionArray[ ind ]->SessionStateChanged( KErrNone );
       
  1505         }
       
  1506     
       
  1507     // reset flag
       
  1508     iPreconditions = EFalse;
       
  1509     
       
  1510     SVPDEBUG1( "CSVPController::IncomingSessionHandlerL Out" )
       
  1511     }
       
  1512    
       
  1513 // ---------------------------------------------------------------------------
       
  1514 // CSVPController::CheckStreamsL
       
  1515 // ---------------------------------------------------------------------------
       
  1516 //    
       
  1517 void CSVPController::CheckStreamsL( CRCSEProfileEntry& aVoipProfile, 
       
  1518                                     CMceSession& aInSession,
       
  1519                                     TInt aKeepAliveValue,
       
  1520                                     TBool aSessionUpdateOngoing)
       
  1521     {
       
  1522     SVPDEBUG1( "CSVPController::CheckStreamsL In" )
       
  1523     
       
  1524     __ASSERT_ALWAYS( &aInSession, User::Leave( KErrArgument ) );
       
  1525 
       
  1526     const RPointerArray< CMceMediaStream >& streamArray = 
       
  1527         aInSession.Streams();
       
  1528     
       
  1529     const TInt streamCount( streamArray.Count() );
       
  1530     
       
  1531     SVPDEBUG3("CSVPController::CheckStreamsL aVoIPProfileId: %u streamCount: %d ",
       
  1532             aVoipProfile.iId, streamCount );
       
  1533     
       
  1534     // Set codec settings, this also removes unneeded codecs.
       
  1535     for ( TInt i = 0; i < streamCount; i++ )
       
  1536         {
       
  1537         iSVPUtility->SetAudioCodecsMTL( aVoipProfile, 
       
  1538                                         *streamArray[ i ], 
       
  1539                                         aKeepAliveValue,
       
  1540                                         aSessionUpdateOngoing );
       
  1541 
       
  1542         // Set the priorities for the remaining codecs. This will handle also the
       
  1543         // DTMF priorites once correct codecs are set in the streams. Also note
       
  1544         // the downlink/uplink (in/out) discrimination.
       
  1545 
       
  1546         if ( KMceAudio == streamArray[i]->Type() && 
       
  1547             streamArray[i]->BoundStream() )
       
  1548             {
       
  1549             SVPDEBUG2( "CSVPController::CheckStreamsL round: %d start", i )
       
  1550             
       
  1551             CMceAudioStream* stream = static_cast<CMceAudioStream*>( streamArray[i] );
       
  1552             
       
  1553             TBool dtmfMode = EFalse;
       
  1554             if ( SVPAudioUtility::IsDownlinkStream( *stream ) )
       
  1555                 {
       
  1556                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL( *stream,
       
  1557                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ) );
       
  1558                 }
       
  1559             else
       
  1560                 {
       
  1561                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL(
       
  1562                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ),
       
  1563                         *stream );
       
  1564                 }
       
  1565             
       
  1566             iSVPUtility->SetDtmfMode( dtmfMode );
       
  1567             
       
  1568             SVPDEBUG2( "CSVPController::CheckStreamsL round: %d done", i )
       
  1569             }
       
  1570         }
       
  1571     
       
  1572     SVPDEBUG1( "CSVPController::CheckStreamsL Out" )
       
  1573     }
       
  1574 
       
  1575 // -----------------------------------------------------------------------------
       
  1576 // CSVPController::GetCallIdFromUserHeadersL
       
  1577 // Extract call id from user headers
       
  1578 // -----------------------------------------------------------------------------
       
  1579 //
       
  1580 TBool CSVPController::GetCallIdFromUserHeadersL(
       
  1581     const CDesC8Array& aUserHeaders,
       
  1582     TDes8& aCallId )
       
  1583     {
       
  1584     // All variables is used for parser.
       
  1585     TInt tmpMark1 = 0;
       
  1586     TInt tmpMark2 = 0;
       
  1587     
       
  1588     TBool found = EFalse;
       
  1589 
       
  1590     // Find replaces header descriptor from userheaders array.
       
  1591     for ( TInt m = 0; &aUserHeaders && m < aUserHeaders.Count() && !found; m++ )
       
  1592         {
       
  1593         TPtrC8 tmpHeader = aUserHeaders[m];
       
  1594         if ( KErrNotFound != tmpHeader.FindF( KSVPReplacesColonTxt ) )
       
  1595             {
       
  1596             SVPDEBUG1("  CSVPController::\
       
  1597             GetCallIdFromUserHeadersL: Replaces: found:");
       
  1598 
       
  1599             // variables used for parse tags from replaces header.
       
  1600             tmpMark1 = tmpHeader.Locate( KSVPColonMark );
       
  1601             tmpMark2 = tmpHeader.Locate( KSVPSemiColonMark );
       
  1602             if ( KErrNotFound == tmpMark1 ||
       
  1603                  KErrNotFound == tmpMark2 )
       
  1604                 {
       
  1605                 SVPDEBUG3("CSVPController::GetCallIdFromUserHeadersL leave \
       
  1606                       tmpMark1: %d, tmpMark2: %d", tmpMark1, tmpMark2 )
       
  1607                 User::Leave( KErrArgument );
       
  1608                 }
       
  1609 
       
  1610             // Call id is between tmpMark1 and tmpMark2 and there is a space
       
  1611             // between Replaces: -text and callid
       
  1612             if ( ( tmpHeader.Mid( tmpMark1+2, tmpMark2 - tmpMark1 - 2 ).Length() < KSVPTempStringlength ) )
       
  1613                 {
       
  1614                 aCallId.Copy( 
       
  1615                     tmpHeader.Mid( tmpMark1+2, tmpMark2 - tmpMark1 - 2 ) );
       
  1616 
       
  1617                 found = ETrue;                
       
  1618                 }
       
  1619             else
       
  1620                 {
       
  1621                 SVPDEBUG1("  CSVPController::\
       
  1622                 GetCallIdFromUserHeadersL: Replaces: Too long, Leave");
       
  1623                 User::Leave( KErrArgument );
       
  1624                 }
       
  1625             }
       
  1626         }
       
  1627     
       
  1628     SVPDEBUG2( "CSVPController::GetCallIdFromUserHeadersL return %d", found )
       
  1629     return found;
       
  1630     }
       
  1631 
       
  1632 // -----------------------------------------------------------------------------
       
  1633 // CSVPController::IsTransferTargetCaseL
       
  1634 // -----------------------------------------------------------------------------
       
  1635 //
       
  1636 void CSVPController::IsTransferTargetCaseL( CDesC8Array* aHeaders )
       
  1637     {
       
  1638     SVPDEBUG1( "CSVPController::IsTransferTargetCaseL In" )
       
  1639     
       
  1640     iHoldCallIndex = KErrNotFound;
       
  1641     TBool found = EFalse;
       
  1642     
       
  1643     if ( aHeaders && aHeaders->Count() )
       
  1644         {
       
  1645         // Variable to contain callID from replaces header.
       
  1646         TBuf8< KSVPTempStringlength > repCallId( KNullDesC8 );
       
  1647 
       
  1648         // This is transfer session if Replaces: text is found from userheader
       
  1649         if ( GetCallIdFromUserHeadersL( *aHeaders, repCallId ) )
       
  1650             {
       
  1651             SVPDEBUG1( "  CSVPController::IsTransferTargetCaseL: \
       
  1652                 (attended) Transfer target case" )
       
  1653             
       
  1654             if ( repCallId.Length() != 0 )
       
  1655                 {
       
  1656                 // Find from SVP session array a session including same CallId
       
  1657                 // that parsed from replace header.
       
  1658                 for ( TInt v = 0; v < iSessionArray.Count() && !found; v++ )
       
  1659                     {
       
  1660                     SVPDEBUG2( "  CSVPController::IsTransferTargetCaseL v=%d", v )
       
  1661                     
       
  1662                     TBuf8< KSVPTempStringlength > holdCallId( KNullDesC8 );     
       
  1663                     TDesC8* callid2 = iSessionArray[v]->CallId();
       
  1664                     
       
  1665                     if ( callid2 )
       
  1666                         {
       
  1667                         TInt index = callid2->Find( KSVPCallId_replaces );
       
  1668                         holdCallId.Append( 
       
  1669                         callid2->Mid( index + KSVPCallId_replaces().Length() ) );
       
  1670 
       
  1671                         SVPDEBUG2( "CSVPController::IsTransferTargetCaseL: SesState: %d",
       
  1672                                      iSessionArray[v]->State() )
       
  1673                         
       
  1674                         if ( repCallId == holdCallId && 
       
  1675                              MCCPCallObserver::ECCPStateDisconnecting != 
       
  1676                                 iSessionArray[v]->State() )
       
  1677                             {
       
  1678                             iHoldCallIndex = v;
       
  1679                             }
       
  1680                         }
       
  1681                     }
       
  1682                 
       
  1683                 if ( KErrNotFound == iHoldCallIndex )
       
  1684                     {
       
  1685                     SVPDEBUG1("CSVPController::IsTransferTargetCaseL: \
       
  1686                         sessions or CallIds does not match, leave !!!" ) 
       
  1687                     User::Leave( KErrNotSupported );
       
  1688                     }
       
  1689                 }
       
  1690             else
       
  1691                 {
       
  1692                 SVPDEBUG1("CSVPController::IsTransferTargetCaseL: \
       
  1693                     Transfer session but CallId wasn't found, leave !!!" )
       
  1694                 User::Leave( KErrNotSupported );
       
  1695                 }
       
  1696             }
       
  1697         else
       
  1698             {
       
  1699 		    TSupplementaryServicesEvent restrictEvent = 
       
  1700 		    	iSuppServices->CheckRestrictionsL( *aHeaders );
       
  1701 
       
  1702 			if ( ESVPSSDoNotDisturb == restrictEvent )
       
  1703 				{
       
  1704 				User::Leave( KSVPErrDnDRejection );
       
  1705 				}
       
  1706 			if ( ESVPSSAnonymousBarring == restrictEvent )
       
  1707 				{
       
  1708 				User::Leave( KSVPErrAnonymousCallRejection );
       
  1709 				}
       
  1710             SVPDEBUG1("  CSVPController::IsTransferTargetCaseL: \
       
  1711                 Normal incoming case");
       
  1712             }
       
  1713         }
       
  1714 
       
  1715     SVPDEBUG2( "CSVPController::IsTransferTargetCaseL Out iHoldCallIndex: %d",
       
  1716                 iHoldCallIndex )
       
  1717     }
       
  1718 
       
  1719 // --------------------------------------------------------------------------
       
  1720 // CSVPController::IsPreconditionRequired
       
  1721 // Check if Require header contains precondition and that Supported header
       
  1722 // includes option tag 100rel, providing support for PRACK's
       
  1723 // --------------------------------------------------------------------------
       
  1724 TBool CSVPController::IsPreconditionRequired( CDesC8Array& aHeaders )
       
  1725     {
       
  1726     SVPDEBUG1( "CSVPController::IsPreconditionRequired In" )
       
  1727         
       
  1728     TInt count = aHeaders.MdcaCount();
       
  1729     TBool require = EFalse;
       
  1730     TBool supported = EFalse;
       
  1731     while ( count-- )  
       
  1732         {
       
  1733         TPtrC8 tmpHeader = aHeaders.MdcaPoint( count );
       
  1734         if ( KErrNotFound != tmpHeader.Find( KSVPRequire ) && !require )
       
  1735             {
       
  1736             // "Require:" found
       
  1737             SVPDEBUG1( "CSVPController::IsPreconditionRequired 'Require-header' found" )
       
  1738             
       
  1739             if ( tmpHeader.FindF( KSVPPrecondition ) )
       
  1740                 {
       
  1741                 // "precondition" found in Require header field
       
  1742                 SVPDEBUG1( "CSVPController::IsPreconditionRequired 'precondition' found" )
       
  1743                 require = ETrue;
       
  1744                 }
       
  1745             }
       
  1746         else if ( KErrNotFound != tmpHeader.Find( KSVPSupported ) && !supported )
       
  1747             {
       
  1748             // "Supported:" found
       
  1749             SVPDEBUG1( "CSVPController::IsPreconditionRequired 'Supported-header' found" )
       
  1750             
       
  1751             if ( tmpHeader.FindF( KSVP100rel ) )
       
  1752                 {
       
  1753                 // "100rel" found in Supported header field
       
  1754                 SVPDEBUG1( "CSVPController::IsPreconditionRequired '100rel' found" )
       
  1755                 supported = ETrue;
       
  1756                 }
       
  1757             }
       
  1758         }
       
  1759     if ( require && supported )
       
  1760         {
       
  1761         SVPDEBUG1( "CSVPController::IsPreconditionRequired return ETrue" )
       
  1762         return ETrue;
       
  1763         }        
       
  1764     SVPDEBUG1( "CSVPController::IsPreconditionRequired return EFalse" )
       
  1765     return EFalse;
       
  1766     }
       
  1767 	
       
  1768 // ---------------------------------------------------------------------------
       
  1769 // CSVPController::CheckHeadersData
       
  1770 // Check and store data (FromHeader, ToHeader, CallId) from the headers
       
  1771 // to the SessionBase.
       
  1772 // ---------------------------------------------------------------------------
       
  1773 //    
       
  1774 void CSVPController::CheckHeadersData( CSVPSessionBase* aSVPSession, 
       
  1775                             TMceTransactionDataContainer* aContainer )
       
  1776     {
       
  1777     SVPDEBUG1( "CSVPController::CheckHeadersData In" )
       
  1778     
       
  1779     TRAPD( stringErr, SIPStrings::OpenL() );
       
  1780 
       
  1781     if ( KErrNone == stringErr )
       
  1782         {
       
  1783         // get headers
       
  1784         CDesC8Array* headers = aContainer->GetHeaders();
       
  1785 	    RStringF fromHdr = SIPStrings::StringF(SipStrConsts::EFromHeader);
       
  1786 	    RStringF fromCompHdr = SIPStrings::StringF(SipStrConsts::EFromHeaderCompact);
       
  1787 
       
  1788 	    RStringF toHdr = SIPStrings::StringF(SipStrConsts::EToHeader);
       
  1789 	    RStringF toCompHdr = SIPStrings::StringF(SipStrConsts::EToHeaderCompact);
       
  1790 
       
  1791 	    RStringF callidHdr = SIPStrings::StringF(SipStrConsts::ECallIDHeader);
       
  1792 	    RStringF callidCompHdr = SIPStrings::StringF(SipStrConsts::ECallIDHeaderCompact);
       
  1793 	    
       
  1794 	    RStringF cSeqHdr = SIPStrings::StringF(SipStrConsts::ECSeqHeader);
       
  1795 
       
  1796         if ( headers )
       
  1797             {
       
  1798             TBool fromFound( EFalse );
       
  1799             TBool toFound( EFalse );
       
  1800             TBool callIdFound( EFalse );
       
  1801             TBool cSeqFound( EFalse );
       
  1802 
       
  1803             for( TInt i = 0;i < headers->MdcaCount();i++ )
       
  1804                 {
       
  1805                 TPtrC8 tmpHeader = headers->MdcaPoint( i );
       
  1806                 TInt colonMark = tmpHeader.FindF( KSVPCln );
       
  1807                 
       
  1808                 SVPDEBUG2( "CSVPController::CheckHeadersData colonMark=%d", colonMark )
       
  1809                 
       
  1810                 TInt fromHdrPos = tmpHeader.FindF( fromHdr.DesC() );
       
  1811                 TInt fromCompHdrPos = tmpHeader.FindF( fromCompHdr.DesC() );
       
  1812 
       
  1813                 TInt toHdrPos = tmpHeader.FindF( toHdr.DesC() );
       
  1814                 TInt toCompHdrPos = tmpHeader.FindF( toCompHdr.DesC() );
       
  1815 
       
  1816                 TInt callidHdrPos = tmpHeader.FindF( callidHdr.DesC() );
       
  1817                 TInt callidCompHdrPos = tmpHeader.FindF( callidCompHdr.DesC() );
       
  1818                 
       
  1819                 TInt cSeqHdrPos = tmpHeader.FindF( cSeqHdr.DesC() );
       
  1820 
       
  1821                 // Header name is separeted by colonmark from header body.
       
  1822                 // There might be space between name and colonmark.
       
  1823 
       
  1824                 if ( !fromFound &&
       
  1825                      ( (KErrNotFound < fromHdrPos && fromHdrPos < colonMark) ||
       
  1826                        (KErrNotFound < fromCompHdrPos && fromCompHdrPos < colonMark ) ) )
       
  1827                     {
       
  1828                     fromFound = ETrue;
       
  1829                     aSVPSession->SetFromHeader( headers->MdcaPoint( i ) );
       
  1830                     }
       
  1831                 else if ( !toFound &&
       
  1832                         ( (KErrNotFound < toHdrPos && toHdrPos < colonMark) ||
       
  1833                           (KErrNotFound < toCompHdrPos && toCompHdrPos < colonMark ) ) )
       
  1834                     {
       
  1835                     toFound = ETrue;
       
  1836                     aSVPSession->SetToHeader( headers->MdcaPoint( i ) );
       
  1837                     }
       
  1838                 else if ( !callIdFound &&
       
  1839                         ( (KErrNotFound < callidHdrPos && callidHdrPos < colonMark) ||
       
  1840                           (KErrNotFound < callidCompHdrPos && callidCompHdrPos < colonMark ) ) )
       
  1841                     {
       
  1842                     callIdFound = ETrue;
       
  1843                     aSVPSession->SetCallId( headers->MdcaPoint( i ) );
       
  1844                     }
       
  1845                 else if ( !cSeqFound && 
       
  1846                           KErrNotFound < cSeqHdrPos && cSeqHdrPos < colonMark )
       
  1847                     {
       
  1848                     cSeqFound = ETrue;
       
  1849                     aSVPSession->SetCSeqHeader( headers->MdcaPoint( i ) );
       
  1850                     }
       
  1851                 }
       
  1852             }
       
  1853         
       
  1854         SIPStrings::Close();
       
  1855         delete headers;
       
  1856         headers = NULL;
       
  1857         }
       
  1858     else
       
  1859         {
       
  1860         SVPDEBUG2( "CSVPController::CheckHeadersData stringErr=%d", stringErr )
       
  1861         }
       
  1862     
       
  1863     SVPDEBUG1( "CSVPController::CheckHeadersData Out" )
       
  1864     }
       
  1865 
       
  1866 // ---------------------------------------------------------------------------
       
  1867 // CSVPController::CheckContactData
       
  1868 // Check and store contact data from the headers to the MoSession
       
  1869 // ---------------------------------------------------------------------------
       
  1870 //    
       
  1871 TInt CSVPController::CheckContactData( CSVPSessionBase* aSVPSession, 
       
  1872                             TMceTransactionDataContainer* aContainer )
       
  1873     {
       
  1874     SVPDEBUG1( "CSVPController::CheckContactData In" )
       
  1875     
       
  1876     TInt count( 0 );
       
  1877     TRAPD( stringErr, SIPStrings::OpenL() );
       
  1878 
       
  1879     if ( KErrNone == stringErr && aSVPSession->IsMobileOriginated() )
       
  1880         {
       
  1881         CDesC8Array* headers = aContainer->GetHeaders();
       
  1882 
       
  1883         if ( headers )
       
  1884             {
       
  1885     	    RStringF contactHdr = SIPStrings::StringF(SipStrConsts::EContactHeader);
       
  1886     	    RStringF contactHdrComp = SIPStrings::StringF(SipStrConsts::EContactHeaderCompact);
       
  1887 
       
  1888             CSVPMoSession* moSession = static_cast< CSVPMoSession* >( aSVPSession );
       
  1889             moSession->ResetForwardAddressChoices();
       
  1890 
       
  1891             TInt ret( 0 );
       
  1892             for( TInt i( 0 ); i < headers->MdcaCount(); i++ )
       
  1893                 {
       
  1894                 TPtrC8 tmpHeader = headers->MdcaPoint( i );
       
  1895                 TInt colonMark = tmpHeader.FindF( KSVPCln );
       
  1896                 TPtrC8 left = tmpHeader.Left( colonMark ); // string until to first colon mark
       
  1897 
       
  1898                 if ( left.CompareF( contactHdr.DesC() ) == KErrNone ||
       
  1899                      left.CompareF( contactHdrComp.DesC() ) == KErrNone ) 
       
  1900                     {
       
  1901                     SVPDEBUG1( "CSVPController::CheckContactData - Contact header found" )
       
  1902 
       
  1903                     // Get the remaining part of the contact header string and
       
  1904                     // send it to mo session for parsing 
       
  1905                     TPtrC8 right = tmpHeader.Right( 
       
  1906                         tmpHeader.Length() - left.Length() - 1 );
       
  1907 
       
  1908                     TRAPD( addErr, ret = moSession->AddForwardAddressL( right ) );
       
  1909                     if (KErrNone == addErr)
       
  1910                         {
       
  1911                         count = count + ret;
       
  1912                         }
       
  1913                     else
       
  1914                         {
       
  1915                         SVPDEBUG2( "CSVPController::CheckContactData: addErr = %d", addErr )
       
  1916                         }
       
  1917                     }
       
  1918                 }
       
  1919             }
       
  1920         else
       
  1921             {
       
  1922             SVPDEBUG1( "CSVPController::CheckContactData No headers" )
       
  1923             }
       
  1924 
       
  1925         SIPStrings::Close();
       
  1926         delete headers;
       
  1927         headers = NULL;
       
  1928         }
       
  1929     else
       
  1930         {
       
  1931         SVPDEBUG2( "CSVPController::CheckContactData stringErr=%d", stringErr )
       
  1932         }
       
  1933     
       
  1934     SVPDEBUG2( "CSVPController::CheckContactData Out return=%d", count )
       
  1935     return count;
       
  1936     }
       
  1937 
       
  1938 // ---------------------------------------------------------------------------
       
  1939 // CSVPController::IncomingUpdate
       
  1940 // ---------------------------------------------------------------------------
       
  1941 //			
       
  1942 void CSVPController::IncomingUpdate(
       
  1943 				CMceSession& aOrigSession, 
       
  1944 				CMceInSession* aUpdatedSession,
       
  1945 				TMceTransactionDataContainer* aContainer )
       
  1946     {
       
  1947     SVPDEBUG1( "CSVPController::IncomingUpdate In" )
       
  1948     
       
  1949     iContainer = *aContainer;
       
  1950     const TInt sessionIndex = FindSVPSession( aOrigSession );
       
  1951     
       
  1952     if ( KErrNotFound != sessionIndex )
       
  1953         {
       
  1954         SVPDEBUG1( "CSVPController::IncomingUpdate - Session found" )
       
  1955         
       
  1956         // handle RE-INVITE without SDP
       
  1957         if ( !aUpdatedSession->Streams().Count() )
       
  1958             {
       
  1959             SVPDEBUG1( "CSVPController::IncomingUpdate No streams present" )
       
  1960             
       
  1961             // this call sets iEmptyReInvite flag to ETrue for session, 
       
  1962             // flag prevents "ghots session" to be seen on UI 
       
  1963             // when empty Re-Invite is received
       
  1964             iSessionArray[ sessionIndex ]->SetEmptyReInvite();
       
  1965                                
       
  1966             
       
  1967             #ifdef _DEBUG
       
  1968             
       
  1969             TRAPD( noSdpErr, IncomingUpdateNoSdpHandlerL( sessionIndex,
       
  1970                                                           aUpdatedSession ) );
       
  1971             
       
  1972             SVPDEBUG2( "CSVPController::IncomingUpdate trapped: %d", noSdpErr )
       
  1973             
       
  1974             #else   // _UREL
       
  1975             
       
  1976             TRAP_IGNORE( IncomingUpdateNoSdpHandlerL(
       
  1977                 sessionIndex, aUpdatedSession ) )
       
  1978             
       
  1979             #endif  // _DEBUG
       
  1980             }
       
  1981         
       
  1982         else
       
  1983             {
       
  1984             SVPDEBUG1( "CSVPController::IncomingUpdate - Normal case" )
       
  1985             IncomingNormalUpdate( sessionIndex,
       
  1986                     aOrigSession, aUpdatedSession );
       
  1987             }
       
  1988         
       
  1989         SVPDEBUG1( "CSVPController::IncomingUpdate - Handled" )
       
  1990         }
       
  1991     else if ( iEmergencySession && 
       
  1992               aUpdatedSession && 
       
  1993               aUpdatedSession->Streams().Count() )
       
  1994         {
       
  1995         // Handle emergency hold
       
  1996         TRAPD( error, iEmergencySession->IncomingRequestL(
       
  1997                 aUpdatedSession, iContainer ) );
       
  1998         
       
  1999         if ( error )
       
  2000             {
       
  2001             SVPDEBUG2( "CSVPController::IncomingUpdate, emergency error=%d",
       
  2002                     error )
       
  2003             }
       
  2004         }
       
  2005     
       
  2006     SVPDEBUG1( "CSVPController::IncomingUpdate Out" )
       
  2007     }
       
  2008 
       
  2009 // ---------------------------------------------------------------------------
       
  2010 // CSVPController::IncomingNormalUpdate
       
  2011 // ---------------------------------------------------------------------------
       
  2012 //
       
  2013 void CSVPController::IncomingNormalUpdate( TInt aSessionIndex,
       
  2014                                            CMceSession& aOrigSession,
       
  2015                                            CMceInSession* aUpdatedSession )
       
  2016     {
       
  2017     SVPDEBUG1( "CSVPController::IncomingNormalUpdate In" )
       
  2018     
       
  2019     TInt err = iSessionArray[ aSessionIndex ]->IncomingRequest(
       
  2020         *aUpdatedSession );
       
  2021     
       
  2022     if ( KErrSVPHoldNotHoldRequest == err )
       
  2023         {
       
  2024         SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Not Hold/Resume" )
       
  2025         
       
  2026         if ( iSessionArray[ aSessionIndex ]->HasHoldController() &&
       
  2027              KSVPHoldConnectedStateIndex != iSessionArray[ aSessionIndex ]->
       
  2028                  HoldController().HoldState() )
       
  2029             {
       
  2030             // Hold is active; must update MCE streams state 
       
  2031             // correspondingly
       
  2032             TRAP( err, iSessionArray[ aSessionIndex ]->HoldController().
       
  2033                             RefreshHoldStateL() );
       
  2034             SVPDEBUG2( "CSVPController::IncomingNormalUpdate - Err: %d", err )
       
  2035             }
       
  2036         
       
  2037         TRAP( err, UpdateSessionL( aOrigSession, *aUpdatedSession ) );
       
  2038         
       
  2039         SVPDEBUG2( "CSVPController::IncomingNormalUpdate - Updated err: %d",
       
  2040             err )
       
  2041         }
       
  2042     else if ( iDtmfStringSending )
       
  2043         {
       
  2044         SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Dtmf sending will be stopped" )
       
  2045         // send stop event to the previous character in string 
       
  2046         // Default tone char
       
  2047         TChar dtmfToneChar( '0' );
       
  2048 
       
  2049         iSessionArray[ aSessionIndex ]->DtmfObserver().HandleDTMFEvent( 
       
  2050                 MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  2051                 KErrNone, 
       
  2052                 dtmfToneChar );
       
  2053 
       
  2054         // send sequence stop event
       
  2055         iSessionArray[ aSessionIndex ]->DtmfObserver().HandleDTMFEvent( 
       
  2056              MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, 
       
  2057              KErrNone, 
       
  2058              dtmfToneChar );
       
  2059 
       
  2060         // sequence complete, clear flags
       
  2061         iDtmfStringSending = EFalse;
       
  2062         iFirstDtmfSent = EFalse;
       
  2063         
       
  2064         SVPDEBUG1( "CSVPController::IncomingNormalUpdate - Dtmf sending stopped" )
       
  2065         }
       
  2066     else
       
  2067         {
       
  2068         SVPDEBUG2( "CSVPController::IncomingNormalUpdate - IncomingRequest err: %d", err )
       
  2069         }
       
  2070     
       
  2071     iSessionArray[ aSessionIndex ]->SetUpdatedSession( aUpdatedSession );
       
  2072     
       
  2073     SVPDEBUG1( "CSVPController::IncomingNormalUpdate Out" )
       
  2074     }
       
  2075 
       
  2076 // ---------------------------------------------------------------------------
       
  2077 // CSVPController::IncomingUpdateNoSdpHandlerL
       
  2078 // ---------------------------------------------------------------------------
       
  2079 //
       
  2080 void CSVPController::IncomingUpdateNoSdpHandlerL( TInt aSessionIndex,
       
  2081         CMceInSession* aUpdatedSession )
       
  2082     {
       
  2083     SVPDEBUG1( "CSVPController::IncomingUpdateNoSdpHandlerL In" )
       
  2084     if ( iRtpObserver )
       
  2085         {
       
  2086         iRtpObserver->ResetSessionInObserving( iSessionArray[ aSessionIndex ] );
       
  2087 		}
       
  2088     // set updated session to SVP, ownership is transferred
       
  2089     // old session is obsolete
       
  2090     iSessionArray[ aSessionIndex ]->SetUpdatedSession( aUpdatedSession );
       
  2091     
       
  2092     // construct audio streams again, adding all the supported codecs
       
  2093     iSessionArray[ aSessionIndex ]->ConstructAudioStreamsL();
       
  2094     
       
  2095     // finally update the session
       
  2096     aUpdatedSession->UpdateL();
       
  2097     
       
  2098     SVPDEBUG1( "CSVPController::IncomingUpdateNoSdpHandlerL Out" )
       
  2099     }
       
  2100 
       
  2101 // ---------------------------------------------------------------------------
       
  2102 // CSVPController::UpdateSessionL
       
  2103 // ---------------------------------------------------------------------------
       
  2104 //			
       
  2105 void CSVPController::UpdateSessionL( CMceSession& aOrigSession,
       
  2106                                      CMceInSession& aUpdatedSession )
       
  2107     {
       
  2108     SVPDEBUG1( "CSVPController::UpdateSessionL In" )
       
  2109     
       
  2110     __ASSERT_ALWAYS( &aOrigSession, User::Leave( KErrArgument ) );
       
  2111     __ASSERT_ALWAYS( &aUpdatedSession, User::Leave( KErrArgument ) );
       
  2112     
       
  2113     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC();
       
  2114     RPointerArray< CRCSEProfileEntry > voipProfiles;
       
  2115     CleanupResetAndDestroy< RPointerArray< CRCSEProfileEntry > >::PushL(
       
  2116         voipProfiles );
       
  2117     
       
  2118     reg->FindBySIPProfileIdL( aOrigSession.Profile(), voipProfiles );
       
  2119     
       
  2120     TInt keepAliveTime = 0;
       
  2121     TInt index = FindSVPSession( aOrigSession );
       
  2122     if ( KErrNotFound != index )
       
  2123         {
       
  2124         keepAliveTime = iSessionArray[ index ]->GetKeepAliveTime();
       
  2125         __ASSERT_ALWAYS( iRtpObserver, User::Leave( KErrTotalLossOfPrecision ) );
       
  2126         iRtpObserver->ResetSessionInObserving( iSessionArray[ index ] );
       
  2127         }
       
  2128 
       
  2129     // flag prevents wrong handling after SessionStateChanged -callback
       
  2130     iSessionUpdateOngoing = ETrue;
       
  2131 
       
  2132     // sets MMF priorities and sets codec specific settings
       
  2133     CheckStreamsL( *voipProfiles[ 0 ], aUpdatedSession, keepAliveTime,
       
  2134                    iSessionUpdateOngoing );
       
  2135     CleanupStack::PopAndDestroy( 2, reg );
       
  2136     
       
  2137     SVPDEBUG1( "CSVPController::UpdateSessionL - Checked" )
       
  2138     
       
  2139     aUpdatedSession.UpdateL();
       
  2140     SVPDEBUG1( "CSVPController::UpdateSessionL Out" )
       
  2141     }
       
  2142 
       
  2143 // ---------------------------------------------------------------------------
       
  2144 // CSVPController::IncomingRefer
       
  2145 // ---------------------------------------------------------------------------
       
  2146 //			
       
  2147 void CSVPController::IncomingRefer( CMceInRefer* aRefer,
       
  2148         const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer )
       
  2149     {
       
  2150     SVPDEBUG1( "CSVPController::IncomingRefer In" )
       
  2151     
       
  2152     // IncomingReferHandlerL is used to handle possible leave 
       
  2153     SVPDEBUG1( "CSVPController::IncomingRefer IncomingReferHandlerL" )
       
  2154     TRAPD( err, IncomingReferHandlerL( aRefer, aReferTo, aContainer ) );
       
  2155     
       
  2156     if ( err )
       
  2157         {
       
  2158         SVPDEBUG2("CSVPController::IncomingRefer: err: %d", err )
       
  2159         if ( err == KSVPErrTransferInProgress )
       
  2160             {
       
  2161             SVPDEBUG1( "CSVPController::IncomingRefer - transfer in progress \
       
  2162                 -> ignore" )
       
  2163             }
       
  2164         else
       
  2165             {
       
  2166             // TRAP is used because of RejectL might leave.
       
  2167             SVPDEBUG1( "CSVPController::IncomingRefer -> reject" )
       
  2168             TRAP( err, aRefer->RejectL() );
       
  2169         
       
  2170             if ( err )
       
  2171                 {
       
  2172                 SVPDEBUG2("CSspController::IncomingRefer: RejectL err: \
       
  2173                     %d", err )
       
  2174                 }
       
  2175             }
       
  2176         }
       
  2177     
       
  2178     SVPDEBUG1( "CSVPController::IncomingRefer Out" )
       
  2179     }
       
  2180 
       
  2181 // ---------------------------------------------------------------------------
       
  2182 // CSVPController::IncomingReferHandlerL
       
  2183 // ---------------------------------------------------------------------------
       
  2184 //			
       
  2185 void CSVPController::IncomingReferHandlerL( CMceInRefer* aRefer,
       
  2186         const TDesC8& aReferTo, TMceTransactionDataContainer* aContainer )
       
  2187     {
       
  2188     SVPDEBUG1( "CSVPController::IncomingReferHandlerL In" )
       
  2189     
       
  2190     __ASSERT_ALWAYS( aRefer, User::Leave( KErrArgument ) );
       
  2191     
       
  2192     iContainer = *aContainer;
       
  2193     TInt sessionIndex = FindSVPSession( *aRefer->AssociatedSession() );
       
  2194     
       
  2195     if ( KErrNotFound != sessionIndex )    
       
  2196         {
       
  2197         SVPDEBUG2( "CSVPController::InRefHL: AssoSes OK,ind=%d",
       
  2198                 sessionIndex )
       
  2199         
       
  2200         iSessionArray[ sessionIndex ]->IncomingReferL( 
       
  2201                 aRefer, aReferTo, aContainer );
       
  2202         
       
  2203         if ( iSessionArray[ sessionIndex ]->IsAttended() )
       
  2204             {
       
  2205             SVPDEBUG1( "CSVPController::InRefHL: - Attended case" )
       
  2206             }
       
  2207         else
       
  2208             {
       
  2209             SVPDEBUG1( "CSVPController::InRefHL: - Unattended case" )
       
  2210             // Create a new session
       
  2211             CreateNewTransferSessionL( sessionIndex, EFalse );
       
  2212             }
       
  2213         }
       
  2214     else
       
  2215         {
       
  2216         SVPDEBUG1( "CSVPController::InRefHL: Session not Found!!" )
       
  2217         User::Leave( KErrNotFound );
       
  2218         }
       
  2219     
       
  2220     SVPDEBUG1( "CSVPController::IncomingReferHandlerL Out" ) 
       
  2221     }
       
  2222 
       
  2223 // ---------------------------------------------------------------------------
       
  2224 // CSVPController::CreateNewTransferSessionL
       
  2225 // ---------------------------------------------------------------------------
       
  2226 //
       
  2227 void CSVPController::CreateNewTransferSessionL( TInt aSessionIndex,
       
  2228         TBool aAttended )
       
  2229     {
       
  2230     SVPDEBUG1( "CSVPController::CreateNewTransferSessionL In" )
       
  2231 
       
  2232     iIncomingReferCallIndex = aSessionIndex;
       
  2233     // Create a new session
       
  2234     // fetch SIP profile ID from VoIP profiles
       
  2235     RPointerArray< CRCSEProfileEntry > entryArray;
       
  2236     CleanupResetAndDestroy<
       
  2237         RPointerArray<CRCSEProfileEntry> >::PushL( entryArray ); //CS: 1
       
  2238     
       
  2239     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); //CS:2
       
  2240 
       
  2241     const CCCPCallParameters& callParams = iSessionArray[ aSessionIndex ]->Parameters();
       
  2242     SVPDEBUG2(" CSVPController::CNTSL: iServiceId = %d", callParams.ServiceId() )
       
  2243 
       
  2244     // Get VoIP profile by service id
       
  2245     reg->FindByServiceIdL( callParams.ServiceId(), entryArray );
       
  2246     // Take first entry from array
       
  2247     CRCSEProfileEntry* entry = NULL;
       
  2248     if (entryArray.Count() > 0)
       
  2249         {
       
  2250         entry = entryArray[0];
       
  2251         }
       
  2252     else
       
  2253         {
       
  2254         User::Leave(KErrNotFound);
       
  2255         }
       
  2256     // array for provisioned data
       
  2257     CDesC8ArrayFlat* userAgentHeaders = new( ELeave )CDesC8ArrayFlat( 4 );
       
  2258     CleanupStack::PushL( userAgentHeaders );
       
  2259     
       
  2260     // variable for storing security status
       
  2261     TUint32 securityStatus = 0;
       
  2262     
       
  2263     // set provisioning data
       
  2264     SVPDEBUG1( "CSVPController::CNTSL: Set provisioning data..." )
       
  2265     TRAP_IGNORE( iSVPUtility->SetProvisioningDataL( 
       
  2266                                 *entry, 
       
  2267                                 *userAgentHeaders,
       
  2268                                 securityStatus,
       
  2269                                 iTerminalType,
       
  2270                                 iWlanMacAddress ) );
       
  2271     
       
  2272     // only one sip profile per voip profile
       
  2273     TInt sipProfileId = entry->iIds[ 0 ].iProfileId; 
       
  2274     SVPDEBUG2( "CSVPController::CNTSL: sipProfileId=%d", sipProfileId )
       
  2275     
       
  2276     if ( KSVPStatusNonSecure != securityStatus )
       
  2277         {
       
  2278         // If preferred sec is 1 or 2, we check also secure mechanism of sip profile.
       
  2279         // create SIP and ProfileRegistry for URI handling
       
  2280         CSIP* sip = CSIP::NewL( KSVPUid, *this );
       
  2281         CleanupStack::PushL( sip );
       
  2282         SVPDEBUG1( "CSVPController::CNTSL: sip CREATED" )
       
  2283         
       
  2284         CSIPProfileRegistry* sipProfileRegistry = 
       
  2285             CSIPProfileRegistry::NewL( *sip, *this );
       
  2286         CleanupStack::PushL( sipProfileRegistry );
       
  2287 
       
  2288         SVPDEBUG1( "CSVPController::CNTSL: sipProfileRegistry CREATED" )
       
  2289         
       
  2290         // retrieve SIP profile by using sip profile id
       
  2291         CSIPProfile* profile = sipProfileRegistry->ProfileL( sipProfileId );
       
  2292         CleanupStack::PushL( profile );
       
  2293 
       
  2294         // set secure status to 0 if no security mechanism found from SIP profile
       
  2295         iSVPUtility->ResolveSecurityMechanismL( *profile, securityStatus );
       
  2296 
       
  2297         CleanupStack::PopAndDestroy( 3, sip );  // profile, sipProfileRegistry, sip
       
  2298         }
       
  2299     
       
  2300     // set transfer data
       
  2301     SVPDEBUG1( "CSVPController::CNTSL: Set transfer data..." )
       
  2302     iSessionArray[ aSessionIndex ]->SetTransferDataL(
       
  2303             userAgentHeaders, securityStatus );
       
  2304     
       
  2305     SVPDEBUG3( "CSVPController::CNTSL: Header count:%d, sec status:%d",
       
  2306             userAgentHeaders->Count(), securityStatus )
       
  2307     
       
  2308     CSVPMoSession* moSessionTemp = NULL;
       
  2309     
       
  2310     // In attended and unattended transfer case recipient is solved here
       
  2311     SVPDEBUG1( "CSVPController::CNTSL: (Un)Attended, create new mo session" )
       
  2312     const TDesC& referTo = iSessionArray[ aSessionIndex ]->TransferTarget();
       
  2313     // "convert" recpient to 8-bit format
       
  2314     HBufC8* recipient = HBufC8::NewLC( referTo.Length() );
       
  2315     recipient->Des().Copy( referTo );
       
  2316     
       
  2317     moSessionTemp = CSVPMoSession::NewL( *iMceManager,
       
  2318                                          *recipient,
       
  2319                                          *entry, 
       
  2320                                          callParams,
       
  2321                                          iContainer,
       
  2322                                          *this,
       
  2323                                          *iSVPUtility,
       
  2324                                          *iRtpObserver,
       
  2325                                          securityStatus,
       
  2326                                          userAgentHeaders );
       
  2327     
       
  2328     CleanupStack::PopAndDestroy( recipient );
       
  2329     CleanupStack::PushL( moSessionTemp );
       
  2330     
       
  2331     // dtmf and rtp observervers are set
       
  2332     moSessionTemp->SetDtmfObserver( iSessionArray[ aSessionIndex ]->DtmfObserver() );
       
  2333     iRtpObserver->AddSessionForObservingL( moSessionTemp );
       
  2334     
       
  2335     // created SVP session is appended to session array
       
  2336     iSessionArray.AppendL( moSessionTemp );
       
  2337     CleanupStack::Pop( moSessionTemp );
       
  2338     CleanupStack::Pop( userAgentHeaders );
       
  2339     CleanupStack::PopAndDestroy( 2, &entryArray );
       
  2340     
       
  2341     // set CCP session observer to SVP session
       
  2342     SVPDEBUG1( "CSVPController::CNTSL: AddObserverL" )
       
  2343     moSessionTemp->AddObserverL( iSessionArray[ aSessionIndex ]->GetCCPSessionObserver() );
       
  2344     
       
  2345     //set CCP supplementary services events observer to SVP session
       
  2346     SVPDEBUG1( "CSVPController::CNTSL: AddSsObserverL" )
       
  2347     moSessionTemp->SetSsObserver( iSessionArray[ aSessionIndex ]->GetSsObserver() );
       
  2348         
       
  2349     SVPDEBUG1( "CSVPController::CNTSL: callcreated, send to CCP" )
       
  2350     ExecCbCallCreated( moSessionTemp, iSessionArray[ aSessionIndex ], aAttended );
       
  2351     
       
  2352     SVPDEBUG1( "CSVPController::CreateNewTransferSessionL Out" )
       
  2353     }
       
  2354 
       
  2355 // ---------------------------------------------------------------------------
       
  2356 // CSVPController::HandleForwardEvent
       
  2357 // ---------------------------------------------------------------------------
       
  2358 // 
       
  2359 void CSVPController::HandleCallForward( TInt aStatusCode,
       
  2360         TInt aSessionIndex, TMceTransactionDataContainer* aContainer )
       
  2361     {
       
  2362     SVPDEBUG1( "CSVPController::HandleForwardEvent In" )
       
  2363     SVPDEBUG2( "CSVPController::HandleForwardEvent aStatusCode=%d", aStatusCode )
       
  2364     
       
  2365     if ( !iSessionArray[ aSessionIndex ]->IsMobileOriginated() )
       
  2366         {
       
  2367         iSessionArray[ aSessionIndex ]->
       
  2368             GetCCPSessionObserver().ErrorOccurred( ECCPErrorNotReached, 
       
  2369                                               iSessionArray[ aSessionIndex ] );
       
  2370         }
       
  2371     else
       
  2372         {
       
  2373         CSVPMoSession* session = static_cast< CSVPMoSession* >(
       
  2374                 iSessionArray[ aSessionIndex ] );
       
  2375         
       
  2376         switch ( aStatusCode )
       
  2377             {
       
  2378             case KSVPMultipleChoicesVal:    // 300
       
  2379             case KSVPMovedPermanentlyVal:   // 301
       
  2380                 {
       
  2381                 // Get contact headers and notify
       
  2382                 TInt count = CheckContactData( session, aContainer );
       
  2383 
       
  2384                 if ( 0 < count )
       
  2385                     {
       
  2386                     session->NotifyForwardEvent( aStatusCode );
       
  2387                     }
       
  2388                 else
       
  2389                     {
       
  2390                     session->GetCCPSessionObserver().ErrorOccurred( 
       
  2391                                                         ECCPErrorNotReached,
       
  2392                                                         session );
       
  2393                     }
       
  2394                 break;
       
  2395                 }
       
  2396             case KSVPMovedTemporarilyVal:   // 302
       
  2397                 {
       
  2398                 // Just notify, this call forward is handled automatically by mce
       
  2399                 session->NotifyForwardEvent( aStatusCode );
       
  2400                 session->GetCCPSessionObserver().
       
  2401                     CallStateChanged( MCCPCallObserver::ECCPStateForwarding,
       
  2402                                       session );
       
  2403                 break;
       
  2404                 }
       
  2405             default:
       
  2406                 {
       
  2407                 SVPDEBUG1( "CSVPController::HandleForwardEvent: unknown code" )
       
  2408                 session->GetCCPSessionObserver().ErrorOccurred( 
       
  2409                                                     ECCPErrorNotReached,
       
  2410                                                     session );
       
  2411                 }
       
  2412             }
       
  2413         }
       
  2414     
       
  2415     SVPDEBUG1( "CSVPController::HandleForwardEvent Out" )
       
  2416     }
       
  2417 
       
  2418 // ---------------------------------------------------------------------------
       
  2419 // CSVPController::StreamStateChanged
       
  2420 // ---------------------------------------------------------------------------
       
  2421 //			
       
  2422 void CSVPController::StreamStateChanged( CMceMediaStream& aStream )
       
  2423     {
       
  2424     SVPDEBUG1("CSVPController::StreamStateChanged In" )
       
  2425     
       
  2426     if ( &aStream )
       
  2427         {
       
  2428         if ( !iEmergencySession )
       
  2429             {
       
  2430             const TInt index = FindSVPSession( *aStream.Session() );
       
  2431             if ( KErrNotFound != index )
       
  2432                 {
       
  2433                 iSessionArray[ index ]->HandleStreamStateChange( aStream );
       
  2434                 }
       
  2435                 
       
  2436             SVPDEBUG2( "CSVPController::StreamStateChanged index: %d", index )
       
  2437             }
       
  2438         else // Emergency session
       
  2439             {
       
  2440             iEmergencySession->StreamStateChanged( aStream );
       
  2441             }
       
  2442         }
       
  2443     else
       
  2444         {
       
  2445         SVPDEBUG1( "CSVPController::StreamStateChanged, faulty arguments" )
       
  2446         }
       
  2447     
       
  2448     SVPDEBUG1("CSVPController::StreamStateChanged Out" )
       
  2449     }
       
  2450 
       
  2451 // ---------------------------------------------------------------------------
       
  2452 // CSVPController::StreamStateChanged
       
  2453 // ---------------------------------------------------------------------------
       
  2454 //
       
  2455 void CSVPController::StreamStateChanged( CMceMediaStream& aStream,
       
  2456     CMceMediaSink& aSink )
       
  2457     {
       
  2458     SVPDEBUG1( "CSVPController::StreamStateChanged SINK In" )
       
  2459     
       
  2460     if ( &aStream && &aSink )
       
  2461         {
       
  2462         SVPDEBUG2( "CSVPController::StreamStateChanged SINK Stream State: %d", aStream.State() )
       
  2463         SVPDEBUG2( "CSVPController::StreamStateChanged SINK Sink IsEnabled: %d", aSink.IsEnabled() )
       
  2464         
       
  2465         if ( !iEmergencySession )
       
  2466             {
       
  2467             const TInt index = FindSVPSession( *aStream.Session() );
       
  2468             
       
  2469             if ( KErrNotFound != index )
       
  2470                 {
       
  2471                 iSessionArray[ index ]->HandleStreamStateChange( aStream, aSink );
       
  2472                 }
       
  2473             
       
  2474             SVPDEBUG2( "CSVPController::StreamStateChanged SINK index: %d", index )
       
  2475             }
       
  2476         else // Emergency session
       
  2477             {
       
  2478             iEmergencySession->StreamStateChanged( aStream );
       
  2479             }
       
  2480         }
       
  2481     else
       
  2482         {
       
  2483         SVPDEBUG1( "CSVPController::StreamStateChanged SINK, faulty arguments" )
       
  2484         }
       
  2485     
       
  2486     SVPDEBUG1( "CSVPController::StreamStateChanged SINK Out" )
       
  2487     }
       
  2488 
       
  2489 // ---------------------------------------------------------------------------
       
  2490 // CSVPController::StreamStateChanged
       
  2491 // ---------------------------------------------------------------------------
       
  2492 //
       
  2493 void CSVPController::StreamStateChanged( CMceMediaStream& aStream,
       
  2494     CMceMediaSource& aSource )
       
  2495     {
       
  2496     SVPDEBUG1( "CSVPController::StreamStateChanged SOURCE In" )
       
  2497     
       
  2498     if ( &aStream && &aSource )
       
  2499         {
       
  2500         SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE Stream State: %d", aStream.State() )
       
  2501         SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE Source IsEnabled: %d", aSource.IsEnabled() )
       
  2502 
       
  2503         if ( !iEmergencySession )
       
  2504             {
       
  2505             const TInt index = FindSVPSession( *aStream.Session() );           
       
  2506             if ( KErrNotFound != index )
       
  2507                 {
       
  2508                 iSessionArray[ index ]->HandleStreamStateChange( aStream, aSource );
       
  2509                 }
       
  2510             
       
  2511             SVPDEBUG2( "CSVPController::StreamStateChanged SOURCE index: %d", index )
       
  2512             }
       
  2513         else // Emergency session
       
  2514             {
       
  2515             iEmergencySession->StreamStateChanged( aStream );
       
  2516             }        
       
  2517         
       
  2518         }
       
  2519     
       
  2520     SVPDEBUG1( "CSVPController::StreamStateChanged SOURCE Out" )
       
  2521     }
       
  2522 
       
  2523 
       
  2524 // from ConvergedCallProvider
       
  2525 // ---------------------------------------------------------------------------
       
  2526 // CSVPController::NewEmergencyCallL
       
  2527 // ---------------------------------------------------------------------------
       
  2528 //
       
  2529 MCCPEmergencyCall* CSVPController::NewEmergencyCallL( 
       
  2530     const TUint32 /*aServiceId*/,
       
  2531     const TDesC&  aAddress, 
       
  2532     const MCCPCallObserver& aObserver )                                            
       
  2533     {
       
  2534     SVPDEBUG1( "CSVPController::NewEmergencyCallL In" )
       
  2535     
       
  2536     // Retrieve available VoIP and IAP IDs
       
  2537     if ( 0 == iEmergencyProfileIds.Count() && 0 == iEmergencyIapIds.Count() )
       
  2538         {
       
  2539         CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:1
       
  2540         CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS:2
       
  2541         CSIPProfileRegistry* sipProfileRegistry = CSIPProfileRegistry::NewLC( 
       
  2542             *sip, *this ); // CS:3
       
  2543         
       
  2544         // Get all VoIP profile IDs into an array
       
  2545         RArray< TUint32 > voipProfileIds;
       
  2546         CleanupClosePushL( voipProfileIds );    //CS: 4
       
  2547         reg->GetAllIdsL( voipProfileIds );
       
  2548     
       
  2549         // Sort the VoIP profile array so that registered profiles are first
       
  2550         for ( TInt i = 0; i < voipProfileIds.Count(); i++ )
       
  2551             {
       
  2552             TBool registered( EFalse );
       
  2553             CRCSEProfileEntry* entry = CRCSEProfileEntry::NewLC(); // CS:5
       
  2554             reg->FindL( voipProfileIds[i], *entry );
       
  2555             // There is only one (or zero) SIP profile per VoIP profile.
       
  2556             // If profileId is not found,
       
  2557             // CSVPEmergencySession::ConstructL will handle the error
       
  2558             if ( 0 < entry->iIds.Count() )
       
  2559                 {
       
  2560                 SVPDEBUG2( "CSVPController::NewEmergencyCallL, SIP Id count:%d",
       
  2561                         entry->iIds.Count() )
       
  2562                 CSIPProfile* sipProfile = sipProfileRegistry->ProfileL( 
       
  2563                     entry->iIds[0].iProfileId );
       
  2564                 sipProfile->GetParameter( KSIPProfileRegistered, registered );
       
  2565                 delete sipProfile;
       
  2566                 }
       
  2567             CleanupStack::PopAndDestroy( entry ); // CS:4
       
  2568             if ( registered )
       
  2569                 {
       
  2570                 // Move registered VoIP profile IDs to the front
       
  2571                 iEmergencyProfileIds.Insert( voipProfileIds[i], 0 );
       
  2572                 }
       
  2573             else
       
  2574                 {
       
  2575                 iEmergencyProfileIds.Append( voipProfileIds[i] );
       
  2576                 }
       
  2577             }
       
  2578         
       
  2579         CleanupStack::PopAndDestroy( 4, reg ); 
       
  2580         // CS:0 voipProfileIds, sipProfileRegistry, sip, reg
       
  2581         
       
  2582         // Request and wait for IAP IDs
       
  2583         CSVPEmergencyIapProvider* iapProvider = 
       
  2584             CSVPEmergencyIapProvider::NewLC( 
       
  2585             CActive::EPriorityStandard ); // CS:1
       
  2586         iapProvider->RequestIapIds( iEmergencyIapIds );
       
  2587         CleanupStack::PopAndDestroy( iapProvider ); // CS:0
       
  2588         }
       
  2589     
       
  2590     SVPDEBUG2("CSVPController::NewEmergencyCallL, VoIP count:%d", 
       
  2591             iEmergencyProfileIds.Count() )
       
  2592     SVPDEBUG2("CSVPController::NewEmergencyCallL, IAP count:%d", 
       
  2593             iEmergencyIapIds.Count() )
       
  2594     
       
  2595     // Define last try
       
  2596     TBool isLastId( EFalse );
       
  2597     
       
  2598     if ( ( 0 == iEmergencyProfileIds.Count() && 
       
  2599            1 == iEmergencyIapIds.Count() ) ||
       
  2600          ( 1 == iEmergencyProfileIds.Count() && 
       
  2601            0 == iEmergencyIapIds.Count() )
       
  2602        )
       
  2603         {
       
  2604         isLastId = ETrue;
       
  2605         SVPDEBUG1("CSVPController::NewEmergencyCallL, last ID");
       
  2606         }
       
  2607     
       
  2608     // Create session
       
  2609     CSVPEmergencySession* emergencySession = NULL;
       
  2610     
       
  2611     if ( iEmergencyProfileIds.Count() )
       
  2612         {
       
  2613         // Create emergency session with VoIP ID
       
  2614         TRAPD( err, emergencySession = CSVPEmergencySession::NewL( 
       
  2615             *iMceManager,
       
  2616             iEmergencyProfileIds[0], 
       
  2617             aAddress,
       
  2618             aObserver,
       
  2619             *iSVPUtility, 
       
  2620             isLastId ) )
       
  2621     
       
  2622         if ( err )
       
  2623             {
       
  2624             // Create dummy session for session release
       
  2625             emergencySession = CSVPEmergencySession::NewL( 
       
  2626                 *iMceManager,
       
  2627                 iEmergencyProfileIds[0], 
       
  2628                 aAddress,
       
  2629                 aObserver,
       
  2630                 *iSVPUtility, 
       
  2631                 isLastId, 
       
  2632                 ETrue );   
       
  2633             }
       
  2634         
       
  2635         // Update profile array
       
  2636         iEmergencyProfileIds.Remove( 0 );
       
  2637         }
       
  2638     else if ( iEmergencyIapIds.Count() )
       
  2639         {
       
  2640         // Create emergency session with IAP ID
       
  2641         TRAPD( err, emergencySession = CSVPEmergencySession::NewL( 
       
  2642             *iMceManager,
       
  2643             aAddress,
       
  2644             aObserver,
       
  2645             *iSVPUtility,
       
  2646             iEmergencyIapIds[0],  
       
  2647             isLastId ) )
       
  2648     
       
  2649         if ( err )
       
  2650             {
       
  2651             // Create dummy session for session release
       
  2652             emergencySession = CSVPEmergencySession::NewL( 
       
  2653                 *iMceManager,
       
  2654                 aAddress,
       
  2655                 aObserver,
       
  2656                 *iSVPUtility, 
       
  2657                 iEmergencyIapIds[0], 
       
  2658                 isLastId, 
       
  2659                 ETrue );   
       
  2660             }        
       
  2661         
       
  2662         // Update IAP array
       
  2663         iEmergencyIapIds.Remove( 0 );
       
  2664         }
       
  2665     else
       
  2666         {
       
  2667         User::Leave( KErrNotFound );
       
  2668         }
       
  2669     
       
  2670     // save emergency session to controller
       
  2671     iEmergencySession = emergencySession;
       
  2672     
       
  2673     if ( iCCPDtmfObserver )
       
  2674             {
       
  2675             SVPDEBUG1( "CSVPController::NewEmergencyCallL setting DTMFObserver" )
       
  2676             iEmergencySession->SetDtmfObserver( *iCCPDtmfObserver );
       
  2677             }
       
  2678     
       
  2679     SVPDEBUG1( "CSVPController::NewEmergencyCallL Out" )
       
  2680     // return pointer to CCP emergency call object
       
  2681     return emergencySession;
       
  2682     }
       
  2683                         
       
  2684 // ---------------------------------------------------------------------------
       
  2685 // CSVPController::NewConferenceL
       
  2686 // ---------------------------------------------------------------------------
       
  2687 //
       
  2688 MCCPConferenceCall* CSVPController::NewConferenceL( 
       
  2689         const TUint32 /* aServiceId */, 
       
  2690         const MCCPConferenceCallObserver& /*aObserver*/ )
       
  2691     {
       
  2692     return NULL;
       
  2693     }
       
  2694     
       
  2695 // ---------------------------------------------------------------------------
       
  2696 // CSVPController::AcceptTransfer
       
  2697 // ---------------------------------------------------------------------------
       
  2698 //                 
       
  2699 void CSVPController::AcceptTransfer( TBool /*aAccept*/ ) 
       
  2700     {
       
  2701     SVPDEBUG1( "CSVPController::AcceptTransfer In" )
       
  2702     SVPDEBUG1( "CSVPController::AcceptTransfer Out" )
       
  2703     }
       
  2704 
       
  2705 // ---------------------------------------------------------------------------
       
  2706 // CSVPController::ForwardCallToAddressL
       
  2707 // ---------------------------------------------------------------------------
       
  2708 //
       
  2709 TInt CSVPController::ForwardCallToAddressL( const TInt /*aIndex*/ ) 
       
  2710     {
       
  2711     return NULL;
       
  2712     }
       
  2713     
       
  2714 // ---------------------------------------------------------------------------
       
  2715 // CSVPController::Caps
       
  2716 // ---------------------------------------------------------------------------
       
  2717 //
       
  2718 TUint32 CSVPController::Caps() const
       
  2719     {
       
  2720     return 0;
       
  2721     }
       
  2722 
       
  2723 // ---------------------------------------------------------------------------
       
  2724 // CSVPController::DTMFProvider
       
  2725 // ---------------------------------------------------------------------------
       
  2726 //
       
  2727 MCCPDTMFProvider* CSVPController::DTMFProviderL(
       
  2728     const MCCPDTMFObserver& aObserver )
       
  2729     {
       
  2730     SVPDEBUG1( "CSVPController::DTMFProviderL In" )
       
  2731     
       
  2732     iCCPDtmfObserver = &aObserver;
       
  2733     
       
  2734     TInt sessions = iSessionArray.Count();
       
  2735     while ( sessions )
       
  2736         {
       
  2737         sessions--;
       
  2738         iSessionArray[ sessions ]->SetDtmfObserver( aObserver );
       
  2739         
       
  2740         SVPDEBUG2( "CSVPController::DTMFProviderL sessions: %d", sessions )
       
  2741         }
       
  2742     
       
  2743     if ( iEmergencySession )
       
  2744         {
       
  2745         iEmergencySession->SetDtmfObserver( aObserver );
       
  2746         }
       
  2747     
       
  2748     SVPDEBUG1( "CSVPController::DTMFProviderL Out" )
       
  2749     return this;
       
  2750     }
       
  2751 
       
  2752 
       
  2753 // ---------------------------------------------------------------------------
       
  2754 // CSVPController::ExtensionProvider
       
  2755 // ---------------------------------------------------------------------------
       
  2756 //
       
  2757 MCCPExtensionProvider* CSVPController::ExtensionProviderL( 
       
  2758     const MCCPExtensionObserver& /*aObserver*/ )
       
  2759     {
       
  2760     return NULL;
       
  2761     }
       
  2762   
       
  2763 // dtmf provider
       
  2764 
       
  2765 // ---------------------------------------------------------------------------
       
  2766 // CSVPController::CancelDtmfStringSending
       
  2767 // ---------------------------------------------------------------------------
       
  2768 //
       
  2769 TInt CSVPController::CancelDtmfStringSending()
       
  2770     {
       
  2771     SVPDEBUG1( "CSVPController::CancelDtmfStringSending In" )
       
  2772     
       
  2773     TInt err( KErrNotSupported ); 
       
  2774     // find active session
       
  2775     
       
  2776     TInt sesCount = iSessionArray.Count();
       
  2777     CSVPSessionBase* session = NULL;
       
  2778     while ( sesCount )
       
  2779         {
       
  2780         sesCount--;
       
  2781         session = iSessionArray[ sesCount ];
       
  2782         
       
  2783         if ( SVPAudioUtility::DtmfActionCapableSession( *session ) )
       
  2784             {
       
  2785             err = session->CancelDtmfStringSending();
       
  2786             }
       
  2787         SVPDEBUG3( "CSVPController::CancelDtmfStringSending sesCount: %d, err: %d",
       
  2788                      sesCount, err )
       
  2789         session = NULL;
       
  2790         }
       
  2791     
       
  2792     if ( iEmergencySession && 
       
  2793          SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) )
       
  2794         {
       
  2795         err = iEmergencySession->CancelDtmfStringSending();
       
  2796         }
       
  2797         
       
  2798     SVPDEBUG2("CSVPController::CancelDtmfStringSending Out return=%d", err )
       
  2799     iDtmfStringSending = EFalse;
       
  2800     iFirstDtmfSent = EFalse;
       
  2801     return err;
       
  2802     }
       
  2803 
       
  2804 // ---------------------------------------------------------------------------
       
  2805 // CSVPController::StartDtmfTone
       
  2806 // ---------------------------------------------------------------------------
       
  2807 //
       
  2808 TInt CSVPController::StartDtmfTone( const TChar aTone )
       
  2809     {
       
  2810     SVPDEBUG1( "CSVPController::StartDtmfTone In" )
       
  2811     
       
  2812     TInt err( KErrNotSupported );
       
  2813     
       
  2814     // Save DTMF tone for later use in outband dtmf start/stop events
       
  2815     iDtmfTone = aTone;
       
  2816     // Send the tone to all sessions, but check mute and hold cases where session must
       
  2817     // be in 'connected' state in order to send DTMF's. Session will then
       
  2818     // discriminate between inband and outband DTMF's.
       
  2819     TInt sesCount = iSessionArray.Count();
       
  2820     CSVPSessionBase* session = NULL;
       
  2821     while ( sesCount )
       
  2822         {
       
  2823         sesCount--;
       
  2824         session = iSessionArray[ sesCount ];
       
  2825         // Checking hold and mute status
       
  2826         if ( SVPAudioUtility::DtmfActionCapableSession( *session ) &&
       
  2827                 !session->IsSessionMuted()  )
       
  2828             {
       
  2829             err = session->StartDtmfTone( aTone );
       
  2830             }
       
  2831         SVPDEBUG3( "CSVPController::StartDtmfTone sesCount: %d, err: %d",
       
  2832                       sesCount, err )
       
  2833         session = NULL;
       
  2834         }
       
  2835     
       
  2836     if ( iEmergencySession && 
       
  2837          SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) )
       
  2838         {
       
  2839         err = iEmergencySession->StartDtmfTone( aTone );
       
  2840         }
       
  2841     
       
  2842     SVPDEBUG2("CSVPController::StartDtmfTone Out return=%d", err )
       
  2843     return err;
       
  2844     }
       
  2845 
       
  2846 // ---------------------------------------------------------------------------
       
  2847 // CSVPController::StopDtmfTone
       
  2848 // ---------------------------------------------------------------------------
       
  2849 //
       
  2850 TInt CSVPController::StopDtmfTone()
       
  2851     {
       
  2852     SVPDEBUG1( "CSVPController::StopDtmfTone In" )
       
  2853     
       
  2854     TInt err( KErrNotSupported );
       
  2855     
       
  2856     TInt sesCount = iSessionArray.Count();
       
  2857     CSVPSessionBase* session = NULL;
       
  2858     while ( sesCount )
       
  2859         {
       
  2860         sesCount--;
       
  2861         session = iSessionArray[ sesCount ];
       
  2862         
       
  2863         if ( SVPAudioUtility::DtmfActionCapableSession( *session ) )
       
  2864             {
       
  2865             err = session->StopDtmfTone();
       
  2866             }
       
  2867         SVPDEBUG3( "CSVPController::StopDtmfTone sesCount: %d, err: %d",
       
  2868                      sesCount, err )
       
  2869         session = NULL;
       
  2870         }
       
  2871 
       
  2872     if ( iEmergencySession && 
       
  2873          SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) )
       
  2874         {
       
  2875         err = iEmergencySession->StopDtmfTone();
       
  2876         }
       
  2877 
       
  2878     SVPDEBUG2("CSVPController::StopDtmfTone Out return=%d", err )
       
  2879     return err;
       
  2880     }
       
  2881 
       
  2882 // ---------------------------------------------------------------------------
       
  2883 // CSVPController::SendDtmfToneString
       
  2884 // ---------------------------------------------------------------------------
       
  2885 //
       
  2886 TInt CSVPController::SendDtmfToneString( const TDesC& aString )
       
  2887     {
       
  2888     SVPDEBUG1( "CSVPController::SendDtmfToneString In" )
       
  2889     
       
  2890     TInt err( KErrNotSupported );
       
  2891     
       
  2892     delete iDtmfString;
       
  2893     iDtmfString = NULL;
       
  2894     TRAPD( errBuf, iDtmfString = HBufC::NewL( aString.Length() ) );
       
  2895     if ( KErrNone != errBuf )
       
  2896         {
       
  2897         return errBuf;
       
  2898         }
       
  2899     // Take local copy of the dtmf string to be sent
       
  2900     // This is needed for outband dtmf sequence start/stop event
       
  2901     *iDtmfString = aString;
       
  2902     iDtmfStringLex.Assign( *iDtmfString );
       
  2903     
       
  2904     TInt sesCount = iSessionArray.Count();
       
  2905     CSVPSessionBase* session = NULL;
       
  2906 
       
  2907     while ( sesCount )
       
  2908         {
       
  2909         sesCount--;
       
  2910         session = iSessionArray[ sesCount ];
       
  2911         // Checking hold and mute status
       
  2912         if ( SVPAudioUtility::DtmfActionCapableSession( *session ) &&
       
  2913              !session->IsSessionMuted() )
       
  2914             {
       
  2915             err = session->SendDtmfToneString( aString );
       
  2916             if ( KErrNone == err )
       
  2917                 {
       
  2918                 iDtmfStringSending = ETrue;
       
  2919                 iFirstDtmfSent = EFalse;
       
  2920                 }
       
  2921             }
       
  2922         SVPDEBUG3( "CSVPController::SendDtmfToneString sesCount: %d, err: %d",
       
  2923                      sesCount, err )
       
  2924         session = NULL;
       
  2925         }
       
  2926     
       
  2927     if ( iEmergencySession )
       
  2928         {
       
  2929         if ( SVPAudioUtility::DtmfActionCapableSession( *iEmergencySession ) )
       
  2930             {
       
  2931             err = iEmergencySession->SendDtmfToneString( aString );
       
  2932             }
       
  2933         iDtmfStringSending = ETrue;
       
  2934         iFirstDtmfSent = EFalse;        
       
  2935         }
       
  2936 
       
  2937     SVPDEBUG2("CSVPController::SendDtmfToneString Out return=%d", err )
       
  2938     return err;
       
  2939     }
       
  2940 
       
  2941 // ---------------------------------------------------------------------------
       
  2942 // CSVPController::ContinueDtmfStringSending
       
  2943 // ---------------------------------------------------------------------------
       
  2944 //
       
  2945 TInt CSVPController::ContinueDtmfStringSending( const TBool /*aContinue*/ )
       
  2946     {
       
  2947     // SVP sessionbase used to implement this as only returning
       
  2948     // KErrNotSupported, so why not accept the situation here and just
       
  2949     // return KErrNotSupported.
       
  2950     
       
  2951     SVPDEBUG1( "CSVPController::ContinueDtmfStringSending KErrNotSupported" )
       
  2952     return KErrNotSupported;
       
  2953     }
       
  2954 
       
  2955 // ---------------------------------------------------------------------------
       
  2956 // CSVPController::AddObserverL
       
  2957 // ---------------------------------------------------------------------------
       
  2958 //   
       
  2959 void CSVPController::AddObserverL( const MCCPDTMFObserver& /*aObserver*/ )
       
  2960     {
       
  2961     SVPDEBUG1( "CSVPController::AddObserverL MCCPDTMFObserver" )
       
  2962     }
       
  2963 
       
  2964 // ---------------------------------------------------------------------------
       
  2965 // CSVPController::RemoveObserver
       
  2966 // ---------------------------------------------------------------------------
       
  2967 //
       
  2968 TInt CSVPController::RemoveObserver( const MCCPDTMFObserver& /*aObserver*/ )
       
  2969     {
       
  2970     SVPDEBUG1( "CSVPController::RemoveObserver MCCPDTMFObserver" )
       
  2971     return KErrNotSupported;
       
  2972     }
       
  2973 
       
  2974   
       
  2975 // refer observer
       
  2976   
       
  2977 // ---------------------------------------------------------------------------
       
  2978 // CSVPController::ReferStateChanged
       
  2979 // ---------------------------------------------------------------------------
       
  2980 //
       
  2981 void CSVPController::ReferStateChanged( CMceRefer& aRefer,
       
  2982         TMceTransactionDataContainer* aContainer )
       
  2983     {
       
  2984     SVPDEBUG1( "CSVPController::ReferStateChanged In" )
       
  2985     
       
  2986     iContainer = *aContainer;
       
  2987     TInt ind = KErrNotFound;
       
  2988 
       
  2989     // loop session array and check refer
       
  2990     for ( TInt s = 0; s < iSessionArray.Count() && 
       
  2991           KErrNotFound == ind; s++ )
       
  2992         { 
       
  2993         if ( iSessionArray[ s ]->IsMceRefer( aRefer ) )
       
  2994             {
       
  2995             ind = s;
       
  2996             } 
       
  2997         }
       
  2998 
       
  2999     if ( KErrNotFound != ind )
       
  3000         {
       
  3001         SVPDEBUG2(" CSVPController::ReferStateChanged ind: %d", ind );
       
  3002         TInt statusCode = iContainer.GetStatusCode();
       
  3003 
       
  3004         iSessionArray[ ind ]->ReferStateChanged( aRefer, statusCode );
       
  3005         }
       
  3006     
       
  3007     SVPDEBUG1( "CSVPController::ReferStateChanged Out" )
       
  3008     }
       
  3009 
       
  3010 // ---------------------------------------------------------------------------
       
  3011 // CSVPController::ReferConnectionStateChanged
       
  3012 // ---------------------------------------------------------------------------
       
  3013 //
       
  3014 void CSVPController::ReferConnectionStateChanged( CMceRefer& /*aRefer*/,
       
  3015         TBool /*aActive*/ )
       
  3016     {
       
  3017     SVPDEBUG1( "CSVPController::ReferConnectionStateChanged" )
       
  3018     }
       
  3019 
       
  3020 // ---------------------------------------------------------------------------
       
  3021 // CSVPController::Failed
       
  3022 // ---------------------------------------------------------------------------
       
  3023 //
       
  3024 #ifdef _DEBUG
       
  3025 void CSVPController::Failed( CMceRefer& /*aRefer*/, TInt aError )
       
  3026 #else
       
  3027 void CSVPController::Failed( CMceRefer& /*aRefer*/, TInt /*aError*/ )
       
  3028 #endif // _DEBUG
       
  3029     {
       
  3030     SVPDEBUG2( "CSVPController::Failed Refer failed with error: %d", aError )
       
  3031     }
       
  3032 
       
  3033 
       
  3034 // Mce DMTF observer
       
  3035 // ---------------------------------------------------------------------------
       
  3036 // CSVPController::DtmfToneReceived
       
  3037 // ---------------------------------------------------------------------------
       
  3038 //
       
  3039 void CSVPController::DtmfToneReceived( CMceSession& /*aSession*/,
       
  3040         CMceAudioStream& /*aStream*/, const TChar& /*aTone*/ )
       
  3041     {
       
  3042     // Not supported
       
  3043     SVPDEBUG1( "CSVPController:: DtmfToneReceived - Not supported" )
       
  3044     }
       
  3045     
       
  3046 // ---------------------------------------------------------------------------
       
  3047 // CSVPController::DtmfEventReceived
       
  3048 // ---------------------------------------------------------------------------
       
  3049 //
       
  3050 void CSVPController::DtmfEventReceived( CMceSession& aSession,
       
  3051                                         CMceAudioStream& /*aStream*/,
       
  3052                                         CMceMediaSource& /*aSource*/,
       
  3053                                         TMceDtmfEvent aEvent )
       
  3054     {
       
  3055     SVPDEBUG3( "CSVPController::DtmfEventReceived In, aEvent: %d, iDtmfStringSending: %d",
       
  3056                    aEvent, iDtmfStringSending )
       
  3057     
       
  3058     // find what session received the event
       
  3059     const TInt index = FindSVPSession( aSession );
       
  3060     
       
  3061     if ( KErrNotFound != index )
       
  3062         {
       
  3063          // match dtmf event
       
  3064         MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = 
       
  3065             iSVPUtility->GetDtmfEvent( aEvent, iDtmfStringSending );
       
  3066         
       
  3067         // dtmf string
       
  3068         if ( iDtmfStringSending ) 
       
  3069             { 
       
  3070             // only start event received from mce
       
  3071             // logic below needed so that stop events can be sent
       
  3072             if ( MCCPDTMFObserver::ECCPDtmfSequenceStart == dtmfEvent )
       
  3073                 {
       
  3074                 if ( !iFirstDtmfSent )
       
  3075                     {
       
  3076                     SVPDEBUG1( "CSVPController::DtmfEventReceived FIRST SEND" )
       
  3077                     
       
  3078                     // send start
       
  3079                     iFirstDtmfSent = ETrue;
       
  3080                      // call back event to application
       
  3081                     iSessionArray[ index ]->
       
  3082                         DtmfObserver().HandleDTMFEvent( dtmfEvent, 
       
  3083                                                         KErrNone, 
       
  3084                                                         iDtmfStringLex.Peek() );
       
  3085                     }  
       
  3086                 else
       
  3087                     {
       
  3088                     SVPDEBUG1( "CSVPController::DtmfEventReceived STOP TO PREVIOUS" )
       
  3089                     
       
  3090                     // send stop event to the previous character in string 
       
  3091                     iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( 
       
  3092                         MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  3093                         KErrNone, 
       
  3094                         iDtmfStringLex.Get() );
       
  3095                      SVPDEBUG1("CSVPController::DtmfEventReceived START TO CURRENT");
       
  3096                     // send start event to the current character in string
       
  3097                     iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( 
       
  3098                         dtmfEvent, 
       
  3099                         KErrNone, 
       
  3100                         iDtmfStringLex.Peek() );
       
  3101                     }
       
  3102                 }
       
  3103              else
       
  3104                 {
       
  3105                 SVPDEBUG1( "CSVPController::DtmfEventReceived STOP TO PREVIOUS AND LAST" )
       
  3106                 
       
  3107                 // send stop event to the previous character in string 
       
  3108                 iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( 
       
  3109                         MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  3110                         KErrNone, 
       
  3111                         iDtmfStringLex.Peek() );
       
  3112                 
       
  3113                 SVPDEBUG1( "CSVPController::DtmfEventReceived COMPLETE" )
       
  3114                 
       
  3115                 // send sequence stop event
       
  3116                 iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( 
       
  3117                      MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, 
       
  3118                      KErrNone, 
       
  3119                      iDtmfStringLex.Peek() );
       
  3120                 // sequence complete, clear flags
       
  3121                 iDtmfStringSending = EFalse;
       
  3122                 iFirstDtmfSent = EFalse;
       
  3123                
       
  3124                 delete iDtmfString;
       
  3125                 iDtmfString = NULL;
       
  3126                 }
       
  3127             }
       
  3128         // manual dtmf
       
  3129         else
       
  3130             {
       
  3131             // call back event to application
       
  3132             iSessionArray[ index ]->DtmfObserver().HandleDTMFEvent( 
       
  3133                                             dtmfEvent, 
       
  3134                                             KErrNone, 
       
  3135                                             iDtmfTone );
       
  3136             }
       
  3137         }
       
  3138     
       
  3139     else if ( iEmergencySession )
       
  3140         {
       
  3141         const MCCPDTMFObserver& dtmfObs = iEmergencySession->DtmfObserver();
       
  3142         SVPDEBUG2("CSVPController::DtmfEventReceived, %d = DtmfObserver()", &dtmfObs )
       
  3143          // match dtmf event
       
  3144         MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = 
       
  3145             iSVPUtility->GetDtmfEvent( aEvent, iDtmfStringSending );
       
  3146         
       
  3147         // dtmf string
       
  3148         if ( iDtmfStringSending && NULL != &dtmfObs ) 
       
  3149             { 
       
  3150             // only start event received from mce
       
  3151             // logic below needed so that stop events can be sent
       
  3152             if ( MCCPDTMFObserver::ECCPDtmfSequenceStart == dtmfEvent )
       
  3153                 {
       
  3154                 if ( !iFirstDtmfSent )
       
  3155                     {
       
  3156                     SVPDEBUG1(
       
  3157                     "CSVPController::DtmfEventReceived, emergency FIRST SEND")
       
  3158                     
       
  3159                     // send start
       
  3160                     iFirstDtmfSent = ETrue;
       
  3161                      // call back event to application
       
  3162                     dtmfObs.HandleDTMFEvent( dtmfEvent, KErrNone, iDtmfStringLex.Peek() );
       
  3163                     }  
       
  3164                 else
       
  3165                     {
       
  3166                     SVPDEBUG1("CSVPController::DtmfEventReceived,\
       
  3167                      emergency STOP TO PREVIOUS")
       
  3168                     
       
  3169                     // send stop event to the previous character in string 
       
  3170                     dtmfObs.HandleDTMFEvent( 
       
  3171                         MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  3172                         KErrNone, 
       
  3173                         iDtmfStringLex.Get() );
       
  3174                      SVPDEBUG1("CSVPController::DtmfEventReceived,\
       
  3175                       emergency START TO CURRENT")
       
  3176                     // send start event to the current character in string
       
  3177                     dtmfObs.HandleDTMFEvent( 
       
  3178                         dtmfEvent, 
       
  3179                         KErrNone, 
       
  3180                         iDtmfStringLex.Peek() );
       
  3181                     }
       
  3182                 }
       
  3183              else
       
  3184                 {
       
  3185                 SVPDEBUG1("CSVPController::DtmfEventReceived,\
       
  3186                  emergency STOP TO PREVIOUS AND LAST")
       
  3187                 
       
  3188                 // send stop event to the previous character in string 
       
  3189                 dtmfObs.HandleDTMFEvent( 
       
  3190                     MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  3191                     KErrNone, 
       
  3192                     iDtmfStringLex.Peek() );
       
  3193                 
       
  3194                 SVPDEBUG1("CSVPController::DtmfEventReceived,\
       
  3195                  emergency COMPLETE")
       
  3196                 
       
  3197                 // send sequence stop event
       
  3198                 dtmfObs.HandleDTMFEvent( 
       
  3199                      MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, 
       
  3200                      KErrNone, 
       
  3201                      iDtmfStringLex.Peek() );
       
  3202                 // sequence complete, clear flags
       
  3203                 iDtmfStringSending = EFalse;
       
  3204                 iFirstDtmfSent = EFalse;
       
  3205                 
       
  3206                 delete iDtmfString;
       
  3207                 iDtmfString = NULL;
       
  3208                 }
       
  3209             }
       
  3210         // manual dtmf
       
  3211         else if( NULL != &dtmfObs )
       
  3212             {
       
  3213             SVPDEBUG1("CSVPController::DtmfEventReceived,\
       
  3214                     manual dtmf ,  call back event to application")
       
  3215             dtmfObs.HandleDTMFEvent( dtmfEvent, KErrNone, iDtmfTone );
       
  3216             }
       
  3217         else
       
  3218             {
       
  3219             SVPDEBUG1("CSVPController::DtmfEventReceived, DtmfObs not set")
       
  3220             }
       
  3221         }
       
  3222     
       
  3223     SVPDEBUG1( "CSVPController::DtmfEventReceived Out" )
       
  3224     }
       
  3225                                   
       
  3226 // ---------------------------------------------------------------------------
       
  3227 // CSVPController::DtmfErrorOccured
       
  3228 // ---------------------------------------------------------------------------
       
  3229 //
       
  3230  void CSVPController::DtmfErrorOccured( CMceSession& aSession,
       
  3231          CMceAudioStream& /*aStream*/,CMceMediaSource& /*aSource*/,
       
  3232          TInt aError )
       
  3233     {
       
  3234     SVPDEBUG2( "CSVPController::DtmfErrorOccured In, aError: %d", aError )
       
  3235     
       
  3236     // find what session received the event
       
  3237     const TInt index = FindSVPSession( aSession );
       
  3238     if ( KErrNotFound != index )
       
  3239         {
       
  3240         // match dtmf event, unknown set as default in error case, 'tis ok?
       
  3241         const MCCPDTMFObserver::TCCPDtmfEvent dtmfEvent = 
       
  3242             MCCPDTMFObserver::ECCPDtmfUnknown;
       
  3243         
       
  3244         // default tone char
       
  3245         TChar dtmfToneChar('0');
       
  3246         
       
  3247         // call back error
       
  3248         iSessionArray[ index ]->
       
  3249             DtmfObserver().HandleDTMFEvent( dtmfEvent, 
       
  3250                                             aError, 
       
  3251                                             dtmfToneChar );  
       
  3252         }
       
  3253     
       
  3254     SVPDEBUG1( "CSVPController::DtmfErrorOccured Out" )
       
  3255     }
       
  3256 
       
  3257 // ---------------------------------------------------------------------------
       
  3258 // CSVPController::FinalizeSessionCreationL
       
  3259 // ---------------------------------------------------------------------------
       
  3260 //
       
  3261 void CSVPController::FinalizeSessionCreationL( CSVPSessionBase* aSession )
       
  3262     {
       
  3263     SVPDEBUG2( "CSVPController::FinalizeSessionCreationL In, aSession: 0x%x",
       
  3264         aSession )
       
  3265     
       
  3266     __ASSERT_ALWAYS( aSession, User::Leave( KErrArgument ) );
       
  3267     
       
  3268     if ( iCCPDtmfObserver )
       
  3269       	{
       
  3270        	aSession->SetDtmfObserver( *iCCPDtmfObserver );
       
  3271        	}
       
  3272     
       
  3273     iRtpObserver->AddSessionForObservingL( aSession );
       
  3274     iSessionArray.AppendL( aSession );
       
  3275     
       
  3276     SVPDEBUG1( "CSVPController::FinalizeSessionCreationL Out" )
       
  3277     }
       
  3278 
       
  3279 // ---------------------------------------------------------------------------
       
  3280 // CSVPController::ExecCbErrorOccurred
       
  3281 // ---------------------------------------------------------------------------
       
  3282 // 
       
  3283 TInt CSVPController::ExecCbErrorOccurred( MCCPObserver::TCCPError aError )
       
  3284     {
       
  3285     SVPDEBUG2( "CSVPController::ExecCbErrorOccurred In, aError=%d", aError )
       
  3286     
       
  3287     TInt status = KErrNotFound;
       
  3288     
       
  3289     if ( iCCPMonitor )
       
  3290         {
       
  3291         status = KErrNone;
       
  3292         iCCPMonitor->ErrorOccurred( aError );
       
  3293         }
       
  3294     
       
  3295     SVPDEBUG2( "CSVPController::ExecCbErrorOccurred Out return=%d", status )
       
  3296     return status;
       
  3297     }
       
  3298 
       
  3299 // ---------------------------------------------------------------------------
       
  3300 // CSVPController::IncomingCall
       
  3301 // ---------------------------------------------------------------------------
       
  3302 // 
       
  3303 TInt CSVPController::ExecCbIncomingCall( MCCPCall* aCall )
       
  3304     {
       
  3305     SVPDEBUG2( "CSVPController::ExecCbIncomingCall In, aCall= 0x%x", aCall )
       
  3306 
       
  3307     TInt status = KErrNotFound;
       
  3308     
       
  3309     if ( iCCPMonitor )
       
  3310         {
       
  3311         status = KErrNone;
       
  3312         iCCPMonitor->IncomingCall( aCall );
       
  3313         }
       
  3314     
       
  3315     SVPDEBUG2( "CSVPController::ExecCbIncomingCall Out return=%d", status )
       
  3316     return status;
       
  3317     }
       
  3318 
       
  3319 // ---------------------------------------------------------------------------
       
  3320 // CSVPController::ExecCbIncomingCall
       
  3321 // ---------------------------------------------------------------------------
       
  3322 // 
       
  3323 TInt CSVPController::ExecCbIncomingCall( MCCPCall* aCall, MCCPCall& aTempCall )
       
  3324     {
       
  3325     SVPDEBUG2( "CSVPController::ExecCbIncomingCall In, aCall= 0x%x", aCall )
       
  3326     SVPDEBUG2( "CSVPController::ExecCbIncomingCall aTempCall= 0x%x", &aTempCall )
       
  3327     
       
  3328     TInt status = KErrNotFound;
       
  3329     
       
  3330     if ( iCCPMonitor )
       
  3331         {
       
  3332         status = KErrNone;
       
  3333         iCCPMonitor->IncomingCall( aCall, aTempCall );
       
  3334         }
       
  3335     
       
  3336     SVPDEBUG2( "CSVPController::ExecCbIncomingCall Out return=%d", status )
       
  3337     return status;
       
  3338     }
       
  3339 
       
  3340 // ---------------------------------------------------------------------------
       
  3341 // CSVPController::ExecCbCallCreated
       
  3342 // ---------------------------------------------------------------------------
       
  3343 // 
       
  3344 TInt CSVPController::ExecCbCallCreated( MCCPCall* aNewTransferCall,
       
  3345         MCCPCall* aOriginator, TBool aAttended )
       
  3346     {
       
  3347     SVPDEBUG2( "CSVPController::ExecCbCallCreated In, aNewTransferCall= 0x%x", aNewTransferCall )
       
  3348     SVPDEBUG2( "CSVPController::ExecCbCallCreated          aOriginator= 0x%x", aOriginator )
       
  3349     SVPDEBUG2( "CSVPController::ExecCbCallCreated            aAttended= %d", aAttended )
       
  3350     
       
  3351     TInt status = KErrNotFound;
       
  3352     
       
  3353     if ( iCCPMonitor )
       
  3354         {
       
  3355         status = KErrNone;
       
  3356         iCCPMonitor->CallCreated( aNewTransferCall, aOriginator, aAttended );
       
  3357         }
       
  3358     
       
  3359     SVPDEBUG2( "CSVPController::ExecCbCallCreated Out return=%d", status )
       
  3360     return status;
       
  3361     }
       
  3362 
       
  3363 // ---------------------------------------------------------------------------
       
  3364 // CSVPController::ParseRecipientDtmfSuffixL
       
  3365 // ---------------------------------------------------------------------------
       
  3366 // 
       
  3367 HBufC* CSVPController::ParseRecipientDtmfSuffixL( const TDesC& aRecipient ) const
       
  3368     {
       
  3369     __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) );
       
  3370 
       
  3371     SVPDEBUG2( "CSVPController::ParseRecipientDtmfSuffixL In, aRecipient=%S", &aRecipient )
       
  3372     
       
  3373     HBufC* result = aRecipient.AllocLC(); // CS:1
       
  3374     
       
  3375     TInt recipientLength = result->Length();
       
  3376     if ( recipientLength )
       
  3377         {
       
  3378         if ( IsValidDtmfRecipientL( *result ) )
       
  3379             {
       
  3380             TInt loopCount = 0;
       
  3381             if (  KErrNotFound != KSVPDtmfTelNumRange().Locate( result->Des()[loopCount] ) )
       
  3382                 {
       
  3383                 loopCount++;
       
  3384                 TBool doLoop = ETrue;
       
  3385                 do
       
  3386                     {
       
  3387                     if ( loopCount < recipientLength )
       
  3388                         {
       
  3389                         if ( KErrNotFound != 
       
  3390                             KSVPDtmfDelimiterRange().Locate( result->Des()[loopCount] ) )
       
  3391                             {
       
  3392                             TInt suffixLength = recipientLength - loopCount;
       
  3393                             result->Des().Delete( loopCount, suffixLength );
       
  3394                             doLoop = EFalse;
       
  3395                             SVPDEBUG1(
       
  3396                                  "CSVPController::ParseRecipientDtmfSuffixL, DTMF suffix removed" )
       
  3397                             }
       
  3398                         else 
       
  3399                             {
       
  3400                             loopCount++;
       
  3401                             }
       
  3402                         }
       
  3403                     else
       
  3404                         {
       
  3405                         doLoop = EFalse;
       
  3406                         }
       
  3407                     } while ( doLoop );
       
  3408                 }
       
  3409             }
       
  3410         }
       
  3411     SVPDEBUG2( "CSVPController::ParseRecipientDtmfSuffixL Out, result=%S", result )
       
  3412     CleanupStack::Pop( result ); // CS:0
       
  3413     return result;
       
  3414     }
       
  3415 
       
  3416 // ---------------------------------------------------------------------------
       
  3417 // CSVPController::IsValidDtmfRecipientL
       
  3418 // ---------------------------------------------------------------------------
       
  3419 // 
       
  3420 TBool CSVPController::IsValidDtmfRecipientL( const TDesC& aRecipient ) const
       
  3421     {
       
  3422     __ASSERT_ALWAYS( &aRecipient, User::Leave( KErrArgument ) );
       
  3423 
       
  3424     SVPDEBUG1( "CSVPController::IsValidDtmfRecipientL In" )
       
  3425 
       
  3426     TBool result = ETrue;
       
  3427     if ( aRecipient.Length() )
       
  3428         {
       
  3429         TBool loopDo = ETrue;
       
  3430         TInt loopCount = 0;
       
  3431         do
       
  3432             {
       
  3433             if ( loopCount < aRecipient.Length() )
       
  3434                 {
       
  3435                 if ( KErrNotFound == KSVPDtmfAllValidChars().Locate( aRecipient[loopCount] ) )
       
  3436                     {
       
  3437                     result = EFalse;
       
  3438                     loopDo = EFalse;
       
  3439                     }
       
  3440                 else
       
  3441                     {
       
  3442                     loopCount++;
       
  3443                     }
       
  3444                 }
       
  3445             else
       
  3446                 {
       
  3447                 loopDo = EFalse;
       
  3448                 }
       
  3449             } while ( loopDo );
       
  3450         }
       
  3451     else
       
  3452         {
       
  3453         SVPDEBUG1( "CSVPController::IsValidDtmfRecipientL, Invalid recipient length" )
       
  3454         result = EFalse;
       
  3455         }
       
  3456     SVPDEBUG2( "CSVPController::IsValidDtmfRecipientL Out, result=%d" , result )
       
  3457     return result;
       
  3458     }
       
  3459 
       
  3460 // ---------------------------------------------------------------------------
       
  3461 // CSVPController::CheckCallEventToBeSent
       
  3462 // ---------------------------------------------------------------------------
       
  3463 //
       
  3464 void CSVPController::CheckCallEventToBeSent( CSVPSessionBase* aNewSVPSession, 
       
  3465                      CSVPSessionBase* aOldSVPSession ) const
       
  3466     {
       
  3467     SVPDEBUG1( "CSVPController::CheckCallEventToBeSent In" )
       
  3468 
       
  3469     if ( aOldSVPSession->IsSecured() != aNewSVPSession->IsSecured() )
       
  3470         {
       
  3471         // Session secure status changed, need to send proper event
       
  3472         if ( aNewSVPSession->IsSecured() )
       
  3473             {
       
  3474             SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, unsecure -> secure case" )
       
  3475             aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPSecureCall );
       
  3476             }
       
  3477         else
       
  3478             {
       
  3479             SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, secure -> unsecure case" )
       
  3480             aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPNotSecureCall );
       
  3481             }
       
  3482         }
       
  3483     else
       
  3484         {
       
  3485         // remoteparty will be updated anyway after attended transfer
       
  3486         SVPDEBUG1( "CSVPController::CheckCallEventToBeSent, remoteparty will be updated after attended transfer" )
       
  3487         aNewSVPSession->SetCallEventToBeSent( MCCPCallObserver::ECCPNotifyRemotePartyInfoChange );
       
  3488         }
       
  3489     SVPDEBUG1( "CSVPController::CheckCallEventToBeSent Out" )
       
  3490     }
       
  3491 
       
  3492 // ---------------------------------------------------------------------------
       
  3493 // From class MSIPObserver
       
  3494 // CSVPController::IncomingRequest
       
  3495 // ---------------------------------------------------------------------------
       
  3496 // 
       
  3497 void CSVPController::IncomingRequest( 
       
  3498     TUint32 /*aIapId*/, CSIPServerTransaction* /*aTransaction*/ )
       
  3499     {
       
  3500     SVPDEBUG1( "CSVPController::IncomingRequest" )
       
  3501     }
       
  3502 
       
  3503 // ---------------------------------------------------------------------------
       
  3504 // From class MSIPObserver
       
  3505 // CSVPController::TimedOut
       
  3506 // ---------------------------------------------------------------------------
       
  3507 //     
       
  3508 void CSVPController::TimedOut( 
       
  3509     CSIPServerTransaction& /*aSIPServerTransaction*/ )
       
  3510     {
       
  3511     SVPDEBUG1( "CSVPController::TimedOut" )
       
  3512     }
       
  3513 
       
  3514 // ---------------------------------------------------------------------------
       
  3515 // From class MSIPProfileRegistryObserver
       
  3516 // CSVPController::ProfileRegistryErrorOccurred
       
  3517 // ---------------------------------------------------------------------------
       
  3518 //  
       
  3519 void CSVPController::ProfileRegistryErrorOccurred( 
       
  3520     TUint32 /*aSIPProfileId*/, TInt /*aError*/ )
       
  3521     {
       
  3522     SVPDEBUG1( "CSVPController::ProfileRegistryErrorOccurred" )
       
  3523     }
       
  3524 
       
  3525 // ---------------------------------------------------------------------------
       
  3526 // From class MSIPProfileRegistryObserver
       
  3527 // CSVPController::ProfileRegistryEventOccurred
       
  3528 // ---------------------------------------------------------------------------
       
  3529 //  
       
  3530 void CSVPController::ProfileRegistryEventOccurred( 
       
  3531     TUint32 /*aProfileId*/, TEvent /*aEvent*/ )
       
  3532     {
       
  3533     SVPDEBUG1( "CSVPController::ProfileRegistryEventOccurred" )
       
  3534     }
       
  3535