Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

426 lines
11 KiB

/*******************************************************************************
Module: bgcall.cpp
Author: Qianbo Huai
Abstract:
implements bridge call object
*******************************************************************************/
#include "stdafx.h"
#include "work.h"
#include <bridge.h>
// to change
const BSTR CLSID_String_BridgeTerminal = L"{581d09e5-0b45-11d3-a565-00c04f8ef6e3}";
/*//////////////////////////////////////////////////////////////////////////////
constructor
////*/
CBridgeCall::CBridgeCall (CBridge *pBridge)
{
m_pBridge = pBridge;
m_pH323Call = NULL;
m_pSDPCall = NULL;
}
/*//////////////////////////////////////////////////////////////////////////////
////*/
CBridgeCall::~CBridgeCall ()
{
Clear ();
m_pBridge = NULL;
}
/*//////////////////////////////////////////////////////////////////////////////
select terminals and connect the call
////*/
HRESULT
CBridgeCall::BridgeCalls ()
{
HRESULT hr;
hr = SelectBridgeTerminals ();
if (FAILED(hr))
return hr;
hr = SetupParticipantInfo ();
if (FAILED(hr))
return hr;
hr = SetMulticastMode ();
if (FAILED(hr))
return hr;
// connect h323 call
hr = m_pH323Call->Answer ();
if (FAILED(hr))
return hr;
// connect sdp call
hr = m_pSDPCall->Connect (VARIANT_TRUE);
if (FAILED(hr))
{
m_pH323Call->Disconnect (DC_NORMAL);
return hr;
}
return S_OK;
}
/*//////////////////////////////////////////////////////////////////////////////
////*/
HRESULT
CBridgeCall::SelectBridgeTerminals ()
{
HRESULT hr;
ITAddress *pAddress = NULL;
ITMSPAddress *pMSPAddress = NULL;
ITTerminal *pH323ToSDPVideoBT = NULL;
ITTerminal *pH323ToSDPAudioBT = NULL;
ITTerminal *pSDPToH323VideoBT = NULL;
ITTerminal *pSDPToH323AudioBT = NULL;
ITStreamControl *pStreamControl = NULL;
IEnumStream *pEnumStreams = NULL;
ITStream *pStream = NULL;
// get SDP address
hr = m_pBridge->GetSDPAddress (&pAddress);
if (FAILED(hr))
return hr;
// get MSP address
hr = pAddress->QueryInterface (IID_ITMSPAddress, (void**)&pMSPAddress);
if (FAILED(hr))
return hr;
IConfBridge *pBridge = NULL;
// create CConfBridge
hr = CoCreateInstance (
__uuidof(ConfBridge),
NULL,
CLSCTX_INPROC_SERVER,
IID_IConfBridge,
(LPVOID *)&pBridge
);
if (FAILED(hr))
return hr;
// create terminal: video H323->SDP
hr = pBridge->CreateBridgeTerminal (
// (MSP_HANDLE)pMSPAddress,
// CLSID_String_BridgeTerminal,
TAPIMEDIATYPE_VIDEO,
// TD_RENDER, // not used
&pH323ToSDPVideoBT
);
if (FAILED(hr))
goto Error;
// create terminal: audio H323->SDP
hr = pBridge->CreateBridgeTerminal (
// (MSP_HANDLE)pMSPAddress,
// CLSID_String_BridgeTerminal,
TAPIMEDIATYPE_AUDIO,
// TD_RENDER, // not used
&pH323ToSDPAudioBT
);
if (FAILED(hr))
goto Error;
// create terminal: video SDP->H323
hr = pBridge->CreateBridgeTerminal (
// (MSP_HANDLE)pMSPAddress,
// CLSID_String_BridgeTerminal,
TAPIMEDIATYPE_VIDEO,
// TD_RENDER, // not used
&pSDPToH323VideoBT
);
if (FAILED(hr))
goto Error;
// create terminal: audio SDP->H323
hr = pBridge->CreateBridgeTerminal (
// (MSP_HANDLE)pMSPAddress,
// CLSID_String_BridgeTerminal,
TAPIMEDIATYPE_AUDIO,
// TD_RENDER, // not used
&pSDPToH323AudioBT
);
if (FAILED(hr))
goto Error;
pMSPAddress->Release ();
pMSPAddress = NULL;
pAddress->Release ();
pAddress = NULL;
pBridge->Release ();
pBridge = NULL;
// get stream control on H323
hr = m_pH323Call->QueryInterface (
IID_ITStreamControl,
(void **)&pStreamControl
);
if (FAILED(hr))
goto Error;
// get enum stream on H323
hr = pStreamControl->EnumerateStreams (&pEnumStreams);
if (FAILED(hr))
goto Error;
pStreamControl->Release ();
pStreamControl = NULL;
// iterate each stream on H323, select terminals
while (S_OK == pEnumStreams->Next (1, &pStream, NULL))
{
if (IsStream (pStream, TAPIMEDIATYPE_VIDEO, TD_CAPTURE))
{
// video: h323 to sdp
hr = pStream->SelectTerminal (pH323ToSDPVideoBT);
if (FAILED(hr))
goto Error;
}
else if (IsStream (pStream, TAPIMEDIATYPE_VIDEO, TD_RENDER))
{
// video: sdp to h323
hr = pStream->SelectTerminal (pSDPToH323VideoBT);
if (FAILED(hr))
goto Error;
IKeyFrameControl* pIKeyFrameControl;
hr = pStream->QueryInterface(&pIKeyFrameControl);
if (SUCCEEDED(hr))
{
hr = pIKeyFrameControl->PeriodicUpdatePicture(TRUE, 5);
pIKeyFrameControl->Release();
}
}
else if (IsStream (pStream, TAPIMEDIATYPE_AUDIO, TD_CAPTURE))
{
// audio: h323 to sdp
hr = pStream->SelectTerminal (pH323ToSDPAudioBT);
if (FAILED(hr))
goto Error;
}
else if (IsStream (pStream, TAPIMEDIATYPE_AUDIO, TD_RENDER))
{
// video: sdp to h323
hr = pStream->SelectTerminal (pSDPToH323AudioBT);
if (FAILED(hr))
goto Error;
}
pStream->Release ();
pStream = NULL;
}
if (pStream)
{
pStream->Release ();
pStream = NULL;
}
pEnumStreams->Release ();
pEnumStreams = NULL;
// get stream control on SDP
hr = m_pSDPCall->QueryInterface (
IID_ITStreamControl,
(void **)&pStreamControl
);
if (FAILED(hr))
goto Error;
// get enum stream on SDP
hr = pStreamControl->EnumerateStreams (&pEnumStreams);
if (FAILED(hr))
goto Error;
pStreamControl->Release ();
pStreamControl = NULL;
// iterate each stream on SDP, select terminals
while (S_OK == pEnumStreams->Next (1, &pStream, NULL))
{
if (IsStream (pStream, TAPIMEDIATYPE_VIDEO, TD_CAPTURE))
{
// video: sdp to h323
hr = pStream->SelectTerminal (pSDPToH323VideoBT);
if (FAILED(hr))
goto Error;
}
else if (IsStream (pStream, TAPIMEDIATYPE_VIDEO, TD_RENDER))
{
// video: h323 to sdp
hr = pStream->SelectTerminal (pH323ToSDPVideoBT);
if (FAILED(hr))
goto Error;
}
else if (IsStream (pStream, TAPIMEDIATYPE_AUDIO, TD_CAPTURE))
{
// audio: sdp to h323
hr = pStream->SelectTerminal (pSDPToH323AudioBT);
if (FAILED(hr))
goto Error;
}
else if (IsStream (pStream, TAPIMEDIATYPE_AUDIO, TD_RENDER))
{
// video: h323 to sdp
hr = pStream->SelectTerminal (pH323ToSDPAudioBT);
if (FAILED(hr))
goto Error;
}
pStream->Release ();
pStream = NULL;
}
Cleanup:
// release streams
if (pStream)
pStream->Release ();
if (pEnumStreams)
pEnumStreams->Release ();
if (pStreamControl)
pStreamControl->Release ();
// release terminals
if (pH323ToSDPVideoBT)
pH323ToSDPVideoBT->Release ();
if (pH323ToSDPAudioBT)
pH323ToSDPAudioBT->Release ();
if (pSDPToH323VideoBT)
pSDPToH323VideoBT->Release ();
if (pSDPToH323AudioBT)
pSDPToH323AudioBT->Release ();
if (pBridge)
pBridge->Release ();
return hr;
Error:
goto Cleanup;
}
HRESULT
CBridgeCall::SetupParticipantInfo ()
{
HRESULT hr = S_OK;
ITCallInfo *pCallInfo = NULL;
BSTR CallerIDName = NULL;
BSTR CallerIDNumber = NULL;
ITLocalParticipant *pLocalParticipant = NULL;
BSTR CName = NULL;
// get the caller info from the H323 side.
hr = m_pH323Call->QueryInterface(&pCallInfo);
if (FAILED(hr)) goto cleanup;
hr = pCallInfo->get_CallInfoString(CIS_CALLERIDNAME, &CallerIDName);
if (FAILED(hr)) goto cleanup;
hr = pCallInfo->get_CallInfoString(CIS_CALLERIDNUMBER, &CallerIDNumber);
if (FAILED(hr)) goto cleanup;
// construct the CName for the SDP side.
CName = SysAllocStringLen(NULL,
SysStringLen(CallerIDName) + SysStringLen(CallerIDNumber) + 2);
wsprintfW(CName, L"%ws@%ws", CallerIDName, CallerIDNumber);
// set the CName on the SDP side.
hr = m_pSDPCall->QueryInterface(&pLocalParticipant);
if (FAILED(hr)) goto cleanup;
hr = pLocalParticipant->put_LocalParticipantTypedInfo(
PTI_CANONICALNAME, CName
);
if (FAILED(hr)) goto cleanup;
hr = pLocalParticipant->put_LocalParticipantTypedInfo(
PTI_NAME, CallerIDName
);
if (FAILED(hr)) goto cleanup;
cleanup:
if (pCallInfo) pCallInfo->Release();
if (CallerIDName) SysFreeString(CallerIDName);
if (CallerIDNumber) SysFreeString(CallerIDNumber);
if (pLocalParticipant) pLocalParticipant->Release();
if (CName) SysFreeString(CName);
return hr;
}
HRESULT
CBridgeCall::SetMulticastMode ()
{
IMulticastControl * pIMulticastControl = NULL;
HRESULT hr = m_pSDPCall->QueryInterface(&pIMulticastControl);
if (FAILED(hr)) return hr;
hr = pIMulticastControl->put_LoopbackMode(MM_SELECTIVE_LOOPBACK);
pIMulticastControl->Release();
return hr;
}
/*//////////////////////////////////////////////////////////////////////////////
clear calls, return to initial state
////*/
void
CBridgeCall::Clear ()
{
if (m_pH323Call)
{
m_pH323Call->Disconnect (DC_NORMAL);
m_pH323Call->Release ();
m_pH323Call = NULL;
}
if (m_pSDPCall)
{
m_pSDPCall->Disconnect (DC_NORMAL);
m_pSDPCall->Release ();
m_pSDPCall = NULL;
}
}
/*//////////////////////////////////////////////////////////////////////////////
////*/
BOOL CBridgeCall::IsStream (
ITStream *pStream,
long lMediaType,
TERMINAL_DIRECTION tdDirection
)
{
long mediatype;
TERMINAL_DIRECTION direction;
if (FAILED (pStream->get_Direction(&direction)))
return false;
if (FAILED (pStream->get_MediaType(&mediatype)))
return false;
return ((direction == tdDirection) &&
(mediatype == lMediaType));
}