dial.c
来自「wince下的源代码集合打包」· C语言 代码 · 共 1,946 行 · 第 1/5 页
C
1,946 行
{ if( (CR == InBuf[i]) || (LF == InBuf[i]) || ((DWORD)i == dwLen-1) || ((pLineDev->dwMaxCmd - 1) <= ModemResponseIndex) ) { // have a complete response (or max length). Now we parse it. ModemResponse[ModemResponseIndex] = 0; // Lets Zero Terminate the string ModemResp = ModemResponseHandler( pLineDev, ModemResponse, pszCommand ); switch (ModemResp) { case MODEM_CARRIER: ParseConnectSpeed(pLineDev, ModemResponse); // fall through!!! case MODEM_PROTOCOL: case MODEM_PROGRESS: NewCallState(pLineDev, LINECALLSTATE_PROCEEDING, 0L); if (i < (int)(dwLen - 1)) { ModemResponseIndex = 0; // Start a new response ModemResp = MODEM_IGNORE; } break; case MODEM_UNKNOWN: case MODEM_IGNORE: ModemResponseIndex = 0; // Start a new response ModemResp = MODEM_IGNORE; break; case MODEM_CONNECT: ParseConnectSpeed(pLineDev, ModemResponse); // fall through default: goto mgr_exit; } ModemResponseIndex = 0; // Start a new response } else { ModemResponseIndex++; //Add another character to the string } } } } } else { // A zero ModemStat is an error, and indicates that the // waitcommevent was stopped by our watchdog or linedrop. ModemResp = MODEM_FAILURE; DEBUGMSG (ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - Timeout\r\n"))); goto mgr_exit; } DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse %s\n"), ResponseName(ModemResp))); } except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Must have been a bad handle. Give up ModemResp = MODEM_FAILURE; DEBUGMSG (ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:MdmGetResponse - Exception. Handle \r\n"), pLineDev->hDevice )); } } mgr_exit: if (bInCS) { LeaveCriticalSection(&pLineDev->OpenCS); } DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-MdmGetResponse %s\r\n"), ResponseName(ModemResp))); return ModemResp;}//// There were cases where the ModemWatchdog thread would not make it to the WaitForSingleObject// before the next SetWatchdog happened. This would leave two or more watchdogs runnning at the// same time which leads to all kinds of problems. Now SetWatchdog passes a UNIMODEM_WATCHDOG_INFO// structure to the thread and the watchdog checks that it is the current one before aborting// any pending operations.//typedef struct _UNIMODEM_WATCHDOG_INFO { PTLINEDEV pLineDev; DWORD dwTimeout; DWORD dwThisWatchdog;} UNIMODEM_WATCHDOG_INFO, * PUNIMODEM_WATCHDOG_INFO;// **********************************************************************//// This is the dialer/answer watchdog thread. It is created by the dialer thread.// Its purpose is to wait for a specified interval, or until signalled by// the dialer. If the wait times out, then the watchdog calls into the// COM port driver, causing the waitcommevent in the dialer thread to// return.// // **********************************************************************voidModemWatchdog( PUNIMODEM_WATCHDOG_INFO pWDInfo ){ DWORD RetCode; BOOL bAbort; PTLINEDEV pLineDev; DWORD dwTimeout; DWORD dwThisWatchdog; pLineDev = pWDInfo->pLineDev; dwTimeout = pWDInfo->dwTimeout; dwThisWatchdog = pWDInfo->dwThisWatchdog; TSPIFree(pWDInfo); DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:+ModemWatchdog(%d) - timeout set to %d seconds\r\n"), dwThisWatchdog, dwTimeout/1000)); // Wait for the specified interval. RetCode = WaitForSingleObject( pLineDev->hTimeoutEvent, dwTimeout ); if ((dwThisWatchdog == pLineDev->dwCurWatchdog) && ( WAIT_TIMEOUT == RetCode )) { pLineDev->bWatchdogTimedOut = TRUE; DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemWatchdog(%d) *** %s TIMEOUT!\n"), dwThisWatchdog, GetPendingName(pLineDev->dwPendingType))); // We need to stop the waitcommevent. Note that we set the // mask to 0, which will cause any subsequent waitcommevent // calls to also return immediately. ToggleCommMask(pLineDev); switch (pLineDev->dwPendingType) { case PENDING_LINEMAKECALL: // // Allow an in progress DCC lineMakeCall to retry // bAbort = !(IS_NULL_MODEM(pLineDev)); break; case PENDING_LINEANSWER: NewCallState(pLineDev, LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_UNKNOWN); NewCallState(pLineDev, LINECALLSTATE_IDLE, 0L); bAbort = TRUE; break; case PENDING_LINEDIAL: case PENDING_LINEDROP: bAbort = TRUE; break; default: bAbort = FALSE; break; } // We set an event when we are done so that DevLineDrop can // continue with his cleanup. if (bAbort) { SetEvent(pLineDev->hCallComplete); SetAsyncStatus(pLineDev, LINEERR_OPERATIONFAILED); } }#ifdef DEBUG else { DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemWatchdog(%d) cancelled\r\n"), dwThisWatchdog)); }#endif // This is a one shot timeout. The thread should go away as // soon as the timer expires or is signalled/cancelled.}// **********************************************************************// Wrapper function to start the watchdog.// Note that a timeout of 0 cancels the current watchdog.// **********************************************************************DWORDSetWatchdog( PTLINEDEV pLineDev, DWORD dwTimeout ){ HANDLE hThread; PUNIMODEM_WATCHDOG_INFO pWDInfo; pLineDev->dwCurWatchdog++; pLineDev->bWatchdogTimedOut = FALSE; // First, lets cancel any current outstanding watchdogs for this line PulseEvent(pLineDev->hTimeoutEvent); // Stop the watchdog // And now, start a new watchdog if they want us to if( dwTimeout ) { pWDInfo = TSPIAlloc(sizeof(UNIMODEM_WATCHDOG_INFO)); if (NULL == pWDInfo) { NKDbgPrintfW( TEXT("UNIMODEM:SetWatchDog Unable to alloc Watchdog info\n") ); return (DWORD)-1; } pWDInfo->pLineDev = pLineDev; pWDInfo->dwTimeout = dwTimeout; pWDInfo->dwThisWatchdog = pLineDev->dwCurWatchdog; hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ModemWatchdog, pWDInfo, 0, NULL ); if ( ! hThread ) { TSPIFree(pWDInfo); NKDbgPrintfW( TEXT("UNIMODEM:SetWatchDog Unable to Create Watchdog Thread\n") ); return (DWORD)-1; } CeSetThreadPriority(hThread, g_dwUnimodemThreadPriority); CloseHandle( hThread ); } return STATUS_SUCCESS;}BOOLModemInit( PTLINEDEV pLineDev ){ MODEMRESPCODES MdmResp = MODEM_FAILURE; DWORD dwSize, dwCmdLen; int RetryCount = 0; PWCHAR pszTemp = NULL; PWCHAR pszExpand = NULL; PCHAR pchCmd = NULL; MODEMMACRO ModemMacro; DWORD dwCallSetupFailTimer; DEVSTATES OrigDevState; static const WCHAR szReset[] = TEXT("Reset"); static const WCHAR szFlowHard[] = TEXT("FlowHard"); static const WCHAR szFlowSoft[] = TEXT("FlowSoft"); static const WCHAR szFlowNone[] = TEXT("FlowOff"); static const WCHAR *szFlowType; // Hard, Soft, None static const WCHAR szCallFail[] = TEXT("CallSetupFailTimeout"); static const UCHAR szEscapeCmd[] = "+++"; OrigDevState = pLineDev->DevState; try { DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ModemInit\r\n"))); // Allocate temp buffers for registry results pszTemp = (PWCHAR)TSPIAlloc( (pLineDev->dwMaxCmd + 1) * SZWCHAR ); pszExpand = (PWCHAR)TSPIAlloc( (pLineDev->dwMaxCmd + 1) * SZWCHAR ); pchCmd = (PCHAR)TSPIAlloc( pLineDev->dwMaxCmd + 1 ); // First, read the reset command from the registry dwSize = pLineDev->dwMaxCmd * SZWCHAR; if (ERROR_SUCCESS != MdmRegGetValue( pLineDev, szSettings, szReset, REG_SZ, (PUCHAR)pszTemp, &dwSize) ) { goto init_error; } MdmConvertCommand(pszTemp, pchCmd, &dwCmdLen); DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Reset string is \"%s\" (%d)\r\n"), pszTemp, dwCmdLen)); // ***** reset modem by clearing DTR if(LineNotDropped(pLineDev, OrigDevState)) { DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit SetCommState - DTR off\r\n"))); EscapeCommFunction ( pLineDev->hDevice, CLRDTR); Sleep( 400 ); } if(LineNotDropped(pLineDev, OrigDevState)) { DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit SetCommState - DTR on\r\n"))); EscapeCommFunction ( pLineDev->hDevice, SETDTR); Sleep( 200 ); } // No matter what the state was, we are now initializing pLineDev->MdmState = MDMST_INITIALIZING; while( (LineNotDropped(pLineDev, OrigDevState)) && (RetryCount < MAX_COMMAND_TRIES) ) { // Set short timeout for init strings if( SetWatchdog( pLineDev, 8000 ) ) { pLineDev->MdmState = MDMST_UNKNOWN; goto init_error; } if( LineNotDropped(pLineDev, OrigDevState) ) { DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Send Init\r\n"))); MdmResp = MODEM_FAILURE; if (MdmSendCommand( pLineDev, pchCmd )) { MdmResp = MdmGetResponse( pLineDev, pchCmd, NOCS ); } } // See if we managed to get initialized if( MODEM_SUCCESS == MdmResp ) { pLineDev->MdmState = MDMST_DISCONNECTED; // It worked break; } else { if( LineNotDropped(pLineDev, OrigDevState) ) { // the modem didn't reset pLineDev->MdmState = MDMST_UNKNOWN; // If szReset didn't work, we likely need a +++ MdmSendCommand( pLineDev, szEscapeCmd ); Sleep( 200 ); } } RetryCount++; } if( (MDMST_DISCONNECTED == pLineDev->MdmState) && (LineNotDropped(pLineDev, OrigDevState)) ) { DWORD mdmRegRslt = ERROR_SUCCESS; WORD wInitKey; // read a sequence of additional init strings from the // registry and send them down now. Can't enumerate the // keys since that wouldn't allow us to have modem specific // values mixed with default values. wInitKey = 0; while( (wInitKey < MAXINITKEYS) && (LineNotDropped(pLineDev, OrigDevState)) && (ERROR_SUCCESS == mdmRegRslt) ) { dwSize = pLineDev->dwMaxCmd * SZWCHAR; mdmRegRslt = MdmRegGetValue( pLineDev, szInit, szInitNum[wInitKey], REG_SZ, (PUCHAR)pszTemp, &dwSize); if (ERROR_SUCCESS == mdmRegRslt) { MdmConvertCommand(pszTemp, pchCmd, &dwCmdLen); DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Init string %d - %s\r\n"), wInitKey, pszTemp)); // Set short timeout for init strings if( SetWatchdog( pLineDev, 8000 ) ) { pLineDev->MdmState = MDMST_UNKNOWN; goto init_error; } if (LineNotDropped(pLineDev, OrigDevState)) { // We got a value, write it out to modem MdmResp = MODEM_FAILURE; if (MdmSendCommand( pLineDev, pchCmd )) { if (LineNotDropped(pLineDev, OrigDevState)) { MdmResp = MdmGetResponse( pLineDev, pchCmd, NOCS ); } } } if( MODEM_SUCCESS != MdmResp ) { // bad init string. We can't recover from this so exit pLineDev->MdmState = MDMST_UNKNOWN; goto init_error; } } else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?