realtimenetprots/sipfw/SDP/src/SdpConnectionField.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2003-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 // Name          : SdpConnectionField.cpp
       
    15 // Part of       : SDP Codec
       
    16 // Version       : 1.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include <in_sock.h>
       
    23 #include <s32strm.h>
       
    24 #include <stringpool.h>
       
    25 #include "SdpConnectionField.h"
       
    26 #include "sdpcodecstringconstants.h"
       
    27 #include "SdpCodecConstants.h"
       
    28 #include "SdpCodecStringPool.h"
       
    29 #include "SdpUtil.h"
       
    30 #include "SdpCodecErr.h"
       
    31 #include "SDPCodec.pan"
       
    32 #include "_sdpdefs.h"
       
    33 #include "uriutils.h"
       
    34 
       
    35 // LOCAL CONSTANTS
       
    36 const TInt KHeaderIndex = 0;
       
    37 const TInt KNetworkTypeIndex = 1;
       
    38 const TInt KAddressTypeIndex = 2;
       
    39 const TInt KAddressIndex = 3;
       
    40 const TInt KTokenCount = 4;
       
    41 const TInt KMaxAddressLength = 256;
       
    42 const TUint KMaxIPDesLength = 39;
       
    43 _LIT16(KWildAddr, "0.0.0.0");
       
    44 _LIT16(KWildAddrIPv6, "::");
       
    45 
       
    46 
       
    47 // ============================ MEMBER FUNCTIONS ===============================
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // CSdpConnectionField::CSdpConnectionField
       
    51 // C++ default constructor can NOT contain any code, that
       
    52 // might leave.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 CSdpConnectionField::CSdpConnectionField() :
       
    56     iTTL( KErrNotFound ),
       
    57     iNumOfAddress( KDefaultNumOfAddress )
       
    58 	{
       
    59 	}
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CSdpConnectionField::ConstructL
       
    63 // Symbian 2nd phase constructor can leave.
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 void CSdpConnectionField::ConstructL(
       
    67     const TDesC8& aText )
       
    68 	{
       
    69     // aText should be in format
       
    70     // c=<network type> <address type> <connection address>
       
    71     iPool = SdpCodecStringPool::StringPoolL();
       
    72 
       
    73     RArray<TPtrC8> array =
       
    74         SdpUtil::GetElementsFromLineL( aText, KErrSdpCodecConnectionField );
       
    75     CleanupClosePushL( array );
       
    76 
       
    77     if ( array.Count() != KTokenCount )
       
    78         {
       
    79         User::Leave( KErrSdpCodecConnectionField );
       
    80         }
       
    81 
       
    82     RStringF origHeader =  iPool.StringF( SdpCodecStringConstants::EConnection,
       
    83                                           SdpCodecStringConstants::Table );
       
    84     if ( origHeader.DesC().CompareF( array[KHeaderIndex] ) != 0 )
       
    85         {
       
    86         // Header didn't match
       
    87         User::Leave( KErrSdpCodecConnectionField );
       
    88         }
       
    89 
       
    90     // <network type>
       
    91     CopyNetTypeL( array[KNetworkTypeIndex] );
       
    92 
       
    93     // <address type>
       
    94     CopyAddressTypeL( array[KAddressTypeIndex] );
       
    95 
       
    96     // <address>
       
    97     CopyAddressL( array[KAddressIndex], iPool );
       
    98 
       
    99     CleanupStack::PopAndDestroy();  // array
       
   100 	}
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CSdpConnectionField::ConstructL
       
   104 // Symbian 2nd phase constructor can leave.
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 void CSdpConnectionField::ConstructL(
       
   108     const TInetAddr& aAddress,
       
   109     TInt aTTL,
       
   110     TUint aNumOfAddress )
       
   111 	{
       
   112     __ASSERT_ALWAYS( IsValidAddress(aAddress, aTTL, aNumOfAddress) == KErrNone,
       
   113                      User::Leave( KErrSdpCodecConnectionField ) );
       
   114 
       
   115     iPool = SdpCodecStringPool::StringPoolL();
       
   116     TBuf<KMaxIPDesLength> addr;
       
   117     //If aAddress is IPv4-Mapped IPv6,the result of Output is IPv4
       
   118     aAddress.Output( addr );
       
   119 
       
   120     // Copy address
       
   121     iAddress = HBufC8::NewL( addr.Length() );
       
   122     iAddress->Des().Copy( addr );
       
   123 
       
   124     // TTL
       
   125     iTTL = aTTL;
       
   126     // Num of addresses
       
   127     iNumOfAddress = aNumOfAddress;
       
   128     // Network type
       
   129     iNetType = iPool.StringF( SdpCodecStringConstants::ENetType,
       
   130                               SdpCodecStringConstants::Table ).Copy();
       
   131     // Address type
       
   132 	if ( UriUtils::HostType( addr ) == UriUtils::EIPv4Host )
       
   133 		{
       
   134 		//addresstype for IPv4
       
   135 			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
       
   136                                       SdpCodecStringConstants::Table ).Copy();
       
   137 			}
       
   138 	else if ( UriUtils::HostType( addr ) == UriUtils::EIPv6Host )
       
   139 			{
       
   140 			//addresstype IPv6
       
   141 			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressType,
       
   142                                       SdpCodecStringConstants::Table ).Copy();
       
   143 			}
       
   144 	else
       
   145 		{
       
   146 		User::Leave(KErrArgument);
       
   147 		}
       
   148 
       
   149 	__TEST_INVARIANT;
       
   150 	}
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CSdpConnectionField::ConstructL
       
   154 // Symbian 2nd phase constructor can leave.
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 void CSdpConnectionField::ConstructL(
       
   158     RStringF aNetType,
       
   159 	RStringF aAddressType,
       
   160 	const TDesC8& aAddress )
       
   161     {
       
   162     iPool = SdpCodecStringPool::StringPoolL();
       
   163 
       
   164     // Network type
       
   165     CopyNetTypeL( aNetType.DesC() );
       
   166 
       
   167     // Address type
       
   168     CopyAddressTypeL( aAddressType.DesC() );
       
   169 
       
   170     // Address + TTL + numOfAddress
       
   171     CopyAddressL( aAddress, aNetType.Pool() );
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CSdpConnectionField::DecodeL
       
   176 // Two-phased constructor
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 EXPORT_C CSdpConnectionField* CSdpConnectionField::DecodeL(
       
   180     const TDesC8& aText )
       
   181 	{
       
   182 	CSdpConnectionField* obj = CSdpConnectionField::DecodeLC( aText );
       
   183 	CleanupStack::Pop();
       
   184 	return obj;
       
   185 	}
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CSdpConnectionField::DecodeLC
       
   189 // Two-phased constructor
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 EXPORT_C CSdpConnectionField* CSdpConnectionField::DecodeLC(
       
   193     const TDesC8& aText )
       
   194 	{
       
   195 	CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
       
   196 	CleanupStack::PushL( obj );
       
   197 	obj->ConstructL( aText );
       
   198 	return obj;
       
   199 	}
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // CSdpConnectionField::NewL
       
   203 // Two-phased constructor
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 EXPORT_C CSdpConnectionField* CSdpConnectionField::NewL(
       
   207     const TInetAddr& aAddress,
       
   208     TInt aTTL,
       
   209     TUint aNumOfAddress )
       
   210 	{
       
   211 	CSdpConnectionField* obj = CSdpConnectionField::NewLC(
       
   212         aAddress, aTTL, aNumOfAddress );
       
   213 	CleanupStack::Pop();
       
   214 	return obj;
       
   215 	}
       
   216 // -----------------------------------------------------------------------------
       
   217 // CSdpConnectionField::NewLC
       
   218 // Two-phased constructor
       
   219 // -----------------------------------------------------------------------------
       
   220 //
       
   221 EXPORT_C CSdpConnectionField* CSdpConnectionField::NewLC(
       
   222     const TInetAddr& aAddress,
       
   223     TInt aTTL,
       
   224     TUint aNumOfAddress )
       
   225 	{
       
   226 	CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
       
   227 	CleanupStack::PushL( obj );
       
   228 	obj->ConstructL( aAddress, aTTL, aNumOfAddress );
       
   229 	return obj;
       
   230 	}
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // CSdpConnectionField::NewL
       
   234 // Two-phased constructor
       
   235 // -----------------------------------------------------------------------------
       
   236 //
       
   237 EXPORT_C CSdpConnectionField* CSdpConnectionField::NewL(
       
   238     RStringF aNetType,
       
   239     RStringF aAddressType,
       
   240     const TDesC8& aAddress )
       
   241     {
       
   242     CSdpConnectionField* obj = CSdpConnectionField::NewLC(
       
   243         aNetType, aAddressType, aAddress );
       
   244 	CleanupStack::Pop();
       
   245 	return obj;
       
   246     }
       
   247 
       
   248 // -----------------------------------------------------------------------------
       
   249 // CSdpConnectionField::NewLC
       
   250 // Two-phased constructor
       
   251 // -----------------------------------------------------------------------------
       
   252 //
       
   253 EXPORT_C CSdpConnectionField* CSdpConnectionField::NewLC(
       
   254     RStringF aNetType,
       
   255     RStringF aAddressType,
       
   256     const TDesC8& aAddress )
       
   257     {
       
   258     CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
       
   259 	CleanupStack::PushL( obj );
       
   260 	obj->ConstructL( aNetType, aAddressType, aAddress );
       
   261 	return obj;
       
   262     }
       
   263 
       
   264 // Destructor
       
   265 EXPORT_C CSdpConnectionField::~CSdpConnectionField()
       
   266 	{
       
   267     delete iAddress;
       
   268     iNetType.Close();
       
   269     iAddressType.Close();
       
   270 	}
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // CSdpConnectionField::EncodeL
       
   274 // Writes attributes in proper format to the stream
       
   275 // -----------------------------------------------------------------------------
       
   276 //
       
   277 EXPORT_C void CSdpConnectionField::EncodeL(
       
   278     RWriteStream& aStream ) const
       
   279 	{
       
   280 	__TEST_INVARIANT;
       
   281     TBuf8<20> number;  // Is enough for addr as well
       
   282 
       
   283     // c=<network type> <address type> <connection address>
       
   284     RStringF header = iPool.StringF( SdpCodecStringConstants::EConnection,
       
   285                                      SdpCodecStringConstants::Table );
       
   286     aStream.WriteL( header.DesC() );
       
   287 
       
   288     // Network type
       
   289     aStream.WriteL( iNetType.DesC() );
       
   290     aStream.WriteL( KSPStr );
       
   291 
       
   292     // Address type
       
   293     aStream.WriteL( iAddressType.DesC() );
       
   294     aStream.WriteL( KSPStr );
       
   295 
       
   296     // Connection address
       
   297     aStream.WriteL( *iAddress );
       
   298     if ( iTTL != KErrNotFound )
       
   299         {
       
   300         number.Zero();
       
   301         number.Append( KSlashStr );
       
   302         number.AppendFormat( _L8("%d"), iTTL );
       
   303         aStream.WriteL( number );
       
   304         }
       
   305 
       
   306     if ( iNumOfAddress > 1 )
       
   307         {
       
   308         number.Zero();
       
   309         number.Append( KSlashStr );
       
   310         number.AppendFormat( _L8("%u"), iNumOfAddress );
       
   311         aStream.WriteL( number );
       
   312         }
       
   313 
       
   314      // End-of-Line mark
       
   315 	aStream.WriteL( KCRLFStr );
       
   316 	}
       
   317 
       
   318 // -----------------------------------------------------------------------------
       
   319 // CSdpConnectionField::CloneL
       
   320 // Clones an exact copy of this object
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 EXPORT_C CSdpConnectionField* CSdpConnectionField::CloneL() const
       
   324 	{
       
   325 	__TEST_INVARIANT;
       
   326 
       
   327 	CSdpConnectionField* obj = NULL;
       
   328     const TInetAddr* addr = InetAddress();
       
   329 
       
   330     if ( addr )
       
   331         {
       
   332         // Could be anything
       
   333         obj = CSdpConnectionField::NewL( *addr, iTTL, iNumOfAddress );
       
   334         }
       
   335     else
       
   336         {
       
   337         // Unicast FQDN address
       
   338         obj = CSdpConnectionField::NewL( iNetType, iAddressType, *iAddress );
       
   339         }
       
   340 
       
   341 	__ASSERT_DEBUG( *this == *obj, User::Panic(
       
   342                                    KSdpCodecPanicCat, KSdpCodecPanicInternal));
       
   343 	return obj;
       
   344 	}
       
   345 
       
   346 // -----------------------------------------------------------------------------
       
   347 // CSdpConnectionField::operator==
       
   348 // Checks if two origin fields are equal
       
   349 // -----------------------------------------------------------------------------
       
   350 //
       
   351 EXPORT_C TBool CSdpConnectionField::operator== (
       
   352     const CSdpConnectionField& aObj ) const
       
   353 	{
       
   354 	__TEST_INVARIANT;
       
   355 
       
   356     TBool equal( EFalse );
       
   357 
       
   358     if ( (*iAddress).CompareF( aObj.Address() ) == 0 &&
       
   359          NetType() == aObj.NetType() &&
       
   360          AddressType() == aObj.AddressType() &&
       
   361          TTLValue() == aObj.TTLValue() &&
       
   362          NumOfAddress() == aObj.NumOfAddress() )
       
   363         {
       
   364         // All attributes match, two fields are equal
       
   365         equal = ETrue;
       
   366         }
       
   367 
       
   368 	return equal;
       
   369 	}
       
   370 
       
   371 // -----------------------------------------------------------------------------
       
   372 // CSdpConnectionField::NetType
       
   373 // Returns network type
       
   374 // -----------------------------------------------------------------------------
       
   375 //
       
   376 EXPORT_C RStringF CSdpConnectionField::NetType() const
       
   377 	{
       
   378 	__TEST_INVARIANT;
       
   379 	return iNetType;
       
   380 	}
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // CSdpConnectionField::AddressType
       
   384 // Returns address type
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 EXPORT_C RStringF CSdpConnectionField::AddressType() const
       
   388 	{
       
   389 	__TEST_INVARIANT;
       
   390 	return iAddressType;
       
   391 	}
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 // CSdpConnectionField::InetAddress
       
   395 // Returns address in TInetAddr format if possible
       
   396 // -----------------------------------------------------------------------------
       
   397 //
       
   398 EXPORT_C const TInetAddr* CSdpConnectionField::InetAddress() const
       
   399 	{
       
   400 	__TEST_INVARIANT;
       
   401 
       
   402     TInetAddr* addr = NULL;
       
   403     TBuf<KMaxAddressLength> addr16;
       
   404 
       
   405     addr16.Copy( iAddress->Des() );
       
   406     TInt err = iInetAddress.Input( addr16 );
       
   407 
       
   408     if ( err == KErrNone )
       
   409         {
       
   410         addr = &iInetAddress;
       
   411         }
       
   412 
       
   413 	return addr;
       
   414 	}
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // CSdpConnectionField::Address
       
   418 // Returns address in TDesC8 format
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 EXPORT_C const TDesC8& CSdpConnectionField::Address() const
       
   422     {
       
   423     return *iAddress;
       
   424     }
       
   425 
       
   426 // -----------------------------------------------------------------------------
       
   427 // CSdpConnectionField::SetInetAddressL
       
   428 // Sets address from TInetAddr
       
   429 // -----------------------------------------------------------------------------
       
   430 //
       
   431 EXPORT_C void CSdpConnectionField::SetInetAddressL(
       
   432     const TInetAddr& aAddress,
       
   433     TInt aTTL,
       
   434     TUint aNumOfAddress )
       
   435 	{
       
   436 	__TEST_INVARIANT;
       
   437 
       
   438     if ( IsValidAddress( aAddress, aTTL, aNumOfAddress ) == KErrNone )
       
   439         {
       
   440         TBuf<KMaxAddressLength> addr16;
       
   441        	//If aAddress IPv4-Mapped IPv6, result of Output IPv4
       
   442          aAddress.Output( addr16 );
       
   443 
       
   444         HBufC8* tempBuf = HBufC8::NewL( addr16.Length() );
       
   445         tempBuf->Des().Copy( addr16 );
       
   446 
       
   447         SdpUtil::SetDefaultNetTypeAndAddrType(
       
   448             iPool, aAddress, iNetType, iAddressType );
       
   449         if(aAddress.Address() && aAddress.IsV4Mapped())
       
   450 			{
       
   451 			iAddressType.Close();
       
   452 			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
       
   453                                       SdpCodecStringConstants::Table ).Copy();
       
   454 			}
       
   455         // Set address
       
   456         delete iAddress;
       
   457         iAddress = tempBuf;
       
   458         // Set attributes for address
       
   459         iTTL = aTTL;
       
   460         iNumOfAddress = aNumOfAddress;
       
   461         }
       
   462     else
       
   463         {
       
   464         User::Leave( KErrSdpCodecConnectionField );
       
   465         }
       
   466 
       
   467 	__TEST_INVARIANT;
       
   468 	}
       
   469 
       
   470 // -----------------------------------------------------------------------------
       
   471 // CSdpConnectionField::SetAddressL
       
   472 // Sets new address and types, leaves on error
       
   473 // -----------------------------------------------------------------------------
       
   474 //
       
   475 EXPORT_C void CSdpConnectionField::SetAddressL(
       
   476     RStringF aNetType,
       
   477     RStringF aAddressType,
       
   478     const TDesC8& aAddress )
       
   479     {
       
   480     __TEST_INVARIANT;
       
   481     TInt err( KErrNone );
       
   482     RStringF netTypeBackup = iNetType.Copy();
       
   483     RStringF addressTypeBackup = iAddressType.Copy();
       
   484     CleanupClosePushL( netTypeBackup );
       
   485     CleanupClosePushL( addressTypeBackup );
       
   486 
       
   487     TRAP( err, CopyNetTypeL( aNetType.DesC() ) );
       
   488     if ( !err )
       
   489         {
       
   490         // Netowrk type changed successfully
       
   491         TRAP( err, CopyAddressTypeL( aAddressType.DesC() ) );
       
   492         if ( !err )
       
   493             {
       
   494             // Address type & network type changed successfully
       
   495             TRAP( err, CopyAddressL( aAddress, iAddressType.Pool() ) );
       
   496 
       
   497             if ( err )
       
   498                 {
       
   499                 // Place back old netType & address
       
   500                 iNetType.Close();
       
   501                 iNetType = netTypeBackup.Copy();
       
   502 
       
   503                 iAddressType.Close();
       
   504                 iAddressType = addressTypeBackup.Copy();
       
   505 
       
   506                 User::LeaveIfError( err );
       
   507                 }
       
   508             // Everything changed succesfully
       
   509             }
       
   510         else
       
   511             {
       
   512             // Place back old netType
       
   513             iNetType.Close();
       
   514             iNetType = netTypeBackup.Copy();
       
   515 
       
   516             User::LeaveIfError( err );
       
   517             }
       
   518         }
       
   519     else
       
   520         {
       
   521         User::LeaveIfError( err );
       
   522         }
       
   523 
       
   524     CleanupStack::PopAndDestroy( 2 );   // netTypeBackup, addressTypeBackup
       
   525     }
       
   526 
       
   527 // -----------------------------------------------------------------------------
       
   528 // CSdpConnectionField::TTLValue
       
   529 // Returns TTL attribute
       
   530 // -----------------------------------------------------------------------------
       
   531 //
       
   532 EXPORT_C TInt CSdpConnectionField::TTLValue() const
       
   533     {
       
   534     __TEST_INVARIANT;
       
   535     return iTTL;
       
   536     }
       
   537 
       
   538 // -----------------------------------------------------------------------------
       
   539 // CSdpConnectionField::SetTTLL
       
   540 // Sets new TTL attribute value, leaves on error
       
   541 // -----------------------------------------------------------------------------
       
   542 //
       
   543 EXPORT_C void CSdpConnectionField::SetTTLL(
       
   544     TInt aTTL )
       
   545     {
       
   546     __TEST_INVARIANT;
       
   547 
       
   548     const TInetAddr* addr = InetAddress();
       
   549 
       
   550     // FQDN; Unicast, can be only KErrNotFound
       
   551     // IP4 Multicast: 0 <= TTL <= 255
       
   552     // IP4 Unicast, can be only KErrNotFound
       
   553     // IP6 can be only KErrNotFound
       
   554 
       
   555     if ( ( !addr && aTTL != KErrNotFound ) ||
       
   556          ( addr && addr->Address() && addr->IsMulticast() && 
       
   557            ( aTTL < 0 || aTTL > 255 ) ) ||
       
   558          ( addr && addr->Address() && !addr->IsMulticast() && 
       
   559            aTTL != KErrNotFound ) ||
       
   560          ( addr && !addr->Address() && aTTL != KErrNotFound ) )
       
   561         {
       
   562         User::Leave( KErrSdpCodecConnectionField );
       
   563         }
       
   564 
       
   565     iTTL = aTTL;
       
   566     }
       
   567 
       
   568 // -----------------------------------------------------------------------------
       
   569 // CSdpConnectionField::NumOfAddress
       
   570 // Returns number of continuous addresses for multicast
       
   571 // -----------------------------------------------------------------------------
       
   572 //
       
   573 EXPORT_C TInt CSdpConnectionField::NumOfAddress() const
       
   574     {
       
   575     return iNumOfAddress;
       
   576     }
       
   577 
       
   578 // -----------------------------------------------------------------------------
       
   579 // CSdpConnectionField::SetNumOfAddressL
       
   580 // Sets number of addresses
       
   581 // -----------------------------------------------------------------------------
       
   582 //
       
   583 EXPORT_C void CSdpConnectionField::SetNumOfAddressL(
       
   584     TUint aNumOfAddress )
       
   585     {
       
   586     const TInetAddr* addr = InetAddress();
       
   587     if ( aNumOfAddress < 1 || ( !addr && aNumOfAddress != 1 )  ||
       
   588          ( addr && !addr->IsMulticast() && aNumOfAddress != 1  ) )
       
   589         {
       
   590         User::Leave( KErrSdpCodecConnectionField );
       
   591         }
       
   592 
       
   593     iNumOfAddress = aNumOfAddress;
       
   594     }
       
   595 
       
   596 // -----------------------------------------------------------------------------
       
   597 // CSdpConnectionField::ExternalizeL
       
   598 // Externalizes the object to stream
       
   599 // -----------------------------------------------------------------------------
       
   600 //
       
   601 void CSdpConnectionField::ExternalizeL(
       
   602     RWriteStream& aStream ) const
       
   603     {
       
   604     __TEST_INVARIANT;
       
   605 
       
   606     // Address
       
   607     aStream.WriteUint32L( iAddress->Des().Length() );
       
   608     aStream.WriteL( iAddress->Des(), iAddress->Des().Length() );
       
   609     // TTL
       
   610     aStream.WriteInt32L( iTTL );
       
   611     // Number of addresses
       
   612     aStream.WriteInt32L( iNumOfAddress );
       
   613     // <network type>
       
   614     aStream.WriteUint32L( iNetType.DesC().Length() );
       
   615     aStream.WriteL( iNetType.DesC() );
       
   616     // <address type>
       
   617     aStream.WriteUint32L( iAddressType.DesC().Length() );
       
   618     aStream.WriteL( iAddressType.DesC() );
       
   619     }
       
   620 
       
   621 // -----------------------------------------------------------------------------
       
   622 // CSdpConnectionField::InternalizeL
       
   623 // Internalizes the object from stream
       
   624 // -----------------------------------------------------------------------------
       
   625 //
       
   626 CSdpConnectionField* CSdpConnectionField::InternalizeL(
       
   627     RReadStream& aStream )
       
   628     {
       
   629     TUint32 length;
       
   630     CSdpConnectionField* obj = NULL;
       
   631     RStringPool pool = SdpCodecStringPool::StringPoolL();
       
   632 
       
   633     // address
       
   634     length = aStream.ReadUint32L();
       
   635 	HBufC8* address = HBufC8::NewLC( length );
       
   636     TPtr8 ptr( address->Des() );
       
   637     aStream.ReadL( ptr, length );
       
   638     // TTL
       
   639     TInt ttl = aStream.ReadInt32L();
       
   640     // Number of addresses
       
   641     TInt numOfAddr = aStream.ReadInt32L();
       
   642     // Network type
       
   643     length = aStream.ReadUint32L();
       
   644     HBufC8* netType = HBufC8::NewLC( length );
       
   645     ptr.Set( netType->Des() );
       
   646     aStream.ReadL( ptr, length );
       
   647     // Address type
       
   648     length = aStream.ReadUint32L();
       
   649     HBufC8* addrType = HBufC8::NewLC( length );
       
   650     ptr.Set( addrType->Des() );
       
   651     aStream.ReadL( ptr, length );
       
   652 
       
   653     TInetAddr addr;
       
   654     HBufC* address16 = HBufC::NewLC( address->Length() ) ;
       
   655     address16->Des().Copy( *address );
       
   656     TInt err = addr.Input( *address16 );
       
   657 
       
   658     if ( !err )
       
   659         {
       
   660         // Create connection field based on TInetAddr
       
   661         obj = CSdpConnectionField::NewL( addr, ttl, numOfAddr );
       
   662         }
       
   663     else
       
   664         {
       
   665         // Create connection field from buffer, ttl & numOfAddr
       
   666         // are in this case irrelevant
       
   667         RStringF netTypeStr = pool.OpenFStringL( *netType );
       
   668         CleanupClosePushL( netTypeStr );
       
   669         RStringF addrTypeStr = pool.OpenFStringL( *addrType );
       
   670         CleanupClosePushL( addrTypeStr );
       
   671         obj = CSdpConnectionField::NewL( netTypeStr, addrTypeStr, *address );
       
   672         CleanupStack::PopAndDestroy( 2 );   // netTypeStr, addrTypeStr
       
   673         }
       
   674 
       
   675     CleanupStack::PopAndDestroy( 4 );  // address, netType, addrType, address16
       
   676     return obj;
       
   677     }
       
   678 
       
   679 // -----------------------------------------------------------------------------
       
   680 // CSdpConnectionField::IsValidAddress
       
   681 // Checks if the given address is valid
       
   682 // -----------------------------------------------------------------------------
       
   683 //
       
   684 TInt CSdpConnectionField::IsValidAddress(
       
   685     TBool aAddressTypeIP4,
       
   686     const TDesC8& aAddress ) const
       
   687     {
       
   688     HBufC8* address = NULL;
       
   689     TInt ttl( 0 );
       
   690     TUint num( 0 );
       
   691 
       
   692     TRAPD( err, address =
       
   693                 ParseAddressFieldL( aAddressTypeIP4, aAddress, ttl, num ) );
       
   694     delete address;
       
   695 
       
   696     return err;
       
   697     }
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // CSdpConnectionField::IsValidAddress
       
   701 // Checks if the given address is valid
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 TInt CSdpConnectionField::IsValidAddress(
       
   705     const TInetAddr& aAddress,
       
   706     TInt aTTL,
       
   707     TUint aNumOfAddress ) const
       
   708     {
       
   709     TInt err( KErrSdpCodecConnectionField );
       
   710     // 0 <= TTL <= 255 or KErrNotFound if not defined
       
   711     // Number of addresses > 0
       
   712     if ( ( aTTL == KErrNotFound || ( aTTL >= 0 && aTTL <= 255 ) ) &&
       
   713            aNumOfAddress > 0 )
       
   714         {
       
   715         TBuf16 <KMaxAddressLength> output;
       
   716         aAddress.Output(output);
       
   717 
       
   718         // Address has to be either of type IP4 or IP6
       
   719         // If IP4 and multicast then it must contain TTL attribute
       
   720         // If IP4 and unicast then it must NOT contain TTL and must have 1 address
       
   721         // If IP6 and multicast then it must NOT contain TTL
       
   722         // If IP6 and unicast then it must NOT contain TTL and must have 1 address
       
   723         if ( ( aAddress.Address() && 
       
   724                ( ( aAddress.IsMulticast() && aTTL != KErrNotFound ) ||
       
   725                  ( aAddress.IsUnicast() && aTTL == KErrNotFound &&
       
   726                    aNumOfAddress == 1 ) ) ) ||
       
   727              ( !aAddress.Address() &&
       
   728                ( ( aAddress.IsMulticast() && aTTL == KErrNotFound ) ||
       
   729                  ( aAddress.IsUnicast() && aTTL == KErrNotFound &&
       
   730                    aNumOfAddress == 1 ) )   ||
       
   731                ( aAddress.IsWildAddr() && 
       
   732                ( output.Match(KWildAddr) == 0||
       
   733                	 output.Match(KWildAddrIPv6) == 0 )) ) )
       
   734            {
       
   735            err = KErrNone;
       
   736            }
       
   737         }
       
   738 
       
   739     return err;
       
   740     }
       
   741 
       
   742 // -----------------------------------------------------------------------------
       
   743 // CSdpConnectionField::ParseAddressFieldL
       
   744 // Format the address field
       
   745 // -----------------------------------------------------------------------------
       
   746 //
       
   747 HBufC8* CSdpConnectionField::ParseAddressFieldL(
       
   748     TBool aAddressTypeIP4,
       
   749     const TDesC8& aAddress,
       
   750     TInt& aTTL,
       
   751     TUint& aNumberOfAddresses ) const
       
   752     {
       
   753     HBufC8* address = NULL;
       
   754 
       
   755     if ( aAddress.Length() > 0 && aAddress.Length() <= KMaxAddressLength )
       
   756         {
       
   757         // IP4 address
       
   758         TInetAddr addr;
       
   759         TBuf<KMaxAddressLength> buf16;
       
   760 
       
   761         // IP address lasts till first separator mark
       
   762         TInt pos = aAddress.Locate( KSlashChar );
       
   763         if ( pos == KErrNotFound )
       
   764             {
       
   765             pos = aAddress.Length();
       
   766             }
       
   767         buf16.Copy( aAddress.Left( pos ) );
       
   768 
       
   769         // Try to convert the string to TInetAddr
       
   770         TInt err = addr.Input( buf16 );
       
   771 
       
   772    		//Type and address check
       
   773         TBuf16 <KMaxAddressLength> output;
       
   774         addr.Output(output);
       
   775         if (err == KErrNone)
       
   776 	        {
       
   777             if (addr.Address() )
       
   778                 {
       
   779                 if ( (addr.IsV4Mapped() && aAddressTypeIP4) ||
       
   780                      (!addr.IsV4Mapped() && !aAddressTypeIP4) )
       
   781                     {
       
   782                     User::Leave( KErrSdpCodecConnectionField );
       
   783                     }
       
   784                 else
       
   785                     {
       
   786                     // IP4 address
       
   787                     address = ParseIP4AddressL( pos, addr, aAddress, aTTL,
       
   788                                             aNumberOfAddresses );
       
   789                     }
       
   790                 }
       
   791             else
       
   792                 {
       
   793                 if ( !aAddressTypeIP4)
       
   794                     {
       
   795                     // IP6 address
       
   796                     address = ParseIP6AddressL( pos, addr, aAddress, aTTL,
       
   797                                         aNumberOfAddresses );
       
   798                     }
       
   799                 else if ( addr.IsWildAddr() && output.Match(KWildAddr) == 0 )
       
   800                     {
       
   801                     // 0.0.0.0
       
   802                     address = ParseIP4AddressL( pos, addr, aAddress, aTTL,
       
   803                                             aNumberOfAddresses );
       
   804                     }
       
   805                 else
       
   806                     {
       
   807                     User::Leave( KErrSdpCodecConnectionField );
       
   808                     }
       
   809 		        }
       
   810 	        }
       
   811         else
       
   812 	        {   
       
   813             // FQDN
       
   814 	        // Clarify that the address contains only valid FQDN chars
       
   815             // This is always unicast
       
   816             for ( TInt i( 0 ); i < aAddress.Length(); i++ )
       
   817 		        {
       
   818                 if ( KValidFQDNChars().Locate( aAddress[i] ) ==
       
   819 			        KErrNotFound )
       
   820                     {
       
   821                     User::Leave( KErrSdpCodecConnectionField );
       
   822                     }
       
   823                 }
       
   824             address = aAddress.AllocL();
       
   825             aTTL = KErrNotFound;
       
   826             aNumberOfAddresses = 1;
       
   827 	        }
       
   828 
       
   829         }
       
   830     else
       
   831         {
       
   832         User::Leave( KErrSdpCodecConnectionField );
       
   833         }
       
   834 
       
   835     return address;
       
   836     }
       
   837 
       
   838 // -----------------------------------------------------------------------------
       
   839 // CSdpConnectionField::ParseIP4AddressL
       
   840 // Parses IP4 address and checks that it is valid
       
   841 // -----------------------------------------------------------------------------
       
   842 //
       
   843 HBufC8* CSdpConnectionField::ParseIP4AddressL(
       
   844     TInt aPos,
       
   845     TInetAddr& aAddr,
       
   846     const TDesC8& aAddress,
       
   847     TInt& aTTL,
       
   848     TUint& aNumberOfAddresses ) const
       
   849     {
       
   850     HBufC8* address = NULL;
       
   851 
       
   852     if ( aAddr.IsMulticast() )
       
   853         {
       
   854         // Multicast address - MUST contain TTL and possibly
       
   855         // number of addresses
       
   856         if ( aPos != aAddress.Length() )
       
   857             {
       
   858             TInt pos2 = aAddress.Right( aAddress.Length() - aPos - 1 ).Locate(
       
   859                 KSlashChar );
       
   860 
       
   861             if ( pos2 != KErrNotFound )
       
   862                 {
       
   863                 pos2 += aPos + 1;
       
   864 
       
   865                 // Validity check for number strings
       
   866                 TBool digit = SdpUtil::IsDigit(
       
   867                     aAddress.Mid( aPos + 1, pos2 - aPos - 1 ) );
       
   868                 digit = digit && SdpUtil::IsDigit(
       
   869                     aAddress.Mid( pos2 + 1, aAddress.Length() - pos2 - 1 ) );
       
   870                 if ( !digit )
       
   871                     {
       
   872                     User::Leave( KErrSdpCodecConnectionField );
       
   873                     }
       
   874 
       
   875                 // TTL & number of addresses
       
   876                 User::LeaveIfError(
       
   877                     TLex8( aAddress.Mid( aPos + 1, pos2 - aPos - 1 ) ).Val(
       
   878                         aTTL ) );
       
   879                 User::LeaveIfError(
       
   880                     TLex8( aAddress.Mid(
       
   881                         pos2 + 1, aAddress.Length() - pos2 - 1 ) ).Val(
       
   882                             aNumberOfAddresses, EDecimal ) );
       
   883 
       
   884                 __ASSERT_ALWAYS( aTTL >= 0
       
   885                                 && aTTL <= 255
       
   886                                 && aNumberOfAddresses > 0,
       
   887                                 User::Leave( KErrSdpCodecConnectionField ) );
       
   888                 }
       
   889             else
       
   890                 {
       
   891                 // Validity check for number strings
       
   892                 TBool digit = SdpUtil::IsDigit(
       
   893                    aAddress.Mid( aPos + 1, aAddress.Length() - aPos - 1 ) );
       
   894                 if ( !digit )
       
   895                     {
       
   896                     User::Leave( KErrSdpCodecConnectionField );
       
   897                     }
       
   898 
       
   899                 // Plain TTL
       
   900                 User::LeaveIfError(
       
   901                     TLex8( aAddress.Mid(
       
   902                         aPos + 1, aAddress.Length() - aPos - 1 ) ).Val(
       
   903                             aTTL ) );
       
   904                 aNumberOfAddresses = 1;
       
   905 
       
   906                 __ASSERT_ALWAYS( aTTL >= 0 && aTTL <= 255,
       
   907                                  User::Leave( KErrSdpCodecConnectionField ) );
       
   908                 }
       
   909 
       
   910             address = aAddress.Left( aPos ).AllocL();
       
   911             }
       
   912         else
       
   913             {
       
   914             User::Leave( KErrSdpCodecConnectionField );
       
   915             }
       
   916         }
       
   917     else
       
   918         {
       
   919         // Unicast address - cannot contain any multicast TTLs etc.
       
   920         if ( aPos == aAddress.Length() )
       
   921             {
       
   922             address = aAddress.AllocL();
       
   923             aTTL = KErrNotFound;
       
   924             aNumberOfAddresses = 1;
       
   925             }
       
   926         else
       
   927             {
       
   928             User::Leave( KErrSdpCodecConnectionField );
       
   929             }
       
   930         }
       
   931 
       
   932     return address;
       
   933     }
       
   934 
       
   935 // -----------------------------------------------------------------------------
       
   936 // CSdpConnectionField::ParseIP6AddressL
       
   937 // Parses IP6 address and checks that it is valid
       
   938 // -----------------------------------------------------------------------------
       
   939 //
       
   940 HBufC8* CSdpConnectionField::ParseIP6AddressL(
       
   941     TInt aPos,
       
   942     TInetAddr& aAddr,
       
   943     const TDesC8& aAddress,
       
   944     TInt& aTTL,
       
   945     TUint& aNumberOfAddresses ) const
       
   946     {
       
   947     HBufC8* address = NULL;
       
   948 
       
   949     if ( aAddr.IsMulticast() )
       
   950         {
       
   951         // Multicast address - CAN contain one extra attribute,
       
   952         // number of addresses
       
   953         if ( aPos != aAddress.Length() )
       
   954             {
       
   955             // Validity check for number strings
       
   956 
       
   957             TBool digit = SdpUtil::IsDigit(
       
   958                 aAddress.Mid( aPos + 1, aAddress.Length() - aPos - 1 ) );
       
   959             if ( !digit )
       
   960                 {
       
   961                 User::Leave( KErrSdpCodecConnectionField );
       
   962                 }
       
   963 
       
   964             User::LeaveIfError( TLex8( aAddress.Mid(
       
   965                 aPos + 1, aAddress.Length() - aPos - 1 ) ).Val(
       
   966                     aNumberOfAddresses, EDecimal ) );
       
   967 
       
   968             __ASSERT_ALWAYS( aNumberOfAddresses > 0,
       
   969                              User::Leave( KErrSdpCodecConnectionField ) );
       
   970             }
       
   971         else
       
   972             {
       
   973             aNumberOfAddresses = 1;
       
   974             }
       
   975 
       
   976         aTTL = KErrNotFound;    // IP6 does not use TTL
       
   977         address = aAddress.Left( aPos ).AllocL();
       
   978         }
       
   979     else
       
   980         {
       
   981         // Unicast address - cannot contain any multicast TTLs etc.
       
   982         if ( aPos == aAddress.Length() )
       
   983             {
       
   984             address = aAddress.AllocL();
       
   985             aTTL = KErrNotFound;
       
   986             aNumberOfAddresses = 1;
       
   987             }
       
   988         else
       
   989             {
       
   990             User::Leave( KErrSdpCodecConnectionField );
       
   991             }
       
   992         }
       
   993 
       
   994     return address;
       
   995     }
       
   996 
       
   997 // -----------------------------------------------------------------------------
       
   998 // CSdpConnectionField::CopyNetTypeL
       
   999 // Copies network type to object after checking that it is valid
       
  1000 // -----------------------------------------------------------------------------
       
  1001 //
       
  1002 void CSdpConnectionField::CopyNetTypeL(
       
  1003     const TDesC8& aNetType )
       
  1004     {
       
  1005     if ( !SdpUtil::IsToken( aNetType ) )
       
  1006         {
       
  1007         User::Leave( KErrSdpCodecConnectionField );
       
  1008         }
       
  1009     else
       
  1010         {
       
  1011         RStringF netType = iPool.OpenFStringL( aNetType );
       
  1012         iNetType.Close();
       
  1013         iNetType = netType;
       
  1014         }
       
  1015     }
       
  1016 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CSdpConnectionField::CopyAddressTypeL
       
  1019 // Copies address type after checking that it is valid
       
  1020 // -----------------------------------------------------------------------------
       
  1021 //
       
  1022 void CSdpConnectionField::CopyAddressTypeL(
       
  1023     const TDesC8& aAddrType )
       
  1024     {
       
  1025     if ( !SdpUtil::IsToken( aAddrType ) )
       
  1026         {
       
  1027         User::Leave( KErrSdpCodecConnectionField );
       
  1028         }
       
  1029     else
       
  1030         {
       
  1031         RStringF addrType = iPool.OpenFStringL( aAddrType );
       
  1032         iAddressType.Close();
       
  1033         iAddressType = addrType;
       
  1034         }
       
  1035     }
       
  1036 
       
  1037 // -----------------------------------------------------------------------------
       
  1038 // CSdpConnectionField::CopyAddressL
       
  1039 // Copies address after checking that it is valid
       
  1040 // -----------------------------------------------------------------------------
       
  1041 //
       
  1042 void CSdpConnectionField::CopyAddressL(
       
  1043     const TDesC8& aAddress,
       
  1044     RStringPool aPool )
       
  1045     {
       
  1046     RStringF addrTypeIP4 = aPool.StringF(
       
  1047         SdpCodecStringConstants::EAddressTypeIP4,
       
  1048         SdpCodecStringConstants::Table );
       
  1049     RStringF addrTypeIP6 = aPool.StringF(
       
  1050         SdpCodecStringConstants::EAddressType,
       
  1051         SdpCodecStringConstants::Table );
       
  1052     HBufC8* addr = NULL;
       
  1053 
       
  1054     if ( iAddressType == addrTypeIP4 || iAddressType == addrTypeIP6 )
       
  1055         {
       
  1056         User::LeaveIfError(
       
  1057             IsValidAddress( iAddressType == addrTypeIP4, aAddress ) );
       
  1058 
       
  1059         addr = ParseAddressFieldL( iAddressType == addrTypeIP4, aAddress,
       
  1060                                iTTL, iNumOfAddress );
       
  1061   		//If address is IPv4-Mapped IPv6 , it is changed to IPv4
       
  1062 		TInetAddr inetaddr;
       
  1063 		TBuf<KMaxAddressLength> address;
       
  1064 		address.Copy(*addr);
       
  1065 		TInt err = inetaddr.Input(address);
       
  1066         TBuf16 <KMaxAddressLength> output;
       
  1067         inetaddr.Output(output);
       
  1068 		if(!err && 
       
  1069             ( ( inetaddr.Address() && inetaddr.IsV4Mapped() ) || 
       
  1070               ( inetaddr.IsWildAddr() && output.Match(KWildAddr) != KErrNotFound ) 
       
  1071             ) )
       
  1072 			{//IPv4-Mapped IPv6 is changed to IPv4 address
       
  1073 			TBuf<KMaxIPDesLength> buf;
       
  1074 			inetaddr.Output( buf );
       
  1075 			// Copy new address to safe
       
  1076 			delete addr;
       
  1077 			addr = NULL;
       
  1078 			addr = HBufC8::NewL(buf.Length());
       
  1079 			addr->Des().Copy(buf);
       
  1080 			iAddressType.Close();
       
  1081 			iAddressType = 
       
  1082 				iPool.StringF(SdpCodecStringConstants::EAddressTypeIP4,
       
  1083                                SdpCodecStringConstants::Table ).Copy();
       
  1084 			}
       
  1085 	
       
  1086         }
       
  1087     else
       
  1088         {
       
  1089         // Address not IP4 or IP6, must be then non-ws-string
       
  1090         if ( SdpUtil::IsNonWhitespace( aAddress ) )
       
  1091             {
       
  1092             addr = aAddress.AllocL();
       
  1093             }
       
  1094         else
       
  1095             {
       
  1096             User::Leave( KErrSdpCodecConnectionField );
       
  1097             }
       
  1098         }
       
  1099 
       
  1100     delete iAddress;
       
  1101     iAddress = addr;
       
  1102     }
       
  1103 
       
  1104 // For DEBUG builds
       
  1105 
       
  1106 // -----------------------------------------------------------------------------
       
  1107 // CSdpConnectionField::__DbgTestInvariant
       
  1108 // Test invariant
       
  1109 // -----------------------------------------------------------------------------
       
  1110 //
       
  1111 
       
  1112 void CSdpConnectionField::__DbgTestInvariant() const
       
  1113 	{
       
  1114     TBool validAddr = EFalse;
       
  1115 
       
  1116     RStringF addrTypeIP4 = iPool.StringF(
       
  1117         SdpCodecStringConstants::EAddressTypeIP4,
       
  1118         SdpCodecStringConstants::Table );
       
  1119     RStringF addrTypeIP6 = iPool.StringF(
       
  1120         SdpCodecStringConstants::EAddressType,
       
  1121         SdpCodecStringConstants::Table );
       
  1122 
       
  1123     if ( iAddress &&
       
  1124         ( iAddressType == addrTypeIP4 || iAddressType == addrTypeIP6 ) )
       
  1125         {
       
  1126         TInetAddr addr;
       
  1127         TBuf<KMaxAddressLength> buf16;
       
  1128         buf16.Copy( *iAddress );
       
  1129         TInt err = addr.Input( buf16 );
       
  1130         if ( !err )
       
  1131             {
       
  1132             validAddr = IsValidAddress(addr, iTTL, iNumOfAddress) == KErrNone;
       
  1133             }
       
  1134         else
       
  1135             {
       
  1136             // FQDN unicast
       
  1137             if ( iTTL == KErrNotFound && iNumOfAddress == 1 )
       
  1138                 {
       
  1139                 validAddr = ETrue;
       
  1140                 }
       
  1141             }
       
  1142         }
       
  1143 
       
  1144     TBool invariant = ( SdpUtil::IsToken( iNetType.DesC() ) &&
       
  1145                         SdpUtil::IsToken( iAddressType.DesC() ) &&
       
  1146                         iAddress && SdpUtil::IsNonWhitespace( *iAddress ) &&
       
  1147                         validAddr );
       
  1148 
       
  1149 	if ( !invariant )
       
  1150         {
       
  1151 		User::Invariant();
       
  1152         }
       
  1153 	}
       
  1154 
       
  1155