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