2 * Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 /*---------------------------------------------------------------------------
28 * i4b_hdlc.h - software-HDLC header file
29 * --------------------------------------
31 * $Id: i4b_hdlc.h,v 1.5 2000/08/28 07:41:19 hm Exp $
35 * last edit-date: [Wed Jul 19 09:41:13 2000]
37 *---------------------------------------------------------------------------*/
42 extern const u_short HDLC_FCS_TAB[256];
43 extern const u_short HDLC_BIT_TAB[256];
45 /*---------------------------------------------------------------------------*
49 * u_char: flag, blevel
50 * u_short: crc, ib, tmp, tmp2, len
52 * next: 'continue' or 'goto xxx'
56 * NOTE: must setup 'len' and 'dst', so that 'dst' may be written
57 * at most 'len' times.
60 * rdd: read data (read byte is stored in 'tmp2')
65 * NOTE: setting flag to '0' and len to '0' => recover from rdu
66 * NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags
67 * NOTE: these variables have to be 'suspended' / 'resumed' somehow:
68 * flag, blevel, crc, ib, tmp, len
69 * NOTE: zero is default value for all variables.
70 * NOTE: each time 'dst' is written, 'len' is decreased by one.
71 *---------------------------------------------------------------------------*/
73 #define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \
74 cfrcmd, rabcmd, rdocmd, nextcmd, d) \
78 ib += HDLC_BIT_TAB[(u_char)tmp2]; \
80 if ((u_char)ib >= 5) \
82 if (ib & 0x20) /* de-stuff (msb) */ \
84 if ((u_char)tmp2 == 0x7e) goto j0##d; \
85 tmp2 += tmp2 & 0x7f; \
88 if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */ \
93 if ((u_char)ib == 6) /* flag seq (lsb) */ \
95 j0##d: if (flag >= 2) \
97 len += (4 - flag) & 3; /* remove CRC bytes */ \
105 blevel = (ib >> 8) & 0xf; \
106 tmp = ((u_char)tmp2) >> blevel; \
107 blevel = 8 - blevel; \
113 if ((u_char)ib >= 7) /* abort (msb & lsb) */ \
127 if ((u_char)ib == 5) /* de-stuff (lsb) */ \
129 tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1; \
132 if (blevel > 7) /* EO - bits */ \
134 tmp |= (u_char)tmp2 >> (8 - (blevel &= 7)); \
142 tmp |= (u_char)tmp2 << blevel; \
148 if (!flag++) { flag--; goto j5##d;} /* hunt mode */ \
151 { case 2: /* new frame */ \
154 if (!len--) { len++; flag++; goto j4##d; } \
156 case 3: /* CRC (lsb's) */ \
157 case 4: /* CRC (msb's) */ \
167 j3##d: dst = (u_char)tmp; \
168 j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \
174 /*------ end of HDLC_DECODE -------------------------------------------------*/
177 /*---------------------------------------------------------------------------*
182 * u_short: tmp2, blevel, ib, crc, len
185 * gfr: This is the place where you free the last [mbuf] chain, and get
186 * the next one. If a mbuf is available the code should setup 'len'
187 * and 'src' so that 'src' may be read 'len' times. If no mbuf is
188 * available leave 'len' and 'src' untouched.
190 * wrd: write data (output = (u_char)tmp)
194 * NOTE: setting flag to '-2' and len to '0' => abort bytes will be sent
195 * NOTE: these variables have to be 'suspended' / 'resumed' somehow:
196 * flag, blevel, crc, ib, tmp, len
197 * NOTE: zero is default value for all variables.
198 * NOTE: each time 'src' is read, 'len' is decreased by one.
199 * NOTE: neither cmd's should exit through 'goto' or 'break' statements.
200 *---------------------------------------------------------------------------*/
202 #define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, wrdcmd, d) \
204 if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; } \
211 { default: /* abort */ \
212 tmp = blevel = 0; /* zero is default */ \
215 case 1: /* 1st time FS */ \
216 case 2: /* 2nd time FS */ \
220 gfrcmd; /* get new frame */ \
224 flag--; /* don't proceed */ \
226 goto j3##d; /* final FS */ \
232 goto j1##d; /* first byte */ \
236 tmp2 = (u_char)crc; \
237 goto j2##d; /* CRC (lsb's) */ \
239 tmp2 = (u_char)(crc >> 8); \
241 goto j2##d; /* CRC (msb's) */ \
246 tmp2 = (u_char)src; \
247 crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \
251 ib += HDLC_BIT_TAB[(u_char)tmp2]; \
253 if ((u_char)ib >= 5) /* stuffing */ \
257 if (ib & 0xc0) /* bit stuff (msb) */ \
259 tmp2 += tmp2 & (0xff * (ib & 0xc0)); \
266 if ((u_char)ib >= 5) /* bit stuff (lsb) */ \
268 tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1) \
272 if ((u_char)ib >= 10) /* bit stuff (msb) */ \
274 tmp2 += tmp2 & ~0x7ff >> ((ib - \
275 (ib >> 8) + 1) & 7); \
278 if (ib & 0x8000) /* bit walk */ \
280 ib = ((u_char)ib % 5) << 12; \
284 tmp |= tmp2 << (u_char)(blevel >> 8); \
285 blevel += (u_char)blevel << 8; \
287 else /* no stuffing */ \
289 j3##d:tmp |= tmp2 << (u_char)(blevel >> 8); \
296 /*------ end of HDLC_ENCODE -------------------------------------------------*/
299 #endif /* _I4B_HDLC_H_ */