Ejemplo n.º 1
0
///////////////////////////////////////////////////////////////////
// DoCallMedia
//
//
// TE_CALLMEDIA is a media event.  pEvent is an ITCallMediaEvent
//
//
///////////////////////////////////////////////////////////////////
HRESULT DoCallMedia(
				IN IDispatch * pEvent)
{

    CALL_MEDIA_EVENT    cme = CME_STREAM_INACTIVE;
    ITCallMediaEvent  * pCallMediaEvent = NULL;

	//
	// check if we still have a call
	//
	if(NULL == g_pCall)
	{
		return E_UNEXPECTED;
	}

    //
	// Get the interface
	//
    HRESULT hr = pEvent->QueryInterface( IID_ITCallMediaEvent, (void **)&pCallMediaEvent );
	if(FAILED(hr))
	{
        DoMessage( _T("ITCallMediaEvent, but failed to get the interface"));
		return hr;
	}

    //
	// get the CALL_MEDIA_EVENT that we are being notified of.
	//
    hr = pCallMediaEvent->get_Event( &cme );
	if(FAILED(hr))
	{
		pCallMediaEvent->Release();
		DoMessage( _T("ITCallMediaEvent, but failed to get_Event"));
		return hr;
	}

    switch ( cme ) 
    {
		// 
		// the only event we process
		//
        case CME_STREAM_ACTIVE:    
        {
            //
            // Get the terminal that's now active. 
            //    
            ITTerminal * pTerminal = NULL;
            hr = GetTerminalFromStreamEvent(pCallMediaEvent, &pTerminal);

            if ( FAILED(hr) )  
			{
				DoMessage(_T("ITCallMediaEvent: GetTerminalFromStreamEvent failed"));
				g_pCall->Disconnect(DC_NORMAL);
				break; 
			}

            //
            // Process this terminal based on the direction.
            //
            TERMINAL_DIRECTION td;
            hr = pTerminal->get_Direction( &td);
			//
			//clean up
			//
            pTerminal->Release(); 

            if ( FAILED(hr) ) 
            { 
	            DoMessage(_T("ITCallMediaEvent: get_Direction failed"));
				g_pCall->Disconnect(DC_NORMAL);
                break; 
            }

			//
			// if TD_CAPTURE and we have playback terminal start streaming
			//
            if ( TD_CAPTURE == td && NULL != g_pPlayFileTerm) 
            {
				ITMediaControl* pITMC = NULL;
				
				hr = g_pPlayFileTerm->QueryInterface(IID_ITMediaControl, (void**)&pITMC);
				//
				// get ITMediaControl so we can start streaming
				//
				if(FAILED(hr))
				{
					DoMessage(_T("ITCallMediaEvent: g_pPlayFileTerm QI for ITMediaControl failed"));
					g_pCall->Disconnect(DC_NORMAL);
					break;
				}
				//
				// Start streaming
				//
				hr = pITMC->Start();
				pITMC->Release();
				if(SUCCEEDED(hr))
				{
					SetStatusMessage(_T("File Playback Terminal started "));
				}
				else
				{
		            DoMessage(_T("ITCallMediaEvent: ITMediaControl::Start() failed"));
					g_pCall->Disconnect(DC_NORMAL);
				}
			}
        
            break;
        }
    
        default:
            break;
    }

    //
	// clean up
	//
    pCallMediaEvent->Release();

	return hr;
}
Ejemplo n.º 2
0
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;
}