realtimenetprots/sipfw/SIP/Registration/src/TSIPRegistrationUtility.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          : TSIPRegistrationUtility.cpp
       
    15 // Part of       : Registration
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "TSIPRegistrationUtility.h"
       
    22 #include "MTransactionUser.h"
       
    23 #include "MSigComp.h"
       
    24 #include "siprequest.h"
       
    25 #include "siptoheader.h"
       
    26 #include "sipfromheader.h"
       
    27 #include "sipcontactheader.h"
       
    28 #include "sipaddress.h"
       
    29 #include "uricontainer.h"
       
    30 #include "sipuri.h"
       
    31 #include "siphostport.h"
       
    32 #include "sipexpiresheader.h"
       
    33 #include "siprouteheader.h"
       
    34 #include "CSIPRegistrationBindingBase.h"
       
    35 #include "SipAssert.h"
       
    36 #include "sipstrings.h"
       
    37 #include "sipstrconsts.h"
       
    38 #include "siperr.h"
       
    39 
       
    40 const TInt KOneHourInSeconds = 3600;
       
    41 
       
    42 #define HEADER_IN_REQUEST(H, N) static_cast<H*>(aRequest.Header(N,0))
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // TSIPRegistrationUtility::LocalAddressLC
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 HBufC8* TSIPRegistrationUtility::LocalAddressLC (const TUint       aIapId,
       
    49                                                  MTransactionUser& aTU)
       
    50 	{
       
    51 	// get local IP address by giving IAP id
       
    52 	TInetAddr localAddress;
       
    53 	aTU.GetLocalAddress(aIapId, localAddress);
       
    54 
       
    55 	// create Local IP address
       
    56 	const TInt KMaxIPAddrLength = 256;
       
    57 	HBufC* ipAddressOutputBuf = HBufC::NewLC(KMaxIPAddrLength);
       
    58 	TPtr ipAddressOutputPtr(ipAddressOutputBuf->Des());
       
    59 	localAddress.Output(ipAddressOutputPtr);
       
    60 
       
    61 	HBufC8* outPutBuf = HBufC8::NewL(ipAddressOutputPtr.Length());
       
    62 	TPtr8 outPutPtr(outPutBuf->Des());
       
    63 	outPutPtr.Copy(ipAddressOutputPtr);
       
    64 	CleanupStack::PopAndDestroy(ipAddressOutputBuf);
       
    65     CleanupStack::PushL(outPutBuf);
       
    66 
       
    67 	return outPutBuf;
       
    68 	}
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // TSIPRegistrationUtility::CheckRegisterRequestL
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 void TSIPRegistrationUtility::CheckRegisterRequestL (
       
    75 	CSIPRequest&           aRequest,
       
    76 	const CSIPRouteHeader* aOutboundProxy,
       
    77     const TUint32          aIapId,
       
    78 	MTransactionUser&      aTU)
       
    79 	{
       
    80 	// panic if there is no To header in request in debug mode.
       
    81 	// leaves with error code KErrArgument in release mode.
       
    82 	__SIP_ASSERT_LEAVE(aRequest.To() != 0, KErrArgument);
       
    83 	
       
    84 	// panic if RegisterRequestNoFromHeader in debug mode.
       
    85 	// leaves with error code KErrArgument in release mode.
       
    86 	__SIP_ASSERT_LEAVE(aRequest.From() != 0, KErrArgument);
       
    87 
       
    88 	CheckToHeaderL(*(aRequest.To()));
       
    89 	CheckRegisterContactL(aRequest, aIapId, aTU);
       
    90 	CheckRegisterExpiresValueL(aRequest);
       
    91 	if (aOutboundProxy)
       
    92 	    {
       
    93 	    CheckSipsSchemeInAorAndOtherAddressL(
       
    94 	        *aRequest.To(),aOutboundProxy->SIPAddress());
       
    95 	    }
       
    96 	}
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // TSIPRegistrationUtility::CheckUpdateRegisterRequestL
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 void TSIPRegistrationUtility::CheckUpdateRegisterRequestL (
       
   103 	CSIPRequest&                 aRequest, 
       
   104 	CSIPRegistrationBindingBase& aBinding)
       
   105 	{
       
   106 	// panic if there is to header in update register request in debug
       
   107 	// mode. leaves with error code KErrArgument in release build
       
   108     __SIP_ASSERT_LEAVE(!aRequest.To(), KErrArgument);
       
   109 
       
   110 	// panic if there is from header in update register request in debug
       
   111 	// mode. leaves with error code KErrArgument in release build
       
   112     __SIP_ASSERT_LEAVE(!aRequest.From(), KErrArgument);
       
   113 
       
   114 	CheckUpdateRegisterContactL(aRequest, aBinding);
       
   115 	CheckUpdateRegisterExpiresValueL(aRequest, aBinding);
       
   116 	}
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // TSIPRegistrationUtility::CheckUnregisterRequestL
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 void TSIPRegistrationUtility::CheckUnregisterRequestL (
       
   123 	CSIPRequest&                 aRequest, 
       
   124 	CSIPRegistrationBindingBase& aBinding)
       
   125 	{
       
   126     const RStringF KContactHeaderName = 
       
   127         SIPStrings::StringF(SipStrConsts::EContactHeader);	
       
   128 	
       
   129 	// panic if there is to header in unregister request in debug mode,
       
   130 	// Leaves with error code KErrArgument in release mode
       
   131     __SIP_ASSERT_LEAVE(!aRequest.To(), KErrArgument);
       
   132 
       
   133 	// panic if there is from header in unregister request in debug mode,
       
   134 	// Leaves with error code KErrArgument in release mode
       
   135     __SIP_ASSERT_LEAVE(!aRequest.From(), KErrArgument);
       
   136 
       
   137 	// panic if there is contact header in unregister request in debug mode,
       
   138 	// Leaves with error code KErrArgument in release mode
       
   139     __SIP_ASSERT_LEAVE(!aRequest.HasHeader(KContactHeaderName),
       
   140                        KErrArgument);
       
   141 
       
   142     // fill in contact header
       
   143 	CSIPContactHeader* contact = 
       
   144 		static_cast<CSIPContactHeader*>(aBinding.Contact().CloneL());
       
   145     CleanupStack::PushL(contact);
       
   146 	contact->SetExpiresParameterL(0); //set expires parameter to 0
       
   147 	aRequest.AddHeaderL(contact);
       
   148 	CleanupStack::Pop(contact);
       
   149 	}
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // TSIPRegistrationUtility::CheckFetchingRequestL
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void TSIPRegistrationUtility::CheckFetchingRequestL (CSIPRequest& aRequest)
       
   156 	{
       
   157     const RStringF KContactHeaderName = 
       
   158         SIPStrings::StringF(SipStrConsts::EContactHeader);	
       
   159 	
       
   160 	// panic if there is contact header in binding in debug mode.
       
   161 	// leaves with error code KErrArgument in release mode.
       
   162     __SIP_ASSERT_LEAVE(!(aRequest.HasHeader(KContactHeaderName)), 
       
   163 		               KErrArgument);
       
   164 
       
   165 	CheckToHeaderL (*(aRequest.To()));
       
   166 	}
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // TSIPRegistrationUtility::CheckOutboundProxyCompParameterL
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void TSIPRegistrationUtility::CheckOutboundProxyCompParameterL(
       
   173 	CSIPRouteHeader& aOutboundProxy,
       
   174 	MSigComp&        aSigComp)
       
   175 	{
       
   176 	if (aOutboundProxy.SIPAddress().URI().IsSIPURI())
       
   177 	    {
       
   178 	    CSIPURI& uri = *(aOutboundProxy.SIPAddress().URI().SIPURI());
       
   179 	
       
   180 	    // when the uri of outboundProxy contains "comp" parameter and
       
   181 	    // comp == "sigcomp", leave if sigComp asked from MSigComp 
       
   182 	    // is not supported.
       
   183         RStringF comp = SIPStrings::StringF(SipStrConsts::EComp);
       
   184         RStringF sigcomp = SIPStrings::StringF(SipStrConsts::ESigComp);
       
   185 	    if (uri.ParamValue(comp) == sigcomp && !aSigComp.IsSupported())
       
   186 		    {
       
   187 		    User::Leave(KErrNotSupported);
       
   188 		    }
       
   189 	    }
       
   190 	}
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // TSIPRegistrationUtility::CheckToHeaderL
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 void TSIPRegistrationUtility::CheckToHeaderL(CSIPToHeader& aTo)
       
   197 	{
       
   198 	CURIContainer& uri = aTo.SIPAddress().URI();
       
   199     if (uri.IsSIPURI())
       
   200         {
       
   201 	    __ASSERT_ALWAYS(uri.SIPURI()->User().Length() > 0, 
       
   202 	                    User::Leave(KErrArgument));
       
   203         }
       
   204 	}
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // TSIPRegistrationUtility::CheckRegisterContactL
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 void TSIPRegistrationUtility::CheckRegisterContactL(
       
   211     CSIPRequest&      aRequest,
       
   212 	const TUint32     aIapId,
       
   213     MTransactionUser& aTU)
       
   214 	{
       
   215     const RStringF KContactHeaderName = 
       
   216         SIPStrings::StringF(SipStrConsts::EContactHeader);	
       
   217 
       
   218 	__SIP_ASSERT_LEAVE(aRequest.HeaderCount(KContactHeaderName) == 1,
       
   219 		               KErrArgument);
       
   220 
       
   221 	CSIPContactHeader* contact = 
       
   222 		HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName);
       
   223 
       
   224 	__SIP_ASSERT_LEAVE(!contact->Star(), KErrArgument);
       
   225 	__SIP_ASSERT_LEAVE(contact->SIPAddress() != 0, KErrArgument);
       
   226 
       
   227     CheckSipsSchemeInAorAndOtherAddressL(*aRequest.To(),*contact->SIPAddress());
       
   228 
       
   229 	CheckSIPAddressInContactHeaderL(*contact, aIapId, aTU);
       
   230 	}
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // TSIPRegistrationUtility::CheckUpdateRegisterContactL
       
   234 // -----------------------------------------------------------------------------
       
   235 //	
       
   236 void TSIPRegistrationUtility::CheckUpdateRegisterContactL(
       
   237     CSIPRequest&                 aRequest,
       
   238 	CSIPRegistrationBindingBase& aBinding)
       
   239 	{
       
   240     const RStringF KContactHeaderName = 
       
   241         SIPStrings::StringF(SipStrConsts::EContactHeader);
       
   242 	
       
   243 	// contact header is not empty in request
       
   244 	if (aRequest.HasHeader(KContactHeaderName))
       
   245 		{
       
   246 		__SIP_ASSERT_LEAVE(aRequest.HeaderCount(KContactHeaderName) == 1, 
       
   247                            KErrArgument);      
       
   248 
       
   249 		CSIPContactHeader* contactInRequest = 
       
   250 			HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName);
       
   251 	
       
   252 		__SIP_ASSERT_LEAVE(!contactInRequest->Star(), KErrArgument);
       
   253 	
       
   254 	    CheckSipsSchemeInAorAndOtherAddressL(
       
   255 	        aBinding.AOR(),*contactInRequest->SIPAddress());
       
   256 		
       
   257 		if (contactInRequest->SIPAddress()->URI().IsSIPURI())
       
   258 		    {
       
   259 		    __ASSERT_ALWAYS(aBinding.Contact().SIPAddress()->URI().IsSIPURI(),
       
   260                             User::Leave(KErrArgument));
       
   261 
       
   262 		    CSIPURI& uriInRequestContact = 
       
   263 		        *(contactInRequest->SIPAddress()->URI().SIPURI());
       
   264 		    
       
   265 		    CSIPURI& uriInBindingContact = 
       
   266 		        *(aBinding.Contact().SIPAddress()->URI().SIPURI());
       
   267 			
       
   268 		    CSIPHostPort& hostPortInRequestContact = 
       
   269 			    uriInRequestContact.HostPort();
       
   270 		    
       
   271 		    CSIPHostPort& hostPortInBindingContact = 
       
   272 			    uriInBindingContact.HostPort();
       
   273 	
       
   274 		    // if there is no host in contact of request
       
   275 		    if (hostPortInRequestContact.Host().CompareF(
       
   276 		            SIPStrings::StringF(SipStrConsts::ELocalHost).DesC()) == 0)
       
   277 			    {
       
   278 			    hostPortInRequestContact.SetHostL(hostPortInBindingContact.Host());
       
   279 			    }
       
   280 		    // if there is no port in contact of request
       
   281 		    if (!hostPortInRequestContact.HasPort() && 
       
   282 			    hostPortInBindingContact.HasPort())
       
   283 			    {
       
   284 			    hostPortInRequestContact.SetPort(hostPortInBindingContact.Port());
       
   285 			    }
       
   286 		    }
       
   287 	
       
   288 		// leave if the contact in binding is different as the one in request
       
   289 		__ASSERT_ALWAYS (contactInRequest->SIPAddress()->URI() ==
       
   290 		                 aBinding.Contact().SIPAddress()->URI(), 
       
   291 			             User::Leave (KErrArgument));	
       
   292 		}
       
   293 	else 
       
   294 		{
       
   295 		// create contact header, fill in the sip address from contact 
       
   296 		// in binding. add the contact header to request
       
   297 		CSIPAddress* address = 
       
   298 			CSIPAddress::NewLC(*(aBinding.Contact().SIPAddress()));
       
   299 		CSIPContactHeader* contactHeader = CSIPContactHeader::NewL(address);
       
   300 		CleanupStack::Pop(address);
       
   301 		CleanupStack::PushL(contactHeader);
       
   302 		aRequest.AddHeaderL(contactHeader);
       
   303 		CleanupStack::Pop(contactHeader);
       
   304 		}
       
   305 	}
       
   306 	
       
   307 // -----------------------------------------------------------------------------
       
   308 // TSIPRegistrationUtility::CheckRegisterExpiresValueL
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 void TSIPRegistrationUtility::CheckRegisterExpiresValueL(CSIPRequest& aRequest)
       
   312 	{
       
   313     const RStringF KContactHeaderName = 
       
   314         SIPStrings::StringF(SipStrConsts::EContactHeader);
       
   315 
       
   316     const RStringF KExpiresHeaderName = 
       
   317         SIPStrings::StringF(SipStrConsts::EExpiresHeader);	
       
   318 	
       
   319 	CSIPContactHeader* contactHeader = 
       
   320 		HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName);
       
   321 
       
   322     // panic if there is no contact header == 0 in debug mode.
       
   323 	// leaves with error code KErrArgument in release mode.
       
   324 	__SIP_ASSERT_LEAVE(contactHeader, KErrArgument);
       
   325 
       
   326 	if (contactHeader->ExpiresParameter() >= 0)
       
   327 		{
       
   328 		// panic RegisterRequestExpiresParameterIsZero in release mode.
       
   329 		// leaves with error code KErrArgument in release mode.
       
   330 		__SIP_ASSERT_LEAVE((contactHeader->ExpiresParameter() != 0),
       
   331 			               KErrArgument);	
       
   332 		}
       
   333     else if (!aRequest.HasHeader(KExpiresHeaderName))
       
   334 		{
       
   335 		// set default expires value one hour
       
   336 		contactHeader->SetExpiresParameterL(KOneHourInSeconds);
       
   337 		}
       
   338 	else
       
   339 		{
       
   340 		CSIPExpiresHeader* expiresHeader = 
       
   341             HEADER_IN_REQUEST(CSIPExpiresHeader, KExpiresHeaderName);
       
   342 
       
   343 		// panic expires header value is 0 in release mode.
       
   344 		// leaves with error code KErrArgument in release mode.
       
   345 		__SIP_ASSERT_LEAVE(expiresHeader->Value() != 0, KErrArgument);
       
   346 		
       
   347 		// copies expires value from expire header to expires parameter
       
   348 		// in Contact, remove the expires header.
       
   349 		contactHeader->SetExpiresParameterL(expiresHeader->Value());
       
   350 		if (aRequest.RemoveHeader(expiresHeader) == KErrNone)
       
   351 			{	
       
   352 			delete expiresHeader; expiresHeader = 0; 
       
   353 			}
       
   354 		}
       
   355 	}
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // TSIPRegistrationUtility::RemoveRegisterExpiresParam
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 void TSIPRegistrationUtility::RemoveRegisterExpiresParam(CSIPRequest& aRequest)
       
   362 	{
       
   363     const RStringF KContactHeaderName = 
       
   364         SIPStrings::StringF(SipStrConsts::EContactHeader);
       
   365     
       
   366     //remove the expires param
       
   367 	if (aRequest.HasHeader(KContactHeaderName))
       
   368 		{
       
   369 		CSIPContactHeader* contactHeader = 
       
   370 				HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName);
       
   371 		if(contactHeader->ExpiresParameter() != KErrNotFound)
       
   372 			{
       
   373 			contactHeader->RemoveExpiresParam();
       
   374 			}
       
   375 		}
       
   376 	}
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // TSIPRegistrationUtility::CheckUpdateRegisterExpiresValueL
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 void TSIPRegistrationUtility::CheckUpdateRegisterExpiresValueL(
       
   383 	CSIPRequest&                 aRequest,
       
   384 	CSIPRegistrationBindingBase& aBinding)
       
   385 	{
       
   386     const RStringF KContactHeaderName = 
       
   387         SIPStrings::StringF(SipStrConsts::EContactHeader);
       
   388 
       
   389     const RStringF KExpiresHeaderName = 
       
   390         SIPStrings::StringF(SipStrConsts::EExpiresHeader);	
       
   391 	
       
   392 	CSIPContactHeader* contactHeader = 
       
   393 		HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName);
       
   394 
       
   395 	// panic is contactHeader == 0 in debug mode.
       
   396 	// leaves with error code KErrArgument in release mode.
       
   397 	__SIP_ASSERT_LEAVE(contactHeader, KErrArgument);
       
   398 
       
   399 	if (contactHeader->ExpiresParameter() < 0)
       
   400 		{
       
   401         if (!aRequest.HasHeader(KExpiresHeaderName))
       
   402 			{
       
   403 			// set default expires value from binding
       
   404 			contactHeader->SetExpiresParameterL(
       
   405 				aBinding.Contact().ExpiresParameter());
       
   406 			}
       
   407 		else
       
   408 			{
       
   409 			// copies expires value from expire header to expires parameter
       
   410 			// in Contact, remove the expires header.
       
   411 			CSIPExpiresHeader* expiresHeader = 
       
   412                 HEADER_IN_REQUEST(CSIPExpiresHeader, KExpiresHeaderName);
       
   413 
       
   414 			contactHeader->SetExpiresParameterL(expiresHeader->Value());
       
   415 			if (aRequest.RemoveHeader(expiresHeader) == KErrNone)
       
   416 				{	
       
   417 				delete expiresHeader; expiresHeader = 0; 
       
   418 				}
       
   419 			}
       
   420 		}
       
   421 	}
       
   422 	
       
   423 // -----------------------------------------------------------------------------
       
   424 // TSIPRegistrationUtility::CheckSIPAddressInContactHeaderL
       
   425 // -----------------------------------------------------------------------------
       
   426 //
       
   427 void TSIPRegistrationUtility::CheckSIPAddressInContactHeaderL(
       
   428 	CSIPContactHeader& aContact,
       
   429 	const TUint32      aIapId,
       
   430     MTransactionUser&  aTransationUser)
       
   431     {
       
   432     if (aContact.SIPAddress()->URI().IsSIPURI())
       
   433         {
       
   434 	    CSIPURI& contactUri = *(aContact.SIPAddress()->URI().SIPURI());
       
   435 	    if (contactUri.HostPort().Host().CompareF(
       
   436 	            SIPStrings::StringF(SipStrConsts::ELocalHost).DesC()) == 0)
       
   437 		    {
       
   438 		    // fills in the host part by coping the Local IP address
       
   439 		    HBufC8* localAddr = 
       
   440 		        TSIPRegistrationUtility::LocalAddressLC(
       
   441 		            aIapId, aTransationUser);
       
   442 		    contactUri.HostPort().SetHostL(*localAddr);
       
   443 		    CleanupStack::PopAndDestroy(); //localAddr
       
   444 		    }
       
   445         }
       
   446     }
       
   447     
       
   448 // -----------------------------------------------------------------------------
       
   449 // TSIPRegistrationUtility::CheckSipsSchemeInAorAndOtherAddressL
       
   450 // -----------------------------------------------------------------------------
       
   451 //
       
   452 void TSIPRegistrationUtility::CheckSipsSchemeInAorAndOtherAddressL(
       
   453     const CSIPToHeader& aAor,
       
   454     const CSIPAddress& aAddress)
       
   455     {
       
   456     if (aAor.SIPAddress().URI().IsSIPURI() &&
       
   457         aAor.SIPAddress().URI().SIPURI()->IsSIPSURI())
       
   458         {
       
   459 	    __ASSERT_ALWAYS(aAddress.URI().IsSIPURI(),
       
   460 	                    User::Leave(KErrSIPInvalidURIType));
       
   461 	    __ASSERT_ALWAYS(aAddress.URI().SIPURI()->IsSIPSURI(),
       
   462 	                    User::Leave(KErrSIPInvalidURIType));       
       
   463         }
       
   464     }