📄 tsapi.cpp
字号:
// Tsapi.cpp : interface to TSAPI Tserver.
//
// This file handles the hidden TSAPI window
//
#include "stdafx.h"
#include "windowsx.h"
#include "Tsapi.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// First, there are the CTsapiDevice methods.
//
// This class is referenced by the TSAPI window class (CTsapiWnd).
// It handles:
// 1. tracking of the window that handles the TSAPI events for each device known
// by the CTsapiWnd
// 3. tracking of the monitor cross reference ID for the current monitoring session
// for each device known by the CTsapiWnd
// 2. tracking of all of the calls and connections for each device known by the
// CTsapiWnd
//
// Note that this sample only implements 1 device tracking. The CTsapiWnd here can
// only track a single device and this memory is hard-coded.
// Note that this sample hard-codes the number of calls and connections that the
// device can support.
CTsapiDevice::CTsapiDevice()
{
m_DeviceID[0] = '\0';
m_MonitorCrossRefID = 0;
m_pWnd = 0;
for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
{
// an empty call ID indicates a free entry
for(int j=0; j<MAX_DEVICES_IN_CALL; j++)
{
m_ConnIDList[i][j].callID = 0;
}
}
}
// This method takes a connection ID and creates a call entry to track this
// call. Note that the connection ID is assumed to be a Local connection ID.
// This means that it is a connection ID that includes the device that is
// stored in this record. It doesn't check to make sure this is true. It can't
// check, because the connection ID may contain a dynamic device ID, which wouldn't
// match the static device ID stored in this record.
// This method returns a "call handle" - this should be used in subsequent methods
// to refer to the particular call created here. Callers of this method should NEVER
// modify the call handle returned by this method.
long CTsapiDevice::CreateCallFromLocalConnection(ConnectionID_t & connID)
{
// This could be replaced with dynamic memory allocation, but static memory
// makes the sample easier.
for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
{
// Local connection info always goes into slot 0 for the call.
// Slot 0 always has full connection IDs, so the device ID does not
// need to be checked.
// An empty call ID indicates a free entry
if(m_ConnIDList[i][0].callID == 0)
{
// place the new connection info into the call record
m_ConnIDList[i][0].callID = connID.callID;
lstrcpy(m_ConnIDList[i][0].deviceID, connID.deviceID);
m_ConnIDList[i][0].devIDType = connID.devIDType;
return (long)(&(m_ConnIDList[i][0]));
}
}
return 0;
}
// This method takes a connection ID, finds the call that it is in and
// removes it from the device record. It returns the call handle that was
// associated with that call, but that call handle no longer refers to an
// active call.
long CTsapiDevice::RemoveCallViaConnection(ConnectionID_t & connID)
{
// This could be replaced with dynamic memory deallocation, but static memory
// makes the sample easier.
for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
{
for(int j=0; j<MAX_DEVICES_IN_CALL; j++)
{
if((m_ConnIDList[i][j].callID == connID.callID) &&
(lstrcmp(m_ConnIDList[i][j].deviceID, connID.deviceID) == 0) &&
(m_ConnIDList[i][j].devIDType == connID.devIDType))
{
// connection found - go back to first connection in call and
// free all of the connections.
for(int k=0; k<MAX_DEVICES_IN_CALL; k++)
{
// an empty call ID indicates a free entry
m_ConnIDList[i][k].callID = 0;
}
return (long)(&(m_ConnIDList[i][0]));
}
}
}
return 0;
}
// This method takes a call handle and a connection ID and associates the connection ID
// with that call handle. Subsequent requests for a call handle based on this connection ID
// can now be satisfied.
// This method returns TRUE if the connection is successfully added to the call, otherwise
// it returns FALSE.
BOOL CTsapiDevice::AddConnectionToCall(long callHandle, ConnectionID_t & connID)
{
ConnectionID_t* pConnIDList = (ConnectionID_t*)callHandle;
// Do some validation of the handle - not perfect, but we won't crash!
if((pConnIDList < &m_ConnIDList[0][0]) ||
(pConnIDList > &m_ConnIDList[MAX_CALLS_AT_DEVICE][0]) ||
(pConnIDList->callID == 0))
{
return FALSE;
}
// skip the 0 entry - this is strictly for the local connection ID and
// should be added with CreateCallFromLocalConnection()
pConnIDList++;
// attempt to place connection in call
for(int j=1; j<MAX_DEVICES_IN_CALL; j++, pConnIDList++)
{
// an empty call ID indicates a free entry
if(pConnIDList->callID == 0)
{
// place the new connection info into the call record
pConnIDList->callID = connID.callID;
lstrcpy(pConnIDList->deviceID, connID.deviceID);
pConnIDList->devIDType = connID.devIDType;
return TRUE;
}
}
return FALSE;
}
// This method takes a connection ID, finds the call that it is in and
// removes that connection ID from the call. It returns the call handle that is
// associated with that call.
long CTsapiDevice::RemoveConnectionFromCall(ConnectionID_t & connID)
{
for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
{
for(int j=0; j<MAX_DEVICES_IN_CALL; j++)
{
if((m_ConnIDList[i][j].callID == connID.callID) &&
(lstrcmp(m_ConnIDList[i][j].deviceID, connID.deviceID) == 0) &&
(m_ConnIDList[i][j].devIDType == connID.devIDType))
{
// connection found
// an empty call ID indicates a free entry
m_ConnIDList[i][j].callID = 0;
return (long)(&(m_ConnIDList[i][0]));
}
}
}
return 0;
}
// This method takes a call handle and returns the associated local connection ID.
// If the local connection ID is returned, the return value is TRUE, else it is
// FALSE and the connID argument should not be referenced.
BOOL CTsapiDevice::GetLocalConnection(long connHandle, ConnectionID_t & connID)
{
ConnectionID_t* pConnIDList = (ConnectionID_t*)connHandle;
// Do some validation of the handle - not perfect, but we won't crash!
if((pConnIDList < &m_ConnIDList[0][0]) ||
(pConnIDList > &m_ConnIDList[MAX_CALLS_AT_DEVICE][0]) ||
(pConnIDList->callID == 0))
{
return FALSE;
}
// return connection info
connID.callID = pConnIDList->callID;
lstrcpy(connID.deviceID, pConnIDList->deviceID);
connID.devIDType = pConnIDList->devIDType;
return TRUE;
}
// This method takes a call handle and connection ID and determines if the connection ID
// is the local connection ID or not.
// If it is, the return value is TRUE, else it is FALSE.
// An invalid call handle also returns FALSE.
BOOL CTsapiDevice::IsLocalConnection(long connHandle, ConnectionID_t & connID)
{
ConnectionID_t* pConnIDList = (ConnectionID_t*)connHandle;
// Do some validation of the handle - not perfect, but we won't crash!
if((pConnIDList < &m_ConnIDList[0][0]) ||
(pConnIDList > &m_ConnIDList[MAX_CALLS_AT_DEVICE][0]) ||
(pConnIDList->callID == 0))
{
return FALSE;
}
if((pConnIDList->callID == connID.callID) &&
(lstrcmp(pConnIDList->deviceID, connID.deviceID) == 0) &&
(pConnIDList->devIDType == connID.devIDType))
{
return TRUE;
}
return FALSE;
}
// This method takes a connection ID and returns the call handle for the call that
// it is in.
// IF exactMatch is TRUE, the full connection ID is used to find the call.
// IF exactMatch is FALSE, only the call ID member of the connection ID is used to
// find the call.
// Should use the exactMatch = TRUE case whenever possbile. The non-exactMatch
// case assumes that the call ID is the same for all connections in the call. This
// is not always safe to do (as not all PBX Drivers guarantee this), but is
// sometimes necessary.
long CTsapiDevice::GetCallHandle(ConnectionID_t & connID, BOOL exactMatch)
{
if(exactMatch)
{
for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
{
for(int j=0; j<MAX_DEVICES_IN_CALL; j++)
{
if((m_ConnIDList[i][j].callID == connID.callID) &&
(lstrcmp(m_ConnIDList[i][j].deviceID, connID.deviceID) == 0) &&
(m_ConnIDList[i][j].devIDType == connID.devIDType))
{
return (long)(&(m_ConnIDList[i][0]));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -