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); } //---------------------------------------------------------------------------