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

📄 chan_h323.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (!got_progress)				h323_send_progress(token);			res = 0;		}		break;	case AST_CONTROL_BUSY:		if (c->_state != AST_STATE_UP) {			h323_answering_call(token, 1);			ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);			res = 0;		}		break;	case AST_CONTROL_CONGESTION:		if (c->_state != AST_STATE_UP) {			h323_answering_call(token, 1);			ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);			res = 0;		}		break;	case AST_CONTROL_HOLD:		ast_moh_start(c, data, NULL);		res = 0;		break;	case AST_CONTROL_UNHOLD:		ast_moh_stop(c);		res = 0;		break;	case AST_CONTROL_SRCUPDATE:		ast_rtp_new_source(pvt->rtp);		res = 0;		break;	case AST_CONTROL_PROCEEDING:	case -1:		break;	default:		ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);		break;	}	if (h323debug)		ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);	if (token)		free(token);	oh323_update_info(c);	return res;}static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan){	struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;	ast_mutex_lock(&pvt->lock);	if (pvt->owner != oldchan) {		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);		return -1;	}	pvt->owner = newchan;	ast_mutex_unlock(&pvt->lock);	return 0;}static int __oh323_rtp_create(struct oh323_pvt *pvt){	struct in_addr our_addr;	if (pvt->rtp)		return 0;	if (ast_find_ourip(&our_addr, bindaddr)) {		ast_mutex_unlock(&pvt->lock);		ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");		return -1;	}	pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr);	if (!pvt->rtp) {		ast_mutex_unlock(&pvt->lock);		ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));		return -1;	}	if (h323debug)		ast_log(LOG_DEBUG, "Created RTP channel\n");	ast_rtp_settos(pvt->rtp, tos);	if (h323debug)		ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);	ast_rtp_setnat(pvt->rtp, pvt->options.nat);	if (pvt->dtmf_pt > 0)		ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0);	if (pvt->peercapability)		ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs);	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {		ast_jb_configure(pvt->owner, &global_jbconf);		pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp);		pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp);		ast_queue_frame(pvt->owner, &ast_null_frame);	/* Tell Asterisk to apply changes */		ast_channel_unlock(pvt->owner);	} else		pvt->update_rtp_info = 1;	return 0;}/* Private structure should be locked on a call */static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host){	struct ast_channel *ch;	char *cid_num, *cid_name;	int fmt;	if (!ast_strlen_zero(pvt->options.cid_num))		cid_num = pvt->options.cid_num;	else		cid_num = pvt->cd.call_source_e164;	if (!ast_strlen_zero(pvt->options.cid_name))		cid_name = pvt->options.cid_name;	else		cid_name = pvt->cd.call_source_name;		/* Don't hold a oh323_pvt lock while we allocate a chanel */	ast_mutex_unlock(&pvt->lock);	ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host);	/* Update usage counter */	ast_module_ref(ast_module_info->self);	ast_mutex_lock(&pvt->lock);	if (ch) {		ch->tech = &oh323_tech;		if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))			fmt = global_options.capability;		ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;		pvt->nativeformats = ch->nativeformats;		fmt = ast_best_codec(ch->nativeformats);		ch->writeformat = fmt;		ch->rawwriteformat = fmt;		ch->readformat = fmt;		ch->rawreadformat = fmt;#if 0		ch->fds[0] = ast_rtp_fd(pvt->rtp);		ch->fds[1] = ast_rtcp_fd(pvt->rtp);#endif#ifdef VIDEO_SUPPORT		if (pvt->vrtp) {			ch->fds[2] = ast_rtp_fd(pvt->vrtp);			ch->fds[3] = ast_rtcp_fd(pvt->vrtp);		}#endif#ifdef T38_SUPPORT		if (pvt->udptl) {			ch->fds[4] = ast_udptl_fd(pvt->udptl);		}#endif		if (state == AST_STATE_RING) {			ch->rings = 1;		}		/* Allocate dsp for in-band DTMF support */		if (pvt->options.dtmfmode & H323_DTMF_INBAND) {			pvt->vad = ast_dsp_new();			ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);		}		/* Register channel functions. */		ch->tech_pvt = pvt;		/* Set the owner of this channel */		pvt->owner = ch;		ast_copy_string(ch->context, pvt->context, sizeof(ch->context));		ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));		ch->priority = 1;		if (!ast_strlen_zero(pvt->accountcode)) {			ast_string_field_set(ch, accountcode, pvt->accountcode);		}		if (pvt->amaflags) {			ch->amaflags = pvt->amaflags;		}		/* Don't use ast_set_callerid() here because it will		 * generate a needless NewCallerID event */		ch->cid.cid_ani = ast_strdup(cid_num);		if (pvt->cd.redirect_reason >= 0) {			ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number);			pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));		}		ch->cid.cid_pres = pvt->cd.presentation;		ch->cid.cid_ton = pvt->cd.type_of_number;		if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {			ch->cid.cid_dnid = strdup(pvt->exten);		}		if (pvt->cd.transfer_capability >= 0)			ch->transfercapability = pvt->cd.transfer_capability;		if (state != AST_STATE_DOWN) {			if (ast_pbx_start(ch)) {				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);				ast_hangup(ch);				ch = NULL;			}		}	} else {		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");	}	return ch;}static struct oh323_pvt *oh323_alloc(int callid){	struct oh323_pvt *pvt;	pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt));	if (!pvt) {		ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");		return NULL;	}	memset(pvt, 0, sizeof(struct oh323_pvt));	pvt->cd.redirect_reason = -1;	pvt->cd.transfer_capability = -1;	/* Ensure the call token is allocated for outgoing call */	if (!callid) {		if ((pvt->cd).call_token == NULL) {			(pvt->cd).call_token = (char *)malloc(128);		}		if (!pvt->cd.call_token) {			ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");			ast_rtp_destroy(pvt->rtp);			free(pvt);			return NULL;		}		memset((char *)(pvt->cd).call_token, 0, 128);		pvt->cd.call_reference = callid;	}	memcpy(&pvt->options, &global_options, sizeof(pvt->options));	pvt->jointcapability = pvt->options.capability;	if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {		pvt->nonCodecCapability |= AST_RTP_DTMF;	} else {		pvt->nonCodecCapability &= ~AST_RTP_DTMF;	}	ast_copy_string(pvt->context, default_context, sizeof(pvt->context));	pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;	ast_mutex_init(&pvt->lock);	/* Add to interface list */	ast_mutex_lock(&iflock);	pvt->next = iflist;	iflist = pvt;	ast_mutex_unlock(&iflock);	return pvt;}static struct oh323_pvt *find_call_locked(int call_reference, const char *token){	struct oh323_pvt *pvt;	ast_mutex_lock(&iflock);	pvt = iflist;	while(pvt) {		if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {			/* Found the call */			if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {				ast_mutex_lock(&pvt->lock);				ast_mutex_unlock(&iflock);				return pvt;			} else if (token == NULL) {				ast_log(LOG_WARNING, "Call Token is NULL\n");				ast_mutex_lock(&pvt->lock);				ast_mutex_unlock(&iflock);				return pvt;			}		}		pvt = pvt->next;	}	ast_mutex_unlock(&iflock);	return NULL;}static int update_state(struct oh323_pvt *pvt, int state, int signal){	if (!pvt)		return 0;	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {		if (state >= 0)			ast_setstate(pvt->owner, state);		if (signal >= 0)			ast_queue_control(pvt->owner, signal);		ast_channel_unlock(pvt->owner);		return 1;	}	else {		if (state >= 0)			pvt->newstate = state;		if (signal >= 0)			pvt->newcontrol = signal;		return 0;	}}static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime){	struct oh323_alias *alias;	int found = 0;	alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);	if (alias)		found++;	else {		if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias))))			return NULL;		ASTOBJ_INIT(alias);	}	if (!found && name)		ast_copy_string(alias->name, name, sizeof(alias->name));	for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {		if (!strcasecmp(v->name, "e164")) {			ast_copy_string(alias->e164, v->value, sizeof(alias->e164));		} else if (!strcasecmp(v->name, "prefix")) {			ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));		} else if (!strcasecmp(v->name, "context")) {			ast_copy_string(alias->context, v->value, sizeof(alias->context));		} else if (!strcasecmp(v->name, "secret")) {			ast_copy_string(alias->secret, v->value, sizeof(alias->secret));		} else {			if (strcasecmp(v->value, "h323")) {				ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);			}		}	}	ASTOBJ_UNMARK(alias);	return alias;}static struct oh323_alias *realtime_alias(const char *alias){	struct ast_variable *var, *tmp;	struct oh323_alias *a;	var = ast_load_realtime("h323", "name", alias, NULL);	if (!var)		return NULL;	for (tmp = var; tmp; tmp = tmp->next) {		if (!strcasecmp(tmp->name, "type") &&		!(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {			ast_variables_destroy(var);			return NULL;		}	}	a = build_alias(alias, var, NULL, 1);	ast_variables_destroy(var);	return a;}#define DEPRECATED(_v, _new_opt) \	ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt))static int update_common_options(struct ast_variable *v, struct call_options *options){	int tmp;	if (!strcasecmp(v->name, "allow")) {		ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);	} else if (!strcasecmp(v->name, "disallow")) {		ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);	} else if (!strcasecmp(v->name, "dtmfmode")) {		if (!strcasecmp(v->value, "inband")) {			options->dtmfmode = H323_DTMF_INBAND;		} else if (!strcasecmp(v->value, "rfc2833")) {			options->dtmfmode = H323_DTMF_RFC2833;		} else {			ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);			options->dtmfmode = H323_DTMF_RFC2833;		}	} else if (!strcasecmp(v->name, "dtmfcodec")) {		tmp = atoi(v->value);		if (tmp < 96)			ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);		else			options->dtmfcodec = tmp;	} else if (!strcasecmp(v->name, "bridge")) {		options->bridge = ast_true(v->value);	} else if (!strcasecmp(v->name, "nat")) {		options->nat = ast_true(v->value);	} else if (!strcasecmp(v->name, "noFastStart")) {		DEPRECATED(v, "fastStart");		options->fastStart = !ast_true(v->value);	} else if (!strcasecmp(v->name, "fastStart")) {		options->fastStart = ast_true(v->value);	} else if (!strcasecmp(v->name, "noH245Tunneling")) {		DEPRECATED(v, "h245Tunneling");		options->h245Tunneling = !ast_true(v->value);	} else if (!strcasecmp(v->name, "h245Tunneling")) {		options->h245Tunneling = ast_true(v->value);	} else if (!strcasecmp(v->name, "noSilenceSuppression")) {		DEPRECATED(v, "silenceSuppression");		options->silenceSuppression = !ast_true(v->value);	} else if (!strcasecmp(v->name, "silenceSuppression")) {		options->silenceSuppression = ast_true(v->value);	} else if (!strcasecmp(v->name, "progress_setup")) {		tmp = atoi(v->value);		if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {			ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);			tmp = 0;		}		options->progress_setup = tmp;	} else if (!strcasecmp(v->name, "progress_alert")) {		tmp = atoi(v->value);		if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {			ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);			tmp = 0;		}		options->progress_alert = tmp;	} else if (!strcasecmp(v->name, "progress_audio")) {		options->progress_audio = ast_true(v->value);	} else if (!strcasecmp(v->name, "callerid")) {		ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));	} else if (!strcasecmp(v->name, "fullname")) {		ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));	} else if (!strcasecmp(v->name, "cid_number")) {		ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));	} else if (!strcasecmp(v->name, "tunneling")) {		if (!strcasecmp(v->value, "none"))			options->tunnelOptions = 0;		else if (!strcasecmp(v->value, "cisco"))			options->tunnelOptions |= H323_TUNNEL_CISCO;		else if (!strcasecmp(v->value, "qsig"))			options->tunnelOptions |= H323_TUNNEL_QSIG;		else			ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);	} else		return 1;	return 0;}#undef DEPRECATEDstatic struct oh323_user *build_user(char *name, struct ast_variable *v, struct ast_variable *alt, int realtime){	struct oh323_user *user;

⌨️ 快捷键说明

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