1 /*
2  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
3  *
4  *Copyright (C) 2002	Wolfgang M�es      <wolfgang@iksw-muees.de>
5  *		2001 	Frode Isaksen      <fisaksen@bewan.com>
6  *              2001 	Kai Germaschewski  <kai.germaschewski@gmx.de>
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License as published by
10  *      the Free Software Foundation; either version 2 of the License, or
11  *      (at your option) any later version.
12  *
13  *      This program is distributed in the hope that it will be useful,
14  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *      GNU General Public License for more details.
17  *
18  *      You should have received a copy of the GNU General Public License
19  *      along with this program; if not, write to the Free Software
20  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include "isdnhdlc.h"
26 
27 /*-------------------------------------------------------------------*/
28 
29 MODULE_AUTHOR("Wolfgang M�es <wolfgang@iksw-muees.de>, "
30 	      "Frode Isaksen <fisaksen@bewan.com>, "
31 	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
32 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
33 MODULE_LICENSE("GPL");
34 
35 /*-------------------------------------------------------------------*/
36 
37 /* bit swap table.
38  * Very handy for devices with different bit order,
39  * and neccessary for each transparent B-channel access for all
40  * devices which works with this HDLC decoder without bit reversal.
41  */
42 const unsigned char isdnhdlc_bit_rev_tab[256] = {
43 	0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
44 	0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
45 	0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
46 	0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
47 	0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
48 	0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
49 	0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
50 	0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
51 	0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
52 	0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
53 	0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
54 	0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
55 	0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
56 	0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
57 	0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
58 	0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
59 };
60 
61 /* Table for CRC16. Internal used only. */
62 static const unsigned short int crc16_tab[] = {
63 	0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
64 	0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
65 	0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
66 	0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
67 	0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
68 	0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
69 	0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
70 	0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
71 	0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
72 	0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
73 	0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
74 	0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
75 	0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
76 	0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
77 	0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
78 	0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
79 	0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
80 	0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
81 	0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
82 	0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
83 	0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
84 	0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
85 	0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
86 	0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
87 	0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
88 	0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
89 	0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
90 	0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
91 	0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
92 	0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
93 	0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
94 	0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
95 };
96 
97 
98 enum {
99 	HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
100 	HDLC_GET_DATA,HDLC_FAST_FLAG
101 };
102 
103 enum {
104 	HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
105 	HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
106 	HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
107 	HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
108 };
109 
isdnhdlc_rcv_init(struct isdnhdlc_vars * hdlc,int do_adapt56)110 void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
111 {
112    	hdlc->bit_shift = 0;
113 	hdlc->hdlc_bits1 = 0;
114 	hdlc->data_bits = 0;
115 	hdlc->ffbit_shift = 0;
116 	hdlc->data_received = 0;
117 	hdlc->state = HDLC_GET_DATA;
118 	hdlc->do_adapt56 = do_adapt56;
119 	hdlc->dchannel = 0;
120 	hdlc->crc = 0;
121 	hdlc->cbin = 0;
122 	hdlc->shift_reg = 0;
123 	hdlc->ffvalue = 0;
124 	hdlc->dstpos = 0;
125 }
126 
isdnhdlc_out_init(struct isdnhdlc_vars * hdlc,int is_d_channel,int do_adapt56)127 void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
128 {
129    	hdlc->bit_shift = 0;
130 	hdlc->hdlc_bits1 = 0;
131 	hdlc->data_bits = 0;
132 	hdlc->ffbit_shift = 0;
133 	hdlc->data_received = 0;
134 	hdlc->do_closing = 0;
135 	hdlc->ffvalue = 0;
136 	if (is_d_channel) {
137 		hdlc->dchannel = 1;
138 		hdlc->state = HDLC_SEND_FIRST_FLAG;
139 	} else {
140 		hdlc->dchannel = 0;
141 		hdlc->state = HDLC_SEND_FAST_FLAG;
142 		hdlc->ffvalue = 0x7e;
143 	}
144 	hdlc->cbin = 0x7e;
145 	hdlc->bit_shift = 0;
146 	if(do_adapt56){
147 		hdlc->do_adapt56 = 1;
148 		hdlc->data_bits = 0;
149 		hdlc->state = HDLC_SENDFLAG_B0;
150 	} else {
151 		hdlc->do_adapt56 = 0;
152 		hdlc->data_bits = 8;
153 	}
154 	hdlc->shift_reg = 0;
155 }
156 
157 /*
158   isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
159 
160   The source buffer is scanned for valid HDLC frames looking for
161   flags (01111110) to indicate the start of a frame. If the start of
162   the frame is found, the bit stuffing is removed (0 after 5 1's).
163   When a new flag is found, the complete frame has been received
164   and the CRC is checked.
165   If a valid frame is found, the function returns the frame length
166   excluding the CRC with the bit HDLC_END_OF_FRAME set.
167   If the beginning of a valid frame is found, the function returns
168   the length.
169   If a framing error is found (too many 1s and not a flag) the function
170   returns the length with the bit HDLC_FRAMING_ERROR set.
171   If a CRC error is found the function returns the length with the
172   bit HDLC_CRC_ERROR set.
173   If the frame length exceeds the destination buffer size, the function
174   returns the length with the bit HDLC_LENGTH_ERROR set.
175 
176   src - source buffer
177   slen - source buffer length
178   count - number of bytes removed (decoded) from the source buffer
179   dst _ destination buffer
180   dsize - destination buffer size
181   returns - number of decoded bytes in the destination buffer and status
182   flag.
183  */
isdnhdlc_decode(struct isdnhdlc_vars * hdlc,const unsigned char * src,int slen,int * count,unsigned char * dst,int dsize)184 int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
185 		     int slen, int *count, unsigned char *dst, int dsize)
186 {
187 	int status=0;
188 
189 	static const unsigned char fast_flag[]={
190 		0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
191 	};
192 
193 	static const unsigned char fast_flag_value[]={
194 		0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
195 	};
196 
197 	static const unsigned char fast_abort[]={
198 		0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
199 	};
200 
201 	*count = slen;
202 
203 	while(slen > 0){
204 		if(hdlc->bit_shift==0){
205 			hdlc->cbin = *src++;
206 			slen--;
207 			hdlc->bit_shift = 8;
208 			if(hdlc->do_adapt56){
209 				hdlc->bit_shift --;
210 			}
211 		}
212 
213 		switch(hdlc->state){
214 		case STOPPED:
215 			return 0;
216 		case HDLC_FAST_IDLE:
217 			if(hdlc->cbin == 0xff){
218 				hdlc->bit_shift = 0;
219 				break;
220 			}
221 			hdlc->state = HDLC_GET_FLAG_B0;
222 			hdlc->hdlc_bits1 = 0;
223 			hdlc->bit_shift = 8;
224 			break;
225 		case HDLC_GET_FLAG_B0:
226 			if(!(hdlc->cbin & 0x80)) {
227 				hdlc->state = HDLC_GETFLAG_B1A6;
228 				hdlc->hdlc_bits1 = 0;
229 			} else {
230 				if(!hdlc->do_adapt56){
231 					if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
232 						hdlc->state = HDLC_FAST_IDLE;
233 				}
234 			}
235 			hdlc->cbin<<=1;
236 			hdlc->bit_shift --;
237 			break;
238 		case HDLC_GETFLAG_B1A6:
239 			if(hdlc->cbin & 0x80){
240 				hdlc->hdlc_bits1++;
241 				if(hdlc->hdlc_bits1==6){
242 					hdlc->state = HDLC_GETFLAG_B7;
243 				}
244 			} else {
245 				hdlc->hdlc_bits1 = 0;
246 			}
247 			hdlc->cbin<<=1;
248 			hdlc->bit_shift --;
249 			break;
250 		case HDLC_GETFLAG_B7:
251 			if(hdlc->cbin & 0x80) {
252 				hdlc->state = HDLC_GET_FLAG_B0;
253 			} else {
254 				hdlc->state = HDLC_GET_DATA;
255 				hdlc->crc = 0xffff;
256 				hdlc->shift_reg = 0;
257 				hdlc->hdlc_bits1 = 0;
258 				hdlc->data_bits = 0;
259 				hdlc->data_received = 0;
260 			}
261 			hdlc->cbin<<=1;
262 			hdlc->bit_shift --;
263 			break;
264 		case HDLC_GET_DATA:
265 			if(hdlc->cbin & 0x80){
266 				hdlc->hdlc_bits1++;
267 				switch(hdlc->hdlc_bits1){
268 				case 6:
269 					break;
270 				case 7:
271 					if(hdlc->data_received) {
272 						// bad frame
273 						status = -HDLC_FRAMING_ERROR;
274 					}
275 					if(!hdlc->do_adapt56){
276 						if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
277 							hdlc->state = HDLC_FAST_IDLE;
278 							hdlc->bit_shift=1;
279 							break;
280 						}
281 					} else {
282 						hdlc->state = HDLC_GET_FLAG_B0;
283 					}
284 					break;
285 				default:
286 					hdlc->shift_reg>>=1;
287 					hdlc->shift_reg |= 0x80;
288 					hdlc->data_bits++;
289 					break;
290 				}
291 			} else {
292 				switch(hdlc->hdlc_bits1){
293 				case 5:
294 					break;
295 				case 6:
296 					if(hdlc->data_received){
297 						if (hdlc->dstpos < 2) {
298 							status = -HDLC_FRAMING_ERROR;
299 						} else if (hdlc->crc != 0xf0b8){
300 							// crc error
301 							status = -HDLC_CRC_ERROR;
302 						} else {
303 							// remove CRC
304 							hdlc->dstpos -= 2;
305 							// good frame
306 							status = hdlc->dstpos;
307 						}
308 					}
309 					hdlc->crc = 0xffff;
310 					hdlc->shift_reg = 0;
311 					hdlc->data_bits = 0;
312 					if(!hdlc->do_adapt56){
313 						if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
314 							hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
315 							hdlc->state = HDLC_FAST_FLAG;
316 							hdlc->ffbit_shift = hdlc->bit_shift;
317 							hdlc->bit_shift = 1;
318 						} else {
319 							hdlc->state = HDLC_GET_DATA;
320 							hdlc->data_received = 0;
321 						}
322 					} else {
323 						hdlc->state = HDLC_GET_DATA;
324 						hdlc->data_received = 0;
325 					}
326 					break;
327 				default:
328 					hdlc->shift_reg>>=1;
329 					hdlc->data_bits++;
330 					break;
331 				}
332 				hdlc->hdlc_bits1 = 0;
333 			}
334 			if (status) {
335 				hdlc->dstpos = 0;
336 				*count -= slen;
337 				hdlc->cbin <<= 1;
338 				hdlc->bit_shift--;
339 				return status;
340 			}
341 			if(hdlc->data_bits==8){
342 				unsigned cval;
343 
344 				hdlc->data_bits = 0;
345 				hdlc->data_received = 1;
346 				cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
347 				hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
348 				// good byte received
349 				if (dsize--) {
350 					dst[hdlc->dstpos++] = hdlc->shift_reg;
351 				} else {
352 					// frame too long
353 					status = -HDLC_LENGTH_ERROR;
354 					hdlc->dstpos = 0;
355 				}
356 			}
357 			hdlc->cbin <<= 1;
358 			hdlc->bit_shift--;
359 			break;
360 		case HDLC_FAST_FLAG:
361 			if(hdlc->cbin==hdlc->ffvalue){
362 				hdlc->bit_shift = 0;
363 				break;
364 			} else {
365 				if(hdlc->cbin == 0xff){
366 					hdlc->state = HDLC_FAST_IDLE;
367 					hdlc->bit_shift=0;
368 				} else if(hdlc->ffbit_shift==8){
369 					hdlc->state = HDLC_GETFLAG_B7;
370 					break;
371 				} else {
372 					hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
373 					hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
374 					if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
375 					hdlc->data_bits = hdlc->ffbit_shift-1;
376 					hdlc->state = HDLC_GET_DATA;
377 					hdlc->data_received = 0;
378 				}
379 			}
380 			break;
381 		default:
382 			break;
383 		}
384 	}
385 	*count -= slen;
386 	return 0;
387 }
388 
389 /*
390   isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
391 
392   The bit stream starts with a beginning flag (01111110). After
393   that each byte is added to the bit stream with bit stuffing added
394   (0 after 5 1's).
395   When the last byte has been removed from the source buffer, the
396   CRC (2 bytes is added) and the frame terminates with the ending flag.
397   For the dchannel, the idle character (all 1's) is also added at the end.
398   If this function is called with empty source buffer (slen=0), flags or
399   idle character will be generated.
400 
401   src - source buffer
402   slen - source buffer length
403   count - number of bytes removed (encoded) from source buffer
404   dst _ destination buffer
405   dsize - destination buffer size
406   returns - number of encoded bytes in the destination buffer
407 */
isdnhdlc_encode(struct isdnhdlc_vars * hdlc,const unsigned char * src,unsigned short slen,int * count,unsigned char * dst,int dsize)408 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
409 		unsigned short slen, int *count,
410 		unsigned char *dst, int dsize)
411 {
412 	static const unsigned char xfast_flag_value[] = {
413 		0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
414 	};
415 
416 	int len = 0;
417 
418 	*count = slen;
419 
420 	while (dsize > 0) {
421 		if(hdlc->bit_shift==0){
422 			if(slen && !hdlc->do_closing){
423 				hdlc->shift_reg = *src++;
424 				slen--;
425 				if (slen == 0)
426 					hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
427 				hdlc->bit_shift = 8;
428 			} else {
429 				if(hdlc->state == HDLC_SEND_DATA){
430 					if(hdlc->data_received){
431 						hdlc->state = HDLC_SEND_CRC1;
432 						hdlc->crc ^= 0xffff;
433 						hdlc->bit_shift = 8;
434 						hdlc->shift_reg = hdlc->crc & 0xff;
435 					} else if(!hdlc->do_adapt56){
436 						hdlc->state = HDLC_SEND_FAST_FLAG;
437 					} else {
438 						hdlc->state = HDLC_SENDFLAG_B0;
439 					}
440 				}
441 
442 			}
443 		}
444 
445 		switch(hdlc->state){
446 		case STOPPED:
447 			while (dsize--)
448 				*dst++ = 0xff;
449 
450 			return dsize;
451 		case HDLC_SEND_FAST_FLAG:
452 			hdlc->do_closing = 0;
453 			if(slen == 0){
454 				*dst++ = hdlc->ffvalue;
455 				len++;
456 				dsize--;
457 				break;
458 			}
459 			if(hdlc->bit_shift==8){
460 				hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
461 				hdlc->state = HDLC_SEND_DATA;
462 				hdlc->crc = 0xffff;
463 				hdlc->hdlc_bits1 = 0;
464 				hdlc->data_received = 1;
465 			}
466 			break;
467 		case HDLC_SENDFLAG_B0:
468 			hdlc->do_closing = 0;
469 			hdlc->cbin <<= 1;
470 			hdlc->data_bits++;
471 			hdlc->hdlc_bits1 = 0;
472 			hdlc->state = HDLC_SENDFLAG_B1A6;
473 			break;
474 		case HDLC_SENDFLAG_B1A6:
475 			hdlc->cbin <<= 1;
476 			hdlc->data_bits++;
477 			hdlc->cbin++;
478 			if(++hdlc->hdlc_bits1 == 6)
479 				hdlc->state = HDLC_SENDFLAG_B7;
480 			break;
481 		case HDLC_SENDFLAG_B7:
482 			hdlc->cbin <<= 1;
483 			hdlc->data_bits++;
484 			if(slen == 0){
485 				hdlc->state = HDLC_SENDFLAG_B0;
486 				break;
487 			}
488 			if(hdlc->bit_shift==8){
489 				hdlc->state = HDLC_SEND_DATA;
490 				hdlc->crc = 0xffff;
491 				hdlc->hdlc_bits1 = 0;
492 				hdlc->data_received = 1;
493 			}
494 			break;
495 		case HDLC_SEND_FIRST_FLAG:
496 			hdlc->data_received = 1;
497 			if(hdlc->data_bits==8){
498 				hdlc->state = HDLC_SEND_DATA;
499 				hdlc->crc = 0xffff;
500 				hdlc->hdlc_bits1 = 0;
501 				break;
502 			}
503 			hdlc->cbin <<= 1;
504 			hdlc->data_bits++;
505 			if(hdlc->shift_reg & 0x01)
506 				hdlc->cbin++;
507 			hdlc->shift_reg >>= 1;
508 			hdlc->bit_shift--;
509 			if(hdlc->bit_shift==0){
510 				hdlc->state = HDLC_SEND_DATA;
511 				hdlc->crc = 0xffff;
512 				hdlc->hdlc_bits1 = 0;
513 			}
514 			break;
515 		case HDLC_SEND_DATA:
516 			hdlc->cbin <<= 1;
517 			hdlc->data_bits++;
518 			if(hdlc->hdlc_bits1 == 5){
519 				hdlc->hdlc_bits1 = 0;
520 				break;
521 			}
522 			if(hdlc->bit_shift==8){
523 				unsigned cval;
524 
525 				cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
526 				hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
527 			}
528 			if(hdlc->shift_reg & 0x01){
529 				hdlc->hdlc_bits1++;
530 				hdlc->cbin++;
531 				hdlc->shift_reg >>= 1;
532 				hdlc->bit_shift--;
533 			} else {
534 				hdlc->hdlc_bits1 = 0;
535 				hdlc->shift_reg >>= 1;
536 				hdlc->bit_shift--;
537 			}
538 			break;
539 		case HDLC_SEND_CRC1:
540 			hdlc->cbin <<= 1;
541 			hdlc->data_bits++;
542 			if(hdlc->hdlc_bits1 == 5){
543 				hdlc->hdlc_bits1 = 0;
544 				break;
545 			}
546 			if(hdlc->shift_reg & 0x01){
547 				hdlc->hdlc_bits1++;
548 				hdlc->cbin++;
549 				hdlc->shift_reg >>= 1;
550 				hdlc->bit_shift--;
551 			} else {
552 				hdlc->hdlc_bits1 = 0;
553 				hdlc->shift_reg >>= 1;
554 				hdlc->bit_shift--;
555 			}
556 			if(hdlc->bit_shift==0){
557 				hdlc->shift_reg = (hdlc->crc >> 8);
558 				hdlc->state = HDLC_SEND_CRC2;
559 				hdlc->bit_shift = 8;
560 			}
561 			break;
562 		case HDLC_SEND_CRC2:
563 			hdlc->cbin <<= 1;
564 			hdlc->data_bits++;
565 			if(hdlc->hdlc_bits1 == 5){
566 				hdlc->hdlc_bits1 = 0;
567 				break;
568 			}
569 			if(hdlc->shift_reg & 0x01){
570 				hdlc->hdlc_bits1++;
571 				hdlc->cbin++;
572 				hdlc->shift_reg >>= 1;
573 				hdlc->bit_shift--;
574 			} else {
575 				hdlc->hdlc_bits1 = 0;
576 				hdlc->shift_reg >>= 1;
577 				hdlc->bit_shift--;
578 			}
579 			if(hdlc->bit_shift==0){
580 				hdlc->shift_reg = 0x7e;
581 				hdlc->state = HDLC_SEND_CLOSING_FLAG;
582 				hdlc->bit_shift = 8;
583 			}
584 			break;
585 		case HDLC_SEND_CLOSING_FLAG:
586 			hdlc->cbin <<= 1;
587 			hdlc->data_bits++;
588 			if(hdlc->hdlc_bits1 == 5){
589 				hdlc->hdlc_bits1 = 0;
590 				break;
591 			}
592 			if(hdlc->shift_reg & 0x01){
593 				hdlc->cbin++;
594 			}
595 			hdlc->shift_reg >>= 1;
596 			hdlc->bit_shift--;
597 			if(hdlc->bit_shift==0){
598 				hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
599 				if(hdlc->dchannel){
600 					hdlc->ffvalue = 0x7e;
601 					hdlc->state = HDLC_SEND_IDLE1;
602 					hdlc->bit_shift = 8-hdlc->data_bits;
603 					if(hdlc->bit_shift==0)
604 						hdlc->state = HDLC_SEND_FAST_IDLE;
605 				} else {
606 					if(!hdlc->do_adapt56){
607 						hdlc->state = HDLC_SEND_FAST_FLAG;
608 						hdlc->data_received = 0;
609 					} else {
610 						hdlc->state = HDLC_SENDFLAG_B0;
611 						hdlc->data_received = 0;
612 					}
613 					// Finished with this frame, send flags
614 					if (dsize > 1) dsize = 1;
615 				}
616 			}
617 			break;
618 		case HDLC_SEND_IDLE1:
619 			hdlc->do_closing = 0;
620 			hdlc->cbin <<= 1;
621 			hdlc->cbin++;
622 			hdlc->data_bits++;
623 			hdlc->bit_shift--;
624 			if(hdlc->bit_shift==0){
625 				hdlc->state = HDLC_SEND_FAST_IDLE;
626 				hdlc->bit_shift = 0;
627 			}
628 			break;
629 		case HDLC_SEND_FAST_IDLE:
630 			hdlc->do_closing = 0;
631 			hdlc->cbin = 0xff;
632 			hdlc->data_bits = 8;
633 			if(hdlc->bit_shift == 8){
634 				hdlc->cbin = 0x7e;
635 				hdlc->state = HDLC_SEND_FIRST_FLAG;
636 			} else {
637 				*dst++ = hdlc->cbin;
638 				hdlc->bit_shift = hdlc->data_bits = 0;
639 				len++;
640 				dsize = 0;
641 			}
642 			break;
643 		default:
644 			break;
645 		}
646 		if(hdlc->do_adapt56){
647 			if(hdlc->data_bits==7){
648 				hdlc->cbin <<= 1;
649 				hdlc->cbin++;
650 				hdlc->data_bits++;
651 			}
652 		}
653 		if(hdlc->data_bits==8){
654 			*dst++ = hdlc->cbin;
655 			hdlc->data_bits = 0;
656 			len++;
657 			dsize--;
658 		}
659 	}
660 	*count -= slen;
661 
662 	return len;
663 }
664 
665 EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);
666 EXPORT_SYMBOL(isdnhdlc_rcv_init);
667 EXPORT_SYMBOL(isdnhdlc_decode);
668 EXPORT_SYMBOL(isdnhdlc_out_init);
669 EXPORT_SYMBOL(isdnhdlc_encode);
670