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

📄 zaptel.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
	chan->cadencepos = 0;	chan->txdialbuf[0] = 0;	return res;}static int initialize_channel(struct zt_chan *chan){	int res;	unsigned long flags;	void *rxgain=NULL;	echo_can_state_t *ec=NULL;	if ((res = zt_reallocbufs(chan, ZT_DEFAULT_BLOCKSIZE, ZT_DEFAULT_NUM_BUFS)))		return res;	spin_lock_irqsave(&chan->lock, flags);	chan->rxbufpolicy = ZT_POLICY_IMMEDIATE;	chan->txbufpolicy = ZT_POLICY_IMMEDIATE;	/* Free up the echo canceller if there is one */	ec = chan->ec;	chan->ec = NULL;	chan->echocancel = 0;	chan->echostate = ECHO_STATE_IDLE;	chan->echolastupdate = 0;	chan->echotimer = 0;	chan->txdisable = 0;	chan->rxdisable = 0;	chan->digitmode = DIGIT_MODE_DTMF;	chan->dialing = 0;	chan->afterdialingtimer = 0;	chan->cadencepos = 0;	chan->firstcadencepos = 0; /* By default loop back to first cadence position */	/* HDLC & FCS stuff */	fasthdlc_init(&chan->rxhdlc);	fasthdlc_init(&chan->txhdlc);	chan->infcs = PPP_INITFCS;		/* Timings for RBS */	chan->prewinktime = ZT_DEFAULT_PREWINKTIME;	chan->preflashtime = ZT_DEFAULT_PREFLASHTIME;	chan->winktime = ZT_DEFAULT_WINKTIME;	chan->flashtime = ZT_DEFAULT_FLASHTIME;		if (chan->sig & __ZT_SIG_FXO)		chan->starttime = ZT_DEFAULT_RINGTIME;	else		chan->starttime = ZT_DEFAULT_STARTTIME;	chan->rxwinktime = ZT_DEFAULT_RXWINKTIME;	chan->rxflashtime = ZT_DEFAULT_RXFLASHTIME;	chan->debouncetime = ZT_DEFAULT_DEBOUNCETIME;	chan->pulsemaketime = ZT_DEFAULT_PULSEMAKETIME;	chan->pulsebreaktime = ZT_DEFAULT_PULSEBREAKTIME;	chan->pulseaftertime = ZT_DEFAULT_PULSEAFTERTIME;		/* Initialize RBS timers */	chan->itimerset = chan->itimer = chan->otimer = 0;	chan->ringdebtimer = 0;			init_waitqueue_head(&chan->sel);	init_waitqueue_head(&chan->readbufq);	init_waitqueue_head(&chan->writebufq);	init_waitqueue_head(&chan->eventbufq);	init_waitqueue_head(&chan->txstateq);	/* Reset conferences */	reset_conf(chan);		/* I/O Mask, etc */	chan->iomask = 0;	/* release conference resource if any */	if (chan->confna) zt_check_conf(chan->confna);	if ((chan->sig & __ZT_SIG_DACS) != __ZT_SIG_DACS) {		chan->confna = 0;		chan->confmode = 0;	}	chan->_confn = 0;	memset(chan->conflast, 0, sizeof(chan->conflast));	memset(chan->conflast1, 0, sizeof(chan->conflast1));	memset(chan->conflast2, 0, sizeof(chan->conflast2));	chan->confmute = 0;	chan->gotgs = 0;	chan->curtone = NULL;	chan->tonep = 0;	chan->pdialcount = 0;	set_tone_zone(chan, -1);	if (chan->gainalloc && chan->rxgain)		rxgain = chan->rxgain;	chan->rxgain = defgain;	chan->txgain = defgain;	chan->gainalloc = 0;	chan->eventinidx = chan->eventoutidx = 0;	zt_set_law(chan,0);	zt_hangup(chan);	/* Make sure that the audio flag is cleared on a clear channel */		if (chan->sig & ZT_SIG_CLEAR) 		chan->flags &= ~ZT_FLAG_AUDIO;	if (chan->sig == ZT_SIG_CLEAR)		chan->flags &= ~(ZT_FLAG_PPP | ZT_FLAG_FCS | ZT_FLAG_HDLC);	chan->flags &= ~ZT_FLAG_LINEAR;	if (chan->curzone) {		/* Take cadence from tone zone */		memcpy(chan->ringcadence, chan->curzone->ringcadence, sizeof(chan->ringcadence));	} else {		/* Do a default */		memset(chan->ringcadence, 0, sizeof(chan->ringcadence));		chan->ringcadence[0] = chan->starttime;		chan->ringcadence[1] = ZT_RINGOFFTIME;	}	spin_unlock_irqrestore(&chan->lock, flags);	if (rxgain)		kfree(rxgain);	if (ec)		echo_can_free(ec);	return 0;}static int zt_timing_open(struct inode *inode, struct file *file){	struct zt_timer *t;	unsigned long flags;	t = kmalloc(sizeof(struct zt_timer), GFP_KERNEL);	if (!t)		return -ENOMEM;	/* Allocate a new timer */	memset(t, 0, sizeof(struct zt_timer));	init_waitqueue_head(&t->sel);	file->private_data = t;#ifndef LINUX26	MOD_INC_USE_COUNT;#endif	spin_lock_irqsave(&zaptimerlock, flags);	t->next = zaptimers;	zaptimers = t;	spin_unlock_irqrestore(&zaptimerlock, flags);	return 0;}static int zt_timer_release(struct inode *inode, struct file *file){	struct zt_timer *t, *cur, *prev;	unsigned long flags;	t = file->private_data;	if (t) {		spin_lock_irqsave(&zaptimerlock, flags);		prev = NULL;		cur = zaptimers;		while(cur) {			if (t == cur)				break;			prev = cur;			cur = cur->next;		}		if (cur) {			if (prev)				prev->next = cur->next;			else				zaptimers = cur->next;		}		spin_unlock_irqrestore(&zaptimerlock, flags);		if (!cur) {			printk("Zap Timer: Not on list??\n");			return 0;		}		kfree(t);#ifndef LINUX26		MOD_DEC_USE_COUNT;#endif			}	return 0;}static int zt_specchan_open(struct inode *inode, struct file *file, int unit, int inc){	int res = 0;	if (chans[unit] && chans[unit]->sig) {		/* Make sure we're not already open, a net device, or a slave device */		if (chans[unit]->flags & ZT_FLAG_OPEN) 			res = -EBUSY;		else if (chans[unit]->flags & ZT_FLAG_NETDEV)			res = -EBUSY;		else if (chans[unit]->master != chans[unit])			res = -EBUSY;		else if ((chans[unit]->sig & __ZT_SIG_DACS) == __ZT_SIG_DACS)			res = -EBUSY;		else {			/* Assume everything is going to be okay */			res = initialize_channel(chans[unit]);			if (chans[unit]->flags & ZT_FLAG_PSEUDO) 				chans[unit]->flags |= ZT_FLAG_AUDIO;			if (chans[unit]->span && chans[unit]->span->open)				res = chans[unit]->span->open(chans[unit]);			if (!res) {				chans[unit]->file = file;#ifndef LINUX26				if (inc)					MOD_INC_USE_COUNT;#endif									chans[unit]->flags |= ZT_FLAG_OPEN;			} else {				close_channel(chans[unit]);			}		}	} else		res = -ENXIO;	return res;}static int zt_specchan_release(struct inode *node, struct file *file, int unit){	int res=0;	if (chans[unit]) {		chans[unit]->flags &= ~ZT_FLAG_OPEN;		chans[unit]->file = NULL;		close_channel(chans[unit]);		if (chans[unit]->span && chans[unit]->span->close)			res = chans[unit]->span->close(chans[unit]);	} else		res = -ENXIO;#ifndef LINUX26	MOD_DEC_USE_COUNT;#endif	return res;}static struct zt_chan *zt_alloc_pseudo(void){	struct zt_chan *pseudo;	unsigned long flags;	/* Don't allow /dev/zap/pseudo to open if there are no spans */	if (maxspans < 1)		return NULL;	pseudo = kmalloc(sizeof(struct zt_chan), GFP_KERNEL);	if (!pseudo)		return NULL;	memset(pseudo, 0, sizeof(struct zt_chan));	pseudo->sig = ZT_SIG_CLEAR;	pseudo->sigcap = ZT_SIG_CLEAR;	pseudo->flags = ZT_FLAG_PSEUDO | ZT_FLAG_AUDIO;	spin_lock_irqsave(&bigzaplock, flags);	if (zt_chan_reg(pseudo)) {		kfree(pseudo);		pseudo = NULL;	} else		sprintf(pseudo->name, "Pseudo/%d", pseudo->channo);	spin_unlock_irqrestore(&bigzaplock, flags);	return pseudo;	}static void zt_free_pseudo(struct zt_chan *pseudo){	unsigned long flags;	if (pseudo) {		spin_lock_irqsave(&bigzaplock, flags);		zt_chan_unreg(pseudo);		spin_unlock_irqrestore(&bigzaplock, flags);		kfree(pseudo);	}}static int zt_open(struct inode *inode, struct file *file){	int unit = UNIT(file);	struct zt_chan *chan;	/* Minor 0: Special "control" descriptor */	if (!unit) 		return zt_ctl_open(inode, file);	if (unit == 253) {		if (maxspans) {			return zt_timing_open(inode, file);		} else {			return -ENXIO;		}	}	if (unit == 254)		return zt_chan_open(inode, file);	if (unit == 255) {		if (maxspans) {			chan = zt_alloc_pseudo();			if (chan) {				file->private_data = chan;				return zt_specchan_open(inode, file, chan->channo, 1);			} else {				return -ENXIO;			}		} else			return -ENXIO;	}	return zt_specchan_open(inode, file, unit, 1);}#if 0static int zt_open(struct inode *inode, struct file *file){	int res;	unsigned long flags;	spin_lock_irqsave(&bigzaplock, flags);	res = __zt_open(inode, file);	spin_unlock_irqrestore(&bigzaplock, flags);	return res;}#endifstatic ssize_t zt_read(struct file *file, char *usrbuf, size_t count, loff_t *ppos){	int unit = UNIT(file);	struct zt_chan *chan;	/* Can't read from control */	if (!unit) {		return -EINVAL;	}		if (unit == 253) 		return -EINVAL;		if (unit == 254) {		chan = file->private_data;		if (!chan)			return -EINVAL;		return zt_chan_read(file, usrbuf, count, chan->channo);	}		if (unit == 255) {		chan = file->private_data;		if (!chan) {			printk("No pseudo channel structure to read?\n");			return -EINVAL;		}		return zt_chan_read(file, usrbuf, count, chan->channo);	}	if (count < 0)		return -EINVAL;	return zt_chan_read(file, usrbuf, count, unit);}static ssize_t zt_write(struct file *file, const char *usrbuf, size_t count, loff_t *ppos){	int unit = UNIT(file);	struct zt_chan *chan;	/* Can't read from control */	if (!unit)		return -EINVAL;	if (count < 0)		return -EINVAL;	if (unit == 253)		return -EINVAL;	if (unit == 254) {		chan = file->private_data;		if (!chan)			return -EINVAL;		return zt_chan_write(file, usrbuf, count, chan->channo);	}	if (unit == 255) {		chan = file->private_data;		if (!chan) {			printk("No pseudo channel structure to read?\n");			return -EINVAL;		}		return zt_chan_write(file, usrbuf, count, chan->channo);	}	return zt_chan_write(file, usrbuf, count, unit);	}/* No bigger than 32k for everything per tone zone */#define MAX_SIZE 32768/* No more than 64 subtones */#define MAX_TONES 64static intioctl_load_zone(unsigned long data){	struct zt_tone *samples[MAX_TONES];	short next[MAX_TONES];	struct zt_tone_def_header th;	void *slab, *ptr;	long size;	struct zt_zone *z;	struct zt_tone_def td;	struct zt_tone *t;	int x;	int space;	int res;		/* XXX Unnecessary XXX */	memset(samples, 0, sizeof(samples));	/* XXX Unnecessary XXX */	memset(next, 0, sizeof(next));	copy_from_user(&th, (struct zt_tone_def_header *)data, sizeof(th));	if ((th.count < 0) || (th.count > MAX_TONES)) {		printk("Too many tones included\n");		return -EINVAL;	}	space = size = sizeof(struct zt_zone) +			th.count * sizeof(struct zt_tone);	if ((size > MAX_SIZE) || (size < 0))		return -E2BIG;	ptr = slab = (char *)kmalloc(size, GFP_KERNEL);	if (!slab)		return -ENOMEM;	/* Zero it out for simplicity */	memset(slab, 0, size);	/* Grab the zone */	z = (struct zt_zone *)slab;	strncpy(z->name, th.name, sizeof(z->name) - 1);	for (x=0;x<ZT_MAX_CADENCE;x++)		z->ringcadence[x] = th.ringcadence[x];	data += sizeof(struct zt_tone_def_header);	ptr += sizeof(struct zt_zone);	space -= sizeof(struct zt_zone);	for (x=0;x<th.count;x++) {		if (space < sizeof(struct zt_tone)) {			/* Check space for zt_tone struct */			kfree(slab);			printk("Insufficient tone zone space\n");			return -EINVAL;		}		if (copy_from_user(&td, (struct zt_tone_def *)data, sizeof(struct zt_tone_def))) {			kfree(slab);			return -EIO;		}		/* Index the current sample */		samples[x] = t = (struct zt_tone *)ptr;		/* Remember which sample is next */		next[x] = td.next;		/* Make sure the "next" one is sane */		if ((next[x] >= th.count) || (next[x] < 0)) {			printk("Invalid 'next' pointer\n");			kfree(slab);			return -EINVAL;		}		if (td.tone >= ZT_TONE_MAX) {			printk("Too many tones defined\n");			/* Make sure it's sane */			kfree(slab);			return -EINVAL;		}		/* Update pointers to account for zt_tone header */		space -= sizeof(struct zt_tone);		ptr += sizeof(struct zt_tone);		data += sizeof(struct zt_tone_def);		/* Fill in tonedata, datalen, and tonesamples fields */		t->tonesamples = td.samples;		t->fac1 = td.fac1;		t->init_v2_1 = td.init_v2_1;		t->init_v3_1 = td.init_v3_1;		t->fac2 = td.fac2;		t->init_v2_2 = td.init_v2_2;		t->init_v3_2 = td.init_v3_2;		t->modulate = td.modulate;		t->next = NULL;					/* XXX Unnecessary XXX */		if (!z->tones[td.tone])			z->tones[td.tone] = t;	}	for (x=0;x<th.count;x++) 		/* Set "next" pointers */		samples[x]->next = samples[next[x]];	/* Actually register zone */	res = zt_register_tone_zone(th.zone, z);	if (res)		kfree(slab);	return res;}void zt_init_tone_state(struct zt_tone_state *ts, struct zt_tone *zt){	ts->v1_1 = 0;	ts->v2_1 = zt->init_v2_1;	ts->v3_1 = zt->init_v3_1;	ts->v1_2 = 0;	ts->v2_2 = zt->init_v2_2;	ts->v3_2 = zt->init_v3_2;	ts->modulate = zt->modulate;}struc

⌨️ 快捷键说明

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