multimediacommsengine/mmcesrv/mmceserver/src/mcestateoffering.cpp
changeset 0 1bce908db942
child 3 513a8b745b2f
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2005 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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include <sipdialogassocbase.h>
       
    22 #include <sipdialog.h>
       
    23 #include <sipclienttransaction.h>
       
    24 #include <sipresponseelements.h>
       
    25 #include <sipcseqheader.h>
       
    26 #include "mcestateoffering.h"
       
    27 #include "mcesipsession.h"
       
    28 #include "mcesipextensions.h"
       
    29 #include "mceactionset.h"
       
    30 #include "mcefcactionset.h"
       
    31 #include "mceclientserver.h"
       
    32 #include "mcesip.h"
       
    33 #include "mcesipsession.h"
       
    34 #include "mcenatmacros.h"
       
    35 #include "mcesdpsession.h"
       
    36 #include "mcesrvlogs.h"
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CMceStateOffering::CMceStateOffering
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 CMceStateOffering::CMceStateOffering ()
       
    43     : CMceState( KMceStateOffering )
       
    44 	{
       
    45 	}
       
    46 
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CMceStateOffering::~CMceStateOffering
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CMceStateOffering::~CMceStateOffering()
       
    53 	{
       
    54 	}
       
    55 
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CMceStateOffering::DoAcceptL
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 TBool CMceStateOffering::DoAcceptL( TMceStateTransitionEvent& aEvent )
       
    62 	{
       
    63 
       
    64     User::LeaveIfError( 	                 
       
    65        aEvent.Code() == EMceUpdate ||
       
    66        aEvent.Code() == EMceResponse  ||
       
    67        aEvent.Code() == EMceProvisionalResponse ||
       
    68        aEvent.Code() == EMceRedirectionResponse ||
       
    69        aEvent.Code() == EMceErrorResponse ||
       
    70        aEvent.Code() == EMceMediaUpdated ||
       
    71        aEvent.Code() == EMceItcCancel ||    
       
    72        aEvent.Code() == EMceBye ||  
       
    73        aEvent.Code() == EMceItcEnable ||
       
    74        aEvent.Code() == EMceItcDisable || 
       
    75        IsExtensionRequestEvent( aEvent )
       
    76        
       
    77        ? KErrNone : KErrTotalLossOfPrecision );
       
    78            
       
    79 	return ETrue;
       
    80 	
       
    81 	}
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CMceStateOffering::EntryL
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 void CMceStateOffering::EntryL( TMceStateTransitionEvent& aEvent )
       
    88 	{
       
    89 
       
    90 	if ( IsExtensionRequestEvent( aEvent ))
       
    91 		{
       
    92 		HandleExtensionRequestEventL( aEvent );	
       
    93 		}
       
    94 	
       
    95     else
       
    96     	{
       
    97 	    switch( aEvent.Code() )
       
    98 	        {
       
    99             case EMceUpdate:
       
   100                 {
       
   101                 EntryUpdateL( aEvent );
       
   102                 break;
       
   103                 }
       
   104 	        case EMceProvisionalResponse:
       
   105 	            {
       
   106 	            EntryProvisionalResponseL( aEvent );
       
   107 	            break;
       
   108 	            }
       
   109 	        //200 OK
       
   110 	        case EMceResponse:
       
   111 	            {
       
   112 	            EntryResponseL( aEvent );
       
   113 	            break;                
       
   114 	            }
       
   115 	        //error
       
   116 	        case EMceRedirectionResponse:
       
   117 	            {
       
   118 	            EntryRedirectionResponseL( aEvent );
       
   119 	            break;   
       
   120 	            }
       
   121 	        case EMceErrorResponse:
       
   122 	            {
       
   123 	            EntryErrorResponseL( aEvent );
       
   124 	            break;                
       
   125 	            }
       
   126 	        //if client cancels, send CANCEL            
       
   127 	        case EMceItcCancel:
       
   128 	            {
       
   129 	            EntryCancelL( aEvent );
       
   130 	            break;
       
   131 	            }
       
   132 	        case EMceMediaUpdated:
       
   133 	            {
       
   134                 CMceSipSession& session = aEvent.Session();
       
   135                 CSIPServerTransaction* update = &session.Request();
       
   136 
       
   137                 if ( update && update->Type() == 
       
   138                     SIPStrings::StringF( SipStrConsts::EUpdate ) )
       
   139                     {
       
   140                     EntryMediaUpdatedL( aEvent );
       
   141                     }
       
   142                 else
       
   143                     {
       
   144                     if ( aEvent.Session().SubState() == CMceSipSession::EUpdating )
       
   145                         {
       
   146                         EntryAnswerToUpdateDecodedL( aEvent );
       
   147                         }
       
   148                     else
       
   149                         {
       
   150                         EntryAnswerToOfferDecodedL( aEvent );
       
   151                         }
       
   152                     }
       
   153 	            break;
       
   154 	            }
       
   155 	      
       
   156 	        case EMceItcEnable:
       
   157 	        case EMceItcDisable:
       
   158 	            {
       
   159 	            aEvent.Session().Actions().ControlMediaL( aEvent.ParamIDs(), 
       
   160 	                                             (TMceItcFunctions)aEvent.Code() );
       
   161 	            break;
       
   162 	            } 
       
   163 	        case EMceBye:
       
   164 	            {
       
   165 	            EntryByeL( aEvent );
       
   166 	            break;
       
   167 	            }
       
   168 	        default:
       
   169 	            {
       
   170 	            //NOP
       
   171 	            break;
       
   172 	            }       
       
   173 	        }
       
   174     	}
       
   175 	}
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CMceStateOffering::EntryUpdateL
       
   179 // -----------------------------------------------------------------------------
       
   180 //
       
   181 void CMceStateOffering::EntryUpdateL( TMceStateTransitionEvent& aEvent )
       
   182     {
       
   183     CMceSipSession& session = aEvent.Session();
       
   184     if ( MceSip::HasContent( session.Request() ) )
       
   185         {
       
   186         // UPDATE carries SDP
       
   187         User::LeaveIfError( session.Actions().CreateSDP( session.Request() ) );
       
   188     
       
   189         session.Actions().DecodeL();
       
   190         TMceReturnStatus status = session.Actions().UpdateL();
       
   191         aEvent.ParamStatus() = status;
       
   192         if ( MCE_IS_ERROR( status ) )
       
   193             {
       
   194             // TBD: update failed, reject
       
   195             }
       
   196         else if ( status == KMceAsync )
       
   197             {
       
   198             // NOP
       
   199             }
       
   200         else // ready
       
   201             {
       
   202             aEvent.Code() = EMceMediaUpdated;
       
   203             EntryMediaUpdatedL( aEvent );
       
   204             }
       
   205         }
       
   206     else 
       
   207         {
       
   208         // TBD: handle UPDATE without content
       
   209         }
       
   210         
       
   211     }
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // CMceStateOffering::EntryProvisionalResponseL
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 void CMceStateOffering::EntryMediaUpdatedL( TMceStateTransitionEvent& aEvent )
       
   218     {
       
   219     CMceSipSession& session = aEvent.Session();
       
   220 
       
   221     TMceReturnStatus status = session.Actions().ReserveL();
       
   222     aEvent.ParamStatus() = status;
       
   223     if ( MCE_IS_ERROR( status ))
       
   224         {
       
   225         // TBD: reservation failed
       
   226         }
       
   227     else
       
   228         if (status == KMceAsync)
       
   229             {
       
   230             // NOP
       
   231             }
       
   232         else // ready, send 2xx to update
       
   233             {
       
   234             CSIPServerTransaction* update= NULL;
       
   235             RStringF trx = session.Request().Type();
       
   236             if (trx == SIPStrings::StringF(SipStrConsts::EUpdate) )
       
   237                 {
       
   238                 update = &session.Request();
       
   239                 }
       
   240 
       
   241             if (update)
       
   242                 {
       
   243                 session.Actions().EncodeL();
       
   244                 session.FCActions().UpdateFCAnswerL( *session.Offer() );
       
   245                 session.Actions().SendAnswerL( *update);
       
   246                 }
       
   247             else
       
   248                 {
       
   249                 User::Leave(KErrTotalLossOfPrecision);
       
   250                 }
       
   251             }
       
   252 	}
       
   253 
       
   254 // -----------------------------------------------------------------------------
       
   255 // CMceStateOffering::EntryProvisionalResponseL
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 void CMceStateOffering::EntryProvisionalResponseL( 
       
   259     TMceStateTransitionEvent& aEvent )
       
   260     {
       
   261     TInt status = KErrNone;
       
   262     CMceSipSession& session = aEvent.Session();
       
   263     CSIPClientTransaction& response = session.Response();
       
   264      
       
   265     session.Extensions().UpdateL( response );
       
   266     session.Actions().CheckContactIsSecureL( response );
       
   267 
       
   268     session.ActiveBody().AnswerType() = KMceNegotiationAnswerTypeIntermediate;
       
   269     
       
   270     TBool IsFork = EFalse;
       
   271     if ( MceSip::ResponseCode( session.Response() ) == KMceSipSessionProgress && 
       
   272     	   session.ForkedDialogsCount() ) 
       
   273         {
       
   274         IsFork = ETrue;
       
   275   	    }
       
   276     if ( session.Actions().NeedToProcessL( aEvent ) || IsFork )
       
   277         {
       
   278         if ( MCE_NEED_TO_SEND( session, NULL ) || IsFork )
       
   279             {
       
   280             if ( MceSip::HasContent( response ) )
       
   281                 {
       
   282                 // create SDP answer
       
   283                 //status = session.Actions().CreateSDP( response );
       
   284                 NAT_WAIT_NO_EXEC( session, (status = session.Actions().CreateSDP( response )));
       
   285         	    
       
   286                 // handle SDP content
       
   287                 if ( !MCE_IS_ERROR( status ) )
       
   288                     {
       
   289                     // process session timer
       
   290                     session.Actions().ProcessSessionTimerClientL( response );
       
   291                     // update FC
       
   292                     session.FCActions().PeekFCDocumentL( *session.Offer() );
       
   293                 
       
   294                     //decode answer, ignore warning code 
       
   295                     if ( session.ActiveBody().SecureSession())
       
   296                     	{
       
   297                     	session.ActiveBody().SecureSession()->iLSReadyToBind = EFalse;
       
   298                     	}
       
   299                     session.Actions().DecodeL();
       
   300 
       
   301                     
       
   302                     // update media
       
   303                     status = session.Actions().UpdateL();
       
   304                     }
       
   305                 }
       
   306         
       
   307             //if there was an error
       
   308             if ( MCE_IS_ERROR( status ) )
       
   309                 {
       
   310                 EntryCancelL( aEvent );
       
   311                 //transition exit is performed here
       
   312                 session.Actions().StateChanged( KMceStateCanceled );
       
   313                 session.Actions().ClientStateChangedL( CMceSession::ECancelling, 
       
   314                                                        aEvent.ParamStatus() );
       
   315                 }
       
   316             else if ( status == KMceAsync )
       
   317                 {
       
   318                 aEvent.Session().SetWaitingMediaCallback( ETrue );
       
   319                 }
       
   320             else // KMceReady 
       
   321                 {
       
   322                 EntryAnswerToOfferDecodedL( aEvent );
       
   323                 }
       
   324             }
       
   325         else
       
   326             {
       
   327             EntryAnswerToOfferDecodedL( aEvent );
       
   328             }
       
   329         }
       
   330     aEvent.ParamStatus() = status;
       
   331     }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 // CMceStateOffering::EntryRedirectionResponseL
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void CMceStateOffering::EntryRedirectionResponseL( 
       
   338     TMceStateTransitionEvent& aEvent )
       
   339     {
       
   340     MCESRV_DEBUG("CMceStateOffering::EntryRedirectionResponseL, Entry");
       
   341 
       
   342 	CMceSipSession& session = aEvent.Session();
       
   343     
       
   344     session.ResetSdpCounts();
       
   345     
       
   346     switch ( MceSip::ResponseCode( session.Response() ) )
       
   347         {   
       
   348         case KMceSipMovedTemporarily:  
       
   349             {
       
   350             // any 3xx response for updating will be handled as
       
   351             // a error situation
       
   352             if ( session.SubState() != CMceSipSession::EUpdating )
       
   353                 {
       
   354                 // get remoteUri information from response 
       
   355                 session.AddRemoteUriFromResponseL( 
       
   356                     *const_cast<CSIPResponseElements*>(session.Response().ResponseElements()) );
       
   357                 // create a new inviteAssociationDialog
       
   358                 session.CreateDialogFrom3XXResponseL();
       
   359                 // send the invite again
       
   360                 session.Actions().SendInviteL();    
       
   361                 }            
       
   362             break;
       
   363             }
       
   364         // include KMceSipUseProxy, KMceSipAlternativeService,
       
   365         // KMceSipMultipleChoices, KMceSipMovedPermanently
       
   366         default: 
       
   367             {
       
   368             // error situation
       
   369             break;
       
   370             }
       
   371         }
       
   372     
       
   373     MCESRV_DEBUG("CMceStateOffering::EntryRedirectionResponseL, Exit");
       
   374     }
       
   375     
       
   376 // -----------------------------------------------------------------------------
       
   377 // CMceStateOffering::ExitRedirectionEventL
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CMceStateOffering::ExitRedirectionEventL( 
       
   381     TMceStateTransitionEvent& aEvent )
       
   382     {
       
   383     MCESRV_DEBUG("CMceStateOffering::RedirectionErrorResponseL, Entry");
       
   384 
       
   385     CMceSipSession& session = aEvent.Session();
       
   386     CMceSipSession::TSubState subState = session.SubState();
       
   387     TUint responseCode = MceSip::ResponseCode( session.Response() );
       
   388     
       
   389     if ( subState == CMceSipSession::EOffering )
       
   390         {
       
   391         if ( responseCode == KMceSipMovedTemporarily )  
       
   392             {
       
   393             session.Actions().ClientStateChangedL( 
       
   394                 CMceSession::EOffering, *session.Body(), session.Response() );           
       
   395             }
       
   396         else
       
   397             {
       
   398             session.Actions().StopMedia();
       
   399             session.FCActions().ReleaseFC();
       
   400             session.Actions().StateChanged( KMceStateTerminated );
       
   401             session.Actions().ClientStateChangedL( 
       
   402                 CMceSession::ETerminated, *session.Body(), session.Response() );       
       
   403             }
       
   404         }
       
   405     else if ( session.SubState() == CMceSipSession::EUpdating ) 
       
   406         {
       
   407         session.Actions().StopUpdatingMedia();
       
   408         session.Actions().UpdateFailed();
       
   409         session.Actions().StateChanged( CMceSession::EEstablished );
       
   410         session.Actions().ClientStateChangedL( 
       
   411             CMceSession::EEstablished, *session.Body(),
       
   412             session.Response(), KErrGeneral );                                    
       
   413         }
       
   414     else
       
   415         {
       
   416         // do nothing  
       
   417         }
       
   418     
       
   419     MCESRV_DEBUG("CMceStateOffering::RedirectionErrorResponseL, Exit");
       
   420     }
       
   421 
       
   422 // -----------------------------------------------------------------------------
       
   423 // CMceStateOffering::EntryResponseL
       
   424 // -----------------------------------------------------------------------------
       
   425 //
       
   426 void CMceStateOffering::EntryResponseL( TMceStateTransitionEvent& aEvent )
       
   427     {
       
   428     TInt status = KErrNone;
       
   429 	CMceSipSession& session = aEvent.Session();
       
   430     CMceSipSession::TSubState subState = session.SubState();
       
   431 	
       
   432     //send ACK
       
   433     session.Actions().SendACKL( session.Response() );
       
   434 	session.Actions().CheckContactIsSecureL( session.Response() );
       
   435     session.ActiveBody().AnswerType() = KMceNegotiationAnswerTypeFinal;
       
   436     
       
   437 	// Handle the answer only if the media processing is not
       
   438 	// already ongoing
       
   439 	if ( !session.WaitingMediaCallback() )
       
   440 	    {
       
   441 	    if ( MceSip::HasContent( session.Response() ) )
       
   442 	        {
       
   443 	        //process session timer
       
   444             session.Actions().ProcessSessionTimerClientL( session.Response() );
       
   445             
       
   446             if ( subState != CMceSipSession::ERefreshing )
       
   447                 {
       
   448                 //create SDP answer
       
   449         	    NAT_WAIT_NO_EXEC( session, (status = session.Actions().CreateSDP( session.Response() ) ));
       
   450         	    
       
   451             	if ( !MCE_IS_ERROR( status ) )
       
   452             	    {
       
   453                     //update FC
       
   454                     session.FCActions().PeekFCDocumentL( *session.Offer() );
       
   455                 	
       
   456             	    //decode answer, ignore warning code 
       
   457                     if ( session.ActiveBody().SecureSession())
       
   458                     	{
       
   459                     	session.ActiveBody().SecureSession()->iLSReadyToBind = ETrue;
       
   460                     	}
       
   461                     status = session.Actions().Decode();
       
   462 
       
   463                     // update media and start waiting EMceMediaUpdated (if needed) 
       
   464 				    if ( !MCE_IS_ERROR( status ) )
       
   465 						{
       
   466 		                status = session.Actions().UpdateL();
       
   467 		                //if everything OK, starts floor control
       
   468 		        		if ( !MCE_IS_ERROR( status ) )
       
   469 		    		        {
       
   470 		                    //check should wait EMceMediaUpdated
       
   471 		                    aEvent.Code() = status == KMceReady ? 
       
   472 		                                    EMceMediaUpdated : EMceResponse;
       
   473 		                    if ( subState == CMceSipSession::EOffering )
       
   474 		                        {
       
   475 		                        // start floor control only for the initial INVITE
       
   476 		                        session.FCActions().StartFCL();
       
   477 		                        }
       
   478 		    		        }
       
   479 						}
       
   480             	    }
       
   481                 }
       
   482             }
       
   483 	    else // no content
       
   484     	    {
       
   485     	    if  ( !MCE_NEED_TO_RECEIVE( session ) )
       
   486     	        {
       
   487                 status = session.Actions().UpdateL();
       
   488     	        // SDP answer was received before
       
   489     	        // go to established state
       
   490     	        session.Actions().StateChanged( KMceStateEstablished );
       
   491                 //session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   492                 //                               session.Response() );
       
   493     	        session.Actions().ClientStateChangedL( CMceSession::EEstablished, 
       
   494                                                    *session.Body(),
       
   495                                                    session.Response(),
       
   496                                                    status );
       
   497     	        }
       
   498     	    else
       
   499     	        {
       
   500     	        // SDP answer is not received
       
   501     	        User::Leave( KErrNotReady );
       
   502     	        }
       
   503     	    }
       
   504         
       
   505 	    aEvent.ParamStatus() = status;
       
   506         
       
   507         //if there was an error
       
   508         if ( MCE_IS_ERROR( status ) )
       
   509             {
       
   510         	//if first invite
       
   511             if ( subState == CMceSipSession::EOffering )
       
   512                 {
       
   513                 //send BYE and stop media
       
   514                 session.Actions().SendBYEL();
       
   515                 session.Actions().StopMedia();
       
   516                 }
       
   517             //if updating
       
   518             else if ( subState == CMceSipSession::EUpdating )
       
   519                 {
       
   520                 //do rollback
       
   521                 session.Actions().UpdateFailed();
       
   522                 if ( session.Body() && &session.Body()->SdpSession() &&
       
   523                      session.Body()->SdpSession().iOOldSchoolCompleted )
       
   524                     {
       
   525                     session.Actions().ClientStateChangedL( 
       
   526                         CMceSession::EEstablished, *( session.Body() ), status );                         
       
   527                     }       
       
   528                 }
       
   529             else
       
   530                 {
       
   531                 //NOP
       
   532                 }
       
   533             }
       
   534         else if ( status == KMceAsync )
       
   535             {
       
   536             // set session waiting for media callback
       
   537             aEvent.Session().SetWaitingMediaCallback( ETrue );
       
   538             }
       
   539         else if ( status == KMceReady && subState == CMceSipSession::EUpdating )
       
   540             {
       
   541             session.Actions().UpdateSucceed();
       
   542             }
       
   543         else
       
   544             {
       
   545             // NOP
       
   546             }
       
   547 	    }
       
   548     }
       
   549     
       
   550 
       
   551 // -----------------------------------------------------------------------------
       
   552 // CMceStateOffering::EntryErrorResponseL
       
   553 // -----------------------------------------------------------------------------
       
   554 //
       
   555 void CMceStateOffering::EntryErrorResponseL( TMceStateTransitionEvent& aEvent )
       
   556     {
       
   557 	CMceSipSession& session = aEvent.Session();
       
   558     
       
   559     session.ResetSdpCounts();
       
   560     
       
   561     CMceSipSession::TSubState subState = session.SubState();
       
   562     
       
   563     TUint code = MceSip::ResponseCode( session.Response() );
       
   564     TInt errorCode = KErrNone;
       
   565        
       
   566     if ( code == KMceSipSessionIntervalTooSmall )
       
   567     	{
       
   568     	if ( session.Dialog()->Dialog().State() == CSIPDialog::EConfirmed )	
       
   569     		{
       
   570     		//sending re-INVITE after 422 for re-INVITE
       
   571     		session.Actions().ProcessSessionTimerClientL( session.Response() );
       
   572 			//send again
       
   573 			session.Actions().SendSessionRefreshL();		
       
   574 	   		}
       
   575 	   		
       
   576 		else if ( session.Dialog()->Dialog().State() == CSIPDialog::ETerminated )	   		
       
   577 			{
       
   578 			//sending re-INVITE after 422 for INVITE
       
   579 			errorCode = session.ReUseDialog();	
       
   580             if ( errorCode == KErrNone )
       
   581 				{
       
   582 			   	session.Actions().ProcessSessionTimerClientL( session.Response() );
       
   583 			 	session.Actions().SendInviteL();
       
   584 				}
       
   585 	  		}
       
   586     	}
       
   587     else if ( code == KMceSipExtensionRequired )    
       
   588         {
       
   589         session.Extensions().UpdateL( session.Response() );
       
   590         session.ReCreateOutgoingDialogL();
       
   591         session.Actions().SendInviteL();
       
   592         }     
       
   593 	//if first invite, stop media and FC
       
   594     else if ( subState == CMceSipSession::EOffering )
       
   595         {
       
   596         session.Actions().StopMedia();
       
   597         session.FCActions().ReleaseFC();
       
   598         }
       
   599 	//if update, reject update
       
   600     else if ( subState == CMceSipSession::EUpdating ||
       
   601               subState == CMceSipSession::ERefreshing )
       
   602         {
       
   603 	 	if ( code == KMceSipCallOrTransactionDoesNotExist ||
       
   604              code == KMceSipRequestTimeout ) 
       
   605             { 
       
   606             session.Actions().UpdateFailed();
       
   607             session.Actions().SendBYEL();
       
   608             session.Actions().StopMedia();
       
   609             session.FCActions().ReleaseFC();
       
   610             session.Actions().StateChanged( KMceStateTerminated );
       
   611             session.Actions().ClientStateChangedL( CMceSession::ETerminated,
       
   612                                                    session.Response() );
       
   613             }
       
   614          else
       
   615             {
       
   616             session.Actions().UpdateFailed(); 
       
   617             session.Actions().StateChanged( KMceStateEstablished );
       
   618             session.Actions().ClientStateChangedL( CMceSession::EEstablished, 
       
   619                                                    *session.Body(),
       
   620                                                    session.Response(),
       
   621                                                    KErrCancel );
       
   622             }
       
   623         }
       
   624     else
       
   625         {
       
   626         //NOP
       
   627         }
       
   628     }
       
   629 
       
   630 // -----------------------------------------------------------------------------
       
   631 // CMceStateOffering::EntryCancelL
       
   632 // -----------------------------------------------------------------------------
       
   633 //
       
   634 void CMceStateOffering::EntryCancelL( TMceStateTransitionEvent& aEvent )
       
   635     {
       
   636 	CMceSipSession& session = aEvent.Session();
       
   637     CMceSipSession::TSubState subState = session.SubState();
       
   638 
       
   639     //(try) send CANCEL
       
   640     session.Actions().SendCancelL();
       
   641 
       
   642     if ( subState == CMceSipSession::EOffering )
       
   643         {
       
   644         session.Actions().StopMedia();
       
   645         session.FCActions().ReleaseFC();
       
   646         }
       
   647     else if ( subState == CMceSipSession::EUpdating )
       
   648         {
       
   649         session.Actions().UpdateFailed();
       
   650         }
       
   651         
       
   652     }
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CMceStateOffering::EntryAnswerToUpdateDecodedL
       
   656 // -----------------------------------------------------------------------------
       
   657 //
       
   658 void CMceStateOffering::EntryAnswerToUpdateDecodedL( TMceStateTransitionEvent& aEvent )
       
   659     {
       
   660 	CMceSipSession& session = aEvent.Session();
       
   661 
       
   662     //if media error, media unusable -> send BYE, stop media and FC
       
   663     if ( aEvent.ParamStatus() == KErrNone )
       
   664         {
       
   665         session.Actions().UpdateSucceed();
       
   666         }
       
   667     else
       
   668         {
       
   669         session.Actions().UpdateFailed();
       
   670         }
       
   671     
       
   672     }
       
   673 
       
   674 // -----------------------------------------------------------------------------
       
   675 // CMceStateOffering::EntryAnswerToOfferDecodedL
       
   676 // -----------------------------------------------------------------------------
       
   677 //
       
   678 void CMceStateOffering::EntryAnswerToOfferDecodedL( TMceStateTransitionEvent& aEvent )
       
   679     {
       
   680 	CMceSipSession& session = aEvent.Session();
       
   681     CSIPClientTransaction* response = &session.Response();
       
   682     
       
   683     TInt status = KErrNone;
       
   684         
       
   685     if ( MceSip::ResponseType( *response ) == E1XX &&
       
   686          session.Extensions().LevelL( *response, CMceSipExtensions::E100rel )
       
   687          == CMceSipExtensions::ERequired )
       
   688         
       
   689         { 
       
   690         TBool hasContent = MceSip::HasContent( *response );
       
   691 		
       
   692         // TBD: Quick Fix: Need to have Support in MediaManager to ask do we need 
       
   693         // to send SDP or not, decision must be based on conf line, and 2ndly 
       
   694         // based on weither negotiation has completed or not.
       
   695         TBool sendSdp = hasContent &&
       
   696                         ( MCE_NEED_TO_SEND( session, NULL ) ||
       
   697                           session.Extensions().RemoteIMSRel5() ||
       
   698                           session.ActiveBody().Modifier( KMceSecPreconditions ) ==
       
   699                            KMcePreconditionsE2ESupported );
       
   700         //if there is required header for precodition but no precondition
       
   701         //Prack should indicate precondition failure
       
   702         if ( MceSip::ResponseType( *response ) == E1XX &&
       
   703          	session.Extensions().LevelL( *response, CMceSipExtensions::ESecPreconds )
       
   704          	== CMceSipExtensions::ERequired )
       
   705         	{
       
   706         	session.ActiveBody().iRemoteSecPreconditionsRequired = ETrue;
       
   707         	}
       
   708         if ( sendSdp )
       
   709             {
       
   710             status = session.Actions().UpdateL();
       
   711             __ASSERT_ALWAYS( status == KMceReady, User::Leave( KErrArgument ) ); 
       
   712             //need not to change secure keys
       
   713             if ( session.ActiveBody().SecureSession() &&
       
   714             	 MceSip:: ResponseCode( *response ) == KMceSipSessionProgress)
       
   715             	{
       
   716             	session.ActiveBody().SecureSession()->iKeyNeedUpdated = EFalse;
       
   717             	}
       
   718             NAT_WAIT_NO_EXEC( session, session.Actions().EncodeL() )	
       
   719             //session, session.Actions().EncodeL(); 
       
   720             }
       
   721 
       
   722 		
       
   723         session.Actions().SendPrackL( sendSdp );
       
   724         
       
   725         aEvent.Code() = EMceProvisionalResponse;
       
   726         }
       
   727         
       
   728     }
       
   729     
       
   730 
       
   731 // -----------------------------------------------------------------------------
       
   732 // CMceStateOffering::EntryByeL
       
   733 // -----------------------------------------------------------------------------
       
   734 //
       
   735 void CMceStateOffering::EntryByeL( TMceStateTransitionEvent& aEvent )
       
   736     {
       
   737 	CMceSipSession& session = aEvent.Session();
       
   738 	
       
   739     //send 200OK and stop media and FC
       
   740     session.Actions().Send200OKL( session.Request() );
       
   741     session.Actions().StopMedia();
       
   742     session.FCActions().ReleaseFC();
       
   743 	
       
   744     }
       
   745     
       
   746 // -----------------------------------------------------------------------------
       
   747 // CMceStateOffering::ExitL
       
   748 // -----------------------------------------------------------------------------
       
   749 //
       
   750 void CMceStateOffering::ExitL( TMceStateTransitionEvent& aEvent )
       
   751 	{
       
   752 	
       
   753 	if ( IsExtensionRequestEvent( aEvent ))
       
   754 		{
       
   755 		//Do Nothing;
       
   756 		}
       
   757 
       
   758 
       
   759 	else
       
   760 		{
       
   761 		CMceSipSession& session = aEvent.Session();
       
   762 		CSIPClientTransaction* response = &session.Response(); 
       
   763 		TInt status = aEvent.ParamStatus();
       
   764 		
       
   765 	    switch( aEvent.Code() )
       
   766 	        {
       
   767 	        //received BYE causes server & client to terminated state
       
   768 	        case EMceBye:
       
   769 	            {
       
   770 	            session.Actions().StateChanged( KMceStateTerminated );
       
   771 	            session.Actions().ClientStateChangedL( 
       
   772 	                CMceSession::ETerminated, session.Request() );
       
   773 	            break;
       
   774 	            }      
       
   775 	        case EMceMediaUpdated:
       
   776 	            {
       
   777 	            if ( MceSip::ResponseType( *response ) == E2XX &&
       
   778                         response->ResponseElements()->CSeqHeader()->Method() == 
       
   779                         SIPStrings::StringF( SipStrConsts::EInvite ) )
       
   780 		    		{
       
   781 			   		//server and client state established,
       
   782 		            //if update was successful Body() returns previous BodyCandidate(),
       
   783 		            //if update was failed Body() returns original body
       
   784 		            session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   785 		                                                   *session.Body(),
       
   786 		                                                   session.Response(),
       
   787 		                                                   status );
       
   788 		            session.Actions().StateChanged( KMceStateEstablished );
       
   789                	    }	            
       
   790 	            break;
       
   791 	            }
       
   792 	        case EMceResponse:
       
   793 	        case EMceErrorResponse:
       
   794 	        case EMceProvisionalResponse:
       
   795 	        case EMceRedirectionResponse:
       
   796 	            {
       
   797 	            ExitSIPEventL( aEvent );
       
   798 	            break;                
       
   799 	            }
       
   800 	       
       
   801 	        case EMceItcCancel:
       
   802 	            {
       
   803 	            session.Actions().StateChanged( KMceStateCanceled );
       
   804 	            session.Actions().ClientStateChanged( aEvent.ParamIDs(), 
       
   805 	                                                  CMceSession::ECancelling );
       
   806 	            break;
       
   807 	            }
       
   808 	            
       
   809 	        default:
       
   810 	            {
       
   811 	            //NOP
       
   812 	            }
       
   813 	            
       
   814 	        }
       
   815 		}
       
   816 	
       
   817 	}
       
   818 
       
   819 
       
   820 // -----------------------------------------------------------------------------
       
   821 // CMceStateOffering::ExitSIPEventL
       
   822 // -----------------------------------------------------------------------------
       
   823 //
       
   824 void CMceStateOffering::ExitSIPEventL( TMceStateTransitionEvent& aEvent )
       
   825     {
       
   826     
       
   827 	CMceSipSession& session = aEvent.Session();
       
   828 	TInt status = aEvent.ParamStatus();
       
   829     CMceSipSession::TSubState subState = session.SubState();
       
   830 	
       
   831 	if ( aEvent.Code() == EMceResponse )
       
   832 	    {
       
   833         //error in response handling
       
   834         if ( status < KErrNone && subState == CMceSipSession::EOffering )//failed
       
   835             {
       
   836             //no need to update body to client
       
   837             session.Actions().StateChanged( KMceStateTerminating );
       
   838             session.Actions().ClientStateChangedL( CMceSession::ETerminating,
       
   839                                                    session.Response(),
       
   840                                                    status );
       
   841             }
       
   842         else if ( status < KErrNone && subState == CMceSipSession::EUpdating )//failed
       
   843             {
       
   844             //original body is updated to client
       
   845             session.Actions().ClientStateChangedL( CMceSession::EEstablished, 
       
   846                                                    *session.Body(),
       
   847                                                    session.Response(),
       
   848                                                    status );
       
   849             session.Actions().StateChanged( KMceStateEstablished );
       
   850             }
       
   851         else if ( subState == CMceSipSession::ERefreshing )
       
   852             {
       
   853             session.Actions().StateChanged( KMceStateEstablished );
       
   854             session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   855                                                    session.Response() );
       
   856             }
       
   857         else
       
   858             {
       
   859             // SDP Answer was received previously, ignore the contents if any
       
   860             // Get into established state.
       
   861             if ( !session.WaitingMediaCallback() &&
       
   862                  !MCE_NEED_TO_RECEIVE( session ) )
       
   863                 {
       
   864                 session.Actions().StateChanged( KMceStateEstablished );
       
   865                 session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   866                                                        session.Response() );
       
   867                 }
       
   868             else
       
   869                 {
       
   870                 //wait EMceAnswerDecoded or EMceAnswerToUpdateDecoded
       
   871                 }
       
   872             }
       
   873 	    }
       
   874     else if ( aEvent.Code() == EMceErrorResponse )
       
   875         {
       
   876         if ( subState == CMceSipSession::EOffering )
       
   877             {
       
   878             TUint code = MceSip::ResponseCode( session.Response() );
       
   879             if ( code != KMceSipExtensionRequired && code != KMceSipSessionIntervalTooSmall  )  
       
   880                 {
       
   881                 session.Actions().StateChanged( KMceStateTerminated );
       
   882                 session.Actions().ClientStateChangedL( CMceSession::ETerminated,
       
   883                                                       session.Response() );
       
   884                 }
       
   885             }
       
   886         else if ( subState == CMceSipSession::EUpdating )
       
   887             {
       
   888             if ( MceSip::ResponseCode( 
       
   889                  session.Response() ) == KMceSipCallOrTransactionDoesNotExist ||
       
   890                  MceSip::ResponseCode( 
       
   891                  session.Response() ) == KMceSipRequestTimeout ) 
       
   892                 {
       
   893                 session.Actions().StateChanged( KMceStateTerminating );
       
   894                 session.Actions().ClientStateChangedL( CMceSession::ETerminating,
       
   895                                                        session.Response() );
       
   896                 }
       
   897             else
       
   898                 {
       
   899                 session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   900                                                        *session.Body(),
       
   901                                                        session.Response(),
       
   902                                                        KErrCancel );
       
   903                 session.Actions().StateChanged( KMceStateEstablished );
       
   904                 }
       
   905             }
       
   906         else
       
   907             {//MediaUpdated
       
   908             if ( session.PendingTransaction( SIPStrings::StringF( SipStrConsts::EPrack ) ) )
       
   909                 {
       
   910                 session.Actions().StateChanged( KMceStateConfirming );
       
   911                 }
       
   912             else
       
   913                 {
       
   914                 session.Actions().ClientStateChangedL( CMceSession::EEstablished,
       
   915                                                    session.Response() );
       
   916                 session.Actions().StateChanged( KMceStateEstablished );
       
   917                 }
       
   918             }
       
   919         }
       
   920     else if ( aEvent.Code() == EMceRedirectionResponse )
       
   921         {
       
   922         ExitRedirectionEventL( aEvent );
       
   923         }
       
   924         
       
   925         
       
   926   	else//EMceProvisionalResponse
       
   927         {
       
   928         if ( MceSip::ResponseCode( session.Response() ) > KMceSipTrying && 
       
   929              session.Actions().NeedToProcessL( aEvent ) )
       
   930             {
       
   931             // update RSeq of a handled response to the session if it contains
       
   932             TInt rseqValueOfLatestResponse = KErrNotFound;
       
   933             
       
   934             rseqValueOfLatestResponse = MceSip::RSeq( *session.Response().ResponseElements() );
       
   935             
       
   936             if ( rseqValueOfLatestResponse != KErrNotFound )
       
   937             	{
       
   938             	session.SetRSeq( rseqValueOfLatestResponse );		
       
   939             	}
       
   940                         
       
   941             session.Actions().ClientStateChangedL( CMceSession::EOffering,
       
   942                 *session.Body(), session.Response() );
       
   943             }
       
   944         
       
   945         if ( session.PendingTransaction( SIPStrings::StringF( SipStrConsts::EPrack ) ) )
       
   946             {
       
   947             session.Actions().StateChanged( KMceStateConfirming );
       
   948             }
       
   949         }
       
   950         
       
   951     }
       
   952 
       
   953 
       
   954 
       
   955 // End of File
       
   956