?? classtwo.cpp
字號(hào):
/*****************************************************************************
* 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 CClassTwo is contain the protocol specifics of EIA
// fax modem class 2
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ClassTwo.h"
#define CLASSTWO_CONNECT "+FCON"
#define CLASSTWO_CONNECT_SIZE 5
#define CLASSTWO_TSI "+FTSI"
#define CLASSTWO_TSI_SIZE 5
#define CLASSTWO_DCS "+FDCS"
#define CLASSTWO_DCS_SIZE 5
#define CLASSTWO_NSS " +FNSS"
#define CLASSTWO_NSS_SIZE 5
#define CLASSTWO_HNGUP "+FHNG"
#define CLASSTWO_HNGUP_SIZE 5
#define CLASSTWO_CSI "+FCSI"
#define CLASSTWO_CSI_SIZE 5
#define CLASSTWO_DIS "+FDIS"
#define CLASSTWO_DIS_SIZE 5
#define CLASSTWO_NSF "+FNSF"
#define CLASSTWO_NSF_SIZE 5
#define CLASSTWO_PTS "+FPTS"
#define CLASSTWO_PTS_SIZE 5
#define CLASSTWO_ET "+FET"
#define CLASSTWO_ET_SIZE 4
#define CLASSTWO_DR "AT+FDR"
#define CLASSTWO_DR_SIZE 6
#define CLASSTWO_DT "AT+FDT"
#define CLASSTWO_DT_SIZE 6
#define CLASSTWO_FK "AT+FK"
#define CLASSTWO_FK_SIZE 5
#define CLASSTWO_SETID "AT+FLID=\"%s\""
#define CLASSTWO_SETRECV "AT+FCR=%d"
#define CLASSTWO_SETBOR "AT+FBOR=0"
#define CLASSTWO_SETPARAMS "AT+FDIS=%d,%d,%d,%d,%d,%d,0,%d"
#define CLASSTWO_SENDET "AT+FET=%d"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CClassTwo::CClassTwo()
{
m_sEIAClass = "2";
m_nScanTime = 0;
}
CClassTwo::~CClassTwo()
{
}
void CClassTwo::OnConnect(void)
{
SetState( STATE_INIT );
m_bGotOK = false;
SendCommand( COMMAND_INIT );
m_nLoopCtr = 0;
}
bool CClassTwo::OnDisconnect(void)
{
switch( m_nState )
{
case STATE_INIT:
SignalEvent( EVENT_ERROR );
return true;
case STATE_PHASE_A:
case STATE_PHASE_B:
case STATE_PHASE_C:
case STATE_PHASE_D:
case STATE_PHASE_E:
Abort( true );
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////
// OnWrite
//////////////////////////////////////////////////////////////////////
void CClassTwo::OnWrite(void)
{
m_dwActivityTimer = GetTickCount();
if( m_nState == STATE_PHASE_C && !m_bReceiving && m_bGotDCS )
{
m_nPageBytes += m_BytesWritten;
int nPercent = 100 * m_nPageBytes / m_FaxFile.GetPageBytes();
if( nPercent > 100 )
nPercent = 100;
SignalEvent( EVENT_PAGE_DATA, nPercent );
}
}
//////////////////////////////////////////////////////////////////////
// OnReadLine
//////////////////////////////////////////////////////////////////////
void CClassTwo::OnReadLine(void)
{
//char szMsg[256];
//wsprintf( szMsg, "CClassTwo::OnReadLine: %s %d\n", m_szLineBuff, m_nLineBuffPtr );
//OutputDebugString( szMsg );
switch( m_nState )
{
case STATE_IDLE:
PhaseIdle();
break;
case STATE_INIT:
PhaseInit();
break;
case STATE_PHASE_A:
PhaseA();
break;
case STATE_PHASE_B:
PhaseB();
break;
case STATE_PHASE_C:
PhaseC();
break;
case STATE_PHASE_D:
PhaseD();
break;
case STATE_PHASE_E:
PhaseE();
break;
case STATE_RINGING:
PhaseRinging();
break;
case STATE_DISCONNECT:
PhaseDisconnect();
break;
}
}
//////////////////////////////////////////////////////////////////////
// PhaseInit
//////////////////////////////////////////////////////////////////////
void CClassTwo::PhaseInit(void)
{
if( stricmp( m_szLineBuff, m_LastCommandString.c_str() ) == 0 )
{
// Echo - ignore
return;
}
if( IsRing() )
{
// RING
m_nRingCount++;
return;
}
switch( m_nLastCommand )
{
case COMMAND_INIT:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
m_bGotOK = true;
}
else
{
if( ++m_nLoopCtr >= 3 )
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
}
break;
case COMMAND_SETUP_STRING:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_DISABLE_ECHO );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_DISABLE_ECHO:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_SPKR_VOL );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_SPKR_VOL:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_SPKR_MODE );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_SPKR_MODE:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_FCLASS_2 );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_FCLASS_2:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_QUERY_CLASS2_CAP );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_QUERY_CLASS2_CAP:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_QUERY_SEND_SPEEDS );
}
else if( stricmp( m_szLineBuff, "ERROR" ) == 0 )
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
else
{
ProcCapabilities( m_szLineBuff );
VerifyOptions();
}
break;
case COMMAND_QUERY_SEND_SPEEDS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_QUERY_RECEIVE_SPEEDS );
}
else
{
ProcSupportedSpeeds( m_szLineBuff, true );
}
break;
case COMMAND_QUERY_RECEIVE_SPEEDS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SetLocalID();
}
else
{
ProcSupportedSpeeds( m_szLineBuff, false );
}
break;
case COMMAND_SET_LOCAL_ID:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SetRecv();
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_RECV:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SetBitOrder();
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_BIT_ORDER:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
m_nScanTime = 0;
SetFaxParams( false );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
case COMMAND_SET_FAX_PARAMS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SetState( STATE_IDLE );
KillTimer( TIMER_COMMAND );
}
else
{
ErrorUnexpectedResponse();
SignalEventString( EVENT_INFO, (char*)LoadString(GEN_REDUCE_COMPRESSION_BAUD_RATE_OR_DISABLE_ECM).c_str() );
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
break;
}
}
//////////////////////////////////////////////////////////////////////
// PhaseIdle
//////////////////////////////////////////////////////////////////////
void CClassTwo::PhaseIdle(void)
{
if( IsRing() )
{
m_nRingCount = 1;
SetState( STATE_RINGING );
SignalEvent( EVENT_RING, m_nRingCount );
}
}
//////////////////////////////////////////////////////////////////////
// Phase Ringing
//////////////////////////////////////////////////////////////////////
void CClassTwo::PhaseRinging(void)
{
if( IsRing() )
{
m_nRingCount++;
SignalEvent( EVENT_RING, m_nRingCount );
/*
if( OkToAnswer() )
{
m_bReceiving = true;
m_bSuccessful = false;
SendCommand( COMMAND_ANSWER );
SetState( STATE_PHASE_B, STATE_RECEIVING );
}
*/
}
else if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
{
EnableSoftFlowControl( false );
m_FaxFile.SetSendEncoding( m_nSendEncoding );
m_bReceiving = true;
m_bSuccessful = false;
SignalEvent( EVENT_START_RECV );
SetState( STATE_PHASE_B, STATE_RECEIVING );
}
else
{
SignalEvent( EVENT_CALLERID );
}
}
//////////////////////////////////////////////////////////////////////
// Phase A - call setup
//////////////////////////////////////////////////////////////////////
void CClassTwo::PhaseA(void)
{
switch( m_nPhaseState )
{
case STATE_SET_PARAMS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SetLocalID();
m_nPhaseState = STATE_SET_CSID;
}
else
{
// Error setting fax params
m_sLastError.assign( (char*)LoadString(GEN_ERROR_SETTING_FAX_PARAMETERS).c_str() );
//SignalEvent( EVENT_ERROR );
Terminate();
PhaseDisconnect();
}
break;
case STATE_SET_CSID:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
if( m_bReceiving )
{
SendCommand( COMMAND_ANSWER );
SetState( STATE_PHASE_B, STATE_RECEIVING );
}
else
{
SendCommand( COMMAND_DIAL );
m_nPhaseState = STATE_DIALING;
}
}
else
{
// Error setting ID
m_sLastError.assign( (char*)LoadString(GEN_ERROR_SETTING_ID).c_str() );
//SignalEvent( EVENT_ERROR );
Terminate();
PhaseDisconnect();
}
break;
case STATE_DIALING:
if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
{
m_nLoopCtr = 0;
SetState( STATE_PHASE_B, STATE_SENDING );
m_bGotDIS = false;
SignalEvent( EVENT_START_SEND );
}
else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
{
OnFHNG();
}
else
{
ErrorConnectResponse();
Terminate();
PhaseDisconnect();
}
break;
}
}
//////////////////////////////////////////////////////////////////////
// Phase B - negotiation and training
//////////////////////////////////////////////////////////////////////
void CClassTwo::PhaseB(void)
{
switch( m_nPhaseState )
{
case STATE_RECEIVING:
if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
{
m_bGotEOP = false;
m_bGotMPS = false;
m_bGotEOM = false;
// On to phase C
DoWrite( CLASSTWO_DR, CLASSTWO_DR_SIZE, true );
SetState( STATE_PHASE_C );
m_FaxFile.WriteFileHeader();
SignalEvent( EVENT_START_TRAINING );
}
else if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
{
SignalEvent( EVENT_START_RECV );
}
else if( strnicmp( m_szLineBuff, CLASSTWO_TSI, CLASSTWO_TSI_SIZE ) == 0 )
{
OnCSI();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_DCS, CLASSTWO_DCS_SIZE ) == 0 )
{
OnDCS();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_NSS, CLASSTWO_NSS_SIZE ) == 0 )
{
OnNSS();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
{
OnFHNG();
}
break;
case STATE_SENDING:
if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
{
// Check DIS and re-set parameters if necessar
if( m_bGotDIS && m_bResendFaxParams )
{
SetFaxParams( true );
m_nPhaseState = STATE_RESET_PARAMS;
}
else
{
// On to Phase C
DoWrite( CLASSTWO_DT, CLASSTWO_DT_SIZE, true );
SetState( STATE_PHASE_C );
m_bGotDCS = false;
SignalEvent( EVENT_START_TRAINING );
m_bLastPageGood = false;
}
}
else if( strnicmp( m_szLineBuff, CLASSTWO_CSI, CLASSTWO_CSI_SIZE ) == 0 )
{
OnCSI();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_DIS, CLASSTWO_DIS_SIZE ) == 0 )
{
OnDIS();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_NSF, CLASSTWO_NSF_SIZE ) == 0 )
{
OnNSF();
}
else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
{
OnFHNG();
}
break;
case STATE_RESET_PARAMS:
if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -