Example #1
0
// ---------------------------------------------------------------------------
// SdpUtil::SetDefaultNetTypeAndAddrType
// Sets network type and address type to their "default" values
// ---------------------------------------------------------------------------
//
void SdpUtil::SetDefaultNetTypeAndAddrType( 
    RStringPool aPool, 
    const TInetAddr& aAddress,
    RStringF& aNetType, 
    RStringF& aAddressType )
    {
     // Sets network type to IN
    aNetType.Close();
    aNetType = aPool.StringF( SdpCodecStringConstants::ENetType,
                              SdpCodecStringConstants::Table ).Copy();
    // Address type       
    aAddressType.Close();

    TBuf16 <KMaxAddressLength> output;
    aAddress.Output(output);


    //addresstype for IPv4    
	if((aAddress.Address() &&  !aAddress.IsV4Mapped()) ||
       (!aAddress.Address() && aAddress.IsWildAddr() && 
        output.Match(KWildAddr) == 0))
        {
        aAddressType = aPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
                                      SdpCodecStringConstants::Table ).Copy();
        }
    else
        {
		//addresstype for IPv4-Mapped IPv6 && IPv6
        aAddressType = aPool.StringF( SdpCodecStringConstants::EAddressType,
                                      SdpCodecStringConstants::Table ).Copy();
        }
    }
// -----------------------------------------------------------------------------
// 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::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;
    }