dial.c

来自「wince下的源代码集合打包」· C语言 代码 · 共 1,946 行 · 第 1/5 页

C
1,946
字号
                {                    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 9DWORDNextBaudRate(    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.//BOOLAutoBaudRate(    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;}   // AutoBaudRateBOOLCallNotDropped(    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.// // **********************************************************************voidDialer(    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        // a response.  All the helper routines in this file are responsible        // for driving the state machine.        LineCallState = LINECALLSTATE_DIALING;        NewCallState(pLineDev, LineCallState, 0L);        //        // If we are here because of a lineDial call, then skip the NULL modem        // and manual dial stuff        //        if (pLineDev->dwPendingType == PENDING_LINEDIAL) {            goto dial_continue;        }#define NULL_MODEM_RETRY	3	        if( IS_NULL_MODEM(pLineDev) )        {            DWORD Retry;            DWORD BaudRates;            DWORD NumBaudRates;                            DEBUGMSG(ZONE_CALLS,                     (TEXT("UNIMODEM:Dialer - Attempting DCC connection\r\n")));            //            // This is a DCC connection.  Dial strings are simple.            // Send 'CLIENT', expect back 'CLIENTSERVER'. Try several            // times, unless we are dropping the line            //            if (pLineDev->DevMiniCfg.dwModemOptions & MDM_SPEED_ADJUST) {                NumBaudRates = NUM_BAUD_RATES;            } else {                //                // Automatic baud rate detection is off, just use the supplied baud rate                //                NumBaudRates = 1;                pLineDev->dwLastBaudRate = 0;            }            if (!AutoBaudRate(                    pLineDev,                     (pLineDev->dwLastBaudRate) ?                            pLineDev->dwLastBaudRate : pLineDev->DevMiniCfg.dwBaudRate)) {                pLineDev->dwLastBaudRate = 0;                LineCallStateParm2 = LINEDISCONNECTMODE_UNKNOWN;                goto dial_done;            }            for (BaudRates=0; BaudRates < NumBaudRates; BaudRates++) {                for( Retry=0;                    (Retry <= NULL_MODEM_RETRY) &

⌨️ 快捷键说明

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