genericservices/httputils/UriParser/TValidator.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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