Modem.cpp
上传用户:glass0516
上传日期:2010-01-11
资源大小:104k
文件大小:28k
- /*****************************************************************************
- * RelayFax Open Source Project
- * Copyright 1996-2004 Alt-N Technologies, Ltd.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the RelayFax Open
- * Source License. A copy of this license is available in file LICENSE
- * in the top-level directory of the distribution.
- *
- * RelayFax is a registered trademark of Alt-N Technologies, Ltd.
- *
- * Individual files and/or contributed packages may be copyright by
- * other parties and subject to additional restrictions.
- *****************************************************************************/
- ////////////////////////////////////////////////////////////////////////////////
- //
- // The purpose of CModem build the message loop of an independent thread
- // into CCommPort and handle communication with other threads.
- //
- ////////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Modem.h"
- char* CModem::s_CommonCmds[COMMAND_COUNT] =
- {
- "", // COMMAND_NONE,
- "ATZ", // COMMAND_INIT,
- "AT&F&C1&D2S7=55S0=0", // COMMAND_SETUP_STRING
- "ATE0", // COMMAND_DISABLE_ECHO,
- "ATL%d", // COMMAND_SET_SPKR_VOL,
- "ATM%d", // COMMAND_SET_SPKR_MODE,
- "AT+FCLASS=1", // COMMAND_SET_FCLASS_1
- "AT+FCLASS=1.0", // COMMAND_SET_FCLASS_1_0
- "AT+FCLASS=2", // COMMAND_SET_FCLASS_2
- "AT+FCLASS=2.0", // COMMAND_SET_FCLASS_2_0
- "AT+FCLASS=2.1", // COMMAND_SET_FCLASS_2_1
- "AT+FTM=?", // COMMAND_QUERY_SEND_SPEEDS,
- "AT+FRM=?", // COMMAND_QUERY_RECEIVE_SPEEDS,
- "", // COMMAND_SET_LOCAL_ID,
- "", // COMMAND_SET_RECV
- "", // COMMAND_SET_BIT_ORDER
- "AT+FLO=%d", // COMMAND_SET_FLOW_CONTROL
- "", // COMMAND_SET_HDLC_REPORTING
- "", // COMMAND_SET_FAX_PARAMS
- "ATDT%s", // COMMAND_DIAL
- "ATH0", // COMMAND_HANGUP
- "ATA", // COMMAND_ANSWER
- "AT+FCLASS=?", // COMMAND_QUERY_FCLASS
- "ATI0", // COMMAND_QUERY_PRODUCT_CODE
- "ATI3", // COMMAND_QUERY_MANUFACTURER
- "AT+FDCC=?", // COMMAND_QUERY_CLASS2_CAP
- "AT+FMFR?", // COMMAND_QUERY_CLASS2_MANUFACT
- "AT+FMDL?", // COMMAND_QUERY_CLASS2_MODEL
- "AT+FCC=?", // COMMAND_QUERY_CLASS2_0_CAP
- "AT+FMI?", // COMMAND_QUERY_CLASS2_0_MANUFACT
- "AT+FMM?", // COMMAND_QUERY_CLASS2_0_MODEL
- };
- //MODEM_EVENT_HANDLER_FUNC CModem::s_ModemEventHandlerFunc = NULL;
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CModem::CModem()
- {
- m_bConnected = false;
- m_sInitString.assign( s_CommonCmds[COMMAND_SETUP_STRING] );
- m_nSpkrVol = 0;
- m_nSpkrMode = 0;
- m_nState = STATE_NONE;
- m_nLastCommand = COMMAND_NONE;
- m_nRingCount = 0;
- m_nAnswerOnRing = 2;
- m_bReceiving = false;
- m_nWaitTimeout = 1000;
- m_bEnableReceive = true;
- InitHDLC();
- m_bHDLCMode = false;
- m_bGotOK = false;
- m_bECMSupported = true;
- m_nSendEncoding = FAXAPI_ENC_CCITT_T6;
- ZeroMemory( m_ParamMatrix, sizeof(m_ParamMatrix) );
- m_nSendBaud = FAXAPI_BAUD_14400;
- m_nRecvBaud = FAXAPI_BAUD_14400;
- m_nMaxSendBaud = FAXAPI_BAUD_33600;
- m_nMaxRecvBaud = FAXAPI_BAUD_33600;
- m_bPulseDialing = false;
- m_FaxThreadID = 0;
- m_nMaxPageRetries = 0; // no limit
- m_nMaxPageRetriesPageNo = -1;
- m_bTerminated = false;
- m_bLastPageGood = false;
- }
- CModem::~CModem()
- {
- }
- //////////////////////////////////////////////////////////////////////
- // Initialize - start the modem thread
- //////////////////////////////////////////////////////////////////////
- void CModem::Initialize( HANDLE hStop, DWORD faxThreadID )
- {
- m_FaxThreadID = faxThreadID;
- AddEvent( hStop );
- AddEvent( m_ReadOverlapped.hEvent );
- AddEvent( m_WriteOverlapped.hEvent );
- AddEvent( m_CommEventOverlapped.hEvent );
- StartThread();
- }
- //////////////////////////////////////////////////////////////////////
- // SetPort
- //////////////////////////////////////////////////////////////////////
- void CModem::SetPort( char* szPort )
- {
- m_sPort = szPort;
- }
- //////////////////////////////////////////////////////////////////////
- // Disconnect - send a message to initiate the disconnect
- //////////////////////////////////////////////////////////////////////
- void CModem::Disconnect(void)
- {
- PostMsg( WM_MODEM_DISCONNECT, 0, 0 );
- }
- //////////////////////////////////////////////////////////////////////
- // Disconnect - send a message to initiate the disconnect
- //////////////////////////////////////////////////////////////////////
- void CModem::RecvFax( char* szFaxFile )
- {
- InternalModemMsg* pMsg = new InternalModemMsg;
- strcpy( pMsg->szFile, szFaxFile );
- // m_FaxFile.SetFileName( szFaxFile );
- PostMsg( WM_MODEM_RECVFAX, (WPARAM)pMsg, 0 );
- }
- //////////////////////////////////////////////////////////////////////
- // SetInitString
- //////////////////////////////////////////////////////////////////////
- void CModem::SetInitString( LPCSTR szString )
- {
- m_sInitString.assign( szString );
- }
- //////////////////////////////////////////////////////////////////////
- // SetInitString
- //////////////////////////////////////////////////////////////////////
- void CModem::ChangeCSID( LPCSTR szString )
- {
- InternalModemMsg* pMsg = new InternalModemMsg;
- strcpy( pMsg->szNumber, szString );
- PostMsg( WM_MODEM_SETID, (WPARAM)pMsg, 0 );
- }
- //////////////////////////////////////////////////////////////////////
- // SetInitString
- //////////////////////////////////////////////////////////////////////
- void CModem::SetCSID( LPCSTR szString )
- {
- char szID[21];
- int nLen = 0;
- while( *szString && nLen < 20 )
- {
- if( *szString > 31 && *szString < 127 && *szString != 34 )
- {
- szID[nLen++] = toupper(*szString);
- }
- szString++;
- }
- szID[nLen] = 0;
- m_sLocalCSID.assign( szID );
- }
- //////////////////////////////////////////////////////////////////////
- // Connect - send a message to initiate the disconnect
- //////////////////////////////////////////////////////////////////////
- void CModem::SetSpkrParams( int nSpkrVol, int nSpkrMode )
- {
- m_nSpkrVol = nSpkrVol;
- m_nSpkrMode = nSpkrMode;
- }
- bool CModem::SendFax( char* szNumberToDial, char* szFaxFile )
- {
- InternalModemMsg* pMsg = new InternalModemMsg;
- strcpy( pMsg->szNumber, szNumberToDial );
- strcpy( pMsg->szFile, szFaxFile );
- // m_sNumberToDial.assign( szNumberToDial );
- // m_FaxFile.SetFileName( szFaxFile );
- PostMsg( WM_MODEM_SENDFAX, (WPARAM)pMsg, 0 );
- return true;
- }
- //////////////////////////////////////////////////////////////////////
- // OnStartup
- //////////////////////////////////////////////////////////////////////
- bool CModem::OnStartup( void )
- {
- m_sThreadName.assign( "Modem Thread" );
- if( CThread::OnStartup() )
- {
- InitWindow();
- PostMsg( WM_MODEM_CONNECT, 0, 0 );
- return true;
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////
- // OnShutdown - called before thread exits
- //////////////////////////////////////////////////////////////////////
- void CModem::OnShutdown( void )
- {
- CThread::OnShutdown();
- ShutdownWindow();
- if( m_bConnected )
- {
- DisconnectPort();
- m_nState = STATE_NONE;
- m_bConnected = false;
- }
- }
- //////////////////////////////////////////////////////////////////////
- // Handle message - return true if WM_QUIT received
- //////////////////////////////////////////////////////////////////////
- bool CModem::OnMsg( MSG* pMsg )
- {
- if( CThread::OnMsg( pMsg ) )
- return true;
- m_dwActivityTimer = GetTickCount();
- switch( pMsg->message )
- {
- case WM_MODEM_CONNECT:
- OnConnectMsg();
- break;
- case WM_MODEM_DISCONNECT:
- OnDisconnectMsg();
- break;
- case WM_MODEM_SENDFAX:
- OnSendFaxMsg( pMsg );
- break;
- case WM_MODEM_RECVFAX:
- OnRecvFaxMsg( pMsg );
- break;
- case WM_MODEM_ABORTFAX:
- OnAbortFaxMsg();
- break;
- case WM_MODEM_CLEARRINGCNT:
- m_nRingCount = 0;
- m_nState = STATE_IDLE;
- break;
- case WM_MODEM_SETID:
- {
- InternalModemMsg* pModemMsg = (InternalModemMsg*) pMsg->wParam;
- if( pModemMsg)
- {
- SetCSID( pModemMsg->szNumber );
- }
- delete pModemMsg;
- }
- break;
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////
- // Handle event - return true if cancel event set
- //////////////////////////////////////////////////////////////////////
- bool CModem::OnEvent( int nIndex )
- {
- switch( nIndex )
- {
- case 0:
- // Cancel event
- OnDisconnectMsg();
- return true;
- case 1:
- // Read event
- ReadEventSignalled();
- return false;
- case 2:
- // Write event
- WriteEventSignalled();
- return false;
- case 3:
- // WaitComm event
- WaitCommEventSignalled();
- return false;
- case 4:
- // Disconnect Event
- return true;
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////
- // OnConnectMsg
- //////////////////////////////////////////////////////////////////////
- void CModem::OnConnectMsg(void)
- {
- if( !m_bConnected )
- {
- m_nRingCount = 0;
- m_bConnected = ConnectPort( m_sLastError );
- if( !m_bConnected )
- {
- SignalEvent( EVENT_ERROR );
- m_nState = STATE_NONE;
- SignalEvent( EVENT_DISCONNECT );
- ExitAndDelete();
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // OnDisconnectMsg
- //////////////////////////////////////////////////////////////////////
- void CModem::OnDisconnectMsg(void)
- {
- if( m_bConnected )
- {
- if( OnDisconnect() )
- {
- DisconnectPort();
- m_nState = STATE_NONE;
- SignalEvent( EVENT_DISCONNECT );
- m_bConnected = false;
- ExitAndDelete();
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // OnSendFaxMsg
- //////////////////////////////////////////////////////////////////////
- void CModem::OnSendFaxMsg( MSG* pMsg )
- {
- InternalModemMsg* pModemMsg = (InternalModemMsg*) pMsg->wParam;
- if( pModemMsg == NULL)
- return;
- m_sNumberToDial.assign( pModemMsg->szNumber );
- m_FaxFile.SetFileName( pModemMsg->szFile );
- delete pModemMsg;
- m_nMaxPageRetriesPageNo = -1;
- }
- void CModem::OnRecvFaxMsg( MSG* pMsg )
- {
- InternalModemMsg* pModemMsg = (InternalModemMsg*) pMsg->wParam;
- if( pModemMsg == NULL)
- return;
- m_FaxFile.SetFileName( pModemMsg->szFile );
- delete pModemMsg;
- }
- void CModem::OnAbortFaxMsg(void)
- {
- }
- //////////////////////////////////////////////////////////////////////
- // SendCommand
- //////////////////////////////////////////////////////////////////////
- void CModem::SendCommand( int nCommand, char* szCmdString )
- {
- char szWorkBuffer[256];
- char* szCmd = NULL;
- if( szCmdString )
- {
- szCmd = szCmdString;
- }
- else if( nCommand == COMMAND_SETUP_STRING )
- {
- szCmd = (char*)m_sInitString.c_str();
- }
- else
- {
- switch( nCommand )
- {
- case COMMAND_SET_SPKR_VOL:
- wsprintf( szWorkBuffer, s_CommonCmds[nCommand], m_nSpkrVol );
- szCmd = szWorkBuffer;
- break;
- case COMMAND_SET_SPKR_MODE:
- wsprintf( szWorkBuffer, s_CommonCmds[nCommand], m_nSpkrMode );
- szCmd = szWorkBuffer;
- break;
- case COMMAND_DIAL:
- if( m_bPulseDialing )
- {
- wsprintf( szWorkBuffer, "ATDP%s", m_sNumberToDial.c_str() );
- }
- else
- {
- wsprintf( szWorkBuffer, "ATDT%s", m_sNumberToDial.c_str() );
- }
- szCmd = szWorkBuffer;
- break;
- case COMMAND_SET_FLOW_CONTROL:
- wsprintf( szWorkBuffer, s_CommonCmds[nCommand], m_bCTSFlowControl ? 2 : 1 );
- szCmd = szWorkBuffer;
- break;
- default:
- if( nCommand >= 0 && nCommand < COMMAND_COUNT )
- {
- szCmd = s_CommonCmds[nCommand];
- }
- break;
- }
- }
-
- if( szCmd )
- {
- m_nLastCommand = nCommand;
- m_LastCommandString.assign( szCmd );
- m_bGotOK = false;
- KillTimer( TIMER_COMMAND );
- if( (nCommand != COMMAND_DIAL) && (nCommand != COMMAND_ANSWER) )
- {
- SetTimer( TIMER_COMMAND, 2000 );
- }
- // m_nLastCommandTickCount = GetTickCount();
- DoWrite( szCmd, strlen(szCmd), true );
- //wsprintf( szWorkBuffer, "Sent Command: %sn", m_LastCommandString.c_str() );
- //OutputDebugString( szWorkBuffer );
- }
- }
- //////////////////////////////////////////////////////////////////////
- // SignalEvent
- //////////////////////////////////////////////////////////////////////
- void CModem::SignalEvent( int nEvent, char info )
- {
- FaxApiModemMsg* pMsg = new FaxApiModemMsg;
- memset( pMsg, 0, sizeof(FaxApiModemMsg) );
- pMsg->m_cbSize = sizeof(FaxApiModemMsg);
- switch( nEvent )
- {
- case EVENT_ERROR:
- strncpy( pMsg->sz, m_sLastError.c_str(), FAXAPI_MODEMMSG_INFOLEN );
- pMsg->sz[FAXAPI_MODEMMSG_INFOLEN-1] = ' ';
- break;
- case EVENT_RECV_DIS:
- case EVENT_SENT_DIS:
- memcpy( &pMsg->p, &m_DISParams.p, sizeof(FaxApiParameters) );
- break;
- case EVENT_RECV_DCS:
- case EVENT_SENT_DCS:
- memcpy( &pMsg->p, &m_DCSParams.p, sizeof(FaxApiParameters) );
- break;
- case EVENT_GOT_REMOTEID:
- strcpy( pMsg->sz, m_sRemoteCSID.c_str() );
- trimws( pMsg->sz );
- break;
- case EVENT_START_PAGE:
- pMsg->t.nPages = GetPageCount();
- break;
- case EVENT_TERMINATE:
- strncpy( pMsg->sz, m_sLastError.c_str(), FAXAPI_MODEMMSG_INFOLEN );
- pMsg->sz[FAXAPI_MODEMMSG_INFOLEN-1] = ' ';
- pMsg->t.nPages = GetPageCount();
- pMsg->t.nSuccessful = (m_bSuccessful && GetPageCount() > 0 ) ? 1 : 0;
- break;
- case EVENT_CALLERID:
- strncpy( pMsg->sz, m_szLineBuff, FAXAPI_MODEMMSG_INFOLEN );
- pMsg->szID[FAXAPI_MODEMMSG_INFOLEN-1] = ' ';
- break;
- default:
- pMsg->sz[0] = info;
- break;
- }
- SendModemMessage( nEvent, pMsg );
- }
- void CModem::SignalEventString( int nEvent, LPCSTR szMsg )
- {
- FaxApiModemMsg* pMsg = new FaxApiModemMsg;
- memset( pMsg, 0, sizeof(FaxApiModemMsg) );
- pMsg->m_cbSize = sizeof(FaxApiModemMsg);
- strncpy( pMsg->sz, szMsg, FAXAPI_MODEMMSG_INFOLEN );
- pMsg->sz[FAXAPI_MODEMMSG_INFOLEN-1] = ' ';
- SendModemMessage( nEvent, pMsg );
- }
- void CModem::SendModemMessage( int nEvent, FaxApiModemMsg* pMsg )
- {
- strcpy( pMsg->szID, m_sPort.c_str() );
- PostThreadMessage( m_FaxThreadID, WM_MODEM_MESSAGE, (WPARAM)pMsg, nEvent );
- }
- //////////////////////////////////////////////////////////////////////
- // ErrorUnexpectedResponse
- //////////////////////////////////////////////////////////////////////
- void CModem::ErrorUnexpectedResponse( void )
- {
- char szMsg[512];
- wsprintf( szMsg, (char*)LoadString(GEN_RECEIVED_IN_RESPONSE_TO).c_str(), m_szLineBuff, m_LastCommandString.c_str() );
- m_sLastError.assign( szMsg );
- SignalEvent( EVENT_ERROR );
- }
- //////////////////////////////////////////////////////////////////////
- // ErrorConnectResponse
- //////////////////////////////////////////////////////////////////////
- void CModem::ErrorConnectResponse( void )
- {
- // For now, use the return string as the error description
- m_sLastError.assign( m_szLineBuff );
- SignalEvent( EVENT_ERROR );
- }
- void CModem::ProcSupportedSpeeds( LPSTR lpSpeeds, bool bSend )
- {
- LPSTR lpTok;
- int val;
- char szDefSpeeds[64];
- if( stricmp( m_szLineBuff, "ERROR" ) == 0 )
- {
- strcpy( szDefSpeeds, "3,24,48,72,73,74,96,97,98,121,122,145,146" );
- lpSpeeds = szDefSpeeds;
- }
- bool* bSupported = (bSend) ? &m_bSendSupported[0] : &m_bRecvSupported[0];
- ZeroMemory( bSupported, sizeof(bool) * MAX_CLS1SPEEDS );
- lpTok = strtok( lpSpeeds, ",");
- while( lpTok ) {
- val = atoi( lpTok );
-
- switch( val ) {
- case 24:
- bSupported[0] = 1;
- break;
- case 48:
- bSupported[1] = 1;
- break;
-
- case 72:
- bSupported[2] = 1;
- break;
- case 73:
- bSupported[6] = 1;
- break;
-
- case 96:
- bSupported[3] = 1;
- break;
- case 97:
- bSupported[7] = 1;
- break;
- case 121:
- bSupported[8] = 1;
- bSupported[4] = 1;
- break;
- case 145:
- bSupported[9] = 1;
- bSupported[5] = 1;
- break;
- }
- lpTok = strtok( NULL, "," );
- }
- if( bSend )
- {
- if( m_bSendSupported[9] )
- {
- m_nMaxSendBaud = 5;
- }
- else if( m_bSendSupported[8] )
- {
- m_nMaxSendBaud = 4;
- }
- else if( m_bSendSupported[7] )
- {
- m_nMaxSendBaud = 3;
- }
- else if( m_bSendSupported[6] )
- {
- m_nMaxSendBaud = 2;
- }
- else if( m_bSendSupported[1] )
- {
- m_nMaxSendBaud = 1;
- }
- else
- {
- m_nMaxSendBaud = 0;
- }
- if( m_nSendBaud > m_nMaxSendBaud )
- {
- m_nSendBaud = m_nMaxSendBaud;
- }
- }
- else
- {
- if( m_bRecvSupported[9] )
- {
- m_nMaxRecvBaud = 5;
- }
- else if( m_bRecvSupported[8] )
- {
- m_nMaxRecvBaud = 4;
- }
- else if( m_bRecvSupported[7] )
- {
- m_nMaxRecvBaud = 3;
- }
- else if( m_bRecvSupported[6] )
- {
- m_nMaxRecvBaud = 2;
- }
- else if( m_bRecvSupported[1] )
- {
- m_nMaxRecvBaud = 1;
- }
- else
- {
- m_nMaxRecvBaud = 0;
- }
- if( m_nRecvBaud > m_nMaxRecvBaud )
- {
- m_nRecvBaud = m_nMaxRecvBaud;
- }
- }
- }
- bool CModem::GetCapParam( int nIndex, int nValue )
- {
- if( nIndex >= 0 && nIndex <= FAXAPI_MAXPARAMETERS && nValue >= 0 && nValue <= FAXAPI_MAXPARAMVALUE )
- {
- return m_ParamMatrix[nIndex][nValue];
- }
-
- return false;
- }
- int CModem::ProcCapValueIndex( LPSTR lpValue, int nIndex, bool bComma, bool bDash, int nLast )
- {
- int nCurrent = 0;
- char* p = lpValue;
- bool bHex = false;
- //OnFHNG
- while( *p )
- {
- if( IsHex(*p) )
- {
- bHex = true;
- break;
- }
- p++;
- }
-
- if( bHex )
- {
- sscanf( lpValue, "%X", &nCurrent );
- }
- else
- {
- nCurrent = atoi(lpValue);
- }
-
- if( bDash )
- {
- while( nLast <= nCurrent )
- {
- if( nIndex >= 0 && nIndex < FAXAPI_MAXPARAMETERS && nLast >= 0 && nLast < FAXAPI_MAXPARAMVALUE )
- {
- m_ParamMatrix[nIndex][nLast] = true;
- }
- nLast++;
- }
- }
- else
- {
- if( nIndex >= 0 && nIndex < FAXAPI_MAXPARAMETERS && nCurrent >= 0 && nCurrent < FAXAPI_MAXPARAMVALUE )
- {
- m_ParamMatrix[nIndex][nCurrent] = true;
- }
- }
-
- return nCurrent;
- }
- void CModem::ProcCapValue( LPSTR lpValue, int nIndex )
- {
- char szN[32];
- bool bComma = false;
- bool bDash = false;
- int nLast = 0;
- int i = 0;
- char* p = lpValue;
- while( *p )
- {
- bool bProcessNumber = false;
- if( *p == ',' )
- {
- szN[i] = 0;
- nLast = ProcCapValueIndex( szN, nIndex, bComma, bDash, nLast );
- bComma = true;
- bDash = false;
- i = 0;
- }
- else if( *p == '-' )
- {
- szN[i] = 0;
- nLast = ProcCapValueIndex( szN, nIndex, bComma, bDash, nLast );
- bDash = true;
- bComma = false;
- i = 0;
- }
- else if( IsHexDigit( *p ) )
- {
- szN[i++] = *p;
- }
- p++;
- if( *p == ' ' )
- {
- szN[i] = 0;
- nLast = ProcCapValueIndex( szN, nIndex, bComma, bDash, nLast );
- i = 0;
- }
- }
- }
- void CModem::ProcCapabilities( LPSTR lpCaps )
- {
- char szValue[32];
- bool bInParens = false;
- int i = 0;
- int j = 0;
- ZeroMemory( m_ParamMatrix, sizeof(m_ParamMatrix) );
- char* p = lpCaps;
- while( *p )
- {
- bool bProcessNumber = false;
- if( bInParens == false )
- {
- if( *p == '(' )
- {
- bInParens = true;
- }
- else if( *p == ',' )
- {
- bProcessNumber = true;
- }
- else
- {
- if( i < (sizeof(szValue) - 1) )
- {
- szValue[i++] = *p;
- }
- }
- }
- else
- {
- if( *p == ')' )
- {
- bInParens = false;
- }
- else
- {
- if( i < (sizeof(szValue) - 1) )
- {
- szValue[i++] = *p;
- }
- }
- }
- p++;
- if( *p == ' ' || bProcessNumber )
- {
- szValue[i] = 0;
- ProcCapValue( szValue, j );
- // next element
- i = 0;
- j++;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // Handle wait timeout - do periodic processing
- //////////////////////////////////////////////////////////////////////
- bool CModem::OnWaitTimeout( void )
- {
- DWORD nInActive = GetTickCount() - m_dwActivityTimer;
- CheckTimeouts( nInActive );
- return false;
- }
- void CModem::CheckTimeouts( DWORD dwInActive )
- {
- }
- void CModem::PurgeWriteQueue( void )
- {
- // Purge write queue
- deque<CWriteBuffer*>::iterator iter = m_WriteQueue.begin();
- while( iter != m_WriteQueue.end() )
- {
- delete (*iter);
- m_WriteQueue.pop_front();
- iter = m_WriteQueue.begin();
- }
- }
- void CModem::PurgeOutput( void )
- {
- PurgeWriteQueue();
- PurgeComm( m_hPort, PURGE_TXABORT | PURGE_TXCLEAR );
- }
- void CModem::DoHangup( void )
- {
- SendCommand( COMMAND_HANGUP );
- m_nState = STATE_DISCONNECT;
- }
- void CModem::PhaseHangup(void)
- {
- // if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
- {
- m_bGotOK = true;
- KillTimer( TIMER_COMMAND );
- m_nState = STATE_IDLE;
- SignalEvent( EVENT_IDLE );
- }
- }
- void CModem::PhaseDisconnect(void)
- {
- // if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
- {
- m_bGotOK = true;
- KillTimer( TIMER_COMMAND );
- DisconnectPort();
- m_nState = STATE_NONE;
- SignalEvent( EVENT_DISCONNECT );
- m_bConnected = false;
- ExitAndDelete();
- }
- }
- void CModem::Terminate()
- {
- if( m_bTerminated == false )
- {
- SignalEvent( EVENT_TERMINATE );
- PurgeWriteQueue();
- m_FaxFile.Close();
- KillTimer( TIMER_MAXPAGERETRIES );
- m_bTerminated = true;
- }
- }
- bool CModem::OkToAnswer( void )
- {
- return ( m_bEnableReceive && (m_nRingCount >= m_nAnswerOnRing) );
- }
- //////////////////////////////////////////////////////////////////////
- // OnRead
- //////////////////////////////////////////////////////////////////////
- void CModem::OnRead(void)
- {
- DWORD i;
- m_dwActivityTimer = GetTickCount();
- // char szMsg[80];
- // wsprintf( szMsg, "OnRead %d bytesn", m_BytesRead );
- // OutputDebugString( szMsg );
- for( i = 0; i < m_BytesRead; i++ )
- {
- //char szDigit[32];
- //wsprintf( szDigit, "%d:[%02x]n", i, m_szReadBuff[i] );
- //OutputDebugString( szDigit );
- if( m_bEolFlag )
- {
- if( (m_szReadBuff[i] != 'r') && (m_szReadBuff[i] != 'n') )
- {
- m_bEolFlag = false;
- }
- }
- if( !m_bEolFlag )
- {
- if( m_bHDLCMode ) // HDLC mode
- {
- if( m_bGotDLE )
- {
- m_bGotDLE = false;
- if( m_szReadBuff[i] == ETX )
- {
- OnHDLCFrame();
- InitLineParser();
- m_bHDLCMode = false;
- }
- else if( m_szReadBuff[i] == DLE )
- {
- if( m_nHDLCBuffPtr >= READBUF_SIZE )
- {
- OnPartialHDLCFrame();
- m_nHDLCBuffPtr = 0;
- }
- m_szHDLCBuff[m_nHDLCBuffPtr++] = m_szReadBuff[i];
- }
- else if( m_szReadBuff[i] == SUB )
- {
- if( m_nHDLCBuffPtr >= READBUF_SIZE )
- {
- OnPartialHDLCFrame();
- m_nHDLCBuffPtr = 0;
- }
- m_szHDLCBuff[m_nHDLCBuffPtr++] = DLE;
- if( m_nHDLCBuffPtr >= READBUF_SIZE )
- {
- OnPartialHDLCFrame();
- m_nHDLCBuffPtr = 0;
- }
- m_szHDLCBuff[m_nHDLCBuffPtr++] = DLE;
- }
- else
- {
- //OutputDebugString( "Illegal HDLC Coding!n" );
- }
- }
- else
- {
- if( m_szReadBuff[i] == DLE )
- {
- m_bGotDLE = true;
- }
- else
- {
- if( m_nHDLCBuffPtr >= READBUF_SIZE )
- {
- OnPartialHDLCFrame();
- InitHDLC();
- }
- m_szHDLCBuff[m_nHDLCBuffPtr++] = m_szReadBuff[i];
- }
- }
- // Sometimes NO CARRIER is returned w/o DLE-ETX
- if( (m_nHDLCBuffPtr > 9) && (m_nHDLCBuffPtr < 14) && strstr( (char*) m_szHDLCBuff, "NO CARRIER" ) )
- {
- m_bHDLCMode = false;
- memcpy( m_szLineBuff, m_szHDLCBuff, m_nHDLCBuffPtr );
- m_nLineBuffPtr = m_nHDLCBuffPtr;
- m_szLineBuff[m_nLineBuffPtr] = ' ';
- OnReadLine();
- InitLineParser();
- }
- }
- else // line mode
- {
- if( (m_szReadBuff[i] == 'r') || (m_szReadBuff[i] == 'n') )
- {
- m_bEolFlag = true;
- if( m_nLineBuffPtr > 0 )
- {
- m_szLineBuff[m_nLineBuffPtr] = ' ';
- //char szMsg[256];
- //wsprintf( szMsg, "OnRead:(%d:%d)n", m_BytesRead, i );
- //OutputDebugString( szMsg );
- // Ignore intermediate responses in init state
- if( ( m_nState > STATE_INIT ) || ((m_BytesRead - i) <= 2 ) )
- {
- OnReadLine();
- }
- else if( ( m_nState == STATE_INIT) &&
- ((m_nLastCommand == COMMAND_QUERY_SEND_SPEEDS)||
- (m_nLastCommand == COMMAND_QUERY_RECEIVE_SPEEDS)||
- (m_nLastCommand >= COMMAND_QUERY_FCLASS)) )
- {
- OnReadLine();
- }
- if( !m_bHDLCMode )
- {
- InitLineParser();
- }
- }
- }
- else
- {
- if( m_nLineBuffPtr >= READBUF_SIZE )
- {
- //OutputDebugString( "Line buffer overflow!n" );
- InitLineParser();
- }
- m_szLineBuff[m_nLineBuffPtr++] = m_szReadBuff[i];
- }
- }
- }
- }
- }
- void CModem::OnHDLCFrame(void)
- {
- }
- void CModem::OnPartialHDLCFrame(void)
- {
- }
- void CModem::OnTimer( UINT nID )
- {
- //OutputDebugString( "CModem::OnTimern" );
- }
- //////////////////////////////////////////////////////////////////////
- // HandleMsg
- //////////////////////////////////////////////////////////////////////
- LRESULT CModem::HandleMsg( UINT message, WPARAM wParam, LPARAM lParam )
- {
- if( message == WM_TIMER )
- {
- OnTimer( wParam );
- }
- return DefWindowProc( m_hwnd, message, wParam, lParam );
- }
- int CModem::ParseFaxParams( int nMaxParams, int* pParams )
- {
- char szNumBuff[21];
- int j;
- int i;
- ZeroMemory( pParams, sizeof(int) * nMaxParams );
- char* p = m_szLineBuff + 5; // Skip +XXXX
- if ( *p == ':' ) // skip the colon
- {
- p++;
- }
- // advance to first digit
- while( *p && (IsHexDigit(*p) == false) && (*p != ',') )
- {
- p++;
- }
- for( i = 0; i < nMaxParams; i++ )
- {
- // check for end of string
- if( *p == ' ' )
- {
- return i;
- }
- j = 0;
- // advance to next comma
- while( *p && IsHexDigit(*p) && (j < 20) )
- {
- szNumBuff[j++] = *p++;
- }
- szNumBuff[j] = ' ';
- pParams[i] = atoi( szNumBuff );
- if( *p ) // advance past comma
- p++;
- }
- return i;
- }
- void CModem::ExitAndDelete(void)
- {
- OnShutdown();
- delete this;
-
- ExitThread(0);
- }
- bool CModem::IsRing(void)
- {
- if( stricmp( m_szLineBuff, "RING" ) == 0 )
- {
- return true;
- }
- if( !m_sRingCodes.empty() )
- {
- if( strchr( m_sRingCodes.c_str(), '1' ) )
- {
- if( ( stricmp( m_szLineBuff, "RING1" ) == 0 ) || ( stricmp( m_szLineBuff, "RINGA" ) == 0 ) )
- {
- return true;
- }
- }
- if( strchr( m_sRingCodes.c_str(), '2' ) )
- {
- if( ( stricmp( m_szLineBuff, "RING2" ) == 0 ) || ( stricmp( m_szLineBuff, "RINGB" ) == 0 ) )
- {
- return true;
- }
- }
- if( strchr( m_sRingCodes.c_str(), '3' ) )
- {
- if( ( stricmp( m_szLineBuff, "RING3" ) == 0 ) || ( stricmp( m_szLineBuff, "RINGC" ) == 0 ) )
- {
- return true;
- }
- }
- }
- return false;
- }
- void CModem::AbortFax(void)
- {
- PostMsg( WM_MODEM_ABORTFAX, 0, 0 );
- }
- bool CModem::IsHexDigit( char digit )
- {
- return (strchr( "1234567890ABCDEFabcdef", digit ) != NULL);
- }
- bool CModem::IsHex( char digit )
- {
- return (strchr( "ABCDEFabcdef", digit ) != NULL);
- }
- void CModem::Abort( bool bUserCancelled )
- {
- }
- void CModem::ClearRingCount(void)
- {
- PostMsg( WM_MODEM_CLEARRINGCNT, 0, 0 );
- };
- void CModem::SetMaxPageRetriesTimer(void)
- {
- DWORD dwTimeout = 0;
- if( m_nMaxPageRetries < 1 )
- return;
- int nPageNo = GetPageCount();
- if( nPageNo > m_nMaxPageRetriesPageNo )
- {
- KillTimer( TIMER_MAXPAGERETRIES );
- m_nMaxPageRetriesPageNo = nPageNo;
- // have to be careful how this timeout is computed so we don't overflow
- unsigned int nSecsPerPage = m_FaxFile.GetTotalPageSize() / (Cls2FaxParamBitRates[m_DCSParams.p.BitRate] / 8) ;
- dwTimeout = m_nMaxPageRetries * 1000 * (15 + nSecsPerPage);
- SetTimer( TIMER_MAXPAGERETRIES, dwTimeout );
- //char szMsg[128];
- //wsprintf( szMsg, "Setting timeout %d for page %d (%d bytes) Bitrate=%dn", dwTimeout, nPageNo, m_FaxFile.GetTotalPageSize(), Cls2FaxParamBitRates[m_DCSParams.p.BitRate] );
- //OutputDebugString( szMsg );
- }
- }