sipvoipprovider/src/svpemergencysession.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
equal deleted inserted replaced
20:65a3ef1d5bd0 21:f742655b05bf
     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     else if ( CMceMediaStream::EStreaming == aStream.State() )
       
   457         {
       
   458         SVPDEBUG1("CSVPEmergencySession::StreamStateChanged() - EStreaming")
       
   459         StopTimer( KSVPRemoteEndDiedExpired );
       
   460         }
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // Handle incoming request, i.e. hold
       
   465 // ---------------------------------------------------------------------------
       
   466 //
       
   467 void CSVPEmergencySession::IncomingRequestL( 
       
   468     CMceInSession* aUpdatedSession, TMceTransactionDataContainer aContainer )
       
   469     {
       
   470     SVPDEBUG1("CSVPEmergencySession::IncomingRequest() In")
       
   471 
       
   472     if ( !aUpdatedSession )
       
   473         {
       
   474         User::Leave( KErrArgument );
       
   475         }
       
   476 
       
   477     // Create hold controller
       
   478     if ( NULL == iHoldController )
       
   479         {
       
   480         iHoldController = CSVPHoldController::NewL( 
       
   481             *iEmergencySession,
       
   482             aContainer,
       
   483             this,
       
   484             ETrue );
       
   485         }
       
   486 
       
   487     iEmergencySession = aUpdatedSession;
       
   488 
       
   489     User::LeaveIfError( iHoldController->IncomingRequest( aUpdatedSession ) );
       
   490     }
       
   491 
       
   492 // ---------------------------------------------------------------------------
       
   493 // Returns ETrue, if hold controller exists
       
   494 // ---------------------------------------------------------------------------
       
   495 //
       
   496 TBool CSVPEmergencySession::HasHoldController() const
       
   497     {
       
   498     if ( iHoldController )
       
   499         {
       
   500         return ETrue;
       
   501         }
       
   502     else
       
   503         {
       
   504         return EFalse;
       
   505         }
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // Returns reference to hold controller
       
   510 // ---------------------------------------------------------------------------
       
   511 //    
       
   512 CSVPHoldController& CSVPEmergencySession::HoldController() const
       
   513     {
       
   514     return *iHoldController;
       
   515     }
       
   516 
       
   517 // ---------------------------------------------------------------------------
       
   518 // Handles hold session state changes
       
   519 // ---------------------------------------------------------------------------
       
   520 //
       
   521 void CSVPEmergencySession::HoldSessionStateChangedL( CMceSession& aSession )
       
   522     {
       
   523     SVPDEBUG1("CSVPEmergencySession::HoldSessionStateChangedL() In")
       
   524     
       
   525     if ( NULL == iHoldController )
       
   526         {
       
   527         User::Leave( KErrNotFound );
       
   528         }
       
   529 
       
   530     if ( iHoldController->HoldInProgress() )
       
   531         {
       
   532         SVPDEBUG1(
       
   533             "CSVPEmergencySession::HoldSessionStateChangedL, in progress")
       
   534         StopTimers();
       
   535         if ( iHoldController->ContinueHoldProcessing( aSession ) )
       
   536             {
       
   537             iEmergencyObserver->ErrorOccurred( ECCPLocalHoldFail, NULL );
       
   538             }
       
   539         }
       
   540 
       
   541     SVPDEBUG1("CSVPEmergencySession::HoldSessionStateChangedL() Out")
       
   542     }
       
   543 
       
   544 // ---------------------------------------------------------------------------
       
   545 // Returns DTMF observer
       
   546 // ---------------------------------------------------------------------------
       
   547 //
       
   548 const MCCPDTMFObserver& CSVPEmergencySession::DtmfObserver()
       
   549     {
       
   550     return *iDtmfObserver;
       
   551     }
       
   552 
       
   553 // ---------------------------------------------------------------------------
       
   554 // Sets DTMF observer
       
   555 // ---------------------------------------------------------------------------
       
   556 //
       
   557 void CSVPEmergencySession::SetDtmfObserver( 
       
   558     const MCCPDTMFObserver& aObserver )
       
   559     {
       
   560     SVPDEBUG1("CSVPEmergencySession::SetDtmfObserver()")
       
   561     
       
   562     iDtmfObserver = const_cast<MCCPDTMFObserver*>( &aObserver );
       
   563     }
       
   564 
       
   565 // ---------------------------------------------------------------------------
       
   566 // Starts DTMF tone
       
   567 // ---------------------------------------------------------------------------
       
   568 //
       
   569 TInt CSVPEmergencySession::StartDtmfTone( const TChar aTone )
       
   570     {
       
   571     SVPDEBUG1("CSVPEmergencySession::StartDtmfTone() In")
       
   572     
       
   573     TInt dtmfErr( KErrNone );
       
   574     if ( iSVPUtility.GetDTMFMode() )
       
   575         {
       
   576         const RPointerArray<CMceMediaStream>& streams = 
       
   577             iEmergencySession->Streams();
       
   578         TInt count = streams.Count();
       
   579         while ( count )
       
   580             {
       
   581             count--;
       
   582             CMceMediaStream& mediaStream = *streams[ count ];
       
   583             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   584                 {
       
   585                 TRAP( dtmfErr, mediaStream.Source()->StartDtmfToneL( aTone ) )
       
   586                 }
       
   587             else
       
   588                 {
       
   589                 dtmfErr = KErrNotSupported;
       
   590                 }
       
   591             
       
   592             if ( KErrNone != dtmfErr )
       
   593                 {
       
   594                 SVPDEBUG2("CSVPEmergencySession::StartDtmfToneL dtmfErr: %d",
       
   595                     dtmfErr)
       
   596                 return dtmfErr;
       
   597                 }
       
   598             }
       
   599         }
       
   600     else
       
   601         {
       
   602         iDtmfTone = aTone;
       
   603         DtmfObserver().HandleDTMFEvent( MCCPDTMFObserver::ECCPDtmfManualStart, 
       
   604                                         KErrNone, 
       
   605                                         aTone );
       
   606         }
       
   607     SVPDEBUG1("CSVPEmergencySession::StartDtmfTone() Out")
       
   608     return dtmfErr;
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // Stops DTMF tone
       
   613 // ---------------------------------------------------------------------------
       
   614 //
       
   615 TInt CSVPEmergencySession::StopDtmfTone()
       
   616     {
       
   617     SVPDEBUG1("CSVPEmergencySession::StopDtmfTone() In")
       
   618     
       
   619     TInt dtmfErr( KErrNone );
       
   620     if ( iSVPUtility.GetDTMFMode() )
       
   621         {
       
   622         const RPointerArray<CMceMediaStream>& streams = 
       
   623             iEmergencySession->Streams();
       
   624         TInt count = streams.Count();
       
   625         while( count )
       
   626             {
       
   627             count--;
       
   628             CMceMediaStream& mediaStream = *streams[ count ];
       
   629             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   630                 {
       
   631                 TRAP( dtmfErr, mediaStream.Source()->StopDtmfToneL() )
       
   632                 }
       
   633             // NOP with inband.
       
   634             
       
   635             if ( KErrNone != dtmfErr )
       
   636                 {
       
   637                 SVPDEBUG2("CSVPEmergencySession::StopDtmfTone dtmfErr: %d",
       
   638                     dtmfErr)
       
   639                 
       
   640                 return dtmfErr;
       
   641                 }
       
   642             }
       
   643         }
       
   644     else
       
   645         {
       
   646         DtmfObserver().HandleDTMFEvent( MCCPDTMFObserver::ECCPDtmfManualStop, 
       
   647                                         KErrNone, 
       
   648                                         iDtmfTone );
       
   649         }
       
   650     SVPDEBUG1("CSVPEmergencySession::StopDtmfTone() Out")
       
   651     return dtmfErr;
       
   652     }
       
   653 
       
   654 // ---------------------------------------------------------------------------
       
   655 // Sends DTMF tone string
       
   656 // ---------------------------------------------------------------------------
       
   657 //
       
   658 TInt CSVPEmergencySession::SendDtmfToneString( const TDesC& aString )
       
   659     {
       
   660     SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString() In")
       
   661     
       
   662     TInt error( KErrNone );
       
   663 
       
   664     TChar dtmfPause('p');
       
   665     // MCE calls if outband DTMF.
       
   666     // Exception is character 'p' which is handled always locally
       
   667     if ( !iSVPUtility.GetDTMFMode() ||
       
   668         ( aString.Length() == 1 &&
       
   669           dtmfPause == aString[0] ) )   
       
   670         {
       
   671         delete iDtmfString;
       
   672         iDtmfString = NULL;
       
   673         TRAP( error, iDtmfString = HBufC::NewL( aString.Length() ) );
       
   674         if ( KErrNone != error )
       
   675             {
       
   676             return error;
       
   677             }
       
   678                        
       
   679         *iDtmfString = aString;
       
   680         iDtmfLex.Assign( *iDtmfString );
       
   681         
       
   682         SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString, inband")
       
   683         if ( !iDTMFEventGenerator )
       
   684             {
       
   685             TRAP( error,
       
   686             iDTMFEventGenerator = CSVPDTMFEventGenerator::NewL( *this ) );
       
   687             }
       
   688         
       
   689         if ( KErrNone != error )
       
   690             {
       
   691             return error;    
       
   692             }
       
   693         
       
   694         // Dtmf pause interval is 2.5s
       
   695         TBool pauseChar = ( aString.Length() == 1 && 
       
   696                             dtmfPause == aString[0] ); 
       
   697         // start events
       
   698         iDTMFEventGenerator->StartDtmfEvents( aString.Length(), pauseChar );
       
   699         }
       
   700     else
       
   701         {
       
   702         SVPDEBUG1("CSVPEmergencySession::SendDtmfToneString, outband")
       
   703         
       
   704         const RPointerArray<CMceMediaStream>& streams = 
       
   705             iEmergencySession->Streams();
       
   706         TInt count = streams.Count();
       
   707         while( count && KErrNone == error )
       
   708             {
       
   709             count--;
       
   710             CMceMediaStream& mediaStream = *streams[ count ];
       
   711             if ( SVPAudioUtility::DtmfActionCapableStream( mediaStream ) )
       
   712                 {
       
   713                 TRAP( error, mediaStream.Source()->SendDtmfToneSequenceL( 
       
   714                     aString ) )
       
   715                 }
       
   716             else
       
   717                 {
       
   718                 error = KErrNotSupported;
       
   719                 }
       
   720             }
       
   721         }
       
   722 
       
   723     SVPDEBUG2("CSVPEmergencySession::SendDtmfToneString, error: %d", error)
       
   724     return error;
       
   725     }
       
   726 
       
   727 // ---------------------------------------------------------------------------
       
   728 // Cancels DTMF tone string sending
       
   729 // ---------------------------------------------------------------------------
       
   730 //
       
   731 TInt CSVPEmergencySession::CancelDtmfStringSending()
       
   732     {
       
   733     SVPDEBUG1("CSVPEmergencySession::CancelDtmfStringSending() In")
       
   734     
       
   735     TInt error( KErrNone );
       
   736     if ( !iSVPUtility.GetDTMFMode() ) 
       
   737         {
       
   738         error = KErrNotFound;
       
   739         if ( iDTMFEventGenerator )
       
   740             {
       
   741             iDTMFEventGenerator->StopEvents();
       
   742             error = KErrNone;
       
   743             }
       
   744         }
       
   745     else 
       
   746         {
       
   747         SVPDEBUG1("CSVPEmergencySession::CancelDtmfStringSending, outband")
       
   748         error = KErrNotSupported;
       
   749         }
       
   750 
       
   751     SVPDEBUG2("CSVPEmergencySession::CancelDtmfStringSending, error: %d", 
       
   752         error)
       
   753     return error;
       
   754     }
       
   755 
       
   756 // ---------------------------------------------------------------------------
       
   757 // CSVPEmergencySession::Dial
       
   758 // ---------------------------------------------------------------------------
       
   759 //
       
   760 TInt CSVPEmergencySession::Dial( const TDesC& /*aRecipient*/ )
       
   761     {
       
   762     SVPDEBUG1("CSVPEmergencySession::Dial()")
       
   763 
       
   764     if ( iIsDummy )
       
   765         {
       
   766         SVPDEBUG1("CSVPEmergencySession::Dial, dummy session")
       
   767         ErrorOccurred( ECCPErrorGeneral );
       
   768         return KErrNone;
       
   769         }
       
   770 
       
   771     iIsDialed = ETrue;
       
   772     ProceedDial();
       
   773 
       
   774     iEmergencyObserver->CallStateChanged( 
       
   775         MCCPCallObserver::ECCPStateDialling, NULL );
       
   776 
       
   777     return KErrNone;
       
   778     }
       
   779 
       
   780 // ---------------------------------------------------------------------------
       
   781 // CSVPEmergencySession::Cancel
       
   782 // ---------------------------------------------------------------------------
       
   783 //
       
   784 TInt CSVPEmergencySession::Cancel()
       
   785     {
       
   786     SVPDEBUG1("CSVPEmergencySession::Cancel()")
       
   787     
       
   788     TInt error( KErrNone );    
       
   789     if ( iEmergencySession )
       
   790         {
       
   791         TRAP( error, ( ( CMceOutSession* )iEmergencySession )->CancelL() )
       
   792         if ( error )
       
   793             {
       
   794             SVPDEBUG2("CSVPEmergencySession::Cancel, error: %d", error)
       
   795             iEmergencyObserver->CallStateChanged( 
       
   796                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   797             }
       
   798         }
       
   799     else
       
   800         {
       
   801         iEmergencyObserver->CallStateChanged( 
       
   802             MCCPCallObserver::ECCPStateIdle, NULL );
       
   803         }
       
   804     
       
   805     return error;
       
   806     }
       
   807 
       
   808 // ---------------------------------------------------------------------------
       
   809 // CSVPEmergencySession::HangUp
       
   810 // ---------------------------------------------------------------------------
       
   811 //
       
   812 TInt CSVPEmergencySession::HangUp()
       
   813     {
       
   814     SVPDEBUG1("CSVPEmergencySession::HangUp()")
       
   815 
       
   816     if ( NULL == iEmergencySession )
       
   817         {
       
   818         iEmergencyObserver->CallStateChanged( 
       
   819             MCCPCallObserver::ECCPStateIdle, NULL );
       
   820         return KErrNone;
       
   821         }
       
   822     
       
   823     CMceSession::TState mceState = iEmergencySession->State();
       
   824     SVPDEBUG2("CSVPEmergencySession::HangUp, MCE state: %d", mceState)
       
   825     
       
   826     TInt err( KErrNone );
       
   827 
       
   828     if ( CMceSession::EEstablished == mceState || 
       
   829          CMceSession::EOffering == mceState )
       
   830         {
       
   831         if ( CMceSession::EEstablished == mceState )
       
   832             {
       
   833             TRAP( err, iEmergencySession->TerminateL() )
       
   834             }
       
   835         else // CMceSession::EOffering
       
   836             {
       
   837             err = Cancel();
       
   838             }
       
   839         
       
   840         if ( !err )
       
   841             {
       
   842             iEmergencyObserver->CallStateChanged( 
       
   843                 MCCPCallObserver::ECCPStateDisconnecting, NULL );
       
   844             TRAP_IGNORE( StartTimerL( 
       
   845                 KSVPMoHangupTerminatingTime, KSVPHangUpTimerExpired ) )
       
   846             }   
       
   847         }    
       
   848     else // Wrong MCE state
       
   849         {
       
   850         SVPDEBUG2("CSVPEmergencySession::HangUp, wrong state: %d ", mceState )
       
   851         StopTimers();
       
   852         iEmergencyObserver->CallStateChanged( 
       
   853             MCCPCallObserver::ECCPStateIdle, NULL );
       
   854         }
       
   855     
       
   856     return err;
       
   857     }
       
   858 
       
   859 // ---------------------------------------------------------------------------
       
   860 // CSVPEmergencySession::Answer
       
   861 // ---------------------------------------------------------------------------
       
   862 //
       
   863 TInt CSVPEmergencySession::Answer()
       
   864     {
       
   865     SVPDEBUG1("CSVPEmergencySession::Answer()")
       
   866     return KErrNotSupported;
       
   867     }
       
   868 
       
   869 // ---------------------------------------------------------------------------
       
   870 // CSVPEmergencySession::TimedOut
       
   871 // ---------------------------------------------------------------------------
       
   872 // 
       
   873 void CSVPEmergencySession::TimedOut( TInt aTimerId )
       
   874     {
       
   875     SVPDEBUG1("CSVPEmergencySession::TimedOut()")
       
   876     
       
   877      // Find the timer and delete it.
       
   878     for ( TInt t = 0; t < iTimers.Count(); )
       
   879         {
       
   880         if ( iTimers[t] ->Id() == aTimerId )
       
   881             {
       
   882             delete iTimers[t];
       
   883             iTimers.Remove( t );
       
   884             }
       
   885         else
       
   886             {
       
   887             t++;
       
   888             }
       
   889         }
       
   890 
       
   891     switch ( aTimerId )
       
   892         {
       
   893         case KSVPHangUpTimerExpired:
       
   894             SVPDEBUG1("CSVPEmergencySession::TimedOut, hangup")
       
   895             iEmergencyObserver->CallStateChanged( 
       
   896                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   897             break;
       
   898 
       
   899         case KSVPTerminationTimerExpired:
       
   900             SVPDEBUG1("CSVPEmergencySession::TimedOut, termination")
       
   901             iSessionState = MCCPCallObserver::ECCPStateIdle;
       
   902             iEmergencyObserver->CallStateChanged( State(), NULL );
       
   903             break;
       
   904 
       
   905         case KSVPInviteTimerExpired:
       
   906             SVPDEBUG1("CSVPEmergencySession::TimedOut, invite")
       
   907             // Connection made but no answer, no point trying other profiles
       
   908             ErrorOccurred( ECCPEmergencyFailed );
       
   909             Cancel();
       
   910             iEmergencyObserver->CallStateChanged( 
       
   911                 MCCPCallObserver::ECCPStateDisconnecting, NULL );
       
   912             iEmergencyObserver->CallStateChanged( 
       
   913                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   914             break;
       
   915         
       
   916         case KSVPEmergencyExpired:
       
   917             SVPDEBUG1("CSVPEmergencySession::TimedOut, emergency")
       
   918             ErrorOccurred( ECCPErrorTimedOut );
       
   919             break;
       
   920         
       
   921         case KSVPRemoteEndDiedExpired:
       
   922             SVPDEBUG1("CSVPEmergencySession::TimedOut, remote end died")
       
   923             iEmergencyObserver->CallStateChanged( 
       
   924                 MCCPCallObserver::ECCPStateIdle, NULL );
       
   925             break;
       
   926         
       
   927         default:
       
   928             SVPDEBUG1("CSVPEmergencySession::TimedOut, no timer found")
       
   929             break;
       
   930         }    
       
   931     }
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 // From class MSIPObserver
       
   935 // CSVPEmergencySession::IncomingRequest
       
   936 // ---------------------------------------------------------------------------
       
   937 // 
       
   938 void CSVPEmergencySession::IncomingRequest( 
       
   939     TUint32 /*aIapId*/, CSIPServerTransaction* /*aTransaction*/ )
       
   940     {
       
   941     }
       
   942 
       
   943 // ---------------------------------------------------------------------------
       
   944 // From class MSIPObserver
       
   945 // CSVPEmergencySession::TimedOut
       
   946 // ---------------------------------------------------------------------------
       
   947 //     
       
   948 void CSVPEmergencySession::TimedOut( 
       
   949     CSIPServerTransaction& /*aSIPServerTransaction*/ )
       
   950     {
       
   951     }
       
   952 
       
   953 // ---------------------------------------------------------------------------
       
   954 // From class MSIPProfileRegistryObserver
       
   955 // CSVPEmergencySession::ProfileRegistryErrorOccurred
       
   956 // ---------------------------------------------------------------------------
       
   957 //  
       
   958 void CSVPEmergencySession::ProfileRegistryErrorOccurred( 
       
   959     TUint32 /*aSIPProfileId*/, TInt /*aError*/ )
       
   960     {
       
   961     }
       
   962 
       
   963 // ---------------------------------------------------------------------------
       
   964 // From class MSIPProfileRegistryObserver
       
   965 // CSVPEmergencySession::ProfileRegistryEventOccurred
       
   966 // ---------------------------------------------------------------------------
       
   967 //  
       
   968 void CSVPEmergencySession::ProfileRegistryEventOccurred( 
       
   969     TUint32 /*aProfileId*/, TEvent /*aEvent*/ )
       
   970     {
       
   971     }
       
   972 
       
   973 // ---------------------------------------------------------------------------
       
   974 // From class MSVPPositioningProviderObserver.
       
   975 // Handles successful positioning requests
       
   976 // ---------------------------------------------------------------------------
       
   977 //
       
   978 void CSVPEmergencySession::PositioningRequestComplete( 
       
   979     const TDesC8& aPosition )
       
   980     {
       
   981     SVPDEBUG2("CSVPEmergencySession::PositioningRequestComplete() - \
       
   982      length: %d", aPosition.Length())
       
   983     
       
   984     iIsLIRequestReady = ETrue;
       
   985     
       
   986     delete iPositionInformation;
       
   987     iPositionInformation = NULL;
       
   988     TRAPD( err, iPositionInformation = HBufC8::NewL( aPosition.Length() ) )
       
   989     if ( !err )
       
   990         {
       
   991         ( iPositionInformation->Des() ).Copy( aPosition );
       
   992         }
       
   993 
       
   994     iPositioningProvider->CloseModule();
       
   995     ProceedDial();
       
   996     }
       
   997 
       
   998 // ---------------------------------------------------------------------------
       
   999 // From class MSVPPositioningProviderObserver.
       
  1000 // Handles failed positioning requests
       
  1001 // ---------------------------------------------------------------------------
       
  1002 //
       
  1003 #ifdef _DEBUG
       
  1004 void CSVPEmergencySession::PositioningErrorOccurred( TInt aError )
       
  1005 #else
       
  1006 void CSVPEmergencySession::PositioningErrorOccurred( TInt /*aError*/ )
       
  1007 #endif // _DEBUG
       
  1008     {
       
  1009     SVPDEBUG2("CSVPEmergencySession::PositioningErrorOccurred( %d )", aError)
       
  1010     
       
  1011     iIsLIRequestReady = ETrue;
       
  1012     iPositioningProvider->CloseModule();
       
  1013     ProceedDial();
       
  1014     }
       
  1015 
       
  1016 // ---------------------------------------------------------------------------
       
  1017 // From class MSVPEmergencyConnectionObserver.
       
  1018 // SNAP connection is established
       
  1019 // ---------------------------------------------------------------------------
       
  1020 //
       
  1021 void CSVPEmergencySession::SnapConnected()
       
  1022     {
       
  1023     SVPDEBUG1("CSVPEmergencySession::SnapConnected() In")
       
  1024     
       
  1025     if ( NULL == iEmergencyConnection )
       
  1026         {
       
  1027         SVPDEBUG1("CSVPEmergencySession::SnapConnected, no connection object")
       
  1028         ErrorOccurred( ECCPErrorGeneral );
       
  1029         return;
       
  1030         }
       
  1031     
       
  1032     TInt err = iEmergencyConnection->IapId( iIapId );
       
  1033     SVPDEBUG2("CSVPEmergencySession::ConnectionReady, IAP ID: %d", iIapId)
       
  1034     if ( err )
       
  1035         {
       
  1036         SVPDEBUG2("CSVPEmergencySession::SnapConnected, error: %d", err)
       
  1037         ErrorOccurred( ECCPErrorGeneral );
       
  1038         return;
       
  1039         }
       
  1040 
       
  1041     TRAP( err, CreateUnregistedSessionL() )
       
  1042     if ( err )
       
  1043         {
       
  1044         SVPDEBUG2("CSVPEmergencySession::SnapConnected, error: %d", err)
       
  1045         ErrorOccurred( ECCPErrorGeneral );
       
  1046         return;
       
  1047         }
       
  1048 
       
  1049     // Request for position information
       
  1050     RequestPosition( iIapId );    
       
  1051     
       
  1052     ProceedDial();
       
  1053         
       
  1054     SVPDEBUG1("CSVPEmergencySession::SnapConnected() Out")
       
  1055     }
       
  1056 
       
  1057 // ---------------------------------------------------------------------------
       
  1058 // From class MSVPEmergencyConnectionObserver.
       
  1059 // Connection is established
       
  1060 // ---------------------------------------------------------------------------
       
  1061 //    
       
  1062 void CSVPEmergencySession::Connected()
       
  1063     {
       
  1064     SVPDEBUG1("CSVPEmergencySession::Connected()")
       
  1065     
       
  1066     TRAPD( error, RequestSipProxyAddressL() )
       
  1067     if ( error )
       
  1068         {
       
  1069         SVPDEBUG2("CSVPEmergencySession::Connected, error: %d", error)
       
  1070         ErrorOccurred( ECCPErrorGeneral );
       
  1071         }
       
  1072     }
       
  1073 
       
  1074 // ---------------------------------------------------------------------------
       
  1075 // From class MSVPEmergencyConnectionObserver.
       
  1076 // SIP proxy address ready
       
  1077 // ---------------------------------------------------------------------------
       
  1078 //    
       
  1079 void CSVPEmergencySession::SipProxyAddressReady( const TDesC16& aAddress )
       
  1080     {
       
  1081     SVPDEBUG1("CSVPEmergencySession::SipProxyAddressReady()")
       
  1082     
       
  1083     TRAPD( error, ContinueConstructWithIapIdL( aAddress ) )
       
  1084     if ( error )
       
  1085         {
       
  1086         SVPDEBUG2("CSVPEmergencySession::SipProxyAddressReady, error: %d", 
       
  1087             error)
       
  1088         ErrorOccurred( ECCPErrorGeneral );
       
  1089         }
       
  1090     }
       
  1091 
       
  1092 // ---------------------------------------------------------------------------
       
  1093 // From class MSVPEmergencyConnectionObserver.
       
  1094 // Connection error has occurred
       
  1095 // ---------------------------------------------------------------------------
       
  1096 //
       
  1097 #ifdef _DEBUG
       
  1098 void CSVPEmergencySession::ConnectionError( TInt aError )
       
  1099 #else
       
  1100 void CSVPEmergencySession::ConnectionError( TInt /*aError*/ )
       
  1101 #endif // _DEBUG
       
  1102     {
       
  1103     SVPDEBUG2("CSVPEmergencySession::ConnectionError, error: %d", aError)
       
  1104     
       
  1105     ErrorOccurred( ECCPErrorGeneral );
       
  1106     }
       
  1107 
       
  1108 // ---------------------------------------------------------------------------
       
  1109 // From class MSVPHoldObserver.
       
  1110 // Local hold
       
  1111 // ---------------------------------------------------------------------------
       
  1112 //
       
  1113 void CSVPEmergencySession::SessionLocallyHeld()
       
  1114     {
       
  1115     SVPDEBUG1("CSVPEmergencySession::SessionLocallyHeld()")
       
  1116     iEmergencyObserver->CallStateChanged( MCCPCallObserver::ECCPStateHold, 
       
  1117                                           NULL );
       
  1118     }
       
  1119 
       
  1120 // ---------------------------------------------------------------------------
       
  1121 // From class MSVPHoldObserver.
       
  1122 // Local resume
       
  1123 // ---------------------------------------------------------------------------
       
  1124 //
       
  1125 void CSVPEmergencySession::SessionLocallyResumed()
       
  1126     {
       
  1127     SVPDEBUG1("CSVPEmergencySession::SessionLocallyResumed()")
       
  1128     iEmergencyObserver->CallStateChanged( 
       
  1129         MCCPCallObserver::ECCPStateConnected, NULL );
       
  1130     }
       
  1131 
       
  1132 // ---------------------------------------------------------------------------
       
  1133 // From class MSVPHoldObserver.
       
  1134 // Remote hold
       
  1135 // ---------------------------------------------------------------------------
       
  1136 //
       
  1137 void CSVPEmergencySession::SessionRemoteHeld()
       
  1138     {
       
  1139     SVPDEBUG1("CSVPEmergencySession::SessionRemoteHeld()")
       
  1140     iEmergencyObserver->CallEventOccurred( MCCPCallObserver::ECCPRemoteHold, 
       
  1141                                            NULL );
       
  1142     }
       
  1143 
       
  1144 // ---------------------------------------------------------------------------
       
  1145 // From class MSVPHoldObserver.
       
  1146 // Remote resume
       
  1147 // ---------------------------------------------------------------------------
       
  1148 //
       
  1149 void CSVPEmergencySession::SessionRemoteResumed()
       
  1150     {
       
  1151     SVPDEBUG1("CSVPEmergencySession::SessionRemoteResumed()")
       
  1152     iEmergencyObserver->CallEventOccurred( 
       
  1153         MCCPCallObserver::ECCPRemoteResume, NULL );
       
  1154     }
       
  1155 
       
  1156 // ---------------------------------------------------------------------------
       
  1157 // From class MSVPHoldObserver.
       
  1158 // Hold request failed
       
  1159 // ---------------------------------------------------------------------------
       
  1160 //
       
  1161 void CSVPEmergencySession::HoldRequestFailed()
       
  1162     {
       
  1163     SVPDEBUG1("CSVPEmergencySession::HoldRequestFailed()")
       
  1164     iEmergencyObserver->ErrorOccurred( ECCPLocalHoldFail, NULL );
       
  1165     }
       
  1166 
       
  1167 // ---------------------------------------------------------------------------
       
  1168 // From class MSVPHoldObserver.
       
  1169 // Resume request failed
       
  1170 // ---------------------------------------------------------------------------
       
  1171 //
       
  1172 void CSVPEmergencySession::ResumeRequestFailed()
       
  1173     {
       
  1174     SVPDEBUG1("CSVPEmergencySession::ResumeRequestFailed()")
       
  1175     iEmergencyObserver->ErrorOccurred( ECCPLocalResumeFail, NULL );
       
  1176     }
       
  1177 
       
  1178 // ---------------------------------------------------------------------------
       
  1179 // Inband DTMF event occurred
       
  1180 // ---------------------------------------------------------------------------
       
  1181 //   
       
  1182 void CSVPEmergencySession::InbandDtmfEventOccurred( TSVPDtmfEvent aEvent )
       
  1183     {
       
  1184     SVPDEBUG2("CSVPEmergencySession::InbandDtmfEventOccurred(), event:%d", 
       
  1185         aEvent)
       
  1186     
       
  1187     switch ( aEvent )
       
  1188         {
       
  1189         case ESvpDtmfSendStarted:
       
  1190             iDtmfObserver->HandleDTMFEvent( 
       
  1191                 MCCPDTMFObserver::ECCPDtmfSequenceStart, 
       
  1192                 KErrNone, 
       
  1193                 iDtmfLex.Peek() );
       
  1194             break;
       
  1195             
       
  1196         case ESvpDtmfSendStopped:
       
  1197             iDtmfObserver->HandleDTMFEvent( 
       
  1198                 MCCPDTMFObserver::ECCPDtmfSequenceStop, 
       
  1199                 KErrNone, 
       
  1200                 iDtmfLex.Get() );
       
  1201             break;
       
  1202             
       
  1203         case ESvpDtmfSendCompleted:
       
  1204             {
       
  1205             iDtmfObserver->HandleDTMFEvent( 
       
  1206                 MCCPDTMFObserver::ECCPDtmfStringSendingCompleted, 
       
  1207                 KErrNone, 
       
  1208                 iDtmfLex.Peek() );
       
  1209             
       
  1210             // String can be deleted as whole string has been sent 
       
  1211             delete iDtmfString;
       
  1212             iDtmfString = NULL;
       
  1213             
       
  1214             break;
       
  1215             }
       
  1216             
       
  1217         default:
       
  1218             break;
       
  1219         }
       
  1220     
       
  1221     SVPDEBUG1("CSVPEmergencySession::InbandDtmfEventOccurred() Out");
       
  1222     }
       
  1223 
       
  1224 // ---------------------------------------------------------------------------
       
  1225 // Deletes failed MCE session and creates a new one without LI. Used when 
       
  1226 // 415 Unsupported Media Type received.
       
  1227 // ---------------------------------------------------------------------------
       
  1228 //
       
  1229 void CSVPEmergencySession::CreateNonLISessionL()
       
  1230     {
       
  1231     SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL() IN")
       
  1232 
       
  1233     // Save failed emergency session
       
  1234     iFailedEmergencySession = iEmergencySession;
       
  1235     iEmergencySession = NULL;
       
  1236 
       
  1237     // Delete LI
       
  1238     delete iPositionInformation;
       
  1239     iPositionInformation = NULL;
       
  1240     iIsLIRequestReady = ETrue;
       
  1241     
       
  1242     if ( KErrNotFound == iVoipProfileId )
       
  1243         {
       
  1244         // No VoIP profile, trying IAP emergency call
       
  1245         SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL, IAP EC")
       
  1246         CreateUnregistedSessionL();
       
  1247         return;
       
  1248         }
       
  1249     
       
  1250     // Initialize SIP registry
       
  1251     CSIP* sip = CSIP::NewLC( KSVPUid, *this ); // CS:1
       
  1252     CSIPProfileRegistry* sipProfileRegistry = CSIPProfileRegistry::NewLC( 
       
  1253         *sip, *this ); // CS:2
       
  1254 
       
  1255     // Get SIP profile, only one SIP profile per VoIP profile
       
  1256     CSIPProfile* sipProfile = sipProfileRegistry->ProfileL( iSipProfileId );
       
  1257     CleanupStack::PushL( sipProfile ); // CS:3
       
  1258 
       
  1259     // Create MCE out session
       
  1260     TBool registered( EFalse );
       
  1261     sipProfile->GetParameter( KSIPProfileRegistered, registered );
       
  1262     if ( registered )
       
  1263         {
       
  1264         SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL, registered")
       
  1265         iEmergencySession = CMceOutSession::NewL( 
       
  1266             iMceManager, *sipProfile, *iRecipientUri );
       
  1267         ConstructAudioStreamsL();
       
  1268         }
       
  1269     else
       
  1270         {
       
  1271         CreateUnregistedSessionL();        
       
  1272         }
       
  1273     
       
  1274     CleanupStack::PopAndDestroy( 3, sip ); 
       
  1275     // CS:0 sip, sipProfileRegistry, sipProfile
       
  1276 
       
  1277     SVPDEBUG1("CSVPEmergencySession::CreateNonLISessionL() OUT")
       
  1278     }
       
  1279 
       
  1280 // ---------------------------------------------------------------------------
       
  1281 // Creates unregistered MCE session
       
  1282 // ---------------------------------------------------------------------------
       
  1283 //
       
  1284 void CSVPEmergencySession::CreateUnregistedSessionL()
       
  1285     {
       
  1286     SVPDEBUG1("CSVPEmergencySession::CreateUnregistedSessionL()")
       
  1287     
       
  1288     iEmergencySession = CMceOutSession::NewL( 
       
  1289         iMceManager, iIapId, *iUserAor, *iRecipientUri );
       
  1290 
       
  1291     ConstructAudioStreamsL();
       
  1292     }
       
  1293 
       
  1294 // ---------------------------------------------------------------------------
       
  1295 // Handles emergency session state change
       
  1296 // ---------------------------------------------------------------------------
       
  1297 //
       
  1298 void CSVPEmergencySession::SessionStateChangedL( TInt aMceStatusCode )
       
  1299     {
       
  1300     SVPDEBUG3("CSVPEmergencySession::SessionStateChangedL,\
       
  1301      status: %d,state: %d ", aMceStatusCode, iEmergencySession->State() )
       
  1302          
       
  1303     // Match TCCPSessionError
       
  1304     TInt ccpStatusCode = aMceStatusCode;     
       
  1305     TCCPError ccpError = iSVPUtility.GetCCPError( ccpStatusCode, iTone );
       
  1306     
       
  1307     // Call voip event logger with original status
       
  1308     if ( ECCPErrorNone != ccpError && KErrNotFound != iVoipProfileId )
       
  1309         {
       
  1310         iSVPUtility.LogVoipEventL( 
       
  1311             aMceStatusCode, iSipProfileId, KNullDesC, KNullDesC );
       
  1312         }        
       
  1313    
       
  1314     // Status code returns KErrNone if TCCPSessionError is not found
       
  1315     if ( KErrNone != ccpStatusCode )
       
  1316         {
       
  1317         SVPDEBUG2("CSVPEmergencySession::SessionStateChanged:\
       
  1318          error: %d", aMceStatusCode )
       
  1319 
       
  1320         if ( ECCPErrorRejected == ccpError || 
       
  1321              ECCPErrorBusy == ccpError || 
       
  1322              ECCPErrorTimedOut == ccpError )
       
  1323             {     
       
  1324             SVPDEBUG1("CSVPEmergencySession::SessionStateChanged\
       
  1325              iSessionState -> Disconnecting")
       
  1326             iSessionState = MCCPCallObserver::ECCPStateDisconnecting;
       
  1327             }
       
  1328         else if ( KSVPUnsupportedMediaTypeVal == aMceStatusCode && 
       
  1329                   CMceSession::ETerminated == iEmergencySession->State() && 
       
  1330                   iPositionInformation )
       
  1331             {
       
  1332             // MT cannot handle LI: create a new session without LI
       
  1333             CreateNonLISessionL();
       
  1334             ProceedDial();
       
  1335             return;
       
  1336             }
       
  1337 
       
  1338         ErrorOccurred( ccpError );
       
  1339         }
       
  1340     
       
  1341     // Handle provisional responses 1XX
       
  1342     if ( KSVPRingingVal == aMceStatusCode || 
       
  1343          KSVPForwardedVal == aMceStatusCode || 
       
  1344          KSVPQueuedVal == aMceStatusCode || 
       
  1345          KSVPSessionProgressVal == aMceStatusCode )
       
  1346         {        
       
  1347         // Response received, stop emergency timer
       
  1348         StopTimer( KSVPEmergencyExpired );
       
  1349 
       
  1350         if ( KSVPRingingVal == aMceStatusCode )
       
  1351             {
       
  1352             SVPDEBUG1(
       
  1353             "CSVPEmergencySession::SessionStateChanged, 180 Ringing received")
       
  1354             iEmergencyObserver->CallStateChanged( 
       
  1355                 MCCPCallObserver::ECCPStateConnecting, NULL );
       
  1356             }
       
  1357         }
       
  1358 
       
  1359     switch( iEmergencySession->State() )
       
  1360         {
       
  1361         case CMceSession::EEstablished:
       
  1362             {
       
  1363             StopTimers();
       
  1364             
       
  1365             // Save state because it may change while checking priorities
       
  1366             MCCPCallObserver::TCCPCallState ccpState = State();
       
  1367             
       
  1368             if ( SVPAudioUtility::MmfPriorityUpdateNeededL( 
       
  1369                      iEmergencySession->Streams() ) )
       
  1370                 {
       
  1371                 CheckMmfPrioritiesForDtmfL( iEmergencySession->Streams() );
       
  1372                 }
       
  1373             
       
  1374             UpdateKeepAliveL();
       
  1375             
       
  1376             SVPAudioUtility::EnableSpeakerSinksL( 
       
  1377                 iEmergencySession->Streams() );
       
  1378             
       
  1379             iEmergencyObserver->CallStateChanged( ccpState, NULL );
       
  1380             break;
       
  1381             }
       
  1382         case CMceSession::EAnswering:
       
  1383         case CMceSession::EReserving:
       
  1384         case CMceSession::EIncoming:
       
  1385         case CMceSession::EOffering:
       
  1386             {
       
  1387             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged, no action")
       
  1388             break;
       
  1389             }
       
  1390         case CMceSession::ECancelling:
       
  1391         case CMceSession::EIdle:
       
  1392         case CMceSession::ETerminating:
       
  1393         case CMceSession::EProceeding:
       
  1394             {
       
  1395             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged:\
       
  1396              Callback state change")
       
  1397             iEmergencyObserver->CallStateChanged( State(), NULL );
       
  1398             break;
       
  1399             }
       
  1400         case CMceSession::ETerminated:
       
  1401             {
       
  1402             SVPDEBUG1("CSVPEmergencySession::SessionStateChanged, terminated")
       
  1403             iSessionState = MCCPCallObserver::ECCPStateDisconnecting;
       
  1404             StartTimerL( KSVPTerminatingTime, KSVPTerminationTimerExpired );
       
  1405             iEmergencyObserver->CallStateChanged( State(), NULL );
       
  1406             break;
       
  1407             }
       
  1408         default:
       
  1409             {
       
  1410             SVPDEBUG1("CSVPEmergencySession:SessionStateChanged: default")
       
  1411             break;
       
  1412             }
       
  1413         }
       
  1414         
       
  1415     SVPDEBUG1("CSVPEmergencySession::SessionStateChanged Out")
       
  1416     }
       
  1417 
       
  1418 // ---------------------------------------------------------------------------
       
  1419 // Determines if dialing can be proceeded
       
  1420 // ---------------------------------------------------------------------------
       
  1421 //
       
  1422 void CSVPEmergencySession::ProceedDial()
       
  1423     {
       
  1424     SVPDEBUG1("CSVPEmergencySession::ProceedDial()")
       
  1425     
       
  1426     if ( iIsDialed && 
       
  1427          iIsLIRequestReady && 
       
  1428          iEmergencySession &&
       
  1429          iEmergencySession->ConnectionActive() )
       
  1430         {
       
  1431         TRAPD( err, DialL() );
       
  1432         if ( err )
       
  1433             {
       
  1434             SVPDEBUG2("CSVPEmergencySession::ProceedDial(), error: %d", err)
       
  1435             ErrorOccurred( ECCPErrorGeneral );
       
  1436             }
       
  1437         }
       
  1438     }
       
  1439 
       
  1440 // ---------------------------------------------------------------------------
       
  1441 // CSVPEmergencySession::DialL
       
  1442 // ---------------------------------------------------------------------------
       
  1443 //
       
  1444 void CSVPEmergencySession::DialL()
       
  1445     {
       
  1446     SVPDEBUG1("CSVPEmergencySession::DialL()")
       
  1447     
       
  1448     // Add priority header
       
  1449     CDesC8ArrayFlat* headers = new ( ELeave ) CDesC8ArrayFlat( 1 );
       
  1450     CleanupStack::PushL( headers ); // CS:1
       
  1451     headers->AppendL( KSVPEmergencyPriorityEmergency() );
       
  1452     
       
  1453     // Add location related headers
       
  1454     if ( iPositionInformation && iUserAor )
       
  1455         {
       
  1456         // Create content headers
       
  1457         CDesC8ArrayFlat* contentHeaders = new ( ELeave ) CDesC8ArrayFlat( 1 );
       
  1458         CleanupStack::PushL( contentHeaders ); // CS:2
       
  1459 
       
  1460         // Content-ID: alice at atlanta.example.com
       
  1461         HBufC8* contentIdValue = ParseContentIdL( *iUserAor );
       
  1462         CleanupStack::PushL( contentIdValue ); // CS:3
       
  1463 
       
  1464         HBufC8* contentId = HBufC8::NewLC( 
       
  1465             KSVPEmergencyContentIdName().Length() + 
       
  1466             contentIdValue->Length() ); // CS:4
       
  1467         ( contentId->Des() ).Copy( KSVPEmergencyContentIdName() );
       
  1468         ( contentId->Des() ).Append( *contentIdValue );
       
  1469 
       
  1470         contentHeaders->AppendL( *contentId );
       
  1471         CleanupStack::PopAndDestroy( contentId ); // CS:3
       
  1472 
       
  1473         // Geolocation: <cid:alice at atlanta.example.com>;
       
  1474         // inserted-by=alice at atlanta.example.com;recipient=endpoint
       
  1475         HBufC8* cidValue = ParseCidL( *contentIdValue );
       
  1476         CleanupStack::PushL( cidValue ); // CS:4
       
  1477         
       
  1478         HBufC8* geolocation = HBufC8::NewL( 
       
  1479             KSVPEmergencyGeolocation().Length() + 
       
  1480             cidValue->Length() + 
       
  1481             KSVPEmergencyTagInsertedBy().Length() + 
       
  1482             contentIdValue->Length() + 
       
  1483             KSVPEmergencyTagRecipientEndpoint().Length() );
       
  1484         ( geolocation->Des() ).Copy( KSVPEmergencyGeolocation() );
       
  1485         ( geolocation->Des() ).Append( *cidValue );
       
  1486         ( geolocation->Des() ).Append( KSVPEmergencyTagInsertedBy() );
       
  1487         ( geolocation->Des() ).Append( *contentIdValue );
       
  1488         ( geolocation->Des() ).Append( KSVPEmergencyTagRecipientEndpoint() );
       
  1489         
       
  1490         // cidValue, contentIdValue CS:2
       
  1491         CleanupStack::PopAndDestroy( 2, contentIdValue );
       
  1492         CleanupStack::PushL( geolocation ); // CS:3
       
  1493         headers->AppendL( *geolocation );
       
  1494         CleanupStack::PopAndDestroy( geolocation ); // CS:2
       
  1495 
       
  1496         // Accept: application/pidf+xml
       
  1497         headers->AppendL( KSVPEmergencyAcceptApplicationSdp() );
       
  1498 
       
  1499         // Content-Type: application/pidf+xml
       
  1500         HBufC8* contentType = HBufC8::NewLC( 
       
  1501             KSVPEmergencyApplicationPidfXml().Length() ); // CS:3
       
  1502         ( contentType->Des() ).Copy( KSVPEmergencyApplicationPidfXml() );
       
  1503 
       
  1504         // Establish call
       
  1505         ( ( CMceOutSession* )iEmergencySession )->EstablishL( 
       
  1506             iSessionExpires, 
       
  1507             headers, 
       
  1508             contentType, 
       
  1509             iPositionInformation->AllocL(), 
       
  1510             contentHeaders );
       
  1511 
       
  1512         // contentType, contentHeaders, Ownership transferred CS:1
       
  1513         CleanupStack::Pop( 2, contentHeaders );
       
  1514         }
       
  1515     else
       
  1516         {
       
  1517         ( ( CMceOutSession* )iEmergencySession )->EstablishL( 
       
  1518             iSessionExpires, headers );
       
  1519         }
       
  1520     CleanupStack::Pop( headers ); // Ownership transferred, CS:0
       
  1521     
       
  1522     // Start INVITE timer in case remote end does not respond
       
  1523     StartTimerL( KSVPInviteTimer, KSVPInviteTimerExpired );
       
  1524     }
       
  1525 
       
  1526 // ---------------------------------------------------------------------------
       
  1527 // CSVPEmergencySession::ConstructAudioStreamsL
       
  1528 // ---------------------------------------------------------------------------
       
  1529 //  
       
  1530 void CSVPEmergencySession::ConstructAudioStreamsL()
       
  1531     {
       
  1532     SVPDEBUG1( "CSVPEmergencySession::ConstructAudioStreamsL In" )
       
  1533 
       
  1534     // OUT STREAM
       
  1535     CMceAudioStream* audioOutStream = CMceAudioStream::NewLC(); // CS:1
       
  1536     // Set microphone as audio out source, only one source at a time    
       
  1537     CMceMicSource* mic = CMceMicSource::NewLC(); // CS:2
       
  1538     audioOutStream->SetSourceL( mic );
       
  1539     CleanupStack::Pop( mic ); // CS:1
       
  1540     CMceRtpSink* rtpSink = CMceRtpSink::NewLC(); // CS:2
       
  1541 	audioOutStream->AddSinkL( rtpSink );
       
  1542 	CleanupStack::Pop( rtpSink ); // CS:1
       
  1543   
       
  1544     // IN STREAM
       
  1545     CMceAudioStream* audioInStream = CMceAudioStream::NewLC(); // CS:2
       
  1546 	CMceRtpSource* rtpSource = CMceRtpSource::NewLC( 
       
  1547 	    KSvpJitterBufferLength, 
       
  1548 	    KSvpJitterBufferThreshold, 
       
  1549 	    KSvpStandbyTimerInMillisecs ); // CS:3
       
  1550 	audioInStream->SetSourceL( rtpSource );
       
  1551 	CleanupStack::Pop( rtpSource ); // CS:2
       
  1552 	// Set speaker as audio in sink	
       
  1553 	CMceSpeakerSink* speakerSink = CMceSpeakerSink::NewLC(); // CS:3
       
  1554 	audioInStream->AddSinkL( speakerSink );
       
  1555 	CleanupStack::Pop( speakerSink ); // CS:2
       
  1556 
       
  1557 	// Bind "audio out" stream to "audio in" stream
       
  1558 	audioOutStream->BindL( audioInStream );
       
  1559 	CleanupStack::Pop( audioInStream ); // CS: 1
       
  1560 	
       
  1561     iEmergencySession->AddStreamL( audioOutStream );
       
  1562     CleanupStack::Pop( audioOutStream ); // CS: 0
       
  1563     
       
  1564     // Modify QoS preconditions off
       
  1565     iEmergencySession->SetModifierL( 
       
  1566         KMcePreconditions, KMcePreconditionsNotUsed );
       
  1567         
       
  1568     // Modify Old way hold on
       
  1569     iEmergencySession->SetModifierL( 
       
  1570         KMceMediaDirection, KMceMediaDirectionWithAddress );
       
  1571 
       
  1572     SVPDEBUG2("CSVPEmergencySession::ConstructAudioStreamsL, in codecs: %d", 
       
  1573         audioInStream->Codecs().Count())
       
  1574     SVPDEBUG2("CSVPEmergencySession::ConstructAudioStreamsL, out codecs: %d", 
       
  1575         audioOutStream->Codecs().Count())
       
  1576 
       
  1577     // Set keep-alive value
       
  1578     SetKeepAlive();
       
  1579     
       
  1580     // Add codecs to audiostream
       
  1581     iSVPUtility.SetAudioCodecsForEmergencyL( 
       
  1582         *audioInStream, iKeepAlive, iVoipProfileId );
       
  1583     
       
  1584     audioOutStream->SetLocalMediaPortL( audioInStream->LocalMediaPort() );
       
  1585     
       
  1586     iSVPUtility.UpdateJitterBufferSizeL( *rtpSource );
       
  1587     
       
  1588     // Set MMF priorities and preferences to codecs
       
  1589     iSVPUtility.SetDtmfMode( SVPAudioUtility::SetPriorityCodecValuesL( 
       
  1590         *audioInStream, *audioOutStream ) );
       
  1591                                          
       
  1592     SVPDEBUG1( "CSVPEmergencySession::ConstructAudioStreamsL Out" )
       
  1593     }
       
  1594 
       
  1595 // ---------------------------------------------------------------------------
       
  1596 // Sets keep-alive value
       
  1597 // ---------------------------------------------------------------------------
       
  1598 //  
       
  1599 void CSVPEmergencySession::SetKeepAlive()
       
  1600     {
       
  1601     SVPDEBUG1("CSVPEmergencySession::SetKeepAlive()")
       
  1602     
       
  1603     // Get keep-alive value, do not leave: return default value instead
       
  1604     TBool found( EFalse );
       
  1605     TRAPD( errKeepAlive, 
       
  1606         found = iSVPUtility.GetKeepAliveByIapIdL( iIapId, iKeepAlive ) )
       
  1607     if ( errKeepAlive || !found )
       
  1608         {
       
  1609         TRAP( errKeepAlive, found = iSVPUtility.GetKeepAliveByAORL( 
       
  1610             *iUserAor, iKeepAlive ) )
       
  1611         if ( errKeepAlive || !found )
       
  1612             {
       
  1613             iKeepAlive = KSVPDefaultUDPRefreshInterval;
       
  1614             }
       
  1615         }
       
  1616     
       
  1617     SVPDEBUG2("CSVPEmergencySession::KeepAlive, value: %d", iKeepAlive)
       
  1618     }
       
  1619 
       
  1620 // ---------------------------------------------------------------------------
       
  1621 // Updates keepalive parameters for MCE session
       
  1622 // ---------------------------------------------------------------------------
       
  1623 //
       
  1624 void CSVPEmergencySession::UpdateKeepAliveL()
       
  1625     {
       
  1626     SVPDEBUG1("CSVPEmergencySession::UpdateKeepAliveL()")
       
  1627     
       
  1628     const RPointerArray<CMceMediaStream>& streamArray = 
       
  1629         iEmergencySession->Streams();
       
  1630     TInt streamCount( streamArray.Count() );
       
  1631     TBool cnInAnswer( EFalse );
       
  1632     
       
  1633     for ( TInt i = 0; i < streamCount; i++ )
       
  1634         {
       
  1635         CMceAudioStream* stream = 
       
  1636             static_cast<CMceAudioStream*>( streamArray[i] );
       
  1637         if ( iSVPUtility.IsComfortNoise( *stream ) )
       
  1638             {
       
  1639             cnInAnswer = ETrue;
       
  1640             iSVPUtility.SetCNKeepAliveL( *stream, iKeepAlive );
       
  1641             }
       
  1642         }
       
  1643     
       
  1644     if ( !cnInAnswer )
       
  1645         {
       
  1646         while( streamCount-- )
       
  1647             {
       
  1648             CMceAudioStream* stream = 
       
  1649                 static_cast<CMceAudioStream*>( streamArray[streamCount] );
       
  1650             iSVPUtility.SetKeepAliveL( *stream, iKeepAlive );
       
  1651             }
       
  1652         }
       
  1653     
       
  1654     iEmergencySession->UpdateL();
       
  1655     }
       
  1656 
       
  1657 // ---------------------------------------------------------------------------
       
  1658 // Check audio priorities in audio streams
       
  1659 // ---------------------------------------------------------------------------
       
  1660 //
       
  1661 void CSVPEmergencySession::CheckMmfPrioritiesForDtmfL(
       
  1662     const RPointerArray<CMceMediaStream>& aAudioStreams ) const
       
  1663     {
       
  1664     SVPDEBUG1( "CSVPEmergencySession::CheckMmfPrioritiesForDtmfL In" )
       
  1665     
       
  1666     RPointerArray<CMceMediaSource> micsToEnable;
       
  1667     CleanupClosePushL( micsToEnable );
       
  1668     const TInt streamCount( aAudioStreams.Count() );
       
  1669     
       
  1670     // First disable the mic before doing any priority updating.
       
  1671     for ( TInt s = 0; s < streamCount; s++ )
       
  1672         {
       
  1673         CMceMediaSource* mic = aAudioStreams[s]->Source();
       
  1674         
       
  1675         if ( mic && KMceMicSource == mic->Type() && mic->IsEnabled() )
       
  1676             {
       
  1677             mic->DisableL();
       
  1678             micsToEnable.AppendL( mic );
       
  1679             }
       
  1680         mic = NULL;
       
  1681         
       
  1682         if ( aAudioStreams[s]->BoundStream() )
       
  1683             {
       
  1684             mic = aAudioStreams[s]->BoundStreamL().Source();
       
  1685             if ( mic && KMceMicSource == mic->Type() && mic->IsEnabled() )
       
  1686                 {
       
  1687                 mic->DisableL();
       
  1688                 micsToEnable.AppendL( mic );
       
  1689                 }
       
  1690             }
       
  1691         mic = NULL;
       
  1692         }
       
  1693     
       
  1694     // Set the correct priority and preference values.
       
  1695     for ( TInt k = 0; k < streamCount; k++ )
       
  1696         {
       
  1697         if ( KMceAudio == aAudioStreams[k]->Type() && 
       
  1698             aAudioStreams[k]->BoundStream() )
       
  1699             {
       
  1700             CMceAudioStream* stream = 
       
  1701                 static_cast<CMceAudioStream*>( aAudioStreams[k] );
       
  1702             
       
  1703             TBool dtmfMode = EFalse;
       
  1704             if ( SVPAudioUtility::IsDownlinkStream( *stream ) )
       
  1705                 {
       
  1706                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL( 
       
  1707                     *stream,
       
  1708                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ) );
       
  1709                 }
       
  1710             else
       
  1711                 {
       
  1712                 dtmfMode = SVPAudioUtility::SetPriorityCodecValuesL(
       
  1713                     static_cast<CMceAudioStream&>( stream->BoundStreamL() ),
       
  1714                     *stream );
       
  1715                 }
       
  1716             
       
  1717             iSVPUtility.SetDtmfMode( dtmfMode );
       
  1718             }
       
  1719         }
       
  1720         
       
  1721     // Priorities are now correct, so update the session.
       
  1722     iEmergencySession->UpdateL();
       
  1723     
       
  1724     // Now enable mics after we have correct priorities.
       
  1725     const TInt mics = micsToEnable.Count();
       
  1726     for ( TInt t = 0; t < mics; t++ )
       
  1727         {
       
  1728         micsToEnable[t]->EnableL();
       
  1729         }
       
  1730     
       
  1731     // Mics not owned
       
  1732     CleanupStack::PopAndDestroy( &micsToEnable );
       
  1733     
       
  1734     SVPDEBUG1( "CSVPEmergencySession::CheckMmfPrioritiesForDtmfL Out" )
       
  1735     }
       
  1736 
       
  1737 // ---------------------------------------------------------------------------
       
  1738 // CSVPEmergencySession::StartTimerL
       
  1739 // ---------------------------------------------------------------------------
       
  1740 //
       
  1741 void CSVPEmergencySession::StartTimerL( TInt aMilliSeconds, TInt aTimerId )
       
  1742     {
       
  1743     CSVPTimer* timer = CSVPTimer::NewL( *this, aTimerId );
       
  1744     timer->SetTime( aMilliSeconds );
       
  1745     iTimers.Append( timer );
       
  1746     }
       
  1747 
       
  1748 // ---------------------------------------------------------------------------
       
  1749 // Stop timer
       
  1750 // ---------------------------------------------------------------------------
       
  1751 //
       
  1752 void CSVPEmergencySession::StopTimer( TInt aTimerId )
       
  1753     {
       
  1754     SVPDEBUG2("CSVPEmergencySession::StopTimer, ID: %d", aTimerId)
       
  1755 
       
  1756     for ( TInt i = 0; i < iTimers.Count(); )
       
  1757         {
       
  1758         if ( aTimerId == iTimers[i]->Id() )
       
  1759             {
       
  1760             iTimers[i]->Stop();
       
  1761             delete iTimers[i];
       
  1762             iTimers.Remove( i );
       
  1763             }
       
  1764         else
       
  1765             {
       
  1766             i++;
       
  1767             }
       
  1768         }
       
  1769     }
       
  1770 
       
  1771 // ---------------------------------------------------------------------------
       
  1772 // CSVPEmergencySession::StopTimers
       
  1773 // ---------------------------------------------------------------------------
       
  1774 //
       
  1775 void CSVPEmergencySession::StopTimers()
       
  1776     {
       
  1777     SVPDEBUG1("CSVPEmergencySession::StopTimers")
       
  1778     
       
  1779     while ( iTimers.Count() )
       
  1780         {
       
  1781         iTimers[0]->Stop();
       
  1782         delete iTimers[0];
       
  1783         iTimers.Remove( 0 );   
       
  1784         }
       
  1785     }
       
  1786 
       
  1787 // ---------------------------------------------------------------------------
       
  1788 // Notify client about an error
       
  1789 // ---------------------------------------------------------------------------
       
  1790 //
       
  1791 void CSVPEmergencySession::ErrorOccurred( TCCPError aError )
       
  1792     {
       
  1793     SVPDEBUG2("CSVPEmergencySession::ErrorOccurred: %d", (TInt)aError)
       
  1794     
       
  1795     if ( iIsLastProfile )
       
  1796         {
       
  1797         iEmergencyObserver->ErrorOccurred( ECCPEmergencyFailed, NULL );
       
  1798         }
       
  1799     else
       
  1800         {
       
  1801         iEmergencyObserver->ErrorOccurred( aError, NULL );
       
  1802         }
       
  1803     }
       
  1804 
       
  1805 // ---------------------------------------------------------------------------
       
  1806 // Traps leaves of RequestPositionL
       
  1807 // ---------------------------------------------------------------------------
       
  1808 //
       
  1809 void CSVPEmergencySession::RequestPosition( TUint32 aIapId )
       
  1810     {
       
  1811     SVPDEBUG1( "CSVPEmergencySession::RequestPosition" )
       
  1812     iIsLIRequestReady = EFalse;
       
  1813     TRAP_IGNORE( RequestPositionL( aIapId ) );
       
  1814     }
       
  1815 
       
  1816 // ---------------------------------------------------------------------------
       
  1817 // Initializes position provider and requests for position information
       
  1818 // ---------------------------------------------------------------------------
       
  1819 //
       
  1820 void CSVPEmergencySession::RequestPositionL( TUint32 aIapId )
       
  1821     {
       
  1822     iPositioningProvider = CSVPPositioningProvider::NewL( 
       
  1823         KSVPEmergencyPositioningPriority, *this );
       
  1824     if ( iPositioningProvider )
       
  1825         {
       
  1826         iPositioningProvider->OpenModuleL( 
       
  1827             KSVPEmergencyDhcpDefaultPsyModuleId );
       
  1828         iPositioningProvider->MakePositioningRequestL( 
       
  1829             aIapId, 
       
  1830             KSVPEmergencyApplicationName, 
       
  1831             KSVPEmergencyPositioningTimeout );
       
  1832         }
       
  1833     }
       
  1834 
       
  1835 // ---------------------------------------------------------------------------
       
  1836 // Parses content ID from URI: removes "sip(s):" prefix, if one exists
       
  1837 // ---------------------------------------------------------------------------
       
  1838 //
       
  1839 HBufC8* CSVPEmergencySession::ParseContentIdL( const TDesC8& aUri )
       
  1840     {
       
  1841     HBufC8* contentId = HBufC8::NewLC( aUri.Length() ); // CS:1
       
  1842     ( contentId->Des() ).Copy( aUri );
       
  1843     if ( 0 == contentId->Find( KSVPSipPrefix ) )
       
  1844         {
       
  1845         contentId->Des().Delete( 0, KSVPSipPrefixLength );
       
  1846         }
       
  1847     else if ( 0 == contentId->Find( KSVPSipsPrefix ) )
       
  1848         {
       
  1849         contentId->Des().Delete( 0, KSVPSipsPrefixLength );
       
  1850         }
       
  1851     CleanupStack::Pop( contentId ); // CS:0
       
  1852     contentId = contentId->ReAllocL( contentId->Length() );
       
  1853     return contentId;
       
  1854     }
       
  1855 
       
  1856 // ---------------------------------------------------------------------------
       
  1857 // Parses cid: adds "cid:" prefix and brackets
       
  1858 // ---------------------------------------------------------------------------
       
  1859 //
       
  1860 HBufC8* CSVPEmergencySession::ParseCidL( const TDesC8& aContentId )
       
  1861     {
       
  1862     HBufC8* cid = HBufC8::NewL( 
       
  1863         KSVPLeftBracketMark().Length() + 
       
  1864         KSVPCidPrefix().Length() + 
       
  1865         aContentId.Length() + 
       
  1866         KSVPRightBracketMark().Length() );
       
  1867 
       
  1868     TPtr8 cidPtr = cid->Des();
       
  1869     cidPtr.Copy( KSVPLeftBracketMark() );
       
  1870     cidPtr.Append( KSVPCidPrefix() );
       
  1871     cidPtr.Append( aContentId );
       
  1872     cidPtr.Append( KSVPRightBracketMark() );
       
  1873     
       
  1874     return cid;
       
  1875     }