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

📄 tapiline.cpp

📁 TAPI编程应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// tapiline.cpp : implementation file  for CTapiLine class
// (c) Dialogic corp 1995, 1996


#include "stdafx.h"
#include <tapi.h>
#include "tapiapp.h"
#include "tapiline.h"
#include "tapicall.h"
#include "wavstate.h"		// temporarily to see if there is a conflict

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTapiLine

IMPLEMENT_DYNCREATE(CTapiLine, CObject)
//{{AFX_MSG_MAP(CTapiApp)
	// NOTE - the ClassWizard will add and remove mapping macros here.
	//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG

// Default constructor - just constructs the CTapiLine object
CTapiLine::CTapiLine()
{
// Do whatever initalization is needed	
	m_hLine = NULL;								
	m_uiWaveInID = 0xffff;
	m_uiWaveOutID = 0xffff;
	m_bRemote = FALSE;
}

CTapiLine::CTapiLine(DWORD dwLineID)
{
// Do whatever initalization is needed	
	m_hLine = NULL;
	m_pApp = (CTapiApp *) AfxGetApp();
	m_dwLineID = dwLineID;
	m_lpCallParms = NULL;
	m_pActiveCall = NULL;
	m_hCallSem = NULL;
	m_uiWaveInID = 0xffff;
	m_uiWaveOutID = 0xffff;
	m_bRemote = FALSE;
	//DWORD dwrc = ctlLineOpen(dwLineID);
}

CTapiLine::~CTapiLine()
{
	TRACE("*** TALKER32 ***: Calling destructor for line %d\n", m_dwLineID);
	ctlLineClose();
	CloseHandle(m_hCallSem);
	m_hCallSem = NULL;
	TRACE("*** TALKER32 ***: exiting destructor\n");
}

DWORD CTapiLine::ctlLineOpen(DWORD dwLineID)
{
	DWORD dwrc;
	LINEEXTENSIONID eidExtID;
	LPLINEDEVCAPS lpDevCaps;

	m_bRemote = FALSE;
	m_dwExtVersion = NULL;
	m_dwApiVersion = NULL;
	if(m_hLine != NULL) return 0L;
    dwrc = (DWORD) lineNegotiateAPIVersion(m_pApp->m_hApp, dwLineID, 
    		0x1000, CURRENT_TAPI_VERSION, &m_dwApiVersion, &eidExtID);
 //   		TAPI_VERSION1_3, TAPI_VERSION1_4, &m_dwApiVersion, &eidExtID);
	if(dwrc) return dwrc;		// what to do with Ext ID???

	if(dwrc = lineNegotiateExtVersion(m_pApp->m_hApp, dwLineID, 
    m_dwApiVersion, 0, 0xfffffff, &m_dwExtVersion)) m_dwExtVersion = NULL;
	m_dwExtVersion = NULL;
	if(dwrc = (DWORD) lineOpen(m_pApp->m_hApp, dwLineID, &m_hLine, 
    	m_dwApiVersion, m_dwExtVersion, NULL, //DWORD dwCallbackInstance, 
    	//LINECALLPRIVILEGE_MONITOR | LINECALLPRIVILEGE_OWNER, 
    	LINECALLPRIVILEGE_OWNER, 
    	LINEMEDIAMODE_INTERACTIVEVOICE, NULL))
	{
		m_hLine = NULL;
		return dwrc;
	}
	// Get the WAVE IDs
	m_csName.Empty();
	ctlGetWaveDeviceID(WAVEIN);	
	ctlGetWaveDeviceID(WAVEOUT);	
	// Get CAPS to determine name & other things
	if(!(dwrc = ctlLineGetCaps(&lpDevCaps)))
	{
		m_csName += (LPCTSTR)((LPSTR)(lpDevCaps)+lpDevCaps->dwLineNameOffset);
//		bRemote = ::IsLineRemote(lpDevCaps);	// find out if line is remote
		delete lpDevCaps;
	}

	m_hCallSem = CreateMutex(NULL, FALSE, "TALKER32_LINE_CALLS");
	if(m_hCallSem == NULL)	return 0xffffffff;
	return dwrc;
}

DWORD CTapiLine::ctlLineClose()
{
	CString csTemp;

	if(m_hLine == NULL) return NULL;
	DWORD dwrc = (DWORD) lineClose(m_hLine);
	if(dwrc) 
	{
		csTemp.Format("lineClose for line %d failed reason=%lx", m_dwLineID, dwrc);
		AfxMessageBox(csTemp);
		return dwrc;
	}
	ctlPurgeCalls();
	m_hLine = 0L;
	m_dwLineID = 0L;
	m_bRemote = FALSE;
	return dwrc;
}

DWORD CTapiLine::ctlLineGetCaps(LPLINEDEVCAPS *lppDevCaps)
{
	DWORD dwrc, i;
	LPLINEDEVCAPS lpDevCaps;
	DWORD dwInitSize = sizeof(LINEDEVCAPS) + 2048;

	for(i = 0; i< 2; i++)
	{
    	if (NULL == (lpDevCaps = (LPLINEDEVCAPS) new char[dwInitSize]))
		{
        	MessageBox(NULL, "Memory alloc for devcaps failed", NULL, MB_ICONSTOP);
			return 0xffffffff;
		}
    	lpDevCaps->dwTotalSize = dwInitSize;

    	// get line capability info 
    	if(!(dwrc = (DWORD) lineGetDevCaps(m_pApp->m_hApp, m_dwLineID,
	    		 m_dwApiVersion,0,lpDevCaps)))
	    {		 				 
 			if(lpDevCaps->dwTotalSize >= lpDevCaps->dwNeededSize) break; // Done	
	    	dwInitSize = lpDevCaps->dwNeededSize;		// More needed
		}
    	delete lpDevCaps; 
		if(dwrc) break;
	}            
	if(!dwrc) *lppDevCaps = lpDevCaps;		// The app MUST delete the structure
	return dwrc;
}

// lineMakeCall wrapper
LONG CTapiLine::ctlLineMakeCall(LPCSTR lpDestAddress, DWORD dwCountryCode)
{
	LONG lrc;

	// need to protect against early return from MakeCall(possible case;pAsync is not yet in the que,REPLY from 
	// MakeCall already arrived. Set some semaphore to make REPLY wait??
	// Allocate new call object, set it up for MAKING before calling TAPI
	lrc = AddCall();
	if(lrc || m_pActiveCall == NULL)
	{
		TRACE("*** TALKER32 ***: AddCall failed\n");
		return lrc;
	}
	m_pActiveCall->UpdateCallState(MAKING, OUTBOUND);
	//m_pActiveCall->SetLine(this);			
	lrc = lineMakeCall(m_hLine, &(m_pActiveCall->m_hCall), lpDestAddress, dwCountryCode, m_lpCallParms);
	if(lrc < 0) 
	{						// need to report an error
		TRACE("*** TALKER32 ***: MakeCall failed on line %d\n", m_dwLineID);
		RemoveCall();
		return lrc;
	}
	//m_pActiveCall->m_hCall = hCall;
	TRACE("*** TALKER32 ***: MakeCall hCall=%lx asyncID=%d\n",m_pActiveCall->m_hCall, lrc);
	m_pApp->SetAsyncID((DWORD) lrc, MAKING, FUNCTION_MAKECALL, 
						(LPVOID) this, (LPVOID) m_pActiveCall); 
	return lrc;
}

// lineDial wrapper
LONG CTapiLine::ctlLineDial(CTapiCall *pCall, LPCSTR lpAddr, DWORD dwCountryCode)
{
	LONG lrc = -1;

	if(pCall == NULL) pCall = m_pActiveCall;
	if(pCall == NULL) return -1;

	lrc = lineDial(pCall->m_hCall, lpAddr, dwCountryCode);

	if(lrc < 0) 
	{						// need to report an error
		TRACE("*** TALKER32 ***: lineDial failed on line %d\n", m_dwLineID);
		return lrc;
	}
	m_pApp->SetAsyncID((DWORD) lrc, DIALING, FUNCTION_DIAL, 
						(LPVOID) this, (LPVOID) pCall); 
	return lrc;
}

// lineAnswer wrapper
LONG CTapiLine::ctlLineAnswer(HCALL hCall)
{
	LONG lrc = -1;

	// Always assume active call. If hCall, check it against active call
	//if(m_pActiveCall == NULL || hCall != m_pActiveCall->m_hCall) return -1L;
	if(m_pActiveCall == NULL)  return -1;
	if(hCall != NULL && hCall != m_pActiveCall->m_hCall) return -1L;
	if(hCall == NULL ) hCall = m_pActiveCall->m_hCall;
	m_pActiveCall->UpdateCallState(ANSWERING, INBOUND);
   	lrc = lineAnswer(hCall, NULL, 0);
	if(lrc < 0)
	{						// need to report an error
		TRACE("*** TALKER32 ***: Answer failed on line %d\n", m_dwLineID);
//		RemoveCall();	// can't remove it here; must move to some list
		return lrc;
	}
//	m_pActiveCall->m_hCall = hCall;
	m_pApp->SetAsyncID((DWORD) lrc, MAKING, FUNCTION_ANSWER, 
						(LPVOID) this, (LPVOID) m_pActiveCall);
	return lrc;						 
}	

// lineDrop wrapper
LONG CTapiLine::ctlLineDrop(CTapiCall *pCall)
{
	LONG lrc = -1;

	if(pCall == NULL) pCall = m_pActiveCall;
	if(pCall == NULL) return -1;
	// special case-drop while MakeCall has not returned
	if(MAKING == pCall->GetCallState()) 
	{
		pCall->UpdateCallState(STOP_MAKING);
		return 0L;
	}
	pCall->StopWave();	//stop WAVE here 
	if(pCall->m_hCall) lrc = lineDrop(pCall->m_hCall, NULL, NULL);
	if(lrc < 0) return lrc;
	// set it up for DROPPING
	m_pApp->SetAsyncID((DWORD) lrc, pCall->GetCallState(), FUNCTION_DROP,
					  	(LPVOID) this, (LPVOID) m_pActiveCall);
	pCall->UpdateCallState(DROPPING);
	m_pApp->NotifyFrontEnd(m_dwLineID);	// do it from here or from onCallState?
	return lrc;
}

// lineDeallocateCall wrapper
LONG CTapiLine::ctlLineDeallocateCall(CTapiCall *pCall)
{
	LONG lrc = -1;

	TRACE(" *** enter ctlLineDeallocateCall pCall=%lx\n",pCall);
	if(pCall == NULL) pCall = m_pActiveCall;
	if(pCall == NULL) return -1;
	TRACE(" *** calling lineDeallocateCall pCall=%lx\n",pCall);
	lrc = lineDeallocateCall(pCall->m_hCall);
	TRACE(" *** lineDeallocateCall rc=%lx\n",lrc);
	if(lrc) 		// Failed, log the info
	{
		// log the information here; can't just free it up
		pCall->UpdateCallState(0xffff, 0xffff, 0xffff, DEALLOCATE_FAILED);
		return lrc;
	}
	RemoveCall(pCall);
	m_pApp->NotifyFrontEnd(m_dwLineID);
	TRACE(" *** exit ctlLineDeallocateCall pCall=%lx\n",pCall);
	return lrc;
}

// Create a call as a result of offering
LONG CTapiLine::ctlOfferCall(HCALL hCall)
{
	if(hCall == NULL) return -1L;
	if(m_pActiveCall) 
	{
		TRACE("*** TALKER32 ***: Offering call while other call is active on line %d\n", m_dwLineID); 
		return -1L;
	}
	LONG lrc = AddCall(hCall);
	if(lrc || m_pActiveCall == NULL)
	{
		TRACE("*** TALKER32 ***: AddCall failed\n");
		return lrc;
	}
	m_pActiveCall->UpdateCallState(OFFERING, INBOUND);
	m_pActiveCall->SetLine(this);			
	m_pApp->NotifyFrontEnd(m_dwLineID);
	return 0L;
}

// Add a call on this line
LONG CTapiLine::AddCall(HCALL hCall)
{

	TRACE("*** TALKER32 ***: AddCall #%lx entering wait for sem\n", hCall);
	DWORD dwrc = WaitForSingleObject(m_hCallSem, 15000);
	if(dwrc != WAIT_OBJECT_0) 
	{
		TRACE("*** TALKER32 ***: AddCall wait for sem failed rc=%lx\n", dwrc);
		return -1L;
	}
	m_pActiveCall = new CTapiCall(hCall, this);
	if(m_pActiveCall && m_uiWaveInID != 0xffff && m_uiWaveOutID != 0xffff) m_pActiveCall->InitWave();
	TRACE("*** TALKER32 ***: AddCall #%lx releasing mutex\n", hCall);
	ReleaseMutex(m_hCallSem);
	if(m_pActiveCall == NULL) return -1L;

⌨️ 快捷键说明

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