307 lines
6.1 KiB
C++
307 lines
6.1 KiB
C++
|
/*
|
||
|
* File: t120chan.cpp
|
||
|
*
|
||
|
* T.120 implementation of ICommChannel, ICtrlCommChannel
|
||
|
*
|
||
|
* Revision History:
|
||
|
*
|
||
|
* 06/11/97 mikev created
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
ImpT120Chan::ImpT120Chan()
|
||
|
:m_MediaID(MEDIA_TYPE_H323_T120),
|
||
|
m_pCtlChan(NULL),
|
||
|
m_pCapObject(NULL),
|
||
|
m_pH323ConfAdvise(NULL),
|
||
|
m_dwFlags(COMCH_ENABLED),
|
||
|
dwhChannel(0),
|
||
|
uRef(1)
|
||
|
{
|
||
|
ZeroMemory(&local_sin, sizeof(local_sin));
|
||
|
ZeroMemory(&remote_sin, sizeof(remote_sin));
|
||
|
}
|
||
|
|
||
|
ImpT120Chan::~ImpT120Chan ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP ImpT120Chan::GetMediaType(LPGUID pGuid)
|
||
|
{
|
||
|
if(!pGuid)
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
*pGuid = m_MediaID;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP ImpT120Chan::QueryInterface( REFIID iid, void ** ppvObject)
|
||
|
{
|
||
|
// this breaks the rules for the official COM QueryInterface because
|
||
|
// the interfaces that are queried for are not necessarily real COM
|
||
|
// interfaces. The reflexive property of QueryInterface would be broken in
|
||
|
// that case.
|
||
|
|
||
|
HRESULT hr = E_NOINTERFACE;
|
||
|
if(!ppvObject)
|
||
|
return hr;
|
||
|
|
||
|
*ppvObject = 0;
|
||
|
if(iid == IID_IUnknown)
|
||
|
{
|
||
|
*ppvObject = this;
|
||
|
hr = hrSuccess;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if((iid == IID_ICommChannel))
|
||
|
{
|
||
|
*ppvObject = (ICommChannel *)this;
|
||
|
hr = hrSuccess;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if((iid == IID_ICtrlCommChannel))
|
||
|
{
|
||
|
*ppvObject = (ICtrlCommChan *)this;
|
||
|
hr = hrSuccess;
|
||
|
AddRef();
|
||
|
}
|
||
|
return (hr);
|
||
|
}
|
||
|
|
||
|
ULONG ImpT120Chan::AddRef()
|
||
|
{
|
||
|
uRef++;
|
||
|
return uRef;
|
||
|
}
|
||
|
|
||
|
ULONG ImpT120Chan::Release()
|
||
|
{
|
||
|
uRef--;
|
||
|
if(uRef == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return uRef;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::BeginControlSession(IControlChannel *pCtlChan, LPIH323PubCap pCapObject)
|
||
|
{
|
||
|
// this channel is now "in a call".
|
||
|
m_pCtlChan = pCtlChan;
|
||
|
m_pCapObject = pCapObject;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
HRESULT ImpT120Chan::EndControlSession()
|
||
|
{
|
||
|
// this channel is no longer "in a call".
|
||
|
m_pCtlChan = NULL;
|
||
|
m_pCapObject = NULL;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::OnChannelClose(DWORD dwStatus)
|
||
|
{
|
||
|
HRESULT hr = hrSuccess;
|
||
|
FX_ENTRY("ImpT120Chan::OnChannelClose");
|
||
|
BOOL fCloseAction = FALSE;
|
||
|
|
||
|
SHOW_OBJ_ETIME("ImpT120Chan::OnChannelClose");
|
||
|
|
||
|
m_dwFlags &= ~COMCH_OPEN_PENDING;
|
||
|
|
||
|
switch(dwStatus)
|
||
|
{
|
||
|
default:
|
||
|
ERRORMESSAGE(("%s: unexpected unidirectional notification\r\n", _fx_));
|
||
|
case CHANNEL_CLOSED:
|
||
|
DEBUGMSG(ZONE_COMMCHAN,("%s:closing\r\n",_fx_));
|
||
|
if(IsComchOpen())
|
||
|
{
|
||
|
fCloseAction = TRUE;
|
||
|
m_dwFlags &= ~COMCH_OPEN;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ERRORMESSAGE(("%s: notification when not open\r\n", _fx_));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
// clear general purpose channel handle
|
||
|
dwhChannel = 0;
|
||
|
if(m_pH323ConfAdvise && m_pCtlChan)
|
||
|
{
|
||
|
DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
|
||
|
m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
HRESULT ImpT120Chan::OnChannelOpening()
|
||
|
{
|
||
|
m_dwFlags |= COMCH_OPEN_PENDING;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::OnChannelOpen(DWORD dwStatus)
|
||
|
{
|
||
|
FX_ENTRY("ImpT120Chan::OnChannelOpen");
|
||
|
|
||
|
SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen");
|
||
|
// the open is no longer pending, regardless of success or failure
|
||
|
m_dwFlags &= ~COMCH_OPEN_PENDING;
|
||
|
|
||
|
if(IsComchOpen())
|
||
|
{
|
||
|
ERRORMESSAGE(("%s: %d notification when open\r\n", _fx_,
|
||
|
dwStatus));
|
||
|
}
|
||
|
switch(dwStatus)
|
||
|
{
|
||
|
case CHANNEL_OPEN:
|
||
|
m_dwFlags |= (COMCH_OPEN | COMCH_SUPPRESS_NOTIFICATION);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
dwStatus = CHANNEL_OPEN_ERROR;
|
||
|
// fall through to notification
|
||
|
case CHANNEL_REJECTED:
|
||
|
case CHANNEL_NO_CAPABILITY:
|
||
|
goto NOTIFICATION;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
NOTIFICATION:
|
||
|
if(m_pH323ConfAdvise && m_pCtlChan)
|
||
|
{
|
||
|
DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
|
||
|
m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
|
||
|
}
|
||
|
else
|
||
|
DEBUGMSG(ZONE_COMMCHAN,("%s: *** not issuing notification 0x%08lX m_pH323ConfAdvise: 0x%08lX, m_pCtlChan:0x%08lX \r\n"
|
||
|
,_fx_, dwStatus,m_pH323ConfAdvise,m_pCtlChan));
|
||
|
|
||
|
SHOW_OBJ_ETIME("ImpT120Chan::OnChannelOpen - done ");
|
||
|
return hrSuccess;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL ImpT120Chan::SelectPorts(LPIControlChannel pCtlChannel)
|
||
|
{
|
||
|
PSOCKADDR_IN psin;
|
||
|
HRESULT hr;
|
||
|
hr = pCtlChannel->GetLocalAddress(&psin);
|
||
|
{
|
||
|
if(!HR_SUCCEEDED(hr))
|
||
|
return FALSE;
|
||
|
}
|
||
|
local_sin = *psin;
|
||
|
// HACK uses well known port
|
||
|
local_sin.sin_port = htons(1503);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::AcceptRemoteAddress (PSOCKADDR_IN pSin)
|
||
|
{
|
||
|
if(!pSin)
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
remote_sin = *pSin;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP ImpT120Chan::GetRemoteAddress(PSOCKADDR_IN pAddrOutput)
|
||
|
{
|
||
|
if (!pAddrOutput)
|
||
|
{
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
}
|
||
|
*pAddrOutput = remote_sin;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::EnableOpen(BOOL bEnable)
|
||
|
{
|
||
|
if(bEnable)
|
||
|
{
|
||
|
m_dwFlags |= COMCH_ENABLED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~COMCH_ENABLED;
|
||
|
}
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::IsChannelOpen(BOOL *pbOpen)
|
||
|
{
|
||
|
if(!pbOpen)
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
*pbOpen = (IsComchOpen()) ? TRUE:FALSE;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::Open(MEDIA_FORMAT_ID idLocalFormat, IH323Endpoint *pConnection)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IConfAdvise * pConfAdvise = NULL;
|
||
|
if((m_dwFlags & COMCH_OPEN_PENDING) || IsComchOpen() || !pConnection)
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
|
||
|
if(!m_pCtlChan) // this channel is not part of a call
|
||
|
{
|
||
|
hr = pConnection->QueryInterface(IID_IConfAdvise, (void **)&pConfAdvise);
|
||
|
if(!HR_SUCCEEDED(hr))
|
||
|
goto EXIT;
|
||
|
hr = pConfAdvise->AddCommChannel(this);
|
||
|
if(!HR_SUCCEEDED(hr))
|
||
|
goto EXIT;
|
||
|
|
||
|
ASSERT(m_pCtlChan && m_pCapObject);
|
||
|
}
|
||
|
|
||
|
// Start the control channel stuff needed to open the channel.
|
||
|
// The media format ID arguments are irrelevant for T.120 channels
|
||
|
hr = m_pCtlChan->OpenChannel((ICtrlCommChan*)this, m_pCapObject,
|
||
|
idLocalFormat, INVALID_MEDIA_FORMAT);
|
||
|
|
||
|
EXIT:
|
||
|
if(pConfAdvise)
|
||
|
pConfAdvise->Release();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::Close()
|
||
|
{
|
||
|
HRESULT hr = CHAN_E_INVALID_PARAM;
|
||
|
if(!IsComchOpen() || !m_pCtlChan)
|
||
|
goto EXIT;
|
||
|
|
||
|
hr = m_pCtlChan->CloseChannel((ICtrlCommChan*)this);
|
||
|
|
||
|
EXIT:
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT ImpT120Chan::SetAdviseInterface(IH323ConfAdvise *pH323ConfAdvise)
|
||
|
{
|
||
|
if (!pH323ConfAdvise)
|
||
|
{
|
||
|
return CHAN_E_INVALID_PARAM;
|
||
|
}
|
||
|
m_pH323ConfAdvise = pH323ConfAdvise;
|
||
|
return hrSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|