|
|
// File: imanager.cpp
#include "precomp.h"
extern "C" { #include "t120.h"
} #include <version.h>
#include "icall.h"
#include "icall_in.h"
#include "imanager.h"
#include <objbase.h>
#include <initguid.h>
static HRESULT OnNotifyConferenceCreated(IUnknown *pManagerNotify, PVOID pv, REFIID riid); static HRESULT OnNotifyCallCreated(IUnknown *pManagerNotify, PVOID pv, REFIID riid);
INodeController* g_pNodeController = NULL;
COprahNCUI *COprahNCUI::m_pOprahNCUI = NULL;
static const IID * g_apiidCP_Manager[] = { {&IID_INmManagerNotify} };
COprahNCUI::COprahNCUI(void) : m_cRef(1), CConnectionPointContainer(g_apiidCP_Manager, ARRAY_ELEMENTS(g_apiidCP_Manager)), m_pOutgoingCallManager(NULL), m_pIncomingCallManager(NULL), m_pConfObject(NULL), m_bstrUserName(NULL) { DebugEntry(COprahNCUI::COprahNCUI); m_pOprahNCUI = this;
DebugExitVOID(COprahNCUI::COprahNCUI); }
COprahNCUI::~COprahNCUI() { DebugEntry(COprahNCUI::COprahNCUI);
if (m_pIncomingCallManager) { delete m_pIncomingCallManager; m_pIncomingCallManager = NULL; }
if (m_pOutgoingCallManager) { delete m_pOutgoingCallManager; m_pOutgoingCallManager = NULL; }
if (m_pConfObject) { m_pConfObject->Release(); m_pConfObject = NULL; }
// cleanup the node controller:
if (g_pNodeController) { g_pNodeController->ReleaseInterface(); g_pNodeController = NULL; }
if (m_bstrUserName) { SysFreeString(m_bstrUserName); m_bstrUserName = NULL; }
m_pOprahNCUI = NULL;
DebugExitVOID(COprahNCUI::~COprahNCUI); }
UINT COprahNCUI::GetOutgoingCallCount() { if (m_pOutgoingCallManager) { return m_pOutgoingCallManager->GetCallCount(); } else { return 0; } }
VOID COprahNCUI::OnOutgoingCallCreated(INmCall* pCall) { // notify the UI about this outgoing call
NotifySink(pCall, OnNotifyCallCreated);
if (m_pConfObject && !m_pConfObject->IsConferenceCreated()) { m_pConfObject->OnConferenceCreated(); NotifySink((INmConference*) m_pConfObject, OnNotifyConferenceCreated); } }
VOID COprahNCUI::OnOutgoingCallCanceled(COutgoingCall* pCall) { if (m_pOutgoingCallManager) { m_pOutgoingCallManager->RemoveFromList(pCall); } }
VOID COprahNCUI::OnIncomingCallAccepted() { if (m_pConfObject && !m_pConfObject->IsConferenceCreated()) { m_pConfObject->OnConferenceCreated(); NotifySink((INmConference*) m_pConfObject, OnNotifyConferenceCreated); } }
VOID COprahNCUI::OnIncomingCallCreated(INmCall* pCall) { NotifySink(pCall, OnNotifyCallCreated); }
VOID COprahNCUI::CancelCalls() { if (m_pOutgoingCallManager) { m_pOutgoingCallManager->CancelCalls(); }
if (m_pIncomingCallManager) { m_pIncomingCallManager->CancelCalls(); } }
ULONG COprahNCUI::GetAuthenticatedName(PBYTE * ppb) { // Buffer created here should be freed by caller.
ULONG cb;
if (::T120_GetSecurityInfoFromGCCID(0,NULL,&cb)) { (*ppb) = new BYTE[cb]; if ((*ppb) != NULL) { ::T120_GetSecurityInfoFromGCCID(0,*ppb,&cb); return cb; } } (* ppb) = NULL; return 0;
}
HRESULT COprahNCUI::OnIncomingInviteRequest(CONF_HANDLE hConference, PCWSTR pcwszNodeName, BOOL fSecure) { DebugEntry(COprahNCUI::OnIncomingInviteRequest); if (!m_pConfObject) { ERROR_OUT(("No m_pConfObject")); return E_FAIL; }
if (!m_pConfObject->OnT120Invite(hConference, fSecure)) { // Respond negatively - already in a call
TRACE_OUT(("Rejecting invite - already in a call")); ASSERT(g_pNodeController); ASSERT(hConference); hConference->InviteResponse(FALSE); } else if (m_pIncomingCallManager) { m_pIncomingCallManager->OnIncomingT120Call( this, TRUE, hConference, pcwszNodeName, fSecure);
//
// This will simply notify the UI about the call state.
//
m_pConfObject->SetConfSecurity(fSecure); }
DebugExitHRESULT(COprahNCUI::OnIncomingInviteRequest, S_OK); return S_OK; }
HRESULT COprahNCUI::OnIncomingJoinRequest( CONF_HANDLE hConference, PCWSTR pcwszNodeName) { DebugEntry(COprahNCUI::OnIncomingJoinRequest);
if (m_pIncomingCallManager) { // shouldn't we be checking for an active conference before accepting a join
// or will T120 not present this
m_pIncomingCallManager->OnIncomingT120Call( this, FALSE, hConference, pcwszNodeName, m_pConfObject->IsConfObjSecure()); }
DebugExitHRESULT(COprahNCUI::OnIncomingJoinRequest, S_OK); return S_OK; }
HRESULT COprahNCUI::OnConferenceStarted(CONF_HANDLE hConference, HRESULT hResult) { DebugEntry(COprahNCUI::OnConferenceStarted);
if (!m_pConfObject) { ERROR_OUT(("OnConferenceStarted - no m_pConfObject")); return E_FAIL; }
if (m_pConfObject->GetConfHandle() == hConference) { m_pConfObject->OnConferenceStarted(hConference, hResult);
m_pOutgoingCallManager->OnConferenceStarted(hConference, hResult); }
DebugExitHRESULT(COprahNCUI::OnConferenceStarted, S_OK); return S_OK; }
HRESULT COprahNCUI::OnQueryRemoteResult(PVOID pvCallerContext, HRESULT hResult, BOOL fMCU, PWSTR* ppwszConferenceNames, PWSTR* ppwszConfDescriptors) { DebugEntry(COprahNCUI::OnQueryRemoteResult);
if (NO_ERROR == hResult) { TRACE_OUT(("COprahNCUI: OnQueryRemoteResult Success!")); } else { TRACE_OUT(("COprahNCUI: OnQueryRemoteResult Failure!")); }
if (m_pOutgoingCallManager) { m_pOutgoingCallManager->OnQueryRemoteResult(pvCallerContext, hResult, fMCU, ppwszConferenceNames, ppwszConfDescriptors); } DebugExitHRESULT(COprahNCUI::OnQueryRemoteResult, S_OK); return S_OK; }
HRESULT COprahNCUI::OnInviteResult( CONF_HANDLE hConference, REQUEST_HANDLE hRequest, UINT uNodeID, HRESULT hResult) { DebugEntry(COprahNCUI::OnInviteResult);
if (!m_pConfObject) { ERROR_OUT(("OnInviteResult - no m_pConfObject")); return E_FAIL; }
if (hConference == m_pConfObject->GetConfHandle()) { if (m_pOutgoingCallManager) { m_pOutgoingCallManager->OnInviteResult( hConference, hRequest, uNodeID, hResult); } }
DebugExitHRESULT(COprahNCUI::OnInviteResult, S_OK); return S_OK; }
HRESULT COprahNCUI::OnConferenceEnded(CONF_HANDLE hConference) { DebugEntry(COprahNCUI::OnConferenceEnded);
if (m_pConfObject && (hConference == m_pConfObject->GetConfHandle())) { m_pConfObject->OnConferenceEnded();
if (m_pOutgoingCallManager) { m_pOutgoingCallManager->OnConferenceEnded(hConference); }
if (m_pIncomingCallManager) { m_pIncomingCallManager->OnT120ConferenceEnded(hConference); } }
DebugExitHRESULT(COprahNCUI::OnConferenceEnded, S_OK); return S_OK; }
HRESULT COprahNCUI::OnRosterChanged(CONF_HANDLE hConf, PNC_ROSTER pRoster) { TRACE_OUT(("COprahNCUI::OnRosterChanged"));
if (!m_pConfObject) { ERROR_OUT(("OnRosterChanged - no m_pConfObject")); return E_FAIL; }
if (hConf == m_pConfObject->GetConfHandle()) { m_pConfObject->OnRosterChanged(pRoster); } return S_OK; }
ULONG STDMETHODCALLTYPE COprahNCUI::AddRef(void) { ++m_cRef; return m_cRef; } ULONG STDMETHODCALLTYPE COprahNCUI::Release(void) { if (m_cRef > 0) { --m_cRef; }
if (!m_cRef) { delete this; return 0; } else { return m_cRef; } }
HRESULT STDMETHODCALLTYPE COprahNCUI::QueryInterface(REFIID riid, PVOID *ppv) { HRESULT hr = S_OK;
if ((riid == IID_INmManager) || (riid == IID_IUnknown)) { *ppv = (INmManager *)this; TRACE_OUT(("COprahNCUI::QueryInterface()")); } else if (riid == IID_IConnectionPointContainer) { *ppv = (IConnectionPointContainer *) this; TRACE_OUT(("COprahNCUI::QueryInterface(): Returning IConnectionPointContainer.")); } else { hr = E_NOINTERFACE; *ppv = NULL; TRACE_OUT(("COprahNCUI::QueryInterface(): Called on unknown interface.")); }
if (S_OK == hr) { AddRef(); }
return hr; }
/* I N I T I A L I Z E */ /*-------------------------------------------------------------------------
%%Function: Initialize
REVIEW: What should the return value be if any of these parts fail to initialize or load? -------------------------------------------------------------------------*/ HRESULT COprahNCUI::Initialize ( BSTR szName, DWORD_PTR dwCredentials, DWORD port, DWORD flags ) { HRESULT hr = S_OK;
ASSERT(!m_bstrUserName); SysFreeString(m_bstrUserName); m_bstrUserName = SysAllocString(szName);
m_pOutgoingCallManager = new COutgoingCallManager; if (!m_pOutgoingCallManager) { ERROR_OUT(("COprahNCUI::Initialize -- failed to create outgoing call mgr")); return(E_OUTOFMEMORY); }
m_pIncomingCallManager = new CIncomingCallManager; if (!m_pIncomingCallManager) { ERROR_OUT(("COprahNCUI::Initialize -- failed to create incoming call mgr")); return(E_OUTOFMEMORY); }
// The lifetime of this object is up to the reference counting crap
m_pConfObject = new CConfObject; if (!m_pConfObject) { ERROR_OUT(("COprahNCUI::Initialize -- failed to create conf object")); return(E_OUTOFMEMORY); }
m_pConfObject->Init();
//
// Create the node controller
//
ASSERT(port == DEFAULT_LISTEN_PORT); hr = ::T120_CreateNodeController(&g_pNodeController, this, szName, dwCredentials, flags); if (FAILED(hr)) { ERROR_OUT(("T120_CreateNodeController() failed!")); }
return hr; }
HRESULT COprahNCUI::Call ( INmCall **ppCall, DWORD dwFlags, NM_ADDR_TYPE addrType, BSTR bstrAddr, BSTR bstrConference, BSTR bstrPassword ) { BSTR bstrRealAddr;
DebugEntry(COprahNCUI::Call);
if (addrType == NM_ADDR_MACHINENAME) { //
// Convert to IP Address
//
int cch; TCHAR * pszOemName; ULONG ulIpAddress; HOSTENT * pHostEnt; WCHAR * pwszName;
cch = SysStringLen(bstrAddr); pszOemName = new TCHAR[cch + 1];
if (!pszOemName) { ERROR_OUT(("Couldn't get OEM Name")); return E_OUTOFMEMORY; }
WideCharToMultiByte(CP_ACP, 0, bstrAddr, -1, pszOemName, cch+1, NULL, NULL);
CharUpper(pszOemName); CharToOem(pszOemName, pszOemName);
pHostEnt = gethostbyname(pszOemName); if (!pHostEnt || (pHostEnt->h_addrtype != AF_INET) || (pHostEnt->h_length != sizeof(ULONG)) || (pHostEnt->h_addr_list[0] == NULL)) { ulIpAddress = 0; WARNING_OUT(("gethostbyname failed")); } else { ulIpAddress = *reinterpret_cast<ULONG *>(pHostEnt->h_addr_list[0]); }
delete pszOemName;
if (!ulIpAddress) { ERROR_OUT(("gethostbyname failed, returning")); return E_FAIL; }
pszOemName = inet_ntoa(*reinterpret_cast<in_addr *>(&ulIpAddress)); cch = lstrlen(pszOemName);
pwszName = new WCHAR[cch + 1]; if (!pwszName) { ERROR_OUT(("Can't alloc OLE string")); return E_OUTOFMEMORY; }
MultiByteToWideChar(CP_ACP, 0, pszOemName, -1, pwszName, cch+1); bstrRealAddr = SysAllocString(pwszName);
delete pwszName; } else if (addrType == NM_ADDR_IP) { bstrRealAddr = SysAllocString(bstrAddr); } else { ERROR_OUT(("INmManager::Call - bogus addrType %d", addrType)); return E_FAIL; }
HRESULT hr = m_pOutgoingCallManager->Call( ppCall, this, dwFlags, addrType, bstrRealAddr, bstrConference, bstrPassword);
SysFreeString(bstrRealAddr);
DebugExitHRESULT(COprahNCUI::Call, hr); return hr; }
HRESULT COprahNCUI::CreateConference ( INmConference **ppConference, BSTR bstrName, BSTR bstrPassword, BOOL fSecure ) { if (NULL == ppConference) { ERROR_OUT(("CreateConferenceEx: null ppConference passed in")); return E_POINTER; }
if (m_pConfObject->IsConferenceActive()) { WARNING_OUT(("CreateConference is failing because IsConferenceActive return TRUE")); return NM_CALLERR_IN_CONFERENCE; }
m_pConfObject->SetConfName(bstrName); m_pConfObject->SetConfSecurity(fSecure);
if (!m_pConfObject->IsConferenceCreated()) { m_pConfObject->OnConferenceCreated(); }
NotifySink((INmConference*) m_pConfObject, OnNotifyConferenceCreated);
*ppConference = m_pConfObject; if(*ppConference) { (*ppConference)->AddRef(); }
return S_OK; }
/* O N N O T I F Y C O N F E R E N C E C R E A T E D */ /*-------------------------------------------------------------------------
%%Function: OnNotifyConferenceCreated
-------------------------------------------------------------------------*/ HRESULT OnNotifyConferenceCreated(IUnknown *pManagerNotify, PVOID pv, REFIID riid) { ASSERT(NULL != pManagerNotify); ((INmManagerNotify*)pManagerNotify)->ConferenceCreated((INmConference *) pv); return S_OK; }
/* O N N O T I F Y C A L L C R E A T E D */ /*-------------------------------------------------------------------------
%%Function: OnNotifyCallCreated
-------------------------------------------------------------------------*/ HRESULT OnNotifyCallCreated(IUnknown *pManagerNotify, PVOID pv, REFIID riid) { ASSERT(NULL != pManagerNotify); ((INmManagerNotify*)pManagerNotify)->CallCreated((INmCall *) pv); return S_OK; }
/* O N N O T I F Y C A L L S T A T E C H A N G E D */ /*-------------------------------------------------------------------------
%%Function: OnNotifyCallStateChanged
-------------------------------------------------------------------------*/ HRESULT OnNotifyCallStateChanged(IUnknown *pCallNotify, PVOID pv, REFIID riid) { ASSERT(NULL != pCallNotify); ((INmCallNotify*)pCallNotify)->StateChanged((NM_CALL_STATE)(DWORD_PTR)pv); return S_OK; }
HRESULT WINAPI CreateNmManager(INmManager ** ppMan) { if (!ppMan) return E_POINTER;
COprahNCUI *pManager = new COprahNCUI(); if (!pManager) return E_OUTOFMEMORY;
*ppMan = (INmManager *)pManager; return S_OK; }
|