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

📄 tapiline.cpp

📁 串口调试助手的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Written by JHCC

#include "stdafx.h"

#include "TAPIx.h"
#include "TAPIErr.h"
#include "comm.h"

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

// ---- CTAPILine ----
IMPLEMENT_SERIAL(CTAPILine, CObject, 0 /* schema number*/ )

CTAPILine::CTAPILine()
{
	m_dwDeviceID = 0;
	m_lpLineDevCaps = NULL;
	m_hLine = 0;
	m_dwAsyncID = (DWORD)-1;
	m_WaitReplyType = REPLY_NONE;

	m_hCall = (HCALL)-1;
	m_bConnected = FALSE;
	m_pComm = NULL;
}

CTAPILine::~CTAPILine()
{
	if (m_lpLineDevCaps != NULL)
		delete  m_lpLineDevCaps;
}

BOOL	CTAPILine::Create(DWORD  dwDeviceID, DWORD  dwAPILowVersion, DWORD  dwAPIHighVersion)
{
	m_dwDeviceID = dwDeviceID;
	if ((m_dwAPIVersion = NegotiateLegacyAPIVersion(dwAPIHighVersion, dwAPIHighVersion)) == 0)
		return  FALSE;
	if ((m_dwAPILegacyVersion = NegotiateLegacyAPIVersion(dwAPILowVersion, dwAPIHighVersion)) == 0)
		return  FALSE;
	m_dwExtVersion = 0;

	long	lReturn = ::lineGetIcon(m_dwDeviceID, NULL/*comm*/, &m_hLineIcon);
	if (lReturn != TAPISUCCESS)
		m_hLineIcon = ::AfxGetApp()->LoadStandardIcon(IDI_QUESTION);

	if ((m_lpLineDevCaps = I_lineGetDevCaps()) == NULL)
	{
		::MessageBox(NULL, "Error on Requested line",
			"Unable to Use Line", MB_OK);
		return  FALSE;
	}
	return  TRUE;
}

BOOL	CTAPILine::IsSupportVoice(void)
{
	return  BOOL(m_lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE);
}

BOOL	CTAPILine::IsSupportDataModem(void)
{
	return  BOOL(m_lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM);
}

BOOL	CTAPILine::IsSupportMakeCall(void)
{
	return  BOOL(m_lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL);
}

DWORD	CTAPILine::GetDevCapFlags(void)
{
	return  m_lpLineDevCaps->dwDevCapFlags;
}

// Negotiate an API Version to use for a specific device.
// This wrapper function not only negotiates the API,
// but also handles LINEERR errors that can occur while negotiating.
DWORD	CTAPILine::NegotiateLegacyAPIVersion(DWORD  dwAPILowVersion, DWORD  dwAPIHighVersion)
{
	ASSERT(dwAPIHighVersion != 0);
	ASSERT(dwAPILowVersion != 0);

	DWORD	dwLocalAPIVersion;
	long	lReturn;

	do
	{
		LINEEXTENSIONID	LineExtensionID;
		lReturn = ::lineNegotiateAPIVersion(CTAPIConnection::m_hLineApp, m_dwDeviceID,
			dwAPILowVersion, dwAPIHighVersion,
			&dwLocalAPIVersion, &LineExtensionID);

		switch (lReturn)
		{
		case LINEERR_INCOMPATIBLEAPIVERSION:
			TRACE0("lineNegotiateAPIVersion, INCOMPATIBLEAPIVERSION.\n");
			return  0;

		default:
			if (!CTAPIError::HandleLineErr(lReturn))
			{
				TRACE1("lineNegotiateAPIVersion unhandled error: %lx\n", lReturn);
				return  0;
			}
		}
	}
	while (lReturn != TAPISUCCESS);

	return  dwLocalAPIVersion;
}

// Open the Line for an outgoing call.
BOOL	CTAPILine::Open(void)
{
	if (m_hLine)	// line is not opened
	{
		TRACE0("Line is already Opened !\n");
		return  FALSE;
	}

	long	lReturn;
	do
	{
		lReturn = ::lineOpen(CTAPIConnection::m_hLineApp, m_dwDeviceID, &m_hLine,
			m_dwAPIVersion, m_dwExtVersion, 0,
			LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM, NULL);

		switch (lReturn)
		{
		case LINEERR_ALLOCATED:
		case LINEERR_RESOURCEUNAVAIL:
			::MessageBox(NULL,
				"Line is already in use by a non-TAPI application "
				"or by another TAPI Service Provider.",
				"Unable to Use Line", MB_OK);
			return  FALSE;

		default:
			if (!CTAPIError::HandleLineErr(lReturn))
			{
				TRACE1("lineOpen unhandled error: %lu\n", lReturn);
				::MessageBox(NULL,
					"Error on Requested line",
					"Unable to Use Line",MB_OK);
				return  FALSE;
			}
			break;
		}
	}
	while (lReturn != TAPISUCCESS);

	// Tell the service provider that we want all notifications that
	// have anything to do with this line.
	do
	{
		// Set the messages we are interested in.
		// Note that while most applications aren't really interested
		// in dealing with all of the possible messages, its interesting
		// to see which come through the callback for testing purposes.
		lReturn = ::lineSetStatusMessages(m_hLine,
			LINEDEVSTATE_OTHER	|
			LINEDEVSTATE_RINGING	|
			LINEDEVSTATE_CONNECTED	|	// Important state!
			LINEDEVSTATE_DISCONNECTED	|	// Important state!
			LINEDEVSTATE_MSGWAITON	|
			LINEDEVSTATE_MSGWAITOFF	|
			LINEDEVSTATE_INSERVICE	|
			LINEDEVSTATE_OUTOFSERVICE	|	// Important state!
			LINEDEVSTATE_MAINTENANCE	|	// Important state!
			LINEDEVSTATE_OPEN	|
			LINEDEVSTATE_CLOSE	|
			LINEDEVSTATE_NUMCALLS	|
			LINEDEVSTATE_NUMCOMPLETIONS	|
			LINEDEVSTATE_TERMINALS	|
			LINEDEVSTATE_ROAMMODE	|
			LINEDEVSTATE_BATTERY	|
			LINEDEVSTATE_SIGNAL	|
			LINEDEVSTATE_DEVSPECIFIC	|
			LINEDEVSTATE_REINIT	|	// Not allowed to disable this.
			LINEDEVSTATE_LOCK	|
			LINEDEVSTATE_CAPSCHANGE	|
			LINEDEVSTATE_CONFIGCHANGE	|
			LINEDEVSTATE_COMPLCANCEL,

			LINEADDRESSSTATE_OTHER	|
			LINEADDRESSSTATE_DEVSPECIFIC	|
			LINEADDRESSSTATE_INUSEZERO	|
			LINEADDRESSSTATE_INUSEONE	|
			LINEADDRESSSTATE_INUSEMANY	|
			LINEADDRESSSTATE_NUMCALLS	|
			LINEADDRESSSTATE_FORWARD	|
			LINEADDRESSSTATE_TERMINALS	|
			LINEADDRESSSTATE_CAPSCHANGE);

		if (CTAPIError::HandleLineErr(lReturn))
			continue;
		else
		{
			// If we do get an unhandled problem, we don't care.
			// We just won't get notifications.
			TRACE1("lineSetStatusMessages unhandled error: %lu\n", lReturn);
			break;
		}
	}
	while (lReturn != TAPISUCCESS);

	return  TRUE;
}

BOOL	CTAPILine::Close(void)
{
	if (m_hLine == 0)
		return  TRUE;

	// if we have a line open, close it.
	long	lReturn;
	do
	{
		lReturn = ::lineClose(m_hLine);
		if (!CTAPIError::HandleLineErr(lReturn))
		{
			TRACE1("lineClose unhandled error: %lu\n", lReturn);
		}
	}
	while (lReturn != TAPISUCCESS);
	m_hLine = 0;
	TRACE0("Line Closed.\n");
	return  TRUE;
}

// Allocates and fills a LINECALLPARAMS structure
// If a non-NULL lpCallParams is passed in, it must have been allocated
// with LocalAlloc, and can potentially be freed and reallocated.  It must
// also have the dwTotalSize field correctly set.
LPLINECALLPARAMS	CTAPILine::CreateCallParams(LPCTSTR  lpszDisplayableAddress)
{
	if (lpszDisplayableAddress == NULL)
		lpszDisplayableAddress = _T("");
        
	int	nSizeDisplayableAddress = ::lstrlen(lpszDisplayableAddress) + 1;
                          
	LPLINECALLPARAMS	lpCallParams = (LPLINECALLPARAMS)new  BYTE[sizeof(LINECALLPARAMS) + nSizeDisplayableAddress];
	if (lpCallParams == NULL)
		return  NULL;

	memset(lpCallParams, 0, sizeof(LINECALLPARAMS));
	lpCallParams->dwTotalSize = sizeof(LINECALLPARAMS) + nSizeDisplayableAddress;
	// This is where we configure the line for DATAMODEM usage.
	lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
	lpCallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM;//LINEMEDIAMODE_INTERACTIVEVOICE;

	// This specifies that we want to use only IDLE calls and
	// don't want to cut into a call that might not be IDLE (ie, in use).
	lpCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
                                    
	// if there are multiple addresses on line, use first anyway.
	// It will take a more complex application than a simple tty app
	// to use multiple addresses on a line anyway.
	lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
	lpCallParams->dwAddressID = 0;

	// Since we don't know where we originated, leave these blank.
	lpCallParams->dwOrigAddressSize = 0;
	lpCallParams->dwOrigAddressOffset = 0;
    
	// Unimodem ignores these values.
	(lpCallParams->DialParams).dwDialSpeed = 0;
	(lpCallParams->DialParams).dwDigitDuration = 0;
	(lpCallParams->DialParams).dwDialPause = 0;
	(lpCallParams->DialParams).dwWaitForDialtone = 0;
    
	// Address we are dialing.
	lpCallParams->dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
	lpCallParams->dwDisplayableAddressSize = nSizeDisplayableAddress;
	lstrcpy((LPSTR)lpCallParams + sizeof(LINECALLPARAMS),
		lpszDisplayableAddress);

	return  lpCallParams;
}

//**************************************************
// line API Wrapper Functions.
//**************************************************

// Gets a LINEDEVCAPS structure for the specified line.
// This function is a wrapper around lineGetDevCaps to make it easy
// to handle the variable sized structure and any errors received.
LPLINEDEVCAPS	CTAPILine::I_lineGetDevCaps(void)
{
	// Allocate enough space for the structure plus 1024.
	int	nSizeLineDevCaps = sizeof(LINEDEVCAPS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		LPLINEDEVCAPS	lpLineDevCaps = (LPLINEDEVCAPS)new  BYTE[nSizeLineDevCaps];
		if (lpLineDevCaps == NULL)
			return  NULL;
		lpLineDevCaps->dwTotalSize = nSizeLineDevCaps;

		// Make the call to fill the structure.
		do
		{            
			lReturn = ::lineGetDevCaps(CTAPIConnection::m_hLineApp,
					m_dwDeviceID, m_dwAPIVersion,
					m_dwExtVersion, lpLineDevCaps);

			if (CTAPIError::HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE0("lineGetDevCaps unhandled error\n");
				delete  lpLineDevCaps;
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

		// If the buffer was big enough, then succeed.
		if ((lpLineDevCaps->dwNeededSize) <= (lpLineDevCaps->dwTotalSize))
		{
			return  lpLineDevCaps;
		}
		else
		{
			// Buffer wasn't big enough.  Make it bigger and try again.
			nSizeLineDevCaps = lpLineDevCaps->dwNeededSize;
			delete  lpLineDevCaps;
		}
	}
}

// Retrieve a LINEADDRESSSTATUS structure for the specified line.
// This function is a wrapper around lineGetAddressStatus to make it easy
// to handle the variable sized structure and any errors received.
LPLINEADDRESSSTATUS	CTAPILine::I_lineGetAddressStatus(DWORD  dwAddressID)
{
	int	nSizeLineAddressStatus = sizeof(LINEADDRESSSTATUS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		LPLINEADDRESSSTATUS	lpLineAddressStatus = 
			(LPLINEADDRESSSTATUS)new  BYTE[nSizeLineAddressStatus];
		if (lpLineAddressStatus == NULL)
		{
			delete  lpLineAddressStatus;
			return  NULL;
		}
		lpLineAddressStatus->dwTotalSize = nSizeLineAddressStatus;

		// Make the call to fill the structure.
		do
		{            
			lReturn = ::lineGetAddressStatus(m_hLine, dwAddressID, lpLineAddressStatus);

			if (CTAPIError::HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE1("lineGetAddressStatus unhandled error: %lu\n", lReturn);
				delete  lpLineAddressStatus;
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

		// If the buffer was big enough, then succeed.
		if ((lpLineAddressStatus->dwNeededSize) <= 
			(lpLineAddressStatus->dwTotalSize))
		{
			return  lpLineAddressStatus;
		}
		else
		{
			// Buffer wasn't big enough.  Make it bigger and try again.
			nSizeLineAddressStatus = lpLineAddressStatus->dwNeededSize;
			delete  lpLineAddressStatus;
		}
	}
}

// Retrieve a LINECALLSTATUS structure for the specified line.
// This function is a wrapper around lineGetCallStatus to make it easy
// to handle the variable sized structure and any errors received.
LPLINECALLSTATUS	CTAPILine::I_lineGetCallStatus(HCALL  hCall)
{
	int	nSizeLineCallStatus = sizeof(LINECALLSTATUS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		LPLINECALLSTATUS	lpLineCallStatus =
			(LPLINECALLSTATUS)new  BYTE[nSizeLineCallStatus];
		if (lpLineCallStatus == NULL)
			return  NULL;
		lpLineCallStatus->dwTotalSize = nSizeLineCallStatus;

		// Make the call to fill the structure.
		do
		{
			lReturn = ::lineGetCallStatus(hCall, lpLineCallStatus);

			if (!CTAPIError::HandleLineErr(lReturn))
			{
				TRACE1("lineGetCallStatus unhandled error: %lu", lReturn);
				delete  lpLineCallStatus;
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

		// If the buffer was big enough, then succeed.
		if ((lpLineCallStatus->dwNeededSize) <= 
			(lpLineCallStatus->dwTotalSize))
		{
			return  lpLineCallStatus;
		}
		else
		{
			// Buffer wasn't big enough.  Make it bigger and try again.
			nSizeLineCallStatus = lpLineCallStatus->dwNeededSize;
			delete  lpLineCallStatus;
		}
	}
}

// Retrieve a LINEADDRESSCAPS structure for the specified line.
// This function is a wrapper around lineGetAddressCaps to make it easy
// to handle the variable sized structure and any errors received.
LPLINEADDRESSCAPS	CTAPILine::I_lineGetAddressCaps(DWORD  dwAddressID)
{
	int	nSizeLineAddressCaps = sizeof(LINEADDRESSCAPS) + 1024;
	long	lReturn;
    
	// Continue this loop until the structure is big enough.
	while (TRUE)
	{
		// Make sure the buffer exists, is valid and big enough.
		LPLINEADDRESSCAPS	lpLineAddressCaps = 
			(LPLINEADDRESSCAPS)new  BYTE[nSizeLineAddressCaps];
		if (lpLineAddressCaps == NULL)
			return  NULL;

		lpLineAddressCaps->dwTotalSize = nSizeLineAddressCaps;

		// Make the call to fill the structure.
		do
		{
			lReturn = ::lineGetAddressCaps(CTAPIConnection::m_hLineApp,
				m_dwDeviceID, dwAddressID,
				m_dwAPIVersion, m_dwExtVersion,
				lpLineAddressCaps);

			if (CTAPIError::HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE0("lineGetAddressCaps unhandled error\n");
				delete  lpLineAddressCaps;
				return  NULL;
			}
		}
		while (lReturn != TAPISUCCESS);

⌨️ 快捷键说明

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