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