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