[TG3]: Add tagged status support.
[linux-2.6/verdex.git] / drivers / isdn / hisax / isdnhdlc.c
blobcbdf54c5af84521f7925565513452e5caed81523
1 /*
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>
25 #include <linux/crc-ccitt.h>
26 #include "isdnhdlc.h"
28 /*-------------------------------------------------------------------*/
30 MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
31 "Frode Isaksen <fisaksen@bewan.com>, "
32 "Kai Germaschewski <kai.germaschewski@gmx.de>");
33 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
34 MODULE_LICENSE("GPL");
36 /*-------------------------------------------------------------------*/
38 /* bit swap table.
39 * Very handy for devices with different bit order,
40 * and neccessary for each transparent B-channel access for all
41 * devices which works with this HDLC decoder without bit reversal.
43 const unsigned char isdnhdlc_bit_rev_tab[256] = {
44 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
45 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
46 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
47 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
48 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
49 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
50 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
51 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
52 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
53 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
54 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
55 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
56 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
57 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
58 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
59 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
62 enum {
63 HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
64 HDLC_GET_DATA,HDLC_FAST_FLAG
67 enum {
68 HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
69 HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
70 HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
71 HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
74 void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
76 hdlc->bit_shift = 0;
77 hdlc->hdlc_bits1 = 0;
78 hdlc->data_bits = 0;
79 hdlc->ffbit_shift = 0;
80 hdlc->data_received = 0;
81 hdlc->state = HDLC_GET_DATA;
82 hdlc->do_adapt56 = do_adapt56;
83 hdlc->dchannel = 0;
84 hdlc->crc = 0;
85 hdlc->cbin = 0;
86 hdlc->shift_reg = 0;
87 hdlc->ffvalue = 0;
88 hdlc->dstpos = 0;
91 void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
93 hdlc->bit_shift = 0;
94 hdlc->hdlc_bits1 = 0;
95 hdlc->data_bits = 0;
96 hdlc->ffbit_shift = 0;
97 hdlc->data_received = 0;
98 hdlc->do_closing = 0;
99 hdlc->ffvalue = 0;
100 if (is_d_channel) {
101 hdlc->dchannel = 1;
102 hdlc->state = HDLC_SEND_FIRST_FLAG;
103 } else {
104 hdlc->dchannel = 0;
105 hdlc->state = HDLC_SEND_FAST_FLAG;
106 hdlc->ffvalue = 0x7e;
108 hdlc->cbin = 0x7e;
109 hdlc->bit_shift = 0;
110 if(do_adapt56){
111 hdlc->do_adapt56 = 1;
112 hdlc->data_bits = 0;
113 hdlc->state = HDLC_SENDFLAG_B0;
114 } else {
115 hdlc->do_adapt56 = 0;
116 hdlc->data_bits = 8;
118 hdlc->shift_reg = 0;
122 isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
124 The source buffer is scanned for valid HDLC frames looking for
125 flags (01111110) to indicate the start of a frame. If the start of
126 the frame is found, the bit stuffing is removed (0 after 5 1's).
127 When a new flag is found, the complete frame has been received
128 and the CRC is checked.
129 If a valid frame is found, the function returns the frame length
130 excluding the CRC with the bit HDLC_END_OF_FRAME set.
131 If the beginning of a valid frame is found, the function returns
132 the length.
133 If a framing error is found (too many 1s and not a flag) the function
134 returns the length with the bit HDLC_FRAMING_ERROR set.
135 If a CRC error is found the function returns the length with the
136 bit HDLC_CRC_ERROR set.
137 If the frame length exceeds the destination buffer size, the function
138 returns the length with the bit HDLC_LENGTH_ERROR set.
140 src - source buffer
141 slen - source buffer length
142 count - number of bytes removed (decoded) from the source buffer
143 dst _ destination buffer
144 dsize - destination buffer size
145 returns - number of decoded bytes in the destination buffer and status
146 flag.
148 int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
149 int slen, int *count, unsigned char *dst, int dsize)
151 int status=0;
153 static const unsigned char fast_flag[]={
154 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
157 static const unsigned char fast_flag_value[]={
158 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
161 static const unsigned char fast_abort[]={
162 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
165 *count = slen;
167 while(slen > 0){
168 if(hdlc->bit_shift==0){
169 hdlc->cbin = *src++;
170 slen--;
171 hdlc->bit_shift = 8;
172 if(hdlc->do_adapt56){
173 hdlc->bit_shift --;
177 switch(hdlc->state){
178 case STOPPED:
179 return 0;
180 case HDLC_FAST_IDLE:
181 if(hdlc->cbin == 0xff){
182 hdlc->bit_shift = 0;
183 break;
185 hdlc->state = HDLC_GET_FLAG_B0;
186 hdlc->hdlc_bits1 = 0;
187 hdlc->bit_shift = 8;
188 break;
189 case HDLC_GET_FLAG_B0:
190 if(!(hdlc->cbin & 0x80)) {
191 hdlc->state = HDLC_GETFLAG_B1A6;
192 hdlc->hdlc_bits1 = 0;
193 } else {
194 if(!hdlc->do_adapt56){
195 if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
196 hdlc->state = HDLC_FAST_IDLE;
199 hdlc->cbin<<=1;
200 hdlc->bit_shift --;
201 break;
202 case HDLC_GETFLAG_B1A6:
203 if(hdlc->cbin & 0x80){
204 hdlc->hdlc_bits1++;
205 if(hdlc->hdlc_bits1==6){
206 hdlc->state = HDLC_GETFLAG_B7;
208 } else {
209 hdlc->hdlc_bits1 = 0;
211 hdlc->cbin<<=1;
212 hdlc->bit_shift --;
213 break;
214 case HDLC_GETFLAG_B7:
215 if(hdlc->cbin & 0x80) {
216 hdlc->state = HDLC_GET_FLAG_B0;
217 } else {
218 hdlc->state = HDLC_GET_DATA;
219 hdlc->crc = 0xffff;
220 hdlc->shift_reg = 0;
221 hdlc->hdlc_bits1 = 0;
222 hdlc->data_bits = 0;
223 hdlc->data_received = 0;
225 hdlc->cbin<<=1;
226 hdlc->bit_shift --;
227 break;
228 case HDLC_GET_DATA:
229 if(hdlc->cbin & 0x80){
230 hdlc->hdlc_bits1++;
231 switch(hdlc->hdlc_bits1){
232 case 6:
233 break;
234 case 7:
235 if(hdlc->data_received) {
236 // bad frame
237 status = -HDLC_FRAMING_ERROR;
239 if(!hdlc->do_adapt56){
240 if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
241 hdlc->state = HDLC_FAST_IDLE;
242 hdlc->bit_shift=1;
243 break;
245 } else {
246 hdlc->state = HDLC_GET_FLAG_B0;
248 break;
249 default:
250 hdlc->shift_reg>>=1;
251 hdlc->shift_reg |= 0x80;
252 hdlc->data_bits++;
253 break;
255 } else {
256 switch(hdlc->hdlc_bits1){
257 case 5:
258 break;
259 case 6:
260 if(hdlc->data_received){
261 if (hdlc->dstpos < 2) {
262 status = -HDLC_FRAMING_ERROR;
263 } else if (hdlc->crc != 0xf0b8){
264 // crc error
265 status = -HDLC_CRC_ERROR;
266 } else {
267 // remove CRC
268 hdlc->dstpos -= 2;
269 // good frame
270 status = hdlc->dstpos;
273 hdlc->crc = 0xffff;
274 hdlc->shift_reg = 0;
275 hdlc->data_bits = 0;
276 if(!hdlc->do_adapt56){
277 if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
278 hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
279 hdlc->state = HDLC_FAST_FLAG;
280 hdlc->ffbit_shift = hdlc->bit_shift;
281 hdlc->bit_shift = 1;
282 } else {
283 hdlc->state = HDLC_GET_DATA;
284 hdlc->data_received = 0;
286 } else {
287 hdlc->state = HDLC_GET_DATA;
288 hdlc->data_received = 0;
290 break;
291 default:
292 hdlc->shift_reg>>=1;
293 hdlc->data_bits++;
294 break;
296 hdlc->hdlc_bits1 = 0;
298 if (status) {
299 hdlc->dstpos = 0;
300 *count -= slen;
301 hdlc->cbin <<= 1;
302 hdlc->bit_shift--;
303 return status;
305 if(hdlc->data_bits==8){
306 hdlc->data_bits = 0;
307 hdlc->data_received = 1;
308 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
310 // good byte received
311 if (hdlc->dstpos < dsize) {
312 dst[hdlc->dstpos++] = hdlc->shift_reg;
313 } else {
314 // frame too long
315 status = -HDLC_LENGTH_ERROR;
316 hdlc->dstpos = 0;
319 hdlc->cbin <<= 1;
320 hdlc->bit_shift--;
321 break;
322 case HDLC_FAST_FLAG:
323 if(hdlc->cbin==hdlc->ffvalue){
324 hdlc->bit_shift = 0;
325 break;
326 } else {
327 if(hdlc->cbin == 0xff){
328 hdlc->state = HDLC_FAST_IDLE;
329 hdlc->bit_shift=0;
330 } else if(hdlc->ffbit_shift==8){
331 hdlc->state = HDLC_GETFLAG_B7;
332 break;
333 } else {
334 hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
335 hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
336 if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
337 hdlc->data_bits = hdlc->ffbit_shift-1;
338 hdlc->state = HDLC_GET_DATA;
339 hdlc->data_received = 0;
342 break;
343 default:
344 break;
347 *count -= slen;
348 return 0;
352 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
354 The bit stream starts with a beginning flag (01111110). After
355 that each byte is added to the bit stream with bit stuffing added
356 (0 after 5 1's).
357 When the last byte has been removed from the source buffer, the
358 CRC (2 bytes is added) and the frame terminates with the ending flag.
359 For the dchannel, the idle character (all 1's) is also added at the end.
360 If this function is called with empty source buffer (slen=0), flags or
361 idle character will be generated.
363 src - source buffer
364 slen - source buffer length
365 count - number of bytes removed (encoded) from source buffer
366 dst _ destination buffer
367 dsize - destination buffer size
368 returns - number of encoded bytes in the destination buffer
370 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
371 unsigned short slen, int *count,
372 unsigned char *dst, int dsize)
374 static const unsigned char xfast_flag_value[] = {
375 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
378 int len = 0;
380 *count = slen;
382 while (dsize > 0) {
383 if(hdlc->bit_shift==0){
384 if(slen && !hdlc->do_closing){
385 hdlc->shift_reg = *src++;
386 slen--;
387 if (slen == 0)
388 hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */
389 hdlc->bit_shift = 8;
390 } else {
391 if(hdlc->state == HDLC_SEND_DATA){
392 if(hdlc->data_received){
393 hdlc->state = HDLC_SEND_CRC1;
394 hdlc->crc ^= 0xffff;
395 hdlc->bit_shift = 8;
396 hdlc->shift_reg = hdlc->crc & 0xff;
397 } else if(!hdlc->do_adapt56){
398 hdlc->state = HDLC_SEND_FAST_FLAG;
399 } else {
400 hdlc->state = HDLC_SENDFLAG_B0;
407 switch(hdlc->state){
408 case STOPPED:
409 while (dsize--)
410 *dst++ = 0xff;
412 return dsize;
413 case HDLC_SEND_FAST_FLAG:
414 hdlc->do_closing = 0;
415 if(slen == 0){
416 *dst++ = hdlc->ffvalue;
417 len++;
418 dsize--;
419 break;
421 if(hdlc->bit_shift==8){
422 hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
423 hdlc->state = HDLC_SEND_DATA;
424 hdlc->crc = 0xffff;
425 hdlc->hdlc_bits1 = 0;
426 hdlc->data_received = 1;
428 break;
429 case HDLC_SENDFLAG_B0:
430 hdlc->do_closing = 0;
431 hdlc->cbin <<= 1;
432 hdlc->data_bits++;
433 hdlc->hdlc_bits1 = 0;
434 hdlc->state = HDLC_SENDFLAG_B1A6;
435 break;
436 case HDLC_SENDFLAG_B1A6:
437 hdlc->cbin <<= 1;
438 hdlc->data_bits++;
439 hdlc->cbin++;
440 if(++hdlc->hdlc_bits1 == 6)
441 hdlc->state = HDLC_SENDFLAG_B7;
442 break;
443 case HDLC_SENDFLAG_B7:
444 hdlc->cbin <<= 1;
445 hdlc->data_bits++;
446 if(slen == 0){
447 hdlc->state = HDLC_SENDFLAG_B0;
448 break;
450 if(hdlc->bit_shift==8){
451 hdlc->state = HDLC_SEND_DATA;
452 hdlc->crc = 0xffff;
453 hdlc->hdlc_bits1 = 0;
454 hdlc->data_received = 1;
456 break;
457 case HDLC_SEND_FIRST_FLAG:
458 hdlc->data_received = 1;
459 if(hdlc->data_bits==8){
460 hdlc->state = HDLC_SEND_DATA;
461 hdlc->crc = 0xffff;
462 hdlc->hdlc_bits1 = 0;
463 break;
465 hdlc->cbin <<= 1;
466 hdlc->data_bits++;
467 if(hdlc->shift_reg & 0x01)
468 hdlc->cbin++;
469 hdlc->shift_reg >>= 1;
470 hdlc->bit_shift--;
471 if(hdlc->bit_shift==0){
472 hdlc->state = HDLC_SEND_DATA;
473 hdlc->crc = 0xffff;
474 hdlc->hdlc_bits1 = 0;
476 break;
477 case HDLC_SEND_DATA:
478 hdlc->cbin <<= 1;
479 hdlc->data_bits++;
480 if(hdlc->hdlc_bits1 == 5){
481 hdlc->hdlc_bits1 = 0;
482 break;
484 if(hdlc->bit_shift==8){
485 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
487 if(hdlc->shift_reg & 0x01){
488 hdlc->hdlc_bits1++;
489 hdlc->cbin++;
490 hdlc->shift_reg >>= 1;
491 hdlc->bit_shift--;
492 } else {
493 hdlc->hdlc_bits1 = 0;
494 hdlc->shift_reg >>= 1;
495 hdlc->bit_shift--;
497 break;
498 case HDLC_SEND_CRC1:
499 hdlc->cbin <<= 1;
500 hdlc->data_bits++;
501 if(hdlc->hdlc_bits1 == 5){
502 hdlc->hdlc_bits1 = 0;
503 break;
505 if(hdlc->shift_reg & 0x01){
506 hdlc->hdlc_bits1++;
507 hdlc->cbin++;
508 hdlc->shift_reg >>= 1;
509 hdlc->bit_shift--;
510 } else {
511 hdlc->hdlc_bits1 = 0;
512 hdlc->shift_reg >>= 1;
513 hdlc->bit_shift--;
515 if(hdlc->bit_shift==0){
516 hdlc->shift_reg = (hdlc->crc >> 8);
517 hdlc->state = HDLC_SEND_CRC2;
518 hdlc->bit_shift = 8;
520 break;
521 case HDLC_SEND_CRC2:
522 hdlc->cbin <<= 1;
523 hdlc->data_bits++;
524 if(hdlc->hdlc_bits1 == 5){
525 hdlc->hdlc_bits1 = 0;
526 break;
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--;
538 if(hdlc->bit_shift==0){
539 hdlc->shift_reg = 0x7e;
540 hdlc->state = HDLC_SEND_CLOSING_FLAG;
541 hdlc->bit_shift = 8;
543 break;
544 case HDLC_SEND_CLOSING_FLAG:
545 hdlc->cbin <<= 1;
546 hdlc->data_bits++;
547 if(hdlc->hdlc_bits1 == 5){
548 hdlc->hdlc_bits1 = 0;
549 break;
551 if(hdlc->shift_reg & 0x01){
552 hdlc->cbin++;
554 hdlc->shift_reg >>= 1;
555 hdlc->bit_shift--;
556 if(hdlc->bit_shift==0){
557 hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
558 if(hdlc->dchannel){
559 hdlc->ffvalue = 0x7e;
560 hdlc->state = HDLC_SEND_IDLE1;
561 hdlc->bit_shift = 8-hdlc->data_bits;
562 if(hdlc->bit_shift==0)
563 hdlc->state = HDLC_SEND_FAST_IDLE;
564 } else {
565 if(!hdlc->do_adapt56){
566 hdlc->state = HDLC_SEND_FAST_FLAG;
567 hdlc->data_received = 0;
568 } else {
569 hdlc->state = HDLC_SENDFLAG_B0;
570 hdlc->data_received = 0;
572 // Finished with this frame, send flags
573 if (dsize > 1) dsize = 1;
576 break;
577 case HDLC_SEND_IDLE1:
578 hdlc->do_closing = 0;
579 hdlc->cbin <<= 1;
580 hdlc->cbin++;
581 hdlc->data_bits++;
582 hdlc->bit_shift--;
583 if(hdlc->bit_shift==0){
584 hdlc->state = HDLC_SEND_FAST_IDLE;
585 hdlc->bit_shift = 0;
587 break;
588 case HDLC_SEND_FAST_IDLE:
589 hdlc->do_closing = 0;
590 hdlc->cbin = 0xff;
591 hdlc->data_bits = 8;
592 if(hdlc->bit_shift == 8){
593 hdlc->cbin = 0x7e;
594 hdlc->state = HDLC_SEND_FIRST_FLAG;
595 } else {
596 *dst++ = hdlc->cbin;
597 hdlc->bit_shift = hdlc->data_bits = 0;
598 len++;
599 dsize = 0;
601 break;
602 default:
603 break;
605 if(hdlc->do_adapt56){
606 if(hdlc->data_bits==7){
607 hdlc->cbin <<= 1;
608 hdlc->cbin++;
609 hdlc->data_bits++;
612 if(hdlc->data_bits==8){
613 *dst++ = hdlc->cbin;
614 hdlc->data_bits = 0;
615 len++;
616 dsize--;
619 *count -= slen;
621 return len;
624 EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);
625 EXPORT_SYMBOL(isdnhdlc_rcv_init);
626 EXPORT_SYMBOL(isdnhdlc_decode);
627 EXPORT_SYMBOL(isdnhdlc_out_init);
628 EXPORT_SYMBOL(isdnhdlc_encode);