📄 tapiconnection.cpp
字号:
// ============================================================================
// TAPI application class
// ============================================================================
// ----------------------------------------------------------------------------
// 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.
//
// ----------------------------------------------------------------------------
#include "stdafx.h"
#include <tapi.h>
#include "TAPILine.h"
#include "TAPIConnection.h"
#include "TAPIDescribe.h"
// ----------------------------------------------------------------------------
// Line Event Handling
static void CALLBACK TapiLineCallback(
DWORD dwDevice,
DWORD nMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3)
{
switch( nMsg )
{
case LINE_CREATE:
// We have been asked to create a line
break;
case LINE_REQUEST:
// We have received an assisted telephony request
break;
default:
// We have received an event relevant to an existing line
TAPILine* pLine = (TAPILine*) dwInstance;
if (pLine)
pLine->OnEvent(dwDevice, nMsg, dwParam1, dwParam2, dwParam3);
break;
}
}
// ----------------------------------------------------------------------------
// Get device capabilities information from TAPI
// Note: The calling function must delete the info structure later on!
HRESULT loopLineGetDevCaps(HLINEAPP hLineApp, DWORD DeviceID,
DWORD APIVersion, DWORD ExtVersion, LINEDEVCAPS*& pLineDevCaps)
{
size_t CurrentSize = 512; // Starting value - usually big enough
HRESULT hr;
for (;;)
{
// Allocate some memory for the call
pLineDevCaps = (LINEDEVCAPS *) new BYTE[CurrentSize];
ZeroMemory(&pLineDevCaps[0], CurrentSize);
pLineDevCaps->dwTotalSize = CurrentSize;
// Ask TAPI for some information
hr = ::lineGetDevCaps(hLineApp, DeviceID, APIVersion, ExtVersion, pLineDevCaps);
// Cope with variable length structures
if (hr == LINEERR_STRUCTURETOOSMALL)
{
if (pLineDevCaps->dwNeededSize <= 0)
break;
CurrentSize = pLineDevCaps->dwNeededSize;
delete [] pLineDevCaps;
pLineDevCaps = NULL;
}
else
break;
}
return hr;
}
// ----------------------------------------------------------------------------
// Create a TAPI application interface class
TAPIConnection::TAPIConnection()
{
m_pMessageWnd = NULL;
m_hLineApp = 0;
m_pLines = NULL;
m_NumDevs = 0;
m_ApiVersions = 0;
m_FirstOpenedLine = -1;
}
// ----------------------------------------------------------------------------
// Destroy a TAPI application interface class
TAPIConnection::~TAPIConnection()
{
if (m_ApiVersions)
delete [] m_ApiVersions;
}
// ----------------------------------------------------------------------------
// Shutdown our channel to TAPI
void TAPIConnection::ShutdownTAPI()
{
if (m_pLines)
{
DWORD LineID;
for (LineID = 0; LineID < m_NumDevs; LineID++)
{
delete m_pLines[LineID];
}
delete [] m_pLines; m_pLines = NULL;
}
if (m_hLineApp )
{
HRESULT tr = ::lineShutdown(m_hLineApp);
m_hLineApp = 0;
}
}
// ----------------------------------------------------------------------------
// Initialise TAPI
void TAPIConnection::InitialiseTAPI(CWnd *pMsgWnd)
{
// Assign message window;
m_pMessageWnd = pMsgWnd;
// const DWORD dwLoVersion = 0x00020000; // TAPI v2.0
// const DWORD dwHiVersion = TAPI_CURRENT_VERSION;
const DWORD dwLoVersion = 0x00020000; // TAPI v2.0
const DWORD dwHiVersion = 0x00030000;
HLINEAPP hLineApp;
DWORD dwAPIVersion = dwHiVersion;
LINEINITIALIZEEXPARAMS params = { sizeof(LINEINITIALIZEEXPARAMS) };
params.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
HINSTANCE hInst = ::AfxGetInstanceHandle();
LPCTSTR pszAppName = ::AfxGetAppName();
HRESULT tr = ::lineInitializeEx(&hLineApp,
hInst,
TapiLineCallback,
pszAppName,
&m_NumDevs,
&dwAPIVersion,
¶ms);
if (S_OK == tr)
{
// Save the handle
m_hLineApp = hLineApp;
// Negotiate the API versions
// (Necessary to get proper notifications)
if (m_NumDevs > 0)
{
m_ApiVersions = new DWORD[m_NumDevs];
if (m_ApiVersions)
{
LINEEXTENSIONID dummy;
for (DWORD LineID = 0; LineID < m_NumDevs; LineID++)
{
if (S_OK != ::lineNegotiateAPIVersion(m_hLineApp,
LineID,
dwLoVersion,
dwHiVersion,
&m_ApiVersions[LineID],
&dummy) )
{
m_ApiVersions[LineID] = 0;
}
}
}
}
}
}
// ----------------------------------------------------------------------------
// Open valid TAPI lines
void TAPIConnection::OpenValidLines()
{
// Get and open valid lines
DWORD nLines = m_NumDevs;
DWORD nOpenedLines = 0;
DWORD LineID;
m_pLines = new PTAPILINE[nLines];
if (m_pLines != NULL)
{
for (LineID = 0; LineID < nLines; LineID++ )
m_pLines[LineID] = NULL;
for (LineID = 0; LineID < nLines; LineID++ )
{
CString info, s1, s2;
LINEDEVCAPS *pDevCaps = NULL;
HRESULT tr = loopLineGetDevCaps(m_hLineApp, LineID,
m_ApiVersions[LineID], 0, pDevCaps);
if( (S_OK == tr) &&
(pDevCaps->dwBearerModes & LINEBEARERMODE_VOICE) &&
(pDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) &&
(pDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL) )
{
// Tell the user who the TAPI service provider is
getTapiString(s1, pDevCaps, pDevCaps->dwProviderInfoSize,
pDevCaps->dwProviderInfoOffset);
//info.Format("[Provider = %s]", LPCTSTR(s1));
//SendInfoMsg(info);
m_pLines[LineID] = new TAPILine(this);
if (m_pLines[LineID])
{
tr = m_pLines[LineID]->Open(this->m_hLineApp,
this->m_ApiVersions,
LineID,
LINECALLPRIVILEGE_OWNER,
// LINEMEDIAMODE_UNKNOWN);
LINEMEDIAMODE_INTERACTIVEVOICE | LINEMEDIAMODE_UNKNOWN
| LINEMEDIAMODE_AUTOMATEDVOICE );
if (S_OK == tr)
{
if (m_FirstOpenedLine == -1)
{
m_FirstOpenedLine = LineID;
}
nOpenedLines++;
// Tell the user about the capabilities of this line
//info.Format("[Supported Line States = %s]",
// DescribeDeviceStatus(s1, pDevCaps->dwLineStates));
//SendInfoMsg(info);
// Find out about each address
for (DWORD AddressID = 0; AddressID < pDevCaps->dwNumAddresses;
AddressID++)
{
// Find out its capabilities
LINEADDRESSCAPS *pAddressCaps = NULL;
tr = loopLineGetAddressCaps(m_hLineApp,
LineID, AddressID,
m_ApiVersions[LineID], 0, pAddressCaps);
// Find and use the name of the extension we control
getTapiString(s1, pAddressCaps, pAddressCaps->dwAddressSize, pAddressCaps->dwAddressOffset);
DWORD ext = atoi(s1);
m_pLines[LineID]->m_extension = ext;
if (ext == 601)
{
m_FirstOpenedLine = LineID;
//if (m_CurrentLine == -1)
//{
// m_CurrentLine = LineID;
// m_extension = ext;
// m_Dlg.SetExtension(s1);
//}
///AMTODO m_Dlg.SetExtension(s1);
SendInfoMsg(s1);
m_pLines[LineID]->SetDefaultExt(s1);
// Tell the user about the capabilities of this address
info.Format("[MaxNumActive = %d, MaxNumOnHold = %d, "
"MaxNumOnHoldPending = %d, MaxNumConference = %d, "
"MaxNumTransConf = %d]",
pAddressCaps->dwMaxNumActiveCalls,
pAddressCaps->dwMaxNumOnHoldCalls,
pAddressCaps->dwMaxNumOnHoldPendingCalls,
pAddressCaps->dwMaxNumConference,
pAddressCaps->dwMaxNumTransConf);
SendInfoMsg(info);
info.Format("[Supported Address() = %s]",
DescribeAddressStatus(s1, pAddressCaps->dwAddressStates));
SendInfoMsg(info);
info.Format("[Supported CallState() = %s]",
DescribeCallState(s1, pAddressCaps->dwCallStates));
SendInfoMsg(info);
info.Format("[Supported CallInfo() = %s]",
DescribeCallInfo(s1, pAddressCaps->dwCallInfoStates));
SendInfoMsg(info);
info.Format("[Call Completion Capabilities = %s]",
DescribeCallCompletion(s1, pAddressCaps->dwCallCompletionModes));
SendInfoMsg(info);
info.Format("[Call Features = %s %s]",
DescribeCallFeatures(s1, pAddressCaps->dwCallFeatures),
DescribeCallFeatures2(s2, pAddressCaps->dwCallFeatures2) );
SendInfoMsg(info);
info.Format("[Address Capabilities = %s]",
DescribeAddressCapabilities(s1, pAddressCaps->dwAddrCapFlags));
SendInfoMsg(info);
// Find out who it is
DWORD id;
loopLineGetID(id, m_pLines[LineID]->m_hLine, 0, 0,
LINECALLSELECT_LINE, "tapi/line");
info.Format("[Line ID = %ld]", id);
SendInfoMsg(info);
DWORD woid;
loopLineGetID(woid, m_pLines[LineID]->m_hLine, 0, 0,
LINECALLSELECT_LINE, "wave/out");
info.Format("[Wave Out ID = %ld]", woid);
m_pLines[LineID]->m_waveOutId = woid;
SendInfoMsg(info);
DWORD wiid;
loopLineGetID(wiid, m_pLines[LineID]->m_hLine, 0, 0,
LINECALLSELECT_LINE, "wave/in");
info.Format("[Wave In ID = %ld]", wiid);
SendInfoMsg(info);
}
delete [] pAddressCaps;
}
}
else
{
delete m_pLines[LineID]; m_pLines[LineID] = NULL;
}
}
}
delete [] pDevCaps;
}
}
if( !nOpenedLines )
{
delete[] m_pLines; m_pLines = NULL;
}
StatusChange();
}
// ----------------------------------------------------------------------------
// Return the current (first) TAPI line
TAPILine *TAPIConnection::GetTapiLine()
{
return (m_pLines && (m_FirstOpenedLine != -1)) ? m_pLines[m_FirstOpenedLine] : NULL;
}
// ----------------------------------------------------------------------------
// Tell parent that the line status has changed.
void TAPIConnection::StatusChange()
{
// Store info and SendMessage to parent which will be actioned synchronuslyouly
if (m_pMessageWnd)
m_pMessageWnd->SendMessage(WM_USER_TAPI_STATUS);
// CheckButtons()
}
// ----------------------------------------------------------------------------
// Tell parent that a info/error message is pending.
void TAPIConnection::SendInfoMsg(LPCTSTR pszCommand)
{
// Store info and SendMessage to parent which will be actioned synchronuslyouly
if (m_pMessageWnd)
{
m_strLatestInfo = pszCommand;
m_pMessageWnd->SendMessage(WM_USER_TAPI_INFO);
}
}
// ----------------------------------------------------------------------------
// Retrieve last info/error message.
LPCTSTR TAPIConnection::GetLastMessage()
{
return m_strLatestInfo;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -