📄 tapiline.cpp
字号:
// ----------------------------------------------------------------------------
// 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 + -