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 + -
显示快捷键?