www.pudn.com > AM.rar > AMSTATE.CPP


#include        
#include  
#include  
#include  
#include  
#include "AM.h" 
#include "AMState.h" 
#include "Wave.h" 
 
char *pszOwnerID="1234"; 
//--------------------------------------------------------------------------- 
void OnGatherDigit(LPLINEINFO pLineData) 
{ 
	if ( strcmp(pLineData->pszLoginID, pszOwnerID) == 0 ) //chech gather digits is 1234 or not 
	{ 
		MMRESULT mmrc; 
 
		printf("\nLine %d receive code is : %s",pLineData->nLineID,	pLineData->pszLoginID); 
 
		pLineData->dwCallState &= ~TAPI_PLAYGREET;		 //clear stop play greet flag 
		pLineData->dwCallState |= TAPI_PREPAREPLAYICM;	 //set begin play ICM 
		pLineData->dwWaveStage = 0; 
 
		if ( mmrc = waveOutReset(pLineData->hWaveOut) ) 
		{ 
			printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc); 
			pLineData->dwCallState = TAPI_HANGUP; 
			OnHangUp(pLineData->hCall,pLineData->nLineID); 
		}	 
		else 
		{ 
			printf("\nLine %d wave Out reset success.",pLineData->nLineID); 
			FinishPlay(pLineData); //finish play greet.wav,then play ICM 
		} 
 
		strcpy(pLineData->pszLoginID,"    "); 
	} 
	else 
	{ 
		printf("\nLine %d receive incorrect code is : %s",pLineData->nLineID,pLineData->pszLoginID); 
		strcpy(pLineData->pszLoginID,"    "); 
	} 
} 
//--------------------------------------------------------------------------- 
void OnHangUp(HCALL hCall, DWORD ID) 
{ 
	LONG tr = lineDrop(hCall, 0, 0);	   // drop a call 
	if( tr > 0 ) 
	{ 
		printf("\nLine %d Call dropping...",ID); 
	} 
	else 
	{ 
		printf("\n###Line %d Can't drop call error#%x.",ID,tr); 
	} 
} 
//--------------------------------------------------------------------------- 
void FinishPlay(LPLINEINFO pLineData) 
{                                  // FinishPlay do waveOutUnprepareHeader 
	MMRESULT mmrc;				   // and mmioClose first, then waveOutClose 
								   // at last free lpwavehdr 
	if (!pLineData->hWaveOut) 
	{ 
		printf("\n###Line %d wave Out Handle is Null",pLineData->nLineID); 
		return; 
	} 
	mmrc =waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr, sizeof(WAVEHDR)); 
	mmrc =waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr2, sizeof(WAVEHDR)); 
	mmrc =mmioClose(pLineData->hmmioH, 0); 
	mmrc = waveOutClose(pLineData->hWaveOut); 
	if ( mmrc ) 
	{ 
		printf("\n###Line %d wave Out close error #%x!",pLineData->nLineID,mmrc); 
	}
	else 
	{ 
		printf("\nLine %d wave Out close success",pLineData->nLineID);	 
	} 
	pLineData->hWaveOut = NULL; 
	free (pLineData->lpWaveHdr);  
	free (pLineData->lpWaveHdr2);  
 
	return;	 
} 
//--------------------------------------------------------------------------- 
void FinishRecord(LPLINEINFO pLineData) 
{   			     // waveInStop first ,then call mmiowrite write wave data into hmmioH 
	MMRESULT mmrc;	 // waveInUnprepareHeader,waveInClose,then free lpwavehdr 
 
	if (!pLineData->hWaveIn) 
	{ 
		printf("\n###Line %d wave In Handle is Null",pLineData->nLineID); 
		return; 
	} 
	waveInStop(pLineData->hWaveIn); 
	if ( pLineData->wWaveBufState )	//check buf state 
	{ 
		mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr2->lpData, pLineData->lpWaveHdr2->dwBytesRecorded); 
		mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr->lpData, pLineData->lpWaveHdr->dwBytesRecorded); 
	} 
	else 
	{ 
		mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr->lpData, pLineData->lpWaveHdr->dwBytesRecorded); 
		mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr2->lpData, pLineData->lpWaveHdr2->dwBytesRecorded); 
	} 
	waveInUnprepareHeader(pLineData->hWaveIn, pLineData->lpWaveHdr, sizeof(WAVEHDR)); 
	waveInUnprepareHeader(pLineData->hWaveIn, pLineData->lpWaveHdr2, sizeof(WAVEHDR)); 
	mmioAscend(pLineData->hmmioH, &pLineData->mmSubchunk,0); //ascend data chunk 
	mmioAscend(pLineData->hmmioH, &pLineData->mmParent, 0);	 //ascend RIFF chunk 
	mmrc = mmioClose(pLineData->hmmioH, 0);					 //close hmmioH 
	mmrc = waveInClose(pLineData->hWaveIn);					 //close Wave In header 
	if ( mmrc ) 
	{ 
		printf("\n###Line %d wave In close error# %x!",pLineData->nLineID,mmrc); 
	} 
	else 
	{ 
		printf("\nLine %d wave In close success",pLineData->nLineID); 
	} 
	pLineData->hWaveIn = NULL; 
	free(pLineData->lpWaveHdr); 
	free(pLineData->lpWaveHdr2); 
 
	return;	 
} 
//--------------------------------------------------------------------------- 
void OnCallState(LPLINEINFO pLineData) //when ADmorelineCallbackFunc receive  
{									   //LINE_CALLSTATE event ,call this function 
	MMRESULT mmrc; 
	LONG tr; 
 
	ADCALLBACK pCall = pLineData->pCallBack; 
	HCALL hCall = (HCALL)pCall.dwDevice; 
	DWORD nCallState = pCall.dwParam1; 
	DWORD dwParam2 = pCall.dwParam2; 
	DWORD nCallPrivilege = pCall.dwParam3; 
 
	//printf("\nhcall=%X d1=%X d2=%X d3=%X",hCall,nCallState,dwParam2,nCallPrivilege); 
	pLineData->hCall = hCall; 
	struct FlagMap { DWORD nFlag; LPCSTR szFlag; }; 
	static FlagMap aFlags[] = 				//callstate event 
	{ 
		{LINECALLSTATE_IDLE,		"idle"}, 
		{LINECALLSTATE_ACCEPTED,    "accepted"}, 
		{LINECALLSTATE_DIALTONE,    "dial tone detected"}, 
		{LINECALLSTATE_DIALING,		"dialing"}, 
		{LINECALLSTATE_RINGBACK,	"ring-back detected"}, 
		{LINECALLSTATE_BUSY,		"busy detected"}, 
		{LINECALLSTATE_SPECIALINFO, "error detected"}, 
		{LINECALLSTATE_CONNECTED,   "connected"}, 
		{LINECALLSTATE_PROCEEDING,  "proceeding"}, 
		{LINECALLSTATE_DISCONNECTED,"disconnected"}, 
		{LINECALLSTATE_OFFERING,    "offering"} 
	}; 
 
	for (int i=0; i < 11; i++) 
	{ 
		if ( aFlags[i].nFlag == nCallState ) 
		{ 
			printf("\nLine %d Call %s", pLineData->nLineID, aFlags[i].szFlag); 
			break; 
		} 
	} 
 
	switch( nCallState ) 
	{ 
		case LINECALLSTATE_DISCONNECTED: 
			switch ( pLineData->dwCallState ) 
			{ 
				case TAPI_PLAYGREET:		 //play greet.wav ? 
				case TAPI_PLAYICM:			 //play Income.wav (ICM)? 
					pLineData->dwCallState = TAPI_HANGUP; 
					pLineData->dwWaveStage = 0; 
					if ( mmrc = waveOutReset(pLineData->hWaveOut) ) 
					{ 
						printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc); 
					} 
					else 
					{ 
						printf("\nLine %d wave Out reset success.",pLineData->nLineID); 
						FinishPlay(pLineData); 
					} 
					OnHangUp(hCall,pLineData->nLineID); 
					break; 
				case TAPI_RECORDICM:		 //Record Income.wav? (ICM) 
					pLineData->dwCallState = TAPI_HANGUP; 
					pLineData->dwWaveStage = 0; 
					if ( mmrc = waveInReset(pLineData->hWaveIn) ) 
					{ 
						printf("\n###Line %d Can't reset wave in error #%x",pLineData->nLineID,mmrc); 
					} 
					else 
					{ 
						printf("\nLine %d wave In reset success.",pLineData->nLineID); 
						FinishRecord(pLineData); 
					} 
					OnHangUp(hCall,pLineData->nLineID); 
					break; 
				case TAPI_PREPAREPLAYICM:	 //Reppare play ICM now? 
					pLineData->dwCallState = TAPI_HANGUP; 
					OnHangUp(hCall,pLineData->nLineID); 
					break; 
			} //end switch ( pLineData->dwCallState ) 
			break; 
 
		case LINECALLSTATE_IDLE:	  
			lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_NONE);	//set dwAppSpeicfic to 0 
			tr = lineDeallocateCall(pLineData->hCall);//deallocate Call 
			if ( tr == NOERR ) 
				printf("\nLine %d linedellocateCall", pLineData->nLineID); 
			else 
				printf("\nLine %d linedellocateCall error#%x",pLineData->nLineID,tr); 
		 
			printf("\nLine %d to wait for income call...", pLineData->nLineID); 
			break; 
 
		case LINECALLSTATE_BUSY: 
			OnHangUp(pLineData->hCall,pLineData->nLineID); 
			break; 
 
		case LINECALLSTATE_OFFERING:	// line get the ring 
			pLineData->dwCallState = 0; 
			tr = lineAnswer(hCall,0,0); // answer the call one this line 
			if( tr > 0 ) 
			{ 
				printf("\nLine %d answer....",pLineData->nLineID); 
			} 
			else 
			{ 
				printf("\n###Line %d answer error #%x....",pLineData->nLineID,tr); 
			} 
			pLineData->hCall = hCall; 
			break; 
 
		case LINECALLSTATE_CONNECTED:  //line connect message receive after line answer 
			//gether the digit in pszLoginID[5]			 
			//lineGatherDigits(pLineData->hCall,LINEDIGITMODE_DTMF, 
			//						pLineData->pszLoginID, 4, "*#", 5000, 1500); 
 
			//call WavePlay to play Greet.wav in DeviceID 
			pLineData->hWaveOut = WavePlay(pLineData->dwWaveID,"Greet.wav",pLineData); 
			if ( pLineData->hWaveOut == NULL )		  // wave out open fail 
			{ 
				OnHangUp(hCall,pLineData->nLineID); 
				break; 
			}	 
			pLineData->dwCallState |= TAPI_PLAYGREET; 
			//gether the digit in pszLoginID[5]			 
			tr=lineGatherDigits(pLineData->hCall,LINEDIGITMODE_DTMF, 
									pLineData->pszLoginID, 4, "*#", 5000, 1500); 
			printf("\nLine %d press '1234' to receive Income message...",pLineData->nLineID); 
			break; 
	}//end switch case 
} 
//--------------------------------------------------------------------------- 
long ADmorelineGetCallInfo(HCALL hCall,LINECALLINFO** ppd) 
{													//get LINECALLINFO 
	DWORD	dwNeededSize = sizeof(LINECALLINFO);	 
	LONG    tr = 0; 
	do 
	{ 
		//Get some more memory if we don't have enough 
		if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize ) 
		{ 
			*ppd = (LPLINECALLINFO)::realloc(*ppd, dwNeededSize); 
 
			if( *ppd ) 
			{ 
				(*ppd)->dwTotalSize = dwNeededSize; 
			} 
			else 
			{ 
				return LINEERR_NOMEM; 
			} 
		} 
 
		//Fill in the buffer 
		tr = lineGetCallInfo(hCall, *ppd); 
 
		//check how much memory we need  
		//because TSPs succeed even if the data size is too small 
		if( (tr == LINEERR_STRUCTURETOOSMALL ) || 
			( tr ==	0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) ) 
		{ 
			dwNeededSize = (*ppd)->dwNeededSize; 
			tr = LINEERR_STRUCTURETOOSMALL; 
		}					  
 
	} 
	while( tr == LINEERR_STRUCTURETOOSMALL ); 
 
	return tr; 
} 
//--------------------------------------------------------------------------- 
long ADmoreGetLineDevCaps(HLINEAPP hLineApp, DWORD nApiVersion, DWORD nLineID, 
							LPLINEINFO pLineInfo, LINEDEVCAPS** ppd) 
{													   //get LINEDEVCAPS 
	DWORD	dwNeededSize = sizeof(LINEDEVCAPS); 
	LONG    tr = 0; 
 
	do 
	{ 
		//Get some more memory if we don't have enough 
		if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize ) 
		{ 
			*ppd = (LPLINEDEVCAPS)::realloc(*ppd, dwNeededSize); 
 
			if( *ppd ) 
			{ 
				(*ppd)->dwTotalSize = dwNeededSize; 
			} 
			else 
			{ 
				return LINEERR_NOMEM; 
			} 
		} 
 
		//Fill in the buffer 
		tr = lineGetDevCaps(hLineApp, nLineID, nApiVersion, 0, *ppd); 
 
		//check how much memory we need  
		//because TSPs succeed even if the data size is too small 
		if( (tr == LINEERR_STRUCTURETOOSMALL ) || 
			( tr ==	0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) ) 
		{ 
			dwNeededSize = (*ppd)->dwNeededSize; 
			tr = LINEERR_STRUCTURETOOSMALL; 
		}					  
 
	} 
	while( tr == LINEERR_STRUCTURETOOSMALL ); 
 
	if (((*ppd) -> dwLineNameSize) && 
        ((*ppd) -> dwLineNameOffset) && 
	    ((*ppd) -> dwStringFormat == STRINGFORMAT_ASCII)) 
    {							   //get line Name on dwLineOffset 
        strcpy(pLineInfo->szLineName, 
			           ((char *) (*ppd)) + (*ppd) -> dwLineNameOffset); 
    } 
	else 
    { 
        strcpy(pLineInfo->szLineName,"UnknowName"); 
    } 
 
	return tr; 
 
} 
//--------------------------------------------------------------------------- 
//--------------------------------------------------------------------------- 
void OpenLine(LPLINEINFO pLineData)	   //open voice line 
{	 
	LINEDEVCAPS* pldc = 0; 
	DWORD nLineID = pLineData->nLineID; 
	if((ADmoreGetLineDevCaps(m_hLineApp,		  //get line device capability in pldc 
								pLineData->dwApiVersion, 
								nLineID, 
								pLineData, 
								&pldc)==0) && 
		(pldc->dwBearerModes & LINEBEARERMODE_VOICE) && 
		(pldc->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) && 
		(pldc->dwLineFeatures & LINEFEATURE_MAKECALL) )	 
	{ 
		if( lineOpen(m_hLineApp, nLineID, &pLineData->hLine, pLineData->dwApiVersion, 
					 0, 0, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_INTERACTIVEVOICE, NULL)==0 ) 
		{ 
		    //easy for user look ch1 ~ ch(m_nLines), not ch0 ~ ch(m_nLines-1) 
			pLineData->nLineID++; 
			/*get line device ID */ 
			lpDeviceID->dwTotalSize =  sizeof (VARSTRING) + 64;	      			  
			lineGetID(pLineData->hLine, 0, 0, LINECALLSELECT_LINE, lpDeviceID,"tapi/line"); 
			pLineData->dwLineID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING));  
			FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f');  //fill lpdevice with 'f' byte 
			/*get wave device ID */ 
			lpDeviceID->dwTotalSize =  sizeof (VARSTRING) + 64;	      			  
			lineGetID(pLineData->hLine, 0, 0, LINECALLSELECT_LINE, lpDeviceID,"wave/out"); 
			pLineData->dwWaveID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING));  
			FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f');  //fill lpdevice with 'f' byte 
			//delete lpDeviceID; 
		    printf("\nOpen Line %d to wait for income call...(%s)", 
										pLineData->nLineID,pLineData->szLineName); 
		} 
		else 
		{ 
			printf("\n### Line %d open fail ! (%s)",  
						++pLineData->nLineID,pLineData->szLineName); 
    	} 
	} 
	else 
	{ 
		printf("\n### Line %d is not device for interactive voice ! (%s)",  
					++pLineData->nLineID,pLineData->szLineName); 
	} 
	free(pldc);	 
} 
//---------------------------------------------------------------------------