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

📄 zaptel.c

📁 This a SOFTWARE pbx DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
			len += sprintf(page + len, "CCS");		/* E1's can enable CRC checking */		if (spans[span]->lineconfig & ZT_CONFIG_CRC4)			len += sprintf(page + len, "/CRC4");	}	len += sprintf(page + len, " ");	/* list alarms */	if (spans[span]->alarms && (spans[span]->alarms > 0)) {		if (spans[span]->alarms & ZT_ALARM_BLUE)			len += sprintf(page + len, "BLUE ");		if (spans[span]->alarms & ZT_ALARM_YELLOW)			len += sprintf(page + len, "YELLOW ");		if (spans[span]->alarms & ZT_ALARM_RED)			len += sprintf(page + len, "RED ");		if (spans[span]->alarms & ZT_ALARM_LOOPBACK)			len += sprintf(page + len, "LOOP ");		if (spans[span]->alarms & ZT_ALARM_RECOVER)			len += sprintf(page + len, "RECOVERING ");		if (spans[span]->alarms & ZT_ALARM_NOTOPEN)			len += sprintf(page + len, "NOTOPEN ");						}	if (spans[span]->syncsrc && (spans[span]->syncsrc == spans[span]->spanno))		len += sprintf(page + len, "ClockSource ");	len += sprintf(page + len, "\n");	if (spans[span]->bpvcount)		len += sprintf(page + len, "\tBPV count: %d\n", spans[span]->bpvcount);	if (spans[span]->crc4count)		len += sprintf(page + len, "\tCRC4 error count: %d\n", spans[span]->crc4count);	if (spans[span]->ebitcount)		len += sprintf(page + len, "\tE-bit error count: %d\n", spans[span]->ebitcount);	if (spans[span]->fascount)		len += sprintf(page + len, "\tFAS error count: %d\n", spans[span]->fascount);	if (spans[span]->irqmisses)		len += sprintf(page + len, "\tIRQ misses: %d\n", spans[span]->irqmisses);	len += sprintf(page + len, "\n");        for (x=1;x<ZT_MAX_CHANNELS;x++) {			if (chans[x]) {			if (chans[x]->span && (chans[x]->span->spanno == span)) {				if (chans[x]->name)					len += sprintf(page + len, "\t%4d %s ", x, chans[x]->name);				if (chans[x]->sig) {					if (chans[x]->sig == ZT_SIG_SLAVE)						len += sprintf(page + len, "%s ", sigstr(chans[x]->master->sig));					else {						len += sprintf(page + len, "%s ", sigstr(chans[x]->sig));						if (chans[x]->nextslave && chans[x]->master->channo == x)							len += sprintf(page + len, "Master ");					}			}			if ((chans[x]->flags & ZT_FLAG_OPEN)) {				len += sprintf(page + len, "(In use) ");			}			len += sprintf(page + len, "\n");			}		}	}	return len;}#endifstatic int zt_first_empty_alias(void){	/* Find the first conference which has no alias pointing to it */	int x;	for (x=1;x<ZT_MAX_CONF;x++) {		if (!confrev[x])			return x;	}	return -1;}static void recalc_maxconfs(void){	int x;	for (x=ZT_MAX_CONF-1;x>0;x--) {		if (confrev[x]) {			maxconfs = x+1;			return;		}	}	maxconfs = 0;}static void recalc_maxlinks(void){	int x;	for (x=ZT_MAX_CONF-1;x>0;x--) {		if (conf_links[x].src || conf_links[x].dst) {			maxlinks = x+1;			return;		}	}	maxlinks = 0;}static int zt_first_empty_conference(void){	/* Find the first conference which has no alias */	int x;	for (x=ZT_MAX_CONF-1;x>0;x--) {		if (!confalias[x])			return x;	}	return -1;}static int zt_get_conf_alias(int x){	int a;	if (confalias[x]) {		return confalias[x];	}	/* Allocate an alias */	a = zt_first_empty_alias();	confalias[x] = a;	confrev[a] = x;	/* Highest conference may have changed */	recalc_maxconfs();	return a;}static void zt_check_conf(int x){	int y;	/* return if no valid conf number */	if (x <= 0) return;	/* Return if there is no alias */	if (!confalias[x])		return;	for (y=0;y<maxchans;y++) {		if (chans[y] && (chans[y]->confna == x) && (chans[y]->confmode & (ZT_CONF_CONF | ZT_CONF_CONFANN | ZT_CONF_CONFMON | ZT_CONF_CONFANNMON | ZT_CONF_REALANDPSEUDO)))			return;	}	/* If we get here, nobody is in the conference anymore.  Clear it out	   both forward and reverse */	confrev[confalias[x]] = 0;	confalias[x] = 0;	/* Highest conference may have changed */	recalc_maxconfs();}/* enqueue an event on a channel */static void __qevent(struct zt_chan *chan, int event){	  /* if full, ignore */	if ((chan->eventoutidx == 0) && (chan->eventinidx == (ZT_MAX_EVENTSIZE - 1))) 		return;	  /* if full, ignore */	if (chan->eventinidx == (chan->eventoutidx - 1)) return;	  /* save the event */	chan->eventbuf[chan->eventinidx++] = event;	  /* wrap the index, if necessary */	if (chan->eventinidx >= ZT_MAX_EVENTSIZE) chan->eventinidx = 0;	  /* wake em all up */	if (chan->iomask & ZT_IOMUX_SIGEVENT) wake_up_interruptible(&chan->eventbufq);	wake_up_interruptible(&chan->readbufq);	wake_up_interruptible(&chan->writebufq);	wake_up_interruptible(&chan->sel);	return;}void zt_qevent_nolock(struct zt_chan *chan, int event){	__qevent(chan, event);}void zt_qevent_lock(struct zt_chan *chan, int event){	unsigned long flags;	spin_lock_irqsave(&chan->lock, flags);	__qevent(chan, event);	spin_unlock_irqrestore(&chan->lock, flags);}/* sleep in user space until woken up. Equivilant of tsleep() in BSD */static int schluffen(wait_queue_head_t *q){	DECLARE_WAITQUEUE(wait, current);	add_wait_queue(q, &wait);	current->state = TASK_INTERRUPTIBLE;	if (!signal_pending(current)) schedule();	current->state = TASK_RUNNING;	remove_wait_queue(q, &wait);	if (signal_pending(current)) return -ERESTARTSYS;	return(0);}static inline void calc_fcs(struct zt_chan *ss){	int x;	unsigned int fcs=PPP_INITFCS;	unsigned char *data = ss->writebuf[ss->inwritebuf];	int len = ss->writen[ss->inwritebuf];	/* Not enough space to do FCS calculation */	if (len < 2)		return;	for (x=0;x<len-2;x++)		fcs = PPP_FCS(fcs, data[x]);	fcs ^= 0xffff;	/* Send out the FCS */	data[len-2] = (fcs & 0xff);	data[len-1] = (fcs >> 8) & 0xff;}static int zt_reallocbufs(struct zt_chan *ss, int j, int numbufs){	unsigned char *newbuf, *oldbuf;	unsigned long flags;	int x;	/* Check numbufs */	if (numbufs < 2)		numbufs = 2;	if (numbufs > ZT_MAX_NUM_BUFS)		numbufs = ZT_MAX_NUM_BUFS;	/* We need to allocate our buffers now */	if (j) {		newbuf = kmalloc(j * 2 * numbufs, GFP_KERNEL);		if (!newbuf) 			return (-ENOMEM);	} else		newbuf = NULL;	  /* Now that we've allocated our new buffer, we can safely	     move things around... */	spin_lock_irqsave(&ss->lock, flags);	ss->blocksize = j; /* set the blocksize */	oldbuf = ss->readbuf[0]; /* Keep track of the old buffer */	ss->readbuf[0] = NULL;	if (newbuf) {		for (x=0;x<numbufs;x++) {			ss->readbuf[x] = newbuf + x * j;			ss->writebuf[x] = newbuf + (numbufs + x) * j;		}	} else {		for (x=0;x<numbufs;x++) {			ss->readbuf[x] = NULL;			ss->writebuf[x] = NULL;		}	}	/* Mark all buffers as empty */	for (x=0;x<numbufs;x++) 		ss->writen[x] = 		ss->writeidx[x]=		ss->readn[x]=		ss->readidx[x] = 0;		/* Keep track of where our data goes (if it goes	   anywhere at all) */	if (newbuf) {		ss->inreadbuf = 0;		ss->inwritebuf = 0;	} else {		ss->inreadbuf = -1;		ss->inwritebuf = -1;	}	ss->outreadbuf = -1;	ss->outwritebuf = -1;	ss->numbufs = numbufs;	if (ss->txbufpolicy == ZT_POLICY_WHEN_FULL)		ss->txdisable = 1;	else		ss->txdisable = 0;	if (ss->rxbufpolicy == ZT_POLICY_WHEN_FULL)		ss->rxdisable = 1;	else		ss->rxdisable = 0;	spin_unlock_irqrestore(&ss->lock, flags);	if (oldbuf)		kfree(oldbuf);	return 0;}static int zt_hangup(struct zt_chan *chan);static void zt_set_law(struct zt_chan *chan, int law);/* Pull a ZT_CHUNKSIZE piece off the queue.  Returns   0 on success or -1 on failure.  If failed, provides   silence */static int __buf_pull(struct confq *q, u_char *data, struct zt_chan *c, char *label){	int oldoutbuf = q->outbuf;	/* Ain't nuffin to read */	if (q->outbuf < 0) {		if (data)			memset(data, ZT_LIN2X(0,c), ZT_CHUNKSIZE);		return -1;	}	if (data)		memcpy(data, q->buf[q->outbuf], ZT_CHUNKSIZE);	q->outbuf = (q->outbuf + 1) % ZT_CB_SIZE;	/* Won't be nuffin next time */	if (q->outbuf == q->inbuf) {		q->outbuf = -1;	}	/* If they thought there was no space then	   there is now where we just read */	if (q->inbuf < 0) 		q->inbuf = oldoutbuf;	return 0;}/* Returns a place to put stuff, or NULL if there is   no room */static u_char *__buf_pushpeek(struct confq *q){	if (q->inbuf < 0)		return NULL;	return q->buf[q->inbuf];}static u_char *__buf_peek(struct confq *q){	if (q->outbuf < 0)		return NULL;	return q->buf[q->outbuf];}#ifdef BUF_MUNGEstatic u_char *__buf_cpush(struct confq *q){	int pos;	/* If we have no space, return where the	   last space that we *did* have was */	if (q->inbuf > -1)		return NULL;	pos = q->outbuf - 1;	if (pos < 0)		pos += ZT_CB_SIZE;	return q->buf[pos];}static void __buf_munge(struct zt_chan *chan, u_char *old, u_char *new){	/* Run a weighted average of the old and new, in order to	   mask a missing sample */	int x;	int val;	for (x=0;x<ZT_CHUNKSIZE;x++) {		val = x * ZT_XLAW(new[x], chan) + (ZT_CHUNKSIZE - x - 1) * ZT_XLAW(old[x], chan);		val = val / (ZT_CHUNKSIZE - 1);		old[x] = ZT_LIN2X(val, chan);	}}#endif/* Push something onto the queue, or assume what   is there is valid if data is NULL */static int __buf_push(struct confq *q, u_char *data, char *label){	int oldinbuf = q->inbuf;	if (q->inbuf < 0) {		return -1;	}	if (data)		/* Copy in the data */		memcpy(q->buf[q->inbuf], data, ZT_CHUNKSIZE);	/* Advance the inbuf pointer */	q->inbuf = (q->inbuf + 1) % ZT_CB_SIZE;	if (q->inbuf == q->outbuf) {		/* No space anymore... */			q->inbuf = -1;	}	/* If they don't think data is ready, let	   them know it is now */	if (q->outbuf < 0) {		q->outbuf = oldinbuf;	}	return 0;}static void reset_conf(struct zt_chan *chan){	int x;	/* Empty out buffers and reset to initialization */	for (x=0;x<ZT_CB_SIZE;x++)		chan->confin.buf[x] = chan->confin.buffer + ZT_CHUNKSIZE * x;	chan->confin.inbuf = 0;	chan->confin.outbuf = -1;	for (x=0;x<ZT_CB_SIZE;x++)		chan->confout.buf[x] = chan->confout.buffer + ZT_CHUNKSIZE * x;	chan->confout.inbuf = 0;	chan->confout.outbuf = -1;}static void close_channel(struct zt_chan *chan){	unsigned long flags;	void *rxgain = NULL;	echo_can_state_t *ec = NULL;	int oldconf;#ifdef CONFIG_ZAPATA_PPP	struct ppp_channel *ppp;#endif	zt_reallocbufs(chan, 0, 0); 	spin_lock_irqsave(&chan->lock, flags);#ifdef CONFIG_ZAPATA_PPP	ppp = chan->ppp;	chan->ppp = NULL;#endif	ec = chan->ec;	chan->ec = NULL;	chan->curtone = NULL;	chan->curzone = NULL;	chan->cadencepos = 0;	chan->pdialcount = 0;	zt_hangup(chan); 	chan->itimerset = chan->itimer = 0;	chan->pulsecount = 0;	chan->pulsetimer = 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);	chan->txdialbuf[0] = '\0';	chan->digitmode = DIGIT_MODE_DTMF;	chan->dialing = 0;	chan->afterdialingtimer = 0;	  /* initialize IO MUX mask */	chan->iomask = 0;	/* save old conf number, if any */	oldconf = chan->confna;	  /* initialize conference variables */	chan->_confn = 0;	if ((chan->sig & __ZT_SIG_DACS) != __ZT_SIG_DACS) {		chan->confna = 0;		chan->confmode = 0;	}	chan->confmute = 0;	/* release conference resource, if any to release */	if (oldconf) zt_check_conf(oldconf);	chan->gotgs = 0;	reset_conf(chan);		if (chan->gainalloc && chan->rxgain)		rxgain = chan->rxgain;	chan->rxgain = defgain;	chan->txgain = defgain;	chan->gainalloc = 0;	chan->eventinidx = chan->eventoutidx = 0;	chan->flags &= ~(ZT_FLAG_LINEAR | ZT_FLAG_PPP | ZT_FLAG_SIGFREEZE);	zt_set_law(chan,0);	memset(chan->conflast, 0, sizeof(chan->conflast));	memset(chan->conflast1, 0, sizeof(chan->conflast1));	memset(chan->conflast2, 0, sizeof(chan->conflast2));	spin_unlock_irqrestore(&chan->lock, flags);	if (rxgain)		kfree(rxgain);	if (ec)		echo_can_free(ec);#ifdef CONFIG_ZAPATA_PPP	if (ppp) {		tasklet_kill(&chan->ppp_calls);		skb_queue_purge(&chan->ppp_rq);		ppp_unregister_channel(ppp);		kfree(ppp);	}#endif}static int tone_zone_init(void){	int x;	for (x=0;x<ZT_TONE_ZONE_MAX;x++)

⌨️ 快捷键说明

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