contentmgmt/referencedrmagent/RefTestAgent/localsdp/src/sdporiginfield.cpp
changeset 66 8873e6835f7b
equal deleted inserted replaced
62:b23410e29e22 66:8873e6835f7b
       
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          :  SdpOriginField.cpp
       
    15 // Part of       :  Local SDP Codec
       
    16 // Version       :  1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include <in_sock.h>
       
    22 #include <s32strm.h>
       
    23 #include "sdporiginfield.h"
       
    24 #include "sdporiginfieldptrs.h"
       
    25 #include "sdputil.h"
       
    26 #include "sdpcodecstringconstants.h"
       
    27 #include "sdpcodecconstants.h"
       
    28 #include "sdpcodecstringpool.h"
       
    29 #include "sdpcodecerr.h"
       
    30 #include "sdpcodec.pan"
       
    31 #include "_sdpdefs.h"
       
    32 
       
    33 // LOCAL CONSTANTS AND MACROS
       
    34 const TUint KMaxIPDesLength = 39;
       
    35 const TUint KHeaderIndex = 0;
       
    36 const TUint KUserNameIndex = 1;
       
    37 const TUint KSessionIdIndex = 2;
       
    38 const TUint KSessionVersionIndex = 3;
       
    39 const TUint KNetworkTypeIndex = 4;
       
    40 const TUint KAddressTypeIndex = 5;
       
    41 const TUint KAddressIndex = 6;
       
    42 const TInt KTokenCount = 7;
       
    43 const TInt64 KDummyValue = 1;
       
    44 
       
    45 // ============================ MEMBER FUNCTIONS ===============================
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CSdpOriginField::CSdpOriginField
       
    49 // C++ default constructor can NOT contain any code, that
       
    50 // might leave.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 CSdpOriginField::CSdpOriginField()
       
    54     {
       
    55     }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CSdpOriginField::ConstructL
       
    59 // Symbian 2nd phase constructor can leave.
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 void CSdpOriginField::ConstructL(    
       
    63     const TDesC8& aText )
       
    64 	{
       
    65     // aText should be of format:
       
    66     // o=<username> <session id> <version> <network type> 
       
    67     // <address type> <address>     
       
    68     iPool = SdpCodecStringPool::StringPoolL();
       
    69 
       
    70     RArray<TPtrC8> array;
       
    71     array = SdpUtil::GetElementsFromLineL( aText, KErrSdpCodecOriginField );
       
    72     
       
    73     CleanupClosePushL( array );
       
    74 
       
    75     if ( array.Count() != KTokenCount )
       
    76         {
       
    77         User::Leave( KErrSdpCodecOriginField );
       
    78         }
       
    79 
       
    80     // Check that the line contains valid header
       
    81     RStringF origHeader =  iPool.StringF( SdpCodecStringConstants::EOrigin, 
       
    82                                           SdpCodecStringConstants::Table );
       
    83     if ( origHeader.DesC().CompareF( array[KHeaderIndex] ) != 0 )
       
    84         {
       
    85         // Header didn't match
       
    86         User::Leave( KErrSdpCodecOriginField );
       
    87         }
       
    88     
       
    89     iUserName =
       
    90     	reinterpret_cast< HBufC8* >( CSdpOriginFieldPtrs::NewL( 0, 0 ) );
       
    91 		
       
    92     
       
    93     // <username>   
       
    94     ParseUserNameL( array );
       
    95     
       
    96     // <session id> & <version>
       
    97     ParseSessionIDAndVersionL( array );
       
    98     
       
    99     // <network type> & <address type>
       
   100     ParseNetTypeAndAddressTypeL( array );
       
   101     
       
   102     // <address>
       
   103     ParseAddressL( array );
       
   104     
       
   105 	//If address is IPv4-Mapped IPv6 , it is changed to IPv4
       
   106 	TInetAddr addr;
       
   107 	TBuf<KMaxAddressLength> address;
       
   108 	address.Copy(iAddress);
       
   109 
       
   110 	TInt err = addr.Input( address );
       
   111 	if ( err == KErrNone )
       
   112 		{
       
   113         // Valid IP address
       
   114 		TBuf<KMaxIPDesLength> buf;
       
   115 		addr.Output( buf );
       
   116 		iAddress.Copy(buf); 
       
   117 
       
   118         SetIPAddressType( addr );
       
   119 		}
       
   120 
       
   121 
       
   122 
       
   123     CleanupStack::PopAndDestroy();  // array
       
   124 
       
   125 	__TEST_INVARIANT;
       
   126 	}
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CSdpOriginField::ConstructL
       
   130 // Symbian 2nd phase constructor can leave.
       
   131 // -----------------------------------------------------------------------------
       
   132 //
       
   133 void CSdpOriginField::ConstructL(
       
   134     const TDesC8& aUserName, 
       
   135     TInt64 aSessionId, 
       
   136     TInt64 aSessionVersion, 
       
   137     TInetAddr& aUnicastAddress )
       
   138 	{
       
   139     iPool = SdpCodecStringPool::StringPoolL();
       
   140 
       
   141 	__ASSERT_ALWAYS( 
       
   142                    IsValidUserName( aUserName )
       
   143 				&& IsValidAddress( aUnicastAddress )
       
   144                 && aSessionId >= 0 && aSessionVersion >= 0,
       
   145 				User::Leave( KErrSdpCodecOriginField ) );
       
   146 
       
   147 	iUserName = reinterpret_cast< HBufC8* >
       
   148 		( CSdpOriginFieldPtrs::NewL( aSessionId, aSessionVersion ) );
       
   149 	OriginFieldPtrs().SetUserNameL( aUserName );
       
   150 	
       
   151     TBuf<KMaxIPDesLength> des;
       
   152     aUnicastAddress.Output( des );
       
   153 	//if aUnicastAddress was IPv4-Mapped IPv6 address,
       
   154 	// the result of Output is IPv4
       
   155 	// the address is stored in IPv4 format, so the iAddressType 
       
   156 	// must also be IPv4.    
       
   157     iAddress.Copy( des );
       
   158     SetIPAddressType( aUnicastAddress );
       
   159 
       
   160     iNetType = iPool.StringF( SdpCodecStringConstants::ENetType, 
       
   161                               SdpCodecStringConstants::Table ).Copy();
       
   162        
       
   163 	__TEST_INVARIANT;
       
   164 	}
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CSdpOriginField::ConstructL
       
   168 // Symbian 2nd phase constructor can leave.
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 void CSdpOriginField::ConstructL( 
       
   172     const TDesC8& aUserName, 
       
   173     TInt64 aSessionId, 
       
   174     TInt64 aSessionVersion, 
       
   175     RStringF aNetType, 
       
   176     RStringF aAddressType, 
       
   177     const TDesC8& aAddress )
       
   178     {        
       
   179     iPool = SdpCodecStringPool::StringPoolL();
       
   180      
       
   181     __ASSERT_ALWAYS(
       
   182                IsValidUserName( aUserName )
       
   183             && IsValidAddress( aAddress ) &&
       
   184             TypeMatchesWithFormat( aAddress, aAddressType.DesC(), iPool )
       
   185             && ( SdpUtil::IsToken( aNetType.DesC() ) )
       
   186             && ( SdpUtil::IsToken( aAddressType.DesC() ) )
       
   187             && aSessionId >= 0 && aSessionVersion >= 0,
       
   188             User::Leave( KErrSdpCodecOriginField ) );
       
   189     
       
   190     iUserName = reinterpret_cast< HBufC8* >
       
   191 		( CSdpOriginFieldPtrs::NewL( aSessionId, aSessionVersion ) );
       
   192 	OriginFieldPtrs().SetUserNameL( aUserName );	
       
   193 
       
   194     iNetType = aNetType.Copy();
       
   195     	TInetAddr addr;
       
   196 	TBuf<KMaxAddressLength> address;
       
   197 	address.Copy(aAddress);
       
   198 	TInt err = addr.Input(address);
       
   199 	if ( err  == KErrNone )
       
   200 		{
       
   201 		// Valid IP address
       
   202 		TBuf< KMaxIPDesLength > buf;
       
   203 		addr.Output( buf );
       
   204 		iAddress.Copy( buf );		
       
   205 		SetIPAddressType( addr );
       
   206 		}
       
   207 	else
       
   208 		{
       
   209 		iAddress = aAddress;
       
   210     	iAddressType = aAddressType.Copy();	
       
   211 		}
       
   212     __TEST_INVARIANT;    
       
   213     }
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // CSdpOriginField::DecodeL
       
   217 // Two-phased constructor
       
   218 // -----------------------------------------------------------------------------
       
   219 //
       
   220 EXPORT_C CSdpOriginField* CSdpOriginField::DecodeL(    
       
   221     const TDesC8& aText )
       
   222 	{
       
   223 	CSdpOriginField* obj = CSdpOriginField::DecodeLC( aText );
       
   224 	CleanupStack::Pop();
       
   225 	return obj;
       
   226 	}
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CSdpOriginField::DecodeLC
       
   230 // Two-phased constructor
       
   231 // -----------------------------------------------------------------------------
       
   232 //
       
   233 EXPORT_C CSdpOriginField* CSdpOriginField::DecodeLC(    
       
   234     const TDesC8& aText )
       
   235 	{
       
   236 	CSdpOriginField* obj = new ( ELeave ) CSdpOriginField;
       
   237 	CleanupStack::PushL( obj );
       
   238 	obj->ConstructL(aText );
       
   239 	return obj;
       
   240 	}
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CSdpOriginField::NewL
       
   244 // Two-phased constructor
       
   245 // -----------------------------------------------------------------------------
       
   246 //
       
   247 EXPORT_C CSdpOriginField* CSdpOriginField::NewL(    
       
   248     const TDesC8& aUserName, 
       
   249 	TInt64 aSessionId, 
       
   250 	TInt64 aSessionVersion, 
       
   251 	TInetAddr& aAddress )
       
   252 	{
       
   253 	CSdpOriginField* obj = CSdpOriginField::NewLC( 
       
   254         aUserName, aSessionId, aSessionVersion, aAddress );
       
   255 	CleanupStack::Pop();
       
   256 	return obj;
       
   257 	}
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CSdpOriginField::NewLC
       
   261 // Two-phased constructor
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 EXPORT_C CSdpOriginField* CSdpOriginField::NewLC(    
       
   265     const TDesC8& aUserName, 
       
   266 	TInt64 aSessionId, 
       
   267 	TInt64 aSessionVersion, 
       
   268 	TInetAddr& aAddress )
       
   269 	{
       
   270 	CSdpOriginField* obj = new ( ELeave ) CSdpOriginField;
       
   271 	CleanupStack::PushL(obj);
       
   272 	obj->ConstructL( aUserName, aSessionId, aSessionVersion, aAddress );
       
   273 	return obj;
       
   274 	}
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CSdpOriginField::NewL
       
   278 // Two-phased constructor
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 EXPORT_C CSdpOriginField* CSdpOriginField::NewL(
       
   282     const TDesC8& aUserName, 
       
   283 	TInt64 aSessionId, 
       
   284 	TInt64 aSessionVersion, 
       
   285     RStringF aNetType,
       
   286     RStringF aAddressType, 
       
   287 	const TDesC8& aAddress )
       
   288     {
       
   289 	CSdpOriginField* obj = CSdpOriginField::NewLC( 
       
   290         aUserName, aSessionId, aSessionVersion, aNetType, 
       
   291         aAddressType, aAddress );
       
   292 	CleanupStack::Pop();
       
   293 	return obj;
       
   294     }
       
   295 
       
   296 // -----------------------------------------------------------------------------
       
   297 // CSdpOriginField::NewLC
       
   298 // Two-phased constructor
       
   299 // -----------------------------------------------------------------------------
       
   300 //
       
   301 EXPORT_C CSdpOriginField* CSdpOriginField::NewLC(
       
   302     const TDesC8& aUserName, 
       
   303 	TInt64 aSessionId, 
       
   304 	TInt64 aSessionVersion, 
       
   305 	RStringF aNetType,
       
   306     RStringF aAddressType, 
       
   307 	const TDesC8& aAddress )
       
   308     {    
       
   309     CSdpOriginField* obj = new ( ELeave ) CSdpOriginField;
       
   310 	CleanupStack::PushL( obj );
       
   311 	obj->ConstructL( aUserName, aSessionId, aSessionVersion, aNetType, 
       
   312                      aAddressType, aAddress );
       
   313     return obj;    
       
   314     }
       
   315 
       
   316 // -----------------------------------------------------------------------------
       
   317 // CSdpOriginField::~CSdpOriginField
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 EXPORT_C CSdpOriginField::~CSdpOriginField()
       
   321 	{
       
   322 	CSdpOriginFieldPtrs* tmp =
       
   323 		reinterpret_cast< CSdpOriginFieldPtrs* >( iUserName );
       
   324 	delete tmp;
       
   325 
       
   326     iNetType.Close();
       
   327     iAddressType.Close();
       
   328 	}
       
   329     
       
   330 // -----------------------------------------------------------------------------
       
   331 // CSdpOriginField::EncodeL
       
   332 // Writes attributes in proper format to the stream
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 EXPORT_C void CSdpOriginField::EncodeL(
       
   336     RWriteStream& aStream ) const
       
   337 	{
       
   338     __TEST_INVARIANT;
       
   339 
       
   340     // o=<username> <session id> <version> <network type> <address type> 
       
   341     //   <address>    
       
   342 
       
   343     // "o="
       
   344     RStringF header = iPool.StringF( SdpCodecStringConstants::EOrigin, 
       
   345                                      SdpCodecStringConstants::Table );
       
   346     aStream.WriteL( header.DesC() );
       
   347 
       
   348     // <username>
       
   349     aStream.WriteL( OriginFieldPtrs().UserName() );
       
   350 	aStream.WriteL( KSPStr );
       
   351 
       
   352     // <session id>    
       
   353 	aStream.WriteL( OriginFieldPtrs().SessionId() );
       
   354 	aStream.WriteL( KSPStr );
       
   355 
       
   356     // <version>
       
   357     aStream.WriteL( OriginFieldPtrs().SessionVersion() );
       
   358 	aStream.WriteL( KSPStr );
       
   359 
       
   360     // <network type>
       
   361     aStream.WriteL( iNetType.DesC() );
       
   362     aStream.WriteL( KSPStr );    
       
   363 
       
   364     // <address type>
       
   365     aStream.WriteL( iAddressType.DesC() );
       
   366     aStream.WriteL( KSPStr );
       
   367 
       
   368     // <address>
       
   369     aStream.WriteL( iAddress );
       
   370 
       
   371     // End-of-Line mark
       
   372 	aStream.WriteL( KCRLFStr );
       
   373 	}
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // CSdpOriginField::CloneL
       
   377 // Creates an exact copy of the origin field
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 EXPORT_C CSdpOriginField* CSdpOriginField::CloneL() const
       
   381 	{
       
   382 	__TEST_INVARIANT;
       
   383 
       
   384     CSdpOriginField* obj = 0;
       
   385 
       
   386     if ( InetAddress() )
       
   387         {
       
   388         // Clones instance with TInetAddr
       
   389         TInetAddr addr( *InetAddress() );        
       
   390         obj = CSdpOriginField::NewLC( UserName(), KDummyValue,
       
   391         							  KDummyValue, addr );
       
   392         }
       
   393     else
       
   394         {
       
   395         // Clones instance with Internet address as a standard string               
       
   396         obj = CSdpOriginField::NewLC( UserName(), KDummyValue, KDummyValue,
       
   397                                       iNetType, iAddressType,  Address() );        
       
   398         }
       
   399 
       
   400 	// Set the real values
       
   401 	obj->OriginFieldPtrs().SetSessionIdL( OriginFieldPtrs().SessionId() );
       
   402 	obj->OriginFieldPtrs().SetSessionVersionL(
       
   403 		OriginFieldPtrs().SessionVersion() );
       
   404 	CleanupStack::Pop( obj );
       
   405 		
       
   406 	__ASSERT_DEBUG( *this == *obj, User::Panic( KSdpCodecPanicCat, 
       
   407                                                 KSdpCodecPanicInternal ) );
       
   408 	return obj;
       
   409 	}
       
   410 
       
   411 // -----------------------------------------------------------------------------
       
   412 // CSdpOriginField::operator ==
       
   413 // Checks if two origin fields are equal
       
   414 // -----------------------------------------------------------------------------
       
   415 //
       
   416 EXPORT_C TBool CSdpOriginField::operator == (
       
   417     const CSdpOriginField& aObj) const
       
   418 	{
       
   419 	__TEST_INVARIANT;
       
   420 
       
   421     TBool equalFields = EFalse;
       
   422 
       
   423     // Check that username, session ID and address type match before
       
   424     // going to internet address       
       
   425     if ( ( UserName().CompareF( aObj.UserName() ) == 0 ) &&
       
   426          ( SessionId() == aObj.SessionId() ) &&
       
   427          ( AddressType() == aObj.AddressType() ) &&
       
   428          ( Version() == aObj.Version() ) &&
       
   429          ( NetType() == aObj.NetType() ) )
       
   430         {
       
   431         if ( InetAddress() && aObj.InetAddress() )
       
   432             {            
       
   433             if ( (*InetAddress()).Match( *aObj.InetAddress() ) )
       
   434                 {
       
   435                 equalFields = ETrue;
       
   436                 }
       
   437             }
       
   438         else if ( !InetAddress() && !aObj.InetAddress() )            
       
   439             {
       
   440             if ( iAddress.CompareF( aObj.Address() ) == 0 )
       
   441                 {
       
   442                 equalFields = ETrue;
       
   443                 }
       
   444             }                
       
   445         else
       
   446             {
       
   447             // These two are not the same
       
   448             }
       
   449         }   
       
   450         
       
   451     return equalFields;
       
   452 	}
       
   453 
       
   454 // -----------------------------------------------------------------------------
       
   455 // CSdpOriginField::UserName
       
   456 // Returns username
       
   457 // -----------------------------------------------------------------------------
       
   458 //
       
   459 EXPORT_C const TDesC8& CSdpOriginField::UserName() const
       
   460     {
       
   461     __TEST_INVARIANT;
       
   462     return OriginFieldPtrs().UserName();
       
   463     }
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // CSdpOriginField::SetUserNameL
       
   467 // Sets a new username
       
   468 // -----------------------------------------------------------------------------
       
   469 //
       
   470 EXPORT_C void CSdpOriginField::SetUserNameL(
       
   471     const TDesC8& aValue )
       
   472     {
       
   473     __TEST_INVARIANT;
       
   474     if ( IsValidUserName( aValue ) )
       
   475         {
       
   476         OriginFieldPtrs().SetUserNameL( aValue );
       
   477         }
       
   478     else
       
   479         {
       
   480         User::Leave( KErrSdpCodecOriginField );
       
   481         }
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CSdpOriginField::SessionId
       
   486 // Returns current session id
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 EXPORT_C TInt64 CSdpOriginField::SessionId() const
       
   490     {
       
   491     __TEST_INVARIANT;
       
   492 
       
   493     return Get63Msbs( OriginFieldPtrs().SessionId() );
       
   494     }
       
   495 
       
   496 // -----------------------------------------------------------------------------
       
   497 // CSdpOriginField::SetSessionId
       
   498 // Sets new session ID
       
   499 // -----------------------------------------------------------------------------
       
   500 //
       
   501 EXPORT_C void CSdpOriginField::SetSessionId(
       
   502 	TInt64 aValue )
       
   503     {
       
   504     __TEST_INVARIANT;
       
   505     if ( aValue >= 0 )
       
   506         {
       
   507         TRAP_IGNORE( OriginFieldPtrs().SetSessionIdL( aValue ) )
       
   508         }
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CSdpOriginField::Version
       
   513 // Returns version number of the announcement
       
   514 // -----------------------------------------------------------------------------
       
   515 //
       
   516 EXPORT_C TInt64 CSdpOriginField::Version() const
       
   517     {
       
   518     __TEST_INVARIANT;
       
   519 
       
   520     return Get63Msbs( OriginFieldPtrs().SessionVersion() );
       
   521     }
       
   522 
       
   523 // -----------------------------------------------------------------------------
       
   524 // CSdpOriginField::SetVersion
       
   525 // Sets new version for this session's announcement
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 EXPORT_C void CSdpOriginField::SetVersion(
       
   529 	TInt64 aValue )
       
   530     {
       
   531     __TEST_INVARIANT;
       
   532     if ( aValue >= 0 )
       
   533         {
       
   534         TRAP_IGNORE( OriginFieldPtrs().SetSessionVersionL( aValue ) )        
       
   535         }
       
   536     }
       
   537 
       
   538 // -----------------------------------------------------------------------------
       
   539 // CSdpOriginField::NetType
       
   540 // Returns net type (always Internet)
       
   541 // -----------------------------------------------------------------------------
       
   542 //
       
   543 EXPORT_C RStringF CSdpOriginField::NetType() const
       
   544 	{
       
   545 	__TEST_INVARIANT;
       
   546 	return iNetType;
       
   547 	}
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // CSdpOriginField::AddressType
       
   551 // Returns address type (IP4/IP6)
       
   552 // -----------------------------------------------------------------------------
       
   553 //
       
   554 EXPORT_C RStringF CSdpOriginField::AddressType() const
       
   555 	{
       
   556 	__TEST_INVARIANT;    
       
   557     return iAddressType;        
       
   558 	}
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // CSdpOriginField::InetAddress
       
   562 // Returns the unicast address
       
   563 // -----------------------------------------------------------------------------
       
   564 //
       
   565 EXPORT_C const TInetAddr* CSdpOriginField::InetAddress() const
       
   566 	{
       
   567 	__TEST_INVARIANT;
       
   568     
       
   569     TBuf<KMaxAddressLength> address16;
       
   570     address16.Copy( iAddress );
       
   571     TInt err = iUnicastAddress.Input( address16 );
       
   572     
       
   573     if ( !err )
       
   574         {
       
   575         return &iUnicastAddress;
       
   576         }
       
   577     else
       
   578         {
       
   579         return NULL;
       
   580         }
       
   581 	}
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // CSdpOriginField::Address
       
   585 // Returns the address
       
   586 // -----------------------------------------------------------------------------
       
   587 //
       
   588 EXPORT_C const TDesC8& CSdpOriginField::Address() const
       
   589     {
       
   590     __TEST_INVARIANT;
       
   591     return iAddress;
       
   592     }
       
   593 
       
   594 // -----------------------------------------------------------------------------
       
   595 // CSdpOriginField::SetInetAddress
       
   596 // Sets Internet Address
       
   597 // -----------------------------------------------------------------------------
       
   598 //
       
   599 EXPORT_C void CSdpOriginField::SetInetAddress(
       
   600     const TInetAddr& aValue )
       
   601 	{    
       
   602 	__TEST_INVARIANT;
       
   603     
       
   604 	if ( IsValidAddress( aValue ) )
       
   605         {                       
       
   606         TBuf<KMaxIPDesLength> buf;
       
   607         aValue.Output( buf );
       
   608         // Copy new address to safe
       
   609         iAddress.Copy( buf );
       
   610     
       
   611         // Copy network type and address type        
       
   612         SdpUtil::SetDefaultNetTypeAndAddrType( 
       
   613             iPool, aValue, iNetType, iAddressType );
       
   614         SetIPAddressType( aValue );
       
   615         }
       
   616 
       
   617     __TEST_INVARIANT;
       
   618 	}
       
   619 
       
   620 // -----------------------------------------------------------------------------
       
   621 // CSdpOriginField::SetAddressL
       
   622 // Sets address from the buffer
       
   623 // -----------------------------------------------------------------------------
       
   624 //
       
   625 EXPORT_C void CSdpOriginField::SetAddressL(
       
   626     const TDesC8& aAddress,
       
   627     RStringF aNetType, 
       
   628     RStringF aAddressType )
       
   629     {
       
   630     __TEST_INVARIANT;
       
   631      
       
   632     __ASSERT_ALWAYS( SdpUtil::IsToken( aNetType.DesC() )  &&
       
   633                      SdpUtil::IsToken( aAddressType.DesC() ) &&
       
   634                      IsValidAddress( aAddress ) &&
       
   635                      TypeMatchesWithFormat( aAddress, 
       
   636                                             aAddressType.DesC(), iPool ),
       
   637                      User::Leave( KErrSdpCodecOriginField ) );
       
   638 
       
   639     iAddress = aAddress;
       
   640     iAddressType.Close();
       
   641     iAddressType = aAddressType.Copy();
       
   642 
       
   643     __TEST_INVARIANT;
       
   644     }
       
   645 
       
   646 // -----------------------------------------------------------------------------
       
   647 // CSdpOriginField::ExternalizeL
       
   648 // Externalizes the field back to string
       
   649 // -----------------------------------------------------------------------------
       
   650 //	
       
   651 void CSdpOriginField::ExternalizeL(
       
   652     RWriteStream& aStream ) const
       
   653     {
       
   654     __TEST_INVARIANT;
       
   655 
       
   656     // <username>    
       
   657     aStream.WriteUint32L( UserName().Length() );
       
   658 	aStream.WriteL( UserName(), UserName().Length() );
       
   659     // <session id>
       
   660     aStream.WriteUint32L( OriginFieldPtrs().SessionId().Length() );
       
   661     aStream.WriteL( OriginFieldPtrs().SessionId(),
       
   662     				OriginFieldPtrs().SessionId().Length() );
       
   663     // <version>
       
   664     aStream.WriteUint32L( OriginFieldPtrs().SessionVersion().Length() );
       
   665     aStream.WriteL( OriginFieldPtrs().SessionVersion(),
       
   666     				OriginFieldPtrs().SessionVersion().Length() );
       
   667     // <network type>
       
   668     aStream.WriteUint32L( iNetType.DesC().Length() );
       
   669     aStream.WriteL( iNetType.DesC() );
       
   670     // <address type>
       
   671     aStream.WriteUint32L( iAddressType.DesC().Length() );
       
   672     aStream.WriteL( iAddressType.DesC() );    
       
   673     // <address>
       
   674     aStream.WriteUint32L( iAddress.Length() );
       
   675     aStream.WriteL( iAddress );
       
   676     }
       
   677 
       
   678 // -----------------------------------------------------------------------------
       
   679 // CSdpOriginField::InternalizeL
       
   680 // Internalizes from stream
       
   681 // -----------------------------------------------------------------------------
       
   682 //	
       
   683 CSdpOriginField* CSdpOriginField::InternalizeL(
       
   684     RReadStream& aStream )
       
   685     {    
       
   686     RStringPool pool = SdpCodecStringPool::StringPoolL();
       
   687 
       
   688     // <username>        
       
   689     TUint32 length = aStream.ReadUint32L();
       
   690 	HBufC8* userName = HBufC8::NewLC( length );
       
   691     TPtr8 ptr( userName->Des() );  
       
   692     aStream.ReadL( ptr, length );    
       
   693 
       
   694     // <session id>
       
   695     length = aStream.ReadUint32L();
       
   696 	HBufC8* sessionId = HBufC8::NewLC( length );
       
   697     ptr.Set( sessionId->Des() );
       
   698     aStream.ReadL( ptr, length );
       
   699 
       
   700     // <version>
       
   701     length = aStream.ReadUint32L();
       
   702 	HBufC8* version = HBufC8::NewLC( length );
       
   703     ptr.Set( version->Des() );
       
   704     aStream.ReadL( ptr, length );
       
   705 
       
   706     // <network type>
       
   707     length = aStream.ReadUint32L();
       
   708     HBufC8* netType = HBufC8::NewLC( length );
       
   709     ptr.Set( netType->Des() );
       
   710     aStream.ReadL( ptr, length );
       
   711 
       
   712     // <address type>
       
   713     length = aStream.ReadUint32L();
       
   714     HBufC8* addrType = HBufC8::NewLC( length );
       
   715     ptr.Set( addrType->Des() );
       
   716     aStream.ReadL( ptr, length );
       
   717 
       
   718     // <address>        
       
   719     length = aStream.ReadUint32L();
       
   720     HBufC8* address = HBufC8::NewLC( length );
       
   721     TPtr8 ptr2( address->Des() );
       
   722     aStream.ReadL( ptr2, length );
       
   723             
       
   724     RStringF netTypeStr = pool.OpenFStringL( *netType );
       
   725     RStringF addrTypeStr = pool.OpenFStringL( *addrType );
       
   726     CleanupClosePushL( netTypeStr );
       
   727     CleanupClosePushL( addrTypeStr );
       
   728 
       
   729 	CSdpOriginField* obj = CSdpOriginField::NewLC( *userName, KDummyValue,
       
   730 												   KDummyValue, netTypeStr,
       
   731 												   addrTypeStr, *address );
       
   732 	// Set the real values
       
   733 	obj->OriginFieldPtrs().SetSessionIdL( *sessionId );
       
   734 	obj->OriginFieldPtrs().SetSessionVersionL( *version );
       
   735 	CleanupStack::Pop( obj );
       
   736     CleanupStack::Pop( 2 ); // addrTypeStr, netTypeStr
       
   737     CleanupStack::PopAndDestroy( address );
       
   738     CleanupStack::PopAndDestroy( addrType );
       
   739     CleanupStack::PopAndDestroy( netType );
       
   740     CleanupStack::PopAndDestroy( version );
       
   741     CleanupStack::PopAndDestroy( sessionId );
       
   742     CleanupStack::PopAndDestroy( userName );    
       
   743 
       
   744     return obj;
       
   745     }
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // CSdpOriginField::IsValidAddress
       
   749 // Checks if the address is valid
       
   750 // -----------------------------------------------------------------------------
       
   751 //
       
   752 TBool CSdpOriginField::IsValidAddress( 
       
   753     const TDesC8& aAddress ) const
       
   754     {
       
   755     TInetAddr addr;
       
   756     TBool valid = ETrue;
       
   757 
       
   758     if ( aAddress.Length() > 0 && aAddress.Length() <= KMaxAddressLength )
       
   759         {
       
   760         TBuf<KMaxAddressLength> address16;
       
   761         address16.Copy( aAddress );
       
   762         TInt err = addr.Input( address16 );
       
   763 
       
   764         if ( !err )
       
   765             {
       
   766             valid = ( addr.IsUnicast() || addr.IsUnspecified() );
       
   767             }
       
   768         else
       
   769             {
       
   770             RStringF addrTypeIP4 = 
       
   771                 iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
       
   772                                SdpCodecStringConstants::Table );
       
   773             RStringF addrTypeIP6 = 
       
   774                 iPool.StringF( SdpCodecStringConstants::EAddressType,
       
   775                                SdpCodecStringConstants::Table );
       
   776             
       
   777             if ( iAddressType == addrTypeIP4 || iAddressType == addrTypeIP6 )
       
   778                 {
       
   779                 // FQDN address, check that it has only valid characters
       
   780                 // 0..9, a..z, A..Z, '.', '-'
       
   781                         
       
   782                 for ( TInt i( 0 ); i < aAddress.Length() && valid; i++ )
       
   783                     {
       
   784                     if (KValidFQDNChars().Locate(aAddress[i]) == KErrNotFound)
       
   785                         {
       
   786                         valid = EFalse;     
       
   787                         }
       
   788                     }
       
   789                 }
       
   790             else
       
   791                 {
       
   792                 valid = SdpUtil::IsNonWhitespace( aAddress );
       
   793                 }
       
   794             }       
       
   795         }
       
   796     else
       
   797     	{
       
   798     	valid = EFalse;
       
   799     	}
       
   800 
       
   801     return valid;
       
   802     }
       
   803 
       
   804 // -----------------------------------------------------------------------------
       
   805 // CSdpOriginField::IsValidAddress
       
   806 // Checks if the address is valid
       
   807 // -----------------------------------------------------------------------------
       
   808 //
       
   809 TBool CSdpOriginField::IsValidAddress( 
       
   810     const TInetAddr& addr ) const
       
   811     {
       
   812     TBuf<KMaxIPDesLength> buf16;
       
   813     TBuf8<KMaxIPDesLength> buf;
       
   814 	//if addr is IPv4-Mapped IPv6, buf value will be IPv4 after Output
       
   815     addr.Output( buf16 );
       
   816     buf.Copy( buf16 );
       
   817 
       
   818     return IsValidAddress( buf );
       
   819     }
       
   820 
       
   821 // -----------------------------------------------------------------------------
       
   822 // CSdpOriginField::TypeMatchesWithFormat
       
   823 // Checks if address type is aligned with the address format
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 TBool CSdpOriginField::TypeMatchesWithFormat( 
       
   827     const TDesC8& aAddress, 
       
   828     const TDesC8& aType,
       
   829     RStringPool aPool ) const
       
   830     {
       
   831     RStringF addrTypeIP4 = 
       
   832         aPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
       
   833                               SdpCodecStringConstants::Table );
       
   834     RStringF addrTypeIP6 = 
       
   835         aPool.StringF( SdpCodecStringConstants::EAddressType,
       
   836                               SdpCodecStringConstants::Table );
       
   837     
       
   838     TBool valid( ETrue );
       
   839     
       
   840     // Check that address type and address matches together
       
   841     TInetAddr addr;
       
   842     TBuf<KMaxAddressLength> address16;
       
   843     address16.Copy( aAddress );
       
   844     TInt err = addr.Input( address16 );    
       
   845     if ( err == KErrNone && !addr.IsUnspecified())
       
   846         {
       
   847         TBool ip4Type = ( addrTypeIP4.DesC().CompareF( aType ) == 0 );
       
   848         TBool ip6Type = ( addrTypeIP6.DesC().CompareF( aType ) == 0 );
       
   849              
       
   850         if ( ip4Type || ip6Type )
       
   851             {
       
   852             if ( ( addr.Address() && !addr.IsV4Mapped() && !ip4Type ) ||
       
   853 				 (addr.Address() && addr.IsV4Mapped() && !ip6Type) ||
       
   854                  ( !addr.Address() && !ip6Type ) )
       
   855                 {
       
   856                 valid = EFalse;
       
   857                 }
       
   858             }
       
   859         } 
       
   860     
       
   861     return valid;
       
   862     }
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // CSdpOriginField::IsValidUserName
       
   866 // Checks if the given username is valid
       
   867 // -----------------------------------------------------------------------------
       
   868 //
       
   869 TBool CSdpOriginField::IsValidUserName( 
       
   870     const TDesC8& aUserName ) const
       
   871     {
       
   872     TBool valid = EFalse;
       
   873 
       
   874     if ( aUserName.Length() > 0 && SdpUtil::IsNonWhitespace( aUserName ) )
       
   875         {
       
   876         valid = ETrue;
       
   877         }
       
   878 
       
   879     return valid;
       
   880     }
       
   881 
       
   882 // -----------------------------------------------------------------------------
       
   883 // CSdpOriginField::ParseUserNameL
       
   884 // Parses username. Can't use CSdpOriginField::SetUserNameL, as invariant would
       
   885 // fail.
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 void CSdpOriginField::ParseUserNameL( 
       
   889     RArray<TPtrC8>& aArray )
       
   890     {
       
   891     __ASSERT_ALWAYS( IsValidUserName( aArray[KUserNameIndex] ), 
       
   892                      User::Leave( KErrSdpCodecOriginField ) );
       
   893 	OriginFieldPtrs().SetUserNameL( aArray[KUserNameIndex] );    
       
   894     }
       
   895 
       
   896 // -----------------------------------------------------------------------------
       
   897 // CSdpOriginField::ParseSessionIDAndVersionL
       
   898 // Parses session ID and version
       
   899 // -----------------------------------------------------------------------------
       
   900 //
       
   901 void CSdpOriginField::ParseSessionIDAndVersionL( 
       
   902     RArray<TPtrC8>& aArray )
       
   903     {
       
   904     __ASSERT_ALWAYS( SdpUtil::IsDigit( aArray[KSessionIdIndex] ) &&
       
   905     				 SdpUtil::IsDigit( aArray[KSessionVersionIndex] ),
       
   906     				 User::Leave( KErrSdpCodecOriginField ) );
       
   907 
       
   908     OriginFieldPtrs().SetSessionIdL( aArray[KSessionIdIndex] );
       
   909     OriginFieldPtrs().SetSessionVersionL( aArray[KSessionVersionIndex] );    
       
   910     }
       
   911  
       
   912  // -----------------------------------------------------------------------------
       
   913 // CSdpOriginField::ParseNetTypeAndAddressTypeL
       
   914 // Parses network type and address type
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 void CSdpOriginField::ParseNetTypeAndAddressTypeL( 
       
   918     RArray<TPtrC8>& aArray )
       
   919     {
       
   920     if ( !SdpUtil::IsToken( aArray[KNetworkTypeIndex] ) ||
       
   921          !SdpUtil::IsToken( aArray[KAddressTypeIndex] ) )
       
   922         {        
       
   923         User::Leave( KErrSdpCodecOriginField );
       
   924         }
       
   925 
       
   926     iNetType = iPool.OpenFStringL( aArray[KNetworkTypeIndex] );  
       
   927     iAddressType = iPool.OpenFStringL( aArray[KAddressTypeIndex] );    
       
   928     }
       
   929 
       
   930 // -----------------------------------------------------------------------------
       
   931 // CSdpOriginField::ParseAddressL
       
   932 // Parses address
       
   933 // -----------------------------------------------------------------------------
       
   934 //
       
   935 void CSdpOriginField::ParseAddressL( 
       
   936     RArray<TPtrC8>& aArray )
       
   937     {    
       
   938     if ( !IsValidAddress( aArray[KAddressIndex] ) )
       
   939         {
       
   940         User::Leave( KErrSdpCodecOriginField );
       
   941         }
       
   942     else
       
   943         {
       
   944         iAddress = aArray[KAddressIndex];
       
   945         }
       
   946 
       
   947     // Check that address type and address matches together
       
   948     if ( !TypeMatchesWithFormat( 
       
   949                     aArray[KAddressIndex], aArray[KAddressTypeIndex], iPool ) )
       
   950         {
       
   951         User::Leave( KErrSdpCodecOriginField );            
       
   952         } 
       
   953     }
       
   954 
       
   955 // -----------------------------------------------------------------------------
       
   956 // CSdpOriginField::OriginFieldPtrs
       
   957 // -----------------------------------------------------------------------------
       
   958 //  
       
   959 inline CSdpOriginFieldPtrs& CSdpOriginField::OriginFieldPtrs()
       
   960     {
       
   961     return *( reinterpret_cast< CSdpOriginFieldPtrs* >( iUserName ) );
       
   962     }
       
   963 
       
   964 // -----------------------------------------------------------------------------
       
   965 // CSdpOriginField::OriginFieldPtrs
       
   966 // -----------------------------------------------------------------------------
       
   967 //  
       
   968 inline const CSdpOriginFieldPtrs& CSdpOriginField::OriginFieldPtrs() const
       
   969     {
       
   970     return *( reinterpret_cast< CSdpOriginFieldPtrs* >( iUserName ) );
       
   971     }
       
   972 
       
   973 // -----------------------------------------------------------------------------
       
   974 // CSdpOriginField::Get63Msbs
       
   975 // Returns a maximum of 63 bits of information from the descriptor containing a
       
   976 // decimal number.
       
   977 // -----------------------------------------------------------------------------
       
   978 //
       
   979 TInt64 CSdpOriginField::Get63Msbs( const TDesC8& aDecimalValue ) const
       
   980 	{	
       
   981 	// The maximum amount of digits in a decimal number, that is guaranteed to
       
   982   	// fit into 63 bits, is 18. Even if all the 18 digits are 9, the decimal
       
   983   	// number is 999999999999999999.
       
   984   	const TInt64 KMaxAmountOfDecimalDigits = 18;
       
   985 
       
   986     TInt64 value( 0 );
       
   987     TPtrC8 msbPart = aDecimalValue.Left( KMaxAmountOfDecimalDigits );
       
   988 	TLex8( msbPart ).Val( value );
       
   989     return value;
       
   990 	}
       
   991 
       
   992 // -----------------------------------------------------------------------------
       
   993 // CSdpOriginField::SetIPAddressType
       
   994 // -----------------------------------------------------------------------------
       
   995 //
       
   996 void CSdpOriginField::SetIPAddressType( const TInetAddr& aAddr )
       
   997     {
       
   998     iAddressType.Close();
       
   999     if ( aAddr.Address() || aAddr.IsUnspecified() )
       
  1000         {
       
  1001         //IPv4, IPv4-Mapped IPv6 and 0.0.0.0
       
  1002 	    iAddressType =
       
  1003             iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
       
  1004                            SdpCodecStringConstants::Table ).Copy();
       
  1005         }
       
  1006     else
       
  1007         {
       
  1008         //IPv6
       
  1009         iAddressType =
       
  1010             iPool.StringF( SdpCodecStringConstants::EAddressType,
       
  1011                            SdpCodecStringConstants::Table ).Copy();
       
  1012  		}
       
  1013     }
       
  1014 
       
  1015 // For DEBUG builds
       
  1016 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CSdpOriginField::__DbgTestInvariant
       
  1019 // Test invariant
       
  1020 // -----------------------------------------------------------------------------
       
  1021 //	
       
  1022 void CSdpOriginField::__DbgTestInvariant() const
       
  1023 	{	    
       
  1024 	TBool invariant = 
       
  1025 				iUserName != NULL	
       
  1026                 && SdpUtil::IsToken( iAddressType.DesC() )
       
  1027                 && SdpUtil::IsToken( iNetType.DesC() )
       
  1028 				&& IsValidAddress( iAddress )
       
  1029 				&& IsValidUserName( OriginFieldPtrs().UserName() )
       
  1030                 && TypeMatchesWithFormat(iAddress, iAddressType.DesC(), iPool)
       
  1031                 && SdpUtil::IsNonWhitespace( OriginFieldPtrs().UserName() );
       
  1032 	
       
  1033     if ( !invariant )
       
  1034         {
       
  1035 		User::Invariant();
       
  1036         }
       
  1037 	}
       
  1038