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

📄 isdn_v110.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	skb_trim(skb, DecodeMatrix(v, v110_buf, len, skb->data));	kfree(v110_buf);	if (skb->len)		return skb;	else {		kfree_skb(skb);		return NULL;	}}/* EncodeMatrix takes input data in buf, len is the bytecount.   Data is encoded into v110 frames in m. Return value is the number of   matrix-lines generated. */static intEncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen){	int line = 0;	int i = 0;	int mbit = 128;	int dbit = 1;	int introducer = 3;	int ibit[] = {0, 1, 1};	while ((i < len) && (line < mlen)) {	/* while we still have input data */		switch (line % 10) {	/* in which line of the matrix are we? */			case 0:				m[line++] = 0x00;	/* line 0 is always 0 */				mbit = 128;	/* go on with the 7th bit */				break;			case 5:				m[line++] = 0xbf;	/* line 5 is always 10111111 */				mbit = 128;	/* go on with the 7th bit */				break;		}		if (line >= mlen) {			printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");			return line;		}	next_bit:		switch (mbit) { /* leftmost or rightmost bit ? */			case 1:				line++;	/* rightmost -> go to next line */				if (line >= mlen) {					printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");					return line;				}			case 128:				m[line] = 128;	/* leftmost -> set byte to 1000000 */				mbit = 64;	/* current bit in the matrix line */				continue;		}		if (introducer) {	/* set 110 sequence ? */			introducer--;	/* set on digit less */			m[line] |= ibit[introducer] ? mbit : 0;	/* set corresponding bit */			mbit >>= 1;	/* bit of matrix line  >> 1 */			goto next_bit;	/* and go on there */		}               /* else push data bits into the matrix! */		m[line] |= (buf[i] & dbit) ? mbit : 0;	/* set data bit in matrix */		if (dbit == 128) {	/* was it the last one? */			dbit = 1;	/* then go on with first bit of  */			i++;            /* next byte in input buffer */			if (i < len)	/* input buffer done ? */				introducer = 3;	/* no, write introducer 110 */			else {  /* input buffer done ! */				m[line] |= (mbit - 1) & 0xfe;	/* set remaining bits in line to 1 */				break;			}		} else          /* not the last data bit */			dbit <<= 1;	/* then go to next data bit */		mbit >>= 1;     /* go to next bit of matrix */		goto next_bit;	}	/* if necessary, generate remaining lines of the matrix... */	if ((line) && ((line + 10) < mlen))		switch (++line % 10) {			case 1:				m[line++] = 0xfe;			case 2:				m[line++] = 0xfe;			case 3:				m[line++] = 0xfe;			case 4:				m[line++] = 0xfe;			case 5:				m[line++] = 0xbf;			case 6:				m[line++] = 0xfe;			case 7:				m[line++] = 0xfe;			case 8:				m[line++] = 0xfe;			case 9:				m[line++] = 0xfe;		}	return line;            /* that's how many lines we have */}/* * Build a sync frame. */static struct sk_buff *isdn_v110_sync(isdn_v110_stream *v){	struct sk_buff *skb;	if (v == NULL) {		/* invalid handle, no chance to proceed */		printk(KERN_WARNING "isdn_v110_sync called with NULL stream!\n");		return NULL;	}	if ((skb = dev_alloc_skb(v->framelen + v->skbres))) {		skb_reserve(skb, v->skbres);		memcpy(skb_put(skb, v->framelen), v->OfflineFrame, v->framelen);	}	return skb;}/* * Build an idle frame. */static struct sk_buff *isdn_v110_idle(isdn_v110_stream *v){	struct sk_buff *skb;	if (v == NULL) {		/* invalid handle, no chance to proceed */		printk(KERN_WARNING "isdn_v110_sync called with NULL stream!\n");		return NULL;	}	if ((skb = dev_alloc_skb(v->framelen + v->skbres))) {		skb_reserve(skb, v->skbres);		memcpy(skb_put(skb, v->framelen), v->OnlineFrame, v->framelen);	}	return skb;}struct sk_buff *isdn_v110_encode(isdn_v110_stream * v, struct sk_buff *skb){	int i;	int j;	int rlen;	int mlen;	int olen;	int size;	int sval1;	int sval2;	int nframes;	unsigned char *v110buf;	unsigned char *rbuf;	struct sk_buff *nskb;	if (v == NULL) {		/* invalid handle, no chance to proceed */		printk(KERN_WARNING "isdn_v110_encode called with NULL stream!\n");		return NULL;	}	if (!skb) {		/* invalid skb, no chance to proceed */		printk(KERN_WARNING "isdn_v110_encode called with NULL skb!\n");		return NULL;	}	rlen = skb->len;	nframes = (rlen + 3) / 4;	v110buf = v->encodebuf;	if ((nframes * 40) > v->maxsize) {		size = v->maxsize;		rlen = v->maxsize / 40;	} else		size = nframes * 40;	if (!(nskb = dev_alloc_skb(size + v->skbres + sizeof(int)))) {		printk(KERN_WARNING "isdn_v110_encode: Couldn't alloc skb\n");		return NULL;	}	skb_reserve(nskb, v->skbres + sizeof(int));	if (skb->len == 0) {		memcpy(skb_put(nskb, v->framelen), v->OnlineFrame, v->framelen);		*((int *)skb_push(nskb, sizeof(int))) = 0;		return nskb;	}	mlen = EncodeMatrix(skb->data, rlen, v110buf, size);	/* now distribute 2 or 4 bits each to the output stream! */	rbuf = skb_put(nskb, size);	olen = 0;	sval1 = 8 - v->nbits;	sval2 = v->key << sval1;	for (i = 0; i < mlen; i++) {		v110buf[i] = FlipBits(v110buf[i], v->nbits);		for (j = 0; j < v->nbytes; j++) {			if (size--)				*rbuf++ = ~v->key | (((v110buf[i] << (j * v->nbits)) & sval2) >> sval1);			else {				printk(KERN_WARNING "isdn_v110_encode: buffers full!\n");				goto buffer_full;			}			olen++;		}	}buffer_full:	skb_trim(nskb, olen);	*((int *)skb_push(nskb, sizeof(int))) = rlen;	return nskb;}intisdn_v110_stat_callback(int idx, isdn_ctrl *c){	isdn_v110_stream *v = NULL;	int i;	int ret = 0;	if (idx < 0)		return 0;	switch (c->command) {		case ISDN_STAT_BSENT:                        /* Keep the send-queue of the driver filled			 * with frames:			 * If number of outstanding frames < 3,			 * send down an Idle-Frame (or an Sync-Frame, if			 * v->SyncInit != 0). 			 */			if (!(v = dev->v110[idx]))				return 0;			atomic_inc(&dev->v110use[idx]);			for (i=0; i * v->framelen < c->parm.length; i++) {				if (v->skbidle > 0) {					v->skbidle--;					ret = 1;				} else {					if (v->skbuser > 0)						v->skbuser--;					ret = 0;				}			}			for (i = v->skbuser + v->skbidle; i < 2; i++) {				struct sk_buff *skb;				if (v->SyncInit > 0)					skb = isdn_v110_sync(v);				else					skb = isdn_v110_idle(v);				if (skb) {					if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {						dev_kfree_skb(skb);						break;					} else {						if (v->SyncInit)							v->SyncInit--;						v->skbidle++;					}				} else					break;			}			atomic_dec(&dev->v110use[idx]);			return ret;		case ISDN_STAT_DHUP:		case ISDN_STAT_BHUP:			while (1) {				atomic_inc(&dev->v110use[idx]);				if (atomic_dec_and_test(&dev->v110use[idx])) {					isdn_v110_close(dev->v110[idx]);					dev->v110[idx] = NULL;					break;				}				mdelay(1);			}			break;		case ISDN_STAT_BCONN:			if (dev->v110emu[idx] && (dev->v110[idx] == NULL)) {				int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen;				int maxsize = dev->drv[c->driver]->interface->maxbufsize;				atomic_inc(&dev->v110use[idx]);				switch (dev->v110emu[idx]) {					case ISDN_PROTO_L2_V11096:						dev->v110[idx] = isdn_v110_open(V110_9600, hdrlen, maxsize);						break;					case ISDN_PROTO_L2_V11019:						dev->v110[idx] = isdn_v110_open(V110_19200, hdrlen, maxsize);						break;					case ISDN_PROTO_L2_V11038:						dev->v110[idx] = isdn_v110_open(V110_38400, hdrlen, maxsize);						break;					default:;				}				if ((v = dev->v110[idx])) {					while (v->SyncInit) {						struct sk_buff *skb = isdn_v110_sync(v);						if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {							dev_kfree_skb(skb);							/* Unable to send, try later */							break;						}						v->SyncInit--;						v->skbidle++;					}				} else					printk(KERN_WARNING "isdn_v110: Couldn't open stream for chan %d\n", idx);				atomic_dec(&dev->v110use[idx]);			}			break;		default:			return 0;	}	return 0;}

⌨️ 快捷键说明

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