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

📄 tapiline.cpp

📁 AVAYA IPO 430系列交换机Wavedriver的demo程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ----------------------------------------------------------------------------
// Copyright (c) Avaya 2002. All rights reserved.
//
//	Derived from 
//  \CTI\CTIntegrator\Develop\tapisample\\tapiline.cpp
//
// This is the implementation file for the tapi support classes.
// See tapiline.h for the definition of this class
//
// ----------------------------------------------------------------------------

#include "stdafx.h"
#include <tapi.h>

#include "TAPIConnection.h"
#include "TAPILine.h"
#include "TAPIDescribe.h"

// ============================================================================
// Static functions
// ============================================================================

// ----------------------------------------------------------------------------
// Get a string from a TAPI structure
void getTapiString(CString& result, void *ptr, DWORD Size, DWORD Offset)
{
	if (Size > 0)
	{
		char *buffer = result.GetBufferSetLength(Size + 1);
		memcpy(buffer, &((BYTE *) ptr)[Offset], Size);
		buffer[Size] = 0;
		result.ReleaseBuffer();
	}
	else
		result.Empty();
}

// ----------------------------------------------------------------------------
// Get call information from TAPI
// Note: The calling function must delete the info structure later on!
HRESULT loopLineGetCallInfo(HCALL hCall, LINECALLINFO*& pCallInfo)
{
	size_t CurrentSize = 512; // Starting value - usually big enough
	HRESULT hr;

	for (;;)
	{
		// Allocate some memory for the call
		pCallInfo = (LINECALLINFO *) new BYTE[CurrentSize];
		ZeroMemory(&pCallInfo[0], CurrentSize);
		pCallInfo->dwTotalSize = CurrentSize;

		// Ask TAPI for some information
		hr = ::lineGetCallInfo(hCall, pCallInfo);

		// Cope with variable length structures
		if (hr == LINEERR_STRUCTURETOOSMALL)
		{
			if (pCallInfo->dwNeededSize <= 0)
				break;
			CurrentSize = pCallInfo->dwNeededSize;
			delete [] pCallInfo;
			pCallInfo = NULL;
		}
		else
			break;
	}
	return hr;
}


// ----------------------------------------------------------------------------
// Get identification information from TAPI
HRESULT loopLineGetID(DWORD& result, HLINE hLine, DWORD AddressID,
	HCALL hCall, DWORD Select, LPCSTR pszDeviceClass)
{
	VARSTRING* pVarString = NULL;
	result = 0xffffffff;
	size_t CurrentSize = 512; // Starting value - usually big enough
	HRESULT hr;

	for (;;)
	{
		// Allocate some memory for the call
		pVarString = (VARSTRING *) new BYTE[CurrentSize];
		ZeroMemory(&pVarString[0], CurrentSize);
		pVarString->dwTotalSize = CurrentSize;

		// Ask TAPI for some information
		hr = ::lineGetID(hLine, AddressID, hCall, Select, pVarString, pszDeviceClass);

		// Cope with variable length structures
		if (hr == LINEERR_STRUCTURETOOSMALL)
		{
			if (pVarString->dwNeededSize <= 0)
				break;
			CurrentSize = pVarString->dwNeededSize;
			delete [] pVarString;
			pVarString = NULL;
		}
		else
			break;
	}
	if (hr == S_OK)
		result = ((DWORD *) (((BYTE *) pVarString) + pVarString->dwStringOffset))[0];
	delete [] pVarString;
	return hr;
}

// ----------------------------------------------------------------------------
// Get address capabilities information from TAPI
HRESULT loopLineGetAddressCaps(HLINEAPP hLineApp, DWORD DeviceID, DWORD AddressID,
	DWORD APIVersion, DWORD ExtVersion, LINEADDRESSCAPS*& pAddressCaps)
{
	size_t CurrentSize = 512; // Starting value - usually big enough
	HRESULT hr;

	for (;;)
	{
		// Allocate some memory for the call
		pAddressCaps = (LINEADDRESSCAPS *) new BYTE[CurrentSize];
		ZeroMemory(&pAddressCaps[0], CurrentSize);
		pAddressCaps->dwTotalSize = CurrentSize;

		// Ask TAPI for some information
		hr = ::lineGetAddressCaps(hLineApp, DeviceID, AddressID, APIVersion,
			ExtVersion, pAddressCaps);

		// Cope with variable length structures
		if (hr == LINEERR_STRUCTURETOOSMALL)
		{
			if (pAddressCaps->dwNeededSize <= 0)
				break;
			CurrentSize = pAddressCaps->dwNeededSize;
			delete [] pAddressCaps;
			pAddressCaps = NULL;
		}
		else
			break;
	}
	return hr;
}


// ============================================================================
// TAPI line class
// ============================================================================

// ----------------------------------------------------------------------------
// Create a TAPI line wrapper object
TAPILine::TAPILine(TAPIConnection	*pTAPIConnection) :
	m_pTAPIConnection(pTAPIConnection)
{
	m_LineID = 0;
	m_hLine = 0;

	m_hConnectedCall = 0;
	m_hWaitingCall = 0;
	m_hHeldCall = 0;
	m_hPendingCall = 0;
	m_hConferenceCall = 0;
}

// ----------------------------------------------------------------------------
// Destroy a TAPI line wrapper object
TAPILine::~TAPILine()
{
	if (m_hLine)
		::lineClose(m_hLine);
	m_hLine = 0;
}

// ----------------------------------------------------------------------------
// Ask TAPI to make a call - only works if we are not on a call.
void TAPILine::MakeCall(LPCTSTR pszAddress)
{
	if ((m_hConnectedCall == 0) && (m_hWaitingCall == 0)) // No currently active call
	{
		// DevSpecificData 
		char pDevSpec[8] = { 'N', 'A', 'L', 'C', 3, 'C', 111, 0 }; // Whisper call

		// Calculate the size of the parameter structure, and allocate it.
		size_t cbDestAddress = strlen(pszAddress) + 1;
		size_t cbCallParams = sizeof(LINECALLPARAMS) + cbDestAddress /*+ 8*/; // 8 chars of devspecific
		LINECALLPARAMS* pCallParams = (LINECALLPARAMS*)(new BYTE[cbCallParams]);
		// Setup the parameters
		if (pCallParams)
		{
			ZeroMemory(pCallParams, cbCallParams);
			pCallParams->dwTotalSize = cbCallParams;
			pCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
			pCallParams->dwMinRate = 0;   // Use device default
			pCallParams->dwMaxRate = 0;   // Use device default
			pCallParams->dwMediaMode = 6;//LINEMEDIAMODE_INTERACTIVEVOICE | LINEMEDIAMODE_UNKNOWN;
			pCallParams->dwCallParamFlags = 0; // No flags
			pCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
			pCallParams->dwAddressID = 0; // Use the main (and only) line address
			// Variable length strings
			pCallParams->dwDisplayableAddressSize = cbDestAddress;
			pCallParams->dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
			char* pszDisplayableAddress = (char*)((BYTE*)pCallParams + sizeof(LINECALLPARAMS));
			strcpy(pszDisplayableAddress, pszAddress);
			//pCallParams->dwDevSpecificSize = 8;
			//pCallParams->dwDevSpecificOffset = sizeof(LINECALLPARAMS) + cbDestAddress;
			//char* pDevspecificData = (char*)((BYTE*)pCallParams + sizeof(LINECALLPARAMS)) + cbDestAddress;
			//memcpy(pDevspecificData, pDevSpec, 8); 
		}
		// Ask TAPI to make the call
		HRESULT tr = ::lineMakeCall(m_hLine, &m_hWaitingCall, pszAddress, 0, pCallParams);
		delete[] pCallParams;
		if (tr > 0)
		{
			REQUEST_INFO ri = { "MakeCall", m_hWaitingCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "MakeCall");
	}
	else
		SendInfoMsg("Error(MakeCall: Active Call)");
}

// ----------------------------------------------------------------------------
// Drop the line - only works if call is currently proceeding
void TAPILine::HangUp()
{
	if (m_hWaitingCall)
	{
		HRESULT tr = ::lineDrop(m_hWaitingCall, NULL, 0);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "DropCall", m_hWaitingCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "DropCall");
	}
	else if (m_hConnectedCall)
	{
		HRESULT tr = ::lineDrop(m_hConnectedCall, NULL, 0);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "DropCall", m_hConnectedCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "DropCall");
	}
	else
		SendInfoMsg("Error(DropCall: No Active Call)");
}


// ----------------------------------------------------------------------------
// Hold the current call - only works if call is currently pending
void TAPILine::AnswerCall()
{
	if (m_hPendingCall)
	{
		HRESULT tr = ::lineAnswer(m_hPendingCall, NULL, 0);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "AnswerCall", m_hPendingCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "AnswerCall");
	}
	else
		SendInfoMsg("Error(AnswerCall: No Pending Call)");
}

// ----------------------------------------------------------------------------
// Hold the current call - only works if call is currently proceeding
void TAPILine::HoldCall()
{
	if (m_hConnectedCall)
	{
		HRESULT tr = ::lineHold(m_hConnectedCall);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "HoldCall", m_hConnectedCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "HoldCall");
	}
	else
		SendInfoMsg("Error(HoldCall: No Active Call)");
}

// ----------------------------------------------------------------------------
// Retrieve the call from hold - only works if call is currently proceeding
void TAPILine::RetrieveCall()
{
	if (m_hHeldCall)
	{
		HRESULT tr = ::lineUnhold(m_hHeldCall);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "RetrieveCall", m_hHeldCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "RetrieveCall");
	}
	else
		SendInfoMsg("Error(RetrieveCall: No Held Call)");
}

// ----------------------------------------------------------------------------
// Conference the current call with the call from hold - only works if call
// is currently proceeding and there is a call on hold.
void TAPILine::ConferenceCall()
{
	if (m_hConnectedCall && m_hHeldCall)
	{
		HRESULT tr = ::lineCompleteTransfer(m_hHeldCall, m_hConnectedCall, &m_hConferenceCall,
			LINETRANSFERMODE_CONFERENCE);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "ConferenceCall", m_hConferenceCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "ConferenceCall");
	}
	else
	{
		if (!m_hConnectedCall)
			SendInfoMsg("Error(ConferenceCall: No Active Call)");
		if (!m_hHeldCall)
			SendInfoMsg("Error(ConferenceCall: No Held Call)");
	}
}

// ----------------------------------------------------------------------------
// Conference the current call with the call from hold - only works if call is currently proceeding
void TAPILine::TransferCall(LPCTSTR pszAddress)
{
	if (m_hConnectedCall)
	{
		HRESULT tr = ::lineBlindTransfer(m_hConnectedCall, pszAddress, 0);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "TransferCall", m_hConnectedCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "TransferCall");
	}
	else if (m_hWaitingCall) // Well, might as well try this to see if it works
	{
		// Blind transfer a call we are ringing
		HRESULT tr = ::lineBlindTransfer(m_hWaitingCall, pszAddress, 0);
		if (tr > 0)
		{
			REQUEST_INFO ri = { "TransferCall", m_hWaitingCall };
			m_Requests.SetAt(tr, ri);
		}
		CheckError(tr, "TransferCall");
	}
	else
		SendInfoMsg("Error(TransferCall: No Active Call)");
}

// ----------------------------------------------------------------------------
// Open a specified TAPI line
HRESULT TAPILine::Open(HLINEAPP hLineApp, 
					DWORD *ApiVersions,
					DWORD LineID, 

⌨️ 快捷键说明

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