realtimenetprots/sipfw/SIP/Dialogs/src/SipDialogMgr.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2005-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          : SipDialogMgr.cpp
       
    15 // Part of       : SIPDialogs
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "CSipDialogMgr.h"
       
    23 #include "sipfromheader.h"
       
    24 #include "DialogStateBase.h"
       
    25 #include "MSipRegistrationContact.h"
       
    26 #include "MTransactionUser.h"
       
    27 #include "MSipRefreshMgr.h"
       
    28 #include "MDialogOwner.h"
       
    29 #include "DeleteMgr.h"
       
    30 #include "sipcontactheader.h"
       
    31 #include "siprequest.h"
       
    32 #include "sipresponse.h"
       
    33 #include "siptoheader.h"
       
    34 #include "sipcallidheader.h"
       
    35 #include "sipcseqheader.h"
       
    36 #include "SipLogs.h"
       
    37 #include "sipaddress.h"
       
    38 #include "siphostport.h"
       
    39 #include "uricontainer.h"
       
    40 #include "sipuri.h"
       
    41 #include "sipcodecutils.h"
       
    42 #include "sipinternalstates.h"
       
    43 #include "MTransactionHeaders.h"
       
    44 #include "siprouteheader.h"
       
    45 #include "DialogsStore.h"
       
    46 #include "SipAssert.h"
       
    47 #include "RefreshItem.h"
       
    48 #include "TransactionItem.h"
       
    49 #include "TransactionItemStore.h"
       
    50 #include "Establishing.h"
       
    51 #include "Early.h"
       
    52 #include "Confirmed.h"
       
    53 #include "Terminated.h"
       
    54 #include "CSigCompMgr.h"
       
    55 #include "sipstrings.h"
       
    56 #include "sipstrconsts.h"
       
    57 #include "siperr.h"
       
    58 #include "TSIPTransportParams.h"
       
    59 
       
    60 _LIT8(KLocalHostSIPURI, "sip:localhost");
       
    61 const TUint K100Response = 100;
       
    62 const TUint K400Response = 400;
       
    63 const TUint K481Response = 481;
       
    64 
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CSipDialogMgr::NewL
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 CSipDialogMgr* CSipDialogMgr::NewL(
       
    71     MTransactionUser& aTU,
       
    72     MSipRefreshMgr& aRefreshMgr,
       
    73     MSipRegistrationContact& aRegistrationContact,
       
    74     CSIPSec& aSIPSec,
       
    75     MSigComp& aSigComp)
       
    76 	{
       
    77 	CSipDialogMgr* self = new(ELeave)CSipDialogMgr(aTU,aRefreshMgr, 
       
    78                                                    aRegistrationContact,
       
    79                                                    aSIPSec, aSigComp);	
       
    80 	CleanupStack::PushL(self);	
       
    81 	self->ConstructL();
       
    82 	CleanupStack::Pop(self);
       
    83 	return self;
       
    84 	}
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CSipDialogMgr::CSipDialogMgr
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 CSipDialogMgr::CSipDialogMgr (MTransactionUser& aTU,  
       
    91                               MSipRefreshMgr& aRefreshMgr,
       
    92 							  MSipRegistrationContact& aRegistratinonContact,
       
    93 							  CSIPSec& aSIPSec,
       
    94 							  MSigComp& aSigComp)
       
    95 : iTU(aTU), 
       
    96   iRefreshMgr(aRefreshMgr), 
       
    97   iRegistrationContact(aRegistratinonContact),
       
    98   iSIPSec(aSIPSec),
       
    99   iSigComp(aSigComp)
       
   100 	{
       
   101 	iContactHeaderName = SIPStrings::StringF(SipStrConsts::EContactHeader);
       
   102 	iRouteHeaderName = SIPStrings::StringF(SipStrConsts::ERouteHeader);
       
   103 	iTagParamName = SIPStrings::StringF(SipStrConsts::ETag);
       
   104     iPhraseCallTransactionDoesNotExist = 
       
   105         SIPStrings::StringF(SipStrConsts::EPhraseCallTransactionDoesNotExist);
       
   106     iPhraseBadRequest = SIPStrings::StringF(SipStrConsts::EPhraseBadRequest);
       
   107 	}
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CSipDialogMgr::ConstructL
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 void CSipDialogMgr::ConstructL ()
       
   114 	{
       
   115 	iDialogsStore = CDialogsStore::NewL();
       
   116 	iDeleteMgr = CDeleteMgr::NewL();
       
   117 	}
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CSipDialogMgr::~CSipDialogMgr
       
   121 // -----------------------------------------------------------------------------
       
   122 //
       
   123 CSipDialogMgr::~CSipDialogMgr ()
       
   124 	{
       
   125 	delete iDialogsStore;
       
   126 	delete iDeleteMgr;
       
   127 	}
       
   128 
       
   129 // -----------------------------------------------------------------------------
       
   130 // CSipDialogMgr::SendAndCreateDialogL
       
   131 // -----------------------------------------------------------------------------
       
   132 //
       
   133 void CSipDialogMgr::SendAndCreateDialogL (TTransactionId& aTransactionId,
       
   134                                           TRefreshId& aRefreshId,
       
   135                                           TRegistrationId aRegistrationId,
       
   136                                           TDialogId& aDialogId,
       
   137                                           CSIPRequest* aRequest,
       
   138                                           CURIContainer& aRemoteTarget,
       
   139                                           MDialogOwner* aOwner,
       
   140                                           MSIPSecUser& aSIPSecUser,
       
   141                                           TBool aRefresh)	
       
   142 	{
       
   143     __SIP_ASSERT_LEAVE(aOwner, KErrArgument);
       
   144 	__SIP_ASSERT_LEAVE(aRequest, KErrArgument);
       
   145 	__SIP_ASSERT_LEAVE(aRequest->To(), KErrSIPMalformedMessage);
       
   146 	__SIP_ASSERT_LEAVE(aRequest->From(), KErrSIPMalformedMessage);
       
   147 	__SIP_ASSERT_LEAVE(aRequest->Method().DesC().Length() > 0, 
       
   148                        KErrSIPMalformedMessage);
       
   149 	__SIP_ASSERT_LEAVE(aRequest->HeaderCount(iContactHeaderName) <= 1,
       
   150                        KErrSIPMalformedMessage);
       
   151 	__SIP_MESSAGE_LOG("Dialogs", *aRequest)
       
   152 
       
   153     TBool newDialogCreated = EFalse;
       
   154     CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   155     if (!dialog)
       
   156         {
       
   157 	    dialog = CSipDialogItem::NewLC(*iDialogsStore,aOwner,aSIPSecUser,iTU,
       
   158                                        iRefreshMgr,iSIPSec,*iDeleteMgr,
       
   159                                        iSigComp,aRegistrationId);
       
   160         newDialogCreated = ETrue;
       
   161         }
       
   162 
       
   163 	dialog->SetLocalAddressL(aRequest->From()->SIPAddress());
       
   164 	dialog->SetRemoteAddressL(aRequest->To()->SIPAddress());
       
   165 	dialog->SetInitialRemoteTargetL(aRemoteTarget);
       
   166 	dialog->SetRouteSetUsingRouteL(*aRequest);
       
   167 	AddContactHeaderL(dialog->IapId(),aRegistrationId,
       
   168 	                  *aRequest,aRequest->From());
       
   169 	dialog->SetLocalTargetWithMsgL(*aRequest,EFalse);
       
   170 
       
   171     CTransactionItemBase* transactionItem = 0;
       
   172 	if (aRefresh)
       
   173 		{
       
   174         transactionItem = CRefreshItem::NewLC(iRefreshMgr,dialog,
       
   175                                               *dialog,aRequest->Method());
       
   176 		}
       
   177 	else
       
   178 		{
       
   179         transactionItem = CTransactionItem::NewLC(iTU,dialog,
       
   180                                                   aRequest->Method());
       
   181         }
       
   182     transactionItem->SetTargetRefresh();
       
   183 
       
   184 	dialog->CurrentState().SendL(aTransactionId,aRequest,*transactionItem,
       
   185 	                             *dialog->RemoteTarget());
       
   186     
       
   187     dialog->TransactionItems().AddItem(transactionItem);
       
   188     CleanupStack::Pop(transactionItem);
       
   189     dialog->SetFirstTransactionId(aTransactionId);
       
   190     
       
   191     if (newDialogCreated)
       
   192         {
       
   193         aDialogId = dialog->DialogId();
       
   194 	    iDialogsStore->AddDialogItem(dialog);
       
   195 	    CleanupStack::Pop(dialog);
       
   196         }
       
   197 	
       
   198 	if (aRefresh)
       
   199 	    {
       
   200 	    aRefreshId = static_cast<CRefreshItem*>(transactionItem)->RefreshId();
       
   201 	    }
       
   202 	}
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CSipDialogMgr::SendWithinDialogL
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 void CSipDialogMgr::SendWithinDialogL (TTransactionId& aTransactionId,
       
   209                                        TRefreshId& aRefreshId,
       
   210                                        const TDialogId& aDialogId,
       
   211                                        CSIPRequest* aRequest,
       
   212                                        const MDialogOwner* aOwner,
       
   213                                        TBool aRefresh,
       
   214                                        TBool aAllowOverlap, 
       
   215                                        TBool aTargetRefresh)
       
   216 	{
       
   217 	__SIP_ASSERT_LEAVE(aDialogId, KErrArgument);
       
   218 	__SIP_ASSERT_LEAVE(aRequest, KErrArgument);
       
   219 	__SIP_ASSERT_LEAVE(aRequest->Method().DesC().Length() != 0, 
       
   220                        KErrSIPMalformedMessage);
       
   221 	__SIP_ASSERT_LEAVE(aRequest->HeaderCount(iContactHeaderName) <= 1, 
       
   222                        KErrSIPMalformedMessage);
       
   223 	__ASSERT_ALWAYS(!aRequest->HasHeader(iRouteHeaderName), 
       
   224                     User::Leave(KErrSIPMalformedMessage));
       
   225 	
       
   226 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   227 	__ASSERT_ALWAYS(dialog, User::Leave(KErrSIPInvalidDialogState));
       
   228 	__ASSERT_ALWAYS(dialog->CurrentState().RequestsWithinDialogAllowed(),
       
   229 					User::Leave(KErrSIPInvalidDialogState));
       
   230 
       
   231 	RStringF method = aRequest->Method();
       
   232 	if (dialog->TransactionItems().OverlappingRestricted(method))
       
   233         {
       
   234 		User::Leave(KErrSIPRequestPending);
       
   235         }
       
   236 
       
   237 	__SIP_MESSAGE_LOG("Dialogs", *aRequest)
       
   238 	
       
   239 	dialog->AddToHeaderInDialogL(*aRequest);
       
   240 	dialog->AddFromHeaderInDialogL(*aRequest);
       
   241 	dialog->AddCallIdHeaderInDialogL(*aRequest);
       
   242 	dialog->AddRouteToMessageL(*aRequest);
       
   243 	AddContactHeaderL(*dialog,*aRequest,aRequest->From(),aTargetRefresh);
       
   244 	if (aTargetRefresh)
       
   245 		{
       
   246 		dialog->UpdateLocalTargetL(*aRequest);
       
   247 		}
       
   248 	if (method != SIPStrings::StringF(SipStrConsts::EAck))
       
   249         {
       
   250 		dialog->AddCSeqHeaderInDialogL(*aRequest);
       
   251         }		
       
   252 	
       
   253     CTransactionItemBase* transactionItem = 0;
       
   254 	if (aRefresh)
       
   255 		{
       
   256         transactionItem = 
       
   257 			CRefreshItem::NewLC(iRefreshMgr,dialog,*dialog,method);
       
   258 		}
       
   259     else
       
   260         {
       
   261         transactionItem = CTransactionItem::NewLC(iTU,dialog,method);
       
   262         }
       
   263     transactionItem->SetOverlappingRestricted(!aAllowOverlap);
       
   264     transactionItem->SetTargetRefresh(aTargetRefresh);
       
   265 
       
   266 	dialog->CurrentState().SendL(aTransactionId,aRequest,*transactionItem,
       
   267 	                             *dialog->RemoteTarget());
       
   268 
       
   269     dialog->TransactionItems().AddItem(transactionItem);
       
   270 	CleanupStack::Pop(transactionItem);
       
   271 	if (aRefresh)
       
   272 	    {
       
   273 	    aRefreshId = static_cast<CRefreshItem*>(transactionItem)->RefreshId();
       
   274 	    }
       
   275 	}
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CSipDialogMgr::SendAndUpdateRefreshL
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 void CSipDialogMgr::SendAndUpdateRefreshL (TTransactionId& aTransactionId,
       
   282                                            const TRefreshId& aRefreshId,
       
   283                                            const TDialogId& aDialogId,
       
   284                                            CSIPRequest* aRequest,
       
   285                                            const MDialogOwner* aOwner)
       
   286     {
       
   287 	__SIP_ASSERT_LEAVE(aRefreshId, KErrArgument);
       
   288 	__SIP_ASSERT_LEAVE(aDialogId, KErrArgument);
       
   289 	__SIP_ASSERT_LEAVE(aRequest, KErrArgument);
       
   290 	__SIP_ASSERT_LEAVE(aRequest->HeaderCount(iContactHeaderName) <= 1, 
       
   291                        KErrSIPMalformedMessage);
       
   292 	__ASSERT_ALWAYS (!aRequest->HasHeader(iRouteHeaderName), 
       
   293                      User::Leave(KErrSIPMalformedMessage));
       
   294 	
       
   295 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   296 	__ASSERT_ALWAYS(dialog, User::Leave(KErrSIPInvalidDialogState));
       
   297 	__ASSERT_ALWAYS(dialog->CurrentState().RequestsWithinDialogAllowed(),
       
   298 					User::Leave(KErrSIPInvalidDialogState));
       
   299 
       
   300     CTransactionItemBase* refreshItem = 
       
   301         dialog->TransactionItems().FindRefreshItem(aRefreshId);
       
   302     __ASSERT_ALWAYS(refreshItem,User::Leave(KErrSIPInvalidTransactionState));
       
   303 
       
   304 	__SIP_MESSAGE_LOG("Dialogs", *aRequest)
       
   305 	
       
   306 	dialog->AddToHeaderInDialogL(*aRequest);
       
   307 	dialog->AddFromHeaderInDialogL(*aRequest);
       
   308 	dialog->AddCallIdHeaderInDialogL(*aRequest);
       
   309     if (aRequest->Method().DesC().Length() == 0)
       
   310         {
       
   311         aRequest->SetMethodL(refreshItem->Method());
       
   312         }
       
   313 	dialog->AddRouteToMessageL(*aRequest);
       
   314     TBool targetRefresh = refreshItem->TargetRefresh();
       
   315 	AddContactHeaderL(*dialog,*aRequest,aRequest->From(),targetRefresh);
       
   316 	if (targetRefresh)
       
   317 		{
       
   318 		dialog->UpdateLocalTargetL(*aRequest);
       
   319 		}
       
   320 	dialog->CurrentState().SendL(aTransactionId,aRequest,*refreshItem,
       
   321 	                             *dialog->RemoteTarget());
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CSipDialogMgr::SendAndCreateDialogL
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CSipDialogMgr::SendAndCreateDialogL (const TTransactionId& aTransactionId,
       
   329 										  TRegistrationId aRegistrationId,
       
   330                                           TDialogId& aDialogId,
       
   331                                           CSIPResponse* aResponse,
       
   332                                           MDialogOwner* aOwner,
       
   333                                           MSIPSecUser& aSIPSecUser)
       
   334 	{
       
   335 	__SIP_ASSERT_LEAVE (aTransactionId != 0, KErrArgument);
       
   336 	__SIP_ASSERT_LEAVE (!aDialogId, KErrNotSupported);
       
   337 	__SIP_ASSERT_LEAVE (aResponse, KErrArgument);
       
   338 	__SIP_ASSERT_LEAVE (aOwner, KErrArgument);
       
   339 	__SIP_ASSERT_LEAVE (aResponse->ResponseCode() > K100Response, KErrArgument);
       
   340 
       
   341 	__SIP_MESSAGE_LOG("Dialogs", *aResponse)
       
   342 	
       
   343 	
       
   344 	CSipDialogItem* dialog = 
       
   345         CSipDialogItem::NewLC(*iDialogsStore,aOwner,aSIPSecUser,
       
   346                               iTU,iRefreshMgr,iSIPSec,*iDeleteMgr,iSigComp, aRegistrationId);
       
   347     TSIPTransportParams transportParams(
       
   348         dialog->TransportParams(aRegistrationId));
       
   349     
       
   350 	MTransactionHeaders* trHeaders = iTU.TransactionHeadersL(aTransactionId);
       
   351 	__ASSERT_ALWAYS(trHeaders, User::Leave(KErrSIPInvalidTransactionState));
       
   352     TCleanupItem cleanupItem(DeleteTransactionHeaders,trHeaders);
       
   353 	CleanupStack::PushL (cleanupItem);
       
   354 
       
   355 	// Remote target 
       
   356     CSIPContactHeader* remoteContact = 
       
   357         ExtractContactL(aTransactionId,*trHeaders,transportParams,ETrue);
       
   358     CleanupStack::PushL(remoteContact);
       
   359 	dialog->SetRemoteTargetL(remoteContact->SIPAddress()->URI());
       
   360 	CleanupStack::PopAndDestroy(remoteContact);
       
   361 
       
   362 	// Remote CSeq
       
   363 	dialog->SetRemoteSeqNum(trHeaders->CSeqNumber());
       
   364 
       
   365 	// Call-ID 
       
   366 	CSIPCallIDHeader* callId = trHeaders->CallIDHeader();
       
   367 	__SIP_ASSERT_LEAVE(callId, KErrSIPInvalidDialogRequest);
       
   368 	dialog->SetCallId(callId);
       
   369 
       
   370     // Route-set
       
   371 	RPointerArray<CSIPRouteHeaderBase>* route = trHeaders->RecordRoute();
       
   372 	if (route)
       
   373 		{
       
   374 		TCleanupItem routeCleanupItem(DeleteRouteSet,route);
       
   375 		CleanupStack::PushL (routeCleanupItem);
       
   376 		CheckRecordRouteL(aTransactionId,*route,transportParams);
       
   377 		dialog->SetRouteSetL(*route);
       
   378 		CleanupStack::PopAndDestroy(1);// routeCleanupItem
       
   379 		}
       
   380 
       
   381     // From
       
   382 	CSIPFromHeader* from = trHeaders->FromHeader();
       
   383 	CleanupStack::PushL(from);
       
   384 	__SIP_ASSERT_LEAVE(from, KErrSIPInvalidDialogRequest);
       
   385 	dialog->SetRemoteAddressL(from->SIPAddress());
       
   386 	if (from->HasParam(iTagParamName))
       
   387         {
       
   388 		dialog->SetRemoteTagL(from);
       
   389         }
       
   390 	aResponse->AddHeaderL(from);
       
   391 	CleanupStack::Pop(from);
       
   392 
       
   393 	// To
       
   394 	CSIPToHeader* to = trHeaders->ToHeader();
       
   395 	CleanupStack::PushL(to);
       
   396 	__SIP_ASSERT_LEAVE(to, KErrSIPInvalidDialogRequest);    
       
   397 	dialog->SetLocalAddressL(to->SIPAddress());
       
   398 	if (!to->HasParam(iTagParamName))
       
   399         {
       
   400 		HBufC8* tagBuf = HBufC8::NewLC(MTransactionUser::KTagLength);
       
   401 		TPtr8 tagPtr = tagBuf->Des();
       
   402 		iTU.MakeTagL(tagPtr);
       
   403 		RStringF tag = SIPStrings::Pool().OpenFStringL(tagPtr);
       
   404 		CleanupClosePushL(tag);
       
   405         to->SetParamL(iTagParamName,tag);
       
   406         CleanupStack::PopAndDestroy(); // tag
       
   407         CleanupStack::PopAndDestroy(tagBuf); 
       
   408 		}
       
   409 	dialog->SetLocalTag(to->ParamValue(iTagParamName));
       
   410 	aResponse->AddHeaderL(to);
       
   411 	CleanupStack::Pop(to);
       
   412 
       
   413 	// Local target (Contact)
       
   414 	CURIContainer* requestURI = trHeaders->RequestURI();
       
   415 	__SIP_ASSERT_LEAVE(requestURI, KErrSIPInvalidDialogRequest);
       
   416 	CleanupStack::PushL(requestURI);
       
   417 	if (!aResponse->IsErrorResponse())
       
   418 	    {
       
   419 	    AddContactHeaderL(dialog->IapId(),*aResponse,aResponse->To(),
       
   420 	                      *requestURI);
       
   421 	    }
       
   422 	CleanupStack::PopAndDestroy(requestURI);
       
   423 	dialog->SetLocalTargetWithMsgL(*aResponse);
       
   424 
       
   425 	dialog->AddRecordRouteToMessageL(*aResponse);
       
   426 	dialog->AddCallIdHeaderInDialogL(*aResponse);
       
   427 	dialog->SetFirstTransactionId(aTransactionId);
       
   428 
       
   429     CTransactionItem* transactionItem = 
       
   430         CTransactionItem::NewLC(iTU,dialog,aTransactionId);
       
   431 	dialog->CurrentState().SendL(*transactionItem,aResponse);
       
   432     dialog->TransactionItems().AddItem(transactionItem);
       
   433 	iDialogsStore->AddDialogItem(dialog);
       
   434 
       
   435     aDialogId = dialog->DialogId();
       
   436 
       
   437     CleanupStack::Pop(transactionItem); 
       
   438     CleanupStack::PopAndDestroy(); // trHeaders
       
   439     CleanupStack::Pop(dialog);
       
   440 	}
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CSipDialogMgr::SendWithinDialogL
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 void CSipDialogMgr::SendWithinDialogL (const TTransactionId& aTransactionId,
       
   447                                        const TDialogId& aDialogId,
       
   448                                        CSIPResponse* aResponse,
       
   449                                        const MDialogOwner* aOwner,
       
   450                                        TBool aTargetRefresh)
       
   451 	{
       
   452 	__SIP_ASSERT_LEAVE (aTransactionId, KErrArgument);
       
   453 	__SIP_ASSERT_LEAVE (aDialogId, KErrSIPInvalidDialogState);
       
   454 	__SIP_ASSERT_LEAVE (aResponse, KErrArgument);
       
   455 	__SIP_ASSERT_LEAVE (aResponse->ResponseCode() > K100Response, KErrArgument);
       
   456 
       
   457 	__SIP_MESSAGE_LOG("Dialogs", *aResponse)
       
   458 
       
   459 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   460 	__ASSERT_ALWAYS(dialog, User::Leave(KErrSIPInvalidDialogState));
       
   461     CTransactionItemBase* transactionItem = 
       
   462         dialog->TransactionItems().FindItem(aTransactionId);
       
   463     __ASSERT_ALWAYS(transactionItem,
       
   464                     User::Leave(KErrSIPInvalidTransactionState));
       
   465 
       
   466 	MTransactionHeaders* trHeaders = iTU.TransactionHeadersL(aTransactionId);
       
   467 	__ASSERT_ALWAYS(trHeaders, User::Leave(KErrSIPInvalidTransactionState));
       
   468     TCleanupItem cleanupItem(DeleteTransactionHeaders,trHeaders);
       
   469 	CleanupStack::PushL (cleanupItem);
       
   470  
       
   471     // To
       
   472 	CSIPToHeader* to = trHeaders->ToHeader();
       
   473 	CleanupStack::PushL(to);
       
   474 	if (!to->HasParam(iTagParamName))
       
   475 		{
       
   476 		to->SetParamL(iTagParamName,dialog->LocalTag());
       
   477 		}
       
   478 	aResponse->AddHeaderL(to);
       
   479 	CleanupStack::Pop(to);
       
   480     
       
   481     // Add Record-Route only to the responses to the first transaction
       
   482     if (aTransactionId == dialog->FirstTransactionId())
       
   483         {
       
   484 	    dialog->AddRecordRouteToMessageL(*aResponse);
       
   485         }
       
   486 
       
   487     // Remote and local target
       
   488 	if (!aResponse->IsErrorResponse())
       
   489 	    {    
       
   490         AddContactHeaderL(*dialog,*aResponse,aResponse->To(),aTargetRefresh);
       
   491 	    }
       
   492 	if (aTargetRefresh && aResponse->Type() == CSIPResponse::E2XX)
       
   493 		{		
       
   494 		CSIPContactHeader* remoteContact = 
       
   495 		    ExtractContactL(aTransactionId,*trHeaders,
       
   496                             dialog->TransportParams(KEmptyRegistrationId),
       
   497                             EFalse);
       
   498 		if (remoteContact) 
       
   499 		    {
       
   500 		    CleanupStack::PushL(remoteContact);
       
   501             CURIContainer& remoteTarget = remoteContact->SIPAddress()->URI();
       
   502     	    dialog->SetRemoteTargetL(remoteTarget);
       
   503     		CleanupStack::PopAndDestroy(remoteContact);		    
       
   504 		    }    
       
   505 		dialog->UpdateLocalTargetL(*aResponse);
       
   506 		}
       
   507     CleanupStack::PopAndDestroy(); // trHeaders
       
   508 	dialog->CurrentState().SendL(*transactionItem, aResponse);	
       
   509 	}
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CSipDialogMgr::TerminateDialog
       
   513 // -----------------------------------------------------------------------------
       
   514 //
       
   515 TInt CSipDialogMgr::TerminateDialog (const TDialogId& aDialogId,
       
   516                                      const MDialogOwner* aOwner)
       
   517 	{
       
   518 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   519 	if(!dialog) 
       
   520         {
       
   521 		return KErrNotFound;
       
   522         }
       
   523 	return iDialogsStore->Remove(dialog);
       
   524 	}
       
   525 
       
   526 // -----------------------------------------------------------------------------
       
   527 // CSipDialogMgr::TerminateDialogsFor
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 TInt CSipDialogMgr::TerminateDialogsFor (const MDialogOwner* aOwner)
       
   531     {
       
   532     return iDialogsStore->RemoveAllWith(aOwner);
       
   533     }
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CSipDialogMgr::TerminateDialogRefresh
       
   537 // -----------------------------------------------------------------------------
       
   538 //
       
   539 TInt CSipDialogMgr::TerminateDialogRefresh (const TDialogId& aDialogId,
       
   540 											const TRefreshId& aRefreshId,
       
   541 											const MDialogOwner* aOwner)
       
   542     {
       
   543 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   544     if (!dialog)
       
   545         {
       
   546         return KErrNotFound;
       
   547         }
       
   548     CTransactionItemBase* refreshItem = 
       
   549         dialog->TransactionItems().FindRefreshItem(aRefreshId);
       
   550     if (!refreshItem)
       
   551         {
       
   552         return KErrNotFound;
       
   553         }
       
   554     return dialog->TransactionItems().RemoveItem(refreshItem->Id());
       
   555     }
       
   556 
       
   557 // -----------------------------------------------------------------------------
       
   558 // CSipDialogMgr::GetStateL
       
   559 // -----------------------------------------------------------------------------
       
   560 //
       
   561 void CSipDialogMgr::GetStateL (const TDialogId& aDialogId, 
       
   562                                CSIPInternalStates::TState& aState)
       
   563     {
       
   564 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId);
       
   565     if (!dialog)
       
   566         {
       
   567         User::Leave(KErrNotFound);
       
   568         }
       
   569 	dialog->CurrentState().GetState(aState);
       
   570     }
       
   571     
       
   572 // -----------------------------------------------------------------------------
       
   573 // CSipDialogMgr::CallIDL
       
   574 // -----------------------------------------------------------------------------
       
   575 //    
       
   576 const CSIPCallIDHeader& CSipDialogMgr::CallIDL (const TDialogId& aDialogId,
       
   577                                                 const MDialogOwner* aOwner)
       
   578     {
       
   579 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   580     if (!dialog)
       
   581         {
       
   582 	    User::Leave(KErrNotFound);
       
   583         }
       
   584     if (!dialog->CallId())
       
   585         {
       
   586 	    User::Leave(KErrNotFound);
       
   587         }         
       
   588     return *(dialog->CallId());
       
   589     }
       
   590     
       
   591 // -----------------------------------------------------------------------------
       
   592 // CSipDialogMgr::LocalTagL
       
   593 // -----------------------------------------------------------------------------
       
   594 //     
       
   595 const TDesC8& CSipDialogMgr::LocalTagL(const TDialogId& aDialogId,
       
   596 	                                   const MDialogOwner* aOwner)
       
   597     {
       
   598 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   599     if (!dialog)
       
   600         {
       
   601 	    User::Leave(KErrNotFound);
       
   602         }
       
   603     return dialog->LocalTag().DesC();
       
   604     }
       
   605 
       
   606 // -----------------------------------------------------------------------------
       
   607 // CSipDialogMgr::ResetStateL
       
   608 // -----------------------------------------------------------------------------
       
   609 //
       
   610 void CSipDialogMgr::ResetStateL(const TDialogId& aDialogId,
       
   611                                 const MDialogOwner* aOwner)
       
   612     {
       
   613 	CSipDialogItem* dialog = iDialogsStore->FindDialogItem(aDialogId,aOwner);
       
   614     if (!dialog)
       
   615         {
       
   616 	    User::Leave(KErrNotFound);
       
   617         }
       
   618     dialog->ResetStateL();
       
   619     }
       
   620 
       
   621 // -----------------------------------------------------------------------------
       
   622 // CSipDialogMgr::SIPSecUserForTransaction
       
   623 // -----------------------------------------------------------------------------
       
   624 //
       
   625 const MSIPSecUser* CSipDialogMgr::SIPSecUserForTransaction(
       
   626     const TTransactionId& aTransactionId)
       
   627     {
       
   628     return iDialogsStore->FindDialogItemByTransaction(aTransactionId);
       
   629     }
       
   630 
       
   631 // -----------------------------------------------------------------------------
       
   632 // CSipDialogMgr::TransactionOwnerL
       
   633 // -----------------------------------------------------------------------------
       
   634 //
       
   635 MTransactionOwner* CSipDialogMgr::TransactionOwnerL (CSIPRequest& aRequest,
       
   636 													 CSIPResponse** aResponse)
       
   637 	{
       
   638 	if (aRequest.To() && !(aRequest.To()->HasParam(iTagParamName)))
       
   639         {
       
   640 		return 0;
       
   641         }
       
   642 	CSipDialogItem* dialog = iDialogsStore->DialogItemForRequest(&aRequest);
       
   643 	if (!dialog)
       
   644 		{
       
   645 		*aResponse = 
       
   646 		    CSIPResponse::NewL(K481Response,iPhraseCallTransactionDoesNotExist);
       
   647 		}
       
   648 	return dialog;
       
   649 	}
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CSipDialogMgr::ConnectionStateChangedL
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 void CSipDialogMgr::ConnectionStateChangedL (TUint32 aIapId,
       
   656 											 CSIPConnection::TState aState)
       
   657 	{
       
   658 	if (aState == CSIPConnection::EInactive ||
       
   659         aState == CSIPConnection::EUnavailable)
       
   660         {
       
   661 		iDialogsStore->DeleteItemsWithThisIapId(aIapId);
       
   662         }
       
   663 	}
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CSipDialogMgr::ExtractContactL
       
   667 // -----------------------------------------------------------------------------
       
   668 //
       
   669 CSIPContactHeader* CSipDialogMgr::ExtractContactL (
       
   670     TTransactionId aTransactionId,
       
   671     MTransactionHeaders& aHeaders,
       
   672     const TSIPTransportParams& aParams,
       
   673     TBool aContactMandatory)
       
   674     {
       
   675     RPointerArray<CSIPContactHeader>* contacts = aHeaders.Contact();
       
   676     TCleanupItem contactsCleanupItem(DeleteContacts,contacts);
       
   677 	CleanupStack::PushL(contactsCleanupItem);    
       
   678     CSIPContactHeader* contact = NULL; 
       
   679     if (contacts && contacts->Count() == 1)
       
   680         {
       
   681         contact = (*contacts)[0];
       
   682         contacts->Remove(0);
       
   683         CleanupStack::PushL(contact);
       
   684         if (!CSipDialogItem::ContactOk(*contact))
       
   685             {
       
   686             SendErrorResponseAndLeaveL(aTransactionId,
       
   687                                        KErrSIPInvalidURIType,
       
   688                                        aParams);
       
   689             }
       
   690         CleanupStack::Pop(contact);      
       
   691         }
       
   692     if (!contact && aContactMandatory)
       
   693         {
       
   694         SendErrorResponseAndLeaveL(aTransactionId,
       
   695                                    KErrSIPInvalidDialogRequest,
       
   696                                    aParams);
       
   697         }
       
   698     CleanupStack::PopAndDestroy(1); // contactsCleanupItem
       
   699     return contact;
       
   700     }
       
   701     
       
   702 // -----------------------------------------------------------------------------
       
   703 // CSipDialogMgr::CheckRecordRouteL
       
   704 // -----------------------------------------------------------------------------
       
   705 //    
       
   706 void CSipDialogMgr::CheckRecordRouteL (
       
   707     TTransactionId aTransactionId,
       
   708     RPointerArray<CSIPRouteHeaderBase>& aRecordRoute,
       
   709     const TSIPTransportParams& aParams)
       
   710     {
       
   711     // For an incoming request creating a dialog it must be checked 
       
   712     // that the first Record-Route-header (the next hop) has a SIP-URI.
       
   713     TInt count = aRecordRoute.Count();
       
   714     if (count > 0)
       
   715         {
       
   716         CSIPRouteHeaderBase* nextHop = aRecordRoute[0];
       
   717         if (!nextHop->SIPAddress().URI().IsSIPURI())
       
   718             {
       
   719             SendErrorResponseAndLeaveL(aTransactionId,KErrSIPInvalidURIType,
       
   720                                        aParams);      
       
   721             }
       
   722         }
       
   723     }
       
   724 
       
   725 // -----------------------------------------------------------------------------
       
   726 // CSipDialogMgr::AddContactHeaderL
       
   727 // -----------------------------------------------------------------------------
       
   728 //
       
   729 void CSipDialogMgr::AddContactHeaderL (TUint32 aIapId,
       
   730                                        TRegistrationId aRegistrationId,
       
   731 									   CSIPRequest& aRequest,
       
   732 									   const CSIPFromHeader* aFrom)
       
   733 	{
       
   734 	if (!aRequest.HasHeader(iContactHeaderName))
       
   735 		{
       
   736 		CreateAndAddContactL(aIapId,aRegistrationId,aRequest,aFrom);
       
   737 		}
       
   738 	else
       
   739 		{
       
   740 		FillHostInContactL(aIapId,aRegistrationId,aRequest,aFrom);
       
   741 		}
       
   742 	}
       
   743 
       
   744 // -----------------------------------------------------------------------------
       
   745 // CSipDialogMgr::AddContactHeaderL
       
   746 // -----------------------------------------------------------------------------
       
   747 //
       
   748 void CSipDialogMgr::AddContactHeaderL (TUint32 aIapId,
       
   749 									   CSIPResponse& aResponse,
       
   750 									   const CSIPToHeader* aTo,
       
   751 									   const CURIContainer& aRequestUri)
       
   752 	{
       
   753 	if (!aResponse.HasHeader(iContactHeaderName))
       
   754 		{
       
   755 		CreateAndAddContactL(aRequestUri,aResponse);
       
   756 		}
       
   757 	else
       
   758 		{
       
   759 		FillHostInContactL(aIapId,KEmptyRegistrationId,aResponse,aTo);
       
   760 		}
       
   761 	}
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // CSipDialogMgr::AddContactHeaderL
       
   765 // -----------------------------------------------------------------------------
       
   766 //
       
   767 void CSipDialogMgr::AddContactHeaderL (CSipDialogItem& aDialog, 
       
   768                                        CSIPMessage& aMessage,
       
   769 									   const CSIPFromToHeaderBase* aFromTo,
       
   770                                        TBool aTargetRefresh)
       
   771 	{
       
   772 	if (!aMessage.HasHeader(iContactHeaderName))
       
   773 		{
       
   774 		if (aTargetRefresh)
       
   775             {
       
   776  	        CSIPContactHeader* contact = 
       
   777  	            static_cast<CSIPContactHeader*>(
       
   778  	                aDialog.LocalTarget()->CloneL());
       
   779 	        CleanupStack::PushL(contact);
       
   780 	        aMessage.AddHeaderL(contact);
       
   781 	        CleanupStack::Pop(contact);
       
   782             }
       
   783 		}
       
   784 	else
       
   785 		{
       
   786 		FillHostInContactL(aDialog.IapId(),aDialog.RegistrationId(),
       
   787 		                   aMessage,aFromTo);
       
   788 		}
       
   789 	}
       
   790 
       
   791 // -----------------------------------------------------------------------------
       
   792 // CSipDialogMgr::CreateAndAddContactL
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 void CSipDialogMgr::CreateAndAddContactL (TUint32 aIapId,
       
   796                                           TRegistrationId aRegistrationId,
       
   797                                           CSIPMessage& aMessage,
       
   798                                           const CSIPFromToHeaderBase* aFromTo)
       
   799 	{
       
   800 	// Create and and Contact with empty host
       
   801 	CURIContainer* uri = CURIContainer::DecodeL(KLocalHostSIPURI);
       
   802 	CleanupStack::PushL(uri);
       
   803 	CreateAndAddContactL(*uri,aMessage);
       
   804 	CleanupStack::PopAndDestroy(uri);
       
   805 	// Fill host
       
   806 	FillHostInContactL(aIapId,aRegistrationId,aMessage,aFromTo);
       
   807 	}
       
   808 
       
   809 // -----------------------------------------------------------------------------
       
   810 // CSipDialogMgr::FillHostInContactL
       
   811 // -----------------------------------------------------------------------------
       
   812 //
       
   813 void CSipDialogMgr::FillHostInContactL (TUint32 aIapId,
       
   814                                         TRegistrationId aRegistrationId,
       
   815 										CSIPMessage& aMessage,
       
   816 										const CSIPFromToHeaderBase* aFromTo)
       
   817 	{
       
   818 	__SIP_ASSERT_LEAVE (aFromTo != 0, KErrArgument);	
       
   819 	
       
   820 	CSIPContactHeader* contact = 
       
   821         static_cast<CSIPContactHeader*>(
       
   822             aMessage.Header(iContactHeaderName,0));
       
   823 
       
   824 	__SIP_ASSERT_LEAVE (contact != 0, KErrArgument);
       
   825 	__SIP_ASSERT_LEAVE (contact->SIPAddress() != 0, KErrArgument);
       
   826 
       
   827     TPtrC8 localHost(SIPStrings::StringF(SipStrConsts::ELocalHost).DesC());
       
   828 
       
   829     CSIPURI* contactUri = contact->SIPAddress()->URI().SIPURI();
       
   830     if (contactUri && contactUri->HostPort().Host().CompareF(localHost) == 0)
       
   831 		{ 
       
   832 		// if contact header does not have host --> add it
       
   833 		iRegistrationContact.ContactL(aIapId,aRegistrationId,aFromTo,*contact);
       
   834 		}
       
   835 	}
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CSipDialogMgr::CreateContactL
       
   839 // -----------------------------------------------------------------------------
       
   840 //
       
   841 void CSipDialogMgr::CreateAndAddContactL (const CURIContainer& aUri,
       
   842 										  CSIPMessage& aMessage)
       
   843 	{
       
   844 	CURIContainer* uri = CURIContainer::NewLC(aUri);
       
   845 	CSIPAddress* sipAddress = SIPCodecUtils::CreateSIPAddressLC(uri);
       
   846 	CleanupStack::Pop(sipAddress);
       
   847 	CleanupStack::Pop(uri);
       
   848 	CleanupStack::PushL(sipAddress);
       
   849 	CSIPContactHeader* contact = CSIPContactHeader::NewL(sipAddress);
       
   850 	CleanupStack::Pop(sipAddress);
       
   851 	CleanupStack::PushL(contact);
       
   852 	aMessage.AddHeaderL(contact);
       
   853 	CleanupStack::Pop(contact);
       
   854 	}
       
   855 
       
   856 // -----------------------------------------------------------------------------
       
   857 // CSipDialogMgr::SendErrorResponseAndLeaveL
       
   858 // -----------------------------------------------------------------------------
       
   859 //	
       
   860 void CSipDialogMgr::SendErrorResponseAndLeaveL (
       
   861     TTransactionId aTransactionId,
       
   862     TInt aLeaveCode,
       
   863     const TSIPTransportParams& aParams)
       
   864     {
       
   865     CSIPResponse* response = 
       
   866         CSIPResponse::NewLC(K400Response,iPhraseBadRequest);
       
   867     iTU.SendL(aTransactionId, response, aParams);
       
   868     CleanupStack::Pop(response); // ownership given to TU 
       
   869     iTU.ClearTransactionOwner(aTransactionId);
       
   870     User::Leave(aLeaveCode);    
       
   871     }
       
   872 
       
   873 // -----------------------------------------------------------------------------
       
   874 // CSipDialogMgr::DeleteTransactionHeaders
       
   875 // -----------------------------------------------------------------------------
       
   876 //
       
   877 void CSipDialogMgr::DeleteTransactionHeaders (TAny* aTransactionHeaders)
       
   878 	{
       
   879 	MTransactionHeaders* transactionHeaders = 
       
   880         reinterpret_cast<MTransactionHeaders*>(aTransactionHeaders);
       
   881     delete transactionHeaders;
       
   882 	}
       
   883 
       
   884 // -----------------------------------------------------------------------------
       
   885 // CSipDialogMgr::DeleteRouteSet
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 void CSipDialogMgr::DeleteRouteSet (TAny* aRouteSet)
       
   889 	{
       
   890     RPointerArray<CSIPRouteHeaderBase>* routeSet =
       
   891         reinterpret_cast<RPointerArray<CSIPRouteHeaderBase>*>(aRouteSet);
       
   892     if (routeSet)
       
   893         {
       
   894         routeSet->ResetAndDestroy();
       
   895         }
       
   896 	delete routeSet;
       
   897 	}
       
   898 
       
   899 // -----------------------------------------------------------------------------
       
   900 // CSipDialogMgr::DeleteContacts
       
   901 // -----------------------------------------------------------------------------
       
   902 //
       
   903 void CSipDialogMgr::DeleteContacts (TAny* aContacts)
       
   904 	{
       
   905     RPointerArray<CSIPContactHeader>* contacts =
       
   906         reinterpret_cast<RPointerArray<CSIPContactHeader>*>(aContacts);
       
   907     if (contacts)
       
   908         {
       
   909         contacts->ResetAndDestroy();
       
   910         }
       
   911 	delete contacts;
       
   912 	}