📄 tapiobj.cpp
字号:
CString strNumber = "";
/* Invalid Handle */
if (!m_hLineApp) return;
/* Give me message information */
ret = lineGetMessage(m_hLineApp,&stLineMsg,dwTimeout);
/* Check errors */
if ( ret!=0 ) {
st.Format(_T("%x"),ret);
ThrowErr(ret,_T("TapiObj.cpp, Ln 460,")
_T("Err: Can't get message. Err:[ ")+st+ _T("]\n"));
return;
}
/* What happend? */
switch (stLineMsg.dwMessageID)
{
case LINE_APPNEWCALL:
if (stLineMsg.dwParam3==LINECALLPRIVILEGE_OWNER)
m_hCall = (HCALL) stLineMsg.dwParam2;
break;
/* Something has changed! */
case LINE_CALLSTATE :
/* What's the change? */
switch (stLineMsg.dwParam1) {
/* Line is IDLE, so Time to clean up */
case LINECALLSTATE_IDLE:
/* Cleanup and restart, to receive next call */
Restart();
break;
/* Don't make mistake!, it is not ringing! */
case LINECALLSTATE_OFFERING:
m_hCall = (HCALL)stLineMsg.hDevice;
break;
/* Line is ready to receive voice, Hi! */
case LINECALLSTATE_CONNECTED:
/* Start listening to touchtones from user */
ret = lineMonitorDigits(
m_hCall,
LINEDIGITMODE_DTMF);
/* Check errors */
if (ret) {
ThrowErr(ret,_T("TapiObj.cpp, Ln 496,")
_T("Err: Unable to listen for user tones."));
return;
}
/* Find a wave id for playing a greeting message */
if (GetWaveID()==-1) {
ThrowErr(6,_T("TapiObj.cpp, Ln 503,")
_T("Err: Unable to find 'wave/out id'."));
return;
}
/* Inform parent that we are answering a call */
PostThreadMessage(
g_lMngrThread,
WM_STATUS_CHNGD,
ST_PICKED_UP,
ST_BUSY);
break;
/* The remote party has disconnected from the call */
/* Bye! */
case LINECALLSTATE_DISCONNECTED:
/* Don't restart here */
lineDrop((HCALL)stLineMsg.hDevice,NULL,0);
break;
}
break;
/* New information about the call is available */
case LINE_CALLINFO :
/* Was it CallerID? */
if( stLineMsg.dwParam1 == LINECALLINFOSTATE_CALLERID)
{
LINECALLINFO *lpCallInfo = NULL;
/* UNDONE :*/
/* Very dirty allocation of memory! */
/* It might cause bugs, please change this */
/* Make this a function*/
lpCallInfo =
(LINECALLINFO *)malloc
(sizeof(LINECALLINFO)+1024/* ! */);
memset(
lpCallInfo,
0,
sizeof(LINECALLINFO)+1024);
lpCallInfo->dwTotalSize =
sizeof(LINECALLINFO)+1024;
lineGetCallInfo(m_hCall, lpCallInfo);
if (lpCallInfo->dwTotalSize <
lpCallInfo->dwNeededSize)
{
lpCallInfo = (LINECALLINFO *)
realloc(
lpCallInfo,
lpCallInfo->dwNeededSize);
lineGetCallInfo(m_hCall, lpCallInfo);
}
/* Find Caller ID */
m_cid.Format(_T("%s"),(LPCTSTR)
((LPBYTE)lpCallInfo +
lpCallInfo->dwCallerIDOffset));
/* Inform parent that we got CID */
PostThreadMessage(
g_lMngrThread,
WM_CALLERID,
0,
0);
if (lpCallInfo)
free(lpCallInfo);
}
break;
/* Close the line */
case LINE_CLOSE:
ShutDown(); // UNDONE: should we shutdown?
break;
case LINE_LINEDEVSTATE :
/* Ringing, Please answer the call */
if (stLineMsg.dwParam1==LINEDEVSTATE_RINGING) {
/* Hey, dady! It's ringing */
PostThreadMessage(
g_lMngrThread,
WM_STATUS_CHNGD,
0,
ST_RING);
/* Should I pick the phone Up? */
if ( stLineMsg.dwParam3 >= m_dwRingCnt ) {
/* Check errors */
ret = lineAnswer(m_hCall,NULL,0);
if (!(ret>0)) {
ThrowErr(ret,_T("TapiObj.cpp, Ln 597,")
_T("Err: Unable to Answer the line."));
return;
}
}
}
break;
/* Touch tone digit arrived! */
case LINE_MONITORDIGITS :
/* Process digits */
if ( stLineMsg.dwParam2 == LINEDIGITMODE_DTMF ) {
OnDetectDTMF( LOBYTE(stLineMsg.dwParam1) );
}
break;
/* Tone arrived, any computer is trying to connect? */
case LINE_MONITORTONE :
// ?
break;
/* Any detectable error(s)? */
case LINE_REPLY :
// Possibly an error occured
// UNDONE: Handle errors, and stop later clls or so...
break;
default :
st.Format(L" [%x] ",stLineMsg.dwMessageID);
ThrowErr(0,st);
break;
}
}
/*********************************************************************
* Tries to get the ID of the wave out device
********************************************************************/
long CLine::GetWaveID()
{
VARSTRING *pVs;
long ret=0;
DWORD dwWaveDev;
DWORD dwSize;
int patience = 0;
/* allocate memory for structure */
pVs = (VARSTRING *) calloc (1, sizeof(VARSTRING));
/* set structure size */
pVs->dwTotalSize = sizeof(VARSTRING);
do {
/* We have not more patience, stop the loop */
if (++patience > 1000) {
ThrowErr(2153,_T("TapiObj.cpp, Ln 649,")
_T("Err: Recovered from unlimited loop."));
return -1;
}
/* Get wave/out ID */
ret = lineGetID(
m_hLine,
0L,
m_hCall,
LINECALLSELECT_CALL,
pVs,
_T("wave/out"));
/* check errors */
if (ret) {
free (pVs);
return -1;
}
/* reallocate and try again */
if (pVs->dwTotalSize < pVs->dwNeededSize) {
dwSize = pVs->dwNeededSize;
free (pVs);
pVs = (VARSTRING *) calloc(1, dwSize);
pVs->dwTotalSize = dwSize;
continue;
}/* end if (need more space) */
break; /* success */
} while (TRUE);
/* copy wave id */
dwWaveDev = (DWORD) *((DWORD *)((LPSTR)pVs + pVs->dwStringOffset));
free (pVs);
m_dwWaveOutID = dwWaveDev;
return dwWaveDev;
}
/*********************************************************************
* Restart the line
********************************************************************/
void CLine::Restart()
{
/* Stop the thread */
m_bContinueEventThread = FALSE;
Sleep(500); /* Sleep while thread exits */
/* Notify parent of a restart event */
PostThreadMessage(g_lMngrThread,WM_STATUS_CHNGD,0,ST_RESTART);
/* Drop the line */
lineDrop(m_hCall, NULL, 0);
/* TAPI cleanup */
lineDeallocateCall (m_hCall);
m_hCall = NULL;
m_bInitialized = TRUE;
m_bOpened = FALSE;
/* Sleep 100 more mili seconds, to make sure hardware is ready*/
Sleep(200);
/* Re open the line */
Open();
}
/*********************************************************************
* Shutting down the line
********************************************************************/
void CLine::ShutDown()
{
/* Notify parent of a shutdown event */
PostThreadMessage(g_lMngrThread,WM_STATUS_CHNGD,0,ST_SHUTDN);
if (m_bInitialized) {
/* Stop the thread */
m_bContinueEventThread = FALSE;
/* Sleep while thread exits */
if ( WaitForSingleObject(m_hLineMsgThread,10000) ==
WAIT_TIMEOUT) {
TerminateThread(m_hLineMsgThread, 0);
}
/* Drop the line */
lineDrop(m_hCall, NULL, 0);
/* Close the line */
lineClose(m_hLine);
m_hLine = NULL;
/* TAPI cleanup */
lineDeallocateCall (m_hCall);
m_hCall = NULL;
/* Shutdown TAPI */
lineShutdown(m_hLineApp);
m_hLineApp = NULL;
m_bInitialized = FALSE;
}
if (m_pLineDevCaps) {
free (m_pLineDevCaps);
}
m_pLineDevCaps = NULL;
}
/*********************************************************************
* Thread to get tapi events
********************************************************************/
DWORD WINAPI CLine::EventThread(LPVOID pParam)
{
/* Get callers pointer */
CLine* pLine = (CLine*) pParam;
if (!pLine) return 0;
/****************************************************************
* Every 10 mili seconds check to make sure we have to continue,
* if so, check to see weather we have any events or not, if so
* process event otherwise goto first place!
****************************************************************/
while(pLine->m_bContinueEventThread) {
switch(WaitForSingleObject(
(HANDLE)(pLine->m_hLineEvent),
5))
{
/* Have we got any events? */
case WAIT_OBJECT_0:
/* I did not catch errors here */
try {
pLine->ProcessEvent();
} catch(CTapiObj::TEx e) {
CString sz;
sz.Format(_T("Line thread Err: [code:%d],")
_T("[date:%s],")
_T("[time:%s],")
_T("[reason:%s]\n"),e.code,e.date,e.time,e.result);
CHErrLogger::LogError(sz);
} catch(...) {
}
break;
/* Sure we have nothing to process now */
case WAIT_TIMEOUT:
break;
/* Go on waiting and processing */
default: continue;
}
}
return 0;
}
/*********************************************************************
* Will be called to process a key pressed by the user
********************************************************************/
void CLine::OnDetectDTMF(char tone)
{
switch (tone) {
case '1': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_1);
break;
case '2': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_2);
break;
case '3': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_3);
break;
case '4': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_4);
break;
case '5': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_5);
break;
case '6': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_6);
break;
case '7': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_7);
break;
case '8': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_8);
break;
case '9': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_9);
break;
case '0': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_0);
break;
case 'A': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_A);
break;
case 'B': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_B);
break;
case 'C': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_C);
break;
case 'D': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_D);
break;
case '*': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_STAR);
break;
case '#': PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_SHARP);
break;
default : PostThreadMessage(m_lBossThreadID,WM_DTMF,0,D_NONE);
break;
}
}
/*********************************************************************
* Starts processing a line
********************************************************************/
BOOL CLine::Start()
{
try {
Init();
Open();
} catch(CTapiObj::TEx e) {
CString sz;
sz.Format(_T("Line Err: [code:%d],")
_T("[date:%s],")
_T("[time:%s],")
_T("[reason:%s]\n"),e.code,e.date,e.time,e.result);
CHErrLogger::LogError(sz);
} catch (...) {
}
return TRUE;
}
/*********************************************************************
* Returns caller ID
********************************************************************/
CString CLine::GetCallerID()
{
return m_cid;
}
/*********************************************************************
* Returns wave device ID
********************************************************************/
DWORD CLine::GetDevWavID()
{
return m_dwWaveOutID;
}
/*********************************************************************
* Set a thread to receive DTMF messages
********************************************************************/
void CLine::SetBossMessenger(unsigned long pThreadID)
{
m_lBossThreadID = pThreadID;
}
/*********************************************************************
* Set number of rings to pickup the line after
********************************************************************/
void CLine::SetRingCount(UINT nRingCnt)
{
m_dwRingCnt = nRingCnt;
/* Pickup after ? rings */
lineSetNumRings (m_hLine, 0, m_dwRingCnt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -