os/ossrv/genericservices/httputils/UriParser/TValidator.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
// System includes
sl@0
    17
#include <uriutilscommon.h>
sl@0
    18
#include <uriutils.h>
sl@0
    19
#include <delimitedpathsegment8.h>
sl@0
    20
#include <delimitedquery8.h>
sl@0
    21
#include <escapeutils.h>
sl@0
    22
sl@0
    23
//User includes
sl@0
    24
#include "UriUtilsInternal.h"
sl@0
    25
#include "TValidator.h"
sl@0
    26
sl@0
    27
//Constants
sl@0
    28
_LIT8(KTransport, "transport");
sl@0
    29
_LIT8(KUser, "user"); 
sl@0
    30
_LIT8(KMethod, "method");
sl@0
    31
_LIT8(KTtl, "ttl");
sl@0
    32
_LIT8(KMaddr, "maddr");
sl@0
    33
_LIT8(KLr, "lr");
sl@0
    34
_LIT8(KExtension, "ext" );
sl@0
    35
_LIT8(KIsdnSubAddress, "isub" );
sl@0
    36
_LIT8(KContext, "phone-context" );
sl@0
    37
const TInt KMaxHostAddr = 255;
sl@0
    38
sl@0
    39
sl@0
    40
/**
sl@0
    41
	Constructor.
sl@0
    42
 */
sl@0
    43
TValidatorBase::TValidatorBase(const TUriC8& aUri)
sl@0
    44
: iUri(aUri)
sl@0
    45
	{
sl@0
    46
	}
sl@0
    47
sl@0
    48
/**
sl@0
    49
	Checks the Uri to be valid. 
sl@0
    50
	If there is no valid Host, Port, userinfo, Path, Query or Fragment then the 
sl@0
    51
	return value indicates an appropriate invalid Component. else returns zero, 
sl@0
    52
	which indicates given uri is valid.
sl@0
    53
sl@0
    54
	@return whether the Uri is Valid by returning zero or appropriate error value 
sl@0
    55
			for Invalid Uri.
sl@0
    56
 */
sl@0
    57
TInt TValidatorBase::Validate()
sl@0
    58
	{
sl@0
    59
	if (!IsValidHost())
sl@0
    60
		{
sl@0
    61
		return KUriUtilsErrInvalidHost;
sl@0
    62
		}
sl@0
    63
	
sl@0
    64
	if (!IsValidPort())
sl@0
    65
		{
sl@0
    66
		return KUriUtilsErrInvalidPort;
sl@0
    67
		}
sl@0
    68
		
sl@0
    69
	if (!IsValidUserInfo())
sl@0
    70
		{
sl@0
    71
		return KUriUtilsErrInvalidUserInfo;
sl@0
    72
		}
sl@0
    73
	
sl@0
    74
	if (!IsValidPath())
sl@0
    75
		{
sl@0
    76
		return KUriUtilsErrInvalidParam;
sl@0
    77
		}
sl@0
    78
	
sl@0
    79
	if (!IsValidQuery())
sl@0
    80
		{
sl@0
    81
		return KUriUtilsErrInvalidHeaders;
sl@0
    82
		}
sl@0
    83
	
sl@0
    84
	if (!IsValidFragment())
sl@0
    85
		{
sl@0
    86
		return KUriUtilsErrInvalidFragment;
sl@0
    87
		}
sl@0
    88
	
sl@0
    89
	return KErrNone;
sl@0
    90
	}
sl@0
    91
sl@0
    92
/**
sl@0
    93
    Checks whether the given character is in Valid Set of characters.
sl@0
    94
 	@param		aChar A Character needs to be checked against Set of characters.
sl@0
    95
 	@param		aCharSet A set of Characters Descriptor.
sl@0
    96
 	@return 	returns ETrue if aChar is a Valid Character else returns EFalse.
sl@0
    97
 */
sl@0
    98
TBool TValidatorBase::IsInCharSet(TText8 aChar, const TDesC8& aCharSet) const
sl@0
    99
	{
sl@0
   100
	for (TInt i = 0; i < aCharSet.Length(); i++)
sl@0
   101
		{
sl@0
   102
		if (aChar == aCharSet[i])
sl@0
   103
			{
sl@0
   104
			return ETrue;
sl@0
   105
		}
sl@0
   106
		}
sl@0
   107
	return EFalse;		
sl@0
   108
	}
sl@0
   109
sl@0
   110
/**
sl@0
   111
    Checks whether the given descriptor is Valid or not.
sl@0
   112
 	@param		aDes A Descriptor needs to be checked against Set of characters 
sl@0
   113
 				defined in aCharTypes.
sl@0
   114
 	@param		aCharTypes A set of Characters Descriptor.
sl@0
   115
 	@param		aEscapeValid For the given aCharTypes whether the Escape encoded is valid 
sl@0
   116
 				or not while Validating aDes, is specified by setting ETrue or EFalse 
sl@0
   117
 	@return 	returns ETrue if aDes is a Valid descriptor else returns EFalse.
sl@0
   118
 */
sl@0
   119
TBool TValidatorBase::IsValidCharacters(const TDesC8& aDes, TUint32 aCharTypes, TBool aEscapeValid) const
sl@0
   120
	{
sl@0
   121
	TInt len = aDes.Length();
sl@0
   122
	for (TInt i=0; i < len; i++)
sl@0
   123
		{
sl@0
   124
		TUint8 ch = aDes[i];
sl@0
   125
		// check for and decode '%' encoded characters
sl@0
   126
		if (aEscapeValid && ch == '%')
sl@0
   127
			{
sl@0
   128
			TInt hex;
sl@0
   129
			if (!EscapeUtils::IsEscapeTriple(aDes.Mid(i,3), hex))
sl@0
   130
				{
sl@0
   131
				// not a valid encoding
sl@0
   132
				return EFalse;
sl@0
   133
				}
sl@0
   134
			i += 2;
sl@0
   135
			continue;
sl@0
   136
			}
sl@0
   137
			
sl@0
   138
		if ((aCharTypes & KCharSetNumber) && (ch >= '0' && ch <= '9'))
sl@0
   139
			{
sl@0
   140
			continue; 
sl@0
   141
			} 
sl@0
   142
		if ((aCharTypes & KCharSetLowerAlpha) && (ch >= 'a' && ch <= 'z'))
sl@0
   143
			{
sl@0
   144
			continue; 
sl@0
   145
			}
sl@0
   146
		if ((aCharTypes & KCharSetUpperAlpha) && (ch >= 'A' && ch <= 'Z'))
sl@0
   147
			{
sl@0
   148
			continue; 
sl@0
   149
			}
sl@0
   150
		if ((aCharTypes & KCharSetAlways) && IsInCharSet(ch, KAlwaysValidChars()))
sl@0
   151
			{
sl@0
   152
			continue; 
sl@0
   153
			}
sl@0
   154
		if ((aCharTypes & KCharSetCommon) && IsInCharSet(ch, KCommonValidChars))
sl@0
   155
			{
sl@0
   156
			continue; 
sl@0
   157
			}
sl@0
   158
		if ((aCharTypes & KCharSetUser) && IsInCharSet(ch, KValidUserChars))
sl@0
   159
			{
sl@0
   160
			continue;
sl@0
   161
			}
sl@0
   162
		if ((aCharTypes & KCharSetParam) && IsInCharSet(ch, KValidParamChars))
sl@0
   163
			{
sl@0
   164
			continue; 
sl@0
   165
			}
sl@0
   166
		if ((aCharTypes & KCharSetHeader) && IsInCharSet(ch, KValidHeaderChars))
sl@0
   167
			{
sl@0
   168
			continue; 
sl@0
   169
			}
sl@0
   170
		if ((aCharTypes & KCharSetSipMark) && IsInCharSet(ch, KUriAlwaysValidSipMarkChars))
sl@0
   171
			{
sl@0
   172
			continue; 	
sl@0
   173
			}
sl@0
   174
			
sl@0
   175
		if ((aCharTypes & KCharSetSipPwd) && IsInCharSet(ch, KUriValidSipPwdChars))
sl@0
   176
			{
sl@0
   177
			continue; 	
sl@0
   178
			}
sl@0
   179
		
sl@0
   180
		if ((aCharTypes & KCharSetSipTkn) && IsInCharSet(ch, KUriValidSipToken))
sl@0
   181
			{
sl@0
   182
			continue; 	
sl@0
   183
			}
sl@0
   184
		
sl@0
   185
		// character is not valid so exit
sl@0
   186
		return EFalse;
sl@0
   187
		}
sl@0
   188
	return ETrue;
sl@0
   189
	}
sl@0
   190
sl@0
   191
/**
sl@0
   192
	The meaning empty here is that the component is present but it's value is not present
sl@0
   193
	This occures when the delimeter for a component is in the URI but there is 
sl@0
   194
	nothing in the URI after the delimeter. For example:
sl@0
   195
	1. sip:loc.com		- a URI with no port
sl@0
   196
	2. sip:loc.com:		- a URI with a port delimeter but no port value. The port is 'empty'.
sl@0
   197
	3. sip:loc.com:1666	- a URI with a port
sl@0
   198
	
sl@0
   199
	@param		aDes A Descriptor.
sl@0
   200
 	@return		ETrue or EFalse.
sl@0
   201
 */
sl@0
   202
TBool TValidatorBase::IsEmpty(const TDesC8& aDes) const
sl@0
   203
	{
sl@0
   204
	TInt len = aDes.Length();
sl@0
   205
	const TUint8* ptr = aDes.Ptr();
sl@0
   206
	if (!len && ptr)
sl@0
   207
		{
sl@0
   208
		// An entry for this item has been created so the delimeter was encountered
sl@0
   209
		// However, no value has been found. The item is empty
sl@0
   210
		return ETrue;
sl@0
   211
		}
sl@0
   212
	return EFalse;
sl@0
   213
	}
sl@0
   214
sl@0
   215
sl@0
   216
//
sl@0
   217
//		Implementatin of support for Sip-Uris as specified in RFC 3261.    //
sl@0
   218
//
sl@0
   219
sl@0
   220
/**
sl@0
   221
	Constructor.
sl@0
   222
 */
sl@0
   223
TValidatorSip::TValidatorSip(const TUriC8& aUri) 
sl@0
   224
: TValidatorBase(aUri)
sl@0
   225
	{
sl@0
   226
	}
sl@0
   227
sl@0
   228
/**
sl@0
   229
	Checks that a Host is in a valid form as specified in RFC 3261.
sl@0
   230
sl@0
   231
	@return		A boolean value of ETrue if uri contains valid Host,
sl@0
   232
				EFalse if it does not.
sl@0
   233
 */	
sl@0
   234
TBool TValidatorSip::IsValidHost() const
sl@0
   235
	{
sl@0
   236
	const TDesC8& host = iUri.Extract(EUriHost);
sl@0
   237
	if (host.Length() == 0)
sl@0
   238
		{
sl@0
   239
		return EFalse;
sl@0
   240
		}
sl@0
   241
	
sl@0
   242
	// IPv4 and IPv6 hosts are validated so just check text hosts
sl@0
   243
	if (UriUtils::HostType(host) == UriUtils::ETextHost &&	!IsTextHostValid(host))
sl@0
   244
		{
sl@0
   245
		return EFalse;
sl@0
   246
		}
sl@0
   247
	return ETrue;
sl@0
   248
	}
sl@0
   249
	
sl@0
   250
/**
sl@0
   251
	Checks that a Port is in a valid form as specified in RFC 3261.
sl@0
   252
sl@0
   253
	@return		A boolean value of ETrue if uri contains valid Port,
sl@0
   254
				EFalse if it does not.
sl@0
   255
 */	
sl@0
   256
TBool TValidatorSip::IsValidPort() const
sl@0
   257
	{
sl@0
   258
	const TDesC8& port = iUri.Extract(EUriPort);
sl@0
   259
	if (IsEmpty(port))
sl@0
   260
		{
sl@0
   261
		return EFalse;
sl@0
   262
		}
sl@0
   263
	return IsValidCharacters(port, KCharSetNumber);
sl@0
   264
	}
sl@0
   265
	
sl@0
   266
/**
sl@0
   267
	Checks whether Userinfo contains valid characters in the sip-uri as specified in RFC 3261.
sl@0
   268
							
sl@0
   269
	@param		aUser	The descriptor to be checked.
sl@0
   270
	@return		A boolean value of ETrue if uri contains valid Userinfo,
sl@0
   271
				EFalse if it does not.
sl@0
   272
*/
sl@0
   273
TBool TValidatorSip::IsValidUser(const TDesC8& aUser) const
sl@0
   274
	{
sl@0
   275
	return IsValidCharacters(aUser, KCharSetUserAll, ETrue);
sl@0
   276
	}
sl@0
   277
sl@0
   278
/**
sl@0
   279
	Checks whether Password contains valid characters in the sip-uri as specified in RFC 3261.
sl@0
   280
							
sl@0
   281
	@param		aPassword	The descriptor to be checked.
sl@0
   282
	@return		A boolean value of ETrue if uri contains valid Password,
sl@0
   283
				EFalse if it does not.
sl@0
   284
*/
sl@0
   285
TBool TValidatorSip::IsValidPassword(const TDesC8& aPassword) const
sl@0
   286
	{
sl@0
   287
	if (!aPassword.Length())
sl@0
   288
		{
sl@0
   289
		return EFalse;
sl@0
   290
		}
sl@0
   291
	return IsValidCharacters(aPassword, KCharSetSipPassWord, ETrue);
sl@0
   292
	}
sl@0
   293
sl@0
   294
/**
sl@0
   295
	Checks that a UserInfo is in a valid form as specified in RFC 3261.
sl@0
   296
sl@0
   297
	@return		A boolean value of ETrue if uri contains valid UserInfo,
sl@0
   298
				EFalse if it does not.
sl@0
   299
 */
sl@0
   300
TBool TValidatorSip::IsValidUserInfo() const
sl@0
   301
	{
sl@0
   302
	const TDesC8& userInfo = iUri.Extract(EUriUserinfo);
sl@0
   303
	
sl@0
   304
	if (IsEmpty(userInfo))
sl@0
   305
		{
sl@0
   306
		// The '@' UserInfo sparator was found in the URI but no username/password 
sl@0
   307
		// is present
sl@0
   308
		return EFalse;
sl@0
   309
		}
sl@0
   310
	
sl@0
   311
	TInt separatorPos = userInfo.Locate(KUserPwdSeparator);
sl@0
   312
	if (separatorPos != KErrNotFound)
sl@0
   313
		{
sl@0
   314
		// seperator found so there is a username and password
sl@0
   315
		// the username is left of the separator
sl@0
   316
		if (!IsValidUser(userInfo.Left(separatorPos)))
sl@0
   317
			{
sl@0
   318
			return EFalse;
sl@0
   319
			}
sl@0
   320
		// the password is right of the separator
sl@0
   321
		return IsValidPassword(userInfo.Right(userInfo.Length() - separatorPos-1));
sl@0
   322
		}
sl@0
   323
		
sl@0
   324
	// there is no password element
sl@0
   325
	return IsValidUser(userInfo);
sl@0
   326
	}
sl@0
   327
sl@0
   328
/**
sl@0
   329
	Checks whether any duplicate parameter names exist in the 
sl@0
   330
	whole path of the sip-uri.
sl@0
   331
							
sl@0
   332
	@param		aParamName	The descriptor to be checked.
sl@0
   333
	@param		aParamList	the path/parameter part of uri, which conatians all parameters and values.
sl@0
   334
	@return		A boolean value of ETrue if uri contains duplicate parameters,
sl@0
   335
				EFalse if it does not.
sl@0
   336
*/
sl@0
   337
TBool TValidatorSip::IsDuplicated(const TDesC8& aParamName, const TDelimitedParserBase8 aParamList) const
sl@0
   338
	{
sl@0
   339
	// roll back to the start of the lhs segment parser
sl@0
   340
	while(aParamList.Dec() != KErrNotFound) 
sl@0
   341
	{
sl@0
   342
	//Nothing to do
sl@0
   343
	}
sl@0
   344
	
sl@0
   345
	TPtrC8 name;
sl@0
   346
	TPtrC8 value;
sl@0
   347
	TPtrC8 segment;
sl@0
   348
	TInt count = 0;
sl@0
   349
	while( aParamList.GetNext(segment) == KErrNone )
sl@0
   350
		{
sl@0
   351
		GetNameValuePair(segment, name, value);
sl@0
   352
		if (aParamName.CompareF(name) == 0)
sl@0
   353
			{
sl@0
   354
			count++;
sl@0
   355
			}
sl@0
   356
		if (count > 1)
sl@0
   357
			{
sl@0
   358
			// The parameter name appears more than once in the paramter list
sl@0
   359
			return ETrue;
sl@0
   360
			}
sl@0
   361
		}
sl@0
   362
	return EFalse;	
sl@0
   363
	}
sl@0
   364
sl@0
   365
/**
sl@0
   366
	Checks whether parameter contains valid characters in the sip-uri as specified in RFC 3261.
sl@0
   367
							
sl@0
   368
	@param		aParam	The descriptor to be checked.
sl@0
   369
	@return		A boolean value of ETrue if uri contains valid parameter,
sl@0
   370
				EFalse if it does not.
sl@0
   371
*/
sl@0
   372
TBool TValidatorSip::IsValidParam(const TDesC8& aParam) const
sl@0
   373
	{
sl@0
   374
	return IsValidCharacters(aParam, KCharSetParamAll, ETrue);
sl@0
   375
	}
sl@0
   376
sl@0
   377
/**
sl@0
   378
	Checks whether ParamSegment contains valid characters in 
sl@0
   379
	Parameter name and Parameter value as specified in RFC 3261.
sl@0
   380
							
sl@0
   381
	@param		aName	The descriptor for parameter name to be checked as per RFC 3261.
sl@0
   382
	@param		aValue	The descriptor for value to be checked as per RFC 3261.
sl@0
   383
	@return		A boolean value of ETrue if uri contains valid parameters and values,
sl@0
   384
				EFalse if it does not.
sl@0
   385
*/
sl@0
   386
TBool TValidatorSip::IsValidParamSegment(const TDesC8& aName, const TDesC8& aValue) const
sl@0
   387
	{
sl@0
   388
	if (!aName.Length() || !IsValidParam(aName) ) 
sl@0
   389
		{
sl@0
   390
		return EFalse;	
sl@0
   391
		}
sl@0
   392
	
sl@0
   393
	/**************************************************************************************************************
sl@0
   394
	* As per RFC 3261 if the uri-parameter contains name as Tranport or User or Method then its Value must be     *
sl@0
   395
	* the characters as specified in Token. else if the name is Ttl then its value must lie in between 0 - 255.   *
sl@0
   396
	* else if the name is Maddr then its value must be a host, else if the name is lr then it must not conatin    *
sl@0
   397
	* any value, else it must be a other-parameter whose value must conatin the characters specified in paramchar.*
sl@0
   398
	* As per INC 115503 and due to IOP issue Validation of lr paramater is not performed.						  *
sl@0
   399
	***************************************************************************************************************/
sl@0
   400
	if ( ( (aName.CompareF(KTransport()) == 0 || aName.CompareF(KUser()) == 0 || aName.CompareF(KMethod()) == 0 ) 	
sl@0
   401
	   	   	  && !IsValidParamToken(aValue) )
sl@0
   402
		|| ( aName.CompareF(KTtl()) == 0 && !IsValidParamTtl(aValue) )
sl@0
   403
		|| ( aName.CompareF(KMaddr()) == 0  && !IsValidParamMaddr(aValue) )
sl@0
   404
		|| ( aName.CompareF(KTransport()) != 0 && aName.CompareF(KUser()) != 0 && aName.CompareF(KMethod()) != 0 && aName.CompareF(KTtl()) != 0 
sl@0
   405
			&& aName.CompareF(KMaddr()) != 0 && aName.CompareF(KLr()) != 0 && !IsValidParam(aValue))
sl@0
   406
		)
sl@0
   407
		{
sl@0
   408
		return EFalse;	
sl@0
   409
		}
sl@0
   410
sl@0
   411
	return ETrue;
sl@0
   412
	}
sl@0
   413
sl@0
   414
/**
sl@0
   415
	Checks whether parameters "transport", "User" and "Method" contains valid characters in the 
sl@0
   416
	sip-uri as specified in RFC 3261.
sl@0
   417
								
sl@0
   418
	@param		aParam	The descriptor to be checked.
sl@0
   419
	@return		A boolean value of ETrue if uri contains valid parameter,
sl@0
   420
				EFalse if it does not.
sl@0
   421
*/
sl@0
   422
TBool TValidatorSip::IsValidParamToken(const TDesC8& aParam) const
sl@0
   423
	{
sl@0
   424
	if (!aParam.Length())
sl@0
   425
		{
sl@0
   426
		return EFalse;	
sl@0
   427
		}
sl@0
   428
	return IsValidCharacters(aParam, KCharSetSipToken, EFalse);
sl@0
   429
	}
sl@0
   430
	
sl@0
   431
/**
sl@0
   432
	Checks whether parameter "ttl" contains valid characters in the sip-uri as specified in RFC 3261.
sl@0
   433
	
sl@0
   434
							
sl@0
   435
	@param		aParam	The descriptor to be checked.
sl@0
   436
	@return		A boolean value of ETrue if uri contains valid parameter,
sl@0
   437
				EFalse if it does not.
sl@0
   438
*/
sl@0
   439
TBool TValidatorSip::IsValidParamTtl(const TDesC8& aParam) const
sl@0
   440
	{
sl@0
   441
	if (!aParam.Length() || aParam.Length() > 3 || !IsValidCharacters(aParam, KCharSetNumber, EFalse) )
sl@0
   442
		{
sl@0
   443
		return EFalse;	
sl@0
   444
		}
sl@0
   445
	
sl@0
   446
	TLex8 lex(aParam);
sl@0
   447
	TInt address = 0;
sl@0
   448
	lex.Val(address);
sl@0
   449
	if( address > KMaxHostAddr )
sl@0
   450
		{
sl@0
   451
		return EFalse;	
sl@0
   452
		}
sl@0
   453
		
sl@0
   454
	return ETrue;
sl@0
   455
	}
sl@0
   456
	
sl@0
   457
/**
sl@0
   458
	Checks whether parameter "maddr" contains valid characters in the sip-uri as specified in RFC 3261.
sl@0
   459
							
sl@0
   460
	@param		aParam	The descriptor to be checked.
sl@0
   461
	@return		A boolean value of ETrue if uri contains valid parameter,
sl@0
   462
				EFalse if it does not.
sl@0
   463
*/
sl@0
   464
TBool TValidatorSip::IsValidParamMaddr(const TDesC8& aParam) const
sl@0
   465
	{
sl@0
   466
	if (!aParam.Length() && UriUtils::HostType(aParam) == UriUtils::ETextHost && !IsTextHostValid(aParam))
sl@0
   467
		{
sl@0
   468
		return EFalse;
sl@0
   469
		}
sl@0
   470
	return ETrue;
sl@0
   471
	}
sl@0
   472
	
sl@0
   473
/**
sl@0
   474
	Checks that a Path/uri-parameter is in a valid form as specified in RFC 3261.
sl@0
   475
	
sl@0
   476
	@return		A boolean value of ETrue if uri contains valid Path/uri-parameter,
sl@0
   477
				EFalse if it does not.
sl@0
   478
*/
sl@0
   479
TBool TValidatorSip::IsValidPath() const
sl@0
   480
	{
sl@0
   481
	const TDesC8& parameters = iUri.Extract(EUriPath);
sl@0
   482
	TDelimitedPathSegmentParser8 parser;
sl@0
   483
	parser.Parse(parameters);
sl@0
   484
	
sl@0
   485
	// sip parameters should start with a ';'
sl@0
   486
	if (parameters.Length() && parameters[0] != ';')
sl@0
   487
		{
sl@0
   488
		return EFalse;
sl@0
   489
		}
sl@0
   490
		
sl@0
   491
	TPtrC8 name;
sl@0
   492
	TPtrC8 value;
sl@0
   493
	TPtrC8 segment;
sl@0
   494
	while( parser.GetNext(segment) == KErrNone )
sl@0
   495
		{
sl@0
   496
		GetNameValuePair(segment, name, value);
sl@0
   497
		if (IsEmpty(value) || IsDuplicated(name, parser) || !IsValidParamSegment(name, value))
sl@0
   498
			{
sl@0
   499
			return EFalse;
sl@0
   500
		}
sl@0
   501
		}
sl@0
   502
sl@0
   503
	return ETrue;
sl@0
   504
	}
sl@0
   505
sl@0
   506
/**
sl@0
   507
	Checks whether Header contains valid characters as specified in RFC 3261.
sl@0
   508
							
sl@0
   509
	@param		aHeader	The descriptor to be checked as per RFC 3261.
sl@0
   510
	@return		A boolean value of ETrue if uri contains valid Header,
sl@0
   511
				EFalse if it does not.
sl@0
   512
*/
sl@0
   513
TBool TValidatorSip::IsValidHeader(const TDesC8& aHeader) const
sl@0
   514
	{
sl@0
   515
	return IsValidCharacters(aHeader, KCharSetHeaderAll, ETrue);
sl@0
   516
	}
sl@0
   517
	
sl@0
   518
/**
sl@0
   519
	Checks whether HeaderSegment contains valid name and values as specified in RFC 3261.
sl@0
   520
							
sl@0
   521
	@param		aName	The descriptor for Header name to be checked as per RFC 3261.
sl@0
   522
	@param		aValue	The descriptor for Header value to be checked as per RFC 3261.
sl@0
   523
	@return		A boolean value of ETrue if uri contains valid Header name and Header values,
sl@0
   524
				EFalse if it does not.
sl@0
   525
*/
sl@0
   526
TBool TValidatorSip::IsValidHeaderSegment(const TDesC8& aName, const TDesC8& aValue) const
sl@0
   527
	{
sl@0
   528
	if (!aName.Length() || !IsValidHeader(aName) || !IsValidHeader(aValue))
sl@0
   529
		{
sl@0
   530
		return EFalse;
sl@0
   531
		}
sl@0
   532
	return ETrue;
sl@0
   533
	}
sl@0
   534
	
sl@0
   535
/**
sl@0
   536
	Checks that a Query/Header is in a valid form as specified in RFC 3261.
sl@0
   537
sl@0
   538
	@return		A boolean value of ETrue if uri contains valid Query/Header,
sl@0
   539
				EFalse if it does not.
sl@0
   540
*/
sl@0
   541
TBool TValidatorSip::IsValidQuery() const
sl@0
   542
	{
sl@0
   543
	const TDesC8& headers = iUri.Extract(EUriQuery);
sl@0
   544
	if (IsEmpty(headers))
sl@0
   545
		{
sl@0
   546
		return EFalse;
sl@0
   547
		}
sl@0
   548
sl@0
   549
	TDelimitedQueryParser8 parser;
sl@0
   550
	parser.Parse(headers);
sl@0
   551
sl@0
   552
	TPtrC8 name;
sl@0
   553
	TPtrC8 value;
sl@0
   554
	TPtrC8 segment;
sl@0
   555
	while( parser.GetNext(segment) == KErrNone )
sl@0
   556
		{
sl@0
   557
		// must be in the form name=value even if the value part is empty
sl@0
   558
		if (segment.Locate(KEqualsSeparator) == KErrNotFound)
sl@0
   559
			{
sl@0
   560
			return EFalse;
sl@0
   561
			}
sl@0
   562
		
sl@0
   563
		GetNameValuePair(segment, name, value);
sl@0
   564
		if (IsDuplicated(name, parser) || !IsValidHeaderSegment(name, value))
sl@0
   565
			{
sl@0
   566
			return EFalse;
sl@0
   567
		}
sl@0
   568
		}
sl@0
   569
	return ETrue;
sl@0
   570
	}
sl@0
   571
sl@0
   572
/**
sl@0
   573
	Checks that a Fragment is in a valid form as specified in RFC 3261.
sl@0
   574
	Infact, SIP URIs should not contain a fragment. It it contains a 
sl@0
   575
	fragment then it is not a valid fragment.
sl@0
   576
	
sl@0
   577
	@return		A boolean value of ETrue if uri contains valid Fragment,
sl@0
   578
				EFalse if it does not.
sl@0
   579
*/
sl@0
   580
TBool TValidatorSip::IsValidFragment() const
sl@0
   581
	{
sl@0
   582
	const TDesC8& frag = iUri.Extract(EUriFragment);
sl@0
   583
	if (IsEmpty(frag))
sl@0
   584
		{
sl@0
   585
		return EFalse;
sl@0
   586
		}
sl@0
   587
	// SIP URIs should not contain a fragment
sl@0
   588
	if (frag.Length())
sl@0
   589
		{
sl@0
   590
		return EFalse;
sl@0
   591
		}
sl@0
   592
	return ETrue;
sl@0
   593
	}
sl@0
   594
sl@0
   595
	
sl@0
   596
//
sl@0
   597
//	Implementatin of partial support for tel-Uris specified in RFC 3966.   //
sl@0
   598
//	Parsing of phone number separators as specified in RFC 3966 		   //
sl@0
   599
//  section 5 will not be supported. 									   //
sl@0
   600
//  The Implementation supports only of the form tel:36789017;isub=1411    //
sl@0
   601
//  It does not support lexicographical order of parameters for Validation.//
sl@0
   602
//
sl@0
   603
sl@0
   604
/**
sl@0
   605
	Constructor.
sl@0
   606
	@param		aUri A reference to a parsed uri object.
sl@0
   607
 */
sl@0
   608
TValidatorTel::TValidatorTel(const TUriC8& aUri) 
sl@0
   609
: TValidatorBase(aUri)
sl@0
   610
	{
sl@0
   611
	}
sl@0
   612
sl@0
   613
/**
sl@0
   614
	Checks whether valid parameter names and values exist in the 
sl@0
   615
	whole path of the tel-uri.
sl@0
   616
								
sl@0
   617
	@param		aName	The descriptor for parameter name to be checked as per RFC3966.
sl@0
   618
	@param		aValue	The descriptor for value to be checked as per RFC3966.
sl@0
   619
	@return		A boolean value of ETrue if uri contains valid parameters and values,
sl@0
   620
				EFalse if it does not.
sl@0
   621
 */
sl@0
   622
TBool TValidatorTel::IsValidParamSegment(const TDesC8& aName, const TDesC8& aValue) const
sl@0
   623
	{
sl@0
   624
	//Validation of the Name
sl@0
   625
	if (!aName.Length() || !IsValidCharacters(aName, KCharSetParamAll) )
sl@0
   626
		{
sl@0
   627
		return EFalse;	
sl@0
   628
		}
sl@0
   629
	//Validation of the Value based on ISDN, EXTN, Phone-context or any.
sl@0
   630
	if( ( KIsdnSubAddress().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetParamAll, ETrue) ) ||
sl@0
   631
		( KExtension().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetNumber) ) ||
sl@0
   632
		( KContext().CompareF(aName) == 0 && !IsValidCharacters(aValue, KCharSetParamAll) ) ||
sl@0
   633
		( KIsdnSubAddress().CompareF(aName) != 0 && 
sl@0
   634
		KExtension().CompareF(aName) != 0	&&
sl@0
   635
		KContext().CompareF(aName) != 0 &&
sl@0
   636
		!IsValidCharacters(aValue, KCharSetParamAll, ETrue) ) )
sl@0
   637
		{
sl@0
   638
		return EFalse;	
sl@0
   639
		}
sl@0
   640
	return ETrue;
sl@0
   641
	}
sl@0
   642
sl@0
   643
/**
sl@0
   644
	Checks whether any duplicate parameter names exist in the 
sl@0
   645
	whole path of the tel-uri, and also checks whether the both ISDN and EXTN 
sl@0
   646
	parameters exist in tel-uri.
sl@0
   647
							
sl@0
   648
	@param		aParamName	The descriptor to be checked.
sl@0
   649
	@param		aParamList	the path part of uri, which conatians all parameters and values.
sl@0
   650
	@return		A boolean value of ETrue if uri contains duplicate parameters or 
sl@0
   651
				both isdn and extn parameters exist, EFalse if it does not.
sl@0
   652
 */
sl@0
   653
TBool TValidatorTel::IsDuplicated(const TDesC8& aParamName, const TDelimitedParserBase8 aParamList) const
sl@0
   654
	{
sl@0
   655
	// roll back to the start of the lhs segment parser
sl@0
   656
	while(aParamList.Dec() != KErrNotFound) 
sl@0
   657
		{
sl@0
   658
		//do nothing
sl@0
   659
		}
sl@0
   660
	aParamList.Inc(); //To exclude phone number from the list.
sl@0
   661
	
sl@0
   662
	TPtrC8 name;
sl@0
   663
	TPtrC8 value;
sl@0
   664
	TPtrC8 segment;
sl@0
   665
	TInt count = 0;
sl@0
   666
	while( aParamList.GetNext(segment) == KErrNone )
sl@0
   667
		{
sl@0
   668
		GetNameValuePair(segment, name, value);
sl@0
   669
		if (aParamName.CompareF(name) == 0)
sl@0
   670
			{
sl@0
   671
			count++;	
sl@0
   672
			}
sl@0
   673
		if (count > 1)
sl@0
   674
			{
sl@0
   675
			// The parameter name appears more than once in the paramter list
sl@0
   676
			return ETrue;
sl@0
   677
			}
sl@0
   678
		if( ( KIsdnSubAddress().CompareF(aParamName) == 0 && KExtension().CompareF(name) == 0 ) || 
sl@0
   679
			( KExtension().CompareF(aParamName) == 0 && KIsdnSubAddress().CompareF(name) == 0 ) )
sl@0
   680
			{
sl@0
   681
			//Both ISDN and EXTN should not exist in Uri
sl@0
   682
			return ETrue;	
sl@0
   683
			}
sl@0
   684
		}
sl@0
   685
sl@0
   686
	return EFalse;	
sl@0
   687
	}
sl@0
   688
sl@0
   689
/**
sl@0
   690
	Checks that a path is in a valid form
sl@0
   691
	
sl@0
   692
	@return	ETrue if the path is valid otherwise EFalse
sl@0
   693
 */
sl@0
   694
TBool TValidatorTel::IsValidPath() const
sl@0
   695
	{
sl@0
   696
	const TDesC8& path = iUri.Extract(EUriPath);
sl@0
   697
	//empty path is invalid
sl@0
   698
	if(!path.Length())
sl@0
   699
		{
sl@0
   700
		return EFalse;	
sl@0
   701
		}
sl@0
   702
	
sl@0
   703
	//Implementation of all the steps specified in section 2.5.2.2 
sl@0
   704
	//Validation of the path components of tel uri
sl@0
   705
	
sl@0
   706
	TDelimitedPathSegmentParser8 parser;
sl@0
   707
	parser.Parse(path);
sl@0
   708
	
sl@0
   709
	// tel parameters should start with a '+' or 'digit'
sl@0
   710
	TChar ch( path[0] );
sl@0
   711
	if(! (ch == '+' || ch.IsDigit()) )
sl@0
   712
		{
sl@0
   713
		return EFalse;	
sl@0
   714
		}
sl@0
   715
			
sl@0
   716
	TPtrC8 name;
sl@0
   717
	TPtrC8 value;
sl@0
   718
	TPtrC8 segment;
sl@0
   719
	//First segemnt must be telephone number
sl@0
   720
	if (parser.GetNext(segment) == KErrNone)
sl@0
   721
		{
sl@0
   722
		GetNameValuePair(segment, name, value);	
sl@0
   723
		//contains only digits
sl@0
   724
		if(!IsValidCharacters(name.Mid(1), KCharSetNumber))
sl@0
   725
			{
sl@0
   726
			return EFalse;	
sl@0
   727
			}
sl@0
   728
		}
sl@0
   729
	//Remainig all the segments
sl@0
   730
	while( parser.GetNext(segment) == KErrNone )
sl@0
   731
		{
sl@0
   732
		GetNameValuePair(segment, name, value);
sl@0
   733
		if(IsEmpty(segment))
sl@0
   734
			{
sl@0
   735
			return ETrue;	
sl@0
   736
			}
sl@0
   737
		if ( IsEmpty(value) || IsDuplicated(name, parser) || !IsValidParamSegment(name, value) )
sl@0
   738
			{
sl@0
   739
			return EFalse;	
sl@0
   740
			}
sl@0
   741
		}
sl@0
   742
	return ETrue;
sl@0
   743
	}
sl@0
   744
sl@0
   745
/**
sl@0
   746
	Checks that a host is in a valid form
sl@0
   747
	
sl@0
   748
	@return	ETrue. "tel" uri does not conatin host
sl@0
   749
 */
sl@0
   750
TBool TValidatorTel::IsValidHost() const
sl@0
   751
	{
sl@0
   752
	//do nothing
sl@0
   753
	return ETrue;
sl@0
   754
	}
sl@0
   755
sl@0
   756
/**
sl@0
   757
	Checks that a UserInfo is in a valid form
sl@0
   758
	
sl@0
   759
	@return	ETrue. "tel" uri does not conatin UserInfo
sl@0
   760
 */
sl@0
   761
TBool TValidatorTel::IsValidUserInfo() const
sl@0
   762
	{ 
sl@0
   763
	//do nothing
sl@0
   764
	return ETrue;
sl@0
   765
	}
sl@0
   766
sl@0
   767
/**
sl@0
   768
	Checks that a Port is in a valid form
sl@0
   769
	
sl@0
   770
	@return	ETrue. "tel" uri does not conatin Port
sl@0
   771
 */
sl@0
   772
TBool TValidatorTel::IsValidPort() const
sl@0
   773
	{
sl@0
   774
	//do nothing
sl@0
   775
	return ETrue;
sl@0
   776
	}
sl@0
   777
sl@0
   778
/**
sl@0
   779
	Checks that a Query is in a valid form
sl@0
   780
	
sl@0
   781
	@return	ETrue. "tel" uri does not conatin Query
sl@0
   782
 */
sl@0
   783
TBool TValidatorTel::IsValidQuery() const
sl@0
   784
	{
sl@0
   785
	//do nothing
sl@0
   786
	return ETrue;
sl@0
   787
	}
sl@0
   788
sl@0
   789
/**
sl@0
   790
	Checks that a Fragment is in a valid form
sl@0
   791
	
sl@0
   792
	@return	ETrue. "tel" uri does not conatin Fragment
sl@0
   793
 */
sl@0
   794
TBool TValidatorTel::IsValidFragment() const
sl@0
   795
	{
sl@0
   796
	//do nothing
sl@0
   797
	return ETrue;
sl@0
   798
	}
sl@0
   799