sipvoipprovider/src/svpemergencysession.cpp
changeset 0 a4daefaec16c
child 6 fc8c25e5a2e8
equal deleted inserted replaced
-1:000000000000 0:a4daefaec16c
       
     1 /*
       
     2 * Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  SVP Emergency Sesssion class. Handles emergency 
       
    15 *                session methods.        
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <sip.h>
       
    21 #include <sipprofile.h>
       
    22 #include <sipprofileregistry.h>
       
    23 
       
    24 #include <mceaudiostream.h>
       
    25 #include <mcertpsource.h>
       
    26 #include <mcertpsink.h>
       
    27 #include <mcemicsource.h>
       
    28 #include <mcespeakersink.h>
       
    29 #include <mcetransactiondatacontainer.h>
       
    30 
       
    31 #include "crcseprofileentry.h"
       
    32 #include "crcseprofileregistry.h"
       
    33 
       
    34 #include "svpemergencysession.h"
       
    35 #include "svpuriparser.h"
       
    36 #include "svputility.h"
       
    37 #include "svpsipconsts.h"
       
    38 #include "svpconsts.h"
       
    39 #include "svppositioningprovider.h"
       
    40 #include "svpemergencyconnection.h"
       
    41 #include "svpholdcontroller.h"
       
    42 #include "svpaudioutility.h"
       
    43 #include "svpdtmfeventgenerator.h"
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // CSVPEmergencySession::CSVPEmergencySession
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CSVPEmergencySession::CSVPEmergencySession( 
       
    50     CSVPUtility& aSVPUtility, 
       
    51     CMceManager& aMceManager, 
       
    52     TBool aIsLastProfile, 
       
    53     TBool aIsDummy )
       
    54     : iSVPUtility( aSVPUtility ), 
       
    55       iMceManager( aMceManager ), 
       
    56       iSessionExpires( KSVPDefaultSessionExpires ), 
       
    57       iIsLastProfile( aIsLastProfile ), 
       
    58       iIsDummy( aIsDummy ), 
       
    59       iIsDialed( EFalse ), 
       
    60       iIsLIRequestReady( ETrue )
       
    61     {
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // CSVPEmergencySession::ConstructL
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 void CSVPEmergencySession::ConstructL( TUint32 aVoipProfileId, 
       
    69                                        const TDesC& aAddress, 
       
    70                                        const MCCPCallObserver& aObserver, 
       
    71                                        TBool aIsDummy )                                   
       
    72     {
       
    73     SVPDEBUG2("CSVPEmergencySession::ConstructL() IN, VoIP profile ID: %d", 
       
    74         aVoipProfileId)
       
    75 
       
    76     iEmergencyObserver = const_cast< MCCPCallObserver* >( &aObserver );
       
    77     iVoipProfileId = ( TInt )aVoipProfileId;
       
    78 
       
    79     // Start emergency timer, timeout 17 seconds
       
    80     StartTimerL( KSVPEmergencyTimeout, KSVPEmergencyExpired );
       
    81 
       
    82     if ( aIsDummy )
       
    83         {
       
    84         SVPDEBUG1("CSVPEmergencySession::ConstructL, dummy session")
       
    85         return;
       
    86         }
       
    87 
       
    88     // Initialize registries
       
    89     CRCSEProfileRegistry* reg = CRCSEProfileRegistry::NewLC(); // CS:1
       
    90     CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS:2
       
    91     CSIPProfileRegistry* sipProfileRegistry = CSIPProfileRegistry::NewLC( 
       
    92         *sip, *this ); // CS:3
       
    93 
       
    94     // Find VoIP profile by its ID
       
    95     CRCSEProfileEntry* voipProfile = CRCSEProfileEntry::NewLC();  // CS:4
       
    96     reg->FindL( aVoipProfileId, *voipProfile );
       
    97 
       
    98     // Set Session Expires value
       
    99     iSessionExpires = ( TUint32 )voipProfile->iSIPSessionExpires;
       
   100     
       
   101     // There is only one (or zero) SIP profile per VoIP profile.
       
   102     // if profileId doesn't exist, report an error ( ECCPErrorGeneral ).
       
   103     if ( 0 == voipProfile->iIds.Count() )
       
   104         {
       
   105         SVPDEBUG1( "CSVPEmergencySession::ConstructL, no SIP profile, return" )
       
   106         CleanupStack::PopAndDestroy( 4, reg ); // CS:0
       
   107         ErrorOccurred( ECCPErrorGeneral );
       
   108         return;
       
   109         }
       
   110     CSIPProfile* sipProfile = sipProfileRegistry->ProfileL( 
       
   111         voipProfile->iIds[0].iProfileId );
       
   112     CleanupStack::PushL( sipProfile ); // CS:5
       
   113 
       
   114     // Get SIP profile ID
       
   115     User::LeaveIfError( 
       
   116         sipProfile->GetParameter( KSIPProfileId, iSipProfileId ) );
       
   117        
       
   118     // Get user AOR
       
   119     const TDesC8* userAor = NULL;
       
   120     User::LeaveIfError( sipProfile->GetParameter( KSIPUserAor, userAor ) );
       
   121     iUserAor = HBufC8::NewL( userAor->Length() );
       
   122     ( iUserAor->Des() ).Copy( *userAor );
       
   123     
       
   124     // Parse SIP URI
       
   125     HBufC8* recipient = HBufC8::NewLC( aAddress.Length() ); // CS:6
       
   126     ( recipient->Des() ).Copy( aAddress );
       
   127     CSVPUriParser* uriParser = CSVPUriParser::NewLC(); // CS:7
       
   128     iRecipientUri = uriParser->CompleteSipUriL( *recipient, *iUserAor, ETrue );
       
   129     CleanupStack::PopAndDestroy( 2, recipient ); // uriparser, recipient CS:5
       
   130 
       
   131     // Get registration status
       
   132     TBool registered( EFalse );
       
   133     sipProfile->GetParameter( KSIPProfileRegistered, registered );
       
   134 
       
   135     // Get SNAP ID
       
   136     TUint32 snapId( 0 );
       
   137     TInt errSnap = sipProfile->GetParameter( KSIPSnapId, snapId );
       
   138 
       
   139     // Define IAP ID
       
   140     if ( !registered && KErrNone == errSnap )
       
   141         {
       
   142         SVPDEBUG2("CSVPEmergencySession::ConstructL, snapId: %d", snapId)
       
   143         // Define IAP ID from SNAP ID, create WLAN connection
       
   144         iEmergencyConnection = CSVPEmergencyConnection::NewL( 
       
   145             CActive::EPriorityStandard, *this );
       
   146         iEmergencyConnection->ConnectWithSnapIdL( snapId );
       
   147         CleanupStack::PopAndDestroy( 5, reg );
       
   148         // reg, sip, sipProfileRegistry, voipProfile, sipProfile CS:0
       
   149         SVPDEBUG1("CSVPEmergencySession::ConstructL, return")
       
   150         return;
       
   151         }
       
   152     else
       
   153         {
       
   154         User::LeaveIfError( 
       
   155             sipProfile->GetParameter( KSIPAccessPointId, iIapId ) );
       
   156         }
       
   157 
       
   158     // Create MCE out session
       
   159     if ( registered )
       
   160         {
       
   161         SVPDEBUG1("CSVPEmergencySession::ConstructL, registered")
       
   162         iEmergencySession = CMceOutSession::NewL( 
       
   163             iMceManager, *sipProfile, *iRecipientUri );
       
   164         ConstructAudioStreamsL();
       
   165         }
       
   166     else
       
   167         {
       
   168         CreateUnregistedSessionL();
       
   169         }
       
   170     
       
   171     CleanupStack::PopAndDestroy( 5, reg ); 
       
   172     // CS:0 reg, sip, sipProfileRegistry, voipProfile, sipProfile
       
   173 
       
   174     // Request for position information
       
   175     RequestPosition( iIapId );
       
   176 
       
   177     SVPDEBUG1("CSVPEmergencySession::ConstructL() OUT")
       
   178     }
       
   179 
       
   180 // ---------------------------------------------------------------------------
       
   181 // CSVPEmergencySession::ConstructWithIapIdL
       
   182 // ---------------------------------------------------------------------------
       
   183 //
       
   184 void CSVPEmergencySession::ConstructWithIapIdL( 
       
   185     TUint32 aIapId, 
       
   186     const TDesC& aAddress, 
       
   187     const MCCPCallObserver& aObserver, 
       
   188     TBool aIsDummy )                                   
       
   189     {
       
   190     SVPDEBUG2("CSVPEmergencySession::ConstructWithIapIdL() In, IAP ID: %d", 
       
   191         aIapId)
       
   192 
       
   193     iEmergencyObserver = const_cast< MCCPCallObserver* >( &aObserver );
       
   194     iVoipProfileId = KErrNotFound;
       
   195     iIapId = aIapId;
       
   196     
       
   197     // Copy recipient address
       
   198     iAddress = HBufC8::NewL( aAddress.Length() );
       
   199     ( iAddress->Des() ).Copy( aAddress );
       
   200     
       
   201     // Start emergency timer, timeout 17 seconds
       
   202     StartTimerL( KSVPEmergencyTimeout, KSVPEmergencyExpired );
       
   203 
       
   204     if ( aIsDummy )
       
   205         {
       
   206         SVPDEBUG1("CSVPEmergencySession::ConstructWithIapIdL, dummy session")
       
   207         return;
       
   208         }
       
   209 
       
   210     // Request for SIP proxy address
       
   211     SVPDEBUG1("CSVPEmergencySession::ConstructWithIapIdL, SIP proxy address")
       
   212     iEmergencyConnection = CSVPEmergencyConnection::NewL( 
       
   213         CActive::EPriorityStandard, *this );
       
   214     iEmergencyConnection->ConnectL( iIapId );
       
   215     
       
   216     SVPDEBUG1("CSVPEmergencySession::ConstructWithIapIdL() Out")
       
   217     }
       
   218 
       
   219 // ---------------------------------------------------------------------------
       
   220 // CSVPEmergencySession::ContinueConstructWithIapIdL
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 void CSVPEmergencySession::RequestSipProxyAddressL()
       
   224     {
       
   225     if ( NULL == iEmergencyConnection )
       
   226         {
       
   227         User::Leave( KErrGeneral );
       
   228         }
       
   229 
       
   230     iEmergencyConnection->RequestSipProxyAddressL( iIapId );
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------------------------
       
   234 // CSVPEmergencySession::ContinueConstructWithIapIdL
       
   235 // ---------------------------------------------------------------------------
       
   236 //
       
   237 void CSVPEmergencySession::ContinueConstructWithIapIdL( 
       
   238     const TDesC16& aSipProxyAddress )
       
   239     {
       
   240     SVPDEBUG2("CSVPEmergencySession::ContinueConstructWithIapIdL(),\
       
   241         SIP proxy address: %S", &aSipProxyAddress)
       
   242 
       
   243     if ( 0 == aSipProxyAddress.Length() )
       
   244         {
       
   245         User::Leave( KErrNotFound );
       
   246         }
       
   247 
       
   248     // Parse user AOR
       
   249     iUserAor = HBufC8::NewL(
       
   250         KSVPSipPrefix().Length() + 
       
   251         KSVPAnonymous().Length() + 
       
   252         KSVPAt().Length() + 
       
   253         aSipProxyAddress.Length() );
       
   254     TPtr8 userAorPtr = iUserAor->Des();
       
   255     userAorPtr.Copy( KSVPSipPrefix );
       
   256     userAorPtr.Append( KSVPAnonymous );
       
   257     userAorPtr.Append( KSVPAt );
       
   258     userAorPtr.Append( aSipProxyAddress );
       
   259 
       
   260     // Parse SIP URI
       
   261     SVPDEBUG1("CSVPEmergencySession::ContinueConstructWithIapIdL,\
       
   262         parse SIP URI")
       
   263     CSVPUriParser* uriParser = CSVPUriParser::NewLC(); // CS:1
       
   264     iRecipientUri = uriParser->CompleteSipUriL( *iAddress, *iUserAor, ETrue );
       
   265     CleanupStack::PopAndDestroy( uriParser ); // CS:0
       
   266 
       
   267     // Create MCE session
       
   268     CreateUnregistedSessionL();
       
   269 
       
   270     // Request for position information
       
   271     RequestPosition( iIapId );
       
   272     
       
   273     SVPDEBUG1("CSVPEmergencySession::ContinueConstructWithIapIdL() Out")
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------------------------
       
   277 // CSVPEmergencySession::NewL
       
   278 // ---------------------------------------------------------------------------
       
   279 //
       
   280 CSVPEmergencySession* CSVPEmergencySession::NewL(  
       
   281                                         CMceManager& aMceManager, 
       
   282                                         TUint32 aVoipProfileId, 
       
   283                                         const TDesC& aAddress, 
       
   284                                         const MCCPCallObserver& aObserver,
       
   285                                         CSVPUtility& aSVPUtility, 
       
   286                                         TBool aIsLastProfile, 
       
   287                                         TBool aIsDummy )
       
   288     {
       
   289     CSVPEmergencySession* self = new( ELeave ) CSVPEmergencySession( 
       
   290         aSVPUtility, aMceManager, aIsLastProfile, aIsDummy );
       
   291     CleanupStack::PushL( self );
       
   292     self->ConstructL( aVoipProfileId, aAddress, aObserver, aIsDummy );
       
   293     CleanupStack::Pop( self );
       
   294     return self;
       
   295     }
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // CSVPEmergencySession::NewL
       
   299 // ---------------------------------------------------------------------------
       
   300 //
       
   301 CSVPEmergencySession* CSVPEmergencySession::NewL(  
       
   302                                         CMceManager& aMceManager, 
       
   303                                         const TDesC& aAddress, 
       
   304                                         const MCCPCallObserver& aObserver,
       
   305                                         CSVPUtility& aSVPUtility, 
       
   306                                         TUint32 aIapId, 
       
   307                                         TBool aIsLastProfile, 
       
   308                                         TBool aIsDummy )
       
   309     {
       
   310     CSVPEmergencySession* self = new( ELeave ) CSVPEmergencySession( 
       
   311         aSVPUtility, aMceManager, aIsLastProfile, aIsDummy );
       
   312     CleanupStack::PushL( self );
       
   313     self->ConstructWithIapIdL( aIapId, aAddress, aObserver, aIsDummy );
       
   314     CleanupStack::Pop( self );
       
   315     return self;
       
   316     }
       
   317 
       
   318 // ---------------------------------------------------------------------------
       
   319 // CSVPEmergencySession::~CSVPEmergencySession
       
   320 // ---------------------------------------------------------------------------
       
   321 //
       
   322 CSVPEmergencySession::~CSVPEmergencySession()
       
   323     {
       
   324     SVPDEBUG1("CSVPEmergencySession::~CSVPEmergencySession() In")
       
   325 
       
   326     StopTimers();  
       
   327     iTimers.Close();
       
   328 
       
   329     delete iEmergencySession;
       
   330     delete iFailedEmergencySession;
       
   331     
       
   332     delete iUserAor;
       
   333     delete iAddress;
       
   334     delete iRecipientUri;
       
   335     
       
   336     delete iPositionInformation;
       
   337     delete iPositioningProvider;
       
   338     
       
   339     delete iEmergencyConnection;
       
   340     
       
   341     delete iHoldController;
       
   342     
       
   343     delete iDTMFEventGenerator;
       
   344     
       
   345     delete iDtmfString;
       
   346 
       
   347     SVPDEBUG1("CSVPEmergencySession::~CSVPEmergencySession() Out")
       
   348     }
       
   349 
       
   350 // ---------------------------------------------------------------------------
       
   351 // CSVPEmergencySession::State
       
   352 // ---------------------------------------------------------------------------
       
   353 //
       
   354 MCCPCallObserver::TCCPCallState CSVPEmergencySession::State() const
       
   355     {
       
   356     SVPDEBUG1("CSVPEmergencySession::State()")
       
   357 
       
   358     // ccpState can be safely initialized with StatusIdle
       
   359     MCCPCallObserver::TCCPCallState ccpState = 
       
   360         MCCPCallObserver::ECCPStateIdle;
       
   361     
       
   362     switch ( iEmergencySession->State() )
       
   363         {
       
   364         case CMceSession::EIdle:
       
   365             SVPDEBUG1("CSVPEmergencySession::State, MCE EIdle")
       
   366             ccpState = MCCPCallObserver::ECCPStateIdle;
       
   367             break;
       
   368        
       
   369         case CMceSession::EProceeding:
       
   370             SVPDEBUG1("CSVPEmergencySession::State, MCE EProceeding")
       
   371             ccpState = MCCPCallObserver::ECCPStateConnecting;
       
   372             break;
       
   373             
       
   374         case CMceSession::EEstablished:
       
   375             SVPDEBUG1("CSVPEmergencySession::State, MCE EEstablished")
       
   376             ccpState = MCCPCallObserver::ECCPStateConnected;
       
   377             break;
       
   378             
       
   379         case CMceSession::ECancelling:
       
   380             SVPDEBUG1("CSVPEmergencySession::State, MCE ECancelling")
       
   381             ccpState = MCCPCallObserver::ECCPStateIdle;  
       
   382             break;
       
   383             
       
   384         case CMceSession::ETerminating:
       
   385             SVPDEBUG1("CSVPEmergencySession::State, MCE ETerminating")
       
   386             ccpState = MCCPCallObserver::ECCPStateDisconnecting;
       
   387             break;
       
   388             
       
   389         case CMceSession::ETerminated:
       
   390             SVPDEBUG1("CSVPEmergencySession::State, MCE ETerminated")
       
   391             if ( MCCPCallObserver::ECCPStateDisconnecting == iSessionState )
       
   392                 {
       
   393                 ccpState = MCCPCallObserver::ECCPStateDisconnecting;
       
   394                 }
       
   395             else
       
   396                 {
       
   397                 ccpState = MCCPCallObserver::ECCPStateIdle;     
       
   398                 }
       
   399             break;
       
   400             
       
   401         default:
       
   402             SVPDEBUG1("CSVPEmergencySession::State, DEFAULT")
       
   403             // This block should never be reached.
       
   404             break;
       
   405         }
       
   406 
       
   407     return ccpState;
       
   408     }
       
   409 
       
   410 // ---------------------------------------------------------------------------
       
   411 // Traps SessionStateChangedL
       
   412 // ---------------------------------------------------------------------------
       
   413 //
       
   414 void CSVPEmergencySession::SessionStateChanged( TInt aStatusCode )
       
   415     {
       
   416     TRAPD( err, SessionStateChangedL( aStatusCode ) )
       
   417     if ( err )
       
   418         {
       
   419         SVPDEBUG2("CSVPEmergencySession::SessionStateChanged, err: %d", err)
       
   420         }
       
   421     }
       
   422 
       
   423 // ---------------------------------------------------------------------------
       
   424 // Session connection state changed
       
   425 // ---------------------------------------------------------------------------
       
   426 //
       
   427 void CSVPEmergencySession::SessionConnectionStateChanged(
       
   428     CMceSession& aSession, TBool aActive )
       
   429     {
       
   430     SVPDEBUG2("CSVPEmergencySession::SessionConnectionStateChanged - %d", 
       
   431         aActive)
       
   432     
       
   433     if ( iEmergencySession == &aSession && aActive )
       
   434         {
       
   435         ProceedDial();
       
   436         }
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // Stream state changed
       
   441 // ---------------------------------------------------------------------------
       
   442 //
       
   443 void CSVPEmergencySession::StreamStateChanged( CMceMediaStream& aStream )
       
   444     {
       
   445     SVPDEBUG1("CSVPEmergencySession::StreamStateChanged()")
       
   446     
       
   447     if ( CMceMediaStream::EDisabled == aStream.State() &&
       
   448          CMceSession::EEstablished == aStream.Session()->State() )
       
   449         {
       
   450         // Remote end died
       
   451         iEmergencyObserver->CallStateChanged( 
       
   452             MCCPCallObserver::ECCPStateDisconnecting, NULL );
       
   453         TRAP_IGNORE( StartTimerL( 
       
   454             KSVPTerminatingTime, KSVPRemoteEndDiedExpired ) )
       
   455         }
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // Handle incoming request, i.e. hold
       
   460 // ---------------------------------------------------------------------------
       
   461 //
       
   462 void CSVPEmergencySession::IncomingRequestL( 
       
   463     CMceInSession* aUpdatedSession, TMceTransactionDataContainer aContainer )
       
   464     {
       
   465     SVPDEBUG1("CSVPEmergencySession::IncomingRequest() In")
       
   466 
       
   467     if ( !aUpdatedSession )
       
   468         {
       
   469         User::Leave( KErrArgument );
       
   470         }
       
   471 
       
   472     // Create hold controller
       
   473     if ( NULL == iHoldController )
       
   474         {
       
   475         iHoldController = CSVPHoldController::NewL( 
       
   476             *iEmergencySession,
       
   477             aContainer,
       
   478             this,
       
   479             ETrue );
       
   480         }
       
   481 
       
   482     iEmergencySession = aUpdatedSession;
       
   483 
       
   484     User::LeaveIfError( iHoldController->IncomingRequest( aUpdatedSession ) );
       
   485     }
       
   486 
       
   487 // ---------------------------------------------------------------------------
       
   488 // Returns ETrue, if hold controller exists
       
   489 // ---------------------------------------------------------------------------
       
   490 //
       
   491 TBool CSVPEmergencySession::HasHoldController() const
       
   492     {
       
   493     if ( iHoldController )
       
   494         {
       
   495         return ETrue;
       
   496         }
       
   497     else
       
   498         {
       
   499         return EFalse;
       
   500         }
       
   501     }
       
   502 
       
   503 // ---------------------------------------------------------------------------
       
   504 // Returns reference to hold controller
       
   505 // ---------------------------------------------------------------------------
       
   506 //    
       
   507 CSVPHoldController& CSVPEmergencySession::HoldController() const
       
   508     {
       
   509     return *iHoldController;
       
   510     }
       
   511 
       
   512 // ---------------------------------------------------------------------------
       
   513 // Handles hold session state changes
       
   514 // ---------------------------------------------------------------------------
       
   515 //
       
   516 void CSVPEmergencySession::HoldSessionStateChangedL( CMceSession& aSession )
       
   517     {
       
   518     SVPDEBUG1("CSVPEmergencySession::HoldSessionStateChangedL() In")
       
   519     
       
   520     if ( NULL == iHoldController )
       
   521         {
       
   522         User::Leave( KErrNotFound );
       
   523         }
       
   524 
       
   525     if ( iHoldController->HoldInProgress() )
       
   526         {
       
   527         SVPDEBUG1(
       
   528             "CSVPEmergencySession::HoldSessionStateChangedL, in progress")
       
   529         StopTimers();
       
   530         if ( iHoldController->ContinueHoldProcessing( aSession ) )
       
   531             {
       
   532             iEmergencyObserver->ErrorOccurred( ECCPLocalHoldFail, NULL );
       
   533             }
       
   534         }
       
   535 
       
   536     SVPDEBUG1("CSVPEmergencySession::HoldSessionStateChangedL() Out")
       
   537     }
       
   538 
       
   539 // ---------------------------------------------------------------------------
       
   540 // Returns DTMF observer
       
   541 // ---------------------------------------------------------------------------
       
   542 //
       
   543 const MCCPDTMFObserver& CSVPEmergencySession::DtmfObserver()
       
   544     {
       
   545     return *iDtmfObserver;
       
   546     }
       
   547 
       
   548 // ---------------------------------------------------------------------------
       
   549 // Sets DTMF observer
       
   550 // ---------------------------------------------------------------------------
       
   551 //
       
   552 void CSVPEmergencySession::SetDtmfObserver( 
       
   553     const MCCPDTMFObserver& aObserver )
       
   554     {
       
   555     SVPDEBUG1("CSVPEmergencySession::SetDtmfObserver()")
       
   556     
       
   557     iDtmfObserver = const_cast<MCCPDTMFObserver*>( &aObserver );
       
   558     }
       
   559 
       
   560 // ---------------------------------------------------------------------------
       
   561 // Starts DTMF tone
       
   562 // ---------------------------------------------------------------------------
       
   563 //
       
   564 TInt CSVPEmergencySession::StartDtmfTone( const TChar aTone )
       
   565     {
       
   566     SVPDEBUG1("CSVPEmergencySession::StartDtmfTone() In")
       
   567     
       
   568     TInt dtmfErr( KErrNone );
       
   569     if ( iSVPUtility.GetDTMFMode() )
       
   570         {
       
   571         const RPointerArray<CMceMediaStream>& streams = 
       
   572             iEmergencySession->Streams();
       
   573         TInt count = streams.Count();
       
   574         while ( count )
       
   575             {
       
   576             count--;
       
   577             CMceMediaStream& mediaStream = *streams[ count ];
       
   578             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   579                 {
       
   580                 TRAP( dtmfErr, mediaStream.Source()->StartDtmfToneL( aTone ) )
       
   581                 }
       
   582             else
       
   583                 {
       
   584                 dtmfErr = KErrNotSupported;
       
   585                 }
       
   586             
       
   587             if ( KErrNone != dtmfErr )
       
   588                 {
       
   589                 SVPDEBUG2("CSVPEmergencySession::StartDtmfToneL dtmfErr: %d",
       
   590                     dtmfErr)
       
   591                 return dtmfErr;
       
   592                 }
       
   593             }
       
   594         }
       
   595     else
       
   596         {
       
   597         iDtmfTone = aTone;
       
   598         DtmfObserver().HandleDTMFEvent( MCCPDTMFObserver::ECCPDtmfManualStart, 
       
   599                                         KErrNone, 
       
   600                                         aTone );
       
   601         }
       
   602     SVPDEBUG1("CSVPEmergencySession::StartDtmfTone() Out")
       
   603     return dtmfErr;
       
   604     }
       
   605 
       
   606 // ---------------------------------------------------------------------------
       
   607 // Stops DTMF tone
       
   608 // ---------------------------------------------------------------------------
       
   609 //
       
   610 TInt CSVPEmergencySession::StopDtmfTone()
       
   611     {
       
   612     SVPDEBUG1("CSVPEmergencySession::StopDtmfTone() In")
       
   613     
       
   614     TInt dtmfErr( KErrNone );
       
   615     if ( iSVPUtility.GetDTMFMode() )
       
   616         {
       
   617         const RPointerArray<CMceMediaStream>& streams = 
       
   618             iEmergencySession->Streams();
       
   619         TInt count = streams.Count();
       
   620         while( count )
       
   621             {
       
   622             count--;
       
   623             CMceMediaStream& mediaStream = *streams[ count ];
       
   624             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   625                 {
       
   626                 TRAP( dtmfErr, mediaStream.Source()->StopDtmfToneL() )
       
   627                 }
       
   628             // NOP with inband.
       
   629             
       
   630             if ( KErrNone != dtmfErr )
       
   631                 {
       
   632                 SVPDEBUG2("CSVPEmergencySession::StopDtmfTone dtmfErr: %d",
       
   633                     dtmfErr)
       
   634                 
       
   635                 return dtmfErr;
       
   636                 }
       
   637             }
       
   638         }
       
   639     else
       
   640         {
       
   641         DtmfObserver().HandleDTMFEvent( MCCPDTMFObserver::ECCPDtmfManualStop, 
       
   642                                         KErrNone, 
       
   643                                         iDtmfTone );
       
   644         }
       
   645     SVPDEBUG1("CSVPEmergencySession::StopDtmfTone() Out")
       
   646     return dtmfErr;
       
   647     }
       
   648 
       
   649 // ---------------------------------------------------------------------------
       
   650 // Sends DTMF tone string
       
   651 // ---------------------------------------------------------------------------
       
   652 //
       
   653 TInt CSVPEmergencySession::SendDtmfToneString( const TDesC& aString )
       
   654     {
       
   655     SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString() In")
       
   656     
       
   657     TInt error( KErrNone );
       
   658 
       
   659     TChar dtmfPause('p');
       
   660     // MCE calls if outband DTMF.
       
   661     // Exception is character 'p' which is handled always locally
       
   662     if ( !iSVPUtility.GetDTMFMode() ||
       
   663         ( aString.Length() == 1 &&
       
   664           dtmfPause == aString[0] ) )   
       
   665         {
       
   666         delete iDtmfString;
       
   667         iDtmfString = NULL;
       
   668         TRAP( error, iDtmfString = HBufC::NewL( aString.Length() ) );
       
   669         if ( KErrNone != error )
       
   670             {
       
   671             return error;
       
   672             }
       
   673                        
       
   674         *iDtmfString = aString;
       
   675         iDtmfLex.Assign( *iDtmfString );
       
   676         
       
   677         SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString, inband")
       
   678         if ( !iDTMFEventGenerator )
       
   679             {
       
   680             TRAP( error,
       
   681             iDTMFEventGenerator = CSVPDTMFEventGenerator::NewL( *this ) );
       
   682             }
       
   683         
       
   684         if ( KErrNone != error )
       
   685             {
       
   686             return error;    
       
   687             }
       
   688         
       
   689         // Dtmf pause interval is 2.5s
       
   690         TBool pauseChar = ( aString.Length() == 1 && 
       
   691                             dtmfPause == aString[0] ); 
       
   692         // start events
       
   693         iDTMFEventGenerator->StartDtmfEvents( aString.Length(), pauseChar );
       
   694         }
       
   695     else
       
   696         {
       
   697         SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString, outband")
       
   698         
       
   699         const RPointerArray<CMceMediaStream>& streams = 
       
   700             iEmergencySession->Streams();
       
   701         TInt count = streams.Count();
       
   702         while( count && KErrNone == error )
       
   703             {
       
   704             count--;
       
   705             CMceMediaStream& mediaStream = *streams[ count ];
       
   706             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   707                 {
       
   708                 TRAP( error, mediaStream.Source()->SendDtmfToneSequenceL( 
       
   709                     aString ) )
       
   710                 }
       
   711             else
       
   712                 {
       
   713                 error = KErrNotSupported;
       
   714                 }
       
   715             }
       
   716         }
       
   717 
       
   718     SVPDEBUG2("CSVPEmergencySession::SendDtmfToneString, error: %d", error)
       
   719     return error;
       
   720     }
       
   721 
       
   722 // ---------------------------------------------------------------------------
       
   723 // Cancels DTMF tone string sending
       
   724 // ---------------------------------------------------------------------------
       
   725 //
       
   726 TInt CSVPEmergencySession::CancelDtmfStringSending()
       
   727     {
       
   728     SVPDEBUG1("CSVPEmergencySession::CancelDtmfStringSending() In")
       
   729     
       
   730     TInt error( KErrNone );
       
   731     if ( !iSVPUtility.GetDTMFMode() ) 
       
   732         {
       
   733         error = KErrNotFound;
       
   734         if ( iDTMFEventGenerator )
       
   735             {
       
   736             iDTMFEventGenerator->StopEvents();
       
   737             error = KErrNone;
       
   738             }
       
   739         }
       
   740     else 
       
   741         {
       
   742         SVPDEBUG1("CSVPEmergencySession::CancelDtmfStringSending, outband")
       
   743         error = KErrNotSupported;
       
   744         }
       
   745 
       
   746     SVPDEBUG2("CSVPEmergencySession::CancelDtmfStringSending, error: %d", 
       
   747         error)
       
   748     return error;
       
   749     }
       
   750 
       
   751 // ---------------------------------------------------------------------------
       
   752 // CSVPEmergencySession::Dial
       
   753 // ---------------------------------------------------------------------------
       
   754 //
       
   755 TInt CSVPEmergencySession::Dial( const TDesC& /*aRecipient*/ )
       
   756     {
       
   757     SVPDEBUG1("CSVPEmergencySession::Dial()")
       
   758 
       
   759     if ( iIsDummy )
       
   760         {
       
   761         SVPDEBUG1("CSVPEmergencySession::Dial, dummy session")
       
   762         ErrorOccurred( ECCPErrorGeneral );
       
   763         return KErrNone;
       
   764         }
       
   765 
       
   766     iIsDialed = ETrue;
       
   767     ProceedDial();
       
   768 
       
   769     iEmergencyObserver->CallStateChanged( 
       
   770         MCCPCallObserver::ECCPStateDialling, NULL );
       
   771 
       
   772     return KErrNone;
       
   773     }
       
   774 
       
   775 // ---------------------------------------------------------------------------
       
   776 // CSVPEmergencySession::Cancel
       
   777 // ---------------------------------------------------------------------------
       
   778 //
       
   779 TInt CSVPEmergencySession::Cancel()
       
   780     {
       
   781     SVPDEBUG1("CSVPEmergencySession::Cancel()")
       
   782     
       
   783     TInt error( KErrNone );    
       
   784     if ( iEmergencySession )
       
   785         {
       
   786         TRAP( error, ( ( CMceOutSession* )iEmergencySession )->CancelL() )
       
   787         if ( error )
       
   788             {
       
   789             SVPDEBUG2("CSVPEmergencySession::Cancel, error: %d", error)
       
   790             iEmergencyObserver->CallStateChanged( 
       
   791                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   792             }
       
   793         }
       
   794     else
       
   795         {
       
   796         iEmergencyObserver->CallStateChanged( 
       
   797             MCCPCallObserver::ECCPStateIdle, NULL );
       
   798         }
       
   799     
       
   800     return error;
       
   801     }
       
   802 
       
   803 // ---------------------------------------------------------------------------
       
   804 // CSVPEmergencySession::HangUp
       
   805 // ---------------------------------------------------------------------------
       
   806 //
       
   807 TInt CSVPEmergencySession::HangUp()
       
   808     {
       
   809     SVPDEBUG1("CSVPEmergencySession::HangUp()")
       
   810 
       
   811     if ( NULL == iEmergencySession )
       
   812         {
       
   813         iEmergencyObserver->CallStateChanged( 
       
   814             MCCPCallObserver::ECCPStateIdle, NULL );
       
   815         return KErrNone;
       
   816         }
       
   817     
       
   818     CMceSession::TState mceState = iEmergencySession->State();
       
   819     SVPDEBUG2("CSVPEmergencySession::HangUp, MCE state: %d", mceState)
       
   820     
       
   821     TInt err( KErrNone );
       
   822 
       
   823     if ( CMceSession::EEstablished == mceState || 
       
   824          CMceSession::EOffering == mceState )
       
   825         {
       
   826         if ( CMceSession::EEstablished == mceState )
       
   827             {
       
   828             TRAP( err, iEmergencySession->TerminateL() )
       
   829             }
       
   830         else // CMceSession::EOffering
       
   831             {
       
   832             err = Cancel();
       
   833             }
       
   834         
       
   835         if ( !err )
       
   836             {
       
   837             iEmergencyObserver->CallStateChanged( 
       
   838                 MCCPCallObserver::ECCPStateDisconnecting, NULL );
       
   839             TRAP_IGNORE( StartTimerL( 
       
   840                 KSVPMoHangupTerminatingTime, KSVPHangUpTimerExpired ) )
       
   841             }   
       
   842         }    
       
   843     else // Wrong MCE state
       
   844         {
       
   845         SVPDEBUG2("CSVPEmergencySession::HangUp, wrong state: %d ", mceState )
       
   846         StopTimers();
       
   847         iEmergencyObserver->CallStateChanged( 
       
   848             MCCPCallObserver::ECCPStateIdle, NULL );
       
   849         }
       
   850     
       
   851     return err;
       
   852     }
       
   853 
       
   854 // ---------------------------------------------------------------------------
       
   855 // CSVPEmergencySession::Answer
       
   856 // ---------------------------------------------------------------------------
       
   857 //
       
   858 TInt CSVPEmergencySession::Answer()
       
   859     {
       
   860     SVPDEBUG1("CSVPEmergencySession::Answer()")
       
   861     return KErrNotSupported;
       
   862     }
       
   863 
       
   864 // ---------------------------------------------------------------------------
       
   865 // CSVPEmergencySession::TimedOut
       
   866 // ---------------------------------------------------------------------------
       
   867 // 
       
   868 void CSVPEmergencySession::TimedOut( TInt aTimerId )
       
   869     {
       
   870     SVPDEBUG1("CSVPEmergencySession::TimedOut()")
       
   871     
       
   872      // Find the timer and delete it.
       
   873     for ( TInt t = 0; t < iTimers.Count(); )
       
   874         {
       
   875         if ( iTimers[t] ->Id() == aTimerId )
       
   876             {
       
   877             delete iTimers[t];
       
   878             iTimers.Remove( t );
       
   879             }
       
   880         else
       
   881             {
       
   882             t++;
       
   883             }
       
   884         }
       
   885 
       
   886     switch ( aTimerId )
       
   887         {
       
   888         case KSVPHangUpTimerExpired:
       
   889             SVPDEBUG1("CSVPEmergencySession::TimedOut, hangup")
       
   890             iEmergencyObserver->CallStateChanged( 
       
   891                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   892             break;
       
   893 
       
   894         case KSVPTerminationTimerExpired:
       
   895             SVPDEBUG1("CSVPEmergencySession::TimedOut, termination")
       
   896             iSessionState = MCCPCallObserver::ECCPStateIdle;
       
   897             iEmergencyObserver->CallStateChanged( State(), NULL );
       
   898             break;
       
   899 
       
   900         case KSVPInviteTimerExpired:
       
   901             SVPDEBUG1("CSVPEmergencySession::TimedOut, invite")
       
   902             // Connection made but no answer, no point trying other profiles
       
   903             ErrorOccurred( ECCPEmergencyFailed );
       
   904             Cancel();
       
   905             iEmergencyObserver->CallStateChanged( 
       
   906                 MCCPCallObserver::ECCPStateDisconnecting, NULL );
       
   907             iEmergencyObserver->CallStateChanged( 
       
   908                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   909             break;
       
   910         
       
   911         case KSVPEmergencyExpired:
       
   912             SVPDEBUG1("CSVPEmergencySession::TimedOut, emergency")
       
   913             ErrorOccurred( ECCPErrorTimedOut );
       
   914             break;
       
   915         
       
   916         case KSVPRemoteEndDiedExpired:
       
   917             SVPDEBUG1("CSVPEmergencySession::TimedOut, remote end died")
       
   918             iEmergencyObserver->CallStateChanged( 
       
   919                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   920             break;
       
   921         
       
   922         default:
       
   923             SVPDEBUG1("CSVPEmergencySession::TimedOut, no timer found")
       
   924             break;
       
   925         }    
       
   926     }
       
   927 
       
   928 // ---------------------------------------------------------------------------
       
   929 // From class MSIPObserver
       
   930 // CSVPEmergencySession::IncomingRequest
       
   931 // ---------------------------------------------------------------------------
       
   932 // 
       
   933 void CSVPEmergencySession::IncomingRequest( 
       
   934     TUint32 /*aIapId*/, CSIPServerTransaction* /*aTransaction*/ )
       
   935     {
       
   936     }
       
   937 
       
   938 // ---------------------------------------------------------------------------
       
   939 // From class MSIPObserver
       
   940 // CSVPEmergencySession::TimedOut
       
   941 // ---------------------------------------------------------------------------
       
   942 //     
       
   943 void CSVPEmergencySession::TimedOut( 
       
   944     CSIPServerTransaction& /*aSIPServerTransaction*/ )
       
   945     {
       
   946     }
       
   947 
       
   948 // ---------------------------------------------------------------------------
       
   949 // From class MSIPProfileRegistryObserver
       
   950 // CSVPEmergencySession::ProfileRegistryErrorOccurred
       
   951 // ---------------------------------------------------------------------------
       
   952 //  
       
   953 void CSVPEmergencySession::ProfileRegistryErrorOccurred( 
       
   954     TUint32 /*aSIPProfileId*/, TInt /*aError*/ )
       
   955     {
       
   956     }
       
   957 
       
   958 // ---------------------------------------------------------------------------
       
   959 // From class MSIPProfileRegistryObserver
       
   960 // CSVPEmergencySession::ProfileRegistryEventOccurred
       
   961 // ---------------------------------------------------------------------------
       
   962 //  
       
   963 void CSVPEmergencySession::ProfileRegistryEventOccurred( 
       
   964     TUint32 /*aProfileId*/, TEvent /*aEvent*/ )
       
   965     {
       
   966     }
       
   967 
       
   968 // ---------------------------------------------------------------------------
       
   969 // From class MSVPPositioningProviderObserver.
       
   970 // Handles successful positioning requests
       
   971 // ---------------------------------------------------------------------------
       
   972 //
       
   973 void CSVPEmergencySession::PositioningRequestComplete( 
       
   974     const TDesC8& aPosition )
       
   975     {
       
   976     SVPDEBUG2("CSVPEmergencySession::PositioningRequestComplete() - \
       
   977      length: %d", aPosition.Length())
       
   978     
       
   979     iIsLIRequestReady = ETrue;
       
   980     
       
   981     delete iPositionInformation;
       
   982     iPositionInformation = NULL;
       
   983     TRAPD( err, iPositionInformation = HBufC8::NewL( aPosition.Length() ) )
       
   984     if ( !err )
       
   985         {
       
   986         ( iPositionInformation->Des() ).Copy( aPosition );
       
   987         }
       
   988 
       
   989     iPositioningProvider->CloseModule();
       
   990     ProceedDial();
       
   991     }
       
   992 
       
   993 // ---------------------------------------------------------------------------
       
   994 // From class MSVPPositioningProviderObserver.
       
   995 // Handles failed positioning requests
       
   996 // ---------------------------------------------------------------------------
       
   997 //
       
   998 #ifdef _DEBUG
       
   999 void CSVPEmergencySession::PositioningErrorOccurred( TInt aError )
       
  1000 #else
       
  1001 void CSVPEmergencySession::PositioningErrorOccurred( TInt /*aError*/ )
       
  1002 #endif // _DEBUG
       
  1003     {
       
  1004     SVPDEBUG2("CSVPEmergencySession::PositioningErrorOccurred( %d )", aError)
       
  1005     
       
  1006     iIsLIRequestReady = ETrue;
       
  1007     iPositioningProvider->CloseModule();
       
  1008     ProceedDial();
       
  1009     }
       
  1010 
       
  1011 // ---------------------------------------------------------------------------
       
  1012 // From class MSVPEmergencyConnectionObserver.
       
  1013 // SNAP connection is established
       
  1014 // ---------------------------------------------------------------------------
       
  1015 //
       
  1016 void CSVPEmergencySession::SnapConnected()
       
  1017     {
       
  1018     SVPDEBUG1("CSVPEmergencySession::SnapConnected() In")
       
  1019     
       
  1020     if ( NULL == iEmergencyConnection )
       
  1021         {
       
  1022         SVPDEBUG1("CSVPEmergencySession::SnapConnected, no connection object")
       
  1023         ErrorOccurred( ECCPErrorGeneral );
       
  1024         return;
       
  1025         }
       
  1026     
       
  1027     TInt err = iEmergencyConnection->IapId( iIapId );
       
  1028     SVPDEBUG2("CSVPEmergencySession::ConnectionReady, IAP ID: %d", iIapId)
       
  1029     if ( err )
       
  1030         {
       
  1031         SVPDEBUG2("CSVPEmergencySession::SnapConnected, error: %d", err)
       
  1032         ErrorOccurred( ECCPErrorGeneral );
       
  1033         return;
       
  1034         }
       
  1035 
       
  1036     TRAP( err, CreateUnregistedSessionL() )
       
  1037     if ( err )
       
  1038         {
       
  1039         SVPDEBUG2("CSVPEmergencySession::SnapConnected, error: %d", err)
       
  1040         ErrorOccurred( ECCPErrorGeneral );
       
  1041         return;
       
  1042         }
       
  1043 
       
  1044     // Request for position information
       
  1045     RequestPosition( iIapId );    
       
  1046     
       
  1047     ProceedDial();
       
  1048         
       
  1049     SVPDEBUG1("CSVPEmergencySession::SnapConnected() Out")
       
  1050     }
       
  1051 
       
  1052 // ---------------------------------------------------------------------------
       
  1053 // From class MSVPEmergencyConnectionObserver.
       
  1054 // Connection is established
       
  1055 // ---------------------------------------------------------------------------
       
  1056 //    
       
  1057 void CSVPEmergencySession::Connected()
       
  1058     {
       
  1059     SVPDEBUG1("CSVPEmergencySession::Connected()")
       
  1060     
       
  1061     TRAPD( error, RequestSipProxyAddressL() )
       
  1062     if ( error )
       
  1063         {
       
  1064         SVPDEBUG2("CSVPEmergencySession::Connected, error: %d", error)
       
  1065         ErrorOccurred( ECCPErrorGeneral );
       
  1066         }
       
  1067     }
       
  1068 
       
  1069 // ---------------------------------------------------------------------------
       
  1070 // From class MSVPEmergencyConnectionObserver.
       
  1071 // SIP proxy address ready
       
  1072 // ---------------------------------------------------------------------------
       
  1073 //    
       
  1074 void CSVPEmergencySession::SipProxyAddressReady( const TDesC16& aAddress )
       
  1075     {
       
  1076     SVPDEBUG1("CSVPEmergencySession::SipProxyAddressReady()")
       
  1077     
       
  1078     TRAPD( error, ContinueConstructWithIapIdL( aAddress ) )
       
  1079     if ( error )
       
  1080         {
       
  1081         SVPDEBUG2("CSVPEmergencySession::SipProxyAddressReady, error: %d", 
       
  1082             error)
       
  1083         ErrorOccurred( ECCPErrorGeneral );
       
  1084         }
       
  1085     }
       
  1086 
       
  1087 // ---------------------------------------------------------------------------
       
  1088 // From class MSVPEmergencyConnectionObserver.
       
  1089 // Connection error has occurred
       
  1090 // ---------------------------------------------------------------------------
       
  1091 //
       
  1092 #ifdef _DEBUG
       
  1093 void CSVPEmergencySession::ConnectionError( TInt aError )
       
  1094 #else
       
  1095 void CSVPEmergencySession::ConnectionError( TInt /*aError*/ )
       
  1096 #endif // _DEBUG
       
  1097     {
       
  1098     SVPDEBUG2("CSVPEmergencySession::ConnectionError, error: %d", aError)
       
  1099     
       
  1100     ErrorOccurred( ECCPErrorGeneral );
       
  1101     }
       
  1102 
       
  1103 // ---------------------------------------------------------------------------
       
  1104 // From class MSVPHoldObserver.
       
  1105 // Local hold
       
  1106 // ---------------------------------------------------------------------------
       
  1107 //
       
  1108 void CSVPEmergencySession::SessionLocallyHeld()
       
  1109     {
       
  1110     SVPDEBUG1("CSVPEmergencySession::SessionLocallyHeld()")
       
  1111     iEmergencyObserver->CallStateChanged( MCCPCallObserver::ECCPStateHold, 
       
  1112                                           NULL );
       
  1113     }
       
  1114 
       
  1115 // ---------------------------------------------------------------------------
       
  1116 // From class MSVPHoldObserver.
       
  1117 // Local resume
       
  1118 // ---------------------------------------------------------------------------
       
  1119 //
       
  1120 void CSVPEmergencySession::SessionLocallyResumed()
       
  1121     {
       
  1122     SVPDEBUG1("CSVPEmergencySession::SessionLocallyResumed()")
       
  1123     iEmergencyObserver->CallStateChanged( 
       
  1124         MCCPCallObserver::ECCPStateConnected, NULL );
       
  1125     }
       
  1126 
       
  1127 // ---------------------------------------------------------------------------
       
  1128 // From class MSVPHoldObserver.
       
  1129 // Remote hold
       
  1130 // ---------------------------------------------------------------------------
       
  1131 //
       
  1132 void CSVPEmergencySession::SessionRemoteHeld()
       
  1133     {
       
  1134     SVPDEBUG1("CSVPEmergencySession::SessionRemoteHeld()")
       
  1135     iEmergencyObserver->CallEventOccurred( MCCPCallObserver::ECCPRemoteHold, 
       
  1136                                            NULL );
       
  1137     }
       
  1138 
       
  1139 // ---------------------------------------------------------------------------
       
  1140 // From class MSVPHoldObserver.
       
  1141 // Remote resume
       
  1142 // ---------------------------------------------------------------------------
       
  1143 //
       
  1144 void CSVPEmergencySession::SessionRemoteResumed()
       
  1145     {
       
  1146     SVPDEBUG1("CSVPEmergencySession::SessionRemoteResumed()")
       
  1147     iEmergencyObserver->CallEventOccurred( 
       
  1148         MCCPCallObserver::ECCPRemoteResume, NULL );
       
  1149     }
       
  1150 
       
  1151 // ---------------------------------------------------------------------------
       
  1152 // From class MSVPHoldObserver.
       
  1153 // Hold request failed
       
  1154 // ---------------------------------------------------------------------------
       
  1155 //
       
  1156 void CSVPEmergencySession::HoldRequestFailed()
       
  1157     {
       
  1158     SVPDEBUG1("CSVPEmergencySession::HoldRequestFailed()")
       
  1159     iEmergencyObserver->ErrorOccurred( ECCPLocalHoldFail, NULL );
       
  1160     }
       
  1161 
       
  1162 // ---------------------------------------------------------------------------
       
  1163 // From class MSVPHoldObserver.
       
  1164 // Resume request failed
       
  1165 // ---------------------------------------------------------------------------
       
  1166 //
       
  1167 void CSVPEmergencySession::ResumeRequestFailed()
       
  1168     {
       
  1169     SVPDEBUG1("CSVPEmergencySession::ResumeRequestFailed()")
       
  1170     iEmergencyObserver->ErrorOccurred( ECCPLocalResumeFail, NULL );
       
  1171     }
       
  1172 
       
  1173 // ---------------------------------------------------------------------------
       
  1174 // Inband DTMF event occurred
       
  1175 // ---------------------------------------------------------------------------
       
  1176 //   
       
  1177 void CSVPEmergencySession::InbandDtmfEventOccurred( TSVPDtmfEvent aEvent )
       
  1178     {
       
  1179     SVPDEBUG2("CSVPEmergencySession::InbandDtmfEventOccurred(), event:%d", 
       
  1180         aEvent)
       
  1181     
       
  1182     switch ( aEvent )
       
  1183         {
       
  1184         case ESvpDtmfSendStarted:
       
  1185             iDtmfObserver->HandleDTMFEvent( 
       
  1186                 MCCPDTMFObserver::ECCPDtmfSequenceStart, 
       
  1187                 KErrNone, 
       
  1188                 iDtmfLex.Peek() );
       
  1189             break;
       
  1190             
       
  1191         case ESvpDtmfSendStopped:
       
  1192             iDtmfObserver->HandleDTMFEvent( 
       
  1193                 MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  1194                 KErrNone, 
       
  1195                 iDtmfLex.Get() );
       
  1196             break;
       
  1197             
       
  1198         case ESvpDtmfSendCompleted:
       
  1199             {
       
  1200             iDtmfObserver->HandleDTMFEvent( 
       
  1201                 MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, 
       
  1202                 KErrNone, 
       
  1203                 iDtmfLex.Peek() );
       
  1204             
       
  1205             // String can be deleted as whole string has been sent 
       
  1206             delete iDtmfString;
       
  1207             iDtmfString = NULL;
       
  1208             
       
  1209             break;
       
  1210             }
       
  1211             
       
  1212         default:
       
  1213             break;
       
  1214         }
       
  1215     
       
  1216     SVPDEBUG1("CSVPEmergencySession::InbandDtmfEventOccurred() Out");
       
  1217     }
       
  1218 
       
  1219 // ---------------------------------------------------------------------------
       
  1220 // Deletes failed MCE session and creates a new one without LI. Used when 
       
  1221 // 415 Unsupported Media Type received.
       
  1222 // ---------------------------------------------------------------------------
       
  1223 //
       
  1224 void CSVPEmergencySession::CreateNonLISessionL()
       
  1225     {
       
  1226     SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL() IN")
       
  1227 
       
  1228     // Save failed emergency session
       
  1229     iFailedEmergencySession = iEmergencySession;
       
  1230     iEmergencySession = NULL;
       
  1231 
       
  1232     // Delete LI
       
  1233     delete iPositionInformation;
       
  1234     iPositionInformation = NULL;
       
  1235     iIsLIRequestReady = ETrue;
       
  1236     
       
  1237     if ( KErrNotFound == iVoipProfileId )
       
  1238         {
       
  1239         // No VoIP profile, trying IAP emergency call
       
  1240         SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL, IAP EC")
       
  1241         CreateUnregistedSessionL();
       
  1242         return;
       
  1243         }
       
  1244     
       
  1245     // Initialize SIP registry
       
  1246     CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS:1
       
  1247     CSIPProfileRegistry* sipProfileRegistry = CSIPProfileRegistry::NewLC( 
       
  1248         *sip, *this ); // CS:2
       
  1249 
       
  1250     // Get SIP profile, only one SIP profile per VoIP profile
       
  1251     CSIPProfile* sipProfile = sipProfileRegistry->ProfileL( iSipProfileId );
       
  1252     CleanupStack::PushL( sipProfile ); // CS:3
       
  1253 
       
  1254     // Create MCE out session
       
  1255     TBool registered( EFalse );
       
  1256     sipProfile->GetParameter( KSIPProfileRegistered, registered );
       
  1257     if ( registered )
       
  1258         {
       
  1259         SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL, registered")
       
  1260         iEmergencySession = CMceOutSession::NewL( 
       
  1261             iMceManager, *sipProfile, *iRecipientUri );
       
  1262         ConstructAudioStreamsL();
       
  1263         }
       
  1264     else
       
  1265         {
       
  1266         CreateUnregistedSessionL();        
       
  1267         }
       
  1268     
       
  1269     CleanupStack::PopAndDestroy( 3, sip ); 
       
  1270     // CS:0 sip, sipProfileRegistry, sipProfile
       
  1271 
       
  1272     SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL() OUT")
       
  1273     }
       
  1274 
       
  1275 // ---------------------------------------------------------------------------
       
  1276 // Creates unregistered MCE session
       
  1277 // ---------------------------------------------------------------------------
       
  1278 //
       
  1279 void CSVPEmergencySession::CreateUnregistedSessionL()
       
  1280     {
       
  1281     SVPDEBUG1("CSVPEmergencySession::CreateUnregistedSessionL()")
       
  1282     
       
  1283     iEmergencySession = CMceOutSession::NewL( 
       
  1284         iMceManager, iIapId, *iUserAor, *iRecipientUri );
       
  1285 
       
  1286     ConstructAudioStreamsL();
       
  1287     }
       
  1288 
       
  1289 // ---------------------------------------------------------------------------
       
  1290 // Handles emergency session state change
       
  1291 // ---------------------------------------------------------------------------
       
  1292 //
       
  1293 void CSVPEmergencySession::SessionStateChangedL( TInt aMceStatusCode )
       
  1294     {
       
  1295     SVPDEBUG3("CSVPEmergencySession::SessionStateChangedL,\
       
  1296      status: %d,state: %d ", aMceStatusCode, iEmergencySession->State() )
       
  1297          
       
  1298     // Match TCCPSessionError
       
  1299     TInt ccpStatusCode = aMceStatusCode;     
       
  1300     TCCPError ccpError = iSVPUtility.GetCCPError( ccpStatusCode, iTone );
       
  1301     
       
  1302     // Call voip event logger with original status
       
  1303     if ( ECCPErrorNone != ccpError && KErrNotFound != iVoipProfileId )
       
  1304         {
       
  1305         iSVPUtility.LogVoipEventL( 
       
  1306             aMceStatusCode, iSipProfileId, KNullDesC, KNullDesC );
       
  1307         }        
       
  1308    
       
  1309     // Status code returns KErrNone if TCCPSessionError is not found
       
  1310     if ( KErrNone != ccpStatusCode )
       
  1311         {
       
  1312         SVPDEBUG2("CSVPEmergencySession::SessionStateChanged:\
       
  1313          error: %d", aMceStatusCode )
       
  1314 
       
  1315         if ( ECCPErrorRejected == ccpError || 
       
  1316              ECCPErrorBusy == ccpError || 
       
  1317              ECCPErrorTimedOut == ccpError )
       
  1318             {     
       
  1319             SVPDEBUG1("CSVPEmergencySession::SessionStateChanged\
       
  1320              iSessionState -> Disconnecting")
       
  1321             iSessionState = MCCPCallObserver::ECCPStateDisconnecting;
       
  1322             }
       
  1323         else if ( KSVPUnsupportedMediaTypeVal == aMceStatusCode && 
       
  1324                   CMceSession::ETerminated == iEmergencySession->State() && 
       
  1325                   iPositionInformation )
       
  1326             {
       
  1327             // MT cannot handle LI: create a new session without LI
       
  1328             CreateNonLISessionL();
       
  1329             ProceedDial();
       
  1330             return;
       
  1331             }
       
  1332 
       
  1333         ErrorOccurred( ccpError );
       
  1334         }
       
  1335     
       
  1336     // Handle provisional responses 1XX
       
  1337     if ( KSVPRingingVal == aMceStatusCode || 
       
  1338          KSVPForwardedVal == aMceStatusCode || 
       
  1339          KSVPQueuedVal == aMceStatusCode || 
       
  1340          KSVPSessionProgressVal == aMceStatusCode )
       
  1341         {        
       
  1342         // Response received, stop emergency timer
       
  1343         StopTimer( KSVPEmergencyExpired );
       
  1344 
       
  1345         if ( KSVPRingingVal == aMceStatusCode )
       
  1346             {
       
  1347             SVPDEBUG1(
       
  1348             "CSVPEmergencySession::SessionStateChanged, 180 Ringing received")
       
  1349             iEmergencyObserver->CallStateChanged( 
       
  1350                 MCCPCallObserver::ECCPStateConnecting, NULL );
       
  1351             }
       
  1352         }
       
  1353 
       
  1354     switch( iEmergencySession->State() )
       
  1355         {
       
  1356         case CMceSession::EEstablished:
       
  1357             {
       
  1358             StopTimers();
       
  1359             
       
  1360             // Save state because it may change while checking priorities
       
  1361             MCCPCallObserver::TCCPCallState ccpState = State();
       
  1362             
       
  1363             if ( SVPAudioUtility::MmfPriorityUpdateNeededL( 
       
  1364                      iEmergencySession->Streams() ) )
       
  1365                 {
       
  1366                 CheckMmfPrioritiesForDtmfL( iEmergencySession->Streams() );
       
  1367                 }
       
  1368             
       
  1369             UpdateKeepAliveL();
       
  1370             
       
  1371             SVPAudioUtility::EnableSpeakerSinksL( 
       
  1372                 iEmergencySession->Streams() );
       
  1373             
       
  1374             iEmergencyObserver->CallStateChanged( ccpState, NULL );
       
  1375             break;
       
  1376             }
       
  1377         case CMceSession::EAnswering:
       
  1378         case CMceSession::EReserving:
       
  1379         case CMceSession::EIncoming:
       
  1380         case CMceSession::EOffering:
       
  1381             {
       
  1382             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged, no action")
       
  1383             break;
       
  1384             }
       
  1385         case CMceSession::ECancelling:
       
  1386         case CMceSession::EIdle:
       
  1387         case CMceSession::ETerminating:
       
  1388         case CMceSession::EProceeding:
       
  1389             {
       
  1390             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged:\
       
  1391              Callback state change")
       
  1392             iEmergencyObserver->CallStateChanged( State(), NULL );
       
  1393             break;
       
  1394             }
       
  1395         case CMceSession::ETerminated:
       
  1396             {
       
  1397             SVPDEBUG1("CSVPEmergencySession::SessionStateChanged, terminated")
       
  1398             iSessionState = MCCPCallObserver::ECCPStateDisconnecting;
       
  1399             StartTimerL( KSVPTerminatingTime, KSVPTerminationTimerExpired );
       
  1400             iEmergencyObserver->CallStateChanged( State(), NULL );
       
  1401             break;
       
  1402             }
       
  1403         default:
       
  1404             {
       
  1405             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged: default")
       
  1406             break;
       
  1407             }
       
  1408         }
       
  1409         
       
  1410     SVPDEBUG1("CSVPEmergencySession::SessionStateChanged Out")
       
  1411     }
       
  1412 
       
  1413 // ---------------------------------------------------------------------------
       
  1414 // Determines if dialing can be proceeded
       
  1415 // ---------------------------------------------------------------------------
       
  1416 //
       
  1417 void CSVPEmergencySession::ProceedDial()
       
  1418     {
       
  1419     SVPDEBUG1("CSVPEmergencySession::ProceedDial()")
       
  1420     
       
  1421     if ( iIsDialed && 
       
  1422          iIsLIRequestReady && 
       
  1423          iEmergencySession &&
       
  1424          iEmergencySession->ConnectionActive() )
       
  1425         {
       
  1426         TRAPD( err, DialL() );
       
  1427         if ( err )
       
  1428             {
       
  1429             SVPDEBUG2("CSVPEmergencySession::ProceedDial(), error: %d", err)
       
  1430             ErrorOccurred( ECCPErrorGeneral );
       
  1431             }
       
  1432         }
       
  1433     }
       
  1434 
       
  1435 // ---------------------------------------------------------------------------
       
  1436 // CSVPEmergencySession::DialL
       
  1437 // ---------------------------------------------------------------------------
       
  1438 //
       
  1439 void CSVPEmergencySession::DialL()
       
  1440     {
       
  1441     SVPDEBUG1("CSVPEmergencySession::DialL()")
       
  1442     
       
  1443     // Add priority header
       
  1444     CDesC8ArrayFlat* headers = new ( ELeave ) CDesC8ArrayFlat( 1 );
       
  1445     CleanupStack::PushL( headers ); // CS:1
       
  1446     headers->AppendL( KSVPEmergencyPriorityEmergency() );
       
  1447     
       
  1448     // Add location related headers
       
  1449     if ( iPositionInformation && iUserAor )
       
  1450         {
       
  1451         // Create content headers
       
  1452         CDesC8ArrayFlat* contentHeaders = new ( ELeave ) CDesC8ArrayFlat( 1 );
       
  1453         CleanupStack::PushL( contentHeaders ); // CS:2
       
  1454 
       
  1455         // Content-ID: alice at atlanta.example.com
       
  1456         HBufC8* contentIdValue = ParseContentIdL( *iUserAor );
       
  1457         CleanupStack::PushL( contentIdValue ); // CS:3
       
  1458 
       
  1459         HBufC8* contentId = HBufC8::NewLC( 
       
  1460             KSVPEmergencyContentIdName().Length() + 
       
  1461             contentIdValue->Length() ); // CS:4
       
  1462         ( contentId->Des() ).Copy( KSVPEmergencyContentIdName() );
       
  1463         ( contentId->Des() ).Append( *contentIdValue );
       
  1464 
       
  1465         contentHeaders->AppendL( *contentId );
       
  1466         CleanupStack::PopAndDestroy( contentId ); // CS:3
       
  1467 
       
  1468         // Geolocation: <cid:alice at atlanta.example.com>;
       
  1469         // inserted-by=alice at atlanta.example.com;recipient=endpoint
       
  1470         HBufC8* cidValue = ParseCidL( *contentIdValue );
       
  1471         CleanupStack::PushL( cidValue ); // CS:4
       
  1472         
       
  1473         HBufC8* geolocation = HBufC8::NewL( 
       
  1474             KSVPEmergencyGeolocation().Length() + 
       
  1475             cidValue->Length() + 
       
  1476             KSVPEmergencyTagInsertedBy().Length() + 
       
  1477             contentIdValue->Length() + 
       
  1478             KSVPEmergencyTagRecipientEndpoint().Length() );
       
  1479         ( geolocation->Des() ).Copy( KSVPEmergencyGeolocation() );
       
  1480         ( geolocation->Des() ).Append( *cidValue );
       
  1481         ( geolocation->Des() ).Append( KSVPEmergencyTagInsertedBy() );
       
  1482         ( geolocation->Des() ).Append( *contentIdValue );
       
  1483         ( geolocation->Des() ).Append( KSVPEmergencyTagRecipientEndpoint() );
       
  1484         
       
  1485         // cidValue, contentIdValue CS:2
       
  1486         CleanupStack::PopAndDestroy( 2, contentIdValue );
       
  1487         CleanupStack::PushL( geolocation ); // CS:3
       
  1488         headers->AppendL( *geolocation );
       
  1489         CleanupStack::PopAndDestroy( geolocation ); // CS:2
       
  1490 
       
  1491         // Accept: application/pidf+xml
       
  1492         headers->AppendL( KSVPEmergencyAcceptApplicationSdp() );
       
  1493 
       
  1494         // Content-Type: application/pidf+xml
       
  1495         HBufC8* contentType = HBufC8::NewLC( 
       
  1496             KSVPEmergencyApplicationPidfXml().Length() ); // CS:3
       
  1497         ( contentType->Des() ).Copy( KSVPEmergencyApplicationPidfXml() );
       
  1498 
       
  1499         // Establish call
       
  1500         ( ( CMceOutSession* )iEmergencySession )->EstablishL( 
       
  1501             iSessionExpires, 
       
  1502             headers, 
       
  1503             contentType, 
       
  1504             iPositionInformation->AllocL(), 
       
  1505             contentHeaders );
       
  1506 
       
  1507         // contentType, contentHeaders, Ownership transferred CS:1
       
  1508         CleanupStack::Pop( 2, contentHeaders );
       
  1509         }
       
  1510     else
       
  1511         {
       
  1512         ( ( CMceOutSession* )iEmergencySession )->EstablishL( 
       
  1513             iSessionExpires, headers );
       
  1514         }
       
  1515     CleanupStack::Pop( headers ); // Ownership transferred, CS:0
       
  1516     
       
  1517     // Start INVITE timer in case remote end does not respond
       
  1518     StartTimerL( KSVPInviteTimer, KSVPInviteTimerExpired );
       
  1519     }
       
  1520 
       
  1521 // ---------------------------------------------------------------------------
       
  1522 // CSVPEmergencySession::ConstructAudioStreamsL
       
  1523 // ---------------------------------------------------------------------------
       
  1524 //  
       
  1525 void CSVPEmergencySession::ConstructAudioStreamsL()
       
  1526     {
       
  1527     SVPDEBUG1( "CSVPEmergencySession::ConstructAudioStreamsL In" )
       
  1528 
       
  1529     // OUT STREAM
       
  1530     CMceAudioStream* audioOutStream = CMceAudioStream::NewLC(); // CS:1
       
  1531     // Set microphone as audio out source, only one source at a time    
       
  1532     CMceMicSource* mic = CMceMicSource::NewLC(); // CS:2
       
  1533     audioOutStream->SetSourceL( mic );
       
  1534     CleanupStack::Pop( mic ); // CS:1
       
  1535     CMceRtpSink* rtpSink = CMceRtpSink::NewLC(); // CS:2
       
  1536 	audioOutStream->AddSinkL( rtpSink );
       
  1537 	CleanupStack::Pop( rtpSink ); // CS:1
       
  1538   
       
  1539     // IN STREAM
       
  1540     CMceAudioStream* audioInStream = CMceAudioStream::NewLC(); // CS:2
       
  1541 	CMceRtpSource* rtpSource = CMceRtpSource::NewLC( 
       
  1542 	    KSvpJitterBufferLength, 
       
  1543 	    KSvpJitterBufferThreshold, 
       
  1544 	    KSvpStandbyTimerInMillisecs ); // CS:3
       
  1545 	audioInStream->SetSourceL( rtpSource );
       
  1546 	CleanupStack::Pop( rtpSource ); // CS:2
       
  1547 	// Set speaker as audio in sink	
       
  1548 	CMceSpeakerSink* speakerSink = CMceSpeakerSink::NewLC(); // CS:3
       
  1549 	audioInStream->AddSinkL( speakerSink );
       
  1550 	CleanupStack::Pop( speakerSink ); // CS:2
       
  1551 
       
  1552 	// Bind "audio out" stream to "audio in" stream
       
  1553 	audioOutStream->BindL( audioInStream );
       
  1554 	CleanupStack::Pop( audioInStream ); // CS: 1
       
  1555 	
       
  1556     iEmergencySession->AddStreamL( audioOutStream );
       
  1557     CleanupStack::Pop( audioOutStream ); // CS: 0
       
  1558     
       
  1559     // Modify QoS preconditions off
       
  1560     iEmergencySession->SetModifierL( 
       
  1561         KMcePreconditions, KMcePreconditionsNotUsed );
       
  1562         
       
  1563     // Modify Old way hold on
       
  1564     iEmergencySession->SetModifierL( 
       
  1565         KMceMediaDirection, KMceMediaDirectionWithAddress );
       
  1566 
       
  1567     SVPDEBUG2("CSVPEmergencySession::ConstructAudioStreamsL, in codecs: %d", 
       
  1568         audioInStream->Codecs().Count())
       
  1569     SVPDEBUG2("CSVPEmergencySession::ConstructAudioStreamsL, out codecs: %d", 
       
  1570         audioOutStream->Codecs().Count())
       
  1571 
       
  1572     // Set keep-alive value
       
  1573     SetKeepAlive();
       
  1574     
       
  1575     // Add codecs to audiostream
       
  1576     iSVPUtility.SetAudioCodecsForEmergencyL( 
       
  1577         *audioInStream, iKeepAlive, iVoipProfileId );
       
  1578     
       
  1579     audioOutStream->SetLocalMediaPortL( audioInStream->LocalMediaPort() );
       
  1580     
       
  1581     iSVPUtility.UpdateJitterBufferSizeL( *rtpSource );
       
  1582     
       
  1583     // Set MMF priorities and preferences to codecs
       
  1584     iSVPUtility.SetDtmfMode( SVPAudioUtility::SetPriorityCodecValuesL( 
       
  1585         *audioInStream, *audioOutStream ) );
       
  1586                                          
       
  1587     SVPDEBUG1( "CSVPEmergencySession::ConstructAudioStreamsL Out" )
       
  1588     }
       
  1589 
       
  1590 // ---------------------------------------------------------------------------
       
  1591 // Sets keep-alive value
       
  1592 // ---------------------------------------------------------------------------
       
  1593 //  
       
  1594 void CSVPEmergencySession::SetKeepAlive()
       
  1595     {
       
  1596     SVPDEBUG1("CSVPEmergencySession::SetKeepAlive()")
       
  1597     
       
  1598     // Get keep-alive value, do not leave: return default value instead
       
  1599     TBool found( EFalse );
       
  1600     TRAPD( errKeepAlive, 
       
  1601         found = iSVPUtility.GetKeepAliveByIapIdL( iIapId, iKeepAlive ) )
       
  1602     if ( errKeepAlive || !found )
       
  1603         {
       
  1604         TRAP( errKeepAlive, found = iSVPUtility.GetKeepAliveByAORL( 
       
  1605             *iUserAor, iKeepAlive ) )
       
  1606         if ( errKeepAlive || !found )
       
  1607             {
       
  1608             iKeepAlive = KSVPDefaultUDPRefreshInterval;
       
  1609             }
       
  1610         }
       
  1611     
       
  1612     SVPDEBUG2("CSVPEmergencySession::KeepAlive, value: %d", iKeepAlive)
       
  1613     }
       
  1614 
       
  1615 // ---------------------------------------------------------------------------
       
  1616 // Updates keepalive parameters for MCE session
       
  1617 // ---------------------------------------------------------------------------
       
  1618 //
       
  1619 void CSVPEmergencySession::UpdateKeepAliveL()
       
  1620     {
       
  1621     SVPDEBUG1("CSVPEmergencySession::UpdateKeepAliveL()")
       
  1622     
       
  1623     const RPointerArray<CMceMediaStream>& streamArray = 
       
  1624         iEmergencySession->Streams();
       
  1625     TInt streamCount( streamArray.Count() );
       
  1626     TBool cnInAnswer( EFalse );
       
  1627     
       
  1628     for ( TInt i = 0; i < streamCount; i++ )
       
  1629         {
       
  1630         CMceAudioStream* stream = 
       
  1631             static_cast<CMceAudioStream*>( streamArray[i] );
       
  1632         if ( iSVPUtility.IsComfortNoise( *stream ) )
       
  1633             {
       
  1634             cnInAnswer = ETrue;
       
  1635             iSVPUtility.SetCNKeepAliveL( *stream, iKeepAlive );
       
  1636             }
       
  1637         }
       
  1638     
       
  1639     if ( !cnInAnswer )
       
  1640         {
       
  1641         while( streamCount-- )
       
  1642             {
       
  1643             CMceAudioStream* stream = 
       
  1644                 static_cast<CMceAudioStream*>( streamArray[streamCount] );
       
  1645             iSVPUtility.SetKeepAliveL( *stream, iKeepAlive );
       
  1646             }
       
  1647         }
       
  1648     
       
  1649     iEmergencySession->UpdateL();
       
  1650     }
       
  1651 
       
  1652 // ---------------------------------------------------------------------------
       
  1653 // Check audio priorities in audio streams
       
  1654 // ---------------------------------------------------------------------------
       
  1655 //
       
  1656 void CSVPEmergencySession::CheckMmfPrioritiesForDtmfL(
       
  1657     const RPointerArray<CMceMediaStream>& aAudioStreams ) const
       
  1658     {
       
  1659     SVPDEBUG1( "CSVPEmergencySession::CheckMmfPrioritiesForDtmfL In" )
       
  1660     
       
  1661     RPointerArray<CMceMediaSource> micsToEnable;
       
  1662     CleanupClosePushL( micsToEnable );
       
  1663     const TInt streamCount( aAudioStreams.Count() );
       
  1664     
       
  1665     // First disable the mic before doing any priority updating.
       
  1666     for ( TInt s = 0; s < streamCount; s++ )
       
  1667         {
       
  1668         CMceMediaSource* mic = aAudioStreams[s]->Source();
       
  1669         
       
  1670         if ( mic && KMceMicSource == mic->Type() && mic->IsEnabled() )
       
  1671             {
       
  1672             mic->DisableL();
       
  1673             micsToEnable.AppendL( mic );
       
  1674             }
       
  1675         mic = NULL;
       
  1676         
       
  1677         if ( aAudioStreams[s]->BoundStream() )
       
  1678             {
       
  1679             mic = aAudioStreams[s]->BoundStreamL().Source();
       
  1680             if ( mic && KMceMicSource == mic->Type() && mic->IsEnabled() )
       
  1681                 {
       
  1682                 mic->DisableL();
       
  1683                 micsToEnable.AppendL( mic );
       
  1684                 }
       
  1685             }
       
  1686         mic = NULL;
       
  1687         }
       
  1688     
       
  1689     // Set the correct priority and preference values.
       
  1690     for ( TInt k = 0; k < streamCount; k++ )
       
  1691         {
       
  1692         if ( KMceAudio == aAudioStreams[k]->Type() && 
       
  1693             aAudioStreams[k]->BoundStream() )
       
  1694             {
       
  1695             CMceAudioStream* stream = 
       
  1696                 static_cast<CMceAudioStream*>( aAudioStreams[k] );
       
  1697             
       
  1698             TBool dtmfMode = EFalse;
       
  1699             if ( SVPAudioUtility::IsDownlinkStream( *stream ) )
       
  1700                 {
       
  1701                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL( 
       
  1702                     *stream,
       
  1703                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ) );
       
  1704                 }
       
  1705             else
       
  1706                 {
       
  1707                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL(
       
  1708                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ),
       
  1709                     *stream );
       
  1710                 }
       
  1711             
       
  1712             iSVPUtility.SetDtmfMode( dtmfMode );
       
  1713             }
       
  1714         }
       
  1715         
       
  1716     // Priorities are now correct, so update the session.
       
  1717     iEmergencySession->UpdateL();
       
  1718     
       
  1719     // Now enable mics after we have correct priorities.
       
  1720     const TInt mics = micsToEnable.Count();
       
  1721     for ( TInt t = 0; t < mics; t++ )
       
  1722         {
       
  1723         micsToEnable[t]->EnableL();
       
  1724         }
       
  1725     
       
  1726     // Mics not owned
       
  1727     CleanupStack::PopAndDestroy( &micsToEnable );
       
  1728     
       
  1729     SVPDEBUG1( "CSVPEmergencySession::CheckMmfPrioritiesForDtmfL Out" )
       
  1730     }
       
  1731 
       
  1732 // ---------------------------------------------------------------------------
       
  1733 // CSVPEmergencySession::StartTimerL
       
  1734 // ---------------------------------------------------------------------------
       
  1735 //
       
  1736 void CSVPEmergencySession::StartTimerL( TInt aMilliSeconds, TInt aTimerId )
       
  1737     {
       
  1738     CSVPTimer* timer = CSVPTimer::NewL( *this, aTimerId );
       
  1739     timer->SetTime( aMilliSeconds );
       
  1740     iTimers.Append( timer );
       
  1741     }
       
  1742 
       
  1743 // ---------------------------------------------------------------------------
       
  1744 // Stop timer
       
  1745 // ---------------------------------------------------------------------------
       
  1746 //
       
  1747 void CSVPEmergencySession::StopTimer( TInt aTimerId )
       
  1748     {
       
  1749     SVPDEBUG2("CSVPEmergencySession::StopTimer, ID: %d", aTimerId)
       
  1750 
       
  1751     for ( TInt i = 0; i < iTimers.Count(); )
       
  1752         {
       
  1753         if ( aTimerId == iTimers[i]->Id() )
       
  1754             {
       
  1755             iTimers[i]->Stop();
       
  1756             delete iTimers[i];
       
  1757             iTimers.Remove( i );
       
  1758             }
       
  1759         else
       
  1760             {
       
  1761             i++;
       
  1762             }
       
  1763         }
       
  1764     }
       
  1765 
       
  1766 // ---------------------------------------------------------------------------
       
  1767 // CSVPEmergencySession::StopTimers
       
  1768 // ---------------------------------------------------------------------------
       
  1769 //
       
  1770 void CSVPEmergencySession::StopTimers()
       
  1771     {
       
  1772     SVPDEBUG1("CSVPEmergencySession::StopTimers")
       
  1773     
       
  1774     while ( iTimers.Count() )
       
  1775         {
       
  1776         iTimers[0]->Stop();
       
  1777         delete iTimers[0];
       
  1778         iTimers.Remove( 0 );   
       
  1779         }
       
  1780     }
       
  1781 
       
  1782 // ---------------------------------------------------------------------------
       
  1783 // Notify client about an error
       
  1784 // ---------------------------------------------------------------------------
       
  1785 //
       
  1786 void CSVPEmergencySession::ErrorOccurred( TCCPError aError )
       
  1787     {
       
  1788     SVPDEBUG2("CSVPEmergencySession::ErrorOccurred: %d", (TInt)aError)
       
  1789     
       
  1790     if ( iIsLastProfile )
       
  1791         {
       
  1792         iEmergencyObserver->ErrorOccurred( ECCPEmergencyFailed, NULL );
       
  1793         }
       
  1794     else
       
  1795         {
       
  1796         iEmergencyObserver->ErrorOccurred( aError, NULL );
       
  1797         }
       
  1798     }
       
  1799 
       
  1800 // ---------------------------------------------------------------------------
       
  1801 // Traps leaves of RequestPositionL
       
  1802 // ---------------------------------------------------------------------------
       
  1803 //
       
  1804 void CSVPEmergencySession::RequestPosition( TUint32 aIapId )
       
  1805     {
       
  1806     SVPDEBUG1( "CSVPEmergencySession::RequestPosition" )
       
  1807     iIsLIRequestReady = EFalse;
       
  1808     TRAP_IGNORE( RequestPositionL( aIapId ) );
       
  1809     }
       
  1810 
       
  1811 // ---------------------------------------------------------------------------
       
  1812 // Initializes position provider and requests for position information
       
  1813 // ---------------------------------------------------------------------------
       
  1814 //
       
  1815 void CSVPEmergencySession::RequestPositionL( TUint32 aIapId )
       
  1816     {
       
  1817     iPositioningProvider = CSVPPositioningProvider::NewL( 
       
  1818         KSVPEmergencyPositioningPriority, *this );
       
  1819     if ( iPositioningProvider )
       
  1820         {
       
  1821         iPositioningProvider->OpenModuleL( 
       
  1822             KSVPEmergencyDhcpDefaultPsyModuleId );
       
  1823         iPositioningProvider->MakePositioningRequestL( 
       
  1824             aIapId, 
       
  1825             KSVPEmergencyApplicationName, 
       
  1826             KSVPEmergencyPositioningTimeout );
       
  1827         }
       
  1828     }
       
  1829 
       
  1830 // ---------------------------------------------------------------------------
       
  1831 // Parses content ID from URI: removes "sip(s):" prefix, if one exists
       
  1832 // ---------------------------------------------------------------------------
       
  1833 //
       
  1834 HBufC8* CSVPEmergencySession::ParseContentIdL( const TDesC8& aUri )
       
  1835     {
       
  1836     HBufC8* contentId = HBufC8::NewLC( aUri.Length() ); // CS:1
       
  1837     ( contentId->Des() ).Copy( aUri );
       
  1838     if ( 0 == contentId->Find( KSVPSipPrefix ) )
       
  1839         {
       
  1840         contentId->Des().Delete( 0, KSVPSipPrefixLength );
       
  1841         }
       
  1842     else if ( 0 == contentId->Find( KSVPSipsPrefix ) )
       
  1843         {
       
  1844         contentId->Des().Delete( 0, KSVPSipsPrefixLength );
       
  1845         }
       
  1846     CleanupStack::Pop( contentId ); // CS:0
       
  1847     contentId = contentId->ReAllocL( contentId->Length() );
       
  1848     return contentId;
       
  1849     }
       
  1850 
       
  1851 // ---------------------------------------------------------------------------
       
  1852 // Parses cid: adds "cid:" prefix and brackets
       
  1853 // ---------------------------------------------------------------------------
       
  1854 //
       
  1855 HBufC8* CSVPEmergencySession::ParseCidL( const TDesC8& aContentId )
       
  1856     {
       
  1857     HBufC8* cid = HBufC8::NewL( 
       
  1858         KSVPLeftBracketMark().Length() + 
       
  1859         KSVPCidPrefix().Length() + 
       
  1860         aContentId.Length() + 
       
  1861         KSVPRightBracketMark().Length() );
       
  1862 
       
  1863     TPtr8 cidPtr = cid->Des();
       
  1864     cidPtr.Copy( KSVPLeftBracketMark() );
       
  1865     cidPtr.Append( KSVPCidPrefix() );
       
  1866     cidPtr.Append( aContentId );
       
  1867     cidPtr.Append( KSVPRightBracketMark() );
       
  1868     
       
  1869     return cid;
       
  1870     }