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

📄 chan_dahdi.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (chan) {		if (ioctl(fd, DAHDI_SPECIFY, &chan)) {			x = errno;			close(fd);			errno = x;			ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));			return -1;		}	}	bs = READ_SIZE;	if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {		ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));		x = errno;		close(fd);		errno = x;		return -1;	}	return fd;}static void dahdi_close(int fd){	if (fd > 0)		close(fd);}static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num){	dahdi_close(chan_pvt->subs[sub_num].dfd);	chan_pvt->subs[sub_num].dfd = -1;} #ifdef HAVE_PRIstatic void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num){	dahdi_close(pri->fds[fd_num]);	pri->fds[fd_num] = -1;}#endifstatic int dahdi_setlinear(int dfd, int linear){	int res;	res = ioctl(dfd, DAHDI_SETLINEAR, &linear);	if (res)		return res;	return 0;}static int alloc_sub(struct dahdi_pvt *p, int x){	struct dahdi_bufferinfo bi;	int res;	if (p->subs[x].dfd < 0) {#ifdef HAVE_ZAPTEL		p->subs[x].dfd = dahdi_open("/dev/zap/pseudo");#else		p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");#endif		if (p->subs[x].dfd > -1) {			res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);			if (!res) {				bi.txbufpolicy = p->buf_policy;				bi.rxbufpolicy = p->buf_policy;				bi.numbufs = p->buf_no;				res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);				if (res < 0) {					ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));				}			} else 				ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));			if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {				ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));				dahdi_close_sub(p, x);				return -1;			}			if (option_debug)				ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);			return 0;		} else			ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));		return -1;	}	ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);	return -1;}static int unalloc_sub(struct dahdi_pvt *p, int x){	if (!x) {		ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);		return -1;	}	ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);	dahdi_close_sub(p, x);	p->subs[x].linear = 0;	p->subs[x].chan = 0;	p->subs[x].owner = NULL;	p->subs[x].inthreeway = 0;	p->polarity = POLARITY_IDLE;	memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));	return 0;}static int digit_to_dtmfindex(char digit){	if (isdigit(digit))		return DAHDI_TONE_DTMF_BASE + (digit - '0');	else if (digit >= 'A' && digit <= 'D')		return DAHDI_TONE_DTMF_A + (digit - 'A');	else if (digit >= 'a' && digit <= 'd')		return DAHDI_TONE_DTMF_A + (digit - 'a');	else if (digit == '*')		return DAHDI_TONE_DTMF_s;	else if (digit == '#')		return DAHDI_TONE_DTMF_p;	else		return -1;}static int dahdi_digit_begin(struct ast_channel *chan, char digit){	struct dahdi_pvt *pvt;	int index;	int dtmf = -1;		pvt = chan->tech_pvt;	ast_mutex_lock(&pvt->lock);	index = dahdi_get_index(chan, pvt, 0);	if ((index != SUB_REAL) || !pvt->owner)		goto out;#ifdef HAVE_PRI	if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {		if (pvt->setup_ack) {			if (!pri_grab(pvt, pvt->pri)) {				pri_information(pvt->pri->pri, pvt->call, digit);				pri_rel(pvt->pri);			} else				ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);		} else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {			int res;			ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);			res = strlen(pvt->dialdest);			pvt->dialdest[res++] = digit;			pvt->dialdest[res] = '\0';		}		goto out;	}#endif	if ((dtmf = digit_to_dtmfindex(digit)) == -1)		goto out;	if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {		int res;		struct dahdi_dialoperation zo = {			.op = DAHDI_DIAL_OP_APPEND,			.dialstr[0] = 'T',			.dialstr[1] = digit,			.dialstr[2] = 0,		};		if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo)))			ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno));		else			pvt->dialing = 1;	} else {		ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);		pvt->dialing = 1;		pvt->begindigit = digit;	}out:	ast_mutex_unlock(&pvt->lock);	return 0;}static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration){	struct dahdi_pvt *pvt;	int res = 0;	int index;	int x;		pvt = chan->tech_pvt;	ast_mutex_lock(&pvt->lock);		index = dahdi_get_index(chan, pvt, 0);	if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)		goto out;#ifdef HAVE_PRI	/* This means that the digit was already sent via PRI signalling */	if (pvt->sig == SIG_PRI && !pvt->begindigit)		goto out;#endif	if (pvt->begindigit) {		x = -1;		ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);		res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);		pvt->dialing = 0;		pvt->begindigit = 0;	}out:	ast_mutex_unlock(&pvt->lock);	return res;}static char *events[] = {	"No event",	"On hook",	"Ring/Answered",	"Wink/Flash",	"Alarm",	"No more alarm",	"HDLC Abort",	"HDLC Overrun",	"HDLC Bad FCS",	"Dial Complete",	"Ringer On",	"Ringer Off",	"Hook Transition Complete",	"Bits Changed",	"Pulse Start",	"Timer Expired",	"Timer Ping",	"Polarity Reversal",	"Ring Begin",};static struct {	int alarm;	char *name;} alarms[] = {	{ DAHDI_ALARM_RED, "Red Alarm" },	{ DAHDI_ALARM_YELLOW, "Yellow Alarm" },	{ DAHDI_ALARM_BLUE, "Blue Alarm" },	{ DAHDI_ALARM_RECOVER, "Recovering" },	{ DAHDI_ALARM_LOOPBACK, "Loopback" },	{ DAHDI_ALARM_NOTOPEN, "Not Open" },	{ DAHDI_ALARM_NONE, "None" },};static char *alarm2str(int alarm){	int x;	for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {		if (alarms[x].alarm & alarm)			return alarms[x].name;	}	return alarm ? "Unknown Alarm" : "No Alarm";}static char *event2str(int event){	static char buf[256];	if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))		return events[event];	sprintf(buf, "Event %d", event); /* safe */	return buf;}#ifdef HAVE_PRIstatic char *dialplan2str(int dialplan){	if (dialplan == -1) {		return("Dynamically set dialplan in ISDN");	}	return (pri_plan2str(dialplan));}#endifstatic char *dahdi_sig2str(int sig){	static char buf[256];	switch (sig) {	case SIG_EM:		return "E & M Immediate";	case SIG_EMWINK:		return "E & M Wink";	case SIG_EM_E1:		return "E & M E1";	case SIG_FEATD:		return "Feature Group D (DTMF)";	case SIG_FEATDMF:		return "Feature Group D (MF)";	case SIG_FEATDMF_TA:		return "Feature Groud D (MF) Tandem Access";	case SIG_FEATB:		return "Feature Group B (MF)";	case SIG_E911:		return "E911 (MF)";	case SIG_FGC_CAMA:		return "FGC/CAMA (Dialpulse)";	case SIG_FGC_CAMAMF:		return "FGC/CAMA (MF)";	case SIG_FXSLS:		return "FXS Loopstart";	case SIG_FXSGS:		return "FXS Groundstart";	case SIG_FXSKS:		return "FXS Kewlstart";	case SIG_FXOLS:		return "FXO Loopstart";	case SIG_FXOGS:		return "FXO Groundstart";	case SIG_FXOKS:		return "FXO Kewlstart";	case SIG_PRI:		return "ISDN PRI";	case SIG_SF:		return "SF (Tone) Immediate";	case SIG_SFWINK:		return "SF (Tone) Wink";	case SIG_SF_FEATD:		return "SF (Tone) with Feature Group D (DTMF)";	case SIG_SF_FEATDMF:		return "SF (Tone) with Feature Group D (MF)";	case SIG_SF_FEATB:		return "SF (Tone) with Feature Group B (MF)";	case SIG_GR303FXOKS:		return "GR-303 with FXOKS";	case SIG_GR303FXSKS:		return "GR-303 with FXSKS";	case 0:		return "Pseudo";	default:		snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);		return buf;	}}#define sig2str dahdi_sig2strstatic int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel){	/* If the conference already exists, and we're already in it	   don't bother doing anything */	struct dahdi_confinfo zi;		memset(&zi, 0, sizeof(zi));	zi.chan = 0;	if (slavechannel > 0) {		/* If we have only one slave, do a digital mon */		zi.confmode = DAHDI_CONF_DIGITALMON;		zi.confno = slavechannel;	} else {		if (!index) {			/* Real-side and pseudo-side both participate in conference */			zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |				DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;		} else			zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;		zi.confno = p->confno;	}	if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))		return 0;	if (c->dfd < 0)		return 0;	if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {		ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));		return -1;	}	if (slavechannel < 1) {		p->confno = zi.confno;	}	memcpy(&c->curconf, &zi, sizeof(c->curconf));	ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);	return 0;}static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c){	/* If they're listening to our channel, they're ours */		if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))		return 1;	/* If they're a talker on our (allocated) conference, they're ours */	if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))		return 1;	return 0;}static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index){	struct dahdi_confinfo zi;	if (/* Can't delete if there's no dfd */		(c->dfd < 0) ||		/* Don't delete from the conference if it's not our conference */		!isourconf(p, c)		/* Don't delete if we don't think it's conferenced at all (implied) */		) return 0;	memset(&zi, 0, sizeof(zi));	zi.chan = 0;	zi.confno = 0;	zi.confmode = 0;	if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {		ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));		return -1;	}	ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);	memcpy(&c->curconf, &zi, sizeof(c->curconf));	return 0;}static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out){	int x;	int useslavenative;	struct dahdi_pvt *slave = NULL;	/* Start out optimistic */	useslavenative = 1;	/* Update conference state in a stateless fashion */	for (x = 0; x < 3; x++) {		/* Any three-way calling makes slave native mode *definitely* out		   of the question */		if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)			useslavenative = 0;	}	/* If we don't have any 3-way calls, check to see if we have	   precisely one slave */	if (useslavenative) {		for (x = 0; x < MAX_SLAVES; x++) {			if (p->slaves[x]) {				if (slave) {					/* Whoops already have a slave!  No 					   slave native and stop right away */					slave = NULL;					useslavenative = 0;					break;				} else {					/* We have one slave so far */					slave = p->slaves[x];				}			}		}	}	/* If no slave, slave native definitely out */	if (!slave)		useslavenative = 0;	else if (slave->law != p->law) {		useslavenative = 0;		slave = NULL;	}	if (out)		*out = slave;	return useslavenative;}static int reset_conf(struct dahdi_pvt *p){	struct dahdi_confinfo zi;	memset(&zi, 0, sizeof(zi));	p->confno = -1;	memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));

⌨️ 快捷键说明

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