multimediacommsengine/tsrc/testdriver/siptester/src/TTcSIPCommandBase.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 #include <sipaddress.h>
       
    19 #include <sipcontenttypeheader.h>
       
    20 #include <sipcseqheader.h>
       
    21 #include <sipdialog.h>
       
    22 #include <sipdialogassocbase.h>
       
    23 #include <sipcontactheader.h>
       
    24 #include <sipexpiresheader.h>
       
    25 #include <sipfromheader.h>
       
    26 #include <sipinvitedialogassoc.h>
       
    27 #include <sipmanagedprofile.h>
       
    28 #include <sipmanagedprofileregistry.h>
       
    29 #include <sipmessageelements.h>
       
    30 #include <siprefresh.h>
       
    31 #include <siprouteheader.h>
       
    32 #include <sipsubscribedialogassoc.h>
       
    33 #include <siptoheader.h>
       
    34 #include <sipprofile.h>
       
    35 #include <sipheaderlookup.h>
       
    36 #include <sipnotifydialogassoc.h>
       
    37 #include <sipreferdialogassoc.h>
       
    38 #include <sipstrings.h>
       
    39 #include <stringpool.h>
       
    40 #include <_sipcodecdefs.h>
       
    41 #include <sipsubscriptionstateheader.h>
       
    42 #include <sipeventheader.h>
       
    43 #include <siprefertoheader.h>
       
    44 #include <uri8.h>
       
    45 
       
    46 #include "CleanupResetAndDestroy.h"
       
    47 #include "CTcSIPContext.h"
       
    48 #include "SIPConstants.h"
       
    49 #include "SipStrConsts.h"
       
    50 #include "TcLog.h"
       
    51 #include "TTcSIPCommandBase.h"
       
    52 
       
    53 #include "CTcSIPProfileContainer.h"
       
    54 
       
    55 TTcSIPCommandBase::TTcSIPCommandBase( MTcTestContext& aContext )
       
    56 	: TTcCommandBase( static_cast< CTcContextBase& >( aContext ) ),
       
    57 	  iContext( static_cast< CTcSIPContext& >( aContext ) ),
       
    58 	  iPushed( 0 )
       
    59 	{
       
    60 	}
       
    61 
       
    62 //
       
    63 // - Header extraction functions ----------------------------------------------
       
    64 //
       
    65 
       
    66 CSIPToHeader* TTcSIPCommandBase::ExtractToHeaderLC(	TBool aIsMandatory )
       
    67 	{
       
    68 	return static_cast< CSIPToHeader* >(
       
    69 				ExtractHeaderLC( KHeaderTo, aIsMandatory ) );
       
    70 	}
       
    71 
       
    72 CSIPContactHeader* TTcSIPCommandBase::ExtractContactHeaderLC(
       
    73 														TBool aIsMandatory )
       
    74 	{
       
    75 	CSIPContactHeader* contact =
       
    76 		static_cast< CSIPContactHeader* >(
       
    77 							ExtractHeaderLC( KHeaderContact, aIsMandatory ) );
       
    78 	return contact;
       
    79 	}
       
    80 
       
    81 CSIPRouteHeader* TTcSIPCommandBase::ExtractRouteHeaderLC( TBool aIsMandatory )
       
    82 	{
       
    83 	return static_cast< CSIPRouteHeader* >(
       
    84 				ExtractHeaderLC( KHeaderRoute, aIsMandatory ) );				
       
    85 	}
       
    86 
       
    87 CSIPFromHeader* TTcSIPCommandBase::ExtractFromHeaderLC( TBool aIsMandatory )
       
    88 	{
       
    89 	CSIPFromHeader* from =
       
    90 		static_cast< CSIPFromHeader* >(
       
    91 							ExtractHeaderLC( KHeaderFrom, aIsMandatory ) );
       
    92 	return from;
       
    93 	}
       
    94 
       
    95 CSIPExpiresHeader* TTcSIPCommandBase::ExtractExpiresHeaderLC( TBool aIsMandatory )
       
    96 	{
       
    97 	return static_cast< CSIPExpiresHeader* >(
       
    98 				ExtractHeaderLC( KHeaderExpires, aIsMandatory ) );
       
    99 	}
       
   100 
       
   101 CSIPReferToHeader* TTcSIPCommandBase::ExtractReferToHeaderLC( TBool aIsMandatory )
       
   102 	{
       
   103 	return static_cast< CSIPReferToHeader* >(
       
   104 				ExtractHeaderLC( KHeaderReferTo, aIsMandatory ) );
       
   105 	}
       
   106 
       
   107 
       
   108 CSIPSubscriptionStateHeader* TTcSIPCommandBase::ExtractSubStateHeaderLC( TBool aIsMandatory )
       
   109 	{
       
   110 	return static_cast< CSIPSubscriptionStateHeader* >(
       
   111 				ExtractHeaderLC( KHeaderSubState, aIsMandatory ) );
       
   112 	}
       
   113 
       
   114 CSIPEventHeader* TTcSIPCommandBase::ExtractEventHeaderLC( TBool aIsMandatory )
       
   115 	{
       
   116 	return static_cast< CSIPEventHeader* >(
       
   117 				ExtractHeaderLC( KHeaderEvent, aIsMandatory ) );
       
   118 	}
       
   119 	
       
   120 CSIPContentTypeHeader* TTcSIPCommandBase::ExtractContentTypeHeaderLC( TBool aIsMandatory )
       
   121 	{
       
   122 	return static_cast< CSIPContentTypeHeader* >(
       
   123 				ExtractHeaderLC( KHeaderContentType, aIsMandatory ) );
       
   124 	}
       
   125 
       
   126 
       
   127 CSIPMessageElements* TTcSIPCommandBase::ExtractHeadersAndContentLC()
       
   128 	{
       
   129 	// Construct message elements container
       
   130 	CSIPMessageElements* elements = CSIPMessageElements::NewLC();
       
   131 
       
   132 	ExtractHeadersAndContentL( *elements );
       
   133 
       
   134 	return elements;
       
   135 	}
       
   136 
       
   137 void TTcSIPCommandBase::ExtractHeadersAndContentL( CSIPMessageElements& aElements )
       
   138 	{
       
   139 	// Extract Content + Content-Type to elements.
       
   140 	ExtractContentL( aElements );
       
   141 
       
   142 	CTcArray* headers = FindArrayL( KResponseHeaders, EFalse );
       
   143 	if( !headers )
       
   144 		{
       
   145 		return;
       
   146 		}
       
   147 
       
   148 	// Extract any headers still left in the request into userHeaders
       
   149 	RPointerArray< CSIPHeaderBase > userHeaders;
       
   150 	ExtractUserHeadersL( *headers, userHeaders );
       
   151 
       
   152 	// Give userHeaders to elements
       
   153 	CleanupResetAndDestroyPushL( userHeaders );
       
   154 	aElements.SetUserHeadersL( userHeaders );
       
   155 	CleanupStack::Pop();	// userHeaders
       
   156 	}
       
   157 
       
   158 //
       
   159 // - Parameter extraction functions -------------------------------------------
       
   160 //
       
   161 
       
   162 CSIPRefresh* TTcSIPCommandBase::ExtractRefreshLC()
       
   163 	{
       
   164 	TPtrC8 value = ExtractTextL( KParamRefresh, EFalse );
       
   165 	if( value.CompareF( KTcTrue ) == 0 )
       
   166 		{
       
   167 		CSIPRefresh* refresh = CSIPRefresh::NewLC();
       
   168 		iPushed++;
       
   169 		return refresh;
       
   170 		}
       
   171 
       
   172 	return NULL;
       
   173 	}
       
   174 
       
   175 CUri8* TTcSIPCommandBase::ExtractRemoteURILC( TBool aIsMandatory )
       
   176 	{
       
   177 	TPtrC8 value = ExtractTextL( KParamRemoteURI, aIsMandatory );
       
   178 	if( value != KNullDesC8 )
       
   179 		{
       
   180     	TUriParser8 parser;
       
   181     	User::LeaveIfError(parser.Parse(value));
       
   182     	CUri8* uri8 = CUri8::NewLC(parser);   
       
   183 		iPushed++;
       
   184 		return uri8;
       
   185 		}
       
   186 
       
   187 	return NULL;
       
   188 	}
       
   189 
       
   190 CSIPRouteHeader* TTcSIPCommandBase::ExtractProxyLC()
       
   191 	{
       
   192     CSIPRouteHeader* proxy = NULL;
       
   193     
       
   194    	TPtrC8 value = ExtractTextL( KParamProxy, EFalse );
       
   195 	if( value != KNullDesC8 )
       
   196 		{
       
   197 		RPointerArray<CSIPRouteHeader> proxies = CSIPRouteHeader::DecodeL( value );
       
   198 		
       
   199 		// First of the proxy parameter addresses will be used altought there
       
   200 		// shouldn't be more		
       
   201 		if ( proxies.Count() > 0 )
       
   202 		    {
       
   203 			proxy = proxies[ 0 ];
       
   204 		    // Used proxy is not deleted over here
       
   205 		    proxies.Remove( 0 );
       
   206 		    // Others can be deleted
       
   207 		    proxies.ResetAndDestroy();
       
   208 		    
       
   209 		    CleanupStack::PushL( proxy );
       
   210 		    iPushed++;	    
       
   211 		    }	
       
   212 		}
       
   213 	return proxy;
       
   214 	}
       
   215 
       
   216 CTcSIPConnectionContainer& TTcSIPCommandBase::SelectConnectionL()
       
   217 	{
       
   218 	TPtrC8 value = ExtractIdL( KConnectionId, EFalse );
       
   219 	if( value != KNullDesC8 )
       
   220 		{
       
   221 		CTcSIPConnectionContainer* conn
       
   222 							= reinterpret_cast< CTcSIPConnectionContainer* >(
       
   223 								iContext.Registry().ObjectPtrL( value ) );
       
   224 		return *conn;
       
   225 		}
       
   226 	else
       
   227 		{
       
   228 		return iContext.Connection();
       
   229 		}
       
   230 	}
       
   231 CTcSIPProfileContainer& TTcSIPCommandBase::SelectProfileL()
       
   232 	{
       
   233 	TPtrC8 value = ExtractIdL( KRegistryId, EFalse );
       
   234 	if( value != KNullDesC8 )
       
   235 		{
       
   236 		CTcSIPProfileContainer* conn
       
   237 							= reinterpret_cast< CTcSIPProfileContainer* >(
       
   238 								iContext.Registry().ObjectPtrL( value ) );
       
   239 		return *conn;
       
   240 		}
       
   241 	else
       
   242 		{
       
   243 		return iContext.Profile();
       
   244 		}
       
   245 	}
       
   246 //
       
   247 // - Response creation functions ----------------------------------------------
       
   248 //
       
   249 void TTcSIPCommandBase::AddIdResponseL( const TDesC8& aName,
       
   250 										const CBase* aObject )
       
   251 	{
       
   252 	// Register object and fetch its name
       
   253 	iContext.Registry().AddObjectL(	const_cast< CBase* >( aObject ) );
       
   254 	TPtrC8 idName = iContext.Registry().ObjectNameL( aObject );
       
   255 
       
   256 	CTcStructure& tcIDs = FindCreateTestClientIdsL();
       
   257 	CTcNameValue* idNameValue = tcIDs.ItemL( aName );
       
   258 	idNameValue->SetValueL( idName );
       
   259 	}
       
   260 	
       
   261 void TTcSIPCommandBase::AddIdResponseL( const TDesC8& aName,
       
   262 										const CBase& aObject )
       
   263 	{
       
   264 	// Register object and fetch its name
       
   265 	iContext.Registry().AddObjectL(	aObject );
       
   266 	TPtrC8 idName = iContext.Registry().ObjectNameL( &aObject );
       
   267 
       
   268 	CTcStructure& tcIDs = FindCreateTestClientIdsL();
       
   269 	CTcNameValue* idNameValue = tcIDs.ItemL( aName );
       
   270 	idNameValue->SetValueL( idName );
       
   271 	}
       
   272 
       
   273 void TTcSIPCommandBase::AddProfileIdResponseL( CSIPProfile* aProfile )
       
   274 	{
       
   275 	// Register object
       
   276 	iContext.Registry().AddObjectL(	aProfile );
       
   277 	TBuf8< KTcMaxIntConversion > idName;
       
   278 	
       
   279 	TUint32 id( 0 );
       
   280 	User::LeaveIfError( aProfile->GetParameter( KSIPProfileId, id ) );
       
   281 	idName.AppendNum( (TInt)id );	
       
   282 
       
   283 	CTcStructure& tcIDs = FindCreateTestClientIdsL();
       
   284 	CTcNameValue* profileId =
       
   285 					const_cast< CTcNameValue* >( tcIDs.ItemL( KProfileId ) );
       
   286 	profileId->SetValueL( idName );
       
   287 	}
       
   288 	
       
   289 void TTcSIPCommandBase::AddProfileIdResponseL( CSIPProfile& aProfile )
       
   290 	{
       
   291 	// Register object
       
   292 	iContext.Registry().AddObjectL(	aProfile );
       
   293 	TBuf8< KTcMaxIntConversion > idName;
       
   294 	
       
   295 	TUint32 id( 0 );
       
   296 	User::LeaveIfError( aProfile.GetParameter( KSIPProfileId, id ) );
       
   297 	idName.AppendNum( (TInt)id );	
       
   298 
       
   299 	CTcStructure& tcIDs = FindCreateTestClientIdsL();
       
   300 	CTcNameValue* profileId =
       
   301 					const_cast< CTcNameValue* >( tcIDs.ItemL( KProfileId ) );
       
   302 	profileId->SetValueL( idName );
       
   303 	}
       
   304 
       
   305 CTcStructure& TTcSIPCommandBase::FindCreateTestClientIdsL()
       
   306 	{
       
   307 	// Find the TestClientIds structure, it may be in several places
       
   308 	// (there might already be a ReceivedMsg item in the return list)
       
   309 	// It may also be missing altogether, if this is the first time
       
   310 	// AddIdResponseL() is called.
       
   311 	TInt pos = iContext.ReturnList().FindParameter( KResponseTestClientIds,
       
   312 													MTcTyped::EStructure );
       
   313 	if( pos == KErrNotFound )
       
   314 		{
       
   315 		// Figure out the correct position for the structure: just
       
   316 		// after the ReceivedMsg if it exists.
       
   317 		pos = iContext.ReturnList().FindParameter( KResponseHeaders,
       
   318 												   MTcTyped::EArray );
       
   319 		if( pos == KErrNotFound )
       
   320 			{
       
   321 			pos = 0;	// no headers, insert at the beginning
       
   322 			}
       
   323 		else
       
   324 			{
       
   325 			pos++;	// insert after headers
       
   326 			}
       
   327 
       
   328 		// Add a structure to the response parameter list for TestClient Ids
       
   329 		CTcStructure* tcIDs = CTcStructure::NewLC();
       
   330 		tcIDs->SetName( KResponseTestClientIds );
       
   331 		iContext.ReturnList().InsertParameterL( tcIDs, pos );
       
   332 		CleanupStack::Pop(); // tcIDs
       
   333 
       
   334 		// All IDs, in alphabetical order
       
   335 		// (this has to be function-local in order to compile for THUMB)
       
   336 		const TDesC8* const TIdNames[] = {
       
   337 			&KConnectionId,
       
   338 			&KDialogId,
       
   339 			&KInviteDialogId,
       
   340             &KNotifyDialogId,
       
   341 			&KProfileId,
       
   342             &KReferDialogId,
       
   343 			&KRefreshId,
       
   344             &KRegistryId,
       
   345 			&KRegistrationId,
       
   346 			&KServerTransactionId,
       
   347 			&KSubscribeDialogId,
       
   348 			&KTransactionId
       
   349 			};
       
   350 
       
   351 		// Add an entry for ALL possible Ids. This is done to go around
       
   352 		// a Telelogic Tau logging problem related to template mismatches
       
   353 		TInt count = sizeof( TIdNames ) / sizeof( const TDesC8* );
       
   354 		for( TInt i = 0; i < count; i++ )
       
   355 			{
       
   356 			CTcNameValue* nameValue = CTcNameValue::NewLC();
       
   357 			nameValue->SetL( *TIdNames[ i ], 0 );
       
   358 			tcIDs->AddItemL( nameValue );
       
   359 			CleanupStack::Pop( nameValue );
       
   360 			}
       
   361 		}
       
   362 
       
   363 	return iContext.ReturnList().AsStructure( pos );
       
   364 	}
       
   365 //
       
   366 // -- SIP object / registry access functions ----------------------------------
       
   367 //
       
   368 
       
   369 CSIPDialog* TTcSIPCommandBase::GetDialogL( TBool aIsMandatory )
       
   370 	{
       
   371 	return reinterpret_cast< CSIPDialog* >(
       
   372 							GetObjectForIdL( KDialogId, aIsMandatory ) );
       
   373 	}
       
   374 
       
   375 CSIPDialogAssocBase* TTcSIPCommandBase::GetAnyDialogAssocL(
       
   376 														TBool aIsMandatory )
       
   377 	{
       
   378 	CSIPDialogAssocBase* dialogAssoc = GetInviteDialogAssocL( EFalse );
       
   379 	if( dialogAssoc )
       
   380 		{
       
   381 		return dialogAssoc;
       
   382 		}
       
   383 
       
   384 	dialogAssoc = GetSubscribeDialogAssocL( EFalse );
       
   385 	if( dialogAssoc )
       
   386 		{
       
   387 		return dialogAssoc;
       
   388 		}
       
   389 
       
   390     dialogAssoc = GetReferDialogAssocL( EFalse );
       
   391 	if( dialogAssoc )
       
   392 		{
       
   393 		return dialogAssoc;
       
   394 		}
       
   395 
       
   396     dialogAssoc = GetNotifyDialogAssocL( EFalse );
       
   397 	if( dialogAssoc )
       
   398 		{
       
   399 		return dialogAssoc;
       
   400 		}
       
   401 	
       
   402 	if( aIsMandatory )
       
   403 		{
       
   404 		User::Leave( KTcErrMandatoryIdNotFound );
       
   405 		}
       
   406 	return NULL;
       
   407 	}
       
   408 
       
   409 CSIPInviteDialogAssoc* TTcSIPCommandBase::GetInviteDialogAssocL( TBool aIsMandatory )
       
   410 	{
       
   411 	return reinterpret_cast< CSIPInviteDialogAssoc* >(
       
   412 							GetObjectForIdL( KInviteDialogId, aIsMandatory ) );
       
   413 	}
       
   414 
       
   415 CSIPSubscribeDialogAssoc* TTcSIPCommandBase::GetSubscribeDialogAssocL( TBool aIsMandatory )
       
   416 	{
       
   417 	return reinterpret_cast< CSIPSubscribeDialogAssoc* >(
       
   418 							GetObjectForIdL( KSubscribeDialogId, aIsMandatory ) );
       
   419 	}
       
   420 
       
   421 CSIPNotifyDialogAssoc* TTcSIPCommandBase::GetNotifyDialogAssocL( TBool aIsMandatory )
       
   422 	{
       
   423 	return reinterpret_cast< CSIPNotifyDialogAssoc* >(
       
   424 							GetObjectForIdL( KNotifyDialogId, aIsMandatory ) );
       
   425 	}
       
   426 
       
   427 CSIPReferDialogAssoc* TTcSIPCommandBase::GetReferDialogAssocL( TBool aIsMandatory )
       
   428 	{
       
   429 	return reinterpret_cast< CSIPReferDialogAssoc* >(
       
   430 							GetObjectForIdL( KReferDialogId, aIsMandatory ) );
       
   431 	}
       
   432 
       
   433 CSIPClientTransaction* TTcSIPCommandBase::GetClientTransactionL( TBool aIsMandatory )
       
   434 	{
       
   435 	return reinterpret_cast< CSIPClientTransaction* >(
       
   436 							GetObjectForIdL( KTransactionId, aIsMandatory ) );
       
   437 	}
       
   438 
       
   439 CSIPServerTransaction* TTcSIPCommandBase::GetServerTransactionL( TBool aIsMandatory )
       
   440 	{
       
   441 	return reinterpret_cast< CSIPServerTransaction* >(
       
   442 							GetObjectForIdL( KServerTransactionId, aIsMandatory ) );
       
   443 	}
       
   444 
       
   445 CSIPRegistrationBinding* TTcSIPCommandBase::GetRegistrationL( TBool aIsMandatory )
       
   446 	{
       
   447 	return reinterpret_cast< CSIPRegistrationBinding* >(
       
   448 							GetObjectForIdL( KRegistrationId, aIsMandatory ) );
       
   449 	}
       
   450 
       
   451 CSIPRefresh* TTcSIPCommandBase::GetRefreshL( TBool aIsMandatory )
       
   452 	{
       
   453 	return reinterpret_cast< CSIPRefresh* >(
       
   454 							GetObjectForIdL( KRefreshId, aIsMandatory ) );
       
   455 	}
       
   456 
       
   457 CSIPManagedProfile& TTcSIPCommandBase::GetManagedProfileL( CTcSIPProfileContainer& aProfileContainer )
       
   458 	{
       
   459 	// Get profile from the registry
       
   460     return aProfileContainer.GetManagedProfileByIdL( ExtractProfileIdL() );
       
   461 	}
       
   462 
       
   463 CSIPProfile& TTcSIPCommandBase::GetProfileL( CTcSIPProfileContainer& aProfileContainer )
       
   464 	{
       
   465 	// Get profile from the registry
       
   466     return aProfileContainer.GetProfileByIdL( ExtractProfileIdL() );
       
   467 	}
       
   468 
       
   469 CSIPProfile* TTcSIPCommandBase::GetProfileL( CTcSIPProfileContainer& aProfileContainer, TBool aIsMandatory )
       
   470 	{
       
   471 	// Get profile from the registry
       
   472 	TPtrC8 profileIdStr = ExtractIdL( KParamProfileId, aIsMandatory );
       
   473 	
       
   474 	CSIPProfile* profile = 0;
       
   475 	
       
   476 	if ( profileIdStr != KNullDesC8 )
       
   477 	    {
       
   478 	    TInt profileId( 0 );
       
   479 	    TLex8 lexer( profileIdStr );
       
   480 	    User::LeaveIfError( lexer.Val( profileId ) );
       
   481 	    profile = &aProfileContainer.GetProfileByIdL( profileId );
       
   482 	    }
       
   483 	
       
   484     return profile;
       
   485 	}
       
   486 	
       
   487 CSIPProfile* TTcSIPCommandBase::GetProfileL()	
       
   488     {
       
   489     CSIPProfile* profile = NULL;
       
   490     TPtrC8 profileIdStr = ExtractIdL( KParamProfileId, EFalse );
       
   491 	if ( profileIdStr.Length() > 0 )
       
   492 	    {
       
   493 	    TInt profileId( 0 );
       
   494 	    TLex8 lexer( profileIdStr );
       
   495 	    User::LeaveIfError( lexer.Val( profileId ) );
       
   496         CTcSIPProfileContainer& conn = SelectProfileL();
       
   497         profile = &( conn.GetProfileByIdL( profileId ) );
       
   498         }
       
   499 	return profile;
       
   500     }		
       
   501 //
       
   502 // - Internal header utility functions ----------------------------------------
       
   503 //
       
   504 
       
   505 void TTcSIPCommandBase::ExtractContentL( CSIPMessageElements& aElements )
       
   506 	{
       
   507 	// Extract content type, if any
       
   508 	CSIPContentTypeHeader* contentType = static_cast< CSIPContentTypeHeader* >(
       
   509 				ExtractHeaderLC( KHeaderContentType, EFalse ) );
       
   510 	if( !contentType )
       
   511 		{
       
   512 		return;
       
   513 		}
       
   514 
       
   515 	// Extract content, if any
       
   516 	HBufC8* content = ExtractHBufLC( KParamContent );
       
   517 	if( !content )
       
   518 		{
       
   519 		// If content didn't exist use empty content
       
   520 		content = KNullDesC8().AllocLC();
       
   521 		iPushed++;
       
   522 		}
       
   523 
       
   524 	aElements.SetContentL( content, contentType );
       
   525 
       
   526 	CleanupStack::Pop( 2 );	// content, contentType
       
   527 	iPushed -= 2; 	// content, contentType
       
   528 	}
       
   529 
       
   530 CSIPHeaderBase* TTcSIPCommandBase::ExtractHeaderLC(	const TDesC8& aHeaderName,
       
   531 													TBool aIsMandatory )
       
   532 	{
       
   533 	TBuf8< KTcMaxTypeName > objectName( aHeaderName );
       
   534 	TBuf8< KTcOptionalLength > optional; if( aIsMandatory ) optional = KTcMandatory; else optional = KTcOptional;
       
   535 	TcLog::WriteFormat( _L8("-- Extract %s header \"%s\""), optional.PtrZ(), objectName.PtrZ() );
       
   536 
       
   537 	CTcArray* headers = FindArrayL( KResponseHeaders, aIsMandatory );
       
   538 	if( !headers )
       
   539 		{
       
   540 		// no headers
       
   541 		return NULL;
       
   542 		}
       
   543 
       
   544 	TInt count = headers->Count();
       
   545 	for( TInt i = 0; i < count; i++ )
       
   546 		{
       
   547 		TPtrC8 header = headers->Item( i );
       
   548 		if( NameFromHeader( header ).CompareF( aHeaderName ) == 0 )
       
   549 			{
       
   550 			// Get headername from stringpool 
       
   551 			TPtrC8 headerPtr = NameFromHeader( header );
       
   552 			RStringF headerStr = SIPStrings::Pool().OpenFStringL(headerPtr);
       
   553 			CleanupClosePushL(headerStr);
       
   554 			
       
   555 			RPointerArray< CSIPHeaderBase > headerArray =
       
   556 				SIPHeaderLookup::CreateHeaderL( headerStr,
       
   557 												 ValueFromHeader( header ) );
       
   558 			CSIPHeaderBase* headerObject = headerArray[ 0 ];
       
   559 			headerArray.Close();
       
   560 			CleanupStack::PopAndDestroy(); // headerStr
       
   561 			CleanupStack::PushL( headerObject );
       
   562 			// header was extracted, remove it from original array
       
   563 			headers->RemoveItem( i );
       
   564 			iPushed++;
       
   565 			TcLog::Write( KLogOk );
       
   566 			return headerObject;
       
   567 			}
       
   568 		}
       
   569 
       
   570 	TcLog::Write( KLogNotFound );
       
   571 	if( aIsMandatory )
       
   572 		{
       
   573 		User::Leave( KTcErrMandatoryHeaderNotFound );
       
   574 		}
       
   575 	return NULL;
       
   576 	}
       
   577 
       
   578 void TTcSIPCommandBase::ExtractUserHeadersL(
       
   579 								CTcArray& aHeaders,
       
   580 								RPointerArray< CSIPHeaderBase >& aHeaderArray )
       
   581 	{
       
   582 	TInt count = aHeaders.Count();
       
   583 	for( TInt i = 0; i < count; i++ )
       
   584 		{
       
   585 		// Instantiate correct SIP header object by using the Header factory
       
   586 		TPtrC8 header = aHeaders.Item( i );
       
   587 
       
   588 		TBuf8< KTcMaxTypeName > headerName( NameFromHeader( header ) );
       
   589 		TcLog::WriteFormat( _L8("-- Extract user header \"%s\""), headerName.PtrZ() );
       
   590 	
       
   591 		// Get headername from stringpool 
       
   592 		RStringF headerNameStr = SIPStrings::Pool().OpenFStringL(headerName);
       
   593 		CleanupClosePushL(headerNameStr);
       
   594 		
       
   595 		if( IsHeaderAllowed( headerNameStr ) )
       
   596 			{
       
   597 			RPointerArray< CSIPHeaderBase > newArray =
       
   598 					SIPHeaderLookup::CreateHeaderL( headerNameStr,
       
   599 													 ValueFromHeader( header ) );
       
   600 			CleanupResetAndDestroyPushL( newArray );
       
   601 
       
   602 			// The factory might have created a bunch of headers, move them to
       
   603 			// our array.
       
   604 			TInt newCount = newArray.Count();
       
   605 			for( TInt j = 0; j < newCount; j++ )
       
   606 				{
       
   607 				User::LeaveIfError( aHeaderArray.Append( newArray[ 0 ] ) );
       
   608 				newArray.Remove( 0 );
       
   609 				}
       
   610 			CleanupStack::PopAndDestroy();	// newArray
       
   611 
       
   612 			TcLog::Write( KLogOk );
       
   613 			}
       
   614 		else
       
   615 			{
       
   616 			TcLog::Write( KLogNotAllowed );
       
   617 			User::Leave( KTcErrHeaderNotAllowed );
       
   618 			}
       
   619 		CleanupStack::PopAndDestroy(); // headerNameStr
       
   620 		}
       
   621 	}
       
   622 
       
   623 HBufC8* TTcSIPCommandBase::ExtractHBufLC( const TDesC8& aParamName )
       
   624 	{
       
   625 	TPtrC8 value = ExtractTextL( aParamName, EFalse );
       
   626 	if( value != KNullDesC8 )
       
   627 		{
       
   628 		HBufC8* buf = value.AllocLC();
       
   629 		iPushed++;
       
   630 		return buf;
       
   631 		}
       
   632 
       
   633 	return NULL;
       
   634 	}
       
   635 	
       
   636 TInt TTcSIPCommandBase::ExtractProfileIdL()
       
   637     {
       
   638     TPtrC8 profileIdStr = ExtractIdL( KParamProfileId );
       
   639 	TInt profileId( 0 );
       
   640 	TLex8 lexer( profileIdStr );
       
   641 	User::LeaveIfError( lexer.Val( profileId ) );
       
   642 	return profileId;
       
   643     }
       
   644     
       
   645 TUid TTcSIPCommandBase::ExtractUidL( const TDesC8& aName,TBool aIsMandatory  )
       
   646     {
       
   647     const TInt KHexAsTextValueStartPos = 2;
       
   648       
       
   649     TPtrC8 uidStr = ExtractTextL( aName, aIsMandatory );
       
   650     
       
   651     if ( !aIsMandatory && uidStr.Length() == 0 )
       
   652         {
       
   653         return TUid::Uid( 0 );
       
   654         }
       
   655     
       
   656     __ASSERT_ALWAYS( uidStr.Length() > KHexAsTextValueStartPos, User::Leave( KErrArgument ) );
       
   657 	TUint uidVal( 0 );
       
   658 	TLex8 lexer( uidStr.Mid( KHexAsTextValueStartPos ) );
       
   659 	User::LeaveIfError( lexer.Val( uidVal, EHex ) );
       
   660 	return TUid::Uid( static_cast<TInt>( uidVal ) );
       
   661     }
       
   662 
       
   663 TPtrC8 TTcSIPCommandBase::NameFromHeader( const TDesC8& aHeader ) const
       
   664 	{
       
   665 	TInt pos = aHeader.Locate( KHeaderSeparator );
       
   666 	if( pos == KErrNotFound )
       
   667 		{
       
   668 		// return an empty pointer descriptor
       
   669 		return TPtrC8();
       
   670 		}
       
   671 	return aHeader.Left( pos );
       
   672 	}
       
   673 
       
   674 TPtrC8 TTcSIPCommandBase::ValueFromHeader( const TDesC8& aHeader ) const
       
   675 	{
       
   676 	TInt pos = aHeader.Locate( KHeaderSeparator );
       
   677 	if( pos == KErrNotFound )
       
   678 		{
       
   679 		// return an empty pointer descriptor
       
   680 		return TPtrC8( 0 );
       
   681 		}
       
   682 	pos++;	// skip the separator
       
   683 	return aHeader.Mid( pos );
       
   684 	}
       
   685 
       
   686 TBool TTcSIPCommandBase::IsHeaderAllowed( RStringF aName )
       
   687 	{
       
   688 	// The SIP headers can be divided to two sets:
       
   689 	// Supported headers and extension headers.
       
   690 	// The supported headers can be further divided into two subsets:
       
   691 	// API headers and private headers. 
       
   692 	// Private headers cannot be set by the application.
       
   693 	if( SIPHeaderLookup::IsAPIHeader( aName ))
       
   694 		{
       
   695         if( aName == SIPStrings::StringF( SipStrConsts::EFromHeader ) ||
       
   696             aName == SIPStrings::StringF( SipStrConsts::EToHeader ) ||
       
   697             aName == SIPStrings::StringF( SipStrConsts::ECSeqHeader ) ||
       
   698             aName == SIPStrings::StringF( SipStrConsts::EContentTypeHeader ) )
       
   699 		  	{
       
   700 			return EFalse;
       
   701 			}
       
   702 		}
       
   703 	else
       
   704 		{
       
   705 		if( SIPHeaderLookup::IsSupported( aName ) ) // Private header
       
   706 			{
       
   707 			return EFalse;
       
   708 			}
       
   709 		}
       
   710 	return ETrue;
       
   711 	}