⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isdn_v110.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: isdn_v110.c,v 1.1.2.2 2004/01/12 22:37:19 keil Exp $ * * Linux ISDN subsystem, V.110 related functions (linklevel). * * Copyright by Thomas Pfeiffer (pfeiffer@pds.de) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */#include <linux/string.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/delay.h>#include <linux/isdn.h>#include "isdn_v110.h"#undef ISDN_V110_DEBUGchar *isdn_v110_revision = "$Revision: 1.1.2.2 $";#define V110_38400 255#define V110_19200  15#define V110_9600    3/*  * The following data are precoded matrices, online and offline matrix  * for 9600, 19200 und 38400, respectively */static unsigned char V110_OnMatrix_9600[] ={0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd};static unsigned char V110_OffMatrix_9600[] ={0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};static unsigned char V110_OnMatrix_19200[] ={0xf0, 0xf0, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf7, 0xfd, 0xff, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf7};static unsigned char V110_OffMatrix_19200[] ={0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};static unsigned char V110_OnMatrix_38400[] ={0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0xfd, 0x7f, 0x7f, 0x7f, 0x7f};static unsigned char V110_OffMatrix_38400[] ={0x00, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff};/*  * FlipBits reorders sequences of keylen bits in one byte. * E.g. source order 7654321 will be converted to 45670123 when keylen = 4, * and to 67452301 when keylen = 2. This is necessary because ordering on * the isdn line is the other way. */static __inline unsigned charFlipBits(unsigned char c, int keylen){	unsigned char b = c;	unsigned char bit = 128;	int i;	int j;	int hunks = (8 / keylen);	c = 0;	for (i = 0; i < hunks; i++) {		for (j = 0; j < keylen; j++) {			if (b & (bit >> j))				c |= bit >> (keylen - j - 1);		}		bit >>= keylen;	}	return c;}/* isdn_v110_open allocates and initializes private V.110 data * structures and returns a pointer to these. */static isdn_v110_stream *isdn_v110_open(unsigned char key, int hdrlen, int maxsize){	int i;	isdn_v110_stream *v;	if ((v = kmalloc(sizeof(isdn_v110_stream), GFP_ATOMIC)) == NULL)		return NULL;	memset(v, 0, sizeof(isdn_v110_stream));	v->key = key;	v->nbits = 0;	for (i = 0; key & (1 << i); i++)		v->nbits++;	v->nbytes = 8 / v->nbits;	v->decodelen = 0;	switch (key) {		case V110_38400:			v->OnlineFrame = V110_OnMatrix_38400;			v->OfflineFrame = V110_OffMatrix_38400;			break;		case V110_19200:			v->OnlineFrame = V110_OnMatrix_19200;			v->OfflineFrame = V110_OffMatrix_19200;			break;		default:			v->OnlineFrame = V110_OnMatrix_9600;			v->OfflineFrame = V110_OffMatrix_9600;			break;	}	v->framelen = v->nbytes * 10;	v->SyncInit = 5;	v->introducer = 0;	v->dbit = 1;	v->b = 0;	v->skbres = hdrlen;	v->maxsize = maxsize - hdrlen;	if ((v->encodebuf = kmalloc(maxsize, GFP_ATOMIC)) == NULL) {		kfree(v);		return NULL;	}	return v;}/* isdn_v110_close frees private V.110 data structures */voidisdn_v110_close(isdn_v110_stream * v){	if (v == NULL)		return;#ifdef ISDN_V110_DEBUG	printk(KERN_DEBUG "v110 close\n");#endif	kfree(v->encodebuf);	kfree(v);}/*  * ValidHeaderBytes return the number of valid bytes in v->decodebuf  */static intValidHeaderBytes(isdn_v110_stream * v){	int i;	for (i = 0; (i < v->decodelen) && (i < v->nbytes); i++)		if ((v->decodebuf[i] & v->key) != 0)			break;	return i;}/*  * SyncHeader moves the decodebuf ptr to the next valid header  */static voidSyncHeader(isdn_v110_stream * v){	unsigned char *rbuf = v->decodebuf;	int len = v->decodelen;	if (len == 0)		return;	for (rbuf++, len--; len > 0; len--, rbuf++)	/* such den SyncHeader in buf ! */		if ((*rbuf & v->key) == 0)	/* erstes byte gefunden ?       */			break;  /* jupp!                        */	if (len)		memcpy(v->decodebuf, rbuf, len);	v->decodelen = len;#ifdef ISDN_V110_DEBUG	printk(KERN_DEBUG "isdn_v110: Header resync\n");#endif}/* DecodeMatrix takes n (n>=1) matrices (v110 frames, 10 bytes) where   len is the number of matrix-lines. len must be a multiple of 10, i.e.   only complete matices must be given.   From these, netto data is extracted and returned in buf. The return-value   is the bytecount of the decoded data. */static intDecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf){	int line = 0;	int buflen = 0;	int mbit = 64;	int introducer = v->introducer;	int dbit = v->dbit;	unsigned char b = v->b;	while (line < len) {    /* Are we done with all lines of the matrix? */		if ((line % 10) == 0) {	/* the 0. line of the matrix is always 0 ! */			if (m[line] != 0x00) {	/* not 0 ? -> error! */#ifdef ISDN_V110_DEBUG				printk(KERN_DEBUG "isdn_v110: DecodeMatrix, V110 Bad Header\n");				/* returning now is not the right thing, though :-( */#endif			} 			line++; /* next line of matrix */			continue;		} else if ((line % 10) == 5) {	/* in line 5 there's only e-bits ! */			if ((m[line] & 0x70) != 0x30) {	/* 011 has to be at the beginning! */#ifdef ISDN_V110_DEBUG				printk(KERN_DEBUG "isdn_v110: DecodeMatrix, V110 Bad 5th line\n");				/* returning now is not the right thing, though :-( */#endif			}			line++; /* next line */			continue;		} else if (!introducer) {	/* every byte starts with 10 (stopbit, startbit) */			introducer = (m[line] & mbit) ? 0 : 1;	/* current bit of the matrix */		      next_byte:			if (mbit > 2) {	/* was it the last bit in this line ? */				mbit >>= 1;	/* no -> take next */				continue;			}       /* otherwise start with leftmost bit in the next line */			mbit = 64;			line++;			continue;		} else {        /* otherwise we need to set a data bit */			if (m[line] & mbit)	/* was that bit set in the matrix ? */				b |= dbit;	/* yes -> set it in the data byte */			else				b &= dbit - 1;	/* no -> clear it in the data byte */			if (dbit < 128)	/* is that data byte done ? */				dbit <<= 1;	/* no, got the next bit */			else {  /* data byte is done */				buf[buflen++] = b;	/* copy byte into the output buffer */				introducer = b = 0;	/* init of the intro sequence and of the data byte */				dbit = 1;	/* next we look for the 0th bit */			}			goto next_byte;	/* look for next bit in the matrix */		}	}	v->introducer = introducer;	v->dbit = dbit;	v->b = b;	return buflen;          /* return number of bytes in the output buffer */}/*  * DecodeStream receives V.110 coded data from the input stream. It recovers the  * original frames. * The input stream doesn't need to be framed */struct sk_buff *isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb){	int i;	int j;	int len;	unsigned char *v110_buf;	unsigned char *rbuf;	if (!skb) {		printk(KERN_WARNING "isdn_v110_decode called with NULL skb!\n");		return NULL;	}	rbuf = skb->data;	len = skb->len;	if (v == NULL) {		/* invalid handle, no chance to proceed */		printk(KERN_WARNING "isdn_v110_decode called with NULL stream!\n");		dev_kfree_skb(skb);		return NULL;	}	if (v->decodelen == 0)  /* cache empty?               */		for (; len > 0; len--, rbuf++)	/* scan for SyncHeader in buf */			if ((*rbuf & v->key) == 0)				break;	/* found first byte           */	if (len == 0) {		dev_kfree_skb(skb);		return NULL;	}	/* copy new data to decode-buffer */	memcpy(&(v->decodebuf[v->decodelen]), rbuf, len);	v->decodelen += len;      ReSync:	if (v->decodelen < v->nbytes) {	/* got a new header ? */		dev_kfree_skb(skb);		return NULL;    /* no, try later      */	}	if (ValidHeaderBytes(v) != v->nbytes) {	/* is that a valid header? */		SyncHeader(v);  /* no -> look for header */		goto ReSync;	}	len = (v->decodelen - (v->decodelen % (10 * v->nbytes))) / v->nbytes;	if ((v110_buf = kmalloc(len, GFP_ATOMIC)) == NULL) {		printk(KERN_WARNING "isdn_v110_decode: Couldn't allocate v110_buf\n");		dev_kfree_skb(skb);		return NULL;	}	for (i = 0; i < len; i++) {		v110_buf[i] = 0;		for (j = 0; j < v->nbytes; j++)			v110_buf[i] |= (v->decodebuf[(i * v->nbytes) + j] & v->key) << (8 - ((j + 1) * v->nbits));		v110_buf[i] = FlipBits(v110_buf[i], v->nbits);	}	v->decodelen = (v->decodelen % (10 * v->nbytes));	memcpy(v->decodebuf, &(v->decodebuf[len * v->nbytes]), v->decodelen);

⌨️ 快捷键说明

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