?? classone.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 CClassOne is contain the protocol specifics of EIA
// fax modem class 1
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ClassOne.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CClassOne::CClassOne()
{
m_sEIAClass = "1";
}
CClassOne::~CClassOne()
{
}
void CClassOne::OnConnect(void)
{
SetState( STATE_INIT );
SendCommand( COMMAND_INIT );
m_nLoopCtr = 0;
}
bool CClassOne::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 CClassOne::OnWrite(void)
{
m_dwActivityTimer = GetTickCount();
if( m_nState == STATE_PHASE_C && !m_bReceiving )
{
m_nPageBytes += m_BytesWritten;
int nPercent = 100 * m_nPageBytes / m_FaxFile.GetPageBytes();
if( nPercent > 100 )
nPercent = 100;
SignalEvent( EVENT_PAGE_DATA, nPercent );
}
}
//////////////////////////////////////////////////////////////////////
// OnReadLine
//////////////////////////////////////////////////////////////////////
void CClassOne::OnReadLine(void)
{
//char szMsg[256];
//wsprintf( szMsg, "CClassOne::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 CClassOne::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;
// m_nLoopCtr = 0;
// SendCommand( COMMAND_SETUP_STRING );
}
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();
//SetState( STATE_IDLE );
SendCommand( COMMAND_DISABLE_ECHO );
}
break;
case COMMAND_DISABLE_ECHO:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_SPKR_VOL );
}
else
{
ErrorUnexpectedResponse();
SendCommand( COMMAND_SET_SPKR_VOL );
}
break;
case COMMAND_SET_SPKR_VOL:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_SPKR_MODE );
}
else
{
ErrorUnexpectedResponse();
SendCommand( COMMAND_SET_SPKR_MODE );
}
break;
case COMMAND_SET_SPKR_MODE:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_SET_FCLASS_1 );
}
else
{
ErrorUnexpectedResponse();
SendCommand( COMMAND_SET_FCLASS_1 );
}
break;
case COMMAND_SET_FCLASS_1:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
SendCommand( COMMAND_QUERY_SEND_SPEEDS );
}
else
{
ErrorUnexpectedResponse();
KillTimer( TIMER_COMMAND );
OnDisconnectMsg();
}
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 )
{
KillTimer( TIMER_COMMAND );
SetState( STATE_IDLE );
}
else
{
ProcSupportedSpeeds( m_szLineBuff, false );
}
break;
}
}
//////////////////////////////////////////////////////////////////////
// PhaseIdle
//////////////////////////////////////////////////////////////////////
void CClassOne::PhaseIdle(void)
{
if( IsRing() )
{
m_nRingCount = 1;
SetState( STATE_RINGING );
SignalEvent( EVENT_RING, m_nRingCount );
}
}
//////////////////////////////////////////////////////////////////////
// Phase Ringing
//////////////////////////////////////////////////////////////////////
void CClassOne::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_A );
}
*/
}
else if( strnicmp( m_szLineBuff, "CONNECT", 7 ) == 0 )
{
m_FaxFile.SetSendEncoding( m_nSendEncoding );
m_bReceiving = true;
m_bSuccessful = false;
m_nLoopCtr = 0;
m_bGotDCN = false;
SignalEvent( EVENT_START_RECV );
SendID(CSI);
SetState( STATE_PHASE_B, STATE_SEND_DIS );
}
else
{
SignalEvent( EVENT_CALLERID );
}
}
//////////////////////////////////////////////////////////////////////
// Phase A - call setup
//////////////////////////////////////////////////////////////////////
void CClassOne::PhaseA(void)
{
if( strnicmp( m_szLineBuff, "CONNECT", 7 ) == 0 )
{
m_nLoopCtr = 0;
m_bGotDCN = false;
if( m_bReceiving )
{
SignalEvent( EVENT_START_RECV );
SendID(CSI);
SetState( STATE_PHASE_B, STATE_SEND_DIS );
}
else
{
SignalEvent( EVENT_START_SEND );
m_bGotDIS = false;
m_bGotConnect = false;
InitHDLC();
SetState( STATE_PHASE_B, STATE_WAIT_FOR_DIS );
}
return;
}
else
{
ErrorConnectResponse();
Terminate();
PhaseDisconnect();
}
}
//////////////////////////////////////////////////////////////////////
// Phase B - negotiation and training
//////////////////////////////////////////////////////////////////////
void CClassOne::PhaseB(void)
{
switch( m_nPhaseState )
{
// begin sending states
case STATE_WAIT_FOR_DIS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
if( m_bGotDCN )
{
m_sLastError.assign( (char*)LoadString(GEN_UNEXPECTED_DCN_RECEIVED).c_str() );
Terminate();
DoHangup();
}
else if( m_bFinalHDLCFrame && m_bGotDIS )
{
m_nLoopCtr = 0;
EnableSoftFlowControl( true );
SendHDLCFrame();
m_nPhaseState = STATE_SEND_TIS;
}
else
{
// ask for another
if( ++m_nLoopCtr >= 6 )
{
m_sLastError.assign( (char*)LoadString(GEN_DIS_NOT_RECEIVED).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
else
{
RecvHDLCFrame();
}
}
}
else if( stricmp( m_szLineBuff, "CONNECT" ) == 0 )
{
// get ready for another HDLC frame
m_bGotConnect = true;
InitHDLC();
KillTimer( TIMER_HDLC_RECV );
}
else
{
if( ++m_nLoopCtr >= 3 )
{
m_sLastError.assign( (char*)LoadString(GEN_DIS_NOT_RECEIVED).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
else
{
RecvHDLCFrame();
}
}
break;
case STATE_SEND_TIS:
if( stricmp( m_szLineBuff, "CONNECT" ) == 0 )
{
SendID(TSI);
m_nPhaseState = STATE_SEND_DCS;
m_bGotConnect = false;
}
else
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_SENDING_TSI).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
break;
case STATE_SEND_DCS:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
// Send 75ms of silence
SendFormattedCommand( "FTS", 8 );
m_nPhaseState = STATE_SEND_SILENCE_BEFORE_TRAINING;
}
else if( stricmp( m_szLineBuff, "CONNECT" ) == 0 )
{
m_bGotConnect = true;
SendDCS();
}
else
{
if( ++m_nLoopCtr >= 3 )
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_SENDING_DCS).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
else
{
SendHDLCFrame();
}
}
break;
case STATE_SEND_SILENCE_BEFORE_TRAINING:
//if( stricmp( m_szLineBuff, "OK" ) != 0 )
//{
// OutputDebugString( "Error sending silence\n" );
//}
SendLongTraining();
// change state
m_nPhaseState = STATE_SEND_TRAINING_DATA;
SignalEvent( EVENT_START_TRAINING );
break;
case STATE_SEND_TRAINING_DATA:
if( stricmp( m_szLineBuff, "CONNECT" ) == 0 )
{
SendTraining();
m_nPhaseState = STATE_SEND_TRAINING;
}
else
{
if( ++m_nLoopCtr >= 3 )
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_SENDING_TRAINING_DATA).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
else
{
SendHDLCFrame();
m_nPhaseState = STATE_SEND_DCS;
m_bGotConnect = false;
}
}
break;
case STATE_SEND_TRAINING:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
m_bGotCFR = false;
m_bGotCRP = false;
//OutputDebugString( "Requesting CFR\n" );
EnableSoftFlowControl( false );
RecvHDLCFrame();
// change state
m_nPhaseState = STATE_WAIT_FOR_CFR;
m_bFinalHDLCFrame = false;
char szEvMsg[FAXAPI_MODEMMSG_INFOLEN];
wsprintf( szEvMsg, (char*)LoadString(GEN_SENT_TRAINING_AT_BAUD).c_str(), cls1Speeds[m_nClass1Speed].dwSpeed );
SignalEventString( EVENT_INFO, szEvMsg );
}
else if( stricmp( m_szLineBuff, "CONNECT" ) == 0 )
{
if( m_WriteQueue.size() == 0 )
{
// Send another end of data in case it got lost
//OutputDebugString( "Sending extra <DLE><ETX>\n" );
unsigned char Frame[2];
Frame[0] = DLE; // <dle>
Frame[1] = ETX; // <etx>
DoWrite( (char*)Frame, 2, false );
}
}
else if( m_szLineBuff[0] == XOFF )
{
// Ignore
}
else
{
if( ++m_nLoopCtr >= 3 )
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_IN_TRAINING).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
else
{
SendHDLCFrame();
m_nPhaseState = STATE_SEND_DCS;
m_bGotConnect = false;
}
}
break;
case STATE_WAIT_FOR_CFR:
if( stricmp( m_szLineBuff, "OK" ) == 0 )
{
if( m_bGotDCN )
{
Terminate();
DoHangup();
}
else if( m_bGotCRP )
{
SendHDLCFrame();
m_nPhaseState = STATE_SEND_DCS;
m_bGotConnect = false;
}
else if( m_bFinalHDLCFrame )
{
m_nLoopCtr = 0;
EnableSoftFlowControl( true );
if( m_bGotCFR )
{
// Send 75ms of silence
SendFormattedCommand( "FTS", 8 );
m_nPhaseState = STATE_SEND_SILENCE_BEFORE_DATA;
m_nPPRCtr = 0;
if( m_FaxFile.ReadPage( m_bECM, m_nClass1Speed, m_wMinLineChars ) == false )
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_READING_TIFF_FILE).c_str() );
// SignalEvent( EVENT_ERROR );
SendHDLCFrame();
SetState( STATE_PHASE_E, STATE_SEND_DCN );
}
}
else
{
if( m_nClass1Speed == 0 )
{
m_sLastError.assign( (char*)LoadString(GEN_ERROR_IN_TRAINING).c_str() );
SendHDLCFrame();
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -