1 /* $Id: tpam_crcpc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
3 * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding)
5 * Copyright 1998-2000 AUVERTECH Télécom
6 * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * For all support questions please contact: <support@auvertech.fr>
15 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 Software HDLC coding / decoding
28 ---------------------------------------------------------------------------*/
30 #include <linux/crc-ccitt.h>
33 #define HDLC_CTRL_CHAR_CMPL_MASK 0x20 /* HDLC control character complement mask */
34 #define HDLC_FLAG 0x7E /* HDLC flag */
35 #define HDLC_CTRL_ESC 0x7D /* HDLC control escapr character */
36 #define HDLC_LIKE_FCS_INIT_VAL 0xFFFF /* FCS initial value (0xFFFF for new equipment or 0) */
37 #define HDLC_FCS_OK 0xF0B8 /* This value is the only valid value of FCS */
42 static u8 ap_t_ctrl_char_complemented
[256]; /* list of characters to complement */
44 static void ap_hdlc_like_ctrl_char_list (u32 ctrl_char
) {
47 for (i
= 0; i
< 256; ++i
)
48 ap_t_ctrl_char_complemented
[i
] = FALSE
;
49 for (i
= 0; i
< 32; ++i
)
50 if ((ctrl_char
>> i
) & 0x0001)
51 ap_t_ctrl_char_complemented
[i
] = TRUE
;
52 ap_t_ctrl_char_complemented
[HDLC_FLAG
] = TRUE
;
53 ap_t_ctrl_char_complemented
[HDLC_CTRL_ESC
] = TRUE
;
58 ap_hdlc_like_ctrl_char_list(0xffffffff);
61 void hdlc_encode_modem(u8
*buffer_in
, u32 lng_in
,
62 u8
*buffer_out
, u32
*lng_out
) {
65 register u8
*p_data_out
= buffer_out
;
67 fcs
= HDLC_LIKE_FCS_INIT_VAL
;
70 * Insert HDLC flag at the beginning of the frame
72 *p_data_out
++ = HDLC_FLAG
;
74 #define ESCAPE_CHAR(data_out, data) \
75 if (ap_t_ctrl_char_complemented[data]) { \
76 *data_out++ = HDLC_CTRL_ESC; \
77 *data_out++ = data ^ 0x20; \
88 fcs
= crc_ccitt_byte(fcs
, data
);
90 ESCAPE_CHAR(p_data_out
, data
);
94 * Add FCS and closing flag
96 fcs
^= 0xFFFF; // Complement
98 data
= (u8
)(fcs
& 0xff); /* LSB */
99 ESCAPE_CHAR(p_data_out
, data
);
101 data
= (u8
)((fcs
>> 8)); /* MSB */
102 ESCAPE_CHAR(p_data_out
, data
);
105 *p_data_out
++ = HDLC_FLAG
;
107 *lng_out
= (u32
)(p_data_out
- buffer_out
);
110 void hdlc_no_accm_encode(u8
*buffer_in
, u32 lng_in
,
111 u8
*buffer_out
, u32
*lng_out
) {
114 register u8
*p_data_out
= buffer_out
;
117 * Insert HDLC flag at the beginning of the frame
119 fcs
= HDLC_LIKE_FCS_INIT_VAL
;
124 fcs
= crc_ccitt_byte(fcs
, data
);
125 *p_data_out
++ = data
;
129 * Add FCS and closing flag
131 fcs
^= 0xFFFF; // Complement
133 *p_data_out
++ = data
;
135 data
=(u8
)((fcs
>> 8)); // revense MSB / LSB
136 *p_data_out
++ = data
;
138 *lng_out
= (u32
)(p_data_out
- buffer_out
);
141 u32
hdlc_no_accm_decode(u8
*buffer_in
, u32 lng_in
) {
147 * Insert HDLC flag at the beginning of the frame
149 fcs
= HDLC_LIKE_FCS_INIT_VAL
;
154 fcs
= crc_ccitt_byte(fcs
, data
);
157 if (fcs
== HDLC_FCS_OK
)