📄 fax.cpp
字号:
state = ((rc = Send_DIS()) != 0) ? // q. DIS send go ok?
RcvError : // a. no .. declare error
GetFrames; // else .. get frames
delay(nGetFrame);
break;
case GetFrames: // get HDLC frames
Display_Msg(46); //
if ((rc = Rcv_Hmsg()) != 0) // q. any error getting a frame?
if (rc < 0) // a. yes .. timeout or ESC?
{ // a. yes ..
error = 3; // .. error receiving HDLC frame
state = RcvError; // .. leave with error.
continue; // .. continue process
}
if (rc) // q. any error yet?
{ // a. yes ..
state = RcvError; // .. declare an error
continue;
}
switch(hmsg.fax_ctl_fld) // process based on message type
{
case FAX_FCF_TSI: // transmitting subscriber ID
Display_Msg(6); // update the status
Reverse_Bytes(hmsg.data, // .. reset the bytes to normal
20);
hmsg.data[20] = 0; // .. end string in zero
Display_ID("发送方:",hmsg.data,did);
did=FALSE;
break;
case FAX_FCF_DCN: // disconnect
Display_Msg(16); // update the status
state = PhaseE; // .. and hang up
continue;
case FAX_FCF_DCS: // digital command signal
Display_Msg(7); // update the status
if(hmsg.len>7)
memcpy(DCS_DATA, hmsg.data, // .. move the DIS to work area
(hmsg.len - 7) >16 ? 16 : (hmsg.len - 7));
else
memcpy(DCS_DATA, hmsg.data,hmsg.len);
dcs_received = 1; // show we got DCS
break;
}
if (hmsg.ctl_fld == FAX_CTL_FF) // q. final frame?
{ // a. yes ..
if(!fileopen)
{
if((faxfile = fopen(faxname, "w+b"))== NULL)
{ // a. no ..
error = 9; // .. set the error code
state = RcvError; // .. and declare an error
continue;
}
fileopen = TRUE; // show the file is open
}
if(!(DCS_DATA[1]&0x02))*(WORD *)header.fine=0;
state = SetSpeed;
}
break;
case SetSpeed: // set the link speed
if (dcs_received == 0) // q. dcs 已被确认?
{ // a. no ..
error = 4; // .. show the error
state = RcvError; // .. and go to error state
continue; // .. continue with next state
}
switch ( DCS_DATA[1] & 0x30 ) // get modulation value
{
case 0x20: // q. speed 9600?
speed = 96; // a. yes .. set speed
i = 41; // .. and message
break;
case 0x30: // q. speed 7200?
speed = 72; // a. yes .. set speed
i = 42; // .. and message
break;
case 0x10: // q. speed 4800?
speed = 48; // a. yes .. set speed
i = 43; // .. and message
break;
case 0x00: // q. speed 2400?
speed = 24; // a. yes . set speed
i = 44; // .. and message
break;
default:
state = RcvError;
continue;
}
Display_Msg(i); // display speed message
state = PrepTCF; // next, prepare to test link
break;
case PrepTCF: // prepare to receive TCF
if((WORD)speed >(WORD)max_recespeeds)
{
rc=Get_Char(&c, 5);
if(rc==0)rc = Get_Char(&c, 2);
cp->Purge(1);
state = FailConnTCF;
//cp->IClear();
//delay(1000);
continue;
// speed =max_recespeeds;
}
else
{
rc = Data_Mode(RECEIVE, speed); // start the receive
}
if (rc == 1) // q. did connection fail?
state = FailConnTCF; // a. yes.. fail TCF connect
else if (rc != 0) // q. other failure?
state = RcvError; // a. yes .. declare an error
else
{
state = RcvTCF; // receive training check frame
Display_Msg(9); // update the status
}
break;
case FailConnTCF: // fail the TCF connect
rc = Send_Hmsg(FINAL, // send failure to train
FAX_FCF_FTT, 0);
if (rc) // q. retrain send fail?
state = RcvError; // a. yes .. declare an error
else
state = GetFrames; // get a new set of frames
break;
case RcvTCF: // receive/test TCF
rc = Get_Char(&c, 15); // wait a max of 5 secs for data
if (rc != 0) // q. any error
{ // a. yes ..
state = RcvError; // .. declare an error
continue; // .. and continue processing
}
if ((BYTE) c == 0) // q. zero byte?
state = RcvTCF1; // a. yes .. receive the rest
break;
case RcvTCF1: // get rest of TCF
st = clock();
for(;;) // get characters
{
rc = Get_Char(&c, 5); // get a character
if (rc != 0) // q. any error?
{ // a. yes ..
cp->Purge(1); // .. purge the comm line
error = 7; // .. TCF too short
state = RcvError; // .. declare an error
break; // .. and exit loop
}
if (c != 0)break;
}
// if (rc != 0) // q. was there an error?
// continue; // a. yes .. continue process
et=clock()-st;
if ( et< small_time) // et > big_time // q. 1.5 seconds +/- 10%?
{ // a. yes ..
cp->Purge(1); // .. purge the comm line
state = FailTCF; // .. declare train failure
continue; // .. and continue loop
}
rc = wait_for(cp,FAX_NO_CARR, // wait for no carrier
FAX_ERR, 10) - 1; // .. or other information
if (rc != 0) // q. NO CARRIER 已被确认?
{ // a. no ..
state = RcvError; // .. declare receieve error
continue; // .. and continue loop
}
state = Confirm; // else .. confirm TCF
break; // .. and continue processing
case FailTCF: // fail the TCF
Display_Msg(19); // update the status
rc = Send_Hmsg(FINAL, // send failure to train
FAX_FCF_FTT, 0);
if (rc) // q. retrain send fail?
state = RcvError; // .. declare an error
else
state = GetFrames; // get a new set of frames
break;
case Confirm: // confirm training check frame
Display_Msg(10); // update the status
rc = Send_Hmsg(FINAL, // send the confirmation
FAX_FCF_CFR, 0);
if (rc != 0) // q. confirmation go ok?
{
state = RcvError; // a. no .. show the error
continue; // .. continue processing
}
state = PhaseC; // start receiving FAX
break;
case PhaseC: // receive the FAX data
rc = Data_Mode(RECEIVE, speed); // start receiving the FAX
if (rc != 0) // q. receive start ok?
{
//state = RcvError; // a. no .. show the error
state = PhaseE; // .. and hang up
continue; // .. continue processing
}
*(long *)header.data_len = 0; // .. and no page data yet
*(WORD *)header.page_count=1;
*(WORD *)header.page_number=*(WORD *)header.page_number+1;
fseek(faxfile, 0L, SEEK_END); // go to end of file
off_len= ftell(faxfile);
fwrite(&header,sizeof(FaxHeader),1,faxfile);
state = RcvPage; // receive a page of data
dleflag = FALSE; // set no DLE seen yet
pbi = 0; // reset the page buffer index
Display_Msg((char *)fax_msgs[11]);
sprintf(fs.f_msg,"第%d页:",*(WORD *)header.page_number);
(stat)(OUT_TITLE,&fs);
strcpy(fs.f_msg,"0字节");
(stat)(OUT_COUNT,&fs);
break;
case RcvPage: // receive 1 page of data
rc = Get_Char(&c, 5); // get a character
if (rc != 0) // q. receive ok?
{ // a. no ..
state = RcvError; // .. declare an error
continue; // .. and continue processing
}
pagebuf[pbi++] = c; // save the character
*(long *)header.data_len=*(long *)header.data_len+1; // increment bytes in page
if (dleflag) // q. previous char DLE?
{ // a. yes ..
dleflag = FALSE; // .. reset the flag
if (c == ETX) // q. DLE ETX sequence?
{ // a. yes ..
state = EndPage; // .. process end of page
Display_Msg(12); // update the status
}
}
else if (c == DLE) // q. char a DLE?
{
pbi--;
*(long *)header.data_len=*(long *)header.data_len-1;
dleflag = TRUE; // a. yes .. show TRUE
}
if (pbi >= RECEIVE_BUFF_SIZE) // q. buffer full?
{ // a. yes ..
fwrite(pagebuf, sizeof(char),RECEIVE_BUFF_SIZE,faxfile);
pbi = 0; // reset page buffer index
sprintf(fs.f_msg,"%lu字节",*(long *)header.data_len);
(stat)(OUT_COUNT,&fs);
}
break; // continue processing
case EndPage: // Page complete
if (pbi)fwrite(pagebuf,sizeof(char),pbi,faxfile); // a. yes.. write out a page
*(long *)header.off_len=ftell(faxfile);
fseek(faxfile,off_len, SEEK_SET);
fwrite(&header,sizeof(FaxHeader),1,faxfile); // update the page's length
fseek(faxfile,0L, SEEK_END);
rc = wait_for(cp,FAX_NO_CARR, // we should now have no carrier
FAX_ERR, 20) - 1;
if (rc != 0) // q. correct response?
{ // a. no ..
state = RcvError; // .. declare an error
continue;
}
state = PhaseD; // start post message procedure
break;
case PhaseD: // post message procedure
rc = Rcv_Hmsg(); // get the next message
if (rc != 0) // q. correct response?
{ // a. no ..
//state = RcvError; // .. declare an error
state = PhaseE; // .. disconnect now
continue;
}
i = hmsg.fax_ctl_fld; // save the response
rc = Send_Hmsg(FINAL, // send the final frame
FAX_FCF_MCF, 0); // .. message confirmation
if (rc != 0) // q. correct response?
{ // a. no ..
// state = RcvError; // .. declare an error
state = PhaseE; // .. disconnect now
continue;
}
switch(i) // based on the response..
{
case FAX_FCF_MPS: // multi-page signal
Display_Msg(13); // update the status
state = PhaseC; // .. receive next page
break;
case FAX_FCF_EOM: // end of message
Display_Msg(14); // update the status
state = PhaseB; // .. renegotiate & continue
break;
case FAX_FCF_EOP: // end of procedure
Display_Msg(15); // update the status
state = PhaseE; // .. disconnect now
break;
case FAX_FCF_DCN: // disconnect
Display_Msg(16); // update the status
state = PhaseE; // .. and hang up
continue;
default:
//state = RcvError; // unknown response
state = PhaseE; // .. disconnect now
break;
}
break; // continue processing
case PhaseE: // call is done .. disconnect
// cp->Write(FAX_HANGUP); // hangup the 调制解调器
state = ExitFax; // .. and exit the fax receive
break;
case RcvError: // error during receive
// Display_Msg(17); // update the status
if (rc == -2) // q. user cancellation?
{ // a. yes ..
state = UserCan; // .. show the reason
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -