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