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

📄 chan_mgcp.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (p->hookstate == MGCP_OFFHOOK) {			if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {				transmit_notify_request_with_callerid(p->sub, "L/wt", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);			}		} else {			/* set our other connection as the primary and swith over to it */			p->sub = sub->next;			p->sub->cxmode = MGCP_CX_RECVONLY;			transmit_modify_request(p->sub);			if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {				transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);			}		}	} else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) {		transmit_notify_request(sub, "L/v");	} else if (p->hookstate == MGCP_OFFHOOK) {		transmit_notify_request(sub, "L/ro");	} else {		transmit_notify_request(sub, "");	}	ast->tech_pvt = NULL;	sub->alreadygone = 0;	sub->outgoing = 0;	sub->cxmode = MGCP_CX_INACTIVE;	sub->callid[0] = '\0';	if (p) {		memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));	}	/* Reset temporary destination */	memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));	if (sub->rtp) {		ast_rtp_destroy(sub->rtp);		sub->rtp = NULL;	}	ast_module_unref(ast_module_info->self);	if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {		p->hidecallerid = 0;		if (p->hascallwaiting && !p->callwaiting) {			if (option_verbose > 2)				ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on %s\n", ast->name);			p->callwaiting = -1;		}		if (has_voicemail(p)) {			if (mgcpdebug) {				ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n", 					ast->name, p->name, p->parent->name);			}			transmit_notify_request(sub, "L/vmwi(+)");		} else {			if (mgcpdebug) {				ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n", 					ast->name, p->name, p->parent->name);			}			transmit_notify_request(sub, "L/vmwi(-)");		}	}	ast_mutex_unlock(&sub->lock);	return 0;}static int mgcp_show_endpoints(int fd, int argc, char *argv[]){	struct mgcp_gateway  *g;	struct mgcp_endpoint *e;	int hasendpoints = 0;	if (argc != 3) 		return RESULT_SHOWUSAGE;	ast_mutex_lock(&gatelock);	g = gateways;	while(g) {		e = g->endpoints;		ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(g->addr.sin_addr) : ast_inet_ntoa(g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static");		while(e) {			/* Don't show wilcard endpoint */			if (strcmp(e->name, g->wcardep) !=0)				ast_cli(fd, "   -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle");			hasendpoints = 1;			e = e->next;		}		if (!hasendpoints) {			ast_cli(fd, "   << No Endpoints Defined >>     ");		}		g = g->next;	}	ast_mutex_unlock(&gatelock);	return RESULT_SUCCESS;}static char show_endpoints_usage[] = "Usage: mgcp show endpoints\n""       Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";static char audit_endpoint_usage[] = "Usage: mgcp audit endpoint <endpointid>\n""       Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n""       mgcp debug MUST be on to see the results of this command.\n";static char debug_usage[] = "Usage: mgcp set debug\n""       Enables dumping of MGCP packets for debugging purposes\n";static char no_debug_usage[] = "Usage: mgcp set debug off\n""       Disables dumping of MGCP packets for debugging purposes\n";static char mgcp_reload_usage[] ="Usage: mgcp reload\n""       Reloads MGCP configuration from mgcp.conf\n""       Deprecated:  please use 'reload chan_mgcp.so' instead.\n";static int mgcp_audit_endpoint(int fd, int argc, char *argv[]){	struct mgcp_gateway  *g;	struct mgcp_endpoint *e;	int found = 0;	char *ename,*gname, *c;	if (!mgcpdebug) {		return RESULT_SHOWUSAGE;	}	if (argc != 4) 		return RESULT_SHOWUSAGE;	/* split the name into parts by null */	ename = argv[3];	gname = ename;	while (*gname) {		if (*gname == '@') {			*gname = 0;			gname++;			break;		}		gname++;	}	if (gname[0] == '[')		gname++;	if ((c = strrchr(gname, ']')))		*c = '\0';	ast_mutex_lock(&gatelock);	g = gateways;	while(g) {		if (!strcasecmp(g->name, gname)) {			e = g->endpoints;			while(e) {				if (!strcasecmp(e->name, ename)) {					found = 1;					transmit_audit_endpoint(e);					break;				}				e = e->next;			}			if (found) {				break;			}		}		g = g->next;	}	if (!found) {		ast_cli(fd, "   << Could not find endpoint >>     ");	}	ast_mutex_unlock(&gatelock);	return RESULT_SUCCESS;}static int mgcp_do_debug(int fd, int argc, char *argv[]){	if (argc != 3)		return RESULT_SHOWUSAGE;	mgcpdebug = 1;	ast_cli(fd, "MGCP Debugging Enabled\n");	return RESULT_SUCCESS;}static int mgcp_no_debug(int fd, int argc, char *argv[]){	if (argc != 4)		return RESULT_SHOWUSAGE;	mgcpdebug = 0;	ast_cli(fd, "MGCP Debugging Disabled\n");	return RESULT_SUCCESS;}static struct ast_cli_entry cli_mgcp[] = {	{ { "mgcp", "audit", "endpoint", NULL },	mgcp_audit_endpoint, "Audit specified MGCP endpoint",	audit_endpoint_usage },	{ { "mgcp", "show", "endpoints", NULL },	mgcp_show_endpoints, "List defined MGCP endpoints",	show_endpoints_usage },	{ { "mgcp", "set", "debug", NULL },	mgcp_do_debug, "Enable MGCP debugging",	debug_usage },	{ { "mgcp", "set", "debug", "off", NULL },	mgcp_no_debug, "Disable MGCP debugging",	no_debug_usage },	{ { "mgcp", "reload", NULL },	mgcp_reload, "Reload MGCP configuration",	mgcp_reload_usage },};static int mgcp_answer(struct ast_channel *ast){	int res = 0;	struct mgcp_subchannel *sub = ast->tech_pvt;	struct mgcp_endpoint *p = sub->parent;	ast_mutex_lock(&sub->lock);	sub->cxmode = MGCP_CX_SENDRECV;	if (!sub->rtp) {		start_rtp(sub);	} else {		transmit_modify_request(sub);	}	/* verbose level check */	if (option_verbose > 2) {		ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_answer(%s) on %s@%s-%d\n", 			ast->name, p->name, p->parent->name, sub->id);	}	if (ast->_state != AST_STATE_UP) {		ast_setstate(ast, AST_STATE_UP);		if (option_debug)			ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name);		transmit_notify_request(sub, "");		transmit_modify_request(sub);	}	ast_mutex_unlock(&sub->lock);	return res;}static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub){	/* Retrieve audio/etc from channel.  Assumes sub->lock is already held. */	struct ast_frame *f;	f = ast_rtp_read(sub->rtp);	/* Don't send RFC2833 if we're not supposed to */	if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833))		return &ast_null_frame;	if (sub->owner) {		/* We already hold the channel lock */		if (f->frametype == AST_FRAME_VOICE) {			if (f->subclass != sub->owner->nativeformats) {				ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);				sub->owner->nativeformats = f->subclass;				ast_set_read_format(sub->owner, sub->owner->readformat);				ast_set_write_format(sub->owner, sub->owner->writeformat);			}			/* Courtesy fearnor aka alex@pilosoft.com */			if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {#if 0				ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n");#endif				f = ast_dsp_process(sub->owner, sub->parent->dsp, f);			}		}	}	return f;}static struct ast_frame *mgcp_read(struct ast_channel *ast){	struct ast_frame *f;	struct mgcp_subchannel *sub = ast->tech_pvt;	ast_mutex_lock(&sub->lock);	f = mgcp_rtp_read(sub);	ast_mutex_unlock(&sub->lock);	return f;}static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame){	struct mgcp_subchannel *sub = ast->tech_pvt;	int res = 0;	if (frame->frametype != AST_FRAME_VOICE) {		if (frame->frametype == AST_FRAME_IMAGE)			return 0;		else {			ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype);			return 0;		}	} else {		if (!(frame->subclass & ast->nativeformats)) {			ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",				frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat);			return -1;		}	}	if (sub) {		ast_mutex_lock(&sub->lock);		if ((sub->parent->sub == sub) || !sub->parent->singlepath) {			if (sub->rtp) {				res =  ast_rtp_write(sub->rtp, frame);			}		}		ast_mutex_unlock(&sub->lock);	}	return res;}static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan){	struct mgcp_subchannel *sub = newchan->tech_pvt;	ast_mutex_lock(&sub->lock);	ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);	if (sub->owner != oldchan) {		ast_mutex_unlock(&sub->lock);		ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);		return -1;	}	sub->owner = newchan;	ast_mutex_unlock(&sub->lock);	return 0;}static int mgcp_senddigit_begin(struct ast_channel *ast, char digit){	struct mgcp_subchannel *sub = ast->tech_pvt;	struct mgcp_endpoint *p = sub->parent;	int res = 0;	ast_mutex_lock(&sub->lock);	if (p->dtmfmode & MGCP_DTMF_INBAND || p->dtmfmode & MGCP_DTMF_HYBRID) {		ast_log(LOG_DEBUG, "Sending DTMF using inband/hybrid\n");		res = -1; /* Let asterisk play inband indications */	} else if (p->dtmfmode & MGCP_DTMF_RFC2833) {		ast_log(LOG_DEBUG, "Sending DTMF using RFC2833");		ast_rtp_senddigit_begin(sub->rtp, digit);	} else {		ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);	}	ast_mutex_unlock(&sub->lock);	return res;}static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration){	struct mgcp_subchannel *sub = ast->tech_pvt;	struct mgcp_endpoint *p = sub->parent;	int res = 0;	char tmp[4];	ast_mutex_lock(&sub->lock);	if (p->dtmfmode & MGCP_DTMF_INBAND || p->dtmfmode & MGCP_DTMF_HYBRID) {		ast_log(LOG_DEBUG, "Stopping DTMF using inband/hybrid\n");		res = -1; /* Tell Asterisk to stop inband indications */	} else if (p->dtmfmode & MGCP_DTMF_RFC2833) {		ast_log(LOG_DEBUG, "Stopping DTMF using RFC2833\n");		tmp[0] = 'D';		tmp[1] = '/';		tmp[2] = digit;		tmp[3] = '\0';		transmit_notify_request(sub, tmp);                ast_rtp_senddigit_end(sub->rtp, digit);	} else {		ast_log(LOG_ERROR, "Don't know about DTMF_MODE %d\n", p->dtmfmode);	}	ast_mutex_unlock(&sub->lock);	return res;}/*! *  \brief  mgcp_devicestate: channel callback for device status monitoring *  \param  data tech/resource name of MGCP device to query * * Callback for device state management in channel subsystem * to obtain device status (up/down) of a specific MGCP endpoint * *  \return device status result (from devicestate.h) AST_DEVICE_INVALID (not available) or AST_DEVICE_UNKNOWN (available but unknown state) */static int mgcp_devicestate(void *data){	struct mgcp_gateway  *g;	struct mgcp_endpoint *e = NULL;	char *tmp, *endpt, *gw;	int ret = AST_DEVICE_INVALID;	endpt = ast_strdupa(data);	if ((tmp = strchr(endpt, '@'))) {		*tmp++ = '\0';		gw = tmp;	} else		goto error;	ast_mutex_lock(&gatelock);	g = gateways;	while (g) {		if (strcasecmp(g->name, gw) == 0) {			e = g->endpoints;			break;		}		g = g->next;	}	if (!e)		goto error;	while (e) {		if (strcasecmp(e->name, endpt) == 0)			break;		e = e->next;	}	if (!e)		goto error;	/*	 * As long as the gateway/endpoint is valid, we'll	 * assume that the device is available and its state	 * can be tracked.	 */	ret = AST_DEVICE_UNKNOWN;error:	ast_mutex_unlock(&gatelock);	return ret;}static char *control2str(int ind) {	switch (ind) {	case AST_CONTROL_HANGUP:		return "Other end has hungup";	case AST_CONTROL_RING:		return "Local ring";	case AST_CONTROL_RINGING:		return "Remote end is ringing";	case AST_CONTROL_ANSWER:		return "Remote end has answered";	case AST_CONTROL_BUSY:		return "Remote end is busy";	case AST_CONTROL_TAKEOFFHOOK:		return "Make it go off hook";	case AST_CONTROL_OFFHOOK:		return "Line is off hook";	case AST_CONTROL_CONGESTION:		return "Congestion (circuits busy)";	case AST_CONTROL_FLASH:		return "Flash hook";	case AST_CONTROL_WINK:		return "Wink";	case AST_CONTROL_OPTION:		return "Set a low-level option";	case AST_CONTROL_RADIO_KEY:		return "Key Radio";	case AST_CONTROL_RADIO_UNKEY:		return "Un-Key Radio";	}	return "UNKNOWN";}static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen){	struct mgcp_subchannel *sub = ast->tech_pvt;	int res = 0;	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "MGCP asked to indicate %d '%s' condition on channel %s\n",			ind, control2str(ind), ast->name);	}	ast_mutex_lock(&sub->lock);	switch(ind) {	case AST_CONTROL_RINGING:#ifdef DLINK_BUGGY_FIRMWARE			transmit_notify_request(sub, "rt");#else

⌨️ 快捷键说明

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