⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 telephonyengine.cpp

📁 基于Tapi 3.0的软电话源代码
💻 CPP
字号:
//----------------------------------------------------------------------------------------
//  Copyright (c) 2002 Avaya Global SME Solutions 
//----------------------------------------------------------------------------------------
//  Project name: TAPI 3 Test Harness
//  Module file : TelephonyEngine.cpp
//  Compiler    : Visual C++ 6.0
//----------------------------------------------------------------------------------------
//  Description : In this module basic telephony operations are called from ITBasicCallControl
//                interface. All of them are responses on actions from main dialog boxes.   
//                Here are implemented actions like: make a call, 
//----------------------------------------------------------------------------------------

#include "stdafx.h"
#include "Tapi3app.h"
#include "TAPIConn.h"
#include "TAPIAddr.h"
#include "TelephonyEngine.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

const char* PARK_ADDRESS = "4000";

// Construction/Destruction
CTelephonyEngine::CTelephonyEngine()
{
	m_State = T_STATE_IDLE;
	m_pAddress = NULL;

    m_callToTransferDisconnected = false;
    m_pTransferCalledCall = NULL;
    m_pBasicCallerCall = NULL;
    m_pBasicCalledCall = NULL;

    m_CallToTransfer.Empty();
}

CTelephonyEngine::~CTelephonyEngine()
{       
    POSITION pos; 
    for( pos = m_mapExtToCall.GetStartPosition(); pos != NULL; )
    {
        CString key;
        ITBasicCallControl* pCallToRelease = NULL;

        m_mapExtToCall.GetNextAssoc( pos, key, (void*&)pCallToRelease);

        if (pCallToRelease != NULL)
        {            
            pCallToRelease->Release();
        }
    }

    m_mapExtToCall.RemoveAll();

	if (m_pAddress) m_pAddress->Release();
}

bool CTelephonyEngine::Init(CString Extn ,CString Name, CString DisplayName)
{
	m_Extn = Extn;
	m_Name = Name;
	m_DisplayName = DisplayName;

	m_pAddress = CTAPIAddr::GetFromAddrMap(Extn);
	
	if (m_pAddress) return true;
	else return false;
}


//   Function:      AnsiToUnicode
//   Description:   Converts the ANSI string pszA to a Unicode string and returns
//                  the Unicode string through ppszW. Space for the converted
//                  string is allocated by AnsiToUnicode.
HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{
    ULONG cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (NULL == pszA)
    {
        *ppszW = NULL;
        return NOERROR;
    }

    // Determine number of wide characters to be allocated for the
    // Unicode string.
    cCharacters =  strlen(pszA)+1;

    // Use of the OLE allocator is required if the resultant Unicode
    // string will be passed to another COM component and if that
    // component will free it. Otherwise you can use your own allocator.
    *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
    if (NULL == *ppszW)
        return E_OUTOFMEMORY;

    // Covert to Unicode.
    if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters,
                  *ppszW, cCharacters))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszW);
        *ppszW = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }

    return NOERROR;
}

//   Function:      AnsiToBSTR
//   Description:   Converts the ANSI string pszA to a BSTR (global alloc).
HRESULT __fastcall AnsiToBSTR(LPCSTR pszA, BSTR *pBstr)
{
   LPOLESTR lpszTmp = NULL;

   HRESULT res = AnsiToUnicode(pszA, &lpszTmp);
   if( FAILED(res) )
      return res;

   *pBstr = SysAllocString(lpszTmp);
   CoTaskMemFree(lpszTmp);

   return NOERROR;
}

bool CTelephonyEngine::MakeCall(CString& Extn)
{		
	ITBasicCallControl *pCallControl;
	if (m_pAddress)
	{
		// Retrieve the TAPI ITAddress object
		ITAddress* pAddress = m_pAddress->GetITAddress();
		if (pAddress)
		{
			BSTR bstrAddrToCall;

            AnsiToBSTR(Extn, &bstrAddrToCall);

			pAddress->CreateCall(bstrAddrToCall, LINEADDRESSTYPE_PHONENUMBER, 
									TAPIMEDIATYPE_AUDIO, &pCallControl);
			pAddress->Release();

            pCallControl->Connect(0);            

            SysFreeString(bstrAddrToCall);
		}
	}
	return true;
}

bool CTelephonyEngine::AnswerCall(ITBasicCallControl *pCallControl)
{
    HRESULT hr = pCallControl->Answer();

	return (hr == S_OK);
}

bool CTelephonyEngine::HoldCall(ITBasicCallControl *pCallControl)
{
    HRESULT hr = pCallControl->Hold(VARIANT_TRUE);

	return (hr == S_OK);
}

bool CTelephonyEngine::UnHoldCall(ITBasicCallControl *pCallControl)
{
    HRESULT hr = pCallControl->Hold(VARIANT_FALSE);

	return (hr == S_OK);
}

bool CTelephonyEngine::DropCall(ITBasicCallControl *pCallControl)
{
    HRESULT hr = pCallControl->Disconnect(DC_NORMAL);
	return (hr == S_OK);
}

bool CTelephonyEngine::ParkCall(ITBasicCallControl *pCallControl)
{
    HRESULT hr;
    BSTR bstrAddr; 

    AnsiToBSTR( PARK_ADDRESS, &bstrAddr);
    hr = pCallControl->ParkDirect(bstrAddr);

    SysFreeString(bstrAddr);
	return (hr == S_OK);
}

bool CTelephonyEngine::UnparkCall()
{
	ITBasicCallControl *pCallControl;
    HRESULT hr;

	if (m_pAddress)
	{
		// Retrieve the TAPI ITAddress object
		ITAddress* pAddress = m_pAddress->GetITAddress();
		if (pAddress)
		{
			BSTR bstrAddrToCall;

            AnsiToBSTR( PARK_ADDRESS, &bstrAddrToCall);

			pAddress->CreateCall(bstrAddrToCall, LINEADDRESSTYPE_PHONENUMBER, 
								 TAPIMEDIATYPE_AUDIO, &pCallControl);
			
            hr = pCallControl->Unpark();

            pCallControl->Release();
            pAddress->Release();
            SysFreeString(bstrAddrToCall);

            return (hr == S_OK);
		}
	}
	return false;
}

bool CTelephonyEngine::BlindTransfer(ITBasicCallControl *pCallControl, CString& Extn)
{
    HRESULT hr;
    BSTR bstrAddrToTransfer;
    AnsiToBSTR(Extn, &bstrAddrToTransfer);

    hr = pCallControl->BlindTransfer(bstrAddrToTransfer);

    SysFreeString(bstrAddrToTransfer);

    return (hr==S_OK);
}

DISCONNECTION_TYPE CTelephonyEngine::Disconnected(CString& Extn)
{   
    if (!m_CallToTransfer.IsEmpty() && Extn == m_CallToTransfer) 
    {
        m_callToTransferDisconnected = true;        
        return DT_TRANSFERING;
    }
    else
    {
        ITBasicCallControl* pCallToRelease = NULL;
        if (m_mapExtToCall.Lookup(Extn, (void*&) pCallToRelease) == TRUE)
        {
            if (pCallToRelease != NULL)
            {
                pCallToRelease->Release();
                m_mapExtToCall.RemoveKey(Extn);
                
                if (m_mapExtToCall.IsEmpty()) return DT_CONFERENCE;

                return DT_CONSULTATION;
            }        
        }
    }

    return DT_NORMAL;
}

ITBasicCallControl* CTelephonyEngine::TransferCall(ITBasicCallControl *pCallersCall, ITBasicCallControl *pCalledCall, CString& Extn, CString& ExtToTransfer)
{
    HRESULT hr;

    m_callToTransferDisconnected = false;

    m_pBasicCallerCall = pCallersCall;
    m_pBasicCallerCall->AddRef();
    m_pBasicCalledCall = pCalledCall;
    m_pBasicCalledCall->AddRef();

    if (m_pTransferCalledCall != NULL)
    {
        m_pTransferCalledCall->Release();
        m_pTransferCalledCall = NULL;
    }
    
    m_CallToTransfer = ExtToTransfer;    

	if (m_pAddress)
	{
		// Retrieve the TAPI ITAddress object
		ITAddress* pAddress = m_pAddress->GetITAddress();
		if (pAddress)
		{
            BSTR bstrAddrToTransfer;
            AnsiToBSTR(Extn, &bstrAddrToTransfer);

            if (m_pBasicCallerCall->Hold(VARIANT_TRUE) != S_OK) ::MessageBox(0, "Unsucessfull Hold", "", MB_OK|MB_ICONEXCLAMATION);

			hr = pAddress->CreateCall(bstrAddrToTransfer, LINEADDRESSTYPE_PHONENUMBER, 
								 TAPIMEDIATYPE_AUDIO, &m_pTransferCalledCall);
			            
            if (hr == S_OK) 
            {                
                hr = m_pBasicCallerCall->Transfer(m_pTransferCalledCall, VARIANT_FALSE);
                if (hr == S_OK) 
                {                    
                    // save extensions which could involved in conference and 
                    // appropriate pointers to call objects
                    m_mapExtToCall.SetAt (ExtToTransfer, m_pBasicCalledCall); 
                    m_mapExtToCall.SetAt (Extn, m_pTransferCalledCall);  
                }
                else
                {
                    PRINT(-1,0, "Can not transfer the call");
                }
            }
            else
            {
                PRINT(-1,0, "Can not create transfer call");
            }
                             
            pAddress->Release();
            SysFreeString(bstrAddrToTransfer);

            if (hr == S_OK) return m_pTransferCalledCall;
		}
	}

    return NULL;
}

bool CTelephonyEngine::FinishTransfer( bool realFinish)
{
    HRESULT hr;

    if ( m_pTransferCalledCall == NULL ) return false;

    if (!realFinish)
    {
        if (m_pTransferCalledCall != NULL)
            m_pTransferCalledCall->Release();
        
        return true;
    }    

    hr = m_pTransferCalledCall->Finish(FM_ASTRANSFER);    
    
    m_pTransferCalledCall->Release();
    m_pTransferCalledCall = NULL;

    m_CallToTransfer.Empty();

    m_pBasicCallerCall->Release();
    m_pBasicCallerCall = NULL; 
    m_pBasicCalledCall->Release();
    m_pBasicCalledCall = NULL;

    return (hr == S_OK);
}

bool CTelephonyEngine::CreateConference()
{
    HRESULT hr;

    if (m_pTransferCalledCall != NULL)
        hr = m_pTransferCalledCall->Finish(FM_ASCONFERENCE);    
    
    m_CallToTransfer.Empty();

    return (hr == S_OK);
}

bool CTelephonyEngine::AddToConference( CString& Extn )
{
    HRESULT hr;
    ITBasicCallControl *pConsultationCall;

	if (m_pAddress && m_pBasicCallerCall)
	{
		// Retrieve the TAPI ITAddress object
		ITAddress* pAddress = m_pAddress->GetITAddress();
		if (pAddress)
		{
            BSTR bstrAddrToTransfer;
            AnsiToBSTR(Extn, &bstrAddrToTransfer);

			hr = pAddress->CreateCall(bstrAddrToTransfer, LINEADDRESSTYPE_PHONENUMBER, 
								 TAPIMEDIATYPE_AUDIO, &pConsultationCall);			            

            if (hr == S_OK) 
            {                
                hr = m_pBasicCallerCall->Conference(pConsultationCall, VARIANT_TRUE);                            
                //if (hr != S_OK) PRINT(-1,0, "%s: Can not add to the conference.", Extn);
                // Even if function Conference fails calling Finish can add call to conference
            }
            else
                PRINT(-1,0, "Can not create the call to the %s", Extn);
            
            hr = pConsultationCall->Finish(FM_ASCONFERENCE);
            
            if (hr != S_OK) 
            {
                pConsultationCall->Release();
                PRINT(-1,0, "%s: Can not Finish adding to the conference.", Extn);
            }
            else            
            {
                m_mapExtToCall.SetAt (Extn, pConsultationCall);
            }
                             
            pAddress->Release();
            SysFreeString(bstrAddrToTransfer);
        }
    }

    return (hr == S_OK);
}

bool CTelephonyEngine::RemoveFromConference( CString& Extn, ITCallInfo* pCallInfo )
{
    PRINT(-1,0, "Remove From Conference is not supported yet.");
    return false;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -