1 /*	$Id$ */
2 /*
3  * Copyright (c) 1990-1996 Sam Leffler
4  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
5  * HylaFAX is a trademark of Silicon Graphics
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  *
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  */
26 #ifndef _CLASS1_
27 #define	_CLASS1_
28 /*
29  * EIA/TIA-578 (Class 1) Modem Driver.
30  */
31 #include "FaxModem.h"
32 #include "FaxParams.h"
33 
34 class HDLCFrame;
35 
36 /*
37  * Class 1 modem capability (for sending/receiving).
38  */
39 typedef struct {
40     int		value;	// Class 1 parameter value (e.g for +FRM)
41     u_char	br;	// Class 2 bit rate parameter
42     u_short	sr;	// T.30 DCS signalling rate
43     u_char	mod;	// modulation technique
44     bool	ok;	// true if modem is capable
45 } Class1Cap;
46 #define	HasShortTraining(c) \
47     ((c)->mod == V17 && ((c)->value & 1) && (c)[1].ok)
48 
49 class Class1Modem : public FaxModem {
50 protected:
51     fxStr	thCmd;			// command for transmitting a frame
52     fxStr	rhCmd;			// command for receiving a frame
53     fxStr	classCmd;		// set class command
54     u_int	serviceType;		// modem service required
55     FaxParams	dis_caps;		// current remote DIS
56     u_int	frameSize;		// size of image frames
57     u_int	signalRcvd;		// last signal received in ECM protocol
58     fxStr	frameRcvd;		// last frame received from the remote
59     fxStr	signalSent;		// last signal sent to remote
60     u_int	nonV34br;		// modemParams.br without V.34
61     bool	sendERR;		// T.30-A send ERR instead of MCF
62     bool	hadV34Trouble;		// indicates failure due to V.34 restrictions
63     bool	hadV17Trouble;		// indicates failure due to V.17 problems
64     bool	batchingError;		// indicates failure due to batching protocol
65     bool	jbigSupported;		// whether or not JBIG is supported in this mode
66     const u_char* frameRev;		// HDLC frame bit reversal table
67     fxStr	lid;			// encoded local id string
68     fxStr	pwd;			// transmit password
69     fxStr	sub;			// transmit subaddress
70     Class1Cap	xmitCaps[15];		// modem send capabilities
71     Class1Cap	recvCaps[15];		// modem recv capabilities
72     const Class1Cap* curcap;		// capabilities being used
73     u_int	discap;			// DIS signalling rate capabilities
74     u_int	prevPage;		// count of previous pages received
75     u_int	prevBlock;		// count of previous blocks (of this page) received
76     bool	pageGood;		// quality of last page received
77     bool	recvdDCN;		// received DCN frame
78     bool	messageReceived;	// expect/don't expect message carrier
79     bool	repeatPhaseB;		// return to beginning of Phase B before next page
80     bool	silenceHeard;		// indicates whether the last command was +FRS
81     time_t	lastMCF;		// indicates the time of the last MCF signal
82     u_int	lastPPM;		// last PPM during receive
83     bool	sendCFR;		// received TCF was not confirmed
84     u_int	ecmPage;		// page number for ECM frame
85     u_short	ecmBitPos;		// bit position to populate on ecmByte
86     u_int	ecmByte;		// pending byte to add to ecmBlock
87     u_short	ecmOnes;		// count of consecutive ones for adding zero bits
88     u_char*	ecmFrame;		// to hold outgoing frames as they are read from the file
89     u_int	ecmFramePos;		// fill pointer for ecmFrame
90     u_char*	ecmBlock;		// to hold 256 raw ecmFrames to send before MCF
91     u_long	ecmBlockPos;		// fill pointer for ecmBlock
92     u_char*	ecmStuffedBlock;	// to hold image block after adding transparent zeros and FCS bytes
93     u_long	ecmStuffedBlockPos;	// fill pointer for ecmStuffedBlockPos
94     u_int	frameNumber;		// frame sequence number of ecmFrame in ecmBlock
95     u_short	blockNumber;		// block sequence number of ecmBlock in page
96     int		imagefd;		// file descriptor for raw image
97 
98     static const u_int modemPFMCodes[8];// map T.30 FCF to Class 2 PFM
99     static const u_int modemPPMCodes[8];// map T.30 FCF to Class 2 PPM
100     static const Class1Cap basicCaps[15];
101     static const char* rmCmdFmt;
102     static const char* tmCmdFmt;
103 
104     enum {			// modulation techniques
105 	V21   = 0,		// v.21, ch 2 300 bits/sec
106 	V27FB = 1,		// v.27ter fallback mode
107 	V27   = 2,		// v.27ter, 4800, 2400
108 	V29   = 3,		// v.29, 9600, 7200
109 	V17   = 4,		// v.17, 14400, 12000, 9600, 7200
110 	V33   = 5 		// v.33, 14400, 12000, 9600, 7200
111     };
112     static const char* modulationNames[6];
113 
114 // V.34 indicators
115     bool	useV34;		// whether or not V.8 handhaking was used
116     bool	gotEOT;		// V.34-fax heard EOT signal
117     bool	gotCONNECT;	// whether or not CONNECT was seen
118     bool	gotCTRL;	// current channel indicator
119     bool	gotRTNC;	// retrain control channel
120     u_short	primaryV34Rate;	// rate indication for primary channel
121     u_short	controlV34Rate;	// rate indication for control channel
122     fxStr	ctrlFrameRcvd;	// unexpected control channel frame received
123 
124 // modem setup stuff
125     virtual bool setupModem(bool isSend = true);
126     virtual bool setupClass1Parameters();
127     virtual bool setupFlowControl(FlowControl fc);
128 // transmission support
129     bool	sendPrologue(FaxParams& dcs_caps, const fxStr& tsi);
130     void	checkReceiverDIS(Class2Params&);
131     bool	dropToNextBR(Class2Params&);
132     bool	raiseToNextBR(Class2Params&);
133     bool	sendTraining(Class2Params&, int, Status& eresult);
134     bool	sendTCF(const Class2Params&, u_int ms);
135     bool	sendPage(TIFF* tif, Class2Params&, u_int, u_int, Status& eresult, bool cover);
136     bool	sendPageData(u_char* data, u_int cc, const u_char* bitrev, bool ecm, Status& eresult);
137     bool	sendRTC(Class2Params params, u_int ppmcmd, uint32 rowsperstrip, Status& eresult);
138     bool	sendPPM(u_int ppm, HDLCFrame& mcf, Status& eresult);
139     bool	decodePPM(const fxStr& pph, u_int& ppm, Status& eresult);
140 // reception support
141     const AnswerMsg* findAnswer(const char*);
142     bool	recvIdentification(
143 		    u_int f1, const fxStr& pwd,
144 		    u_int f2, const fxStr& addr,
145 		    u_int f3, const fxStr& nsf,
146 		    u_int f4, const fxStr& id,
147 		    u_int f5, FaxParams& dics,
148 		    u_int timer, bool notransmit, Status& eresult);
149     bool	recvDCSFrames(HDLCFrame& frame);
150     bool	recvTraining();
151     bool	recvPPM(int& ppm, Status& eresult);
152     bool	recvPageData(TIFF*, Status& eresult);
153     bool	raiseRecvCarrier(bool& dolongtrain, Status& eresult);
154     void	recvData(TIFF*, u_char* buf, int n);
155     void	processDCSFrame(const HDLCFrame& frame);
156     void	abortPageRecv();
157 // miscellaneous
158     enum {			// Class 1-specific AT responses
159 	AT_FCERROR	= 100, 	// "+FCERROR"
160 	AT_FRH3		= 101	// "+FRH:3"
161     };
162     virtual ATResponse atResponse(char* buf, long ms = 30*1000);
163     virtual bool waitFor(ATResponse wanted, long ms = 30*1000);
164     virtual bool atCmd(const fxStr& cmd, ATResponse = AT_OK, long ms = 30*1000);
165     bool	switchingPause(Status& eresult, u_int times = 1);
166     void	encodeTSI(fxStr& binary, const fxStr& ascii);
167     void	encodeNSF(fxStr& binary, const fxStr& ascii);
168     const fxStr& decodeTSI(fxStr& ascii, const HDLCFrame& binary);
169     void	encodePWD(fxStr& binary, const fxStr& ascii);
170     const fxStr& decodePWD(fxStr& ascii, const HDLCFrame& binary);
171     const Class1Cap* findSRCapability(u_short sr, const Class1Cap[]);
172     const Class1Cap* findBRCapability(u_short br, const Class1Cap[]);
173     static bool isCapable(u_int sr, FaxParams& dis);
174 // class 1 HDLC frame support
175     bool	transmitFrame(fxStr& signal);
176     bool	transmitFrame(u_char fcf, bool lastFrame = true);
177     bool	transmitFrame(u_char fcf, FaxParams& dcs_caps, bool lastFrame = true);
178     bool	transmitFrame(u_char fcf, const fxStr&, bool lastFrame=true);
179     bool	transmitFrame(u_char fcf, const u_char* code, const fxStr&, bool lastFrame=true);
180     bool	transmitData(int br, u_char* data, u_int cc,
181 		    const u_char* bitrev, bool eod);
182     bool	sendFrame(u_char fcf, bool lastFrame = true);
183     bool	sendFrame(u_char fcf, FaxParams& dcs_caps, bool lastFrame = true);
184     bool	sendFrame(u_char fcf, const fxStr&, bool lastFrame = true);
185     bool	sendFrame(u_char fcf, const u_char* code, const fxStr&, bool lastFrame = true);
186     bool	sendRawFrame(HDLCFrame& frame);
187     bool	sendClass1Data(const u_char* data, u_int cc, const u_char* bitrev, bool eod, long ms);
188     bool	sendClass1ECMData(const u_char* data, u_int cc,
189 		     const u_char* bitrev, bool eod, u_int ppmcmd, Status& eresult);
190     bool	recvFrame(HDLCFrame& frame, u_char dir, long ms = 10*1000, bool readPending = false, bool docrp = true, bool usehooksensitivity = true);
191     bool	recvTCF(int br, HDLCFrame&, const u_char* bitrev, long ms);
192     bool	recvRawFrame(HDLCFrame& frame);
193     bool	recvECMFrame(HDLCFrame& frame);
194     bool        waitForDCEChannel(bool awaitctrl);
195     bool        renegotiatePrimary(bool constrain);
196     bool	syncECMFrame();
197     void	abortPageECMRecv(TIFF* tif, const Class2Params& params, u_char* block, u_int fcount, u_short seq, bool pagedataseen);
198     bool	recvPageECMData(TIFF* tif, const Class2Params& params, Status& eresult);
199     void	blockData(u_int byte, bool flag);
200     bool	blockFrame(const u_char* bitrev, bool lastframe, u_int ppmcmd, Status& eresult);
201     bool	endECMBlock();
202     void	abortReceive();
203     void	traceHDLCFrame(const char* direction, const HDLCFrame& frame, bool isecm = false);
204 // class 1 command support routines
205     bool	class1Query(const fxStr& queryCmd, Class1Cap caps[]);
206     bool	parseQuery(const char*, Class1Cap caps[]);
207 public:
208     Class1Modem(FaxServer&, const ModemConfig&);
209     virtual ~Class1Modem();
210     void	hangup();
211 
212 // send support
213     bool	sendSetup(FaxRequest&, const Class2Params&, Status& eresult);
214     CallStatus	dialResponse(Status& eresult);
215     FaxSendStatus getPrologue(Class2Params&, bool&, Status& eresult, u_int&);
216     void	sendBegin();
217     void	sendSetupPhaseB(const fxStr& pwd, const fxStr& sub);
218     FaxSendStatus sendPhaseB(TIFF* tif, Class2Params&, FaxMachineInfo&,
219 		    fxStr& pph, Status& eresult, u_int& batched, PageType pt);
220     void	sendEnd();
221     void	sendAbort();
222 
223 // receive support
224     CallType	answerCall(AnswerType, Status& eresult, const char* number);
225     FaxParams	modemDIS() const;
226     bool	setupReceive();
227     bool	recvBegin(Status& eresult);
228     bool	recvEOMBegin(Status& eresult);
229     bool	recvPage(TIFF*, u_int& ppm, Status& eresult, const fxStr& id);
230     bool	recvEnd(Status& eresult);
231     void	recvAbort();
232     void	pokeConfig(bool isSend);
233 
234 // polling support
235     bool	requestToPoll(Status& eresult);
236     bool	pollBegin(const fxStr& cig, const fxStr& sep, const fxStr& pwd,
237 		    Status& eresult);
238 
239 // miscellaneous
240     bool	faxService(bool enableV34, bool enableV17);	// switch to fax mode (send)
241     bool	reset(long ms);			// reset modem
242     bool	ready(long ms);			// ready modem for receive
243     void	setLID(const fxStr& number);	// set local id string
244     bool	supportsPolling() const;	// modem capability
245 };
246 #endif /* _CLASS1_ */
247