⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dial.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 - 1);
        CloseHandle( hThread );
    }
    return STATUS_SUCCESS;
}

#define INIT_WATCHDOG_TIMEOUT 4000

BOOL
ModemInit(
    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;
    BOOL bFailed;
    BOOL bEscapeSent;   // only send "+++" once.
    MDMSTATE NewMdmState;

    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[] = "+++";
    
    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ModemInit\r\n")));

    EnterCriticalSection(&pLineDev->OpenCS);
    if (bFailed = (pLineDev->MdmState == MDMST_INITIALIZING)) {
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Already MDMST_INITIALIZING!\r\n")));
    } else {
        pLineDev->MdmState = MDMST_INITIALIZING;
        OrigDevState = pLineDev->DevState;
    }
    LeaveCriticalSection(&pLineDev->OpenCS);

    if (bFailed) {
        return FALSE;
    }

    bFailed = TRUE;
    bEscapeSent = FALSE;
    NewMdmState = MDMST_UNKNOWN;

    try
    {

        // 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 );
        if (!(pszTemp && pszExpand && pchCmd))
        {
            goto init_error;
        }
    
        // 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 EscapeCommFunction - DTR off\r\n")));
            EscapeCommFunction ( pLineDev->hDevice, CLRDTR);
            Sleep( 400 );
        }
    
    
        if(LineNotDropped(pLineDev, OrigDevState))
        {
            DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit EscapeCommFunction - DTR on\r\n")));
            EscapeCommFunction ( pLineDev->hDevice, SETDTR);
            Sleep( 200 );
        }
    
        while( (LineNotDropped(pLineDev, OrigDevState)) &&
                 (RetryCount < MAX_COMMAND_TRIES) )
        {
            // Set short timeout for init strings
            if( SetWatchdog( pLineDev, INIT_WATCHDOG_TIMEOUT ) )
            {
                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, OPENED);
                }
            }
        
            // See if we managed to get initialized
            if( MODEM_SUCCESS == MdmResp )
            {
                NewMdmState = MDMST_DISCONNECTED;  // It worked
                break;
            }
            else
            {
                if (bEscapeSent) {
                    //
                    // Avoid trying "+++" 3 times. If there is no modem on the port
                    // we'd take over 15 seconds to fail. If there is a modem, one "+++"
                    // ought to be enough.
                    //
                    goto init_error;
                } else {
                    bEscapeSent = TRUE;
                    if( LineNotDropped(pLineDev, OrigDevState) )
                    {
                        // the modem didn't reset
                        NewMdmState = MDMST_UNKNOWN;

                        // If szReset didn't work, we likely need a +++
                        MdmSendCommand( pLineDev, szEscapeCmd );
                        Sleep( 200 );
                    }
                }
            }
            RetryCount++;
        }

        if( (MDMST_DISCONNECTED == NewMdmState) &&
            (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, INIT_WATCHDOG_TIMEOUT ) )
                    {
                        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, OPENED);
                            }
                        }
                    }
                    if( MODEM_SUCCESS != MdmResp )
                    {
                        // bad init string.  We can't recover from this so exit
                        goto init_error;
                    }
                }
                else
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:ModemInit Error x%X reading Init string %d\r\n"),
                                          mdmRegRslt, wInitKey));
                }
            
                wInitKey++;
            }

            // And now that we have the basic init in place, we still need to
            // make sure the flow control settings match what we are doing in
            // the UART.
            if( MDM_FLOWCONTROL_HARD & pLineDev->DevMiniCfg.dwModemOptions )
            {  // Set Modem for hardware flow control
                szFlowType = szFlowHard;
            }
            else  if( MDM_FLOWCONTROL_SOFT & pLineDev->DevMiniCfg.dwModemOptions )
            {  // Set Modem for software flow control
                szFlowType = szFlowSoft;            
            }
            else
            {  // Set modem for no flow control
                szFlowType = szFlowNone;            
            }
            dwSize = pLineDev->dwMaxCmd * SZWCHAR;
            if( ERROR_SUCCESS == MdmRegGetValue( pLineDev,
                                                 szSettings,
                                                 szFlowType,
                                                 REG_SZ,
                                                 (PUCHAR)pszTemp,
                                                 &dwSize) )
            {
                // OK, we got the flow control command, send it.
                MdmConvertCommand(pszTemp, pchCmd, &dwCmdLen);
                DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Flow Control string %s\r\n"),
                                      pszTemp));
            
                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, OPENED);
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // bad flow control string.  We can't recover from this.
                    goto init_error;
                }
            }

            // Now we set up the call fail timer if it exists.
            dwSize = pLineDev->dwMaxCmd * SZWCHAR;
            if( ERROR_SUCCESS == MdmRegGetValue( pLineDev,
                                                 szSettings,
                                                 szCallFail,
                                                 REG_SZ,
                                                 (PUCHAR)pszTemp,
                                                 &dwSize) )
            {
                // OK, we got the Call Fail setup command, send it.

                // Most modems can't handle a value > 255 for call fail time
                // And a time of 0 usually really means wait the maximum
                dwCallSetupFailTimer = pLineDev->DevMiniCfg.dwCallSetupFailTimer;
                if( (dwCallSetupFailTimer > 255) ||
                    (dwCallSetupFailTimer == 0) )
                    dwCallSetupFailTimer = 255;
                
                // Expand macros, including the fail time <#>
                wcscpy(ModemMacro.MacroName, INTEGER_MACRO);
                StringCchPrintfW(ModemMacro.MacroValue, sizeof(ModemMacro.MacroValue)/sizeof(WCHAR), L"%d", dwCallSetupFailTimer);
                ExpandMacros(pszTemp, pszExpand, pLineDev->dwMaxCmd, &ModemMacro);
            
                // We need to convert the UniCode to ASCII
                dwCmdLen = wcslen(pszExpand) + 1;
                dwCmdLen = wcstombs( pchCmd, pszExpand, dwCmdLen );
                DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Call fail timer string %s\r\n"),
                                      pszTemp));
            
                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, OPENED);
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // Hmm, we could probably ignore this failure, but the call might
                    // never time out.  Lets be safe and abort now.
                    goto init_error;
                }
            }

            // And finally, see if user requested any special modifier string
            if( dwCmdLen = wcslen(pLineDev->DevMiniCfg.szDialModifier) )
            {
                DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Dial Modifier string %s\r\n"),
                                      pLineDev->DevMiniCfg.szDialModifier));

                // Convert the UniCode to ASCII, and insert 'AT' in command
                pchCmd[0] = 'A';
                pchCmd[1] = 'T';
                
                dwCmdLen += 1;
                dwCmdLen = wcstombs( pchCmd+2, pLineDev->DevMiniCfg.szDialModifier, dwCmdLen );

                // OK, now don't forget the CR at end.
                strcat( pchCmd, "\r" );
                DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:ModemInit Generated Modifier string %a\r\n"),
                                      pchCmd));

                if (LineNotDropped(pLineDev, OrigDevState))
                {
                    // And write this out to modem
                    MdmResp = MODEM_FAILURE;
                    if (MdmSendCommand( pLineDev, pchCmd )) {
                        if (LineNotDropped(pLineDev, OrigDevState)) {
                            MdmResp = MdmGetResponse( pLineDev, pchCmd, NOCS, OPENED);
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // bad modifier string.  We can't recover from this.
                    DEBUGMSG(ZONE_CALLS | ZONE_ERROR,
                             (TEXT("UNIMODEM:ModemInit Bad user supplied dial modifier %s\r\n"),
                              pLineDev->DevMiniCfg.szDialModifier));
                    goto init_error;
                }
            }
            
        }
        bFailed = FALSE;
    } except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
              EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Most likely a bad handle.  Just give up
        bFailed = TRUE;
    }
    
init_error:
    EnterCri

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -