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

📄 tapiobj.cpp

📁 一个使用tapi实现的自动语音应答的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

/*********************************************************************
 * End of CLine impelementation
 ********************************************************************/

/*********************************************************************
 * CPhone class
 *********************************************************************
 * This class impelements  a phone and defines main operations on it *
 * phone devices are to control mic/spk jacks behind your modem or   *
 * through the sound card. They also make it possible to work with   *
 * the phone socket (socket simmilar to RJ-45) of the modem.		 *
 *																	 *
 * This impelementation covers Speaker/phone capability of modems.	 *
 *																	 *
 ********************************************************************/

/*********************************************************************
 * Constructor CPhone class
 ********************************************************************/
CPhone::CPhone()
{
	m_ID = 0;
	m_bInitialized = FALSE;
	m_bOpened = FALSE;
	m_bContinueEventThread = TRUE;

	m_hPhoneApp = NULL;
	m_hPhone = NULL;
	m_hPhoneEvent = NULL;
	m_hPhoneMsgThread = NULL;
	m_pPhoneDevCaps = NULL;
	m_dwApiVersion = 0;
}

/*********************************************************************
 * Distructor CPhone class
 ********************************************************************/
CPhone::~CPhone()
{
	ShutDown();
}

/*********************************************************************
 * Initialize the phone (~ 120 lines)
 * 
 * very similar to line initialization above
 ********************************************************************/
long CPhone::Init()
{
	int ret = -1;

	// Varibles
	int		patience = 0;
	DWORD	nPhoneCnt=0;
	BOOL	noMem;

	PHONEINITIALIZEEXPARAMS *phoneParams = 
		(PHONEINITIALIZEEXPARAMS *) 
		calloc(1,sizeof(PHONEINITIALIZEEXPARAMS));

	memset(phoneParams,NULL,sizeof(PHONEINITIALIZEEXPARAMS));
	phoneParams->dwOptions = PHONEINITIALIZEEXOPTION_USEEVENT;
	phoneParams->dwTotalSize = sizeof(PHONEINITIALIZEEXPARAMS);

										  /* Try to initilize phone */
	do {
									 /* We have not memory shortage */
		noMem = FALSE;

		ret = phoneInitializeEx( &m_hPhoneApp,
								 AfxGetInstanceHandle(),
								 NULL,
								 m_appName,
								 &nPhoneCnt,
								 &m_version,
								 phoneParams );
	
							 /* If more memory is needed, Realocate */
		if ( phoneParams->dwNeededSize > phoneParams->dwTotalSize ) {
			int needed = phoneParams->dwNeededSize;
			noMem = TRUE;
			free(phoneParams);
			phoneParams = NULL;

			phoneParams = (PHONEINITIALIZEEXPARAMS *) 
				calloc(1,needed);

			if (!phoneParams) {
				ThrowErr(0,_T("TapiObj.cpp, Ln 987,")
					_T("can't alocate memory"));
			}

			memset(phoneParams,NULL,needed);
			phoneParams->dwOptions = 
				PHONEINITIALIZEEXOPTION_USEEVENT;
			phoneParams->dwTotalSize = needed;
		}


												/* looping too much */
		if (++patience> 1000) {

			if (phoneParams) free(phoneParams);
			ThrowErr(1,_T("TapiObj.cpp, Ln 1002,")
				_T("Recovered from unlimited loop"));
		};

											/* Sleep 5 mili seconds */
		Sleep(5);
	} while ( (ret==PHONEERR_REINIT) || (noMem==TRUE) );


							   /* Get a handle for thread waking up */
	m_hPhoneEvent = (phoneParams->Handles.hEvent);

											  /* Free unused memory */
	if (phoneParams) free(phoneParams);

													/* Check errors */
	if (ret != 0) {
		CString sr;

		sr.Format(_T("%d"),ret);
		ThrowErr(ret,_T("TapiObj.cpp, Ln 1022, ret=")+sr);
	}

	memset(&(m_extID),NULL,sizeof(PHONEEXTENSIONID));

							/* Time to negotiate! for a good device */
	for (UINT i=m_ID;i<nPhoneCnt;i++) {

		ret = phoneNegotiateAPIVersion(
			m_hPhoneApp,
			i,
			m_version,
			m_version,
			&m_dwApiVersion,
			&m_extID );
		if (ret !=0 ) continue;

									   /* Check device capabilities */
			/* Warning: this line MUST be before calling GetDevCaps */
		m_ID = i;
		ret = GetDevCaps();
		
													/* Check errors */
		if (ret != 0) {
			CString sr;

			sr.Format(_T("%d"),ret);
			ThrowErr(ret,_T("TapiObj.cpp, Ln 1049, ret=")+sr);
		}

											/* Is device demanding? */
		if ( (m_pPhoneDevCaps->dwHookSwitchDevs & 
			  PHONEHOOKSWITCHDEV_SPEAKER) && 
			 (m_pPhoneDevCaps->dwSpeakerHookSwitchModes &
			  PHONEHOOKSWITCHMODE_MICSPEAKER) > 0)  {
			m_ID = i;
			m_bInitialized = TRUE;
			break;
		}
	}

	if (i>=nPhoneCnt) {
		m_bInitialized = FALSE;
	}

	return ret;
}

/*********************************************************************
 * Opens a phone device
 ********************************************************************/
long CPhone::Open()
{
	long ret = -1;

						   /* If phone has not been initialized yet */
	if (!m_bInitialized) return ret;

													  /* Open phone */
	ret = phoneOpen(m_hPhoneApp,
		m_ID,
		&m_hPhone,
		m_dwApiVersion,
		0, 0, PHONEPRIVILEGE_OWNER);

												/* Check for errors */
	if (ret !=0 ) {
		return ret;
	}

	m_bOpened = TRUE;

	/* I want to receive all messages and events appropriate to me! */
	ret = phoneSetStatusMessages(m_hPhone,
		m_pPhoneDevCaps->dwPhoneStates,0,0);

			  /* Start a thread to listen to events from this phone */
	m_bContinueEventThread = TRUE;
	m_hPhoneMsgThread = CreateThread(
		NULL,
		NULL,
		EventThread,
		(LPVOID)this,
		NULL,0);

	return ret;
}

/*********************************************************************
 * Find out phone device capabilities
 ********************************************************************/
long CPhone::GetDevCaps()
{
	long ret = -1;
	int  patience = 0;
	DWORD dwRealSize = 0;

		  /* Free the memory that possibly alocated from last calls */
	if (m_pPhoneDevCaps) free(m_pPhoneDevCaps);
	m_pPhoneDevCaps = NULL;

						  /* Try to alocate minimum possible memory */
	m_pPhoneDevCaps = (PHONECAPS*) calloc(1,sizeof(PHONECAPS));
	if (!m_pPhoneDevCaps)
		return PHONEERR_NOMEM;

													/* Clean memory */
	memset(m_pPhoneDevCaps,NULL,sizeof(PHONECAPS));
	m_pPhoneDevCaps->dwTotalSize = sizeof(PHONECAPS);

	do {
		ret = phoneGetDevCaps (m_hPhoneApp,
			m_ID,
			m_dwApiVersion,
			0,
			m_pPhoneDevCaps);

				   /* Check memory size and realocate, if nessesery */
		dwRealSize = m_pPhoneDevCaps->dwNeededSize;
		if (m_pPhoneDevCaps->dwTotalSize < dwRealSize) {
			
			free(m_pPhoneDevCaps);
			m_pPhoneDevCaps = NULL;
			
						   /* Try to alocate minimum posible memory */
			m_pPhoneDevCaps = (PHONECAPS*) calloc(1,dwRealSize);
			if (!m_pPhoneDevCaps)
				return PHONEERR_NOMEM;

			memset(m_pPhoneDevCaps,NULL,dwRealSize);
			m_pPhoneDevCaps->dwTotalSize = dwRealSize;
		} else break;

												/* Toomuch looping! */
		if (++patience> 1000) {

			if (m_pPhoneDevCaps) free(m_pPhoneDevCaps);
			ThrowErr(3,_T("TapiObj.cpp,")
				_T("Ln 1160, Recovered from unlimited loop"));
			break;
		};

	} while (1);

	return ret;
}

/*********************************************************************
 * Processing events from phone device
 ********************************************************************/
void CPhone::ProcessEvent()
{
	PHONEMESSAGE stPhoneMsg;
	DWORD		dwTimeout = 10;// Miliseconds
	long		ret=0;
	CString tmp,st;
	CString strNumber = "";

								/* Retreive a new message to process*/
	ret = phoneGetMessage(m_hPhoneApp,&stPhoneMsg,dwTimeout);
	if ( ret!=0 ) {
		st.Format(_T("%x"),ret);
		ThrowErr(ret,_T("TapiObj.cpp, Ln 1184,")
		_T(" Err: Can't get message. Err:[   ")+st+ _T("]"));
		return;
	}

	//UNDONE
	// THIS FUNCTION HAS NOT BEEN IMPELEMENTED YET ****
	if (stPhoneMsg.dwMessageID == PHONE_REPLY) {
		if (stPhoneMsg.dwParam2!=0) {
			TRACE (_T("\n\n\n\n\n%ld\n\n"),stPhoneMsg.dwParam2);
		}
//		OnRequestComplete (stPhoneMsg.dwParam1, stPhoneMsg.dwParam2);
      
	 /* A new phone has been dynamically added to TAPI (Plug&Play). */
	} else if (stPhoneMsg.dwMessageID == PHONE_CREATE) {

	/* A phone has been removed from the system.*/
	} else if (stPhoneMsg.dwMessageID == PHONE_REMOVE) {
//		OnPhoneRemove (stPhoneMsg.dwParam1);

	} else if (stPhoneMsg.dwMessageID == PHONE_CLOSE) {
//		OnPhoneClose (stPhoneMsg.dwParam1);

	/* Other phone related message */
	} else {
		if (stPhoneMsg.dwMessageID == PHONE_STATE) {
		}
	}
}

/*********************************************************************
 * Thread to get tapi phone events
 ********************************************************************/
DWORD WINAPI CPhone::EventThread(LPVOID pParam)
{
									  /* Obtain a pointer to parent */
	CPhone* phone = (CPhone*) pParam;
	if (!phone) return 0;

	while(phone->m_bContinueEventThread) {
		switch(WaitForSingleObject(
			(HANDLE)(phone->m_hPhoneEvent), 10)) {
		
										 /* Have we got any events? */
		case WAIT_OBJECT_0:
			try {
				phone->ProcessEvent();
			} catch(...) {
				CString sz;
				sz.Format(_T("Err: PhoneEventThread ,Line 1233\n"));
				CHErrLogger::LogError(sz);
			}
			break;
		
							 /* Sure we have nothing to process now */
		case WAIT_TIMEOUT:
			break;

									/* Go on waiting and processing */
		default: continue;
		}
	}

	return 0;
}

/*********************************************************************
 * Switches a line to Mic/Spk phone device
 ********************************************************************/
LONG CPhone::SwichToMicSpk()
{
	long ret = 0;
	ret = phoneSetHookSwitch( 
		m_hPhone, 
		PHONEHOOKSWITCHDEV_SPEAKER,
		PHONEHOOKSWITCHMODE_MICSPEAKER
		);

	if (ret<0) {
	}
	return ret;
}

/*********************************************************************
 * Resets a phone device
 ********************************************************************/
void CPhone::Reset()
{
	phoneClose( m_hPhone );

	Start();
}

/*********************************************************************
 * Starts a phone device operation
 ********************************************************************/
BOOL CPhone::Start()
{
	try {
		Init();
		Open();
	} catch(CTapiObj::TEx e) {
		CString sz;
		sz.Format(_T("Phone 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;
}

/*********************************************************************
 * Misplaced function!
 ********************************************************************/
void CTapiObj::ThrowErr(int id, CString res)
{
	CTime	tm;
	tm=tm.GetCurrentTime();
	CString stdt,sttm;

	stdt.Format(_T("%d/%d/%d"),tm.GetYear(),tm.GetMonth(),tm.GetDay());
	sttm.Format(_T("%d:%d:%d"),tm.GetHour(),tm.GetMinute(),tm.GetSecond());

	throw(CTapiObj::TEx(id,res,stdt,sttm));
}

/*********************************************************************
 * Shutdown & Clenup phone device
 ********************************************************************/
void CPhone::ShutDown()
{
	if (m_bInitialized) {

												 /* Stop the thread */
		m_bContinueEventThread = FALSE;
										/* Sleep while thread exits */
		if ( WaitForSingleObject(m_hPhoneMsgThread,10000) == 
			WAIT_TIMEOUT) {
			TerminateThread(m_hPhoneMsgThread, 0);
		}

												   /* Drop the line */
		phoneClose(m_hPhone);
												  /* Close the line */
		m_hPhone = NULL;
												   /* Shutdown TAPI */
		phoneShutdown(m_hPhoneApp);
		m_hPhoneApp = NULL;

		m_bInitialized = FALSE;
	}
	if (m_pPhoneDevCaps) {
		free (m_pPhoneDevCaps);
	}
	
	m_pPhoneDevCaps = NULL;
}

⌨️ 快捷键说明

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