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

📄 chan_features.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct feature_pvt *p = ast->tech_pvt;	int res = -1;	int x;	/* Queue up a frame representing the indication as a control frame */	ast_mutex_lock(&p->lock);	x = indexof(p, ast, 0);	if (!x && p->subchan)		res = ast_indicate(p->subchan, condition);	ast_mutex_unlock(&p->lock);	return res;}static int features_digit_begin(struct ast_channel *ast, char digit){	struct feature_pvt *p = ast->tech_pvt;	int res = -1;	int x;	/* Queue up a frame representing the indication as a control frame */	ast_mutex_lock(&p->lock);	x = indexof(p, ast, 0);	if (!x && p->subchan)		res = ast_senddigit_begin(p->subchan, digit);	ast_mutex_unlock(&p->lock);	return res;}static int features_digit_end(struct ast_channel *ast, char digit, unsigned int duration){	struct feature_pvt *p = ast->tech_pvt;	int res = -1;	int x;	/* Queue up a frame representing the indication as a control frame */	ast_mutex_lock(&p->lock);	x = indexof(p, ast, 0);	if (!x && p->subchan)		res = ast_senddigit_end(p->subchan, digit, duration);	ast_mutex_unlock(&p->lock);	return res;}static int features_call(struct ast_channel *ast, char *dest, int timeout){	struct feature_pvt *p = ast->tech_pvt;	int res = -1;	int x;	char *dest2;			dest2 = strchr(dest, '/');	if (dest2) {		ast_mutex_lock(&p->lock);		x = indexof(p, ast, 0);		if (!x && p->subchan) {			p->subchan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);			p->subchan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);			p->subchan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);			p->subchan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);					p->subchan->cid.cid_pres = p->owner->cid.cid_pres;			ast_string_field_set(p->subchan, language, p->owner->language);			ast_string_field_set(p->subchan, accountcode, p->owner->accountcode);			p->subchan->cdrflags = p->owner->cdrflags;			res = ast_call(p->subchan, dest2, timeout);			update_features(p, x);		} else			ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n");		ast_mutex_unlock(&p->lock);	}	return res;}static int features_hangup(struct ast_channel *ast){	struct feature_pvt *p = ast->tech_pvt;	int x;	ast_mutex_lock(&p->lock);	x = indexof(p, ast, 0);	if (x > -1) {		restore_channel(p, x);		p->subs[x].owner = NULL;		/* XXX Re-arrange, unconference, etc XXX */	}	ast->tech_pvt = NULL;		if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {		ast_mutex_unlock(&p->lock);		/* Remove from list */		AST_LIST_LOCK(&features);		AST_LIST_REMOVE(&features, p, list);		AST_LIST_UNLOCK(&features);		ast_mutex_lock(&p->lock);		/* And destroy */		if (p->subchan)			ast_hangup(p->subchan);		ast_mutex_unlock(&p->lock);		ast_mutex_destroy(&p->lock);		free(p);		return 0;	}	ast_mutex_unlock(&p->lock);	return 0;}static struct feature_pvt *features_alloc(char *data, int format){	struct feature_pvt *tmp;	char *dest=NULL;	char *tech;	int x;	int status;	struct ast_channel *chan;		tech = ast_strdupa(data);	if (tech) {		dest = strchr(tech, '/');		if (dest) {			*dest = '\0';			dest++;		}	}	if (!tech || !dest) {		ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n", 			data);		return NULL;	}	AST_LIST_LOCK(&features);	AST_LIST_TRAVERSE(&features, tmp, list) {		if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest))			break;	}	AST_LIST_UNLOCK(&features);	if (!tmp) {		chan = ast_request(tech, format, dest, &status);		if (!chan) {			ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);			return NULL;		}		tmp = malloc(sizeof(struct feature_pvt));		if (tmp) {			memset(tmp, 0, sizeof(struct feature_pvt));			for (x=0;x<3;x++)				init_sub(tmp->subs + x);			ast_mutex_init(&tmp->lock);			ast_copy_string(tmp->tech, tech, sizeof(tmp->tech));			ast_copy_string(tmp->dest, dest, sizeof(tmp->dest));			tmp->subchan = chan;			AST_LIST_LOCK(&features);			AST_LIST_INSERT_HEAD(&features, tmp, list);			AST_LIST_UNLOCK(&features);		}	}	return tmp;}static struct ast_channel *features_new(struct feature_pvt *p, int state, int index){	struct ast_channel *tmp;	int x,y;	char *b2 = 0;	if (!p->subchan) {		ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n");		return NULL;	}	if (p->subs[index].owner) {		ast_log(LOG_WARNING, "Called to put index %d already there!\n", index);		return NULL;	}	/* figure out what you want the name to be */	for (x=1;x<4;x++) {		if (b2)			free(b2);		b2 = ast_safe_string_alloc("%s/%s-%d", p->tech, p->dest, x);		for (y=0;y<3;y++) {			if (y == index)				continue;			if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, b2))				break;		}		if (y >= 3)			break;	}	tmp = ast_channel_alloc(0, state, 0,0, "", "", "", 0, "Feature/%s", b2);	/* free up the name, it was copied into the channel name */	if (b2)		free(b2);	if (!tmp) {		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");		return NULL;	}	tmp->tech = &features_tech;	tmp->writeformat = p->subchan->writeformat;	tmp->rawwriteformat = p->subchan->rawwriteformat;	tmp->readformat = p->subchan->readformat;	tmp->rawreadformat = p->subchan->rawreadformat;	tmp->nativeformats = p->subchan->readformat;	tmp->tech_pvt = p;	p->subs[index].owner = tmp;	if (!p->owner)		p->owner = tmp;	ast_module_ref(ast_module_info->self);	return tmp;}static struct ast_channel *features_request(const char *type, int format, void *data, int *cause){	struct feature_pvt *p;	struct ast_channel *chan = NULL;	p = features_alloc(data, format);	if (p && !p->subs[SUB_REAL].owner)		chan = features_new(p, AST_STATE_DOWN, SUB_REAL);	if (chan)		update_features(p,SUB_REAL);	return chan;}static int features_show(int fd, int argc, char **argv){	struct feature_pvt *p;	if (argc != 3)		return RESULT_SHOWUSAGE;	if (AST_LIST_EMPTY(&features)) {		ast_cli(fd, "No feature channels in use\n");		return RESULT_SUCCESS;	}	AST_LIST_LOCK(&features);	AST_LIST_TRAVERSE(&features, p, list) {		ast_mutex_lock(&p->lock);		ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);		ast_mutex_unlock(&p->lock);	}	AST_LIST_UNLOCK(&features);	return RESULT_SUCCESS;}static char show_features_usage[] = "Usage: feature show channels\n""       Provides summary information on feature channels.\n";static struct ast_cli_entry cli_features[] = {	{ { "feature", "show", "channels", NULL },	features_show, "List status of feature channels",	show_features_usage },};static int load_module(void){	/* Make sure we can register our sip channel type */	if (ast_channel_register(&features_tech)) {		ast_log(LOG_ERROR, "Unable to register channel class 'Feature'\n");		return -1;	}	ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));	return 0;}static int unload_module(void){	struct feature_pvt *p;		/* First, take us out of the channel loop */	ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));	ast_channel_unregister(&features_tech);		if (!AST_LIST_LOCK(&features))		return -1;	/* Hangup all interfaces if they have an owner */	AST_LIST_TRAVERSE_SAFE_BEGIN(&features, p, list) {		if (p->owner)			ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);		AST_LIST_REMOVE_CURRENT(&features, list);		free(p);	}	AST_LIST_TRAVERSE_SAFE_END	AST_LIST_UNLOCK(&features);		return 0;}AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Feature Proxy Channel");

⌨️ 快捷键说明

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