📄 dial.c
字号:
MODEMRESPCODES
ModemResponseHandler(
PTLINEDEV pLineDev,
PUCHAR pszResponse,
PUCHAR pszOrigCommand
)
{
UINT16 wRespCode = MODEM_UNKNOWN;
int i;
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:+ModemResponseHandler x%X, x%X, x%X\r\n"),
pLineDev, pszResponse, pszOrigCommand));
// Lets remove any leading CR/LF from response.
while( (CR == *pszResponse) || (LF == *pszResponse) )
pszResponse++;
if( 0 == *pszResponse )
{
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-ModemResponseHandler, Empty response\r\n")));
return MODEM_IGNORE;
}
DEBUGMSG(ZONE_CALLS,
(TEXT("UNIMODEM:ModemResponseHandler Modem Response '%a'\r\n"), pszResponse));
// Lets remove any leading CR/LF from orig command.
while( (CR == *pszOrigCommand) || (LF == *pszOrigCommand) )
pszOrigCommand++;
// First, check to see if this is just an echo of the command
if( NULL != pszOrigCommand )
{
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:ModemResponseHandler Checking for echo of CMD %a\r\n"), pszOrigCommand));
if( ! strncmpi( pszResponse, pszOrigCommand, strlen(pszResponse) ) )
{
// Ignore this, it was just a duplicate
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-ModemResponseHandler, Command Echo\r\n")));
return MODEM_IGNORE;
}
}
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:ModemResponseHandler response was not an echo\r\n")));
// Regular Modems have a lookup table for responses
// Lets convert the ASCII response to a numeric code
for( i=0; i<SZ_RESPONSE_TABLE; i++ )
{
if( !strncmpi( pszResponse, ResponseTable[i].pszResponse,
(strlen(ResponseTable[i].pszResponse) - 1) ) )
{
wRespCode = ResponseTable[i].ModemRespCode;
break;
}
}
DEBUGMSG(ZONE_CALLS|ZONE_FUNC,
(TEXT("UNIMODEM:-ModemResponseHandler, %s\n"), ResponseName(wRespCode) ));
return wRespCode;
}
//
// Expand macros and convert command to chars
//
LPSTR
MdmConvertCommand(
WCHAR const *pszWCommand,
LPSTR pchCmd,
LPDWORD lpdwSize
)
{
LPSTR lpstr;
WCHAR szExpand[256];
DWORD dwCmdLen;
if (pchCmd) {
lpstr = pchCmd;
} else {
lpstr = NULL;
}
if (!ExpandMacros((PWCHAR)pszWCommand, (PWCHAR)szExpand, 0, NULL, 0)) {
return NULL;
}
dwCmdLen = wcslen(szExpand) + 1;
if (lpstr == NULL) {
lpstr = TSPIAlloc(dwCmdLen);
if (lpstr == NULL) {
return NULL;
}
}
dwCmdLen = wcstombs( lpstr, szExpand, dwCmdLen );
if (lpdwSize) {
*lpdwSize = dwCmdLen;
}
return lpstr;
}
BOOL
MdmSendCommand(
PTLINEDEV pLineDev,
UCHAR const *pszCommand
)
{
DWORD dwLen;
BOOL bRet = FALSE;
//
// This routine sends a Modem command, and then waits for
// a valid response from the modem (or timeout).
//
try
{
if( (HANDLE)INVALID_DEVICE != pLineDev->hDevice )
{
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmSendCommand '%a'\r\n"), pszCommand));
// Purge any old responses sitting in serial buffer
if (PurgeComm( pLineDev->hDevice, PURGE_RXCLEAR|PURGE_TXCLEAR )) {
// Set the Comm Mask for waitcommevent
if (SetCommMask(pLineDev->hDevice, EV_DEFAULT)) {
// Now, lets send this nice new string to the modem
bRet = WriteFile(pLineDev->hDevice, (LPVOID)pszCommand, strlen((LPVOID)pszCommand), &dwLen, 0 );
if ((FALSE == bRet) || (dwLen != strlen((LPVOID)pszCommand))) {
bRet = FALSE;
RETAILMSG (1,
(TEXT("UNIMODEM:!!!MdmSendCommand wrote %d of %d byte dial string\r\n"),
dwLen, strlen((LPVOID)pszCommand)) );
DEBUGMSG(ZONE_MISC,
(TEXT("UNIMODEM:MdmSendCommand Wrote %d bytes of %d byte dial string\r\n"),
dwLen, strlen((LPVOID)pszCommand)) );
}
}
}
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Just return of handle is bad
}
WriteModemLog(pLineDev, (PUCHAR)pszCommand, bRet ? MDMLOG_COMMAND_OK : MDMLOG_COMMAND_FAIL);
return bRet;
}
#ifdef DEBUG
void
DisplayModemStatus(
DWORD ModemStat
)
{
WCHAR szModemStat[256];
szModemStat[0] = 0;
if( ModemStat & EV_BREAK)
wcscat(szModemStat, TEXT(" EV_BREAK"));
if( ModemStat & EV_CTS)
wcscat(szModemStat, TEXT(" EV_CTS"));
if( ModemStat & EV_DSR)
wcscat(szModemStat, TEXT(" EV_DSR"));
if( ModemStat & EV_ERR)
wcscat(szModemStat, TEXT(" EV_ERR"));
if( ModemStat & EV_RING)
wcscat(szModemStat, TEXT(" EV_RING"));
if( ModemStat & EV_RLSD)
wcscat(szModemStat, TEXT(" EV_RLSD"));
if( ModemStat & EV_RXCHAR)
wcscat(szModemStat, TEXT(" EV_RXCHAR"));
if( ModemStat & EV_RXFLAG)
wcscat(szModemStat, TEXT(" EV_RXFLAG"));
if( ModemStat & EV_TXEMPTY)
wcscat(szModemStat, TEXT(" EV_TXEMPTY"));
DEBUGMSG (ZONE_MISC, (TEXT("UNIMODEM:DisplayModemStatus ModemStat =%s\n"), szModemStat));
} // DisplayModemStatus
void
DisplayCommError(
DWORD dwCommError
)
{
WCHAR szCommError[256];
szCommError[0] = 0;
if (dwCommError & CE_BREAK) {
wcscat(szCommError, TEXT(" CE_BREAK"));
}
if (dwCommError & CE_FRAME) {
wcscat(szCommError, TEXT(" CE_FRAME"));
}
if (dwCommError & CE_IOE) {
wcscat(szCommError, TEXT(" CE_IOE"));
}
if (dwCommError & CE_MODE) {
wcscat(szCommError, TEXT(" CE_MODE"));
}
if (dwCommError & CE_OOP) {
wcscat(szCommError, TEXT(" CE_OOP"));
}
if (dwCommError & CE_OVERRUN) {
wcscat(szCommError, TEXT(" CE_OVERRUN"));
}
if (dwCommError & CE_RXOVER) {
wcscat(szCommError, TEXT(" CE_RXOVER"));
}
if (dwCommError & CE_RXPARITY) {
wcscat(szCommError, TEXT(" CE_RXPARITY"));
}
if (dwCommError & CE_TXFULL) {
wcscat(szCommError, TEXT(" CE_TXFULL"));
}
if (dwCommError & CE_DNS) {
wcscat(szCommError, TEXT(" CE_DNS"));
}
if (dwCommError & CE_PTO) {
wcscat(szCommError, TEXT(" CE_PTO"));
}
DEBUGMSG (ZONE_MISC, (TEXT("UNIMODEM:DisplayCommError CommError=%s\n"), szCommError));
} // DisplayCommError
#endif
BOOL
LineNotDropped(
PTLINEDEV pLineDev,
DEVSTATES OrigDevState
)
{
if (pLineDev->DevState == OrigDevState) {
return TRUE;
}
return FALSE;
}
MODEMRESPCODES
MdmGetResponse(
PTLINEDEV pLineDev,
PUCHAR pszCommand,
BOOL bLeaveCS
)
{
MODEMRESPCODES ModemResp = MODEM_IGNORE;
DWORD ModemStat;
UCHAR InBuf[MAXSTRINGLENGTH];
int i;
UCHAR ModemResponse[MAXSTRINGLENGTH];
UINT16 ModemResponseIndex = 0;
DWORD dwLen;
DEVSTATES OrigDevState;
PUCHAR pchDCC; // either pchDCCCmd or pchDCCResp
MODEMRESPCODES DCCResp;
DWORD dwDCCLen;
BOOL bInCS;
DWORD OrigPendingOp;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+MdmGetResponse for %a\r\n"), pszCommand));
OrigDevState = pLineDev->DevState;
OrigPendingOp = pLineDev->dwPendingType;
bInCS = bLeaveCS;
// Wait until we get some type of meaningful response from the modem
while ((MODEM_IGNORE == ModemResp) && LineNotDropped(pLineDev, OrigDevState))
{
try
{
ModemStat = 0;
if (bInCS) {
//
// To help avoid missing signals from SignalControlThread, stay in CS as long
// as possible before calling WaitCommEvent.
//
LeaveCriticalSection(&pLineDev->OpenCS);
bInCS = FALSE;
}
if (!WaitCommEvent( pLineDev->hDevice, &ModemStat, NULL)) {
dwLen = GetLastError();
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - WaitCommEvent failed %d\n"), dwLen));
ModemResp = MODEM_EXIT;
goto mgr_exit;
}
if (pLineDev->bWatchdogTimedOut) {
pLineDev->bWatchdogTimedOut = FALSE;
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - Watchdog timed out\n")));
ModemResp = MODEM_EXIT;
goto mgr_exit;
}
//
// Look for signals from SignalControlThread
//
if (pLineDev->dwPendingType != OrigPendingOp) {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - Interrupted\n")));
ModemResp = MODEM_FAILURE;
goto mgr_exit;
}
if (ModemStat) {
#ifdef DEBUG
DisplayModemStatus(ModemStat);
#endif
if (ModemStat & EV_ERR) {
if (ClearCommError(pLineDev->hDevice, &dwLen, NULL)) {
#ifdef DEBUG
if (dwLen) {
DisplayCommError(dwLen);
}
} else {
dwLen = GetLastError();
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse ClearCommError failed %d\n"), dwLen));
#endif
}
}
if( ModemStat & EV_RING) {
ModemResp = MODEM_RING;
}
if ((ModemStat & EV_RXCHAR) && LineNotDropped(pLineDev, OrigDevState))
{
if (!ReadFile (pLineDev->hDevice, (LPVOID)InBuf, sizeof(InBuf), &dwLen, 0)) {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - ReadFile failed %d\n"), GetLastError()));
ModemResp = MODEM_EXIT;
goto mgr_exit;
}
InBuf[dwLen] = 0;
WriteModemLog(pLineDev, (PUCHAR)InBuf, MDMLOG_RESPONSE);
#ifdef DEBUG_RESPONSES
if (dwLen) {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse Response = %a\n"), InBuf));
}
#endif
// Now lets process each response as they arrive
for( i=0; i<(int)dwLen; i++ )
{
ModemResponse[ModemResponseIndex] = InBuf[i];
if( IS_NULL_MODEM(pLineDev) )
{
//
// Only allow one response per call to MdmGetResponse for a DCC connection
//
ModemResp = MODEM_FAILURE;
//
// Are we client or server?
//
if (pLineDev->dwPendingType == PENDING_LINEMAKECALL) {
pchDCC = (PUCHAR)pchDCCResp;
DCCResp = MODEM_CONNECT;
} else {
pchDCC = (PUCHAR)pchDCCCmd;
DCCResp = MODEM_RING;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -