///////////////////////////////////////////////////////////////////
// SameCall
//
// check if same call object as g_pCall
//
///////////////////////////////////////////////////////////////////
bool SameCall(ITCallStateEvent* pCallStateEvent)
{

	//
	// sanity check
	//
	if(NULL == pCallStateEvent)
	{
		return false;
	}

	//
	//get call object
	//
	ITCallInfo* pCallInfo = NULL;
	HRESULT hr = pCallStateEvent->get_Call(&pCallInfo);
	//
	//check if we have a call and get_Call succeded
	//
	if(NULL != pCallInfo &&  ( SUCCEEDED(hr) && NULL != g_pCall) )
	{
		bool bIsEqual = true;
		//
		//get and compare IUnknown for both objects
		//
		IUnknown* pIUnkCallInfo = NULL;
		IUnknown* pIUnkCallControl = NULL;
		pCallInfo->QueryInterface(IID_IUnknown, (void**)&pIUnkCallInfo);
		g_pCall->QueryInterface(IID_IUnknown, (void**)&pIUnkCallControl);
		//
		//compare
		//
		if(pIUnkCallInfo != pIUnkCallControl)
		{
			bIsEqual = false;
		}

		//
		//clean up
		//
		pCallInfo->Release();
		if(NULL != pIUnkCallInfo)
		{
			pIUnkCallInfo->Release();
		}
		if(NULL != pIUnkCallControl)
		{
			pIUnkCallControl->Release();
		}
		return bIsEqual;
	}
	else
	{
		return false;
	}

}
///////////////////////////////////////////////////////////////////
// DoCallNotification
//
// TE_CALLNOTIFICATION means that the application is being notified
// of a new call.
//
// Note that we don't answer to call at this point.  The application
// should wait for a CS_OFFERING CallState message before answering
// the call.
//
///////////////////////////////////////////////////////////////////
HRESULT DoCallNotification(
				IN IDispatch * pEvent)
{

    ITCallNotificationEvent         * pNotify = NULL;

    HRESULT hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify );

    if (FAILED(hr))
    {
        DoMessage( _T("Incoming call, but failed to get the interface"));
		return hr;
    }

    CALL_PRIVILEGE          cp = CP_MONITOR;
    ITCallInfo *            pCall = NULL;

    //
    // get the call
    //
    hr = pNotify->get_Call( &pCall );
    
    //
    // release the event object
    //
    pNotify->Release();

	if(FAILED(hr))
	{
		DoMessage( _T("Incoming call, but failed to get the call"));
		return hr;
	}

    //
    // check to see if we own the call
    //

    hr = pCall->get_Privilege( &cp );

	if(FAILED(hr))
	{
		pCall->Release();
		DoMessage( _T("Incoming call, but failed to get_Privilege"));
		return hr;
	}

    if ( CP_OWNER != cp )
    {
        //
		// just ignore it if we don't own it
		//
        pCall->Release();
		return hr;
    }

	//
	//check if we already have a call - if yes reject it
	//
	if(NULL != g_pCall)
	{
		ITBasicCallControl* pITBCC = NULL;

	    hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&pITBCC );
        pCall->Release();
		//
		//sanity check
		//
		if(SUCCEEDED(hr))
		{
			//
			//disconnect - we'll handle the other events from this call later
			//
			pITBCC->Disconnect(DC_REJECTED);
	        pITBCC->Release();
		}
		return hr;
	}

	//
	//get the call if do not have already one
	//
    hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&g_pCall );
	pCall->Release();
	if(FAILED(hr))
	{
		DoMessage( _T("Incoming call, but failed to QI ITBasicCallControl"));
	}
	else
	{
		//
		// update UI
		//
		SetStatusMessage(_T("Incoming Owner Call"));
	}

	//
	//clean up
	//

	return hr;
}
HRESULT
OnTapiEvent(
    TAPI_EVENT TapiEvent,
    IDispatch * pEvent
)
{
    HRESULT hr;

    switch ( TapiEvent )
    {
    case TE_CALLNOTIFICATION:
    {
        //
        // TE_CALLNOTIFICATION means that the application is being notified
        // of a new call.
        //
        // Note that we don't answer to call at this point.  The application
        // should wait for a CS_OFFERING CallState message before answering
        // the call.
        //

        ITCallNotificationEvent         * pNotify;

        hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify );

        if (S_OK != hr)
        {
            DoMessage( L"Incoming call, but failed to get the interface");
        }
        else
        {
            CALL_PRIVILEGE          cp;
            ITCallInfo *            pCall;

            //
            // get the call
            //

            hr = pNotify->get_Call( &pCall );

            pNotify->Release();

            if ( SUCCEEDED(hr) )
            {
                //
                // check to see if we own the call
                //

                hr = pCall->get_Privilege( &cp );

                if ( FAILED(hr) || (CP_OWNER != cp) )
                {
                    //
                    // just ignore it if we don't own it
                    //

                    pCall->Release();

                    pEvent->Release(); // we addrefed it CTAPIEventNotification::Event()

                    return S_OK;
                }

                //
                // Get the ITBasicCallControl interface
                //

                //
                // If we're already in a call, disconnect the new call.  Otherwise,
                // save it in our global variable.
                //

                ITBasicCallControl * pCallControl;

                hr = pCall->QueryInterface( IID_ITBasicCallControl,
                                            (void**)&pCallControl );

                pCall->Release();


                if ( SUCCEEDED(hr) )
                {
                    if (gpCall == NULL)
                    {
                        gpCall = pCallControl;

                        //
                        // update UI
                        //

                        EnableButton( IDC_ANSWER );
                        DisableButton( IDC_DISCONNECT );
                        SetStatusMessage(L"Incoming Owner Call");
                    }
                    else
                    {
                        //
                        // Reject this call since we're already in a call
                        //

                        hr = pCallControl->Disconnect(DC_REJECTED);

                        pCallControl->Release();

                        if (FAILED(hr))
                        {
                            break;
                        }
                    }
                }

            }
        }

        break;
    }

    case TE_CALLSTATE:
    {
        // TE_CALLSTATE is a call state event.  pEvent is
        // an ITCallStateEvent

        CALL_STATE           cs;
        ITCallStateEvent   * pCallStateEvent;
        ITCallInfo *         pCall;
        ITBasicCallControl * pCallControl;

        // Get the interface
        hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent );

        if ( FAILED(hr) )
        {
            break;
        }

        // get the CallInfo interface
        hr = pCallStateEvent->get_Call( &pCall );

        if ( FAILED(hr) )
        {
            pCallStateEvent->Release();
            break;
        }

        //get the ITBasicCallControl interface and compare it to our existing call
        hr = pCall->QueryInterface( IID_ITBasicCallControl,(void**)&pCallControl );

        pCall->Release();

        if (FAILED(hr))
        {
            pCallStateEvent->Release();
            break;
        }

        //ignore call state events for other calls
        if (pCallControl != gpCall)
        {
            pCallControl->Release();
            pCallStateEvent->Release();
            break;
        }
        pCallControl->Release();

        //
        // This is a call state event for our call
        //

        // get the CallState that we are being notified of.
        hr = pCallStateEvent->get_State( &cs );

        // Release the interface
        pCallStateEvent->Release();

        if ( FAILED(hr) )
        {
            break;
        }

        // if it's offering, update our UI
        if (CS_OFFERING == cs)
        {
            if (gfAutoAnswer)
            {
                PostMessage(ghDlg, WM_COMMAND, IDC_ANSWER, 0);
            }
            else
            {
                SetStatusMessage(L"Click the Answer button");
            }
        }
        else if (CS_DISCONNECTED == cs)
        {
            PostMessage(ghDlg, WM_COMMAND, IDC_DISCONNECTED, 0);
        }
        else if (CS_CONNECTED == cs)
        {
            // nothing to do -- we handle connection synchronously
        }

        break;
    }

    case TE_CALLMEDIA:
    {
        // TE_CALLMEDIA is a media event.  pEvent is
        // an ITCallMediaEvent

        CALL_MEDIA_EVENT    cme;
        ITCallMediaEvent  * pCallMediaEvent;

        // Get the interface
        hr = pEvent->QueryInterface( IID_ITCallMediaEvent, (void **)&pCallMediaEvent );

        if ( FAILED(hr) )
        {
            break;
        }

        // get the CALL_MEDIA_EVENT that we are being notified of.
        hr = pCallMediaEvent->get_Event( &cme );

        if ( SUCCEEDED(hr) )
        {
            switch ( cme )
            {
            case CME_STREAM_NOT_USED:
            case CME_STREAM_INACTIVE:
            case CME_NEW_STREAM:
                break;

            case CME_STREAM_FAIL:
                DoMessage( L"Call media event: stream failed");
                break;

            case CME_TERMINAL_FAIL:
                DoMessage( L"Call media event: terminal failed");
                break;

            case CME_STREAM_ACTIVE:
            {
                //
                // Find out if this stream has a video render terminal. If not,
                // we don't need to do anything with this stream. Also note
                // if this is the video capture stream or the video render
                // stream.
                //

                ITTerminal * pTerminal;
                BOOL         fRenderStream;

                hr = GetVideoRenderTerminalFromStreamEvent(
                         pCallMediaEvent,
                         &pTerminal,
                         &fRenderStream
                     );

                if ( SUCCEEDED(hr) )
                {
                    // Get the video window interface for the terminal
                    IVideoWindow *pVideoWindow = NULL;

                    hr = pTerminal->QueryInterface( IID_IVideoWindow, (void**)&pVideoWindow );

                    pTerminal->Release();

                    if ( SUCCEEDED(hr) )
                    {
                        // Put this window in our dialog
                        HostWindow(pVideoWindow, fRenderStream);

                        pVideoWindow->Release();
                    }
                }

                break;
            }

            default:
                break;
            }
        }

        // We no longer need this interface.
        pCallMediaEvent->Release();

        break;
    }

    default:
        break;
    }

    pEvent->Release(); // we addrefed it CTAPIEventNotification::Event()

    return S_OK;
}
Exemple #4
0
/**********************************************************
* COperator::OnTapiEvent *
*------------------------*
*   Description:
*       This is the real TAPI event handler, called on our
*       UI thread upon receipt of the WM_PRIVATETAPIEVENT
*       message.
*   Return:
*       S_OK
************************************************************/
HRESULT COperator::OnTapiEvent( TAPI_EVENT TapiEvent,
                                IDispatch * pEvent )
{
    HRESULT hr;
    switch ( TapiEvent )
    {
        case TE_CALLNOTIFICATION:
        {
            // TE_CALLNOTIFICATION means that the application is being notified
            // of a new call.
            //
            // Note that we don't answer to call at this point.  The application
            // should wait for a CS_OFFERING CallState message before answering
            // the call.
            //
            ITCallNotificationEvent         * pNotify;
            hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify );
            if (S_OK != hr)
            {
                DoMessage( L"Incoming call, but failed to get the interface");
            }
            else
            {
                CALL_PRIVILEGE          cp;
                ITCallInfo *            pCall;

                // Get the call
                hr = pNotify->get_Call( &pCall );
                pNotify->Release();
                if ( SUCCEEDED(hr) )
                {
                    // Check to see if we own the call
                    hr = pCall->get_Privilege( &cp );
                    if ( FAILED(hr) || (CP_OWNER != cp) )
                    {
                        // Just ignore it if we don't own it
                        pCall->Release();
                        pEvent->Release(); // We addrefed it CTAPIEventNotification::Event()
                        return S_OK;
                    }

                    // Get the ITBasicCallControl interface and save it in our
                    // member variable.
                    hr = pCall->QueryInterface( IID_ITBasicCallControl,
                                                (void**)&m_pCall );
                    pCall->Release();
                
                    if ( SUCCEEDED(hr) )
                    {
                        // Update UI
                        ::EnableWindow( ::GetDlgItem( m_hDlg, IDC_ANSWER ), TRUE );
                        SetStatusMessage(L"Incoming Owner Call");
                    }
                }
            }
            
            break;
        }
        
        case TE_CALLSTATE:
        {
            // TE_CALLSTATE is a call state event.  pEvent is
            // an ITCallStateEvent

            // Get the interface
            ITCallStateEvent * pCallStateEvent;
            hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent );
            if ( FAILED(hr) )
            {
                break;
            }

            // Get the CallState that we are being notified of.
            CALL_STATE         cs;
            hr = pCallStateEvent->get_State( &cs );
            pCallStateEvent->Release();
            if ( FAILED(hr) )
            {
                break;
            }

            // If it's offering to be answered, update our UI
            if (CS_OFFERING == cs)
            {
                if (m_fAutoAnswer)
                {
                    ::PostMessage(m_hDlg, WM_COMMAND, IDC_ANSWER, 0); 
                }
                else
                {
                    SetStatusMessage(L"Click the Answer button");
                }
            }
            else if (CS_DISCONNECTED == cs)
            {
                ::PostMessage(m_hDlg, WM_COMMAND, IDC_DISCONNECTED, 0);
            }
            else if (CS_CONNECTED == cs)
            {
                // Nothing to do -- we handle connection synchronously
            }
            break;
        }
        default:
            break;
    }

    pEvent->Release(); // We addrefed it CTAPIEventNotification::Event()
    
    return S_OK;
}