Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bd4bcd3 authored by Karsten Keil's avatar Karsten Keil
Browse files

ISDN: Clean up isdnhdlc code



Clean up isdnhdlc to meet current code standard.
Remove hint to already removed bit reversal table.

Signed-off-by: default avatarKarsten Keil <keil@b1-systems.de>
parent cb3824ba
Loading
Loading
Loading
Loading
+194 −172
Original line number Diff line number Diff line
/*
 * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
 *
 *Copyright (C) 2002	Wolfgang Mües      <wolfgang@iksw-muees.de>
 * Copyright (C)
 *	2002	Wolfgang Mües		<wolfgang@iksw-muees.de>
 *	2001	Frode Isaksen		<fisaksen@bewan.com>
 *      2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
 *
@@ -63,8 +64,10 @@ void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
	hdlc->ffvalue = 0;
	hdlc->dstpos = 0;
}
EXPORT_SYMBOL(isdnhdlc_out_init);

void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
	int do_adapt56)
{
	hdlc->bit_shift = 0;
	hdlc->hdlc_bits1 = 0;
@@ -93,6 +96,25 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
	}
	hdlc->shift_reg = 0;
}
EXPORT_SYMBOL(isdnhdlc_rcv_init);

static int
check_frame(struct isdnhdlc_vars *hdlc)
{
	int status;

	if (hdlc->dstpos < 2) 	/* too small - framing error */
		status = -HDLC_FRAMING_ERROR;
	else if (hdlc->crc != 0xf0b8)	/* crc error */
		status = -HDLC_CRC_ERROR;
	else {
		/* remove CRC */
		hdlc->dstpos -= 2;
		/* good frame */
		status = hdlc->dstpos;
	}
	return status;
}

/*
  isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
@@ -121,8 +143,8 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
  returns - number of decoded bytes in the destination buffer and status
  flag.
 */
int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
		     int slen, int *count, unsigned char *dst, int dsize)
int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
	int *count, u8 *dst, int dsize)
{
	int status = 0;

@@ -138,6 +160,30 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
		0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
	};

#define handle_fast_flag(h) \
	do {\
		if (h->cbin == fast_flag[h->bit_shift]) {\
			h->ffvalue = fast_flag_value[h->bit_shift];\
			h->state = HDLC_FAST_FLAG;\
			h->ffbit_shift = h->bit_shift;\
			h->bit_shift = 1;\
		} else {\
			h->state = HDLC_GET_DATA;\
			h->data_received = 0;\
		} \
	} while (0)

#define handle_abort(h) \
	do {\
		h->shift_reg = fast_abort[h->ffbit_shift - 1];\
		h->hdlc_bits1 = h->ffbit_shift - 2;\
		if (h->hdlc_bits1 < 0)\
			h->hdlc_bits1 = 0;\
		h->data_bits = h->ffbit_shift - 1;\
		h->state = HDLC_GET_DATA;\
		h->data_received = 0;\
	} while (0)

	*count = slen;

	while (slen > 0) {
@@ -145,10 +191,9 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
			hdlc->cbin = *src++;
			slen--;
			hdlc->bit_shift = 8;
			if(hdlc->do_adapt56){
			if (hdlc->do_adapt56)
				hdlc->bit_shift--;
		}
		}

		switch (hdlc->state) {
		case STOPPED:
@@ -167,23 +212,21 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
				hdlc->state = HDLC_GETFLAG_B1A6;
				hdlc->hdlc_bits1 = 0;
			} else {
				if(!hdlc->do_adapt56){
					if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
				if ((!hdlc->do_adapt56) &&
				    (++hdlc->hdlc_bits1 >= 8) &&
				    (hdlc->bit_shift == 1))
						hdlc->state = HDLC_FAST_IDLE;
			}
			}
			hdlc->cbin <<= 1;
			hdlc->bit_shift--;
			break;
		case HDLC_GETFLAG_B1A6:
			if (hdlc->cbin & 0x80) {
				hdlc->hdlc_bits1++;
				if(hdlc->hdlc_bits1==6){
				if (hdlc->hdlc_bits1 == 6)
					hdlc->state = HDLC_GETFLAG_B7;
				}
			} else {
			} else
				hdlc->hdlc_bits1 = 0;
			}
			hdlc->cbin <<= 1;
			hdlc->bit_shift--;
			break;
@@ -208,19 +251,19 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
				case 6:
					break;
				case 7:
					if(hdlc->data_received) {
						// bad frame
					if (hdlc->data_received)
						/* bad frame */
						status = -HDLC_FRAMING_ERROR;
					}
					if (!hdlc->do_adapt56) {
						if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
							hdlc->state = HDLC_FAST_IDLE;
						if (hdlc->cbin == fast_abort
						    [hdlc->bit_shift + 1]) {
							hdlc->state =
								HDLC_FAST_IDLE;
							hdlc->bit_shift = 1;
							break;
						}
					} else {
					} else
						hdlc->state = HDLC_GET_FLAG_B0;
					}
					break;
				default:
					hdlc->shift_reg >>= 1;
@@ -233,33 +276,14 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
				case 5:
					break;
				case 6:
					if(hdlc->data_received){
						if (hdlc->dstpos < 2) {
							status = -HDLC_FRAMING_ERROR;
						} else if (hdlc->crc != 0xf0b8){
							// crc error
							status = -HDLC_CRC_ERROR;
						} else {
							// remove CRC
							hdlc->dstpos -= 2;
							// good frame
							status = hdlc->dstpos;
						}
					}
					if (hdlc->data_received)
						status = check_frame(hdlc);
					hdlc->crc = 0xffff;
					hdlc->shift_reg = 0;
					hdlc->data_bits = 0;
					if(!hdlc->do_adapt56){
						if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
							hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
							hdlc->state = HDLC_FAST_FLAG;
							hdlc->ffbit_shift = hdlc->bit_shift;
							hdlc->bit_shift = 1;
						} else {
							hdlc->state = HDLC_GET_DATA;
							hdlc->data_received = 0;
						}
					} else {
					if (!hdlc->do_adapt56)
						handle_fast_flag(hdlc);
					else {
						hdlc->state = HDLC_GET_DATA;
						hdlc->data_received = 0;
					}
@@ -281,13 +305,14 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
			if (hdlc->data_bits == 8) {
				hdlc->data_bits = 0;
				hdlc->data_received = 1;
				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
				hdlc->crc = crc_ccitt_byte(hdlc->crc,
						hdlc->shift_reg);

				// good byte received
				if (hdlc->dstpos < dsize) {
				/* good byte received */
				if (hdlc->dstpos < dsize)
					dst[hdlc->dstpos++] = hdlc->shift_reg;
				} else {
					// frame too long
				else {
					/* frame too long */
					status = -HDLC_LENGTH_ERROR;
					hdlc->dstpos = 0;
				}
@@ -306,14 +331,8 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
				} else if (hdlc->ffbit_shift == 8) {
					hdlc->state = HDLC_GETFLAG_B7;
					break;
				} else {
					hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
					hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
					if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
					hdlc->data_bits = hdlc->ffbit_shift-1;
					hdlc->state = HDLC_GET_DATA;
					hdlc->data_received = 0;
				}
				} else
					handle_abort(hdlc);
			}
			break;
		default:
@@ -323,7 +342,7 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
	*count -= slen;
	return 0;
}

EXPORT_SYMBOL(isdnhdlc_decode);
/*
  isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.

@@ -343,9 +362,8 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
  dsize - destination buffer size
  returns - number of encoded bytes in the destination buffer
*/
int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
		unsigned short slen, int *count,
		unsigned char *dst, int dsize)
int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
	int *count, u8 *dst, int dsize)
{
	static const unsigned char xfast_flag_value[] = {
		0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
@@ -361,7 +379,8 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
				hdlc->shift_reg = *src++;
				slen--;
				if (slen == 0)
					hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
					/* closing sequence, CRC + flag(s) */
					hdlc->do_closing = 1;
				hdlc->bit_shift = 8;
			} else {
				if (hdlc->state == HDLC_SEND_DATA) {
@@ -369,12 +388,14 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
						hdlc->state = HDLC_SEND_CRC1;
						hdlc->crc ^= 0xffff;
						hdlc->bit_shift = 8;
						hdlc->shift_reg = hdlc->crc & 0xff;
					} else if(!hdlc->do_adapt56){
						hdlc->state = HDLC_SEND_FAST_FLAG;
					} else {
						hdlc->state = HDLC_SENDFLAG_B0;
					}
						hdlc->shift_reg =
							hdlc->crc & 0xff;
					} else if (!hdlc->do_adapt56)
						hdlc->state =
							HDLC_SEND_FAST_FLAG;
					else
						hdlc->state =
							HDLC_SENDFLAG_B0;
				}

			}
@@ -395,7 +416,8 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
				break;
			}
			if (hdlc->bit_shift == 8) {
				hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
				hdlc->cbin = hdlc->ffvalue >>
					(8 - hdlc->data_bits);
				hdlc->state = HDLC_SEND_DATA;
				hdlc->crc = 0xffff;
				hdlc->hdlc_bits1 = 0;
@@ -457,9 +479,9 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
				hdlc->hdlc_bits1 = 0;
				break;
			}
			if(hdlc->bit_shift==8){
				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
			}
			if (hdlc->bit_shift == 8)
				hdlc->crc = crc_ccitt_byte(hdlc->crc,
					hdlc->shift_reg);
			if (hdlc->shift_reg & 0x01) {
				hdlc->hdlc_bits1++;
				hdlc->cbin++;
@@ -524,29 +546,32 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
				hdlc->hdlc_bits1 = 0;
				break;
			}
			if(hdlc->shift_reg & 0x01){
			if (hdlc->shift_reg & 0x01)
				hdlc->cbin++;
			}
			hdlc->shift_reg >>= 1;
			hdlc->bit_shift--;
			if (hdlc->bit_shift == 0) {
				hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
				hdlc->ffvalue =
					xfast_flag_value[hdlc->data_bits];
				if (hdlc->dchannel) {
					hdlc->ffvalue = 0x7e;
					hdlc->state = HDLC_SEND_IDLE1;
					hdlc->bit_shift = 8-hdlc->data_bits;
					if (hdlc->bit_shift == 0)
						hdlc->state = HDLC_SEND_FAST_IDLE;
						hdlc->state =
							HDLC_SEND_FAST_IDLE;
				} else {
					if (!hdlc->do_adapt56) {
						hdlc->state = HDLC_SEND_FAST_FLAG;
						hdlc->state =
							HDLC_SEND_FAST_FLAG;
						hdlc->data_received = 0;
					} else {
						hdlc->state = HDLC_SENDFLAG_B0;
						hdlc->data_received = 0;
					}
					// Finished with this frame, send flags
					if (dsize > 1) dsize = 1;
					/* Finished this frame, send flags */
					if (dsize > 1)
						dsize = 1;
				}
			}
			break;
@@ -570,7 +595,8 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
				hdlc->state = HDLC_SEND_FIRST_FLAG;
			} else {
				*dst++ = hdlc->cbin;
				hdlc->bit_shift = hdlc->data_bits = 0;
				hdlc->bit_shift = 0;
				hdlc->data_bits = 0;
				len++;
				dsize = 0;
			}
@@ -596,8 +622,4 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,

	return len;
}

EXPORT_SYMBOL(isdnhdlc_rcv_init);
EXPORT_SYMBOL(isdnhdlc_decode);
EXPORT_SYMBOL(isdnhdlc_out_init);
EXPORT_SYMBOL(isdnhdlc_encode);
+37 −31
Original line number Diff line number Diff line
/*
 * isdnhdlc.h  --  General purpose ISDN HDLC decoder.
 * hdlc.h  --  General purpose ISDN HDLC decoder.
 *
 * Implementation of a HDLC decoder/encoder in software.
 * Neccessary because some ISDN devices don't have HDLC
 * controllers. Also included: a bit reversal table.
 * controllers.
 *
 *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
 * Copyright (C)
 *	2002	Wolfgang Mües		<wolfgang@iksw-muees.de>
 *	2001	Frode Isaksen		<fisaksen@bewan.com>
 *	2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
 *
@@ -31,20 +32,24 @@ struct isdnhdlc_vars {
	int bit_shift;
	int hdlc_bits1;
	int data_bits;
	int ffbit_shift; 	// encoding only
	int ffbit_shift;	/* encoding only */
	int state;
	int dstpos;

	unsigned short crc;
	u16 crc;

	unsigned char cbin;
	unsigned char shift_reg;
	unsigned char ffvalue;
	u8 cbin;
	u8 shift_reg;
	u8 ffvalue;

	unsigned int data_received:1; 	// set if transferring data
	unsigned int dchannel:1; 	// set if D channel (send idle instead of flags)
	unsigned int do_adapt56:1; 	// set if 56K adaptation
	unsigned int do_closing:1; 	// set if in closing phase (need to send CRC + flag
	/* set if transferring data */
	u32 data_received:1;
	/* set if D channel (send idle instead of flags) */
	u32 dchannel:1;
	/* set if 56K adaptation */
	u32 do_adapt56:1;
	/* set if in closing phase (need to send CRC + flag) */
	u32 do_closing:1;
};


@@ -59,12 +64,13 @@ struct isdnhdlc_vars {

extern void	isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, int do_adapt56);

extern int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, int slen,int *count,
	                    unsigned char *dst, int dsize);
extern int	isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
			int slen, int *count, u8 *dst, int dsize);

extern void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc,int is_d_channel,int do_adapt56);
extern void	isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, int is_d_channel,
			int do_adapt56);

extern int isdnhdlc_encode (struct isdnhdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
	                    unsigned char *dst,int dsize);
extern int	isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
			u16 slen, int *count, u8 *dst, int dsize);

#endif /* __ISDNHDLC_H__ */