📄 dial.cpp
字号:
LPVOID ReAllocBuffer(LPVOID lpBuffer,size_t sizeBufferMinimum)
{
size_t sizeBuffer;
if (lpBuffer == NULL) // allocate the buffer if necessary
{
sizeBuffer = sizeBufferMinimum;
lpBuffer = (LPVOID) LocalAlloc (LPTR, sizeBuffer);
if (lpBuffer == NULL)
{
printf("\nLocalAlloc failed in CheckAndReAllocBuffer.");
return NULL;
}
}
else // if the structure already exists, make sure it is good
{
sizeBuffer = LocalSize((HLOCAL) lpBuffer);
if (sizeBuffer == 0) // bad pointer?
{
printf("\nBad pointer");
return NULL;
}
// Was the buffer big enough for the structure?
if (sizeBuffer < sizeBufferMinimum)
{
LocalFree(lpBuffer);
return ReAllocBuffer(NULL, sizeBufferMinimum);
}
}
// Set the dwTotalSize field to the size of the buffer or the call will
// fail.
memset(lpBuffer, 0, sizeBuffer);
((LPVARSTRING) lpBuffer ) -> dwTotalSize = (DWORD) sizeBuffer;
return lpBuffer;
}
//---------------------------------------------------------------------------
LPLINECALLPARAMS CreateCallParams (LPLINECALLPARAMS lpCallParams,
LPCSTR lpszDisplayableAddress)
{
size_t sizeDisplayableAddress;
if (lpszDisplayableAddress == NULL)
lpszDisplayableAddress = "";
sizeDisplayableAddress = strlen(lpszDisplayableAddress) + 1;
lpCallParams = (LPLINECALLPARAMS) ReAllocBuffer(
(LPVOID) lpCallParams,
sizeof(LINECALLPARAMS) + sizeDisplayableAddress);
if (lpCallParams == NULL)
return NULL;
// This is where we configure the line.
lpCallParams -> dwBearerMode = LINEBEARERMODE_VOICE;
lpCallParams -> dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE ;//LINEMEDIAMODE_DATAMODEM;
// This specifies that we want to use only IDLE calls and
// don't want to cut into a call that might not be IDLE (ie, in use).
lpCallParams -> dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
// If there are multiple addresses on line, use first anyway.
// It will take a more complex application than a simple tty app
// to use multiple addresses on a line anyway.
lpCallParams -> dwAddressMode = LINEADDRESSMODE_ADDRESSID;
//lpCallParams -> dwNoAnswerTimeout = 5;
// Address we are dialing.
lpCallParams -> dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
lpCallParams -> dwDisplayableAddressSize = sizeDisplayableAddress;
strcpy((LPSTR)lpCallParams + sizeof(LINECALLPARAMS),
lpszDisplayableAddress);
return lpCallParams;
}
//---------------------------------------------------------------------------
void SelectChn()
{
do
{
printf("\nSelect 0~%d Channel to make a call : ",(m_nLines-1));
scanf("%d", &dwActiveChn);
} while (dwActiveChn >= m_nLines);
/* input phone number for channel you select to dial*/
printf("Enter phone number of CH<%d> [%s] : ",dwActiveChn,pLineInfo[dwActiveChn].szLineName);
scanf("%s",pLineInfo[dwActiveChn].tcDialNo);
}
//---------------------------------------------------------------------------
void CallOut(LPLINEINFO pLineData)
{
HCALL m_hCall;
LPLINECALLPARAMS lpCallParams;
lpCallParams=NULL;
lpCallParams=CreateCallParams(lpCallParams,pLineData->tcDialNo);
LONG tr = lineMakeCall(pLineData->hLine,
&m_hCall,
pLineData->tcDialNo,
0,
lpCallParams);
if (tr > 0)
{
pLineData->hCall = m_hCall;
printf("\nLine %d Placing a call to %s ...",pLineData->nLineID,pLineData->tcDialNo);
}
else
{
pLineData->hCall = 0;
printf("\nLine %d Can't make a call on line ...",pLineData->nLineID);
lineClose(pLineData->hLine);
}
}
//---------------------------------------------------------------------------
BOOL OpenLine(LPLINEINFO pLineData)
{
HLINE m_hLine;
DWORD nLineID = pLineData->nLineID;
if((ADmoreGetLineDevCaps(m_hLineApp,
pLineData->dwApiVersion,
nLineID,
&pldc)==0) &&
(pldc->dwBearerModes & LINEBEARERMODE_VOICE) &&
(pldc->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) &&
(pldc->dwLineFeatures & LINEFEATURE_MAKECALL) )
{
if( lineOpen(m_hLineApp, nLineID, &m_hLine, pLineData->dwApiVersion,
0, 0, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_INTERACTIVEVOICE, NULL)==0 )
{
printf("\nLine %d open ...", pLineData->nLineID);
pLineData->hLine = m_hLine;
/*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
CallOut(pLineData);
return TRUE;
}
else
{
printf("\n###Cannot Open Line %d (%s)!\n\n", nLineID,pLineData->szLineName);
return FALSE;
}
}
else
{
printf("\n### Line %d is not device for interactive voice ! (%s)\n\n",
nLineID,pLineData->szLineName);
return FALSE;
}
}
//---------------------------------------------------------------------------
long InitializeLines(DWORD dwLoVersion, DWORD dwHiVersion)
{
DWORD m_aApiVersions;
LONG tr = lineInitialize(&m_hLineApp,
NULL,
ADmorelineCallbackFunc,
"Duncan",
&m_nLines);
if ( tr == 0 )
{
/* Allocation a block memory to all channel */
pLineInfo = new LINEINFO[m_nLines];
ZeroMemory(pLineInfo,sizeof(LINEINFO)*m_nLines);
if( m_nLines )
{
//Negotiate the API versions
LINEEXTENSIONID extid;
for(WORD nLineID=0; nLineID < m_nLines; nLineID++) //m_nLines
{
tr = lineNegotiateAPIVersion(m_hLineApp,
nLineID,
dwLoVersion,
dwHiVersion,
&m_aApiVersions,
&extid);
if( tr < 0 )
{
pLineInfo[nLineID].dwApiVersion = 0;
tr = 0;
}
else
{
pLineInfo[nLineID].dwApiVersion = m_aApiVersions;
}
ADmoreGetLineDevCaps(m_hLineApp,
pLineInfo[nLineID].dwApiVersion, nLineID,&pldc);
pLineInfo[nLineID].lpWaveDataAlloc = (HPSTR) LocalAlloc(LMEM_MOVEABLE, 0); //123000
pLineInfo[nLineID].nLineID = nLineID;
}
}
}
return tr;
}
//===========================================================================
// Main Program
//===========================================================================
int main(int argc,char **argv)
{
MSG msg;
BOOL fSuccess;
lpDeviceID = (LPVARSTRING) new char[sizeof(VARSTRING) + 64];
lpDeviceID->dwTotalSize = sizeof (VARSTRING) + 64;
fSuccess = SetConsoleCtrlHandler((PHANDLER_ROUTINE) ExitCtrlHandler //handle function
, TRUE); //add to list
if (!fSuccess) printf("\nCound not set control handler.");
SetProcessShutdownParameters(0x280, SHUTDOWN_NORETRY);//terminates without displaying
//a retry dialog box for the user.
if (InitializeLines(TAPI_VERSION_1_0, TAPI_VERSION_2_0) != NOERR)
{
printf("\n\r###Fail to initialize driver !");
exit(1);
}
if ( m_nLines > 0 )
printf("\nTotal %d channels supported.", m_nLines);
else
{
printf("\nNo channels supported.");
printf("\nPress any key to exit.\n");
getch();
return 1;
}
for (DWORD i=0 ; i < m_nLines; i++)
printf("\nChannel %d Name: [%s]",i,pLineInfo[i].szLineName);
printf("\npress Ctrl-C to exit.");
SelectChn();
while(!OpenLine(&pLineInfo[dwActiveChn])) SelectChn();
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/* program exits in ExitCtrlHandler*/
return 1; //satisfy compiler only
}
//---------------------------------------------------------------------------
// End Main
//---------------------------------------------------------------------------
BOOL ExitCtrlHandler(DWORD fdwCtrlType)
{
delete lpDeviceID;
lineShutdown(m_hLineApp);
printf("\nLine Shutdown.");
for (DWORD i = 0; i < m_nLines; i++)
if (pLineInfo[i].lpWaveDataAlloc)
LocalFree(pLineInfo[i].lpWaveDataAlloc);
delete pLineInfo;
ExitProcess(1);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -