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

📄 chan_dahdi.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (p->subs[SUB_REAL].dfd > -1) {		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))			ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));	}	return 0;}static int update_conf(struct dahdi_pvt *p){	int needconf = 0;	int x;	int useslavenative;	struct dahdi_pvt *slave = NULL;	useslavenative = isslavenative(p, &slave);	/* Start with the obvious, general stuff */	for (x = 0; x < 3; x++) {		/* Look for three way calls */		if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {			conf_add(p, &p->subs[x], x, 0);			needconf++;		} else {			conf_del(p, &p->subs[x], x);		}	}	/* If we have a slave, add him to our conference now. or DAX	   if this is slave native */	for (x = 0; x < MAX_SLAVES; x++) {		if (p->slaves[x]) {			if (useslavenative)				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));			else {				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);				needconf++;			}		}	}	/* If we're supposed to be in there, do so now */	if (p->inconference && !p->subs[SUB_REAL].inthreeway) {		if (useslavenative)			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));		else {			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);			needconf++;		}	}	/* If we have a master, add ourselves to his conference */	if (p->master) {		if (isslavenative(p->master, NULL)) {			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));		} else {			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);		}	}	if (!needconf) {		/* Nobody is left (or should be left) in our conference.		   Kill it. */		p->confno = -1;	}	if (option_debug)		ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);	return 0;}static void dahdi_enable_ec(struct dahdi_pvt *p){	int x;	int res;	if (!p)		return;	if (p->echocanon) {		ast_log(LOG_DEBUG, "Echo cancellation already on\n");		return;	}	if (p->digital) {		ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");		return;	}	if (p->echocancel) {		if (p->sig == SIG_PRI) {			x = 1;			res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);			if (res)				ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));		}		x = p->echocancel;		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);		if (res) 			ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));		else {			p->echocanon = 1;			if (option_debug)				ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);		}	} else if (option_debug)		ast_log(LOG_DEBUG, "No echo cancellation requested\n");}static void dahdi_train_ec(struct dahdi_pvt *p){	int x;	int res;	if (p && p->echocancel && p->echotraining) {		x = p->echotraining;		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);		if (res)			ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));		else {			ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);		}	} else		ast_log(LOG_DEBUG, "No echo training requested\n");}static void dahdi_disable_ec(struct dahdi_pvt *p){	int x;	int res;	if (p->echocancel) {		x = 0;		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);		if (res)			ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));		else if (option_debug)			ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);	}	p->echocanon = 0;}static void fill_txgain(struct dahdi_gains *g, float gain, int law){	int j;	int k;	float linear_gain = pow(10.0, gain / 20.0);	switch (law) {	case DAHDI_LAW_ALAW:		for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {			if (gain) {				k = (int) (((float) AST_ALAW(j)) * linear_gain);				if (k > 32767) k = 32767;				if (k < -32767) k = -32767;				g->txgain[j] = AST_LIN2A(k);			} else {				g->txgain[j] = j;			}		}		break;	case DAHDI_LAW_MULAW:		for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {			if (gain) {				k = (int) (((float) AST_MULAW(j)) * linear_gain);				if (k > 32767) k = 32767;				if (k < -32767) k = -32767;				g->txgain[j] = AST_LIN2MU(k);			} else {				g->txgain[j] = j;			}		}		break;	}}static void fill_rxgain(struct dahdi_gains *g, float gain, int law){	int j;	int k;	float linear_gain = pow(10.0, gain / 20.0);	switch (law) {	case DAHDI_LAW_ALAW:		for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {			if (gain) {				k = (int) (((float) AST_ALAW(j)) * linear_gain);				if (k > 32767) k = 32767;				if (k < -32767) k = -32767;				g->rxgain[j] = AST_LIN2A(k);			} else {				g->rxgain[j] = j;			}		}		break;	case DAHDI_LAW_MULAW:		for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {			if (gain) {				k = (int) (((float) AST_MULAW(j)) * linear_gain);				if (k > 32767) k = 32767;				if (k < -32767) k = -32767;				g->rxgain[j] = AST_LIN2MU(k);			} else {				g->rxgain[j] = j;			}		}		break;	}}static int set_actual_txgain(int fd, int chan, float gain, int law){	struct dahdi_gains g;	int res;	memset(&g, 0, sizeof(g));	g.chan = chan;	res = ioctl(fd, DAHDI_GETGAINS, &g);	if (res) {		if (option_debug)			ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));		return res;	}	fill_txgain(&g, gain, law);	return ioctl(fd, DAHDI_SETGAINS, &g);}static int set_actual_rxgain(int fd, int chan, float gain, int law){	struct dahdi_gains g;	int res;	memset(&g, 0, sizeof(g));	g.chan = chan;	res = ioctl(fd, DAHDI_GETGAINS, &g);	if (res) {		ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));		return res;	}	fill_rxgain(&g, gain, law);	return ioctl(fd, DAHDI_SETGAINS, &g);}static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law){	return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);}static int bump_gains(struct dahdi_pvt *p){	int res;	/* Bump receive gain by 5.0db */	res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain + 5.0, p->txgain, p->law);	if (res) {		ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));		return -1;	}	return 0;}static int restore_gains(struct dahdi_pvt *p){	int res;	res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);	if (res) {		ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));		return -1;	}	return 0;}static inline int dahdi_set_hook(int fd, int hs){	int x, res;	x = hs;	res = ioctl(fd, DAHDI_HOOK, &x);	if (res < 0) {		if (errno == EINPROGRESS)			return 0;		ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));		/* will expectedly fail if phone is off hook during operation, such as during a restart */	}	return res;}static inline int dahdi_confmute(struct dahdi_pvt *p, int muted){	int x, y, res;	x = muted;	if (p->sig == SIG_PRI) {		y = 1;		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);		if (res)			ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", p->channel, strerror(errno));	}	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);	if (res < 0)		ast_log(LOG_WARNING, "dahdi confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));	return res;}static int save_conference(struct dahdi_pvt *p){	struct dahdi_confinfo c;	int res;	if (p->saveconf.confmode) {		ast_log(LOG_WARNING, "Can't save conference -- already in use\n");		return -1;	}	p->saveconf.chan = 0;	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);	if (res) {		ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));		p->saveconf.confmode = 0;		return -1;	}	c.chan = 0;	c.confno = 0;	c.confmode = DAHDI_CONF_NORMAL;	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);	if (res) {		ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));		return -1;	}	if (option_debug)		ast_log(LOG_DEBUG, "Disabled conferencing\n");	return 0;}static int restore_conference(struct dahdi_pvt *p){	int res;	if (p->saveconf.confmode) {		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);		p->saveconf.confmode = 0;		if (res) {			ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));			return -1;		}	}	if (option_debug)		ast_log(LOG_DEBUG, "Restored conferencing\n");	return 0;}static int send_callerid(struct dahdi_pvt *p);static int send_cwcidspill(struct dahdi_pvt *p){	p->callwaitcas = 0;	p->cidcwexpire = 0;	if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))		return -1;	p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));	/* Make sure we account for the end */	p->cidlen += READ_SIZE * 4;	p->cidpos = 0;	send_callerid(p);	if (option_verbose > 2)		ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);	return 0;}static int has_voicemail(struct dahdi_pvt *p){	return ast_app_has_voicemail(p->mailbox, NULL);}static int send_callerid(struct dahdi_pvt *p){	/* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */	int res;	/* Take out of linear mode if necessary */	if (p->subs[SUB_REAL].linear) {		p->subs[SUB_REAL].linear = 0;		dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);	}	while (p->cidpos < p->cidlen) {		res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);		if (res < 0) {			if (errno == EAGAIN)				return 0;			else {				ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));				return -1;			}		}		if (!res)			return 0;		p->cidpos += res;	}	free(p->cidspill);	p->cidspill = NULL;	if (p->callwaitcas) {		/* Wait for CID/CW to expire */		p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;	} else		restore_conference(p);	return 0;}static int dahdi_callwait(struct ast_channel *ast){	struct dahdi_pvt *p = ast->tech_pvt;	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;	if (p->cidspill) {		ast_log(LOG_WARNING, "Spill already exists?!?\n");		free(p->cidspill);	}	if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))		return -1;	save_conference(p);	/* Silence */	memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);	if (!p->callwaitrings && p->callwaitingcallerid) {		ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));		p->callwaitcas = 1;		p->cidlen = 2400 + 680 + READ_SIZE * 4;	} else {		ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));		p->callwaitcas = 0;		p->cidlen = 2400 + READ_SIZE * 4;	}	p->cidpos = 0;	send_callerid(p);		return 0;}static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout){	struct dahdi_pvt *p = ast->tech_pvt;	int x, res, index,mysig;	char *c, *n, *l;#ifdef HAVE_PRI	char *s = NULL;#endif	char dest[256]; /* must be same length as p->dialdest */	ast_mutex_lock(&p->lock);	ast_copy_string(dest, rdest, sizeof(dest));	ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));	if ((ast->_state == AST_STATE_BUSY)) {		p->subs[SUB_REAL].needbusy = 1;		ast_mutex_unlock(&p->lock);		return 0;	}	if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {		ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name);		ast_mutex_unlock(&p->lock);		return -1;	}	p->dialednone = 0;	if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */	{		/* Special pseudo -- automatically up */		ast_setstate(ast, AST_STATE_UP); 		ast_mutex_unlock(&p->lock);		return 0;	}	x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);	if (res)		ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));	p->outgoing = 1;

⌨️ 快捷键说明

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