tapiwave.c
来自「一个tapi开发的很好的语音通信程序」· C语言 代码 · 共 1,109 行 · 第 1/3 页
C
1,109 行
case LINECALLSTATE_BUSY:
case LINECALLSTATE_DISCONNECTED:
if (dwParam1 == LINECALLSTATE_BUSY)
printf("BUSY. Hanging up.\n");
else
printf("DISCONNECTED. Hanging up.\n");
if (!bDropped)
dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
if (dwLineDropAsyncID < 0)
{
printf("lineDrop failed. Terminating\n");
hCall = 0;
StopEverything();
}
bDropped = TRUE;
break;
case LINECALLSTATE_OFFERING:
case LINECALLSTATE_ACCEPTED: // Could be handed off an accepted call
if (bAnswered)
break;
if (dwParam1 == LINECALLSTATE_OFFERING)
printf("Answering an OFFERING call.\r\n");
else
printf("Answering an ACCEPTED call.\r\n");
lRet = lineAnswer(hCall, NULL, 0);
// Should check to make sure lineAnswer succeeded
bAnswered = TRUE;
break;
case LINECALLSTATE_CONNECTED:
if (!bConnected)
{
bConnected = TRUE;
printf("CONNECTED.\n");
DoConnectedStuff();
if (!bDropped)
{
dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
if (dwLineDropAsyncID < 0)
{
printf("lineDrop failed. Terminating\n");
hCall = 0;
StopEverything();
}
bDropped = TRUE;
}
}
break;
}
break;
}
}
}
BOOL GetCallInfo()
{
while (TRUE)
{
if (lRet = lineGetCallInfo(hCall, lpLineCallInfo))
{
printf("lineGetCallInfo failed: %s.\n", FormatTapiError(lRet, szBuff));
return FALSE;
}
if (lpLineCallInfo->dwNeededSize > lpLineCallInfo->dwTotalSize)
{
LocalReAlloc(lpLineCallInfo, lpLineCallInfo->dwNeededSize, LMEM_MOVEABLE);
lpLineCallInfo->dwTotalSize = lpLineCallInfo->dwNeededSize;
continue;
}
return TRUE;
}
}
// Parse the command line and change the default settings.
BOOL SetupEnvironment (int argc, char * argv[])
{
int i = 0, j;
char chFlag;
BOOL bMaxCallsSet = FALSE;
if (argc == 1)
{
PrintHelp();
return FALSE;
}
while (++i < argc)
{
j = 0;
if ((argv[i][j] == '/') || (argv[i][j] == '-') || (argv[i][j] == '+'))
j = 1;
chFlag = argv[i][j++];
if (argv[i][j] == ':')
j++;
if (argv[i][j] == '\"')
j++;
switch(tolower(chFlag))
{
case '?':
printf("Runs a test of the TAPI and WAVE system.\n");
PrintHelp();
return FALSE;
case 'l':
if (!sscanf(&argv[i][j], "%lu", &dwDeviceID))
{
printf("Invalid [L]ine selection.\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
break;
case 'i':
if (!sscanf(&argv[i][j], "%lu", &dwAddressID))
{
printf("Invalid Address [I]D selection.\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
break;
case 'p':
bDontClose = TRUE;
break;
case 'x':
bLogExtraInfo = TRUE;
printf("Extra call and data flow information will be displayed.\n");
break;
case 'a':
bAnswer = TRUE;
break;
case 'd':
if (!sscanf(&argv[i][j], "%s\"", &szPhoneNumber))
{
printf("Invalid phone number selection.\r\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
bAnswer = FALSE;
break;
case 'f':
if (!sscanf(&argv[i][j], "%s\"", &szFileName))
{
printf("Invalid Wave File selection.\r\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
break;
case 'w':
if (!sscanf(&argv[i][j], "%lu", &WaveInID))
{
printf("Invalid [W]ave ID selection.\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
if (WaveInID == 99)
{
printf("Using WAVE_MAPPER.\n");
WaveOutID = WaveInID = WAVE_MAPPER;
}
else
WaveOutID = WaveInID;
bWaveLocal = TRUE;
break;
case 't':
if ((2 != sscanf(&argv[i][j], "%lu,%lu",
&dwWaveBuffers, &dwWaveBuffSize)) ||
!(dwWaveBuffers && dwWaveBuffSize))
{
printf("Invalid wave [T]est values.\n");
bCommandLineError = TRUE;
PrintHelp();
return FALSE;
}
break;
case 'z':
dwWaveMapped = 0;
break;
}
}
return TRUE;
}
// Print the help screen.
void PrintHelp()
{
printf(
"\n"
"%s [options]\n"
"\n"
"[Wave File] File to record to or play back.\n"
"\n"
"Options:\n"
"/L:# Line Device ID (dwDeviceID) to use.\n"
//"/I:# Line Address ID to use. Ignored when AutoAnswer is set.\n"
"/P Pause and wait for ^C when finished.\n"
"/X Display extra call and data flow information.\n"
"/F:file Use file as the wave file\n"
"/D:[number] Dial number\n"
"/A Answer a call\n"
"\n"
//"/W:# Specify a wave ID to use for both IN and OUT.\n"
//" If this flag is used, all TAPI is bypassed.\n"
//" A wave ID of 99 means to use WAVE_MAPPER.\n"
//"/T:#1,#2 Test wave output with a #1 buffers of size #2. ^c to terminate test.\n"
"/Z Don't use WAVE_MAPPED\n"
"\n"
"defaults: /L:%lu /I:%lu\n /F:%s /A"
"\n",
szAppName, dwDeviceID, dwAddressID, szFileName);
}
// Break Hander: Try and terminate gracefully.
// Note that ^Break can call lineShutdown *DURING* a lineMakeCall. Very
// unpredictable results; TAPI is not re-entrant and is *usually* protected by
// the Win16 Mutex. However, a Break Handler is a special case.
BOOL BreakHandlerRoutine(DWORD dwCtrlType)
{
// ^BREAK will always break.
// Use with care; it can mess up TAPI if in the middle of a TAPI API.
if (dwCtrlType == CTRL_BREAK_EVENT)
{
printf("\r\n^[Break] terminated! TAPI may not be left in a usable state.\r\n\r\n");
lineShutdown(hLineApp);
LocalFree(lpLineDevStatus);
LocalFree(lpLineCallInfo);
LocalFree(lpLineCallParams);
CloseHandle(hSleep);
ExitProcess(1);
}
else
{
if (hCall)
printf("\r\n^C Dropping call in progress.\r\n\r\n");
else
printf("\r\n^C stopped.\r\n\r\n");
StopEverything();
SetEvent(hSleep);
}
return TRUE;
}
BOOL PumpMessages(BOOL bWaitForMessage)
{
static MSG msg;
if (bReadyToEnd)
return FALSE;
if (bWaitForMessage)
{
if (!GetMessage(&msg, NULL, 0, 0))
return FALSE;
}
else
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
return TRUE;
else
if (msg.message == WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
return TRUE;
}
void StopEverything()
{
bReadyToEnd = TRUE;
if (bConnected)
StopConnectedStuff();
if (hCall && !bDropped)
{
dwLineDropAsyncID = lineDrop(hCall, NULL, 0);
if (dwLineDropAsyncID < 0)
{
printf("lineDrop failed. Terminating\n");
hCall = 0;
}
bDropped = TRUE;
}
// lets prime the pump with a message.
PostThreadMessage(dwThreadID, WM_USER, 0, 0);
}
// ---------------
// CONNECTED! Now do data steam testing. Return FALSE to stop TAPI.
BOOL DoConnectedStuff()
{
MMRESULT mmResult;
if (!bWaveLocal)
{
if (lRet = lineGetID(0, 0, hCall, LINECALLSELECT_CALL,
(LPVARSTRING) lpVarString, "wave/in"))
{
printf("lineGetID failed %s\n", FormatTapiError(lRet, szBuff));
return FALSE;
}
WaveInID = *((LPUINT)((LPBYTE) lpVarString +
(lpVarString -> dwStringOffset)));
if (lRet = lineGetID(0, 0, hCall, LINECALLSELECT_CALL,
(LPVARSTRING) lpVarString, "wave/out"))
{
printf("lineGetID failed %s\n", FormatTapiError(lRet, szBuff));
return FALSE;
}
WaveOutID = *((LPUINT)((LPBYTE) lpVarString +
(lpVarString -> dwStringOffset)));
}
printf("Using WaveInID %lu and WaveOutID %lu\n",
(DWORD) WaveInID, (DWORD) WaveOutID);
// Open the given file for reading using buffered I/O.
if(!(hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF)))
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?