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();
        }
    }
QHostAddress qt_QHostAddressFromTInetAddr(const TInetAddr& addr)
{
    if (addr.IsV4Mapped() || addr.Family() == KAfInet) {
        //convert v4 host address
        return QHostAddress(addr.Address());
    } else {
        //convert v6 host address
        return QHostAddress((quint8 *)(addr.Ip6Address().u.iAddr8));
    }
}
//TODO: share this, at least QHostInfo needs to do the same thing
static QHostAddress qt_QHostAddressFromTInetAddr(const TInetAddr& addr)
{
    //TODO: do we want to call v4 mapped addresses v4 or v6 outside of this file?
    if (addr.IsV4Mapped() || addr.Family() == KAfInet) {
        //convert v4 host address
        return QHostAddress(addr.Address());
    } else {
        //convert v6 host address
        return QHostAddress((quint8 *)(addr.Ip6Address().u.iAddr8));
    }
}
// -----------------------------------------------------------------------------
// CSdpOriginField::TypeMatchesWithFormat
// Checks if address type is aligned with the address format
// -----------------------------------------------------------------------------
//
TBool CSdpOriginField::TypeMatchesWithFormat( 
    const TDesC8& aAddress, 
    const TDesC8& aType,
    RStringPool aPool ) const
    {
    RStringF addrTypeIP4 = 
        aPool.StringF( SdpCodecStringConstants::EAddressTypeIP4,
                              SdpCodecStringConstants::Table );
    RStringF addrTypeIP6 = 
        aPool.StringF( SdpCodecStringConstants::EAddressType,
                              SdpCodecStringConstants::Table );
    
    TBool valid( ETrue );
    
    // Check that address type and address matches together
    TInetAddr addr;
    TBuf<KMaxAddressLength> address16;
    address16.Copy( aAddress );
    TInt err = addr.Input( address16 );    
    if ( err == KErrNone && !addr.IsUnspecified())
        {
        TBool ip4Type = ( addrTypeIP4.DesC().CompareF( aType ) == 0 );
        TBool ip6Type = ( addrTypeIP6.DesC().CompareF( aType ) == 0 );
             
        if ( ip4Type || ip6Type )
            {
            if ( ( addr.Address() && !addr.IsV4Mapped() && !ip4Type ) ||
				 (addr.Address() && addr.IsV4Mapped() && !ip6Type) ||
                 ( !addr.Address() && !ip6Type ) )
                {
                valid = EFalse;
                }
            }
        } 
    
    return valid;
    }
// -----------------------------------------------------------------------------
// CLocalAddrResolver::CheckAndSetAddr
// -----------------------------------------------------------------------------
//
void CLocalAddrResolver::CheckAndSetAddr( TInetAddr& aTarget,
                                          TInetAddr& aCandidate,
                                          TUint32 aCandidateIap,
				                          TUint32 aSpecifiedIap )
    {
    if ( !aCandidate.IsUnspecified() && !aCandidate.IsLoopback() )
        {
        if ( aCandidate.IsV4Mapped())
            {
            aCandidate.ConvertToV4();
            }
        if ( aCandidateIap == aSpecifiedIap )
            {
            SetAddr( aTarget, aCandidate );
            }
        }
    }				                          
// -----------------------------------------------------------------------------
// 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::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;
    }