isocdata.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,011 行 · 第 1/3 页

C
1,011
字号
 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db, 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb, 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b, 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b, 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b, 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b, 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b, 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb, 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb, 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,// previous 1s = 4: 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d, 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d, 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d, 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d, 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d, 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd, 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd, 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d, 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d, 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d, 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d, 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d, 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d, 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd, 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd, 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d};/* hdlc_bitstuff_byte * perform HDLC bitstuffing for one input byte (8 bits, LSB first) * parameters: *	cin	input byte *	ones	number of trailing '1' bits in result before this step *	iwb	pointer to output buffer structure (write semaphore must be held) * return value: *	number of trailing '1' bits in result after this step */static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,				     int ones){	u16 stuff;	int shiftinc, newones;	/* get stuffing information for input byte	 * value: bit  9.. 0 = result bits	 *        bit 12..10 = number of trailing '1' bits in result	 *        bit 14..13 = number of bits added by stuffing	 */	stuff = stufftab[256 * ones + cin];	shiftinc = (stuff >> 13) & 3;	newones = (stuff >> 10) & 7;	stuff &= 0x3ff;	/* append stuffed byte to output stream */	isowbuf_putbits(iwb, stuff, 8 + shiftinc);	return newones;}/* hdlc_buildframe * Perform HDLC framing with bitstuffing on a byte buffer * The input buffer is regarded as a sequence of bits, starting with the least * significant bit of the first byte and ending with the most significant bit * of the last byte. A 16 bit FCS is appended as defined by RFC 1662. * Whenever five consecutive '1' bits appear in the resulting bit sequence, a * '0' bit is inserted after them. * The resulting bit string and a closing flag pattern (PPP_FLAG, '01111110') * are appended to the output buffer starting at the given bit position, which * is assumed to already contain a leading flag. * The output buffer must have sufficient length; count + count/5 + 6 bytes * starting at *out are safe and are verified to be present. * parameters: *	in	input buffer *	count	number of bytes in input buffer *	iwb	pointer to output buffer structure (write semaphore must be held) * return value: *	position of end of packet in output buffer on success, *	-EAGAIN if write semaphore busy or buffer full */static inline int hdlc_buildframe(struct isowbuf_t *iwb,				  unsigned char *in, int count){	int ones;	u16 fcs;	int end;	unsigned char c;	if (isowbuf_freebytes(iwb) < count + count / 5 + 6 ||	    !isowbuf_startwrite(iwb)) {		gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN",			__func__, isowbuf_freebytes(iwb));		return -EAGAIN;	}	dump_bytes(DEBUG_STREAM, "snd data", in, count);	/* bitstuff and checksum input data */	fcs = PPP_INITFCS;	ones = 0;	while (count-- > 0) {		c = *in++;		ones = hdlc_bitstuff_byte(iwb, c, ones);		fcs = crc_ccitt_byte(fcs, c);	}	/* bitstuff and append FCS (complemented, least significant byte first) */	fcs ^= 0xffff;	ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);	ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);	/* put closing flag and repeat byte for flag idle */	isowbuf_putflag(iwb);	end = isowbuf_donewrite(iwb);	dump_bytes(DEBUG_STREAM_DUMP, "isowbuf", iwb->data, end + 1);	return end;}/* trans_buildframe * Append a block of 'transparent' data to the output buffer, * inverting the bytes. * The output buffer must have sufficient length; count bytes * starting at *out are safe and are verified to be present. * parameters: *	in	input buffer *	count	number of bytes in input buffer *	iwb	pointer to output buffer structure (write semaphore must be held) * return value: *	position of end of packet in output buffer on success, *	-EAGAIN if write semaphore busy or buffer full */static inline int trans_buildframe(struct isowbuf_t *iwb,				   unsigned char *in, int count){	int write;	unsigned char c;	if (unlikely(count <= 0))		return atomic_read(&iwb->write); /* better ideas? */	if (isowbuf_freebytes(iwb) < count ||	    !isowbuf_startwrite(iwb)) {		gig_dbg(DEBUG_ISO, "can't put %d bytes", count);		return -EAGAIN;	}	gig_dbg(DEBUG_STREAM, "put %d bytes", count);	write = atomic_read(&iwb->write);	do {		c = gigaset_invtab[*in++];		iwb->data[write++] = c;		write %= BAS_OUTBUFSIZE;	} while (--count > 0);	atomic_set(&iwb->write, write);	iwb->idle = c;	return isowbuf_donewrite(iwb);}int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len){	int result;	switch (bcs->proto2) {	case ISDN_PROTO_L2_HDLC:		result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);		gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",			__func__, len, result);		break;	default:			/* assume transparent */		result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len);		gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d",			__func__, len, result);	}	return result;}/* hdlc_putbyte * append byte c to current skb of B channel structure *bcs, updating fcs */static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs){	bcs->fcs = crc_ccitt_byte(bcs->fcs, c);	if (unlikely(bcs->skb == NULL)) {		/* skipping */		return;	}	if (unlikely(bcs->skb->len == SBUFSIZE)) {		dev_warn(bcs->cs->dev, "received oversized packet discarded\n");		bcs->hw.bas->giants++;		dev_kfree_skb_any(bcs->skb);		bcs->skb = NULL;		return;	}	*__skb_put(bcs->skb, 1) = c;}/* hdlc_flush * drop partial HDLC data packet */static inline void hdlc_flush(struct bc_state *bcs){	/* clear skb or allocate new if not skipping */	if (likely(bcs->skb != NULL))		skb_trim(bcs->skb, 0);	else if (!bcs->ignore) {		if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)			skb_reserve(bcs->skb, HW_HDR_LEN);		else			dev_err(bcs->cs->dev, "could not allocate skb\n");	}	/* reset packet state */	bcs->fcs = PPP_INITFCS;}/* hdlc_done * process completed HDLC data packet */static inline void hdlc_done(struct bc_state *bcs){	struct sk_buff *procskb;	if (unlikely(bcs->ignore)) {		bcs->ignore--;		hdlc_flush(bcs);		return;	}	if ((procskb = bcs->skb) == NULL) {		/* previous error */		gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);		gigaset_rcv_error(NULL, bcs->cs, bcs);	} else if (procskb->len < 2) {		dev_notice(bcs->cs->dev, "received short frame (%d octets)\n",			   procskb->len);		bcs->hw.bas->runts++;		gigaset_rcv_error(procskb, bcs->cs, bcs);	} else if (bcs->fcs != PPP_GOODFCS) {		dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n",			   bcs->fcs);		bcs->hw.bas->fcserrs++;		gigaset_rcv_error(procskb, bcs->cs, bcs);	} else {		procskb->len -= 2;		/* subtract FCS */		procskb->tail -= 2;		gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",			__func__, procskb->len);		dump_bytes(DEBUG_STREAM,			   "rcv data", procskb->data, procskb->len);		bcs->hw.bas->goodbytes += procskb->len;		gigaset_rcv_skb(procskb, bcs->cs, bcs);	}	if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)		skb_reserve(bcs->skb, HW_HDR_LEN);	else		dev_err(bcs->cs->dev, "could not allocate skb\n");	bcs->fcs = PPP_INITFCS;}/* hdlc_frag * drop HDLC data packet with non-integral last byte */static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits){	if (unlikely(bcs->ignore)) {		bcs->ignore--;		hdlc_flush(bcs);		return;	}	dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);	bcs->hw.bas->alignerrs++;	gigaset_rcv_error(bcs->skb, bcs->cs, bcs);	if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)		skb_reserve(bcs->skb, HW_HDR_LEN);	else		dev_err(bcs->cs->dev, "could not allocate skb\n");	bcs->fcs = PPP_INITFCS;}/* bit counts lookup table for HDLC bit unstuffing * index: input byte * value: bit 0..3 = number of consecutive '1' bits starting from LSB *        bit 4..6 = number of consecutive '1' bits starting from MSB *		     (replacing 8 by 7 to make it fit; the algorithm won't care) *        bit 7 set if there are 5 or more "interior" consecutive '1' bits */static unsigned char bitcounts[256] = {  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,  0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,  0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,  0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,  0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78};/* hdlc_unpack * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation) * on a sequence of received data bytes (8 bits each, LSB first) * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb * notify of errors via gigaset_rcv_error * tally frames, errors etc. in BC structure counters * parameters: *	src	received data *	count	number of received bytes *	bcs	receiving B channel structure */static inline void hdlc_unpack(unsigned char *src, unsigned count,			       struct bc_state *bcs){	struct bas_bc_state *ubc = bcs->hw.bas;	int inputstate;	unsigned seqlen, inbyte, inbits;	/* load previous state:	 * inputstate = set of flag bits:	 * - INS_flag_hunt: no complete opening flag received since connection setup or last abort	 * - INS_have_data: at least one complete data byte received since last flag	 * seqlen = number of consecutive '1' bits in last 7 input stream bits (0..7)	 * inbyte = accumulated partial data byte (if !INS_flag_hunt)	 * inbits = number of valid bits in inbyte, starting at LSB (0..6)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?