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 _HDLCFRAME_
27 #define	_HDLCFRAME_
28 /*
29  * Raw HDLC Frame Interface.
30  */
31 #include "Types.h"
32 #include "FaxParams.h"
33 
34 class HDLCFrame {
35 public:
36     HDLCFrame(u_int frameOverhead);
37     HDLCFrame(const HDLCFrame& fr);
38     ~HDLCFrame();
39 
40     void put(u_char c);			// Put the character "c" into the buffer
41     void put(const u_char* c, u_int len);// Put bunch of bytes in the buffer
42     void reset();			// Reset buffer to empty
43     u_int getLength() const;		// Return number of bytes in buffer
44 
45     operator u_char*();			// Return base of buffer
46     u_char& operator[](u_int i) const;	// NB: no bounds checking
47     u_char& operator[](int i) const;	// NB: no bounds checking
48 
49     bool moreFrames() const;		// more frames follow
50     bool isOK() const;			// frame has good FCS
51     bool checkCRC() const;		// validate the CRC checksum
52     u_int getCRC() const;		// return the 1s complement of the CRC
53     void setOK(bool b);			// set frame FCS indicator
54     u_int getRawFCF() const;		// raw FCF in frame
55     u_int getFCF() const;		// FCF &~ (FCF_SNDR|FCF_RCVR)
56     u_int getFCF2() const;		// FCF2 for T.30 Annex A
57     const u_char* getFrameData() const;	// data following FCF
58     u_int getFrameDataLength() const;	// length of data - (FCF+FCS)
59     u_int getDataWord() const;		// first 0-4 bytes of data
60     FaxParams getDIS() const;	// DIS/DCS data
61 protected:
62     u_char	buf[2048];		// large enough for TCF at 9600 baud
63     u_char*	next;
64     u_char*	end;
65     u_char*	base;
66     u_short	amountToGrowBy;
67     u_short	frameOverhead;		// # bytes for leader & FCS
68     u_int	crc;			// CRC16-CCITT calculation
69     bool	ok;			// FCS correct
70 
71     void addc(u_char c);		// make room & add a char to the buffer
72     void grow(u_int amount);		// make more room in the buffer
73     void buildCRC(u_char c);		// calculate the CRC for the frame
74 };
75 
put(u_char c)76 inline void HDLCFrame::put(u_char c)
77     { if (next < end) *next++ = c; else addc(c); buildCRC(c); }
reset()78 inline void HDLCFrame::reset()			    { next = base; ok = false; crc = 0xffff; }
getLength()79 inline u_int HDLCFrame::getLength() const	    { return next - base; }
80 
81 inline HDLCFrame::operator u_char*()		    { return base; }
82 inline u_char& HDLCFrame::operator[](u_int i) const { return base[i]; }
83 inline u_char& HDLCFrame::operator[](int i) const   { return base[i]; }
84 
moreFrames()85 inline bool HDLCFrame::moreFrames() const
86     { return ((*this)[1]&0x08) == 0; }
isOK()87 inline bool HDLCFrame::isOK() const		     { return ok; }
checkCRC()88 inline bool HDLCFrame::checkCRC() const		     { return crc == 0x1d0f; }
getCRC()89 inline u_int HDLCFrame::getCRC() const		     { return ~crc; }
setOK(bool b)90 inline void HDLCFrame::setOK(bool b)		     { ok = b; }
getRawFCF()91 inline u_int HDLCFrame::getRawFCF() const	     { return (*this)[2]; }
getFCF()92 inline u_int HDLCFrame::getFCF() const		     { return (*this)[2]&0x7f; }
getFCF2()93 inline u_int HDLCFrame::getFCF2() const		     { return (*this)[3]&0x7f; }
getFrameData()94 inline const u_char* HDLCFrame::getFrameData() const { return &((*this)[3]); }
getFrameDataLength()95 inline u_int HDLCFrame::getFrameDataLength() const
96     { u_int len = getLength(); return  len > frameOverhead ? len - frameOverhead : 0; }
97 #endif /* _HDLCFRAME_ */
98