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

📄 chan_dahdi.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);	mysig = p->sig;	if (p->outsigmod > -1)		mysig = p->outsigmod;	switch (mysig) {	case SIG_FXOLS:	case SIG_FXOGS:	case SIG_FXOKS:		if (p->owner == ast) {			/* Normal ring, on hook */						/* Don't send audio while on hook, until the call is answered */			p->dialing = 1;			if (p->use_callerid) {				/* Generate the Caller-ID spill if desired */				if (p->cidspill) {					ast_log(LOG_WARNING, "cidspill already exists??\n");					free(p->cidspill);				}				p->callwaitcas = 0;				if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {					p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));					p->cidpos = 0;					send_callerid(p);				}			}			/* Choose proper cadence */			if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {				if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))					ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));				p->cidrings = cidrings[p->distinctivering - 1];			} else {				if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))					ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));				p->cidrings = p->sendcalleridafter;			}			/* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */			c = strchr(dest, '/');			if (c)				c++;			if (c && (strlen(c) < p->stripmsd)) {				ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);				c = NULL;			}			if (c) {				p->dop.op = DAHDI_DIAL_OP_REPLACE;				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);				ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);			} else {				p->dop.dialstr[0] = '\0';			}			x = DAHDI_RING;			if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x) && (errno != EINPROGRESS)) {				ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));				ast_mutex_unlock(&p->lock);				return -1;			}			p->dialing = 1;		} else {			/* Call waiting call */			p->callwaitrings = 0;			if (ast->cid.cid_num)				ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));			else				p->callwait_num[0] = '\0';			if (ast->cid.cid_name)				ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));			else				p->callwait_name[0] = '\0';			/* Call waiting tone instead */			if (dahdi_callwait(ast)) {				ast_mutex_unlock(&p->lock);				return -1;			}			/* Make ring-back */			if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].dfd, DAHDI_TONE_RINGTONE))				ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);						}		n = ast->cid.cid_name;		l = ast->cid.cid_num;		if (l)			ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));		else			p->lastcid_num[0] = '\0';		if (n)			ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));		else			p->lastcid_name[0] = '\0';		ast_setstate(ast, AST_STATE_RINGING);		index = dahdi_get_index(ast, p, 0);		if (index > -1) {			p->subs[index].needringing = 1;		}		break;	case SIG_FXSLS:	case SIG_FXSGS:	case SIG_FXSKS:	case SIG_EMWINK:	case SIG_EM:	case SIG_EM_E1:	case SIG_FEATD:	case SIG_FEATDMF:	case SIG_E911:	case SIG_FGC_CAMA:	case SIG_FGC_CAMAMF:	case SIG_FEATB:	case SIG_SFWINK:	case SIG_SF:	case SIG_SF_FEATD:	case SIG_SF_FEATDMF:	case SIG_FEATDMF_TA:	case SIG_SF_FEATB:		c = strchr(dest, '/');		if (c)			c++;		else			c = "";		if (strlen(c) < p->stripmsd) {			ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);			ast_mutex_unlock(&p->lock);			return -1;		}#ifdef HAVE_PRI		/* Start the trunk, if not GR-303 */		if (!p->pri) {#endif			x = DAHDI_START;			res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);			if (res < 0) {				if (errno != EINPROGRESS) {					ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));					ast_mutex_unlock(&p->lock);					return -1;				}			}#ifdef HAVE_PRI		}#endif		ast_log(LOG_DEBUG, "Dialing '%s'\n", c);		p->dop.op = DAHDI_DIAL_OP_REPLACE;		c += p->stripmsd;		switch (mysig) {		case SIG_FEATD:			l = ast->cid.cid_num;			if (l) 				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);			else				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);			break;		case SIG_FEATDMF:			l = ast->cid.cid_num;			if (l) 				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);			else				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);			break;		case SIG_FEATDMF_TA:		{			const char *cic, *ozz;			/* If you have to go through a Tandem Access point you need to use this */			ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");			if (!ozz)				ozz = defaultozz;			cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");			if (!cic)				cic = defaultcic;			if (!ozz || !cic) {				ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");				ast_mutex_unlock(&p->lock);				return -1;			}			snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);			snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);			p->whichwink = 0;		}			break;		case SIG_E911:			ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));			break;		case SIG_FGC_CAMA:			snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);			break;		case SIG_FGC_CAMAMF:		case SIG_FEATB:			snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);			break;		default:			if (p->pulse)				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);			else				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);			break;		}		if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {			memset(p->echorest, 'w', sizeof(p->echorest) - 1);			strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);			p->echorest[sizeof(p->echorest) - 1] = '\0';			p->echobreak = 1;			p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';		} else			p->echobreak = 0;		if (!res) {			if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {				int saveerr = errno;				x = DAHDI_ONHOOK;				ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);				ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));				ast_mutex_unlock(&p->lock);				return -1;			}		} else			ast_log(LOG_DEBUG, "Deferring dialing...\n");		p->dialing = 1;		if (ast_strlen_zero(c))			p->dialednone = 1;		ast_setstate(ast, AST_STATE_DIALING);		break;	case 0:		/* Special pseudo -- automatically up*/		ast_setstate(ast, AST_STATE_UP);		break;			case SIG_PRI:		/* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */		p->dialdest[0] = '\0';		break;	default:		ast_log(LOG_DEBUG, "not yet implemented\n");		ast_mutex_unlock(&p->lock);		return -1;	}#ifdef HAVE_PRI	if (p->pri) {		struct pri_sr *sr;#ifdef SUPPORT_USERUSER		const char *useruser;#endif		int pridialplan;		int dp_strip;		int prilocaldialplan;		int ldp_strip;		int exclusive;		const char *rr_str;		int redirect_reason;		c = strchr(dest, '/');		if (c)			c++;		else			c = dest;		l = NULL;		n = NULL;		if (!p->hidecallerid) {			l = ast->cid.cid_num;			if (!p->hidecalleridname) {				n = ast->cid.cid_name;			}		}		if (strlen(c) < p->stripmsd) {			ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);			ast_mutex_unlock(&p->lock);			return -1;		}		if (mysig != SIG_FXSKS) {			p->dop.op = DAHDI_DIAL_OP_REPLACE;			s = strchr(c + p->stripmsd, 'w');			if (s) {				if (strlen(s) > 1)					snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);				else					p->dop.dialstr[0] = '\0';				*s = '\0';			} else {				p->dop.dialstr[0] = '\0';			}		}		if (pri_grab(p, p->pri)) {			ast_log(LOG_WARNING, "Failed to grab PRI!\n");			ast_mutex_unlock(&p->lock);			return -1;		}		if (!(p->call = pri_new_call(p->pri->pri))) {			ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);			pri_rel(p->pri);			ast_mutex_unlock(&p->lock);			return -1;		}		if (!(sr = pri_sr_new())) {			ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);			pri_destroycall(p->pri->pri, p->call);			p->call = NULL;			pri_rel(p->pri);			ast_mutex_unlock(&p->lock);			return -1;		}		if (p->bearer || (mysig == SIG_FXSKS)) {			if (p->bearer) {				ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);				p->bearer->call = p->call;			} else				ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");			pri_set_crv(p->pri->pri, p->call, p->channel, 0);		}		p->digital = IS_DIGITAL(ast->transfercapability);		/* Add support for exclusive override */		if (p->priexclusive)			exclusive = 1;		else {		/* otherwise, traditional behavior */			if (p->pri->nodetype == PRI_NETWORK)				exclusive = 0;			else				exclusive = 1;		}				pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);		pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 					(p->digital ? -1 : 						((p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));		if (p->pri->facilityenable)			pri_facility_enable(p->pri->pri);		if (option_verbose > 2)			ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));		dp_strip = 0; 		pridialplan = p->pri->dialplan - 1; 		if (pridialplan == -2) { /* compute dynamically */ 			if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) { 				dp_strip = strlen(p->pri->internationalprefix); 				pridialplan = PRI_INTERNATIONAL_ISDN; 			} else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) { 				dp_strip = strlen(p->pri->nationalprefix); 				pridialplan = PRI_NATIONAL_ISDN; 			} else {				pridialplan = PRI_LOCAL_ISDN; 			} 		} 		pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);		ldp_strip = 0;		prilocaldialplan = p->pri->localdialplan - 1;		if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */			if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {				ldp_strip = strlen(p->pri->internationalprefix);				prilocaldialplan = PRI_INTERNATIONAL_ISDN;			} else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {				ldp_strip = strlen(p->pri->nationalprefix);				prilocaldialplan = PRI_NATIONAL_ISDN;			} else {				prilocaldialplan = PRI_LOCAL_ISDN;			}		}		pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,			p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));		if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {			if (!strcasecmp(rr_str, "UNKNOWN"))				redirect_reason = 0;			else if (!strcasecmp(rr_str, "BUSY"))				redirect_reason = 1;			else if (!strcasecmp(rr_str, "NO_REPLY"))				redirect_reason = 2;			else if (!strcasecmp(rr_str, "UNCONDITIONAL"))				redirect_reason = 15;			else				redirect_reason = PRI_REDIR_UNCONDITIONAL;		} else			redirect_reason = PRI_REDIR_UNCONDITIONAL;		pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);#ifdef SUPPORT_USERUSER		/* User-user info */		useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");		if (useruser)			pri_sr_set_useruser(sr, useruser);#endif		if (pri_setup(p->pri->pri, p->call, sr)) { 			ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",  				c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));			pri_rel(p->pri);			ast_mutex_unlock(&p->lock);			pri_sr_free(sr);			return -1;		}		pri_sr_free(sr);		ast_setstate(ast, AST_STATE_DIALING);		pri_rel(p->pri);	}#endif			ast_mutex_unlock(&p->lock);	return 0;}static void destroy_dahdi_pvt(struct dahdi_pvt **pvt){	struct dahdi_pvt *p = *pvt;	/* Remove channel from the list */	if (p->prev)		p->prev->next = p->next;	if (p->next)		p->next->prev = p->prev;	if (p->use_smdi)		ast_smdi_interface_unref(p->smdi_iface);	ast_mutex_destroy(&p->lock);	dahdi_close_sub(p, SUB_REAL);	if (p->owner)		p->owner->tech_pvt = NULL;	free(p);	*pvt = NULL;}static int destroy_channel(struct dahdi_pvt *prev, struct dahdi_pvt *cur, int now){	int owned = 0;	int i = 0;	if (!now) {		if (cur->owner) {			owned = 1;		}		for (i = 0; i < 3; i++) {			if (cur->subs[i].owner) {				owned = 1;			}		}		if (!owned) {			if (prev) {				prev->next = cur->next;				if (prev->next)					prev->next->prev = prev;				else					ifend = prev;			} else {				iflist = cur->next;				if (iflist)					iflist->prev = NULL;				else					ifend = NULL;			}			destroy_dahdi_pvt(&cur);		}	} else {		if (prev) {			prev->next = cur->next;			if (prev->next)				prev->next->prev = prev;			else

⌨️ 快捷键说明

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