1 /*
2  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
3  *
4  * Copyright (C)
5  *	2009	Karsten Keil		<keil@b1-systems.de>
6  *	2002	Wolfgang Mües		<wolfgang@iksw-muees.de>
7  *	2001	Frode Isaksen		<fisaksen@bewan.com>
8  *      2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/crc-ccitt.h>
28 #include <linux/isdn/hdlc.h>
29 #include <linux/bitrev.h>
30 
31 /*-------------------------------------------------------------------*/
32 
33 MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
34 	      "Frode Isaksen <fisaksen@bewan.com>, "
35 	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
36 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
37 MODULE_LICENSE("GPL");
38 
39 /*-------------------------------------------------------------------*/
40 
41 enum {
42 	HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
43 	HDLC_GET_DATA, HDLC_FAST_FLAG
44 };
45 
46 enum {
47 	HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
48 	HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
49 	HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
50 	HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
51 };
52 
isdnhdlc_rcv_init(struct isdnhdlc_vars * hdlc,u32 features)53 void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
54 {
55 	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
56 	hdlc->state = HDLC_GET_DATA;
57 	if (features & HDLC_56KBIT)
58 		hdlc->do_adapt56 = 1;
59 	if (features & HDLC_BITREVERSE)
60 		hdlc->do_bitreverse = 1;
61 }
62 EXPORT_SYMBOL(isdnhdlc_out_init);
63 
isdnhdlc_out_init(struct isdnhdlc_vars * hdlc,u32 features)64 void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
65 {
66 	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
67 	if (features & HDLC_DCHANNEL) {
68 		hdlc->dchannel = 1;
69 		hdlc->state = HDLC_SEND_FIRST_FLAG;
70 	} else {
71 		hdlc->dchannel = 0;
72 		hdlc->state = HDLC_SEND_FAST_FLAG;
73 		hdlc->ffvalue = 0x7e;
74 	}
75 	hdlc->cbin = 0x7e;
76 	if (features & HDLC_56KBIT) {
77 		hdlc->do_adapt56 = 1;
78 		hdlc->state = HDLC_SENDFLAG_B0;
79 	} else
80 		hdlc->data_bits = 8;
81 	if (features & HDLC_BITREVERSE)
82 		hdlc->do_bitreverse = 1;
83 }
84 EXPORT_SYMBOL(isdnhdlc_rcv_init);
85 
86 static int
check_frame(struct isdnhdlc_vars * hdlc)87 check_frame(struct isdnhdlc_vars *hdlc)
88 {
89 	int status;
90 
91 	if (hdlc->dstpos < 2) 	/* too small - framing error */
92 		status = -HDLC_FRAMING_ERROR;
93 	else if (hdlc->crc != 0xf0b8)	/* crc error */
94 		status = -HDLC_CRC_ERROR;
95 	else {
96 		/* remove CRC */
97 		hdlc->dstpos -= 2;
98 		/* good frame */
99 		status = hdlc->dstpos;
100 	}
101 	return status;
102 }
103 
104 /*
105   isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
106 
107   The source buffer is scanned for valid HDLC frames looking for
108   flags (01111110) to indicate the start of a frame. If the start of
109   the frame is found, the bit stuffing is removed (0 after 5 1's).
110   When a new flag is found, the complete frame has been received
111   and the CRC is checked.
112   If a valid frame is found, the function returns the frame length
113   excluding the CRC with the bit HDLC_END_OF_FRAME set.
114   If the beginning of a valid frame is found, the function returns
115   the length.
116   If a framing error is found (too many 1s and not a flag) the function
117   returns the length with the bit HDLC_FRAMING_ERROR set.
118   If a CRC error is found the function returns the length with the
119   bit HDLC_CRC_ERROR set.
120   If the frame length exceeds the destination buffer size, the function
121   returns the length with the bit HDLC_LENGTH_ERROR set.
122 
123   src - source buffer
124   slen - source buffer length
125   count - number of bytes removed (decoded) from the source buffer
126   dst _ destination buffer
127   dsize - destination buffer size
128   returns - number of decoded bytes in the destination buffer and status
129   flag.
130  */
isdnhdlc_decode(struct isdnhdlc_vars * hdlc,const u8 * src,int slen,int * count,u8 * dst,int dsize)131 int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
132 	int *count, u8 *dst, int dsize)
133 {
134 	int status = 0;
135 
136 	static const unsigned char fast_flag[] = {
137 		0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
138 	};
139 
140 	static const unsigned char fast_flag_value[] = {
141 		0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
142 	};
143 
144 	static const unsigned char fast_abort[] = {
145 		0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
146 	};
147 
148 #define handle_fast_flag(h) \
149 	do {\
150 		if (h->cbin == fast_flag[h->bit_shift]) {\
151 			h->ffvalue = fast_flag_value[h->bit_shift];\
152 			h->state = HDLC_FAST_FLAG;\
153 			h->ffbit_shift = h->bit_shift;\
154 			h->bit_shift = 1;\
155 		} else {\
156 			h->state = HDLC_GET_DATA;\
157 			h->data_received = 0;\
158 		} \
159 	} while (0)
160 
161 #define handle_abort(h) \
162 	do {\
163 		h->shift_reg = fast_abort[h->ffbit_shift - 1];\
164 		h->hdlc_bits1 = h->ffbit_shift - 2;\
165 		if (h->hdlc_bits1 < 0)\
166 			h->hdlc_bits1 = 0;\
167 		h->data_bits = h->ffbit_shift - 1;\
168 		h->state = HDLC_GET_DATA;\
169 		h->data_received = 0;\
170 	} while (0)
171 
172 	*count = slen;
173 
174 	while (slen > 0) {
175 		if (hdlc->bit_shift == 0) {
176 			/* the code is for bitreverse streams */
177 			if (hdlc->do_bitreverse == 0)
178 				hdlc->cbin = bitrev8(*src++);
179 			else
180 				hdlc->cbin = *src++;
181 			slen--;
182 			hdlc->bit_shift = 8;
183 			if (hdlc->do_adapt56)
184 				hdlc->bit_shift--;
185 		}
186 
187 		switch (hdlc->state) {
188 		case STOPPED:
189 			return 0;
190 		case HDLC_FAST_IDLE:
191 			if (hdlc->cbin == 0xff) {
192 				hdlc->bit_shift = 0;
193 				break;
194 			}
195 			hdlc->state = HDLC_GET_FLAG_B0;
196 			hdlc->hdlc_bits1 = 0;
197 			hdlc->bit_shift = 8;
198 			break;
199 		case HDLC_GET_FLAG_B0:
200 			if (!(hdlc->cbin & 0x80)) {
201 				hdlc->state = HDLC_GETFLAG_B1A6;
202 				hdlc->hdlc_bits1 = 0;
203 			} else {
204 				if ((!hdlc->do_adapt56) &&
205 				    (++hdlc->hdlc_bits1 >= 8) &&
206 				    (hdlc->bit_shift == 1))
207 						hdlc->state = HDLC_FAST_IDLE;
208 			}
209 			hdlc->cbin <<= 1;
210 			hdlc->bit_shift--;
211 			break;
212 		case HDLC_GETFLAG_B1A6:
213 			if (hdlc->cbin & 0x80) {
214 				hdlc->hdlc_bits1++;
215 				if (hdlc->hdlc_bits1 == 6)
216 					hdlc->state = HDLC_GETFLAG_B7;
217 			} else
218 				hdlc->hdlc_bits1 = 0;
219 			hdlc->cbin <<= 1;
220 			hdlc->bit_shift--;
221 			break;
222 		case HDLC_GETFLAG_B7:
223 			if (hdlc->cbin & 0x80) {
224 				hdlc->state = HDLC_GET_FLAG_B0;
225 			} else {
226 				hdlc->state = HDLC_GET_DATA;
227 				hdlc->crc = 0xffff;
228 				hdlc->shift_reg = 0;
229 				hdlc->hdlc_bits1 = 0;
230 				hdlc->data_bits = 0;
231 				hdlc->data_received = 0;
232 			}
233 			hdlc->cbin <<= 1;
234 			hdlc->bit_shift--;
235 			break;
236 		case HDLC_GET_DATA:
237 			if (hdlc->cbin & 0x80) {
238 				hdlc->hdlc_bits1++;
239 				switch (hdlc->hdlc_bits1) {
240 				case 6:
241 					break;
242 				case 7:
243 					if (hdlc->data_received)
244 						/* bad frame */
245 						status = -HDLC_FRAMING_ERROR;
246 					if (!hdlc->do_adapt56) {
247 						if (hdlc->cbin == fast_abort
248 						    [hdlc->bit_shift + 1]) {
249 							hdlc->state =
250 								HDLC_FAST_IDLE;
251 							hdlc->bit_shift = 1;
252 							break;
253 						}
254 					} else
255 						hdlc->state = HDLC_GET_FLAG_B0;
256 					break;
257 				default:
258 					hdlc->shift_reg >>= 1;
259 					hdlc->shift_reg |= 0x80;
260 					hdlc->data_bits++;
261 					break;
262 				}
263 			} else {
264 				switch (hdlc->hdlc_bits1) {
265 				case 5:
266 					break;
267 				case 6:
268 					if (hdlc->data_received)
269 						status = check_frame(hdlc);
270 					hdlc->crc = 0xffff;
271 					hdlc->shift_reg = 0;
272 					hdlc->data_bits = 0;
273 					if (!hdlc->do_adapt56)
274 						handle_fast_flag(hdlc);
275 					else {
276 						hdlc->state = HDLC_GET_DATA;
277 						hdlc->data_received = 0;
278 					}
279 					break;
280 				default:
281 					hdlc->shift_reg >>= 1;
282 					hdlc->data_bits++;
283 					break;
284 				}
285 				hdlc->hdlc_bits1 = 0;
286 			}
287 			if (status) {
288 				hdlc->dstpos = 0;
289 				*count -= slen;
290 				hdlc->cbin <<= 1;
291 				hdlc->bit_shift--;
292 				return status;
293 			}
294 			if (hdlc->data_bits == 8) {
295 				hdlc->data_bits = 0;
296 				hdlc->data_received = 1;
297 				hdlc->crc = crc_ccitt_byte(hdlc->crc,
298 						hdlc->shift_reg);
299 
300 				/* good byte received */
301 				if (hdlc->dstpos < dsize)
302 					dst[hdlc->dstpos++] = hdlc->shift_reg;
303 				else {
304 					/* frame too long */
305 					status = -HDLC_LENGTH_ERROR;
306 					hdlc->dstpos = 0;
307 				}
308 			}
309 			hdlc->cbin <<= 1;
310 			hdlc->bit_shift--;
311 			break;
312 		case HDLC_FAST_FLAG:
313 			if (hdlc->cbin == hdlc->ffvalue) {
314 				hdlc->bit_shift = 0;
315 				break;
316 			} else {
317 				if (hdlc->cbin == 0xff) {
318 					hdlc->state = HDLC_FAST_IDLE;
319 					hdlc->bit_shift = 0;
320 				} else if (hdlc->ffbit_shift == 8) {
321 					hdlc->state = HDLC_GETFLAG_B7;
322 					break;
323 				} else
324 					handle_abort(hdlc);
325 			}
326 			break;
327 		default:
328 			break;
329 		}
330 	}
331 	*count -= slen;
332 	return 0;
333 }
334 EXPORT_SYMBOL(isdnhdlc_decode);
335 /*
336   isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
337 
338   The bit stream starts with a beginning flag (01111110). After
339   that each byte is added to the bit stream with bit stuffing added
340   (0 after 5 1's).
341   When the last byte has been removed from the source buffer, the
342   CRC (2 bytes is added) and the frame terminates with the ending flag.
343   For the dchannel, the idle character (all 1's) is also added at the end.
344   If this function is called with empty source buffer (slen=0), flags or
345   idle character will be generated.
346 
347   src - source buffer
348   slen - source buffer length
349   count - number of bytes removed (encoded) from source buffer
350   dst _ destination buffer
351   dsize - destination buffer size
352   returns - number of encoded bytes in the destination buffer
353 */
isdnhdlc_encode(struct isdnhdlc_vars * hdlc,const u8 * src,u16 slen,int * count,u8 * dst,int dsize)354 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
355 	int *count, u8 *dst, int dsize)
356 {
357 	static const unsigned char xfast_flag_value[] = {
358 		0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
359 	};
360 
361 	int len = 0;
362 
363 	*count = slen;
364 
365 	/* special handling for one byte frames */
366 	if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
367 		hdlc->state = HDLC_SENDFLAG_ONE;
368 	while (dsize > 0) {
369 		if (hdlc->bit_shift == 0) {
370 			if (slen && !hdlc->do_closing) {
371 				hdlc->shift_reg = *src++;
372 				slen--;
373 				if (slen == 0)
374 					/* closing sequence, CRC + flag(s) */
375 					hdlc->do_closing = 1;
376 				hdlc->bit_shift = 8;
377 			} else {
378 				if (hdlc->state == HDLC_SEND_DATA) {
379 					if (hdlc->data_received) {
380 						hdlc->state = HDLC_SEND_CRC1;
381 						hdlc->crc ^= 0xffff;
382 						hdlc->bit_shift = 8;
383 						hdlc->shift_reg =
384 							hdlc->crc & 0xff;
385 					} else if (!hdlc->do_adapt56)
386 						hdlc->state =
387 							HDLC_SEND_FAST_FLAG;
388 					else
389 						hdlc->state =
390 							HDLC_SENDFLAG_B0;
391 				}
392 
393 			}
394 		}
395 
396 		switch (hdlc->state) {
397 		case STOPPED:
398 			while (dsize--)
399 				*dst++ = 0xff;
400 			return dsize;
401 		case HDLC_SEND_FAST_FLAG:
402 			hdlc->do_closing = 0;
403 			if (slen == 0) {
404 				/* the code is for bitreverse streams */
405 				if (hdlc->do_bitreverse == 0)
406 					*dst++ = bitrev8(hdlc->ffvalue);
407 				else
408 					*dst++ = hdlc->ffvalue;
409 				len++;
410 				dsize--;
411 				break;
412 			}
413 			/* fall through */
414 		case HDLC_SENDFLAG_ONE:
415 			if (hdlc->bit_shift == 8) {
416 				hdlc->cbin = hdlc->ffvalue >>
417 					(8 - hdlc->data_bits);
418 				hdlc->state = HDLC_SEND_DATA;
419 				hdlc->crc = 0xffff;
420 				hdlc->hdlc_bits1 = 0;
421 				hdlc->data_received = 1;
422 			}
423 			break;
424 		case HDLC_SENDFLAG_B0:
425 			hdlc->do_closing = 0;
426 			hdlc->cbin <<= 1;
427 			hdlc->data_bits++;
428 			hdlc->hdlc_bits1 = 0;
429 			hdlc->state = HDLC_SENDFLAG_B1A6;
430 			break;
431 		case HDLC_SENDFLAG_B1A6:
432 			hdlc->cbin <<= 1;
433 			hdlc->data_bits++;
434 			hdlc->cbin++;
435 			if (++hdlc->hdlc_bits1 == 6)
436 				hdlc->state = HDLC_SENDFLAG_B7;
437 			break;
438 		case HDLC_SENDFLAG_B7:
439 			hdlc->cbin <<= 1;
440 			hdlc->data_bits++;
441 			if (slen == 0) {
442 				hdlc->state = HDLC_SENDFLAG_B0;
443 				break;
444 			}
445 			if (hdlc->bit_shift == 8) {
446 				hdlc->state = HDLC_SEND_DATA;
447 				hdlc->crc = 0xffff;
448 				hdlc->hdlc_bits1 = 0;
449 				hdlc->data_received = 1;
450 			}
451 			break;
452 		case HDLC_SEND_FIRST_FLAG:
453 			hdlc->data_received = 1;
454 			if (hdlc->data_bits == 8) {
455 				hdlc->state = HDLC_SEND_DATA;
456 				hdlc->crc = 0xffff;
457 				hdlc->hdlc_bits1 = 0;
458 				break;
459 			}
460 			hdlc->cbin <<= 1;
461 			hdlc->data_bits++;
462 			if (hdlc->shift_reg & 0x01)
463 				hdlc->cbin++;
464 			hdlc->shift_reg >>= 1;
465 			hdlc->bit_shift--;
466 			if (hdlc->bit_shift == 0) {
467 				hdlc->state = HDLC_SEND_DATA;
468 				hdlc->crc = 0xffff;
469 				hdlc->hdlc_bits1 = 0;
470 			}
471 			break;
472 		case HDLC_SEND_DATA:
473 			hdlc->cbin <<= 1;
474 			hdlc->data_bits++;
475 			if (hdlc->hdlc_bits1 == 5) {
476 				hdlc->hdlc_bits1 = 0;
477 				break;
478 			}
479 			if (hdlc->bit_shift == 8)
480 				hdlc->crc = crc_ccitt_byte(hdlc->crc,
481 					hdlc->shift_reg);
482 			if (hdlc->shift_reg & 0x01) {
483 				hdlc->hdlc_bits1++;
484 				hdlc->cbin++;
485 				hdlc->shift_reg >>= 1;
486 				hdlc->bit_shift--;
487 			} else {
488 				hdlc->hdlc_bits1 = 0;
489 				hdlc->shift_reg >>= 1;
490 				hdlc->bit_shift--;
491 			}
492 			break;
493 		case HDLC_SEND_CRC1:
494 			hdlc->cbin <<= 1;
495 			hdlc->data_bits++;
496 			if (hdlc->hdlc_bits1 == 5) {
497 				hdlc->hdlc_bits1 = 0;
498 				break;
499 			}
500 			if (hdlc->shift_reg & 0x01) {
501 				hdlc->hdlc_bits1++;
502 				hdlc->cbin++;
503 				hdlc->shift_reg >>= 1;
504 				hdlc->bit_shift--;
505 			} else {
506 				hdlc->hdlc_bits1 = 0;
507 				hdlc->shift_reg >>= 1;
508 				hdlc->bit_shift--;
509 			}
510 			if (hdlc->bit_shift == 0) {
511 				hdlc->shift_reg = (hdlc->crc >> 8);
512 				hdlc->state = HDLC_SEND_CRC2;
513 				hdlc->bit_shift = 8;
514 			}
515 			break;
516 		case HDLC_SEND_CRC2:
517 			hdlc->cbin <<= 1;
518 			hdlc->data_bits++;
519 			if (hdlc->hdlc_bits1 == 5) {
520 				hdlc->hdlc_bits1 = 0;
521 				break;
522 			}
523 			if (hdlc->shift_reg & 0x01) {
524 				hdlc->hdlc_bits1++;
525 				hdlc->cbin++;
526 				hdlc->shift_reg >>= 1;
527 				hdlc->bit_shift--;
528 			} else {
529 				hdlc->hdlc_bits1 = 0;
530 				hdlc->shift_reg >>= 1;
531 				hdlc->bit_shift--;
532 			}
533 			if (hdlc->bit_shift == 0) {
534 				hdlc->shift_reg = 0x7e;
535 				hdlc->state = HDLC_SEND_CLOSING_FLAG;
536 				hdlc->bit_shift = 8;
537 			}
538 			break;
539 		case HDLC_SEND_CLOSING_FLAG:
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->cbin++;
548 			hdlc->shift_reg >>= 1;
549 			hdlc->bit_shift--;
550 			if (hdlc->bit_shift == 0) {
551 				hdlc->ffvalue =
552 					xfast_flag_value[hdlc->data_bits];
553 				if (hdlc->dchannel) {
554 					hdlc->ffvalue = 0x7e;
555 					hdlc->state = HDLC_SEND_IDLE1;
556 					hdlc->bit_shift = 8-hdlc->data_bits;
557 					if (hdlc->bit_shift == 0)
558 						hdlc->state =
559 							HDLC_SEND_FAST_IDLE;
560 				} else {
561 					if (!hdlc->do_adapt56) {
562 						hdlc->state =
563 							HDLC_SEND_FAST_FLAG;
564 						hdlc->data_received = 0;
565 					} else {
566 						hdlc->state = HDLC_SENDFLAG_B0;
567 						hdlc->data_received = 0;
568 					}
569 					/* Finished this frame, send flags */
570 					if (dsize > 1)
571 						dsize = 1;
572 				}
573 			}
574 			break;
575 		case HDLC_SEND_IDLE1:
576 			hdlc->do_closing = 0;
577 			hdlc->cbin <<= 1;
578 			hdlc->cbin++;
579 			hdlc->data_bits++;
580 			hdlc->bit_shift--;
581 			if (hdlc->bit_shift == 0) {
582 				hdlc->state = HDLC_SEND_FAST_IDLE;
583 				hdlc->bit_shift = 0;
584 			}
585 			break;
586 		case HDLC_SEND_FAST_IDLE:
587 			hdlc->do_closing = 0;
588 			hdlc->cbin = 0xff;
589 			hdlc->data_bits = 8;
590 			if (hdlc->bit_shift == 8) {
591 				hdlc->cbin = 0x7e;
592 				hdlc->state = HDLC_SEND_FIRST_FLAG;
593 			} else {
594 				/* the code is for bitreverse streams */
595 				if (hdlc->do_bitreverse == 0)
596 					*dst++ = bitrev8(hdlc->cbin);
597 				else
598 					*dst++ = hdlc->cbin;
599 				hdlc->bit_shift = 0;
600 				hdlc->data_bits = 0;
601 				len++;
602 				dsize = 0;
603 			}
604 			break;
605 		default:
606 			break;
607 		}
608 		if (hdlc->do_adapt56) {
609 			if (hdlc->data_bits == 7) {
610 				hdlc->cbin <<= 1;
611 				hdlc->cbin++;
612 				hdlc->data_bits++;
613 			}
614 		}
615 		if (hdlc->data_bits == 8) {
616 			/* the code is for bitreverse streams */
617 			if (hdlc->do_bitreverse == 0)
618 				*dst++ = bitrev8(hdlc->cbin);
619 			else
620 				*dst++ = hdlc->cbin;
621 			hdlc->data_bits = 0;
622 			len++;
623 			dsize--;
624 		}
625 	}
626 	*count -= slen;
627 
628 	return len;
629 }
630 EXPORT_SYMBOL(isdnhdlc_encode);
631