📄 awfax.pas
字号:
(***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower Async Professional
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1991-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* AWFAX.PAS 4.06 *}
{*********************************************************}
{* Low-level fax support *}
{*********************************************************}
{
Contains the fax state machine, access methods for the fax
records, etc.
}
{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}
{Options required for this unit}
{$A+,F+,I-,R-,S-,V-,X+,T-}
{$IFDEF Win32}
{$J+}
{$ENDIF}
{.$DEFINE DebugFax}
unit AwFax;
{-Class 1, class 2 and class 2.0 fax send/receive objects}
interface
uses
WinTypes,
WinProcs,
Graphics,
Messages,
SysUtils,
Classes,
OoMisc,
AwUser,
AwFaxCvt,
AwAbsFax;
{$IFDEF DebugFax}
var
debug : text;
{$ENDIF}
const
MaxModIndex = 6;
PhysicalTopMargin : Word = 8; {Physical top margin in raster lines}
{Default values for fax transmit yielding}
DefMaxSendCnt = 50; {Max blocks/lines per call}
DefBufferMin = 1000; {Minimum buffer quantity before yield}
awfDefFaxDialTimeout = 1092; {Default ticks for dial timeout}
awfDefCmdTimeout = 182; {Default ticks for command timeout (10 secs)}
awfDefTransTimeout = 1092; {Default ticks to wait for flow control release}
aDataTrigger = 0;
type
PFaxDataBuffer = ^TFaxDataBuffer;
TFaxDataBuffer = array[0..$FFF0] of Byte;
{Class 2/2.0 command/response strings}
TClass2Str = String[13];
{Modem response string}
TModemResponse = String[128];
{Class 1/2 abstract data}
PC12AbsData = ^TC12AbsData;
TC12AbsData = record
cForceStatus : Boolean; {True to force special status}
cMorePages : Boolean; {True if more fax pages to receive}
cSessionRes : Boolean; {Remote/session resolution}
cSessionWid : Boolean; {Remote/session high width}
cSessionECM : Boolean; {Remote/session ECM}
cCanDoHighRes : Boolean; {True if capable of high res}
cCanDoHighWid : Boolean; {True if capable of high width}
cLastFrame : Boolean; {True if last Class 1 frame}
cToneDial : Boolean; {True to use tone dialing}
cLastPageOk : Boolean; {True if last page received OK}
cUseLengthWord: Boolean; {True if file has length words}
cCoverIsAPF : Boolean; {True if cover page is apf file}
cInitSent : Boolean; {True if modem/def init sent once}
cSlowBaud : Boolean; {True if using slow baud rate}
cGotCFR : Boolean; {True if got CFR after training}
cBlindDial : Boolean; {True to use X3 instead of X4}
cDetectBusy : Boolean; {True to use X2 instead of X4}
cCheckChar : Char; {ECM character}
cResC : Char; {Resolution character}
cResCPrev : Char; {Previous resolution}
cFaxAndData : Char; {'0' = fax, '1' = fax and data}
cSessionScan : Byte; {Remote/session scantime}
cReceivedFrame: Byte; {last received HDLC frame type}
cCRLFIndex : Byte; {Index for CRLF checking}
cETXIndex : Byte; {Index for DLE/ETX checking}
cReplyWait : Word; {Ticks to wait for a modem reply}
cTransWait : Word; {Ticks to wait for outbuf space}
cMaxFaxBPS : Word; {Max fax BPS for this modem}
cBPSIndex : Word; {Last Class 1BPS index}
cMinBytes : Word; {Minimum raster line length}
cHangupCode : Word; {Last FHNG code}
cCurrOfs : Word; {curr offset in DataBuffer}
cBadData : Word; {Bad bytes during train}
cRetry : Word; {General retry counter}
cBytesRead : Integer; {Bytes to be transmitted}
cDialWait : Integer; {ticks timeout for dialing}
cAnswerOnRing : Integer; {ring on which to answer phone}
cRingCounter : Integer; {count of rings seen}
cSessionBPS : LongInt; {Remote/session BPS}
cNormalBaud : LongInt; {Normal baud rate}
cInitBaud : LongInt; {Initialization baud rate}
cDataBuffer : PFaxDataBuffer; {buffer for received data}
cInFile : File; {received data file}
cFaxHeader : TFaxHeaderRec; {fax file header block}
cPageHeader : TPageHeaderRec; {fax file page header block}
cClassCmd : TClass2Str; {class 2/2.0 +FCLASS command}
cModelCmd : TClass2Str; {class 2/2.0 model command}
cMfrCmd : TClass2Str; {class 2/2.0 manufacturer command}
cRevCmd : TClass2Str; {class 2/2.0 revision command}
cDISCmd : TClass2Str; {class 2/2.0 DIS }
cStationCmd : TClass2Str; {class 2/2.0 Station ID command}
cDCCCmd : TClass2Str; {class 2/2.0 DCC command}
cFaxResp : TClass2Str; {class 2/2.0 Fax call response}
cDISResp : TClass2Str; {class 2/2.0 DIS response}
cDCSResp : TClass2Str; {class 2/2.0 DCS response}
cTSIResp : TClass2Str; {class 2/2.0 TSI response}
cCSIResp : TClass2Str; {class 2/2.0 CSI response}
cPageResp : TClass2Str; {class 2/2.0 page-end response}
cHangResp : TClass2Str; {class 2/2.0 hangup response}
cModCode : String[3]; {modulation code}
cForcedInit : String[40]; {forced init string}
cModemInit : String[40]; {optional modem init string}
cDialPrefix : String[40]; {dialing prefix}
cDialTonePulse: Char; {tone/pulse modifier}
cResponse : TModemResponse; {Current modem response}
cInFileName : ShortString; {name of current file}
cReplyTimer : EventTimer; {Timer for all replies}
cLocalMods : array[1..MaxModIndex] of Boolean; {Local Class 1 mods}
cRmtMods : array[1..MaxModIndex] of Boolean; {Remote Class 1 mods}
cBufferBlock : array[0..8191] of byte; {Buffer for PutBlocks}
cEnhTextEnabled : Boolean; {True to use Enhanced mode}
cEnhSmallFont : TFont; {Font used for header}
cEnhStandardFont: TFont; {Font used for other text}
end;
PC12FaxData = ^TC12FaxData;
TC12FaxData = record
fPData : PFaxData;
fCData : PC12AbsData;
end;
type
PC12SendFax = ^TC12SendFax;
TC12SendFax = record
fPData : PFaxData;
fCData : PC12AbsData; {Pointer to C12 abstract data}
fSafeMode : Boolean; {True to not yield when critical}
fMaxSendCount : Word; {Max iterations before yield}
fBufferMinimum: Word; {Min outbuff value before yield}
fMCFConnect : Boolean; {True if CONNECT waiting for MCF}
fRetries : Integer; {Count of retries on failed page send}
fMaxRetries : Integer; {Max times to retry failed send}
fConverter : PAbsFaxCvt; {fax converter for header lines}
fState : SendStates; {Current state of machine}
fHeaderLine : ShortString; {Header line for each page}
fCvrF : TLineReader; {File for cover page}
fCvrOpen : Boolean; {True if cover opened}
fRetryPage : Boolean; {True to retry page}
fRetryMax : Word; {Number of times to retry a page}
fFastPage : Boolean; {True for old class 1 xmit neg.}
end;
type
PC12ReceiveFax = ^TC12ReceiveFax;
TC12ReceiveFax = record
fPData : PFaxData;
fCData : PC12AbsData; {Pointer to C12 abstract data}
fSafeMode : Boolean; {True to not yield when critical}
fOneFax : Boolean; {True if only receiving one fax}
fConstantStatus : Boolean; {True to display constant status}
fShowStatus : Boolean; {True if status window opened}
fLast : Char; {Last received data char}
fPageStatus : ReceivePageStatus; {Status of most-recent page}
fState : ReceiveStates; {Current state of StateMachine}
fFirstState : ReceiveStates; {State in 1st call to FaxReceivePart}
fRenegotiate : Boolean; {True if we get an EOM frame}
end;
{C12AbsData}
function cInitC12AbsData(var DP : PC12AbsData) : Integer;
{-Allocate and initialize a C12AbsData record}
function cDoneC12AbsData(var DP : PC12AbsData) : Integer;
{-Dispose of a C12AbsData record}
{User Control}
procedure fSetFaxPort(FP : PFaxRec; ComPort : TApdBaseDispatcher);
{-Select the commport to use}
procedure fSetModemInit(FP : PFaxRec; MIS : ShortString);
{-Define the modem init string}
function fSetClassType(FP : PFaxRec; CT : ClassType) : ClassType;
{-Set type of modem, return detected or set type}
procedure fSetInitBaudRate(FP : PFaxRec;
InitRate, NormalRate : LongInt;
DoIt : Boolean);
{-Set baud rate to use when initializing modem}
function fGetModemInfo(FP : PFaxRec; var FaxClass : Char;
var Model, Chip, Rev : TPassString;
Reset : Boolean) : Boolean;
{-Get specific data from modem}
function fGetModemFeatures(FP : PFaxRec; var BPS : LongInt;
var Correction : Char) : Integer;
{-Return highest possible codes}
procedure fSetModemFeatures(FP : PFaxRec; BPS : LongInt;
Correction : Char);
{-Set modem features for this session}
function fGetLastPageStatus(FP : PFaxRec) : Boolean;
{-Return True if last page received OK, false otherwise}
function fGetRemoteID(FP : PFaxRec) : ShortString;
{-Return remote station ID}
procedure fGetSessionParams(FP : PFaxRec;
var BPS : LongInt;
var Resolution : Boolean;
var Correction : Boolean);
{-Return remote/session parameters}
function fGetHangupResult(FP : PFaxRec) : Word;
{-Return last hangup result, class 2 only}
procedure fGetPageInfoC12(FP : PFaxRec;
var Pages : Word;
var Page : Word;
var BytesTransferred : LongInt;
var PageLength : LongInt);
{C12Send init/destroy routines}
function fInitC12SendFax(var FP : PFaxRec; ID : Str20;
ComPort : TApdBaseDispatcher; Window : TApdHwnd) : Integer;
{-Allocate and initialize a send fax record}
{function fDoneC12SendFax(var FP : PFaxRec) : Integer;}
procedure fDoneC12SendFax(var FP : PFaxRec);
{-Dispose of a send fax record}
{User control}
procedure fSetEnhTextEnabled(FP : PFaxRec; Enabled : Boolean);
{-Select normal or "enhanced" text}
procedure fSetEnhSmallFont(FP : PFaxRec; SmFont : TFont);
{-Select font for header text}
procedure fSetEnhStandardFont(FP : PFaxRec; StFont : TFont);
{-Select font for normal text}
procedure fSetBlindDial(FP : PFaxRec; Blind : Boolean);
{-Select normal or "blind" dialing}
procedure fSetDetectBusy(FP : PFaxRec; DetectBusySignal : Boolean);
{-Select busy signal detection}
procedure fSetToneDial(FP : PFaxRec; Tone : Boolean);
{-Select tone or pulse dial (send only)}
procedure fSetDialPrefix(FP : PFaxRec; P : ShortString);
{-Set the dial prefix string}
procedure fSetDialTime(FP : PFaxRec; DT : Integer);
{-Set the dialing timeout}
procedure fSetHeaderText(FP : PFaxRec; S : ShortString);
{-Set HeaderLine to S}
procedure fSetMaxRetries(FP : PFaxRec; MR : Integer);
{-Set MaxRetries to MR}
procedure fSetYielding(FP : PFaxRec; MaxLines, FreeBuffer : Word);
{-Set the max lines sent per call and the minimum free outbuffer space}
procedure fSetSafeMode(FP : PFaxRec; SafeMode : Boolean);
{-Enable/disable safe mode}
procedure fFaxTransmit(Msg, wParam : Cardinal;
lParam : LongInt);
{-Perform one increment of a fax transmit session}
function fPrepareFaxTransmit(FP : PFaxRec) : Integer;
{-Start a background fax transmit}
{C12Receive init/destroy routines}
function fInitC12ReceiveFax(var FP : PFaxRec; ID : Str20;
ComPort : TApdBaseDispatcher; Window : TApdHwnd) : Integer;
{-Allocate and initialize a receive fax record}
function fDoneC12ReceiveFax(var FP : PFaxRec) : Integer;
{-Dispose of a receive fax record}
{User control}
function fInitModemForFaxReceive(FP : PFaxRec) : Boolean;
{-Send nessessary commands to initialize modem for fax receive}
procedure fSetAnswerOnRing(FP : PFaxRec; AOR : Integer);
{-set to answer call on AOR'th ring}
procedure fSetFaxAndData(FP : PFaxRec; OnOff : Boolean);
{-True for fax to answer either fax or data, False for fax only}
procedure fSetConnectState(FP : PFaxRec);
{-Force the receiver to pick up a connection in progress}
procedure fSetOneFax(FP : PFaxRec; OnOff : Boolean);
{-Set "one fax" receive behavior on/off}
procedure fFaxReceive(Msg, wParam : Cardinal;
lParam : LongInt);
{-Perform one increment of a fax transmit session}
function fPrepareFaxReceive(FP : PFaxRec) : Integer;
{-Prepare for first call to fFaxReceive}
function fGetModemClassSupport(FP : PFaxRec;
var Class1, Class2, Class2_0 : Boolean;
Reset : Boolean) : Boolean;
{-Get class support, including 2.0}
const
{Undocumented constants}
AbortDelay : Word = 1000; {Msec wait for +++}
PreCommandDelay : Word = 100; {MSec before general modem cmds}
PreFaxDelay : Word = 40; {MSec before inprog fax modem cmds}
ExtraCommandDelay : Word = 200; {MSec extra delay before some cmds}
PreEOPDelay : Word = 500; {MSec delay before sending EOP}
InterCharDelay : Word = 0; {MSec between modem chars}
OkDelay : Word = 18; {Tick wait for optional OK}
BaudChangeDelay : Word = 9; {Tick delay before changing baud}
Class1Wait : Word = 54; {Tick till frame carrier}
MaxClass1Retry : Word = 3; {Max class 1 frame retries}
implementation
const
{For calculating minimum bytes per line}
ScanTimes : array[0..7, Boolean] of Byte = (
(0,0), {0}
(5,5), {1}
(10,5), {2}
(10,10), {3}
(20,10), {4}
(20,20), {5}
(40,20), {6}
(40,40)); {7}
{For calculating scan time response in DCS frame}
ScanTimeResponse : array[0..7, Boolean] of Byte = (
($70, $70),
($10, $10),
($20, $10),
($20, $20),
($00, $20),
($00, $00),
($40, $00),
($40, $40));
ZeroScanTime = $70;
{For managing Class 1 modulations}
ModArray : array[1..MaxModIndex] of String[3] = (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -