📄 processing.cpp
字号:
LogMessage("ProcessCallNotificationEvent: "
"incoming call while another call in progress");
ITBasicCallControl *pSecondCall = NULL;
hr = pCall->QueryInterface(IID_ITBasicCallControl,
(void**)&pSecondCall);
pCall->Release();
pCall = NULL;
if (FAILED(hr))
{
LogError("ProcessCallNotificationEvent: failed to qi incoming call "
"for ITBasicCallConrtrol");
return hr;
}
//
// reject the incoming call
//
LogMessage("ProcessCallNotificationEvent: rejecting the incoming call");
hr = pSecondCall->Disconnect(DC_REJECTED);
pSecondCall->Release();
pSecondCall = NULL;
return E_FAIL;
}
//
// check to see if we own the call
//
CALL_PRIVILEGE cp;
hr = pCall->get_Privilege( &cp );
if ( FAILED(hr) )
{
LogError("ProcessCallNotificationEvent: Failed to get call owner info");
pCall->Release();
pCall = NULL;
LeaveCriticalSection(&g_CurrentCallCritSection);
return hr;
}
if ( CP_OWNER != cp )
{
//
// we don't own the call. ignore it.
//
LogMessage("ProcessCallNotificationEvent: We don't own the call.");
pCall->Release();
pCall = NULL;
LeaveCriticalSection(&g_CurrentCallCritSection);
return E_FAIL;
}
else
{
LogMessage("ProcessCallNotificationEvent: Incoming call.");
}
//
// keep the call for future use
//
hr = pCall->QueryInterface(IID_ITBasicCallControl,
(void**)&g_pCurrentCall);
if (FAILED(hr))
{
LogError("ProcessCallNotificationEvent: failed to qi incoming call for"
"ITBasicCallControl.");
g_pCurrentCall = NULL;
}
LeaveCriticalSection(&g_CurrentCallCritSection);
pCall->Release();
pCall = NULL;
return hr;
} // ProcessCallNotificationEvent
///////////////////////////////////////////////////////////////////////////////
//
// ProcessCallMediaEvent
//
// processing for TE_CALLMEDIA event. if stream is active, record the
// incoming data
//
///////////////////////////////////////////////////////////////////////////////
HRESULT ProcessCallMediaEvent(IDispatch *pEvent)
{
//
// Get ITCallMediaEvent interface from the event
//
ITCallMediaEvent *pCallMediaEvent = NULL;
HRESULT hr = pEvent->QueryInterface( IID_ITCallMediaEvent,
(void **)&pCallMediaEvent );
if (FAILED(hr))
{
//
// the event does not have the interface we want
//
LogError("ProcessCallMediaEvent: TE_CALLMEDIA. "
"Failed to QI event for ITCallMediaEvent");
return hr;
}
//
// get the CALL_MEDIA_EVENT that we are being notified of.
//
CALL_MEDIA_EVENT CallMediaEvent;
hr = pCallMediaEvent->get_Event(&CallMediaEvent);
if ( FAILED(hr) )
{
//
// failed to get call media event
//
LogError("ProcessCallMediaEvent: TE_CALLMEDIA. "
"Failed to get call media event hr = 0x%lx", hr);
pCallMediaEvent->Release();
pCallMediaEvent = NULL;
return hr;
}
LogMessage("ProcessCallMediaEvent: processing call media event");
switch (CallMediaEvent)
{
case CME_STREAM_INACTIVE:
{
LogMessage("ProcessCallMediaEvent: CME_STREAM_INACTIVE");
break;
}
case CME_STREAM_NOT_USED:
LogMessage("ProcessCallMediaEvent: CME_STREAM_NOT_USED");
break;
case CME_NEW_STREAM:
LogMessage("ProcessCallMediaEvent: CME_NEW_STREAM received");
break;
case CME_STREAM_FAIL:
LogError("ProcessCallMediaEvent: CME_STREAM_FAIL received");
break;
case CME_TERMINAL_FAIL:
LogError("ProcessCallMediaEvent: CME_STREAM_FAIL received");
break;
case CME_STREAM_ACTIVE:
{
LogError("ProcessCallMediaEvent: CME_STREAM_ACTIVE received");
//
// Get the terminal on the active stream
//
ITTerminal *pRecordStreamTerminal = NULL;
hr = GetTerminalFromMediaEvent(pCallMediaEvent,
&pRecordStreamTerminal);
if ( FAILED(hr) )
{
//
// the stream has no terminals associated with it
//
LogError("ProcessCallMediaEvent: "
"failed to get terminal on the active stream");
break;
}
//
// make sure the direction is right -- we are recording, so the
// terminal should be TD_RENDER
//
TERMINAL_DIRECTION td;
hr = pRecordStreamTerminal->get_Direction( &td);
if ( FAILED(hr) )
{
LogError("ProcessCallMediaEvent: "
"failed to get record terminal's direction.");
pRecordStreamTerminal->Release();
pRecordStreamTerminal = NULL;
break;
}
//
// double check that the terminal is rendering terminal
// since we are the recording side
//
if ( TD_RENDER != td )
{
//
// this should never ever happen
//
LogError("ProcessCallMediaEvent: bad terminal direction");
pRecordStreamTerminal->Release();
pRecordStreamTerminal = NULL;
hr = E_FAIL;
break;
}
//
// Now do the actual streaming.
//
//
// this will block until:
//
// the call is disconnected, or
// the user chooses to close the app, or
// there is an error
//
// Since we are in the message processing thread,
// the application will not be able to process messages
// (the messages will still be queued) until this call
// returns.
//
// If it is important that messages are processed while
// file is being recorded, recording should be done on
// a different thread.
//
RecordMessage(pRecordStreamTerminal);
pRecordStreamTerminal->Release();
pRecordStreamTerminal = NULL;
break;
}
default:
break;
} // switch (call media event)
//
// We no longer need the event interface.
//
pCallMediaEvent->Release();
pCallMediaEvent = NULL;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//
// ProcessCallStateEvent
//
// processing for TE_CALLSTATE. if CS_OFFERING, creates and selects MST,
// answers the call . Release call if disconnected.
//
// also verifies that the event is for the current call
//
///////////////////////////////////////////////////////////////////////////////
HRESULT ProcessCallStateEvent(IDispatch *pEvent)
{
HRESULT hr = S_OK;
//
// TE_CALLSTATE is a call state event.
// pEvent is an ITCallStateEvent
//
ITCallStateEvent *pCallStateEvent = NULL;
//
// Get the interface
//
hr = pEvent->QueryInterface(IID_ITCallStateEvent,
(void **)&pCallStateEvent);
if ( FAILED(hr) )
{
LogError("ProcessCallStateEvent: "
"Failed to QI event for ITCallStateEvent");
return hr;
}
//
// make sure the message is for the active call!
//
EnterCriticalSection(&g_CurrentCallCritSection);
if (!IsMessageForActiveCall(pCallStateEvent))
{
LogMessage("ProcessCallStateEvent: received TE_CALLSTATE message "
"for a different call. ignoring.");
pCallStateEvent->Release();
pCallStateEvent = NULL;
LeaveCriticalSection(&g_CurrentCallCritSection);
return E_FAIL;
}
//
// get the CallState that we are being notified of.
//
CALL_STATE CallState;
hr = pCallStateEvent->get_State(&CallState);
//
// no longer need the event
//
pCallStateEvent->Release();
pCallStateEvent = NULL;
if (FAILED(hr))
{
LogError("ProcessCallStateEvent: "
"failed to get state from call state event.");
LeaveCriticalSection(&g_CurrentCallCritSection);
return hr;
}
//
// log the new call state
//
if (CS_OFFERING == CallState)
{
LogMessage("ProcessCallStateEvent: call state is CS_OFFERING");
//
// try to create and select media streaming terminal on one of
// the call's incoming audio streams
//
hr = CreateAndSelectMST();
if (S_OK == hr)
{
//
// we have selected a terminal on one of the streams
// answer the call
//
LogMessage("ProcessCallStateEvent: answering the call");
hr = g_pCurrentCall->Answer();
if (FAILED(hr))
{
LogError("ProcessCallStateEvent: Failed to answer the call");
}
}
else
{
//
// we could not create mst on any of the streams of
// the incoming call. reject the call.
//
LogMessage("ProcessCallStateEvent: rejecting the call");
HRESULT hr2 = g_pCurrentCall->Disconnect(DC_REJECTED);
if (FAILED(hr2))
{
LogError("ProcessCallStateEvent: Failed to reject the call");
}
}
} // CS_OFFERING
else if (CS_DISCONNECTED == CallState)
{
LogMessage("ProcessCallStateEvent: call state is CS_DISCONNECTED. "
"Releasing the call.");
//
// release the call -- no longer need it!
//
g_pCurrentCall->Release();
g_pCurrentCall = NULL;
//
// signal the main thread that it can exit if it is time to exit
//
LogMessage("ProcessCallStateEvent: signaling main thread.");
SetEvent(g_hExitEvent);
} // CS_DISCONNECTED
else if (CS_CONNECTED == CallState)
{
LogMessage("ProcessCallStateEvent: call state is CS_CONNECTED");
} // CS_CONNECTED
//
// no longer need to protect current call
//
LeaveCriticalSection(&g_CurrentCallCritSection);
return hr;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnTapiEvent
//
// handler for tapi events. called on a thread that provides asychronous
// processing of tapi messages
//
/////////////////////////////////////////////////////////////////////////////
HRESULT OnTapiEvent(TAPI_EVENT TapiEvent, IDispatch *pEvent)
{
LogMessage("OnTapiEvent: message received");
HRESULT hr = S_OK;
switch ( TapiEvent )
{
case TE_CALLNOTIFICATION:
{
LogMessage("OnTapiEvent: received TE_CALLNOTIFICATION");
hr = ProcessCallNotificationEvent(pEvent);
break;
} // TE_CALLNOTIFICATION
case TE_CALLSTATE:
{
LogMessage("OnTapiEvent: received TE_CALLSTATE");
hr = ProcessCallStateEvent(pEvent);
break;
} // TE_CALLSTATE
case TE_CALLMEDIA:
{
LogMessage("OnTapiEvent: received TE_CALLMEDIA");
hr = ProcessCallMediaEvent(pEvent);
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -