📄 modem.c
字号:
} else {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:WatchForDisconnect GetCommModemStatus failed %d\n"), GetLastError()));
break;
}
}
//
// See if we got signalled to drop via TSPI_lineDrop
//
if ((Mask == 0) || (pLineDev->dwCallFlags & CALL_DROPPING)) {
break;
}
} else {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:WatchForDisconnect WaitCommEvent failed %d\n"), GetLastError()));
break;
}
}
wfd_exit:
EnterCriticalSection(&pLineDev->OpenCS);
pLineDev->dwWaitMask = EV_DEFAULT;
LeaveCriticalSection(&pLineDev->OpenCS);
MdmCommandMode(pLineDev);
DEBUGMSG(ZONE_ASYNC, (TEXT("UNIMODEM:WatchForDisconnect Current Op=%s\n"), GetPendingName(pLineDev->dwPendingType)));
if (pLineDev->dwPendingType != PENDING_LINEDROP) {
DoDevlineDrop(pLineDev);
}
DEBUGMSG(ZONE_CALLS|ZONE_FUNCTION, (TEXT("UNIMODEM:-WatchForDisconnect\n")));
} // WatchForDisconnect
//
// Process a RING response from the modem
//
LONG
ProcessModemRing(
PTLINEDEV pLineDev
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ProcessModemRing\n")));
if (pLineDev->dwNumRings == 0) {
if (SetWatchdog(pLineDev, 25000)) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:ProcessModemRing - SetWatchDog failed!!\n")));
}
pLineDev->dwCallFlags = CALL_INBOUND;
pLineDev->dwCallState = LINECALLSTATE_OFFERING;
pLineDev->DevState = DEVST_PORTLISTENOFFER;
CallLineEventProc(
pLineDev,
0,
LINE_NEWCALL,
(DWORD)pLineDev, // HDRVCALL
(DWORD)&pLineDev->htCall, // LPHTAPICALL
0);
pLineDev->dwCurMediaModes = pLineDev->dwDefaultMediaModes | LINEMEDIAMODE_UNKNOWN;
NewCallState(pLineDev, LINECALLSTATE_OFFERING, 0);
}
CallLineEventProc(
pLineDev,
0,
LINE_LINEDEVSTATE,
LINEDEVSTATE_RINGING,
0,
pLineDev->dwNumRings);
pLineDev->dwNumRings++;
//
// If lineAnswer has been called and the answer command has not been issued, then do it now.
//
if ((PENDING_LINEANSWER == pLineDev->dwPendingType) && (!(pLineDev->dwCallFlags & CALL_ALLOCATED))) {
return ProcessModemFailure(pLineDev);
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemRing\n")));
return 0;
} // ProcessModemRing
//
// Process a CARRIER, PROTOCOL or PROGRESS response from the modem
//
LONG
ProcessModemProceeding(
PTLINEDEV pLineDev
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ProcessModemProceeding\n")));
if ((pLineDev->DevState == DEVST_PORTLISTENING) || (pLineDev->DevState == DEVST_PORTLISTENOFFER)) {
SetAsyncStatus(pLineDev, 0);
}
NewCallState(pLineDev, LINECALLSTATE_PROCEEDING, 0);
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemProceeding\n")));
return 0;
} // ProcessModemProceeding
//
// Process a CONNECT response from the modem
//
LONG
ProcessModemConnect(
PTLINEDEV pLineDev
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ProcessModemConnect\n")));
SetWatchdog( pLineDev, 0 ); // Cancel watchdog
pLineDev->dwCallFlags |= CALL_ACTIVE;
if ((pLineDev->DevState == DEVST_PORTLISTENING) || (pLineDev->DevState == DEVST_PORTLISTENOFFER)) {
pLineDev->DevState = DEVST_CONNECTED;
SetAsyncStatus(pLineDev, 0);
}
NewCallState(pLineDev, LINECALLSTATE_CONNECTED, 0);
//
// Now watch the comm state to notify of disconnect
//
WatchForDisconnect(pLineDev);
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemConnect\n")));
return 0;
} // ProcessModemConnect
//
// Process a SUCCESS response from the modem
//
LONG
ProcessModemSuccess(
PTLINEDEV pLineDev
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ProcessModemSuccess\n")));
if ((pLineDev->DevState == DEVST_PORTLISTENING) || (pLineDev->DevState == DEVST_PORTLISTENOFFER)) {
SetAsyncStatus(pLineDev, 0);
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemSuccess\n")));
return 0;
} // ProcessModemSuccess
#define DEFAULT_ANSWER_TIMEOUT 25
extern const UCHAR pchDCCResp[];
//
// Process a FAILURE response from the modem
//
// SetCommMask(0) is used to signal UnimodemControlThread when some new command
// has been requested. This gets interpreted by MdmGetResponse as a
// MODEM_FAILURE.
//
LONG
ProcessModemFailure(
PTLINEDEV pLineDev
)
{
WCHAR szTemp[256];
DWORD dwSize;
LONG rc = 0;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ProcessModemFailure\n")));
pmf_next:
switch (pLineDev->dwPendingType) {
case PENDING_LINEANSWER:
{
DWORD dwTimeout;
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure PENDING_LINEANSWER\n")));
FreeNextCmd(pLineDev);
dwTimeout = DEFAULT_ANSWER_TIMEOUT;
MdmRegGetValue(
pLineDev,
szSettings,
szAnswerTimeout,
REG_DWORD,
(PUCHAR)&dwTimeout,
&dwSize);
if (SetWatchdog(pLineDev, dwTimeout * 1000)) {
return 1;
}
pLineDev->dwCallFlags |= CALL_ALLOCATED;
if (IS_NULL_MODEM(pLineDev)) {
pLineDev->lpstrNextCmd = TSPIAlloc(strlen(pchDCCResp)+1); // answer DCC w/"CLIENTSERVER"
if (pLineDev->lpstrNextCmd) {
strcpy(pLineDev->lpstrNextCmd, pchDCCResp);
}
} else {
if (MdmRegGetValue(
pLineDev,
szSettings,
szAnswer,
REG_SZ,
(PUCHAR)szTemp,
&dwSize) == ERROR_SUCCESS) {
pLineDev->lpstrNextCmd = MdmConvertCommand(szTemp, NULL, NULL);
} else {
pLineDev->lpstrNextCmd = TSPIAlloc(sizeof(szDefaultAnswerCmd));
if (pLineDev->lpstrNextCmd) {
strcpy(pLineDev->lpstrNextCmd, szDefaultAnswerCmd);
}
}
}
if (pLineDev->lpstrNextCmd) {
MdmCommandMode(pLineDev);
if (!MdmSendCommand(pLineDev, pLineDev->lpstrNextCmd)) {
FreeNextCmd(pLineDev);
SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED);
return 2;
}
FreeNextCmd(pLineDev);
} else {
SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED);
return 3;
}
}
break;
case PENDING_EXIT:
{
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure PENDING_EXIT\n")));
return 4;
}
break;
case PENDING_LINEMAKECALL:
case PENDING_LINEDIAL:
{
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure PENDING_LINEDIAL/PENDING_LINEMAKECALL\n")));
Dialer(pLineDev);
switch (pLineDev->dwCallState) {
case LINECALLSTATE_CONNECTED:
WatchForDisconnect(pLineDev);
goto pmf_next;
case LINECALLSTATE_DIALING:
MdmGetResponse(pLineDev, "listening", NOCS, OPENED);
goto pmf_next;
}
}
break;
case PENDING_LINEDROP:
{
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure PENDING_LINEDROP\n")));
rc = DoDevlineDrop(pLineDev);
}
break;
case PENDING_LISTEN:
{
// The WatchDog that was set after the first RING has timed out
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure PENDING_LISTEN\n")));
rc = DevlineDrop(pLineDev);
}
break;
default:
{
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:ProcessModemFailure default case %d\n"), pLineDev->dwPendingType));
return 5;
}
} // switch
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ProcessModemFailure %d\n"), rc));
return rc;
} // ProcessModemFailure
BOOL
GetMonitorCommand(
PTLINEDEV pLineDev
)
{
LPWSTR lpszTemp;
DWORD dwSize;
//
// For manual dial modems, don't listen for incoming calls
//
if (pLineDev->DevMiniCfg.fwOptions & MANUAL_DIAL) {
FreeNextCmd(pLineDev);
return TRUE;
}
if (MdmRegGetValue(
pLineDev,
szSettings,
szMonitor,
REG_SZ,
NULL,
&dwSize) == ERROR_SUCCESS) {
lpszTemp = TSPIAlloc(dwSize);
if (!lpszTemp) {
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:GetMonitorCommand - Monitor cmd alloc failed 1\n")));
goto gmc_DefaultMonitorCmd;
}
if (MdmRegGetValue(
pLineDev,
szSettings,
szMonitor,
REG_SZ,
(PUCHAR)lpszTemp,
&dwSize) == ERROR_SUCCESS) {
pLineDev->lpstrNextCmd = MdmConvertCommand(lpszTemp, NULL, NULL);
TSPIFree(lpszTemp);
} else {
goto gmc_DefaultMonitorCmd;
}
} else {
gmc_DefaultMonitorCmd:
pLineDev->lpstrNextCmd = TSPIAlloc(strlen(szDefaultMonitorCmd)+1);
if (!pLineDev->lpstrNextCmd) {
DEBUGMSG(ZONE_THREAD, (TEXT("UNIMODEM:GetMonitorCommand - Monitor cmd alloc failed 2\n")));
return FALSE;
}
strcpy(pLineDev->lpstrNextCmd, szDefaultMonitorCmd);
}
return TRUE;
}
BOOL
DoModemInit(
PTLINEDEV pLineDev
)
{
BOOL bRet;
LeaveCriticalSection(&pLineDev->OpenCS);
bRet = ModemInit(pLineDev);
EnterCriticalSection(&pLineDev->OpenCS);
//
// If ModemInit got interrupted by a lineMakeCall, then proceed because
// Dialer() will perform the modem init.
//
if (FALSE == bRet) {
if (bRet = (pLineDev->dwPendingType == PENDING_LINEMAKECALL)) {
pLineDev->dwWaitMask = EV_DEFAULT;
SetCommMask(pLineDev->hDevice, EV_DEFAULT);
}
}
return bRet;
}
//
// Send commands and listen for responses until the line is closed
//
DWORD
UnimodemControlThread(
PTLINEDEV pLineDev
)
{
MODEMRESPCODES MdmResp;
DWORD rc;
BOOL bPendingOp;
HTAPICALL hPrevCall;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -