contentmgmt/referencedrmagent/RefTestAgent/localsdp/src/sdpconnectionfield.cpp
changeset 72 de46a57f75fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contentmgmt/referencedrmagent/RefTestAgent/localsdp/src/sdpconnectionfield.cpp	Thu Jun 24 15:39:07 2010 +0530
@@ -0,0 +1,1155 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : SdpConnectionField.cpp
+// Part of       : Local SDP Codec
+// Version       : 1.0
+//
+
+
+
+
+#include <in_sock.h>
+#include <s32strm.h>
+#include <stringpool.h>
+#include "sdpconnectionfield.h"
+#include "sdpcodecstringconstants.h"
+#include "sdpcodecconstants.h"
+#include "sdpcodecstringpool.h"
+#include "sdputil.h"
+#include "sdpcodecerr.h"
+#include "sdpcodec.pan"
+#include "_sdpdefs.h"
+#include "uriutils.h"
+
+// LOCAL CONSTANTS
+const TInt KHeaderIndex = 0;
+const TInt KNetworkTypeIndex = 1;
+const TInt KAddressTypeIndex = 2;
+const TInt KAddressIndex = 3;
+const TInt KTokenCount = 4;
+const TInt KMaxAddressLength = 256;
+const TUint KMaxIPDesLength = 39;
+_LIT16(KWildAddr, "0.0.0.0");
+_LIT16(KWildAddrIPv6, "::");
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::CSdpConnectionField
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CSdpConnectionField::CSdpConnectionField() :
+    iTTL( KErrNotFound ),
+    iNumOfAddress( KDefaultNumOfAddress )
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::ConstructL(
+    const TDesC8& aText )
+	{
+    // aText should be in format
+    // c=<network type> <address type> <connection address>
+    iPool = SdpCodecStringPool::StringPoolL();
+
+    RArray<TPtrC8> array =
+        SdpUtil::GetElementsFromLineL( aText, KErrSdpCodecConnectionField );
+    CleanupClosePushL( array );
+
+    if ( array.Count() != KTokenCount )
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+    RStringF origHeader =  iPool.StringF( SdpCodecStringConstants::EConnection,
+                                          SdpCodecStringConstants::Table );
+    if ( origHeader.DesC().CompareF( array[KHeaderIndex] ) != 0 )
+        {
+        // Header didn't match
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+    // <network type>
+    CopyNetTypeL( array[KNetworkTypeIndex] );
+
+    // <address type>
+    CopyAddressTypeL( array[KAddressTypeIndex] );
+
+    // <address>
+    CopyAddressL( array[KAddressIndex], iPool );
+
+    CleanupStack::PopAndDestroy();  // array
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::ConstructL(
+    const TInetAddr& aAddress,
+    TInt aTTL,
+    TUint aNumOfAddress )
+	{
+    __ASSERT_ALWAYS( IsValidAddress(aAddress, aTTL, aNumOfAddress) == KErrNone,
+                     User::Leave( KErrSdpCodecConnectionField ) );
+
+    iPool = SdpCodecStringPool::StringPoolL();
+    TBuf<KMaxIPDesLength> addr;
+    //If aAddress is IPv4-Mapped IPv6,the result of Output is IPv4
+    aAddress.Output( addr );
+
+    // Copy address
+    iAddress = HBufC8::NewL( addr.Length() );
+    iAddress->Des().Copy( addr );
+
+    // TTL
+    iTTL = aTTL;
+    // Num of addresses
+    iNumOfAddress = aNumOfAddress;
+    // Network type
+    iNetType = iPool.StringF( SdpCodecStringConstants::ENetType,
+                              SdpCodecStringConstants::Table ).Copy();
+    // Address type
+	if ( UriUtils::HostType( addr ) == UriUtils::EIPv4Host )
+		{
+		//addresstype for IPv4
+			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
+                                      SdpCodecStringConstants::Table ).Copy();
+			}
+	else if ( UriUtils::HostType( addr ) == UriUtils::EIPv6Host )
+			{
+			//addresstype IPv6
+			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressType,
+                                      SdpCodecStringConstants::Table ).Copy();
+			}
+	else
+		{
+		User::Leave(KErrArgument);
+		}
+
+	__TEST_INVARIANT;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::ConstructL(
+    RStringF aNetType,
+	RStringF aAddressType,
+	const TDesC8& aAddress )
+    {
+    iPool = SdpCodecStringPool::StringPoolL();
+
+    // Network type
+    CopyNetTypeL( aNetType.DesC() );
+
+    // Address type
+    CopyAddressTypeL( aAddressType.DesC() );
+
+    // Address + TTL + numOfAddress
+    CopyAddressL( aAddress, aNetType.Pool() );
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::DecodeL
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::DecodeL(
+    const TDesC8& aText )
+	{
+	CSdpConnectionField* obj = CSdpConnectionField::DecodeLC( aText );
+	CleanupStack::Pop();
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::DecodeLC
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::DecodeLC(
+    const TDesC8& aText )
+	{
+	CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
+	CleanupStack::PushL( obj );
+	obj->ConstructL( aText );
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NewL
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::NewL(
+    const TInetAddr& aAddress,
+    TInt aTTL,
+    TUint aNumOfAddress )
+	{
+	CSdpConnectionField* obj = CSdpConnectionField::NewLC(
+        aAddress, aTTL, aNumOfAddress );
+	CleanupStack::Pop();
+	return obj;
+	}
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NewLC
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::NewLC(
+    const TInetAddr& aAddress,
+    TInt aTTL,
+    TUint aNumOfAddress )
+	{
+	CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
+	CleanupStack::PushL( obj );
+	obj->ConstructL( aAddress, aTTL, aNumOfAddress );
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NewL
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::NewL(
+    RStringF aNetType,
+    RStringF aAddressType,
+    const TDesC8& aAddress )
+    {
+    CSdpConnectionField* obj = CSdpConnectionField::NewLC(
+        aNetType, aAddressType, aAddress );
+	CleanupStack::Pop();
+	return obj;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NewLC
+// Two-phased constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::NewLC(
+    RStringF aNetType,
+    RStringF aAddressType,
+    const TDesC8& aAddress )
+    {
+    CSdpConnectionField* obj = new ( ELeave ) CSdpConnectionField;
+	CleanupStack::PushL( obj );
+	obj->ConstructL( aNetType, aAddressType, aAddress );
+	return obj;
+    }
+
+// Destructor
+EXPORT_C CSdpConnectionField::~CSdpConnectionField()
+	{
+    delete iAddress;
+    iNetType.Close();
+    iAddressType.Close();
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::EncodeL
+// Writes attributes in proper format to the stream
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpConnectionField::EncodeL(
+    RWriteStream& aStream ) const
+	{
+	__TEST_INVARIANT;
+    TBuf8<20> number;  // Is enough for addr as well
+
+    // c=<network type> <address type> <connection address>
+    RStringF header = iPool.StringF( SdpCodecStringConstants::EConnection,
+                                     SdpCodecStringConstants::Table );
+    aStream.WriteL( header.DesC() );
+
+    // Network type
+    aStream.WriteL( iNetType.DesC() );
+    aStream.WriteL( KSPStr );
+
+    // Address type
+    aStream.WriteL( iAddressType.DesC() );
+    aStream.WriteL( KSPStr );
+
+    // Connection address
+    aStream.WriteL( *iAddress );
+    if ( iTTL != KErrNotFound )
+        {
+        number.Zero();
+        number.Append( KSlashStr );
+        number.AppendFormat( _L8("%d"), iTTL );
+        aStream.WriteL( number );
+        }
+
+    if ( iNumOfAddress > 1 )
+        {
+        number.Zero();
+        number.Append( KSlashStr );
+        number.AppendFormat( _L8("%u"), iNumOfAddress );
+        aStream.WriteL( number );
+        }
+
+     // End-of-Line mark
+	aStream.WriteL( KCRLFStr );
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::CloneL
+// Clones an exact copy of this object
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSdpConnectionField* CSdpConnectionField::CloneL() const
+	{
+	__TEST_INVARIANT;
+
+	CSdpConnectionField* obj = NULL;
+    const TInetAddr* addr = InetAddress();
+
+    if ( addr )
+        {
+        // Could be anything
+        obj = CSdpConnectionField::NewL( *addr, iTTL, iNumOfAddress );
+        }
+    else
+        {
+        // Unicast FQDN address
+        obj = CSdpConnectionField::NewL( iNetType, iAddressType, *iAddress );
+        }
+
+	__ASSERT_DEBUG( *this == *obj, User::Panic(
+                                   KSdpCodecPanicCat, KSdpCodecPanicInternal));
+	return obj;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::operator==
+// Checks if two origin fields are equal
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CSdpConnectionField::operator== (
+    const CSdpConnectionField& aObj ) const
+	{
+	__TEST_INVARIANT;
+
+    TBool equal( EFalse );
+
+    if ( (*iAddress).CompareF( aObj.Address() ) == 0 &&
+         NetType() == aObj.NetType() &&
+         AddressType() == aObj.AddressType() &&
+         TTLValue() == aObj.TTLValue() &&
+         NumOfAddress() == aObj.NumOfAddress() )
+        {
+        // All attributes match, two fields are equal
+        equal = ETrue;
+        }
+
+	return equal;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NetType
+// Returns network type
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RStringF CSdpConnectionField::NetType() const
+	{
+	__TEST_INVARIANT;
+	return iNetType;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::AddressType
+// Returns address type
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RStringF CSdpConnectionField::AddressType() const
+	{
+	__TEST_INVARIANT;
+	return iAddressType;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::InetAddress
+// Returns address in TInetAddr format if possible
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TInetAddr* CSdpConnectionField::InetAddress() const
+	{
+	__TEST_INVARIANT;
+
+    TInetAddr* addr = NULL;
+    TBuf<KMaxAddressLength> addr16;
+
+    addr16.Copy( iAddress->Des() );
+    TInt err = iInetAddress.Input( addr16 );
+
+    if ( err == KErrNone )
+        {
+        addr = &iInetAddress;
+        }
+
+	return addr;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::Address
+// Returns address in TDesC8 format
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CSdpConnectionField::Address() const
+    {
+    return *iAddress;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::SetInetAddressL
+// Sets address from TInetAddr
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpConnectionField::SetInetAddressL(
+    const TInetAddr& aAddress,
+    TInt aTTL,
+    TUint aNumOfAddress )
+	{
+	__TEST_INVARIANT;
+
+    if ( IsValidAddress( aAddress, aTTL, aNumOfAddress ) == KErrNone )
+        {
+        TBuf<KMaxAddressLength> addr16;
+       	//If aAddress IPv4-Mapped IPv6, result of Output IPv4
+         aAddress.Output( addr16 );
+
+        HBufC8* tempBuf = HBufC8::NewL( addr16.Length() );
+        tempBuf->Des().Copy( addr16 );
+
+        SdpUtil::SetDefaultNetTypeAndAddrType(
+            iPool, aAddress, iNetType, iAddressType );
+        if(aAddress.Address() && aAddress.IsV4Mapped())
+			{
+			iAddressType.Close();
+			iAddressType = iPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
+                                      SdpCodecStringConstants::Table ).Copy();
+			}
+        // Set address
+        delete iAddress;
+        iAddress = tempBuf;
+        // Set attributes for address
+        iTTL = aTTL;
+        iNumOfAddress = aNumOfAddress;
+        }
+    else
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+	__TEST_INVARIANT;
+	}
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::SetAddressL
+// Sets new address and types, leaves on error
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpConnectionField::SetAddressL(
+    RStringF aNetType,
+    RStringF aAddressType,
+    const TDesC8& aAddress )
+    {
+    __TEST_INVARIANT;
+    TInt err( KErrNone );
+    RStringF netTypeBackup = iNetType.Copy();
+    RStringF addressTypeBackup = iAddressType.Copy();
+    CleanupClosePushL( netTypeBackup );
+    CleanupClosePushL( addressTypeBackup );
+
+    TRAP( err, CopyNetTypeL( aNetType.DesC() ) );
+    if ( !err )
+        {
+        // Netowrk type changed successfully
+        TRAP( err, CopyAddressTypeL( aAddressType.DesC() ) );
+        if ( !err )
+            {
+            // Address type & network type changed successfully
+            TRAP( err, CopyAddressL( aAddress, iAddressType.Pool() ) );
+
+            if ( err )
+                {
+                // Place back old netType & address
+                iNetType.Close();
+                iNetType = netTypeBackup.Copy();
+
+                iAddressType.Close();
+                iAddressType = addressTypeBackup.Copy();
+
+                User::LeaveIfError( err );
+                }
+            // Everything changed succesfully
+            }
+        else
+            {
+            // Place back old netType
+            iNetType.Close();
+            iNetType = netTypeBackup.Copy();
+
+            User::LeaveIfError( err );
+            }
+        }
+    else
+        {
+        User::LeaveIfError( err );
+        }
+
+    CleanupStack::PopAndDestroy( 2 );   // netTypeBackup, addressTypeBackup
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::TTLValue
+// Returns TTL attribute
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CSdpConnectionField::TTLValue() const
+    {
+    __TEST_INVARIANT;
+    return iTTL;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::SetTTLL
+// Sets new TTL attribute value, leaves on error
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpConnectionField::SetTTLL(
+    TInt aTTL )
+    {
+    __TEST_INVARIANT;
+
+    const TInetAddr* addr = InetAddress();
+
+    // FQDN; Unicast, can be only KErrNotFound
+    // IP4 Multicast: 0 <= TTL <= 255
+    // IP4 Unicast, can be only KErrNotFound
+    // IP6 can be only KErrNotFound
+
+    if ( ( !addr && aTTL != KErrNotFound ) ||
+         ( addr && addr->Address() && addr->IsMulticast() && 
+           ( aTTL < 0 || aTTL > 255 ) ) ||
+         ( addr && addr->Address() && !addr->IsMulticast() && 
+           aTTL != KErrNotFound ) ||
+         ( addr && !addr->Address() && aTTL != KErrNotFound ) )
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+    iTTL = aTTL;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::NumOfAddress
+// Returns number of continuous addresses for multicast
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CSdpConnectionField::NumOfAddress() const
+    {
+    return iNumOfAddress;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::SetNumOfAddressL
+// Sets number of addresses
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSdpConnectionField::SetNumOfAddressL(
+    TUint aNumOfAddress )
+    {
+    const TInetAddr* addr = InetAddress();
+    if ( aNumOfAddress < 1 || ( !addr && aNumOfAddress != 1 )  ||
+         ( addr && !addr->IsMulticast() && aNumOfAddress != 1  ) )
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+    iNumOfAddress = aNumOfAddress;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ExternalizeL
+// Externalizes the object to stream
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::ExternalizeL(
+    RWriteStream& aStream ) const
+    {
+    __TEST_INVARIANT;
+
+    // Address
+    aStream.WriteUint32L( iAddress->Des().Length() );
+    aStream.WriteL( iAddress->Des(), iAddress->Des().Length() );
+    // TTL
+    aStream.WriteInt32L( iTTL );
+    // Number of addresses
+    aStream.WriteInt32L( iNumOfAddress );
+    // <network type>
+    aStream.WriteUint32L( iNetType.DesC().Length() );
+    aStream.WriteL( iNetType.DesC() );
+    // <address type>
+    aStream.WriteUint32L( iAddressType.DesC().Length() );
+    aStream.WriteL( iAddressType.DesC() );
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::InternalizeL
+// Internalizes the object from stream
+// -----------------------------------------------------------------------------
+//
+CSdpConnectionField* CSdpConnectionField::InternalizeL(
+    RReadStream& aStream )
+    {
+    TUint32 length;
+    CSdpConnectionField* obj = NULL;
+    RStringPool pool = SdpCodecStringPool::StringPoolL();
+
+    // address
+    length = aStream.ReadUint32L();
+	HBufC8* address = HBufC8::NewLC( length );
+    TPtr8 ptr( address->Des() );
+    aStream.ReadL( ptr, length );
+    // TTL
+    TInt ttl = aStream.ReadInt32L();
+    // Number of addresses
+    TInt numOfAddr = aStream.ReadInt32L();
+    // Network type
+    length = aStream.ReadUint32L();
+    HBufC8* netType = HBufC8::NewLC( length );
+    ptr.Set( netType->Des() );
+    aStream.ReadL( ptr, length );
+    // Address type
+    length = aStream.ReadUint32L();
+    HBufC8* addrType = HBufC8::NewLC( length );
+    ptr.Set( addrType->Des() );
+    aStream.ReadL( ptr, length );
+
+    TInetAddr addr;
+    HBufC* address16 = HBufC::NewLC( address->Length() ) ;
+    address16->Des().Copy( *address );
+    TInt err = addr.Input( *address16 );
+
+    if ( !err )
+        {
+        // Create connection field based on TInetAddr
+        obj = CSdpConnectionField::NewL( addr, ttl, numOfAddr );
+        }
+    else
+        {
+        // Create connection field from buffer, ttl & numOfAddr
+        // are in this case irrelevant
+        RStringF netTypeStr = pool.OpenFStringL( *netType );
+        CleanupClosePushL( netTypeStr );
+        RStringF addrTypeStr = pool.OpenFStringL( *addrType );
+        CleanupClosePushL( addrTypeStr );
+        obj = CSdpConnectionField::NewL( netTypeStr, addrTypeStr, *address );
+        CleanupStack::PopAndDestroy( 2 );   // netTypeStr, addrTypeStr
+        }
+
+    CleanupStack::PopAndDestroy( 4 );  // address, netType, addrType, address16
+    return obj;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::IsValidAddress
+// Checks if the given address is valid
+// -----------------------------------------------------------------------------
+//
+TInt CSdpConnectionField::IsValidAddress(
+    TBool aAddressTypeIP4,
+    const TDesC8& aAddress ) const
+    {
+    HBufC8* address = NULL;
+    TInt ttl( 0 );
+    TUint num( 0 );
+
+    TRAPD( err, address =
+                ParseAddressFieldL( aAddressTypeIP4, aAddress, ttl, num ) );
+    delete address;
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::IsValidAddress
+// Checks if the given address is valid
+// -----------------------------------------------------------------------------
+//
+TInt CSdpConnectionField::IsValidAddress(
+    const TInetAddr& aAddress,
+    TInt aTTL,
+    TUint aNumOfAddress ) const
+    {
+    TInt err( KErrSdpCodecConnectionField );
+    // 0 <= TTL <= 255 or KErrNotFound if not defined
+    // Number of addresses > 0
+    if ( ( aTTL == KErrNotFound || ( aTTL >= 0 && aTTL <= 255 ) ) &&
+           aNumOfAddress > 0 )
+        {
+        TBuf16 <KMaxAddressLength> output;
+        aAddress.Output(output);
+
+        // Address has to be either of type IP4 or IP6
+        // If IP4 and multicast then it must contain TTL attribute
+        // If IP4 and unicast then it must NOT contain TTL and must have 1 address
+        // If IP6 and multicast then it must NOT contain TTL
+        // If IP6 and unicast then it must NOT contain TTL and must have 1 address
+        if ( ( aAddress.Address() && 
+               ( ( aAddress.IsMulticast() && aTTL != KErrNotFound ) ||
+                 ( aAddress.IsUnicast() && aTTL == KErrNotFound &&
+                   aNumOfAddress == 1 ) ) ) ||
+             ( !aAddress.Address() &&
+               ( ( aAddress.IsMulticast() && aTTL == KErrNotFound ) ||
+                 ( aAddress.IsUnicast() && aTTL == KErrNotFound &&
+                   aNumOfAddress == 1 ) )   ||
+               ( aAddress.IsWildAddr() && 
+               ( output.Match(KWildAddr) == 0||
+               	 output.Match(KWildAddrIPv6) == 0 )) ) )
+           {
+           err = KErrNone;
+           }
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ParseAddressFieldL
+// Format the address field
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSdpConnectionField::ParseAddressFieldL(
+    TBool aAddressTypeIP4,
+    const TDesC8& aAddress,
+    TInt& aTTL,
+    TUint& aNumberOfAddresses ) const
+    {
+    HBufC8* address = NULL;
+
+    if ( aAddress.Length() > 0 && aAddress.Length() <= KMaxAddressLength )
+        {
+        // IP4 address
+        TInetAddr addr;
+        TBuf<KMaxAddressLength> buf16;
+
+        // IP address lasts till first separator mark
+        TInt pos = aAddress.Locate( KSlashChar );
+        if ( pos == KErrNotFound )
+            {
+            pos = aAddress.Length();
+            }
+        buf16.Copy( aAddress.Left( pos ) );
+
+        // Try to convert the string to TInetAddr
+        TInt err = addr.Input( buf16 );
+
+   		//Type and address check
+        TBuf16 <KMaxAddressLength> output;
+        addr.Output(output);
+        if (err == KErrNone)
+	        {
+            if (addr.Address() )
+                {
+                if ( (addr.IsV4Mapped() && aAddressTypeIP4) ||
+                     (!addr.IsV4Mapped() && !aAddressTypeIP4) )
+                    {
+                    User::Leave( KErrSdpCodecConnectionField );
+                    }
+                else
+                    {
+                    // IP4 address
+                    address = ParseIP4AddressL( pos, addr, aAddress, aTTL,
+                                            aNumberOfAddresses );
+                    }
+                }
+            else
+                {
+                if ( !aAddressTypeIP4)
+                    {
+                    // IP6 address
+                    address = ParseIP6AddressL( pos, addr, aAddress, aTTL,
+                                        aNumberOfAddresses );
+                    }
+                else if ( addr.IsWildAddr() && output.Match(KWildAddr) == 0 )
+                    {
+                    // 0.0.0.0
+                    address = ParseIP4AddressL( pos, addr, aAddress, aTTL,
+                                            aNumberOfAddresses );
+                    }
+                else
+                    {
+                    User::Leave( KErrSdpCodecConnectionField );
+                    }
+		        }
+	        }
+        else
+	        {   
+            // FQDN
+	        // Clarify that the address contains only valid FQDN chars
+            // This is always unicast
+            for ( TInt i( 0 ); i < aAddress.Length(); i++ )
+		        {
+                if ( KValidFQDNChars().Locate( aAddress[i] ) ==
+			        KErrNotFound )
+                    {
+                    User::Leave( KErrSdpCodecConnectionField );
+                    }
+                }
+            address = aAddress.AllocL();
+            aTTL = KErrNotFound;
+            aNumberOfAddresses = 1;
+	        }
+
+        }
+    else
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+
+    return address;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ParseIP4AddressL
+// Parses IP4 address and checks that it is valid
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSdpConnectionField::ParseIP4AddressL(
+    TInt aPos,
+    TInetAddr& aAddr,
+    const TDesC8& aAddress,
+    TInt& aTTL,
+    TUint& aNumberOfAddresses ) const
+    {
+    HBufC8* address = NULL;
+
+    if ( aAddr.IsMulticast() )
+        {
+        // Multicast address - MUST contain TTL and possibly
+        // number of addresses
+        if ( aPos != aAddress.Length() )
+            {
+            TInt pos2 = aAddress.Right( aAddress.Length() - aPos - 1 ).Locate(
+                KSlashChar );
+
+            if ( pos2 != KErrNotFound )
+                {
+                pos2 += aPos + 1;
+
+                // Validity check for number strings
+                TBool digit = SdpUtil::IsDigit(
+                    aAddress.Mid( aPos + 1, pos2 - aPos - 1 ) );
+                digit = digit && SdpUtil::IsDigit(
+                    aAddress.Mid( pos2 + 1, aAddress.Length() - pos2 - 1 ) );
+                if ( !digit )
+                    {
+                    User::Leave( KErrSdpCodecConnectionField );
+                    }
+
+                // TTL & number of addresses
+                User::LeaveIfError(
+                    TLex8( aAddress.Mid( aPos + 1, pos2 - aPos - 1 ) ).Val(
+                        aTTL ) );
+                User::LeaveIfError(
+                    TLex8( aAddress.Mid(
+                        pos2 + 1, aAddress.Length() - pos2 - 1 ) ).Val(
+                            aNumberOfAddresses, EDecimal ) );
+
+                __ASSERT_ALWAYS( aTTL >= 0
+                                && aTTL <= 255
+                                && aNumberOfAddresses > 0,
+                                User::Leave( KErrSdpCodecConnectionField ) );
+                }
+            else
+                {
+                // Validity check for number strings
+                TBool digit = SdpUtil::IsDigit(
+                   aAddress.Mid( aPos + 1, aAddress.Length() - aPos - 1 ) );
+                if ( !digit )
+                    {
+                    User::Leave( KErrSdpCodecConnectionField );
+                    }
+
+                // Plain TTL
+                User::LeaveIfError(
+                    TLex8( aAddress.Mid(
+                        aPos + 1, aAddress.Length() - aPos - 1 ) ).Val(
+                            aTTL ) );
+                aNumberOfAddresses = 1;
+
+                __ASSERT_ALWAYS( aTTL >= 0 && aTTL <= 255,
+                                 User::Leave( KErrSdpCodecConnectionField ) );
+                }
+
+            address = aAddress.Left( aPos ).AllocL();
+            }
+        else
+            {
+            User::Leave( KErrSdpCodecConnectionField );
+            }
+        }
+    else
+        {
+        // Unicast address - cannot contain any multicast TTLs etc.
+        if ( aPos == aAddress.Length() )
+            {
+            address = aAddress.AllocL();
+            aTTL = KErrNotFound;
+            aNumberOfAddresses = 1;
+            }
+        else
+            {
+            User::Leave( KErrSdpCodecConnectionField );
+            }
+        }
+
+    return address;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::ParseIP6AddressL
+// Parses IP6 address and checks that it is valid
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSdpConnectionField::ParseIP6AddressL(
+    TInt aPos,
+    TInetAddr& aAddr,
+    const TDesC8& aAddress,
+    TInt& aTTL,
+    TUint& aNumberOfAddresses ) const
+    {
+    HBufC8* address = NULL;
+
+    if ( aAddr.IsMulticast() )
+        {
+        // Multicast address - CAN contain one extra attribute,
+        // number of addresses
+        if ( aPos != aAddress.Length() )
+            {
+            // Validity check for number strings
+
+            TBool digit = SdpUtil::IsDigit(
+                aAddress.Mid( aPos + 1, aAddress.Length() - aPos - 1 ) );
+            if ( !digit )
+                {
+                User::Leave( KErrSdpCodecConnectionField );
+                }
+
+            User::LeaveIfError( TLex8( aAddress.Mid(
+                aPos + 1, aAddress.Length() - aPos - 1 ) ).Val(
+                    aNumberOfAddresses, EDecimal ) );
+
+            __ASSERT_ALWAYS( aNumberOfAddresses > 0,
+                             User::Leave( KErrSdpCodecConnectionField ) );
+            }
+        else
+            {
+            aNumberOfAddresses = 1;
+            }
+
+        aTTL = KErrNotFound;    // IP6 does not use TTL
+        address = aAddress.Left( aPos ).AllocL();
+        }
+    else
+        {
+        // Unicast address - cannot contain any multicast TTLs etc.
+        if ( aPos == aAddress.Length() )
+            {
+            address = aAddress.AllocL();
+            aTTL = KErrNotFound;
+            aNumberOfAddresses = 1;
+            }
+        else
+            {
+            User::Leave( KErrSdpCodecConnectionField );
+            }
+        }
+
+    return address;
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::CopyNetTypeL
+// Copies network type to object after checking that it is valid
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::CopyNetTypeL(
+    const TDesC8& aNetType )
+    {
+    if ( !SdpUtil::IsToken( aNetType ) )
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+    else
+        {
+        RStringF netType = iPool.OpenFStringL( aNetType );
+        iNetType.Close();
+        iNetType = netType;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::CopyAddressTypeL
+// Copies address type after checking that it is valid
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::CopyAddressTypeL(
+    const TDesC8& aAddrType )
+    {
+    if ( !SdpUtil::IsToken( aAddrType ) )
+        {
+        User::Leave( KErrSdpCodecConnectionField );
+        }
+    else
+        {
+        RStringF addrType = iPool.OpenFStringL( aAddrType );
+        iAddressType.Close();
+        iAddressType = addrType;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::CopyAddressL
+// Copies address after checking that it is valid
+// -----------------------------------------------------------------------------
+//
+void CSdpConnectionField::CopyAddressL(
+    const TDesC8& aAddress,
+    RStringPool aPool )
+    {
+    RStringF addrTypeIP4 = aPool.StringF(
+        SdpCodecStringConstants::EAddressTypeIP4,
+        SdpCodecStringConstants::Table );
+    RStringF addrTypeIP6 = aPool.StringF(
+        SdpCodecStringConstants::EAddressType,
+        SdpCodecStringConstants::Table );
+    HBufC8* addr = NULL;
+
+    if ( iAddressType == addrTypeIP4 || iAddressType == addrTypeIP6 )
+        {
+        User::LeaveIfError(
+            IsValidAddress( iAddressType == addrTypeIP4, aAddress ) );
+
+        addr = ParseAddressFieldL( iAddressType == addrTypeIP4, aAddress,
+                               iTTL, iNumOfAddress );
+  		//If address is IPv4-Mapped IPv6 , it is changed to IPv4
+		TInetAddr inetaddr;
+		TBuf<KMaxAddressLength> address;
+		address.Copy(*addr);
+		TInt err = inetaddr.Input(address);
+        TBuf16 <KMaxAddressLength> output;
+        inetaddr.Output(output);
+		if(!err && 
+            ( ( inetaddr.Address() && inetaddr.IsV4Mapped() ) || 
+              ( inetaddr.IsWildAddr() && output.Match(KWildAddr) != KErrNotFound ) 
+            ) )
+			{//IPv4-Mapped IPv6 is changed to IPv4 address
+			TBuf<KMaxIPDesLength> buf;
+			inetaddr.Output( buf );
+			// Copy new address to safe
+			delete addr;
+			addr = NULL;
+			addr = HBufC8::NewL(buf.Length());
+			addr->Des().Copy(buf);
+			iAddressType.Close();
+			iAddressType = 
+				iPool.StringF(SdpCodecStringConstants::EAddressTypeIP4,
+                               SdpCodecStringConstants::Table ).Copy();
+			}
+	
+        }
+    else
+        {
+        // Address not IP4 or IP6, must be then non-ws-string
+        if ( SdpUtil::IsNonWhitespace( aAddress ) )
+            {
+            addr = aAddress.AllocL();
+            }
+        else
+            {
+            User::Leave( KErrSdpCodecConnectionField );
+            }
+        }
+
+    delete iAddress;
+    iAddress = addr;
+    }
+
+// For DEBUG builds
+
+// -----------------------------------------------------------------------------
+// CSdpConnectionField::__DbgTestInvariant
+// Test invariant
+// -----------------------------------------------------------------------------
+//
+
+void CSdpConnectionField::__DbgTestInvariant() const
+	{
+    TBool validAddr = EFalse;
+
+    RStringF addrTypeIP4 = iPool.StringF(
+        SdpCodecStringConstants::EAddressTypeIP4,
+        SdpCodecStringConstants::Table );
+    RStringF addrTypeIP6 = iPool.StringF(
+        SdpCodecStringConstants::EAddressType,
+        SdpCodecStringConstants::Table );
+
+    if ( iAddress &&
+        ( iAddressType == addrTypeIP4 || iAddressType == addrTypeIP6 ) )
+        {
+        TInetAddr addr;
+        TBuf<KMaxAddressLength> buf16;
+        buf16.Copy( *iAddress );
+        TInt err = addr.Input( buf16 );
+        if ( !err )
+            {
+            validAddr = IsValidAddress(addr, iTTL, iNumOfAddress) == KErrNone;
+            }
+        else
+            {
+            // FQDN unicast
+            if ( iTTL == KErrNotFound && iNumOfAddress == 1 )
+                {
+                validAddr = ETrue;
+                }
+            }
+        }
+
+    TBool invariant = ( SdpUtil::IsToken( iNetType.DesC() ) &&
+                        SdpUtil::IsToken( iAddressType.DesC() ) &&
+                        iAddress && SdpUtil::IsNonWhitespace( *iAddress ) &&
+                        validAddr );
+
+	if ( !invariant )
+        {
+		User::Invariant();
+        }
+	}
+
+