📄 tapiline.cpp
字号:
// 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 + -