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

📄 dial.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 5 页
字号:
			// 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
                {
                    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 );
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // bad flow control string.  We can't recover from this.
                    pLineDev->MdmState = MDMST_UNKNOWN;
                    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);
                wsprintf(ModemMacro.MacroValue, TEXT("%d"), dwCallSetupFailTimer );
                ExpandMacros(pszTemp, pszExpand, NULL, &ModemMacro, 1);
            
                // 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 );
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // Hmm, we could probably ignore this failure, but the call might
                    // never time out.  Lets be safe and abort now.
                    pLineDev->MdmState = MDMST_UNKNOWN;
                    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 );
                        }
                    }
                }
                if( MODEM_SUCCESS != MdmResp )
                {
                    // bad modifier string.  We can't recover from this.
                    pLineDev->MdmState = MDMST_UNKNOWN;
                    DEBUGMSG(ZONE_CALLS | ZONE_ERROR,
                             (TEXT("UNIMODEM:ModemInit Bad user supplied dial modifier %s\r\n"),
                              pLineDev->DevMiniCfg.szDialModifier));
                    goto init_error;
                }
            }
            
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Most likely a bad handle.  Just give up
        pLineDev->MdmState = MDMST_UNKNOWN;
    }
    
init_error:
    // Cancel watchdog if he's still around.
    SetWatchdog( pLineDev, 0 );
    if( pszTemp )
        TSPIFree( pszTemp );        
    if( pchCmd )
        TSPIFree( pchCmd );
    if( pszExpand )
        TSPIFree( pszExpand );

    DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM: -ModemInit %s\n"),
        (pLineDev->MdmState == MDMST_UNKNOWN) ? TEXT("FAILED"): TEXT("OK")));
    return (pLineDev->MdmState == MDMST_UNKNOWN) ? FALSE : TRUE;
}   // ModemInit


#define NUM_BAUD_RATES 9

DWORD
NextBaudRate(
    DWORD dwBaudRate
    )
{
    switch (dwBaudRate) {
    case CBR_19200:  return CBR_57600;
    case CBR_57600:  return CBR_115200;
    case CBR_115200: return CBR_38400;
    case CBR_38400:  return CBR_56000;
    case CBR_56000:  return CBR_128000;
    case CBR_128000: return CBR_256000;
    case CBR_256000: return CBR_9600;
    case CBR_9600:   return CBR_14400;
    case CBR_14400:  return CBR_19200;
    }
    return CBR_19200;
}

//
// Called to set the baud rate for a NULL MODEM device.
//
BOOL
AutoBaudRate(
    PTLINEDEV pLineDev,
    DWORD dwBaudRate
    )
{
    DCB commDCB;
    DWORD status;
    DWORD Retry;
    DWORD dwCurBaud;

    Sleep(200);
    if (!EscapeCommFunction ( pLineDev->hDevice, CLRDTR)) {
        status = GetLastError();
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate EscapeCommFunction(CLRDTR) failed %d\n"), status));
        return FALSE;
    }
    Sleep(400);

    if (!GetCommState(pLineDev->hDevice, &commDCB)) {
        status = GetLastError();
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate GetCommState failed %d\n"), status));
        return FALSE;
    }

    Retry = 0;

    if (dwBaudRate) {
        dwCurBaud = dwBaudRate;
    } else {
abr_next:
        dwCurBaud = NextBaudRate(pLineDev->dwCurrentBaudRate);
    }

    pLineDev->dwCurrentBaudRate = commDCB.BaudRate = dwCurBaud;

    if (!PurgeComm(pLineDev->hDevice, PURGE_TXCLEAR|PURGE_RXCLEAR)) {
        status = GetLastError();
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate PurgeComm failed %d\r\n"), status));
    }
    if (!SetCommState(pLineDev->hDevice, &commDCB)) {
        status = GetLastError();
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate SetCommState(baud = %d) failed %d\n"),
            commDCB.BaudRate, status));
        //
        // If SetCommState fails with inval parm, assume the error was an unsupported baud rate
        // and try the next one.
        //
        if (status == ERROR_INVALID_PARAMETER) {
            Retry++;
            if (Retry < NUM_BAUD_RATES) {
                goto abr_next;
            }
        }
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate failed.\n")));
        return FALSE;
    }

    if (!EscapeCommFunction ( pLineDev->hDevice, SETDTR)) {
        status = GetLastError();
        DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate EscapeCommFunction(SETDTR) failed %d\n"), status));
        return FALSE;
    }
    Sleep(200);

    DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:AutoBaudRate trying %d\n"), commDCB.BaudRate));
    return TRUE;
}   // AutoBaudRate


BOOL
CallNotDropped(
    PTLINEDEV pLineDev
    )
{
    switch (pLineDev->dwCallState) {
    case LINECALLSTATE_CONNECTED:
    case LINECALLSTATE_DIALING:
    case LINECALLSTATE_DIALTONE:
    case LINECALLSTATE_PROCEEDING:
    case LINECALLSTATE_UNKNOWN:
            return TRUE;
    }
    DEBUGMSG(ZONE_CALLS, (TEXT("UNIMODEM:CallNotDropped call state = %x\n"), pLineDev->dwCallState));
    return FALSE;
}


// **********************************************************************
//
// This is the dialer thread.  It is created whenever we decide to
// dial a modem, and exists until the call completes or is terminated.
// 
// **********************************************************************
void
Dialer(
    PTLINEDEV pLineDev
    )
{
    DCB  commDCB;
    MODEMRESPCODES MdmResp;
    BOOL fOriginate;
    BOOL bFirstResp;
    PWCHAR pszzDialCommands = NULL;  // strings of dial strings returned from CreateDialCommand
    PWCHAR ptchDialCmd;
    PCHAR  pchDialCmd = NULL;
    DWORD  dwDialLen;
    DWORD  LineCallState;
    DWORD  LineCallStateParm2;
    DWORD  LineError;   // Indicates asynchronous return code for LineMakeCall completion
    DWORD  dwCallFailTimer;
    BOOL bKeepLooping;
    
    DEBUGMSG(ZONE_FUNC|ZONE_CALLS,
             (TEXT("UNIMODEM:Dialer - dial options x%X (x%X), modem options x%X\r\n"),
              pLineDev->dwDialOptions, pLineDev->DevMiniCfg.fwOptions, pLineDev->DevMiniCfg.dwModemOptions));

    dwCallFailTimer = pLineDev->DevMiniCfg.dwCallSetupFailTimer;
    LineCallStateParm2 = LINEDISCONNECTMODE_NORMAL;
    LineError = LINEERR_OPERATIONFAILED;
    bFirstResp = TRUE;

        if( (dwCallFailTimer == 0) ||
        (dwCallFailTimer > 512) )
        dwCallFailTimer = 512;
    
    // Clear any old CallComplete events before starting a new call
    WaitForSingleObject(pLineDev->hCallComplete, 0);
    
    pLineDev->dwCallState = LineCallState = LINECALLSTATE_UNKNOWN;

    try
    {
        // Disable HW flow control while we try to connect.
        // Otherwise, our xmit may get stuck in a flowed-off state and
        // then we cannot send.
        GetCommState( pLineDev->hDevice, &commDCB );
        commDCB.fRtsControl = RTS_CONTROL_ENABLE;
        commDCB.fOutxCtsFlow = 0;
        SetCommState( pLineDev->hDevice, &commDCB );
    
        // Our job is to dial the modem, and then sit here waiting for
       

⌨️ 快捷键说明

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