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

📄 tapiconn._cp

📁 串口调试助手的源代码
💻 _CP
📖 第 1 页 / 共 5 页
字号:
	// Handle the line messages.
	switch (dwMsg)
	{
	case LINE_CALLSTATE:
		DoLineCallState(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2,
			dwParam3);
		break;

	case LINE_CLOSE:
		DoLineClose(dwDevice, dwMsg, dwCallbackInstance,
			dwParam1, dwParam2, dwParam3);
		break;
/*
		// Line has been shut down.  
		ASSERT(m_this);
		m_this->m_hLine = NULL;
		m_this->m_hCall = NULL;
		m_this->HangupCall();	// all handles invalidated by this time
		break;
*/
	case LINE_LINEDEVSTATE:
		DoLineDevState(dwDevice, dwMsg, dwCallbackInstance,
			dwParam1, dwParam2, dwParam3);
		break;

	case LINE_REPLY:
		DoLineReply(dwDevice, dwMsg, dwCallbackInstance,
			dwParam1, dwParam2, dwParam3);
		break;
/*		
		if ((long)dwParam2 != TAPISUCCESS)
			TRACE0("LINE_REPLY error\n");
		else
			TRACE0("LINE_REPLY: successfully replied.\n");
		break;*/

	case LINE_CREATE:
		DoLineCreate(dwDevice, dwMsg, dwCallbackInstance,
			dwParam1, dwParam2, dwParam3);
		break;
/*
		ASSERT(m_this);
		if (m_this->m_dwNumDevs <= dwParam1)
			m_this->m_dwNumDevs = dwParam1+1;
		break;
*/
	default:
		TRACE0("lineCallbackFunc message ignored\n");
		break;
	}
}

//
//  FUNCTION: DoLineCallState(..)
//
//  PURPOSE: Handle LINE_CALLSTATE asynchronous messages.
//
void	CTapiConnection::DoLineCallState(
	DWORD  dwDevice, DWORD  dwMessage, DWORD  dwCallbackInstance,
	DWORD  dwParam1, DWORD  dwParam2, DWORD  dwParam3)
{
	// Error if this CALLSTATE doesn't apply to our call in progress.
	if ((HCALL)dwDevice != m_this->m_hCall)
	{
		TRACE0("LINE_CALLSTATE: Unknown device ID ");
//		return;
	}

	// This sets the global g_dwCallState variable so if we are waiting
	// for a specific call state change, we will know when it happens.
	m_dwCallState = dwParam1;
	m_bCallStateReceived = TRUE;

	// dwParam3 contains changes to LINECALLPRIVILEGE, if there are any.
	switch (dwParam3)
	{
	case  0:
		break;	// no change to call state

	// close line if we are made monitor.  Shouldn't happen!
	case LINECALLPRIVILEGE_MONITOR:
		TRACE0("line given monitor privilege; closing\n");
//		m_this->HangupCall();
		return;

	// close line if we are made owner.  Shouldn't happen!
	case LINECALLPRIVILEGE_OWNER:
		TRACE0("line given owner privilege; closing\n");
//		m_this->HangupCall();
		break;

	default:	// Shouldn't happen!  All cases handled.
		TRACE0("Unknown LINECALLPRIVILEGE message: closing\n");
		m_this->HangupCall();
		return;
	}

	// dwParam1 is the specific CALLSTATE change that is occurring.
	switch (dwParam1)
	{
	case LINECALLSTATE_DIALTONE:
		TRACE0("Dial Tone\n");
		break;

	case LINECALLSTATE_DIALING:
		TRACE0("Dialing\n");
		break;

	case LINECALLSTATE_PROCEEDING:
		TRACE0("Proceeding\n");
		break;

	case LINECALLSTATE_RINGBACK:
		TRACE0("RingBack\n");
		break;

	case LINECALLSTATE_BUSY:
		TRACE0("Line busy, shutting down\n");
		m_this->HangupCall();
		break;

	case LINECALLSTATE_IDLE:
		TRACE0("Line idle\n");
		m_this->HangupCall();
		break;

	case LINECALLSTATE_OFFERING:
		// The call is being offered, signaling the arrival
		// of a  new call.  check if we are the owner of the call, and if we are,
		// then answer it.
		if (dwParam3 == LINECALLPRIVILEGE_OWNER)
		{
			m_this->WaitForReply(::lineAnswer(m_this->m_hCall = (HCALL)dwDevice, NULL, 0));
		}	// end if (we own this call)
		break;

	case LINECALLSTATE_SPECIALINFO:
		TRACE0("Special Info, probably couldn't dial number\n");
		m_this->HangupCall();
		break;

	case LINECALLSTATE_DISCONNECTED:
	{
		LPSTR	pszReasonDisconnected;

		switch (dwParam2)
		{
		case LINEDISCONNECTMODE_NORMAL:
			pszReasonDisconnected = "Remote Party Disconnected";
			break;

		case LINEDISCONNECTMODE_UNKNOWN:
			pszReasonDisconnected = "Disconnected: Unknown reason";
			break;

		case LINEDISCONNECTMODE_REJECT:
			pszReasonDisconnected = "Remote Party rejected call";
			break;

		case LINEDISCONNECTMODE_PICKUP:
			pszReasonDisconnected = 
				"Disconnected: Local phone picked up";
			break;

		case LINEDISCONNECTMODE_FORWARDED:
			pszReasonDisconnected = "Disconnected: Forwarded";
			break;

		case LINEDISCONNECTMODE_BUSY:
			pszReasonDisconnected = "Disconnected: Busy";
			break;

		case LINEDISCONNECTMODE_NOANSWER:
			pszReasonDisconnected = "Disconnected: No Answer";
			break;

		case LINEDISCONNECTMODE_BADADDRESS:
			pszReasonDisconnected = "Disconnected: Bad Address";
			break;

		case LINEDISCONNECTMODE_UNREACHABLE:
			pszReasonDisconnected = "Disconnected: Unreachable";
			break;

		case LINEDISCONNECTMODE_CONGESTION:
			pszReasonDisconnected = "Disconnected: Congestion";
			break;

		case LINEDISCONNECTMODE_INCOMPATIBLE:
			pszReasonDisconnected = "Disconnected: Incompatible";
			break;

		case LINEDISCONNECTMODE_UNAVAIL:
			pszReasonDisconnected = "Disconnected: Unavail";
			break;

		case LINEDISCONNECTMODE_NODIALTONE:
			pszReasonDisconnected = "Disconnected: No Dial Tone";
			break;

		default:
			pszReasonDisconnected = 
				"Disconnected: LINECALLSTATE; Bad Reason";
			break;
		}

		TRACE0(pszReasonDisconnected);
		TRACE0("\n");
		m_this->HangupCall();
		break;
	}

	case LINECALLSTATE_CONNECTED:	// CONNECTED!!!
	{
		LPVARSTRING	lpVarString = NULL;
		DWORD	dwSizeofVarString = sizeof(VARSTRING) + 1024;
		HANDLE	hCommFile = NULL;
		long	lReturn;

		// Very first, make sure this isn't a duplicated message.
		// A CALLSTATE message can be sent whenever there is a
		// change to the capabilities of a line, meaning that it is
		// possible to receive multiple CONNECTED messages per call.
		// The CONNECTED CALLSTATE message is the only one in TapiComm
		// where it would cause problems if it where sent more
		// than once.

		if (m_this->m_bConnected)
			break;

		m_this->m_bConnected = TRUE;

		// Get the handle to the comm port from the driver so we can start
		// communicating.  This is returned in a LPVARSTRING structure.
		do
		{
			// Allocate the VARSTRING structure
			lpVarString = (LPVARSTRING)CheckAndReAllocBuffer((LPVOID)lpVarString,
                    dwSizeofVarString);

			if (lpVarString == NULL)
				goto  LABEL_ERRORCONNECTING;

			// Fill the VARSTRING structure
			lReturn = ::lineGetID(0, 0, m_this->m_hCall, LINECALLSELECT_CALL,
				lpVarString, "comm/datamodem");

			if (m_this->HandleLineErr(lReturn))
				; // Still need to check if structure was big enough.
			else
			{
				OutputDebugLineError(lReturn, 
					"lineGetID unhandled error: ");
				goto  LABEL_ERRORCONNECTING;
			}

			// If the VARSTRING wasn't big enough, loop again.
			if ((lpVarString->dwNeededSize) > (lpVarString->dwTotalSize))
			{
				dwSizeofVarString = lpVarString->dwNeededSize;
				lReturn = -1;	// Lets loop again.
			}
		}
		while (lReturn != TAPISUCCESS);

		TRACE0("Connected!  Starting communications!\n");

		// Again, the handle to the comm port is contained in a
		// LPVARSTRING structure.  Thus, the handle is the very first
		// thing after the end of the structure.  Note that the name of
		// the comm port is right after the handle, but I don't want it.
		hCommFile = 
			*((LPHANDLE)((LPBYTE)lpVarString +
				lpVarString->dwStringOffset));

		// Started communications!
		if (m_this->StartComm(hCommFile))
		{
//			char	szBuff[300];

//			wsprintf(szBuff, "Connected to '%s'", g_szDisplayableAddress);
//			UpdateStatusBar(szBuff, 1, 0);

			::LocalFree(lpVarString);
			break;
		}

		// Couldn't start communications.  Clean up instead.
	LABEL_ERRORCONNECTING:

		// Its very important that we close all Win32 handles.
		// The CommCode module is responsible for closing the hCommFile
		// handle if it succeeds in starting communications.
		if (hCommFile)
			CloseHandle(hCommFile);

		m_this->HangupCall();
		{
//			char	szBuff[300];
//			wsprintf(szBuff,"Failed to Connect to '%s'",
//				g_szDisplayableAddress);
//			UpdateStatusBar(szBuff, 1, 0);
		}

		if (lpVarString)
			::LocalFree(lpVarString);

		break;
	}

	default:
		TRACE0("Unhandled LINECALLSTATE message\n");
		break;
	}
}

//
//  FUNCTION: HandleLineErr(long)
//
//  PURPOSE: Handle several of the standard LINEERR errors
//
BOOL	CTapiConnection::HandleLineErr(long  lLineErr)
{
	BOOL	bRet = FALSE;

	// lLineErr is really an async request ID, not an error.
	if (lLineErr > TAPISUCCESS)
		return  bRet;

	// All we do is dispatch the correct error handler.
	switch (lLineErr)
	{
	case TAPISUCCESS:
		bRet = TRUE;
		break;

	case LINEERR_INVALCARD:
	case LINEERR_INVALLOCATION:
	case LINEERR_INIFILECORRUPT:
		TRACE0("The values in the INI file are invalid.\n");
		break;

	case LINEERR_NODRIVER:
		TRACE0("There is a problem with your Telephony device driver.\n");
		break;

	case LINEERR_REINIT:
		ShutdownTAPI();
		break;

	case LINEERR_NOMULTIPLEINSTANCE:
		TRACE0("Remove one of your copies of your Telephony driver.\n");
		break;

	case LINEERR_NOMEM:
		TRACE0("Out of memory. Cancelling action.\n");
		break;

	case LINEERR_OPERATIONFAILED:
		TRACE0("The TAPI operation failed.\n");
		break;

	case LINEERR_RESOURCEUNAVAIL:
		TRACE0("A TAPI resource is unavailable at this time.\n");
		break;

	// Unhandled errors fail.
	default:
		break;
	}
	return  bRet;
}

//
//  FUNCTION: BOOL HangupCall()
//
//  PURPOSE: Hangup the call in progress if it exists.
//
BOOL	CTapiConnection::HangupCall()
{         
	LPLINECALLSTATUS	pLineCallStatus = NULL;
	long	lReturn;

	// Prevent HangupCall re-entrancy problems.
	if (m_bStoppingCall)
		return  TRUE;

	// If Tapi is not being used right now, then the call is hung up.
	if (!m_bTapiInUse)
		return  TRUE;

	m_bStoppingCall = TRUE;

	TRACE0("Stopping Call in progress\n");

	// If there is a call in progress, drop and deallocate it.
	if (m_hCall)
	{
		pLineCallStatus = (LPLINECALLSTATUS)::malloc(sizeof(LINECALLSTATUS));

		if (!pLineCallStatus)
		{
			ShutdownTAPI();
			m_bStoppingCall = FALSE;
			return  FALSE;
		}
		lReturn = ::lineGetCallStatus(m_hCall, pLineCallStatus);

		// Only drop the call when the line is not IDLE.
		if (!((pLineCallStatus->dwCallState) & LINECALLSTATE_IDLE))
		{
			WaitForReply(::lineDrop(m_hCall, NULL, 0));
			TRACE0("Call Dropped.\n");
		}

		// The call is now idle. Deallocate it!
		do
		{
			lReturn = ::lineDeallocateCall(m_hCall);
			if (HandleLineErr(lReturn))
				continue;
			else
			{
				TRACE0("lineDeallocateCall unhandled error\n");
				break;
			}
		}
		while (lReturn != TAPISUCCESS);

		TRACE0("Call Deallocated.\n");
	}

	// if we have a line open, close it.
	if (m_hLine)
	{
		lReturn = ::lineClose(m_hLine);
		if (!HandleLineErr(lReturn))
			TRACE0("lineClose unhandled error\n");

		TRACE0("Line Closed.\n");
	}

	// Clean up.
	m_hCall = NULL;
	m_hLine = NULL;
	m_bTapiInUse = FALSE;
	m_bStoppingCall = FALSE; // allow HangupCall to be called again.

	// Need to free buffer returned from lineGetCallStatus
	if (pLineCallStatus)
		::free(pLineCallStatus);
        
	TRACE0("Call stopped\n");
	return  TRUE;
}

//
//  FUNCTION: BOOL ShutdownTAPI()
//
//  PURPOSE: Shuts down all use of TAPI
//
BOOL CTapiConnection::ShutdownTAPI()
{
	long	lReturn;

	// If we aren't initialized, then Shutdown is unnecessary.
	if (m_hLineApp == NULL)
		return  TRUE;

	// Prevent ShutdownTAPI re-entrancy problems.
	if (m_bShuttingDown)
		return  TRUE;

	m_bShuttingDown = TRUE;
	HangupCall();
    
	do
	{
		lReturn = ::lineShutdown(m_hLineApp);
		if (HandleLineErr(lReturn))
			continue;
		else
		{

⌨️ 快捷键说明

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