Ejemplo n.º 1
0
static void update_dahdi_ring(xpd_t *xpd, int pos, bool on)
{
	dahdi_rxsig_t	rxsig;

	BUG_ON(!xpd);
	if(on) {
		if(caller_id_style == CID_STYLE_BELL) {
			LINE_DBG(SIGNAL, xpd, pos, "Caller-ID PCM: off\n");
			BIT_CLR(xpd->cid_on, pos);
		}
		rxsig = DAHDI_RXSIG_RING;
	} else {
		if(caller_id_style == CID_STYLE_BELL) {
			LINE_DBG(SIGNAL, xpd, pos, "Caller-ID PCM: on\n");
			BIT_SET(xpd->cid_on, pos);
		}
		rxsig = DAHDI_RXSIG_OFFHOOK;
	}
	pcm_recompute(xpd, 0);
	/*
	 * We should not spinlock before calling dahdi_hooksig() as
	 * it may call back into our xpp_hooksig() and cause
	 * a nested spinlock scenario
	 */
	if(SPAN_REGISTERED(xpd))
		dahdi_hooksig(&xpd->chans[pos], rxsig);
}
Ejemplo n.º 2
0
/**
 * Prints a general procfs entry for the bus, under xpp/BUSNAME/summary
 * @page TODO: figure out procfs
 * @start TODO: figure out procfs
 * @off TODO: figure out procfs
 * @count TODO: figure out procfs
 * @eof TODO: figure out procfs
 * @data an xbus_t pointer with the bus data.
 */
static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	int		len = 0;
	xpd_t		*xpd = data;
	xbus_t		*xbus;
	int		i;

	if(!xpd)
		goto out;

	xbus = xpd->xbus;
	len += sprintf(page + len, "%s (%s, card %s, span %d)\n"
			"timing_priority: %d\n"
			"timer_count: %d span->mainttimer=%d\n"
			,
			xpd->xpdname, xpd->type_name,
			(xpd->card_present) ? "present" : "missing",
			(SPAN_REGISTERED(xpd)) ? xpd->span.spanno : 0,
			xpd->timing_priority,
			xpd->timer_count, xpd->span.mainttimer
			);
	len += sprintf(page + len, "Address: U=%d S=%d\n", xpd->addr.unit, xpd->addr.subunit);
	len += sprintf(page + len, "Subunits: %d\n", xpd->subunits);
	len += sprintf(page + len, "Type: %d.%d\n\n", xpd->type, xpd->subtype);
	len += sprintf(page + len, "pcm_len=%d\n\n", xpd->pcm_len);
	len += sprintf(page + len, "wanted_pcm_mask=0x%04X\n\n", xpd->wanted_pcm_mask);
	len += sprintf(page + len, "mute_dtmf=0x%04X\n\n", xpd->mute_dtmf);
	len += sprintf(page + len, "STATES:");
	len += sprintf(page + len, "\n\t%-17s: ", "output_relays");
	for_each_line(xpd, i) {
		len += sprintf(page + len, "%d ", IS_SET(xpd->digital_outputs, i));
	}
Ejemplo n.º 3
0
static void xbus_tick(xbus_t *xbus)
{
	int		i;
	xpd_t		*xpd;
	xframe_t	*xframe = NULL;
	xpacket_t	*pack = NULL;
	size_t		pcm_len;
	bool		sent_sync_bit = 0;

	/*
	 * Update zaptel
	 */
	for(i = 0; i < MAX_XPDS; i++) {
		xpd = xpd_of(xbus, i);
		if(xpd && SPAN_REGISTERED(xpd)) {
#ifdef	OPTIMIZE_CHANMUTE
			int		j;
			xpp_line_t	xmit_mask = xpd->wanted_pcm_mask;
			
			xmit_mask |= xpd->silence_pcm;
			xmit_mask |= xpd->digital_signalling;
			for_each_line(xpd, j) {
				xpd->chans[j].chanmute = (optimize_chanmute)
					? !IS_SET(xmit_mask, j)
					: 0;
			}
#endif
			/*
			 * calls to zt_transmit should be out of spinlocks, as it may call back
			 * our hook setting methods.
			 */
			zt_transmit(&xpd->span);
		}
	}
Ejemplo n.º 4
0
/*
 * Generic implementations of card_pcmfromspan()/card_pcmtospan()
 * For FXS/FXO
 */
void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xpacket_t *pack)
{
	byte		*pcm;
	struct zt_chan	*chans;
	unsigned long	flags;
	int		i;

	BUG_ON(!xbus);
	BUG_ON(!xpd);
	BUG_ON(!pack);
	RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
	pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm);
	spin_lock_irqsave(&xpd->lock, flags);
	chans = xpd->span.chans;
	for (i = 0; i < xpd->channels; i++) {
		if(IS_SET(lines, i)) {
			if(SPAN_REGISTERED(xpd)) {
#ifdef	DEBUG_PCMTX
				int     channo = xpd->span.chans[i].channo;

				if(pcmtx >= 0 && pcmtx_chan == channo)
					memset((u_char *)pcm, pcmtx, ZT_CHUNKSIZE);
				else
#endif
					memcpy((u_char *)pcm, chans[i].writechunk, ZT_CHUNKSIZE);
			} else
				memset((u_char *)pcm, 0x7F, ZT_CHUNKSIZE);
			pcm += ZT_CHUNKSIZE;
		}
	}
	XPD_COUNTER(xpd, PCM_WRITE)++;
	spin_unlock_irqrestore(&xpd->lock, flags);
}
Ejemplo n.º 5
0
static DEVICE_ATTR_READER(span_show, dev, buf)
{
	xpd_t *xpd;
	unsigned long flags;
	int len = 0;

	BUG_ON(!dev);
	xpd = dev_to_xpd(dev);
	if (!xpd)
		return -ENODEV;
	spin_lock_irqsave(&xpd->lock, flags);
	len +=
	    sprintf(buf, "%d\n",
		    SPAN_REGISTERED(xpd) ? PHONEDEV(xpd).span.spanno : 0);
	spin_unlock_irqrestore(&xpd->lock, flags);
	return len;
}
Ejemplo n.º 6
0
void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
{
	byte		*pcm;
	xpp_line_t	pcm_mask;
	xpp_line_t	pcm_mute;
	unsigned long	flags;
	int		i;

	pcm = RPACKET_FIELD(pack, GLOBAL, PCM_READ, pcm);
	pcm_mask = RPACKET_FIELD(pack, GLOBAL, PCM_READ, lines);
	spin_lock_irqsave(&xpd->lock, flags);
	/*
	 * Calculate the channels we want to mute
	 */
	pcm_mute = ~xpd->wanted_pcm_mask;
	pcm_mute |= xpd->mute_dtmf | xpd->silence_pcm;
	if(!SPAN_REGISTERED(xpd))
		goto out;
	for (i = 0; i < xpd->channels; i++) {
		volatile u_char	*r = xpd->span.chans[i].readchunk;
		bool		got_data = IS_SET(pcm_mask, i);

		if(got_data && !IS_SET(pcm_mute, i)) {
			/* We have and want real data */
			// memset((u_char *)r, 0x5A, ZT_CHUNKSIZE);	// DEBUG
			memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
		} else if(IS_SET(xpd->wanted_pcm_mask | xpd->silence_pcm, i)) {
			/* Inject SILENCE */
			memset((u_char *)r, 0x7F, ZT_CHUNKSIZE);
			if(IS_SET(xpd->silence_pcm, i)) {
				/*
				 * This will clear the EC buffers until next tick
				 * So we don't have noise residues from the past.
				 */
				memset(xpd->ec_chunk2[i], 0x7F, ZT_CHUNKSIZE);
				memset(xpd->ec_chunk1[i], 0x7F, ZT_CHUNKSIZE);
			}
		}
		if(got_data)
			pcm += ZT_CHUNKSIZE;
	}
out:
	XPD_COUNTER(xpd, PCM_READ)++;
	spin_unlock_irqrestore(&xpd->lock, flags);
}
Ejemplo n.º 7
0
static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe)
{
	byte		*xframe_end;
	xpacket_t	*pack;
	byte		*p;
	int		ret = -EPROTO;	/* Assume error */

	if(debug & DBG_PCM)
		dump_xframe("RX_XFRAME_PCM", xbus, xframe, debug);
	/* handle content */

	p = xframe->packets;
	xframe_end = p + XFRAME_LEN(xframe);
	do {
		int		len;
		xpd_t		*xpd;

		pack = (xpacket_t *)p;
		len = XPACKET_LEN(pack);
		/* Sanity checks */
		if(unlikely(XPACKET_OP(pack) != XPROTO_NAME(GLOBAL,PCM_READ))) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_NOTICE(xbus,
					"%s: Non-PCM packet within a PCM xframe. (%d)\n",
					__FUNCTION__, rate_limit);
				dump_xframe("In PCM xframe", xbus, xframe, debug);
			}
			goto out;
		}
		p += len;
		if(p > xframe_end || len < RPACKET_HEADERSIZE) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_NOTICE(xbus,
					"%s: Invalid packet length %d. (%d)\n",
					__FUNCTION__, len, rate_limit);
				dump_xframe("BAD LENGTH", xbus, xframe, debug);
			}
			goto out;
		}
		xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
		if(unlikely(!xpd)) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), "RECEIVE PCM");
				dump_xframe("Unknown XPD addr", xbus, xframe, debug);
			}
			goto out;
		}
		if(!pcm_valid(xpd, pack))
			goto out;
		if(SPAN_REGISTERED(xpd)) {
			XBUS_COUNTER(xbus, RX_PACK_PCM)++;
			CALL_XMETHOD(card_pcm_tospan, xbus, xpd, pack);
		}
	} while(p < xframe_end);
	ret = 0;	/* all good */
	XBUS_COUNTER(xbus, RX_XFRAME_PCM)++;
out:
	FREE_RECV_XFRAME(xbus, xframe);
	return ret;
}