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

📄 tapiobj.cpp

📁 一个使用tapi实现的自动语音应答的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -