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: [Thu Jan 11 11:31:01 2001]
37 * Please conform "ihfc/i4b_ihfc_drv.c" (ihfc_hdlc_Bxxxx)
38 * for correct usage! (-hp)
40 *---------------------------------------------------------------------------*/
45 extern const u_short HDLC_FCS_TAB[256];
46 extern const u_short HDLC_BIT_TAB[256];
48 /*---------------------------------------------------------------------------*
52 * u_char: flag, blevel
53 * u_short: crc, ib, tmp, tmp2, len
55 * next: 'continue' or 'goto xxx'
59 * NOTE: must setup 'len' and 'dst', so that 'dst' may be written
60 * at most 'len' times.
63 * rdd: read data (read byte is stored in 'tmp2')
68 * NOTE: setting flag to '0' and len to '0' => recover from rdu
69 * NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags
70 * NOTE: these variables have to be 'suspended' / 'resumed' somehow:
71 * flag, blevel, crc, ib, tmp, len
72 * NOTE: zero is default value for all variables.
73 * NOTE: each time 'dst' is written, 'len' is decreased by one.
74 *---------------------------------------------------------------------------*/
76 #define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \
77 cfrcmd, rabcmd, rdocmd, nextcmd, d) \
81 ib += HDLC_BIT_TAB[(u_char)tmp2]; \
83 if ((u_char)ib >= 5) \
85 if (ib & 0x20) /* de-stuff (msb) */ \
87 if ((u_char)tmp2 == 0x7e) goto j0##d; \
88 tmp2 += tmp2 & 0x7f; \
91 if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */ \
96 if ((u_char)ib == 6) /* flag seq (lsb) */ \
98 j0##d: if (flag >= 2) \
100 len += (4 - flag) & 3; /* remove CRC bytes */ \
108 blevel = (ib >> 8) & 0xf; \
109 tmp = ((u_char)tmp2) >> blevel; \
110 blevel = 8 - blevel; \
116 if ((u_char)ib >= 7) /* abort (msb & lsb) */ \
130 if ((u_char)ib == 5) /* de-stuff (lsb) */ \
132 tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1; \
135 if (blevel > 7) /* EO - bits */ \
137 tmp |= (u_char)tmp2 >> (8 - (blevel &= 7)); \
145 tmp |= (u_char)tmp2 << blevel; \
151 if (!flag++) { flag--; goto j5##d;} /* hunt mode */ \
154 { case 2: /* new frame */ \
157 if (!len--) { len++; flag++; goto j4##d; } \
159 case 3: /* CRC (lsb's) */ \
160 case 4: /* CRC (msb's) */ \
170 j3##d: dst = (u_char)tmp; \
171 j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \
177 /*------ end of HDLC_DECODE -------------------------------------------------*/
180 /*---------------------------------------------------------------------------*
185 * u_short: tmp2, blevel, ib, crc, len
188 * gfr: This is the place where you free the last [mbuf] chain, and get
189 * the next one. If a mbuf is available the code should setup 'len'
190 * and 'src' so that 'src' may be read 'len' times. If no mbuf is
191 * available leave 'len' and 'src' untouched.
193 * nmb: If your implementation accept/use chained mbufs, this is the
194 * place where you update 'len' and 'src' to the next mbuf of
195 * the chain that makes up a frame. If no further mbuf is
196 * available leave 'len' and 'src' untouched. This is not the
197 * place where you free the mbuf. Leave the block empty if your
198 * implementation does not accept/use chained mbufs.
200 * wrd: write data (output = (u_char)tmp)
204 * NOTE: setting flag to '-2' and len to '0' => abort bytes will be sent
205 * NOTE: these variables have to be 'suspended' / 'resumed' somehow:
206 * flag, blevel, crc, ib, tmp, len
207 * NOTE: zero is default value for all variables.
208 * NOTE: each time 'src' is read, 'len' is decreased by one.
209 * NOTE: neither cmd's should exit through 'goto' or 'break' statements.
210 *---------------------------------------------------------------------------*/
212 #define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, nmbcmd, wrdcmd, d) \
214 if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; } \
221 { default: /* abort */ \
222 tmp = blevel = 0; /* zero is default */ \
225 case 1: /* 1st time FS */ \
226 case 2: /* 2nd time FS */ \
230 gfrcmd; /* get new frame */ \
234 flag--; /* don't proceed */ \
236 goto j3##d; /* final FS */ \
242 goto j1##d; /* first byte */ \
245 nmbcmd; /* get next mbuf in chain */ \
250 tmp2 = (u_char)crc; \
251 goto j2##d; /* CRC (lsb's) */ \
256 goto j1##d; /* proceed with the frame */ \
259 tmp2 = (u_char)(crc >> 8); \
261 goto j2##d; /* CRC (msb's) */ \
266 tmp2 = (u_char)src; \
267 crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \
271 ib += HDLC_BIT_TAB[(u_char)tmp2]; \
273 if ((u_char)ib >= 5) /* stuffing */ \
277 if (ib & 0xc0) /* bit stuff (msb) */ \
279 tmp2 += tmp2 & (0xff * (ib & 0xc0)); \
286 if ((u_char)ib >= 5) /* bit stuff (lsb) */ \
288 tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1) \
292 if ((u_char)ib >= 10) /* bit stuff (msb) */ \
294 tmp2 += tmp2 & ~0x7ff >> ((ib - \
295 (ib >> 8) + 1) & 7); \
298 if (ib & 0x8000) /* bit walk */ \
300 ib = ((u_char)ib % 5) << 12; \
304 tmp |= tmp2 << (u_char)(blevel >> 8); \
305 blevel += (u_char)blevel << 8; \
307 else /* no stuffing */ \
309 j3##d:tmp |= tmp2 << (u_char)(blevel >> 8); \
316 /*------ end of HDLC_ENCODE -------------------------------------------------*/
319 #endif /* _I4B_HDLC_H_ */