📄 dial.c
字号:
{ "FCERROR", MODEM_FAILURE },
{ "FCON", MODEM_FAILURE },
{ "NOT CORRECT", MODEM_NODIALTONE },
{ "NOT READY", MODEM_NODIALTONE },
{ "OUT OF SERVICE", MODEM_NODIALTONE },
{ "PS NO RESPONSE", MODEM_NODIALTONE },
{ "RESTRICT", MODEM_NODIALTONE },
{ "RRING", MODEM_RING},
{ "VCON", MODEM_SUCCESS },
{ "VOICE", MODEM_FAILURE },
{ "+FCERROR", MODEM_FAILURE },
{ "+FCON", MODEM_FAILURE },
{ "+CRING", MODEM_RING},
{ "+CME ERROR", MODEM_FAILURE },
{ "+ILRR", MODEM_CARRIER },
{ "+MRR", MODEM_CARRIER },
};
#ifdef DEBUG
LPWSTR
ResponseName(
MODEMRESPCODES MdmRsp
)
{
switch (MdmRsp) {
case MODEM_SUCCESS: return TEXT("MODEM_SUCCESS");
case MODEM_PENDING: return TEXT("MODEM_PENDING");
case MODEM_CONNECT: return TEXT("MODEM_CONNECT");
case MODEM_FAILURE: return TEXT("MODEM_FAILURE");
case MODEM_HANGUP: return TEXT("MODEM_HANGUP");
case MODEM_NODIALTONE: return TEXT("MODEM_NODIALTONE");
case MODEM_BUSY: return TEXT("MODEM_BUSY");
case MODEM_NOANSWER: return TEXT("MODEM_NOANSWER");
case MODEM_RING: return TEXT("MODEM_RING");
case MODEM_CARRIER: return TEXT("MODEM_CARRIER");
case MODEM_PROTOCOL: return TEXT("MODEM_PROTOCOL");
case MODEM_PROGRESS: return TEXT("MODEM_PROGRESS");
case MODEM_UNKNOWN: return TEXT("MODEM_UNKNOWN");
case MODEM_IGNORE: return TEXT("MODEM_IGNORE");
case MODEM_EXIT: return TEXT("MODEM_EXIT");
default: return TEXT("UNKNOWN Modem Response Code!!!");
}
}
LPWSTR
PendingOpName(
DWORD dwPendingOp
)
{
switch (dwPendingOp){
case INVALID_PENDINGOP: return TEXT("INVALID_PENDINGOP");
case PENDING_LINEMAKECALL: return TEXT("PENDING_LINEMAKECALL");
case PENDING_LINEANSWER: return TEXT("PENDING_LINEANSWER");
case PENDING_LINEDROP: return TEXT("PENDING_LINEDROP");
case PENDING_LINEDIAL: return TEXT("PENDING_LINEDIAL");
case PENDING_LINEACCEPT: return TEXT("PENDING_LINEACCEPT");
case PENDING_LINEDEVSPECIFIC: return TEXT("PENDING_LINEDEVSPECIFIC");
case PENDING_LISTEN: return TEXT("PENDING_LISTEN");
case PENDING_EXIT: return TEXT("PENDING_EXIT");
default: return TEXT("");
} // endswitch
}
#endif // DEBUG
// The only valid NULL_MODEM response is "CLIENTSERVER"
const UCHAR pchDCCResp[] = "CLIENTSERVER";
const UCHAR pchDCCCmd[] = "CLIENT";
#define SZ_RESPONSE_TABLE (sizeof(ResponseTable)/sizeof(MODEM_RESPONSE))
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) ) )
{
// Found a match.
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, 256, NULL)) {
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));
//
// Some modems just can't take commands so fast.
//
if(pLineDev->dwCmdSendDelay) {
Sleep(pLineDev->dwCmdSendDelay);
}
// Purge any old responses sitting in serial buffer
if (PurgeComm( pLineDev->hDevice, PURGE_RXCLEAR|PURGE_TXCLEAR )) {
// 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
bRet = FALSE;
}
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 (NULL == pLineDev->htLine) {
DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:LineNotDropped line closed\n")));
return FALSE;
}
if (pLineDev->DevState == OrigDevState) {
return TRUE;
}
return FALSE;
}
#define LOW_COMPLETE_READ_THRESHOLD 15 // sizeof CONNECT 115200
MODEMRESPCODES
MdmGetResponse(
PTLINEDEV pLineDev,
PUCHAR pszCommand,
BOOL bLeaveCS,
BOOL bOpened
)
{
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;
BOOL bStatus;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+MdmGetResponse for %a\r\n"), pszCommand));
OrigDevState = pLineDev->DevState;
OrigPendingOp = pLineDev->dwPendingType;
bInCS = bLeaveCS;
EnterCriticalSection(&pLineDev->OpenCS);
if (pLineDev->dwWaitMask) {
SetCommMask(pLineDev->hDevice, EV_DEFAULT);
}
LeaveCriticalSection(&pLineDev->OpenCS);
// Wait until we get some type of meaningful response from the modem
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -