📄 dial.cpp
字号:
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <conio.h>
#include <TAPI.h>
#include "Dial.h"
#include "WavePlay.h"
HLINEAPP m_hLineApp;
DWORD m_nLines;
LPLINEINFO pLineInfo;
LPVARSTRING lpDeviceID;
DWORD dwActiveChn;
LINEDEVCAPS* pldc = 0;
//---------------------------------------------------------------------------
void FinishPlay(LPLINEINFO pLineData)
{
MMRESULT mmrc;
if (!pLineData->hWaveOut) return;
waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr, sizeof(WAVEHDR));
if ( mmrc = waveOutClose(pLineData->hWaveOut) )
{
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;
LocalUnlock((HLOCAL)pLineData->lpWaveDataAlloc); //unlock the memory
free (pLineData->lpWaveHdr);
return;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void OnHangUp(HCALL hCall, DWORD ID)
{
LONG tr = lineDrop(hCall, 0, 0);
if( tr > 0 )
{
printf("\nLine %d Call dropping...",ID);
}
else
{
printf("\n###Line %d Can't drop call.",ID);
}
}
//---------------------------------------------------------------------------
void OnCallState(LPLINEINFO pLineData)
{
MMRESULT mmrc;
ADCALLBACK pCall = pLineData->pCallBack;
HCALL hCall = (HCALL)pCall.dwDevice;
DWORD nCallState = pCall.dwParam1;
DWORD dwParam2 = pCall.dwParam2;
DWORD nCallPrivilege = pCall.dwParam3;
struct FlagMap { DWORD nFlag; LPCSTR szFlag; };
static FlagMap aFlags[] =
{
{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"},
};
for (int i=0; i < 10; i++)
{
if ( aFlags[i].nFlag == nCallState )
{
printf("\nLine %d Call %s", pLineData->nLineID, aFlags[i].szFlag);
break;
}
}
switch( nCallState )
{
case LINECALLSTATE_DISCONNECTED:
switch( dwParam2 )
{
case LINEDISCONNECTMODE_NODIALTONE:
printf("\nLine %d No dial tone",pLineData->nLineID);
OnHangUp(hCall,pLineData->dwLineID);
break;
case LINEDISCONNECTMODE_NOANSWER: //this call is no answer
printf("\nLine %d No answer.",pLineData->nLineID);
OnHangUp(hCall,pLineData->dwLineID);
break;
default:
if (pLineData->dwCallState & TAPI_PLAYGREET) //hang up when play hello.wav
{
pLineData->dwCallState = TAPI_HANGUP;
if ( mmrc = waveOutReset(pLineData->hWaveOut) )
printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc);
else
FinishPlay(pLineData);
OnHangUp(pLineData->hCall,pLineData->dwLineID);
}
break;
}
break;
case LINECALLSTATE_IDLE:
lineDeallocateCall(hCall);
printf("\nLine %d linedellocateCall", pLineData->nLineID);
lineClose(pLineData->hLine);
printf("\nLine %d lineclose\n", pLineData->nLineID);
SelectChn();
while(!OpenLine(&pLineInfo[dwActiveChn])) SelectChn();
break;
case LINECALLSTATE_BUSY:
OnHangUp(hCall,pLineInfo->dwLineID);
break;
case LINECALLSTATE_PROCEEDING:
break;
case LINECALLSTATE_CONNECTED:
pLineData->hCall = hCall;
//call WavePlay to play hello.wave in DeviceID
pLineData->hWaveOut=WavePlay(pLineData->dwWaveID,"hello.wav", pLineData);
pLineData->dwCallState |= TAPI_PLAYGREET;
break;
}
}
//---------------------------------------------------------------------------
void CALLBACK ADmorelineCallbackFunc(DWORD dwDevice, DWORD nMsg, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
lpDeviceID->dwTotalSize = sizeof (VARSTRING) + 64;
lineGetID(0, 0, (HCALL)dwDevice, LINECALLSELECT_CALL, lpDeviceID,"tapi/line");
DWORD dwID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING)); // get id for wave out
FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f'); //fill lpdevice with 'f' byte
if ( dwID >= m_nLines ) //chech device range
return;
ADCALLBACK pCall={dwDevice,nMsg,dwCallbackInstance,dwParam1,dwParam2,dwParam3};
switch( nMsg )
{
case LINE_REPLY:
printf("\nLine %d Call Back ------>LINE_REPLY",dwID);
break;
case LINE_CALLSTATE:
printf("\nLine %d Call Back ------>LINE CALLSTATE",dwID);
pLineInfo[dwID].pCallBack = pCall;
OnCallState(&pLineInfo[dwID]);
break;
case LINE_CLOSE:
// Line has been shut down.
printf("\nLine %d Call Back ------>LINE_CLOSE",dwID);
OnHangUp((HCALL)dwDevice,dwID); // all handles invalidated by this time
break;
case LINE_CREATE:
printf("\nLine %d Call Back ------>LINE_CREATE",dwID);
break;
case LINE_GATHERDIGITS :
printf("\nLine %d Call Back ------>LINE_LINE_GATHERDIGITS",dwID);
break;
case LINE_CALLINFO :
printf("\nLine %d Call Back ------>LINE_CALLINFO",dwID);
ADmorelineGetCallInfo(pLineInfo[dwID].hCall,&pLineInfo[dwID].lpCallInfo);
if ((dwParam1==LINECALLINFOSTATE_APPSPECIFIC) && //check dwAppSpecific state
(pLineInfo[dwID].dwCallState!=TAPI_HANGUP) && //check call is alive
(pLineInfo[dwID].lpCallInfo->dwAppSpecific==TAPI_SETAPP_ENDPLAYGREET))
{
pLineInfo[dwID].dwCallState &= ~TAPI_PLAYGREET;
FinishPlay(&pLineInfo[dwID]); //then call WaveRecord Rec ICM
OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
}
break;
default:
printf("\nLine %d Call Back ------>lineCallbackFunc message ignored",dwID);
break;
}
}
//---------------------------------------------------------------------------
long ADmorelineGetCallInfo(HCALL hCall,LINECALLINFO** ppd)
{
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,
LINEDEVCAPS** ppd)
{
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[nLineID].szLineName,
((char *) (*ppd)) + (*ppd) -> dwLineNameOffset);
}
else
{
strcpy(pLineInfo[nLineID].szLineName,"UnknowName");
}
return tr;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -