realtimenetprots/sipfw/SIP/sipapi/src/SipDialogImplementation.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : SipDialogImplementation.cpp
       
    15 // Part of       : SIPAPI
       
    16 // Version       : SIP/6.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include <uri8.h>
       
    22 #include "siperr.h"
       
    23 #include "SipAssert.h"
       
    24 #include "SipDialogImplementation.h"
       
    25 #include "SipDialogAssocImplementation.h"
       
    26 #include "sipinvitedialogassoc.h"
       
    27 #include "sipsubscribedialogassoc.h"
       
    28 #include "sipdialogstate.h"
       
    29 #include "sipmessageelements.h"
       
    30 #include "siprequestelements.h"
       
    31 #include "sipresponseelements.h"
       
    32 #include "SipConnectionImplementation.h"
       
    33 #include "sipclientconnection.h"
       
    34 #include "sipinviteclienttransaction.h"
       
    35 #include "sipservertransaction.h"
       
    36 #include "sipregistrationcontext.h"
       
    37 #include "siprefresh.h"
       
    38 #include "sipaddress.h"
       
    39 #include "sipfromheader.h"
       
    40 #include "siptoheader.h"
       
    41 #include "sipcontactheader.h"
       
    42 #include "sipcallidheader.h"
       
    43 #include "sip.h"
       
    44 #include "SipImplementation.h"
       
    45 #include "sipstrings.h"
       
    46 #include "sipstrconsts.h"
       
    47 
       
    48 #ifdef CPPUNIT_TEST
       
    49 #include "TestCleanupStack.h"
       
    50 #endif
       
    51 
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CSIPDialogImplementation::NewLC
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 CSIPDialogImplementation* CSIPDialogImplementation::NewLC(
       
    58 						CSIPConnectionImplementation& aConnImplementation,
       
    59 						const MSIPRegistrationContext* aContext)
       
    60 	{
       
    61 	CSIPDialog* dialog = aContext ?
       
    62 		CSIPDialog::NewL(aConnImplementation, *aContext) :
       
    63 		CSIPDialog::NewL(aConnImplementation);	
       
    64 
       
    65     CSIPDialogImplementation* self = &dialog->Implementation();
       
    66     CleanupStack::PushL(self);
       
    67     return self;
       
    68 	}
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CSIPDialogImplementation::NewL
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 CSIPDialogImplementation* CSIPDialogImplementation::NewL(
       
    75 						CSIPDialog* aDialog,
       
    76 						CSIPConnectionImplementation& aConnImplementation)
       
    77     {
       
    78     CSIPDialogImplementation* self =
       
    79     	new (ELeave) CSIPDialogImplementation(aConnImplementation);
       
    80     CleanupStack::PushL(self);
       
    81     self->ConstructL(aDialog);
       
    82     CleanupStack::Pop(self);
       
    83     return self;
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CSIPDialogImplementation::NewL
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 CSIPDialogImplementation* CSIPDialogImplementation::NewL(
       
    91 							CSIPDialog* aDialog,
       
    92 							CSIPConnectionImplementation& aConnImplementation,
       
    93                             const MSIPRegistrationContext& aContext)
       
    94     {
       
    95     CSIPDialogImplementation* self =
       
    96     	new (ELeave) CSIPDialogImplementation(aConnImplementation, aContext);
       
    97     CleanupStack::PushL(self);
       
    98     self->ConstructL(aDialog);
       
    99     CleanupStack::Pop(self);
       
   100     return self;
       
   101     }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CSIPDialogImplementation::CSIPDialogImplementation
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 CSIPDialogImplementation::CSIPDialogImplementation(
       
   108 						CSIPConnectionImplementation& aConnImplementation) :
       
   109     iConnection(&aConnImplementation)
       
   110 #ifdef CPPUNIT_TEST
       
   111     , iDialogAssocs(1)
       
   112 #endif	
       
   113     {
       
   114     }
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CSIPDialogImplementation::CSIPDialogImplementation
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 CSIPDialogImplementation::CSIPDialogImplementation(
       
   121 						CSIPConnectionImplementation& aConnImplementation,
       
   122                        	const MSIPRegistrationContext& aContext) :
       
   123     iConnection(&aConnImplementation),
       
   124     iRegistration(&aContext)
       
   125 #ifdef CPPUNIT_TEST
       
   126     , iDialogAssocs(1)
       
   127 #endif
       
   128 	, iStringPoolOpened(EFalse)
       
   129     {
       
   130     }
       
   131 
       
   132 // -----------------------------------------------------------------------------
       
   133 // CSIPDialogImplementation::ConstructL
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 void CSIPDialogImplementation::ConstructL(CSIPDialog* aDialog)
       
   137     {
       
   138     CheckConnectionL();
       
   139     iConnection->AddDialogL(*this);
       
   140     iState = iConnection->InitialDialogStateL();
       
   141     iDialog = aDialog;
       
   142 
       
   143     SIPStrings::OpenL();
       
   144     iStringPoolOpened = ETrue;
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CSIPDialogImplementation::~CSIPDialogImplementation
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 CSIPDialogImplementation::~CSIPDialogImplementation()
       
   152     {
       
   153     if (iConnection)
       
   154         {        
       
   155         iConnection->RemoveDialog(*this);
       
   156         }
       
   157 
       
   158     iDialogAssocs.Reset();
       
   159 
       
   160 	delete iDialog;
       
   161     delete iFrom;
       
   162     delete iTo;
       
   163     delete iRemoteUri;
       
   164     delete iContact;
       
   165     delete iCallID;
       
   166 
       
   167 	if (iStringPoolOpened)
       
   168 		{
       
   169     	SIPStrings::Close();
       
   170 		}
       
   171     }
       
   172 
       
   173 // -----------------------------------------------------------------------------
       
   174 // CSIPDialogImplementation::State
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 CSIPDialog::TState CSIPDialogImplementation::State() const
       
   178     {
       
   179     __TEST_INVARIANT;
       
   180     return iState ? iState->State() : CSIPDialog::ETerminated;
       
   181     }
       
   182 
       
   183 // -----------------------------------------------------------------------------
       
   184 // CSIPDialogImplementation::ChangeState
       
   185 // -----------------------------------------------------------------------------
       
   186 //
       
   187 void CSIPDialogImplementation::ChangeState(const CDialogState* aNewState)
       
   188 	{
       
   189     __TEST_INVARIANT;
       
   190 
       
   191 	iState = aNewState;
       
   192 
       
   193     __TEST_INVARIANT;
       
   194 	}
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CSIPDialogImplementation::ConnectionLost
       
   198 // -----------------------------------------------------------------------------
       
   199 //
       
   200 void CSIPDialogImplementation::ConnectionLost()
       
   201     {
       
   202     __TEST_INVARIANT;
       
   203 
       
   204     if (iState)
       
   205         {        
       
   206         iState->ConnectionLost(*this);
       
   207         }
       
   208     
       
   209     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
   210         {
       
   211         iDialogAssocs[i]->Implementation().ConnectionLost();
       
   212         }
       
   213 
       
   214     __TEST_INVARIANT;
       
   215     }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 // CSIPDialogImplementation::SIPDialogAssociations
       
   219 // -----------------------------------------------------------------------------
       
   220 //
       
   221 const RPointerArray<CSIPDialogAssocBase>&
       
   222 CSIPDialogImplementation::SIPDialogAssociations() const
       
   223     {
       
   224     __TEST_INVARIANT;
       
   225     return iDialogAssocs;
       
   226     }
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CSIPDialogImplementation::RegistrationContext
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 const MSIPRegistrationContext*
       
   233 CSIPDialogImplementation::RegistrationContext() const
       
   234     {
       
   235     __TEST_INVARIANT;
       
   236     return iRegistration;
       
   237     }
       
   238 
       
   239 // -----------------------------------------------------------------------------
       
   240 // CSIPDialogImplementation::IsAssociated
       
   241 // -----------------------------------------------------------------------------
       
   242 //
       
   243 TBool
       
   244 CSIPDialogImplementation::IsAssociated(const CSIPDialogAssocBase& aAssoc) const
       
   245     {
       
   246     __TEST_INVARIANT;
       
   247 
       
   248     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
   249         {
       
   250         if (iDialogAssocs[i] == &aAssoc)
       
   251             {
       
   252             return ETrue;
       
   253             }
       
   254         }
       
   255 
       
   256     return EFalse;
       
   257     }
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CSIPDialogImplementation::Connection
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 CSIPConnection* CSIPDialogImplementation::Connection()
       
   264     {    
       
   265     return GetConnection();
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CSIPDialogImplementation::Connection
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 const CSIPConnection* CSIPDialogImplementation::Connection() const
       
   273     {
       
   274     return GetConnection();
       
   275     }
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CSIPDialogImplementation::GetConnection
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 CSIPConnection* CSIPDialogImplementation::GetConnection() const
       
   282 	{
       
   283 	__TEST_INVARIANT;
       
   284 
       
   285 	CSIPConnection* conn = NULL;
       
   286     if (iConnection)
       
   287     	{
       
   288     	TRAP_IGNORE((conn = &iConnection->SIPConnectionL()))
       
   289     	}
       
   290     return conn;
       
   291 	}
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // CSIPDialogImplementation::FromHeader
       
   295 // -----------------------------------------------------------------------------
       
   296 //
       
   297 const CSIPFromHeader& CSIPDialogImplementation::FromHeader() const
       
   298     {
       
   299     __TEST_INVARIANT;
       
   300     return *iFrom;
       
   301     }
       
   302 
       
   303 // -----------------------------------------------------------------------------
       
   304 // CSIPDialogImplementation::ToHeader
       
   305 // -----------------------------------------------------------------------------
       
   306 //
       
   307 const CSIPToHeader& CSIPDialogImplementation::ToHeader() const
       
   308     {
       
   309     __TEST_INVARIANT;
       
   310     return *iTo;
       
   311     }
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // CSIPDialogImplementation::RemoteURI
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 const CUri8& CSIPDialogImplementation::RemoteURI() const
       
   318     {
       
   319     __ASSERT_DEBUG(iRemoteUri,
       
   320     	User::Panic(_L("CSIPDlgImp:RemoteURI"), KErrNotFound));
       
   321     return *iRemoteUri;
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CSIPDialogImplementation::CallIdL
       
   326 // If Call-ID doesn't exist yet, application has asked it too early.
       
   327 // -----------------------------------------------------------------------------
       
   328 //
       
   329 const CSIPCallIDHeader& CSIPDialogImplementation::CallIdL() const
       
   330 	{
       
   331 	__ASSERT_ALWAYS(iCallID, User::Leave(KErrSIPInvalidDialogState));
       
   332 	return *iCallID;
       
   333 	}
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CSIPDialogImplementation::StoreCallIdL
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 void CSIPDialogImplementation::StoreCallIdL()
       
   340 	{
       
   341 	__TEST_INVARIANT;
       
   342 	__SIP_ASSERT_LEAVE(iDialogId != 0, KErrNotFound);	
       
   343 	CheckConnectionL();
       
   344 
       
   345     CSIPCallIDHeader* tmp = iConnection->ClientConnectionL().CallIDL(iDialogId);
       
   346 	delete iCallID;
       
   347 	iCallID = tmp;
       
   348 	}
       
   349 
       
   350 // -----------------------------------------------------------------------------
       
   351 // CSIPDialogImplementation::CopyCallIdL
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 void CSIPDialogImplementation::CopyCallIdL(
       
   355     const CSIPDialogImplementation& aDialog)
       
   356 	{
       
   357 	__TEST_INVARIANT;	
       
   358 
       
   359 	CSIPCallIDHeader* tmp = 
       
   360 	    static_cast<CSIPCallIDHeader*>(aDialog.CallIdL().CloneL());
       
   361 	delete iCallID;
       
   362 	iCallID = tmp;
       
   363 	}
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CSIPDialogImplementation::operator==
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 TBool CSIPDialogImplementation::operator==(
       
   370 						const CSIPDialogImplementation& aDialog) const
       
   371     {
       
   372     __TEST_INVARIANT;
       
   373     return this == &aDialog ||
       
   374     	   (iDialogId && aDialog.iDialogId && (iDialogId == aDialog.iDialogId));
       
   375     }
       
   376 
       
   377 // -----------------------------------------------------------------------------
       
   378 // CSIPDialogImplementation::ReuseInitialRequestData
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 TInt CSIPDialogImplementation::ReuseInitialRequestData()
       
   382     {
       
   383     TInt err = KErrSIPInvalidDialogState;
       
   384     
       
   385     if (iState && iState->State() == CSIPDialog::ETerminated &&
       
   386         iConnection && iConnection->SIP() && iConnection->ClientConnection())
       
   387         {
       
   388         TUint32 originalRequestId = iInitialRequestId;
       
   389         iInitialRequestId = 0;
       
   390         const CDialogState* originalState = iState;
       
   391         iState = iConnection->SIP()->Implementation().InitialDialogState();
       
   392         err = iConnection->ClientConnection()->ResetDialogState(iDialogId);
       
   393         if (err != KErrNone)
       
   394             {
       
   395             // Rollback to the original state
       
   396             iInitialRequestId = originalRequestId;
       
   397             iState = originalState;
       
   398             }
       
   399         else
       
   400             {
       
   401             iTo->DeleteParam(SIPStrings::StringF(SipStrConsts::ETag));
       
   402             }
       
   403         }       
       
   404     
       
   405     return err;
       
   406     }
       
   407 
       
   408 // -----------------------------------------------------------------------------
       
   409 // CSIPDialogImplementation::Dialog
       
   410 // Don't use invariant here.
       
   411 // -----------------------------------------------------------------------------
       
   412 //
       
   413 CSIPDialog& CSIPDialogImplementation::Dialog()
       
   414 	{
       
   415 	__ASSERT_DEBUG(iDialog, User::Panic(_L("CSIPDlgImp:Dialog"), KErrNotFound));
       
   416 	return *iDialog;
       
   417 	}
       
   418 
       
   419 // -----------------------------------------------------------------------------
       
   420 // CSIPDialogImplementation::IncomingResponseL
       
   421 // -----------------------------------------------------------------------------
       
   422 //
       
   423 TBool
       
   424 CSIPDialogImplementation::IncomingResponseL(CSIPResponseElements* aElements,
       
   425 				                            TUint32 aRequestId,
       
   426 		                                    TUint32 aDialogId,
       
   427 		                                    CConnectionCallback& aCallback)
       
   428     {
       
   429     __TEST_INVARIANT;
       
   430     __SIP_ASSERT_LEAVE(aElements != NULL, KErrArgument);
       
   431 
       
   432     if (iState)
       
   433         {
       
   434         return iState->IncomingResponseL(*this,
       
   435                                          aElements,
       
   436 		                                 aRequestId,
       
   437                                          aDialogId,
       
   438                                          aCallback);
       
   439         }
       
   440     delete aElements;
       
   441     return EFalse;    
       
   442     }
       
   443 
       
   444 // -----------------------------------------------------------------------------
       
   445 // CSIPDialogImplementation::IncomingResponseL
       
   446 // -----------------------------------------------------------------------------
       
   447 //
       
   448 TBool
       
   449 CSIPDialogImplementation::IncomingResponseL(CSIPResponseElements* aElements,
       
   450 				                            TUint32 aRequestId,
       
   451 		                                    TUint32 aRefreshId,
       
   452 							                TUint32 aDialogId,
       
   453 		                                    CConnectionCallback& aCallback)                                   
       
   454     {
       
   455     __TEST_INVARIANT;
       
   456     __SIP_ASSERT_LEAVE(aElements != NULL, KErrArgument);
       
   457 
       
   458     if (iState)
       
   459         {
       
   460         return iState->IncomingResponseL(*this,
       
   461                                          aElements,
       
   462 		                                 aRequestId,
       
   463                                          aRefreshId,
       
   464                                          aDialogId,
       
   465                                          aCallback);
       
   466         }
       
   467     delete aElements;
       
   468     return EFalse;
       
   469     }
       
   470 
       
   471 // -----------------------------------------------------------------------------
       
   472 // CSIPDialogImplementation::IncomingRequest
       
   473 // -----------------------------------------------------------------------------
       
   474 //
       
   475 TBool CSIPDialogImplementation::IncomingRequestL(
       
   476 									CSIPServerTransaction* aTransaction,
       
   477                                    	CConnectionCallback& aCallback)                                  
       
   478     {
       
   479     __TEST_INVARIANT;
       
   480     __SIP_ASSERT_LEAVE(aTransaction != NULL, KErrArgument);
       
   481 
       
   482     if (iState)
       
   483         {
       
   484         return iState->IncomingRequestL(*this, aTransaction, aCallback);
       
   485         }
       
   486     delete aTransaction;
       
   487     return EFalse;
       
   488     }
       
   489 
       
   490 // -----------------------------------------------------------------------------
       
   491 // CSIPDialogImplementation::ErrorOccured
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 TBool CSIPDialogImplementation::ErrorOccured(TInt aError,
       
   495 				                             TUint32 aRequestId,
       
   496 				                             CConnectionCallback& aCallback)
       
   497     {
       
   498     __TEST_INVARIANT;
       
   499     return iState &&
       
   500     	   iState->ErrorOccured(*this, aError, aRequestId, aCallback);
       
   501     }
       
   502 
       
   503 // -----------------------------------------------------------------------------
       
   504 // CSIPDialogImplementation::ErrorOccured
       
   505 // -----------------------------------------------------------------------------
       
   506 //
       
   507 TBool CSIPDialogImplementation::ErrorOccured(TInt aError,             
       
   508 				                             TUint32 aRefreshId,
       
   509 				                             TUint32 aRequestId,
       
   510 				                             CConnectionCallback& aCallback)
       
   511     {
       
   512     __TEST_INVARIANT;
       
   513     return iState &&
       
   514     	iState->ErrorOccured(*this, aError, aRefreshId, aRequestId, aCallback);        
       
   515     }
       
   516 
       
   517 // -----------------------------------------------------------------------------
       
   518 // CSIPDialogImplementation::DialogId
       
   519 // Don't use invariant here.
       
   520 // -----------------------------------------------------------------------------
       
   521 //
       
   522 TUint32 CSIPDialogImplementation::DialogId() const
       
   523     {    
       
   524     return iDialogId;
       
   525     }
       
   526 
       
   527 // -----------------------------------------------------------------------------
       
   528 // CSIPDialogImplementation::SetDialogId
       
   529 // -----------------------------------------------------------------------------
       
   530 //
       
   531 void CSIPDialogImplementation::SetDialogId(TUint32 aDialogId)
       
   532     {
       
   533     __TEST_INVARIANT;
       
   534 
       
   535     iDialogId = aDialogId;
       
   536 
       
   537     __TEST_INVARIANT;
       
   538     }
       
   539 
       
   540 // -----------------------------------------------------------------------------
       
   541 // CSIPDialogImplementation::FindTransaction
       
   542 // -----------------------------------------------------------------------------
       
   543 //
       
   544 CSIPTransactionBase*
       
   545 CSIPDialogImplementation::FindTransaction(TUint32 aRequestId) const
       
   546     {
       
   547     __TEST_INVARIANT;
       
   548 
       
   549     CSIPTransactionBase* ta = NULL;
       
   550     for (TInt i = 0; i < iDialogAssocs.Count() && !ta; ++i)
       
   551         {
       
   552         ta = iDialogAssocs[i]->Implementation().FindTransaction(aRequestId);
       
   553         }
       
   554 
       
   555     return ta;
       
   556     }
       
   557 
       
   558 // -----------------------------------------------------------------------------
       
   559 // CSIPDialogImplementation::FindTransactionAndAssoc
       
   560 // -----------------------------------------------------------------------------
       
   561 //
       
   562 TBool CSIPDialogImplementation::FindTransactionAndAssoc(TUint32 aRequestId,
       
   563                                     CSIPTransactionBase** aTransaction,
       
   564                                     CSIPDialogAssocBase** aAssoc) const
       
   565     {
       
   566     __TEST_INVARIANT;
       
   567     __SIP_ASSERT_RETURN_VALUE(aTransaction && aAssoc, EFalse);
       
   568 
       
   569     CSIPTransactionBase* ta = NULL;
       
   570     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
   571         {
       
   572         ta = iDialogAssocs[i]->Implementation().FindTransaction(aRequestId);
       
   573         if (ta)
       
   574             {
       
   575             *aTransaction = ta;
       
   576             *aAssoc = iDialogAssocs[i];
       
   577             return ETrue;
       
   578             }
       
   579         }
       
   580 
       
   581     return EFalse;
       
   582     }
       
   583 
       
   584 // -----------------------------------------------------------------------------
       
   585 // CSIPDialogImplementation::FindAssocAndRefreshL
       
   586 // Search with aRequestId. If not found, search with aRefreshId.
       
   587 // -----------------------------------------------------------------------------
       
   588 //
       
   589 TBool CSIPDialogImplementation::FindAssocAndRefreshL(TUint32 aRequestId,
       
   590                                   TUint32 aRefreshId,
       
   591                                   CSIPDialogAssocBase** aAssoc,
       
   592                                   CSIPRefresh** aRefresh,
       
   593                                   CSIPTransactionBase** aTransaction) const
       
   594     {
       
   595     __TEST_INVARIANT;
       
   596     __SIP_ASSERT_RETURN_VALUE(aAssoc && aRefresh && aTransaction, EFalse);
       
   597 
       
   598     if (FindTransactionAndAssoc(aRequestId, aTransaction, aAssoc))
       
   599         {
       
   600         *aRefresh =
       
   601             static_cast<CSIPClientTransaction*>(*aTransaction)->Refresh();
       
   602 
       
   603         //Refresh must exist now
       
   604         __ASSERT_DEBUG(*aRefresh,
       
   605 		    User::Panic(_L("CSIPDlgImp:FindAssocAndRfr"), KErrNotFound));
       
   606         if (*aRefresh)
       
   607             {
       
   608             return ETrue;
       
   609             }
       
   610         }
       
   611 
       
   612 	if (FindAssocAndRefresh(aRefreshId, aAssoc, aRefresh))
       
   613 		{
       
   614 		CSIPTransactionBase* ta = (*aRefresh)->Transaction();
       
   615 		if (ta)
       
   616 			{
       
   617 			CSIPTransactionBase::TState state = ta->StateL();
       
   618 			//If transaction has received a final response, it is the initial
       
   619 			//transaction creating the refresh. Ignore EConfirmed state, as only
       
   620 			//INVITE _server_ transaction has it.
       
   621 			if (state != CSIPTransactionBase::ECompleted &&
       
   622 				state != CSIPTransactionBase::ETerminated)
       
   623 				{
       
   624 				*aTransaction = ta;
       
   625 				}
       
   626 			}
       
   627 		return ETrue;
       
   628 		}
       
   629 	return EFalse;
       
   630     }
       
   631 
       
   632 // -----------------------------------------------------------------------------
       
   633 // CSIPDialogImplementation::FindAssocAndRefresh
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 TBool CSIPDialogImplementation::FindAssocAndRefresh(TUint32 aRefreshId,
       
   637                                       CSIPDialogAssocBase** aAssoc,
       
   638                                       CSIPRefresh** aRefresh) const
       
   639     {
       
   640     __TEST_INVARIANT;
       
   641     __SIP_ASSERT_RETURN_VALUE(aAssoc && aRefresh, EFalse);
       
   642 	
       
   643     CSIPRefresh* refresh = NULL;
       
   644     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
   645         {
       
   646         refresh = iDialogAssocs[i]->FindRefresh(aRefreshId);
       
   647         if (refresh)
       
   648             {
       
   649             *aAssoc = iDialogAssocs[i];
       
   650             *aRefresh = refresh;
       
   651             return ETrue;
       
   652             }
       
   653         }
       
   654 
       
   655     return EFalse;
       
   656     }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CSIPDialogImplementation::FindRefresh
       
   660 // -----------------------------------------------------------------------------
       
   661 //  
       
   662 CSIPRefresh* CSIPDialogImplementation::FindRefresh(
       
   663     TUint32 aRequestId,
       
   664     TUint32 aRefreshId) const
       
   665     {
       
   666     CSIPDialogAssocBase* dummyAssoc = NULL;
       
   667     CSIPRefresh* refresh = NULL;
       
   668     CSIPTransactionBase* dummyTransaction;
       
   669     if (FindTransactionAndAssoc(aRequestId, &dummyTransaction, &dummyAssoc))
       
   670         {
       
   671         return static_cast<CSIPClientTransaction*>(dummyTransaction)->Refresh();
       
   672         }
       
   673     FindAssocAndRefresh(aRefreshId,&dummyAssoc,&refresh);
       
   674     return refresh;
       
   675     }
       
   676 
       
   677 // -----------------------------------------------------------------------------
       
   678 // CSIPDialogImplementation::SendNonTargetRefreshRequestL
       
   679 // -----------------------------------------------------------------------------
       
   680 //
       
   681 CSIPClientTransaction* CSIPDialogImplementation::SendNonTargetRefreshRequestL(
       
   682 										CSIPDialogAssocImplementation& aAssoc,
       
   683                                         RStringF aMethod,
       
   684                                         CSIPMessageElements* aElements) const
       
   685     {
       
   686     __TEST_INVARIANT;
       
   687     return StateL().SendNonTargetRefreshRequestL(*this,
       
   688                                                  aAssoc,
       
   689                                                  aMethod,
       
   690                                                  aElements);
       
   691     }
       
   692 
       
   693 // -----------------------------------------------------------------------------
       
   694 // CSIPDialogImplementation::SendInviteL
       
   695 // -----------------------------------------------------------------------------
       
   696 //
       
   697 CSIPClientTransaction*
       
   698 CSIPDialogImplementation::SendInviteL(CSIPInviteDialogAssoc& aAssoc,
       
   699                         			  CSIPMessageElements* aElements) const
       
   700     {
       
   701     __TEST_INVARIANT;    
       
   702     return StateL().SendInviteL(*this, aAssoc, aElements);
       
   703     }
       
   704 
       
   705 // -----------------------------------------------------------------------------
       
   706 // CSIPDialogImplementation::SendPrackL
       
   707 // -----------------------------------------------------------------------------
       
   708 //
       
   709 CSIPClientTransaction*
       
   710 CSIPDialogImplementation::SendPrackL(CSIPInviteDialogAssoc& aAssoc,
       
   711                        				 CSIPMessageElements* aElements) const
       
   712     {
       
   713     __TEST_INVARIANT;    
       
   714     return StateL().SendPrackL(aAssoc, aElements);
       
   715     }
       
   716 
       
   717 // -----------------------------------------------------------------------------
       
   718 // CSIPDialogImplementation::SendUpdateL
       
   719 // -----------------------------------------------------------------------------
       
   720 //
       
   721 CSIPClientTransaction*
       
   722 CSIPDialogImplementation::SendUpdateL(CSIPInviteDialogAssoc& aAssoc,
       
   723                         			  CSIPMessageElements* aElements) const
       
   724     {
       
   725     __TEST_INVARIANT;
       
   726     return StateL().SendUpdateL(aAssoc, aElements);
       
   727     }
       
   728 
       
   729 // -----------------------------------------------------------------------------
       
   730 // CSIPDialogImplementation::SendAckL
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 void CSIPDialogImplementation::SendAckL(CSIPInviteDialogAssoc& aAssoc,
       
   734 			                       const CSIPClientTransaction& aTransaction,
       
   735 			                       CSIPMessageElements* aElements) const
       
   736     {
       
   737     __TEST_INVARIANT;
       
   738 
       
   739     StateL().SendAckL(aAssoc, aTransaction, aElements);
       
   740     }
       
   741 
       
   742 // -----------------------------------------------------------------------------
       
   743 // CSIPDialogImplementation::SendSubscribeL
       
   744 // -----------------------------------------------------------------------------
       
   745 //
       
   746 CSIPClientTransaction*
       
   747 CSIPDialogImplementation::SendSubscribeL(CSIPSubscribeDialogAssoc& aAssoc,
       
   748 			                             CSIPMessageElements* aElements,
       
   749 			                             CSIPRefresh* aRefresh) const
       
   750     {
       
   751     __TEST_INVARIANT;
       
   752     return StateL().SendSubscribeL(*this, aAssoc, aElements, aRefresh);
       
   753     }
       
   754 
       
   755 // -----------------------------------------------------------------------------
       
   756 // CSIPDialogImplementation::UpdateL
       
   757 // -----------------------------------------------------------------------------
       
   758 //
       
   759 CSIPClientTransaction*
       
   760 CSIPDialogImplementation::UpdateL(CSIPSubscribeDialogAssoc& aAssoc,
       
   761 			                      CSIPMessageElements* aElements) const
       
   762     {
       
   763     __TEST_INVARIANT;
       
   764     return StateL().UpdateL(*this, aAssoc, aElements);
       
   765     }
       
   766 
       
   767 // -----------------------------------------------------------------------------
       
   768 // CSIPDialogImplementation::SendUnsubscribeL
       
   769 // -----------------------------------------------------------------------------
       
   770 //
       
   771 CSIPClientTransaction*
       
   772 CSIPDialogImplementation::SendUnsubscribeL(CSIPSubscribeDialogAssoc& aAssoc,
       
   773                              			   CSIPMessageElements* aElements) const
       
   774     {
       
   775     __TEST_INVARIANT;
       
   776     return StateL().SendUnsubscribeL(aAssoc, aElements);
       
   777     }
       
   778 
       
   779 // -----------------------------------------------------------------------------
       
   780 // CSIPDialogImplementation::SendByeL
       
   781 // -----------------------------------------------------------------------------
       
   782 //
       
   783 CSIPClientTransaction*
       
   784 CSIPDialogImplementation::SendByeL(CSIPInviteDialogAssoc& aAssoc,
       
   785                      			   CSIPMessageElements* aElements) const
       
   786     {
       
   787     __TEST_INVARIANT;    
       
   788     return StateL().SendByeL(aAssoc, aElements);
       
   789     }
       
   790 
       
   791 // -----------------------------------------------------------------------------
       
   792 // CSIPDialogImplementation::SendCancelL
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 CSIPClientTransaction*
       
   796 CSIPDialogImplementation::SendCancelL(TUint32 aRequestId) const
       
   797     {
       
   798     __TEST_INVARIANT;
       
   799 
       
   800     CSIPTransactionBase* dummyTa = NULL;
       
   801     CSIPDialogAssocBase* assoc = NULL;
       
   802 	__ASSERT_ALWAYS(FindTransactionAndAssoc(aRequestId, &dummyTa, &assoc),
       
   803 					User::Leave(KErrSIPInvalidTransactionState));
       
   804 	__ASSERT_ALWAYS(assoc->Type() == SIPStrings::StringF(SipStrConsts::EInvite),
       
   805 					User::Leave(KErrSIPInvalidTransactionState));
       
   806     return static_cast<CSIPInviteDialogAssoc*>
       
   807     	(assoc)->DoSendCancelL(aRequestId);
       
   808     }
       
   809 
       
   810 // -----------------------------------------------------------------------------
       
   811 // CSIPDialogImplementation::SendNotifyL
       
   812 // -----------------------------------------------------------------------------
       
   813 //
       
   814 CSIPClientTransaction*
       
   815 CSIPDialogImplementation::SendNotifyL(CSIPNotifyDialogAssoc& aAssoc,
       
   816                         			  CSIPMessageElements* aElements) const
       
   817     {
       
   818     __TEST_INVARIANT;    
       
   819     return StateL().SendNotifyL(aAssoc, aElements);
       
   820     }
       
   821 
       
   822 // -----------------------------------------------------------------------------
       
   823 // CSIPDialogImplementation::SendReferL
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 CSIPClientTransaction*
       
   827 CSIPDialogImplementation::SendReferL(CSIPReferDialogAssoc& aAssoc,
       
   828                        				 CSIPMessageElements* aElements) const
       
   829    	{
       
   830    	__TEST_INVARIANT;    
       
   831     return StateL().SendReferL(*this, aAssoc, aElements);
       
   832    	}
       
   833 
       
   834 // -----------------------------------------------------------------------------
       
   835 // CSIPDialogImplementation::SendResponseL
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 void
       
   839 CSIPDialogImplementation::SendResponseL(const CSIPResponseElements& aElements,
       
   840 							            TUint32 aRequestId,
       
   841 			                            TBool aAffectsDialogState,
       
   842 			                            TBool aTargetRefresh)
       
   843     {
       
   844     __TEST_INVARIANT;
       
   845 
       
   846     StateL().SendResponseL(*this,
       
   847                            aElements,
       
   848                            aRequestId,
       
   849                            aAffectsDialogState,
       
   850                            aTargetRefresh);
       
   851     __TEST_INVARIANT;
       
   852     }
       
   853 
       
   854 // -----------------------------------------------------------------------------
       
   855 // CSIPDialogImplementation::SendRequestInDialogL
       
   856 // CSIPClientConnection checks that connection is active.
       
   857 // -----------------------------------------------------------------------------
       
   858 //
       
   859 CSIPClientTransaction* CSIPDialogImplementation::SendRequestInDialogL(
       
   860                                         CSIPDialogAssocImplementation& aAssoc,
       
   861                                         RStringF aMethod,
       
   862                                         CSIPMessageElements* aElements) const
       
   863     {
       
   864     __TEST_INVARIANT;
       
   865     CheckConnectionL();
       
   866 
       
   867 	CSIPClientTransaction* ta = CreateClientTransactionL(aMethod, aAssoc, NULL);
       
   868     CleanupStack::PushL(ta);
       
   869 
       
   870     TUint32 requestId(0);
       
   871     TUint32 dummyRefreshId(0); // Not used for non-refreshed requests
       
   872     iConnection->ClientConnectionL().SendRequestWithinDialogL(iDialogId,
       
   873 							  requestId,
       
   874 							  dummyRefreshId,
       
   875                               aMethod,
       
   876 							  aElements,
       
   877                               CSIPTransactionBase::IsTargetRefresh(aMethod));
       
   878 	CleanupStack::Pop(ta);
       
   879     ta->SetRequestId(requestId);
       
   880 
       
   881     delete aElements;
       
   882     return ta;
       
   883     }
       
   884 
       
   885 // -----------------------------------------------------------------------------
       
   886 // CSIPDialogImplementation::CreateClientTransactionL
       
   887 // -----------------------------------------------------------------------------
       
   888 //
       
   889 CSIPClientTransaction*
       
   890 CSIPDialogImplementation::CreateClientTransactionL(RStringF aType,                                     
       
   891                                      CSIPDialogAssocImplementation& aAssoc,                                     
       
   892                                      CSIPRefresh* aRefresh) const
       
   893     {
       
   894     __TEST_INVARIANT;
       
   895 
       
   896     if (aType == SIPStrings::StringF(SipStrConsts::EInvite))
       
   897         {
       
   898         __SIP_ASSERT_LEAVE(!aRefresh, KErrArgument);
       
   899         return CSIPInviteClientTransaction::NewL(aAssoc);
       
   900         }
       
   901 
       
   902     return CSIPClientTransaction::NewL(aType, aAssoc, aRefresh);
       
   903     }
       
   904 
       
   905 // -----------------------------------------------------------------------------
       
   906 // CSIPDialogImplementation::AddAssocL
       
   907 // Needs aType as aAssoc.Type can't be used as aAssoc::iImplementation is NULL
       
   908 // (CSIPDialogAssocImplementation::NewL hasn't returned yet). No invariant here.
       
   909 // -----------------------------------------------------------------------------
       
   910 //
       
   911 void CSIPDialogImplementation::AddAssocL(CSIPDialogAssocBase& aAssoc,
       
   912 										 RStringF aType)
       
   913     {
       
   914     __ASSERT_ALWAYS(iDialogAssocs.Find(&aAssoc) == KErrNotFound &&
       
   915         			(aType != SIPStrings::StringF(SipStrConsts::EInvite) ||
       
   916          			!HasInviteAssoc()), User::Leave(KErrAlreadyExists));    
       
   917     iDialogAssocs.AppendL(&aAssoc);
       
   918     }
       
   919 
       
   920 // -----------------------------------------------------------------------------
       
   921 // CSIPDialogImplementation::RemoveAssoc
       
   922 // CDeleteMgr isn't used, as it'd be in CSIP, which is not always accessible as
       
   923 // CSIPConnection and/or CSIP may've been deleted. Don't use invariant here.
       
   924 // -----------------------------------------------------------------------------
       
   925 //
       
   926 void CSIPDialogImplementation::RemoveAssoc(const CSIPDialogAssocBase& aAssoc)
       
   927     {
       
   928     //Returns KErrNotFound e.g. if CSIPDialogAssocImplementation::ConstructL
       
   929     //runs out of memory.
       
   930     TInt pos = iDialogAssocs.Find(&aAssoc);
       
   931     if (pos != KErrNotFound)
       
   932         {
       
   933 	    iDialogAssocs.Remove(pos);
       
   934 
       
   935 	    if (iDialogAssocs.Count() == 0)
       
   936 	        {
       
   937 	        delete this;
       
   938 	        }
       
   939         }
       
   940     }
       
   941 
       
   942 // -----------------------------------------------------------------------------
       
   943 // CSIPDialogImplementation::HasInviteAssoc
       
   944 // Don't use invariant here.
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 TBool CSIPDialogImplementation::HasInviteAssoc() const
       
   948     {
       
   949     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
   950         {
       
   951         if (iDialogAssocs[i]->Type() ==
       
   952         	SIPStrings::StringF(SipStrConsts::EInvite))
       
   953             {
       
   954             return ETrue;
       
   955             }
       
   956         }
       
   957 
       
   958     return EFalse;
       
   959     }
       
   960 
       
   961 // -----------------------------------------------------------------------------
       
   962 // CSIPDialogImplementation::ConnectionDeleted
       
   963 // As CSIPClientConnection is deleted, SIP client terminates all dialogs. So
       
   964 // TerminateDialog is not called here. Clear iState, as CSIPDialogImplementation
       
   965 // won't get noticed, when the CSIP owning the dialog states, is deleted.
       
   966 // -----------------------------------------------------------------------------
       
   967 //
       
   968 void CSIPDialogImplementation::ConnectionDeleted()
       
   969     {
       
   970     __TEST_INVARIANT;
       
   971 
       
   972     iState = NULL;
       
   973     iConnection = NULL;
       
   974 
       
   975     __TEST_INVARIANT;
       
   976     }
       
   977 
       
   978 // -----------------------------------------------------------------------------
       
   979 // CSIPDialogImplementation::CheckConnectionL
       
   980 // Don't use invariant here.
       
   981 // -----------------------------------------------------------------------------
       
   982 //
       
   983 void CSIPDialogImplementation::CheckConnectionL() const
       
   984     {
       
   985     __ASSERT_ALWAYS(iConnection, User::Leave(KErrSIPResourceNotAvailable));
       
   986     }
       
   987 
       
   988 // -----------------------------------------------------------------------------
       
   989 // CSIPDialogImplementation::StateL
       
   990 // -----------------------------------------------------------------------------
       
   991 //
       
   992 const CDialogState& CSIPDialogImplementation::StateL() const
       
   993     {
       
   994     __TEST_INVARIANT;
       
   995     __ASSERT_ALWAYS(iState != NULL, User::Leave(KErrSIPResourceNotAvailable));
       
   996     return *iState;
       
   997     }
       
   998 
       
   999 // -----------------------------------------------------------------------------
       
  1000 // CSIPDialogImplementation::UpdateState
       
  1001 // -----------------------------------------------------------------------------
       
  1002 //
       
  1003 void
       
  1004 CSIPDialogImplementation::UpdateState(const CSIPClientTransaction& aTransaction,
       
  1005 			                          const CDialogState& aEarly,
       
  1006 			                          const CDialogState& aConfirmed,
       
  1007 			                          const CDialogState& aTerminated)
       
  1008     {
       
  1009     __TEST_INVARIANT;
       
  1010 
       
  1011     const CSIPResponseElements* elem = aTransaction.ResponseElements();
       
  1012     __SIP_ASSERT_RETURN(elem != NULL, KErrArgument);
       
  1013 
       
  1014 	TUint status = elem->StatusCode();
       
  1015     if (aTransaction.AffectsDialogState())
       
  1016         {
       
  1017         if (status >= 300)
       
  1018             {
       
  1019             ChangeState(&aTerminated);
       
  1020             }
       
  1021         else if (status >= 200)
       
  1022             {
       
  1023             ChangeState(&aConfirmed);
       
  1024             }
       
  1025         else
       
  1026             {
       
  1027             if (status > 100 && State() == CSIPDialog::EInit)
       
  1028                 {
       
  1029                 ChangeState(&aEarly);
       
  1030                 }
       
  1031             }
       
  1032         }
       
  1033 
       
  1034     __TEST_INVARIANT;
       
  1035     }
       
  1036 
       
  1037 // -----------------------------------------------------------------------------
       
  1038 // CSIPDialogImplementation::CheckNoTransactionExistsL
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 void CSIPDialogImplementation::CheckNoTransactionExistsL() const
       
  1042     {
       
  1043     __TEST_INVARIANT;    
       
  1044     __ASSERT_ALWAYS(!iInitialRequestId, User::Leave(KErrSIPInvalidDialogState));
       
  1045     }
       
  1046 
       
  1047 // -----------------------------------------------------------------------------
       
  1048 // CSIPDialogImplementation::InitialTransactionStarted
       
  1049 // -----------------------------------------------------------------------------
       
  1050 //
       
  1051 void CSIPDialogImplementation::InitialTransactionStarted(TUint32 aRequestId)
       
  1052     {
       
  1053     __TEST_INVARIANT;
       
  1054     __SIP_ASSERT_RETURN(aRequestId, KErrArgument);
       
  1055     __SIP_ASSERT_RETURN(!iInitialRequestId, KErrAlreadyExists);
       
  1056 
       
  1057 	iInitialRequestId = aRequestId;
       
  1058 
       
  1059     __TEST_INVARIANT;
       
  1060     }
       
  1061 
       
  1062 // -----------------------------------------------------------------------------
       
  1063 // CSIPDialogImplementation::InitialTransactionStarted
       
  1064 // -----------------------------------------------------------------------------
       
  1065 //
       
  1066 void CSIPDialogImplementation::InitialTransactionStarted(
       
  1067 											CSIPTransactionBase& aTransaction)
       
  1068     {
       
  1069     __TEST_INVARIANT;
       
  1070 
       
  1071     InitialTransactionStarted(aTransaction.RequestId());
       
  1072     aTransaction.SetAffectsDialogState();
       
  1073 
       
  1074     __TEST_INVARIANT;
       
  1075     }
       
  1076 
       
  1077 // -----------------------------------------------------------------------------
       
  1078 // CSIPDialogImplementation::DoesNotifyConfirmDialog
       
  1079 // -----------------------------------------------------------------------------
       
  1080 //
       
  1081 TBool CSIPDialogImplementation::DoesNotifyConfirmDialog() const
       
  1082 	{
       
  1083 	__TEST_INVARIANT;
       
  1084 
       
  1085 	if (iInitialRequestId)
       
  1086 		{
       
  1087 		CSIPTransactionBase* ta = FindTransaction(iInitialRequestId);
       
  1088 		return (ta &&
       
  1089 				(ta->Type() == SIPStrings::StringF(SipStrConsts::ESubscribe) ||
       
  1090 				 ta->Type() == SIPStrings::StringF(SipStrConsts::ERefer)) &&
       
  1091 				ta->IsSIPClientTransaction());
       
  1092 		}
       
  1093 	return EFalse;
       
  1094 	}
       
  1095 
       
  1096 // -----------------------------------------------------------------------------
       
  1097 // CSIPDialogImplementation::ChangeRefreshesToActive
       
  1098 // Adding a virtual function CSIPDialogAssocBase::ChangeRefreshToActive breaks
       
  1099 // BC, so an ugly way like this is used.
       
  1100 // -----------------------------------------------------------------------------
       
  1101 //
       
  1102 void CSIPDialogImplementation::ChangeRefreshesToActive() const
       
  1103 	{
       
  1104 	__TEST_INVARIANT;
       
  1105 
       
  1106     for (TInt i = 0; i < iDialogAssocs.Count(); ++i)
       
  1107         {
       
  1108         if (iDialogAssocs[i]->Type() ==
       
  1109         	SIPStrings::StringF(SipStrConsts::ESubscribe))
       
  1110         	{
       
  1111         	const CSIPRefresh* rfr = static_cast<CSIPSubscribeDialogAssoc*>
       
  1112         		(iDialogAssocs[i])->SIPRefresh();
       
  1113 			if (rfr && rfr->State() == CSIPRefresh::EInactive)
       
  1114 				{
       
  1115 				//Get a modifiable pointer to the refresh
       
  1116 				CSIPRefresh* refresh =
       
  1117 					iDialogAssocs[i]->FindRefresh(rfr->RefreshId());
       
  1118 				__SIP_ASSERT_RETURN(refresh != NULL, KErrNotFound);
       
  1119 				refresh->ChangeState(CSIPRefresh::EActive);
       
  1120 				}
       
  1121         	}
       
  1122         }
       
  1123 	}
       
  1124 
       
  1125 // -----------------------------------------------------------------------------
       
  1126 // CSIPDialogImplementation::UpdateRemoteTargetL
       
  1127 // -----------------------------------------------------------------------------
       
  1128 //
       
  1129 void CSIPDialogImplementation::UpdateRemoteTargetL(RStringF aMethod,
       
  1130 									 const CSIPMessageElements& aElements)
       
  1131 	{
       
  1132 	__TEST_INVARIANT;
       
  1133 
       
  1134 	if (CSIPTransactionBase::IsTargetRefresh(aMethod))
       
  1135 		{
       
  1136 		CUri8* uri = GetUriFromContactL(aElements);
       
  1137 		if (uri)
       
  1138 			{
       
  1139 			delete iRemoteUri;
       
  1140 			iRemoteUri = uri;
       
  1141 			}
       
  1142 		}
       
  1143 	__TEST_INVARIANT;
       
  1144 	}
       
  1145 
       
  1146 // -----------------------------------------------------------------------------
       
  1147 // CSIPDialogImplementation::SetHeadersL
       
  1148 // -----------------------------------------------------------------------------
       
  1149 //
       
  1150 void CSIPDialogImplementation::SetHeadersL(CSIPFromHeader* aFrom,
       
  1151 			                               CSIPToHeader* aTo,
       
  1152 			                               CUri8* aRemoteUri,
       
  1153 			                               CSIPContactHeader* aContact)
       
  1154     {
       
  1155     __SIP_ASSERT_LEAVE(aRemoteUri, KErrArgument);
       
  1156     __SIP_ASSERT_LEAVE(!iFrom && !iTo && !iRemoteUri && !iContact,
       
  1157                        KErrAlreadyExists);
       
  1158    	if (!aFrom)
       
  1159         {
       
  1160         __SIP_ASSERT_LEAVE(iRegistration != NULL, KErrNotFound);
       
  1161         iFrom =
       
  1162             iConnection->ClientConnectionL().AorL(iRegistration->ContextId());
       
  1163         iFrom->DeleteParam(SIPStrings::StringF(SipStrConsts::ETag));
       
  1164         }
       
  1165 
       
  1166 	if (aTo)
       
  1167 		{
       
  1168 		iTo = aTo;
       
  1169 		}
       
  1170 	else
       
  1171 		{
       
  1172 		iTo = CSIPToHeader::DecodeL(aRemoteUri->Uri().UriDes());
       
  1173 		}
       
  1174 
       
  1175     if (aFrom)
       
  1176         {
       
  1177         iFrom = aFrom;
       
  1178         }
       
  1179 
       
  1180 	iRemoteUri = aRemoteUri;
       
  1181     iContact = aContact;
       
  1182 
       
  1183     __TEST_INVARIANT;
       
  1184     }
       
  1185 
       
  1186 // -----------------------------------------------------------------------------
       
  1187 // CSIPDialogImplementation::InitialTransactionReceivedL
       
  1188 // Request must have exactly one Contact header. Dialog subsystem hasn't checked
       
  1189 // that as request came outside dialog. iRemoteUri is set with the Contact URI.
       
  1190 // -----------------------------------------------------------------------------
       
  1191 //
       
  1192 void CSIPDialogImplementation::InitialTransactionReceivedL(
       
  1193 										CSIPServerTransaction& aTransaction)
       
  1194     {
       
  1195     __SIP_ASSERT_LEAVE(!iFrom && !iTo && !iRemoteUri, KErrAlreadyExists);
       
  1196 
       
  1197 	const CSIPRequestElements* elem = aTransaction.RequestElements();
       
  1198     __SIP_ASSERT_LEAVE(elem != NULL, KErrArgument);
       
  1199 
       
  1200 	//From includes the remote tag, if remote filled it
       
  1201 	iFrom = CSIPFromHeader::NewL(*elem->FromHeader());
       
  1202     iTo = CSIPToHeader::NewL(*elem->ToHeader());
       
  1203 	iRemoteUri = GetUriFromContactL(elem->MessageElements());
       
  1204 	InitialTransactionStarted(aTransaction);
       
  1205 
       
  1206 	if (!iRemoteUri)
       
  1207 		{
       
  1208 		CSIPResponseElements* resp = CSIPResponseElements::NewLC(400,
       
  1209         	SIPStrings::StringF(SipStrConsts::EPhraseBadRequest));
       
  1210         aTransaction.SendResponseL(resp);
       
  1211         CleanupStack::Pop(resp);
       
  1212         User::Leave(KErrSIPMalformedMessage);
       
  1213 		}
       
  1214 
       
  1215     __TEST_INVARIANT;
       
  1216     }
       
  1217 
       
  1218 // -----------------------------------------------------------------------------
       
  1219 // CSIPDialogImplementation::SendDialogCreatingRequestL
       
  1220 // -----------------------------------------------------------------------------
       
  1221 //
       
  1222 CSIPClientTransaction*
       
  1223 CSIPDialogImplementation::SendDialogCreatingRequestL(
       
  1224 									   CSIPDialogAssocImplementation& aAssoc,
       
  1225 									   CSIPMessageElements* aElements,
       
  1226 									   CSIPRefresh* aRefresh)
       
  1227 	{
       
  1228 	__TEST_INVARIANT;
       
  1229 	CheckConnectionL();
       
  1230 
       
  1231 	CSIPClientTransaction* ta =
       
  1232 		CreateClientTransactionL(aAssoc.Type(), aAssoc, aRefresh);
       
  1233     CleanupStack::PushL(ta);
       
  1234 
       
  1235     TUint32 requestId(0);
       
  1236 	TUint32 refreshId(0);
       
  1237 	iConnection->ClientConnectionL().SendRequestAndCreateDialogL(requestId,
       
  1238                          refreshId,
       
  1239 					     iDialogId,
       
  1240 						 aAssoc.Type(),
       
  1241 						 *iRemoteUri,
       
  1242 						 iFrom,
       
  1243 						 aElements,
       
  1244                      	 iTo,
       
  1245                      	 RegistrationId(),
       
  1246                      	 (aRefresh != NULL));
       
  1247 	ta->SetRequestId(requestId);
       
  1248 	InitialTransactionStarted(*ta);
       
  1249 	StoreCallIdL();
       
  1250 	FillLocalTagL(ETrue);
       
  1251 	CleanupStack::Pop(ta);
       
  1252 
       
  1253 	if (aRefresh)
       
  1254         {
       
  1255         aRefresh->SetRefreshIdIfEmpty(refreshId);
       
  1256         }
       
  1257 	delete aElements;
       
  1258 
       
  1259     //Contact can now be freed
       
  1260     delete iContact;
       
  1261     iContact = NULL;
       
  1262 
       
  1263 	return ta;
       
  1264 	}
       
  1265 
       
  1266 // -----------------------------------------------------------------------------
       
  1267 // CSIPDialogImplementation::ContactHeader
       
  1268 // -----------------------------------------------------------------------------
       
  1269 //
       
  1270 const CSIPContactHeader* CSIPDialogImplementation::ContactHeader() const
       
  1271 	{
       
  1272 	__TEST_INVARIANT;
       
  1273 	return iContact;
       
  1274 	}
       
  1275 
       
  1276 // -----------------------------------------------------------------------------
       
  1277 // CSIPDialogImplementation::GetUriFromContactL
       
  1278 // Don't use invariant here.
       
  1279 // -----------------------------------------------------------------------------
       
  1280 //
       
  1281 CUri8* CSIPDialogImplementation::GetUriFromContactL(
       
  1282 								const CSIPMessageElements& aElements) const
       
  1283 	{
       
  1284 	CUri8* uri = NULL;
       
  1285 	
       
  1286 	RStringF contact = SIPStrings::StringF(SipStrConsts::EContactHeader);
       
  1287 	if (aElements.UserHeaderCount(contact) == 1)
       
  1288 		{
       
  1289 		RPointerArray<CSIPHeaderBase> headers = aElements.UserHeadersL(contact);
       
  1290 		CleanupClosePushL(headers);
       
  1291 
       
  1292 		CSIPContactHeader* contactHeader =
       
  1293 			static_cast<CSIPContactHeader*>(headers[0]);
       
  1294 
       
  1295 		const CSIPAddress* addr = contactHeader->SIPAddress();
       
  1296 		if (addr)
       
  1297 			{
       
  1298 			uri = CUri8::NewL(addr->Uri8().Uri());
       
  1299 			}
       
  1300 	    CleanupStack::PopAndDestroy(); //headers
       
  1301 		}
       
  1302 	return uri;
       
  1303 	}
       
  1304 
       
  1305 // -----------------------------------------------------------------------------
       
  1306 // CSIPDialogImplementation::FillLocalTagL
       
  1307 // -----------------------------------------------------------------------------
       
  1308 //
       
  1309 void CSIPDialogImplementation::FillLocalTagL(TBool aClientInitiatedDialog) const
       
  1310 	{
       
  1311 	__TEST_INVARIANT;
       
  1312 	__SIP_ASSERT_LEAVE(iDialogId != 0, KErrNotFound);
       
  1313 
       
  1314 	RStringF tag = SIPStrings::StringF(SipStrConsts::ETag);
       
  1315 	CSIPFromToHeaderBase* header = iFrom;
       
  1316 	if (!aClientInitiatedDialog)
       
  1317 		{		
       
  1318 		header = iTo;
       
  1319 		}
       
  1320 
       
  1321 	if (!header->HasParam(tag))
       
  1322 		{
       
  1323 		CheckConnectionL();
       
  1324 		RStringF localTag =
       
  1325 			iConnection->ClientConnectionL().LocalTagL(iDialogId);
       
  1326 		CleanupClosePushL(localTag);
       
  1327 		header->SetParamL(tag, localTag);
       
  1328 		CleanupStack::PopAndDestroy(); //localTag
       
  1329 		}	
       
  1330 	}
       
  1331 
       
  1332 // -----------------------------------------------------------------------------
       
  1333 // CSIPDialogImplementation::FillRemoteTagL
       
  1334 // -----------------------------------------------------------------------------
       
  1335 //
       
  1336 void
       
  1337 CSIPDialogImplementation::FillRemoteTagL(const CSIPToHeader& aToHeader) const
       
  1338 	{
       
  1339 	__TEST_INVARIANT;
       
  1340 
       
  1341 	RStringF tag = SIPStrings::StringF(SipStrConsts::ETag);
       
  1342 	if (aToHeader.HasParam(tag))
       
  1343 		{
       
  1344 		iTo->SetParamL(tag, aToHeader.ParamValue(tag));
       
  1345 		}
       
  1346 	}
       
  1347 
       
  1348 // -----------------------------------------------------------------------------
       
  1349 // CSIPDialogImplementation::RegistrationId
       
  1350 // -----------------------------------------------------------------------------
       
  1351 //
       
  1352 TUint32 CSIPDialogImplementation::RegistrationId() const
       
  1353     {
       
  1354     return (iRegistration ? iRegistration->ContextId() : 0);
       
  1355     }
       
  1356 
       
  1357 // -----------------------------------------------------------------------------
       
  1358 // CSIPDialogImplementation::__DbgTestInvariant
       
  1359 // iState is NULL if CSIP has been deleted.
       
  1360 // Don't check iRemoteUri, as 400 response is sent when missing iRemoteUri from
       
  1361 // an incoming request that creates a dialog.
       
  1362 // -----------------------------------------------------------------------------
       
  1363 //
       
  1364 
       
  1365 void CSIPDialogImplementation::__DbgTestInvariant() const
       
  1366 	{
       
  1367 	if (!iDialog || !iFrom || !iTo)
       
  1368 		{
       
  1369 		User::Invariant();
       
  1370 		}
       
  1371 	}