📄 fax.cpp
字号:
if (! connected) // q. connected already?
{ // a. no .. connect now
rc = HDLC_Mode(TRANSMIT); // attempt the connection
if (rc) // q. connect ok?
return(rc); // a. no .. leave w/error
connected = TRUE; // else .. show connected.
}
cp->Write((char *) cmsg, len+5); // send to remote
if (finalflg) // q. final flag on?
{ // a. yes ..
rc = wait_for(cp,FAX_OK, FAX_ERR, 3) - 1; // .. wait for OK
connected = FALSE; // .. and we're not connected
}
else
rc = wait_for1(cp,FAX_CONN, // else .. wait for CONNECT
FAX_NO_CARR,FERROR, 3) - 1; // .. or NO CARRIER
return(rc); // return to caller
}
/* ******************************************************************** *
*
* Get_Char -- retrieve a single character
*
* returns: -2 = User pressed ESC
* -1 - Timeout
* 0 = successful
* 1 = data overrun
*
* ******************************************************************** */
short Fax::Get_Char(char *c, // character to retrieve
short timer) // length of timeout
{
short loop = TRUE; // loop condition
while(loop) // for as long as necessary ..
{
if(cp->WaitComm(timer))
switch(cp->Read(c)) // attempting to read a byte
{
case 0xFFFF: // no character available
if ((stat)(SCAN_EXIT, &fs)) // q. user press escape?
return(-2); // a. yes.. tell the caller
// ThreadSwitchWithDelay();
continue; // else .. continue loop
case 0: // character 已被确认
loop = FALSE; // .. end the loop
break;
default: // lost characters
return(1); // .. show receive unsuccessful
}
else return (-1);
}
return(0); // show we finished ok
}
/* ******************************************************************** *
*
* Reverse_Byte() -- Reverse the bits in a byte
*
* ******************************************************************** */
#if defined(__BORLANDC__)
BYTE Fax::Reverse_Byte(BYTE value) // byte to reverse
{
_asm mov cx, 8 // cx = bits to shift
_asm mov al, value // al = starting value
top_loop: // top of reverse loop
_asm shl ah, 1 // shift ah up by one
_asm shr al, 1 // shift out a bit
_asm adc ah, 0 // .. add carry into ah
_asm loop top_loop // .. until all bits moved
_asm mov value, ah // save reversed value
return(value); // .. and return it
}
#endif
#ifndef _MSC_VER
#ifdef __WATCOMC__
BYTE reverse_byte(BYTE value);
#pragma aux reverse_byte="mov ecx, 8"\
"top_loop: "\
"shl ah, 1"\
"shr al, 1"\
"adc ah, 0"\
"loop top_loop"\
parm[AL] \
value [AH];
BYTE Fax::Reverse_Byte(BYTE value) // byte to reverse
{
return reverse_byte(value);
}
#endif
#else
#if defined(_WIN32)
BYTE Fax::Reverse_Byte(BYTE value) // byte to reverse
{
_asm mov ecx, 8 // cx = bits to shift
_asm mov al, value // al = starting value
top_loop: // top of reverse loop
_asm shl ah, 1 // shift ah up by one
_asm shr al, 1 // shift out a bit
_asm adc ah, 0 // .. add carry into ah
_asm loop top_loop // .. until all bits moved
_asm mov value, ah // save reversed value
return(value); // .. and return it
}
#else
BYTE Fax::Reverse_Byte(BYTE value) // byte to reverse
{
_asm mov cx, 8 // cx = bits to shift
_asm mov al, value // al = starting value
top_loop: // top of reverse loop
_asm shl ah, 1 // shift ah up by one
_asm shr al, 1 // shift out a bit
_asm adc ah, 0 // .. add carry into ah
_asm loop top_loop // .. until all bits moved
_asm mov value, ah // save reversed value
return(value); // .. and return it
}
#endif
#endif
/* ******************************************************************** *
*
* Reverse_Bytes -- reverse the bits in the bytes of a string
*
* ******************************************************************** */
void Fax::Reverse_Bytes(BYTE *str, // string to reverse
short len) // length of string
{
while(len--) // while there are bytes..
{
*str = Reverse_Byte(*str); // .. reverse the bits
str++; // .. next byte
}
}
/* ******************************************************************** *
*
* Display_Msg -- display a message without parameters
*
* ******************************************************************** */
void Fax::Display_Msg(short msgno)
{
fs.f_ptr=(char *)fax_msgs[msgno];
(stat)(OUT_STATICMSG,&fs);
}
void Fax::Display_Msg(char *msgno)
{
fs.f_ptr=msgno;
(stat)(OUT_STATICMSG,&fs);
}
/* ********************************************************************
*
* Send -- Send a Facsimile
*
* ******************************************************************** */
static void SendLine(Comm *cp,char *p,int i)
{
if(memchr(p,DLE,i))
{
char *buf=new char[i*2];
int count=0;
for(int u=0;u<i;u++)
{
buf[count++]=p[u];
if(p[u]==DLE)buf[count++]=DLE;
}
cp->Write(buf,count);
delete buf;
}
else cp->Write(p,i);
}
/* ********************************************************************
*
* Receive -- Receive a Facsimile transmission
*
* ******************************************************************** */
const small_time=(int)((float)CLK_TCK*1.2);
const big_time =(int)((float)CLK_TCK*1.8);
const RECEIVE_BUFF_SIZE =4096;
short Fax::Receive(char *faxname,short __status)
{
char DCS_DATA[16];
short rc = 0, // return code
speed, // link speed
fileopen = FALSE, // receive file not open
dcs_received = FALSE, // DCS not yet 已被确认
i, // work variable
error = 0, // error number
dleflag = FALSE, // DLE sequence found flag
loop = TRUE; // loop until complete
header=FaxHeader();
FILE *faxfile; // fax file
BOOL did=TRUE;
long off_len;
char c; // work character
DWORD st;
DWORD et;
enum RcvStates // FAX receive states
{
PhaseA, // phase A - make connection
AwaitCall, // wait for a call
AnswerCall, // answer incoming call
SendNSF,
SendCSI, // send our CSI frame, if needed
PhaseB, // negotiate session parameters
GetFrames, // get HDLC frames
SetSpeed, // set the link speed
PrepTCF, // prepare to receive TCF
FailConnTCF, // fail the TCF connect
RcvTCF, // receive/test TCF
RcvTCF1, // get rest of TCF
FailTCF, // fail the TCF
Confirm, // confirm training check frame
PhaseC, // receive the FAX data
RcvPage, // receive 1 page of data
EndPage, // page complete
PhaseD, // post message procedure
PhaseE, // call is done .. disconnect
RcvError, // error during receive
UserCan, // user cancelled transmission
ExitFax // exit FAX receive
} state;
pagebuf =new BYTE[RECEIVE_BUFF_SIZE];
state = PhaseA; // start in Phase A
while(loop) // top of state machine
{
switch(state) // perform next state
{
case PhaseA: // phase A - make connection
#if !defined(SERVER_NLM)
Display_Msg(1); // update the status
#endif
if ((rc = Init_Modem(1)) != 0) // q. 调制解调器 init ok?
{
error = 1; // a. no .. exit now
state = RcvError; // .. declare the error
continue;
}
if(__status==0)
state = AwaitCall; // else .. wait for a ring
else
{
state= AnswerCall; // .. go answer the call
}
#if !defined(SERVER_NLM)
Display_Msg(2); // update the status
#endif
break; // end this state
case AwaitCall: // wait for a call
rc = wait_for(cp,FAX_RING, // wait for a RING from 调制解调器
FAX_RING, 30);
if (rc > 0) // q. RING arrive?
{ // a. yes ..
state = AnswerCall; // .. go answer the call
continue;
}
if (rc == -1) // q. user press ESC?
state = UserCan; // a. yes .. exit now
break; // else .. continue waiting
case AnswerCall: // answer incoming call
Display_Msg(3); // update the status
cp->Write(FAX_ANSWER); // send the answer command
rc = wait_for1(cp,FAX_CONN, // wait for a carrier
FAX_NO_CARR,FAX_BUSY, 60)-1;
if (rc == 0) // q. connect?
{
state = SendNSF;
//state = SendCSI;
connected = TRUE; // .. show we're connected
delay(nSendNSF);
}
else // else ..
{
state = RcvError; // .. process general error
error = 2; // .. show the error type
}
break; // .. next state
case SendNSF:
Display_Msg(47); // update the status
rc = Send_Hmsg(NON_FINAL,FAX_FCF_NSF, 0);
if (rc) // q. error?
state = RcvError; // a. yes .. declare the error
else
state = SendCSI; // select next state
break;
case SendCSI: // send our CSI frame
Display_Msg(4); // update the status
rc = Send_CSI(); // .. send our ID
if (rc) // q. error?
state = RcvError; // a. yes .. declare the error
else
state = PhaseB; // select next state
break;
case PhaseB: // negotiate session parameters
Display_Msg(5); //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -