/****************************************************************************
 *
 *  Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved.
 *
 *  This program is free software.  It may be distributed under the terms
 *  in the file LICENSE, found in the top level of the source distribution.
 *
 */

#include "proxysession.h"
#include "dbg.h"

/**************************************
 *
 * CSessionHdr class
 *
 **************************************/
CSessionHdr::CSessionHdr( const CString& strSession )
{
    CPCHAR pSess = strSession;
    size_t nSessLen = strlen( pSess );
    CPCHAR pSemi = strchr( pSess, ';' );
    if( pSemi != NULL )
    {
        m_strTimeout = pSemi + 1;
        nSessLen = pSemi - pSess;
    }

    m_strSessionID.Set( strSession, nSessLen );
}

CSessionHdr::~CSessionHdr( void )
{
    //empty
}

CString &CSessionHdr::GetSessionID( void )
{
    return m_strSessionID;
}

void CSessionHdr::SetSessionID( CString& strSessionID )
{
    m_strSessionID = strSessionID;
}

CString & CSessionHdr::GetSessionHdrString( void )
{
    if( m_strTimeout.IsEmpty() )
    {
        return m_strSessionID;
    }
    
    m_strSessionHdr.Append( m_strSessionID );
    m_strSessionHdr.Append( ";" );
    m_strSessionHdr.Append( m_strTimeout );

    return m_strSessionHdr;
}


/**************************************
 *
 * CProxyDataTunnel class
 *
 **************************************/

CProxyDataTunnel::CProxyDataTunnel( void ) :
    m_bSetup( false ),
    m_refCount( 0 ),
    m_bInterleaved( false ),
    m_clientPort( 0 ),
    m_serverPort( 0 ),
    m_proxyToClientPort( 0 ),
    m_proxyToServerPort( 0 )
{
    //empty
}

CProxyDataTunnel::~CProxyDataTunnel( void )
{
    //empty;
}

void CProxyDataTunnel::AddRef( void )
{
    m_refCount++;
}

UINT CProxyDataTunnel::Release( void )
{
    return --m_refCount;
}

bool CProxyDataTunnel::IsSetup( void )
{
    return m_bSetup;
}

bool CProxyDataTunnel::Init( int nPorts )
{
    if( !m_clientSideTran.Init( nPorts ) )
        return false;
    if( !m_serverSideTran.Init( nPorts ) )
    {
        m_clientSideTran.Close( );
        return false;
    }

    m_proxyToClientPort = m_clientSideTran.GetBasePort();
    m_proxyToServerPort = m_serverSideTran.GetBasePort();

    return true;
}

bool CProxyDataTunnel::Init( CRtspProtocol* pClientProt, CRtspProtocol* pServerProt,
                            int nChannels, UINT16 clientChannel, UINT16 serverChannel )

{
    m_bInterleaved = true;
    m_clientPort = m_proxyToClientPort = clientChannel;
    m_serverPort = m_proxyToServerPort = serverChannel;

    if( !m_clientSideTran.Init( nChannels, clientChannel, pClientProt ) )
        return false;

    if( !m_serverSideTran.Init( nChannels, serverChannel, pServerProt ) )
        return false;

    return true;
}

UINT16 CProxyDataTunnel::GetClientPort( void ) 
{ 
    return m_clientPort; 
}

void CProxyDataTunnel::SetClientAddr( const CInetAddr& addrClient )
{
    m_addrClient = addrClient;
}

void CProxyDataTunnel::SetServerAddr( const CInetAddr& addrServer )
{
    m_addrServer = addrServer;
}

void CProxyDataTunnel::SetupTunnel( void )
{
    if( !m_bInterleaved )
    {
        m_clientSideTran.SetPeer( m_addrClient, m_clientPort );
        m_serverSideTran.SetPeer( m_addrServer, m_serverPort );
    }
    m_clientSideTran.SetSibling( &m_serverSideTran );
    m_serverSideTran.SetSibling( &m_clientSideTran );

    m_bSetup = true;
}

void CProxyDataTunnel::SetClientPort( UINT16 clientPort )
{ 
    m_clientPort = clientPort; 
}

UINT16 CProxyDataTunnel::GetServerPort( void ) 
{
    return m_serverPort; 
}

void CProxyDataTunnel::SetServerPort( UINT16 serverPort ) 
{ 
    m_serverPort = serverPort; 
}

UINT16 CProxyDataTunnel::GetProxyToClientPort( void ) 
{ 
    return m_proxyToClientPort; 
}
void CProxyDataTunnel::SetProxyToClientPort( UINT16 proxyToClientPort ) 
{ 
    m_proxyToClientPort = proxyToClientPort; 
}

UINT16 CProxyDataTunnel::GetProxyToServerPort( void ) 
{ 
    return m_proxyToServerPort; 
}
void CProxyDataTunnel::SetProxyToServerPort( UINT16 proxyToServerPort ) 
{ 
    m_proxyToServerPort = proxyToServerPort; 
}
    
/**************************************
 *
 * CRtspProxySession class
 *
 **************************************/

CRtspProxySession::CRtspProxySession( void )
{
    // Empty
}

CRtspProxySession::~CRtspProxySession( void )
{
    // Empty
}

const CString& CRtspProxySession::GetServerSessionID( void ) const
{
    return m_serverSessionID;
}

const CString& CRtspProxySession::GetClientSessionID( void ) const
{
    return m_clientSessionID;
}

const CString& CRtspProxySession::GetSetupCSeq( void ) const
{
    return m_setupCSeq;
}

const CString& CRtspProxySession::GetHost( void ) const
{
    return m_strHost;
}

void CRtspProxySession::SetSetupCSeq( CString strSetupCSeq )
{
    m_setupCSeq = strSetupCSeq;
}

void CRtspProxySession::SetSessionID( const CString& strSessionID, const CString& strHost, UINT16 sessionIndex )
{
    m_serverSessionID = strSessionID;
    m_strHost = strHost;
    m_clientSessionID = strSessionID;

    char szSessionIndex[20];
    sprintf( szSessionIndex, "%u", sessionIndex );
    m_clientSessionID.Append( szSessionIndex );
}

void CRtspProxySession::AddTunnel( CProxyDataTunnel* pTunnel )
{
    m_listTunnel.InsertTail( pTunnel );
}

void CRtspProxySession::ReleaseAllTunnels( void )
{
    CProxyDataTunnel* pTunnel;
    while( !m_listTunnel.IsEmpty() )
    {
        pTunnel = m_listTunnel.RemoveHead();
        if( pTunnel->Release() == 0 )
        {
            delete pTunnel;
        }
    }
}

CProxyDataTunnel * CRtspProxySession::FindTunnelByClientPort( UINT16 clientPort )
{
    CProxyDataTunnel* pTunnel;
    CProxyDataTunnelList::Iterator itr( m_listTunnel.Begin() );
    while( itr )
    {
        pTunnel = *itr;
        if( pTunnel->GetClientPort() == clientPort )
        {
            return pTunnel;
        }
        itr++;
    }
    return NULL;
}

CProxyDataTunnel* CRtspProxySession::FindTunnelByProxyPort( UINT16 proxyToServerPort )
{
    CProxyDataTunnel* pTunnel;
    CProxyDataTunnelList::Iterator itr( m_listTunnel.Begin() );
    while( itr )
    {
        pTunnel = *itr;
        if( pTunnel->GetProxyToServerPort( ) == proxyToServerPort )
        {
            return pTunnel;
        }
        itr++;
    }

    return NULL;
}


syntax highlighted by Code2HTML, v. 0.9.1