2 * isdnhdlc.c -- General purpose ISDN HDLC decoder.
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>
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.
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.
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.
23 #include <linux/module.h>
24 #include <linux/init.h>
27 /*-------------------------------------------------------------------*/
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");
35 /*-------------------------------------------------------------------*/
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.
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
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
99 HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
100 HDLC_GET_DATA,HDLC_FAST_FLAG
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
110 void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
113 hdlc->hdlc_bits1 = 0;
115 hdlc->ffbit_shift = 0;
116 hdlc->data_received = 0;
117 hdlc->state = HDLC_GET_DATA;
118 hdlc->do_adapt56 = do_adapt56;
127 void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
130 hdlc->hdlc_bits1 = 0;
132 hdlc->ffbit_shift = 0;
133 hdlc->data_received = 0;
134 hdlc->do_closing = 0;
138 hdlc->state = HDLC_SEND_FIRST_FLAG;
141 hdlc->state = HDLC_SEND_FAST_FLAG;
142 hdlc->ffvalue = 0x7e;
147 hdlc->do_adapt56 = 1;
149 hdlc->state = HDLC_SENDFLAG_B0;
151 hdlc->do_adapt56 = 0;
158 isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
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
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.
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
184 int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
185 int slen, int *count, unsigned char *dst, int dsize)
189 static const unsigned char fast_flag[]={
190 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
193 static const unsigned char fast_flag_value[]={
194 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
197 static const unsigned char fast_abort[]={
198 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
204 if(hdlc->bit_shift==0){
208 if(hdlc->do_adapt56){
217 if(hdlc->cbin == 0xff){
221 hdlc->state = HDLC_GET_FLAG_B0;
222 hdlc->hdlc_bits1 = 0;
225 case HDLC_GET_FLAG_B0:
226 if(!(hdlc->cbin & 0x80)) {
227 hdlc->state = HDLC_GETFLAG_B1A6;
228 hdlc->hdlc_bits1 = 0;
230 if(!hdlc->do_adapt56){
231 if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
232 hdlc->state = HDLC_FAST_IDLE;
238 case HDLC_GETFLAG_B1A6:
239 if(hdlc->cbin & 0x80){
241 if(hdlc->hdlc_bits1==6){
242 hdlc->state = HDLC_GETFLAG_B7;
245 hdlc->hdlc_bits1 = 0;
250 case HDLC_GETFLAG_B7:
251 if(hdlc->cbin & 0x80) {
252 hdlc->state = HDLC_GET_FLAG_B0;
254 hdlc->state = HDLC_GET_DATA;
257 hdlc->hdlc_bits1 = 0;
259 hdlc->data_received = 0;
265 if(hdlc->cbin & 0x80){
267 switch(hdlc->hdlc_bits1){
271 if(hdlc->data_received) {
273 status = -HDLC_FRAMING_ERROR;
275 if(!hdlc->do_adapt56){
276 if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
277 hdlc->state = HDLC_FAST_IDLE;
282 hdlc->state = HDLC_GET_FLAG_B0;
287 hdlc->shift_reg |= 0x80;
292 switch(hdlc->hdlc_bits1){
296 if(hdlc->data_received){
297 if (hdlc->dstpos < 2) {
298 status = -HDLC_FRAMING_ERROR;
299 } else if (hdlc->crc != 0xf0b8){
301 status = -HDLC_CRC_ERROR;
306 status = hdlc->dstpos;
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;
319 hdlc->state = HDLC_GET_DATA;
320 hdlc->data_received = 0;
323 hdlc->state = HDLC_GET_DATA;
324 hdlc->data_received = 0;
332 hdlc->hdlc_bits1 = 0;
341 if(hdlc->data_bits==8){
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
350 dst[hdlc->dstpos++] = hdlc->shift_reg;
353 status = -HDLC_LENGTH_ERROR;
361 if(hdlc->cbin==hdlc->ffvalue){
365 if(hdlc->cbin == 0xff){
366 hdlc->state = HDLC_FAST_IDLE;
368 } else if(hdlc->ffbit_shift==8){
369 hdlc->state = HDLC_GETFLAG_B7;
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;
390 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
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
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.
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
408 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
409 unsigned short slen, int *count,
410 unsigned char *dst, int dsize)
412 static const unsigned char xfast_flag_value[] = {
413 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
421 if(hdlc->bit_shift==0){
422 if(slen && !hdlc->do_closing){
423 hdlc->shift_reg = *src++;
426 hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */
429 if(hdlc->state == HDLC_SEND_DATA){
430 if(hdlc->data_received){
431 hdlc->state = HDLC_SEND_CRC1;
434 hdlc->shift_reg = hdlc->crc & 0xff;
435 } else if(!hdlc->do_adapt56){
436 hdlc->state = HDLC_SEND_FAST_FLAG;
438 hdlc->state = HDLC_SENDFLAG_B0;
451 case HDLC_SEND_FAST_FLAG:
452 hdlc->do_closing = 0;
454 *dst++ = hdlc->ffvalue;
459 if(hdlc->bit_shift==8){
460 hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
461 hdlc->state = HDLC_SEND_DATA;
463 hdlc->hdlc_bits1 = 0;
464 hdlc->data_received = 1;
467 case HDLC_SENDFLAG_B0:
468 hdlc->do_closing = 0;
471 hdlc->hdlc_bits1 = 0;
472 hdlc->state = HDLC_SENDFLAG_B1A6;
474 case HDLC_SENDFLAG_B1A6:
478 if(++hdlc->hdlc_bits1 == 6)
479 hdlc->state = HDLC_SENDFLAG_B7;
481 case HDLC_SENDFLAG_B7:
485 hdlc->state = HDLC_SENDFLAG_B0;
488 if(hdlc->bit_shift==8){
489 hdlc->state = HDLC_SEND_DATA;
491 hdlc->hdlc_bits1 = 0;
492 hdlc->data_received = 1;
495 case HDLC_SEND_FIRST_FLAG:
496 hdlc->data_received = 1;
497 if(hdlc->data_bits==8){
498 hdlc->state = HDLC_SEND_DATA;
500 hdlc->hdlc_bits1 = 0;
505 if(hdlc->shift_reg & 0x01)
507 hdlc->shift_reg >>= 1;
509 if(hdlc->bit_shift==0){
510 hdlc->state = HDLC_SEND_DATA;
512 hdlc->hdlc_bits1 = 0;
518 if(hdlc->hdlc_bits1 == 5){
519 hdlc->hdlc_bits1 = 0;
522 if(hdlc->bit_shift==8){
525 cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
526 hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
528 if(hdlc->shift_reg & 0x01){
531 hdlc->shift_reg >>= 1;
534 hdlc->hdlc_bits1 = 0;
535 hdlc->shift_reg >>= 1;
542 if(hdlc->hdlc_bits1 == 5){
543 hdlc->hdlc_bits1 = 0;
546 if(hdlc->shift_reg & 0x01){
549 hdlc->shift_reg >>= 1;
552 hdlc->hdlc_bits1 = 0;
553 hdlc->shift_reg >>= 1;
556 if(hdlc->bit_shift==0){
557 hdlc->shift_reg = (hdlc->crc >> 8);
558 hdlc->state = HDLC_SEND_CRC2;
565 if(hdlc->hdlc_bits1 == 5){
566 hdlc->hdlc_bits1 = 0;
569 if(hdlc->shift_reg & 0x01){
572 hdlc->shift_reg >>= 1;
575 hdlc->hdlc_bits1 = 0;
576 hdlc->shift_reg >>= 1;
579 if(hdlc->bit_shift==0){
580 hdlc->shift_reg = 0x7e;
581 hdlc->state = HDLC_SEND_CLOSING_FLAG;
585 case HDLC_SEND_CLOSING_FLAG:
588 if(hdlc->hdlc_bits1 == 5){
589 hdlc->hdlc_bits1 = 0;
592 if(hdlc->shift_reg & 0x01){
595 hdlc->shift_reg >>= 1;
597 if(hdlc->bit_shift==0){
598 hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
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;
606 if(!hdlc->do_adapt56){
607 hdlc->state = HDLC_SEND_FAST_FLAG;
608 hdlc->data_received = 0;
610 hdlc->state = HDLC_SENDFLAG_B0;
611 hdlc->data_received = 0;
613 // Finished with this frame, send flags
614 if (dsize > 1) dsize = 1;
618 case HDLC_SEND_IDLE1:
619 hdlc->do_closing = 0;
624 if(hdlc->bit_shift==0){
625 hdlc->state = HDLC_SEND_FAST_IDLE;
629 case HDLC_SEND_FAST_IDLE:
630 hdlc->do_closing = 0;
633 if(hdlc->bit_shift == 8){
635 hdlc->state = HDLC_SEND_FIRST_FLAG;
638 hdlc->bit_shift = hdlc->data_bits = 0;
646 if(hdlc->do_adapt56){
647 if(hdlc->data_bits==7){
653 if(hdlc->data_bits==8){
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);