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

📄 chan_mgcp.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	p->capability = capability & peercapability;	if (mgcpdebug) {		ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n",			capability, peercapability, p->capability);		ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n",			nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);	}	if (!p->capability) {		ast_log(LOG_WARNING, "No compatible codecs!\n");		return -1;	}	return 0;}static int add_header(struct mgcp_request *req, char *var, char *value){	if (req->len >= sizeof(req->data) - 4) {		ast_log(LOG_WARNING, "Out of space, can't add anymore\n");		return -1;	}	if (req->lines) {		ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");		return -1;	}	req->header[req->headers] = req->data + req->len;	snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value);	req->len += strlen(req->header[req->headers]);	if (req->headers < MGCP_MAX_HEADERS)		req->headers++;	else {		ast_log(LOG_WARNING, "Out of header space\n");		return -1;	}	return 0;	}static int add_line(struct mgcp_request *req, char *line){	if (req->len >= sizeof(req->data) - 4) {		ast_log(LOG_WARNING, "Out of space, can't add anymore\n");		return -1;	}	if (!req->lines) {		/* Add extra empty return */		snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");		req->len += strlen(req->data + req->len);	}	req->line[req->lines] = req->data + req->len;	snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line);	req->len += strlen(req->line[req->lines]);	if (req->lines < MGCP_MAX_LINES)		req->lines++;	else {		ast_log(LOG_WARNING, "Out of line space\n");		return -1;	}	return 0;	}static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest){	/* Initialize a response */	if (req->headers || req->len) {		ast_log(LOG_WARNING, "Request already initialized?!?\n");		return -1;	}	req->header[req->headers] = req->data + req->len;	snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest);	req->len += strlen(req->header[req->headers]);	if (req->headers < MGCP_MAX_HEADERS)		req->headers++;	else		ast_log(LOG_WARNING, "Out of header space\n");	return 0;}static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb){	/* Initialize a response */	if (req->headers || req->len) {		ast_log(LOG_WARNING, "Request already initialized?!?\n");		return -1;	}	req->header[req->headers] = req->data + req->len;	/* check if we need brackets around the gw name */	if (p->parent->isnamedottedip)		snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@[%s] MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name);	else		snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@%s MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name);	req->len += strlen(req->header[req->headers]);	if (req->headers < MGCP_MAX_HEADERS)		req->headers++;	else		ast_log(LOG_WARNING, "Out of header space\n");	return 0;}static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest){	memset(resp, 0, sizeof(*resp));	init_resp(resp, msg, req, msgrest);	return 0;}static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb){	memset(req, 0, sizeof(struct mgcp_request));	oseq++;	if (oseq > 999999999)		oseq = 1;	init_req(p, req, verb);	return 0;}static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest){	struct mgcp_request resp;	struct mgcp_endpoint *p = sub->parent;	struct mgcp_response *mgr;	respprep(&resp, p, msg, req, msgrest);	mgr = malloc(sizeof(struct mgcp_response) + resp.len + 1);	if (mgr) {		/* Store MGCP response in case we have to retransmit */		memset(mgr, 0, sizeof(struct mgcp_response));		sscanf(req->identifier, "%d", &mgr->seqno);		time(&mgr->whensent);		mgr->len = resp.len;		memcpy(mgr->buf, resp.data, resp.len);		mgr->buf[resp.len] = '\0';		mgr->next = p->parent->responses;		p->parent->responses = mgr;	}	return send_response(sub, &resp);}static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp *rtp){	int len;	int codec;	char costr[80];	struct sockaddr_in sin;	char v[256];	char s[256];	char o[256];	char c[256];	char t[256];	char m[256] = "";	char a[1024] = "";	int x;	struct sockaddr_in dest;	struct mgcp_endpoint *p = sub->parent;	/* XXX We break with the "recommendation" and send our IP, in order that our	       peer doesn't have to ast_gethostbyname() us XXX */	len = 0;	if (!sub->rtp) {		ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");		return -1;	}	ast_rtp_get_us(sub->rtp, &sin);	if (rtp) {		ast_rtp_get_peer(rtp, &dest);	} else {		if (sub->tmpdest.sin_addr.s_addr) {			dest.sin_addr = sub->tmpdest.sin_addr;			dest.sin_port = sub->tmpdest.sin_port;			/* Reset temporary destination */			memset(&sub->tmpdest, 0, sizeof(sub->tmpdest));		} else {			dest.sin_addr = p->parent->ourip;			dest.sin_port = sin.sin_port;		}	}	if (mgcpdebug) {		ast_verbose("We're at %s port %d\n", ast_inet_ntoa(p->parent->ourip), ntohs(sin.sin_port));	}	snprintf(v, sizeof(v), "v=0\r\n");	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", (int)getpid(), (int)getpid(), ast_inet_ntoa(dest.sin_addr));	snprintf(s, sizeof(s), "s=session\r\n");	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));	snprintf(t, sizeof(t), "t=0 0\r\n");	snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));	for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) {		if (p->capability & x) {			if (mgcpdebug) {				ast_verbose("Answering with capability %d\n", x);			}			codec = ast_rtp_lookup_code(sub->rtp, 1, x);			if (codec > -1) {				snprintf(costr, sizeof(costr), " %d", codec);				strncat(m, costr, sizeof(m) - strlen(m) - 1);				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x, 0));				strncat(a, costr, sizeof(a) - strlen(a) - 1);			}		}	}	for (x = 1; x <= AST_RTP_MAX; x <<= 1) {		if (p->nonCodecCapability & x) {			if (mgcpdebug) {				ast_verbose("Answering with non-codec capability %d\n", x);			}			codec = ast_rtp_lookup_code(sub->rtp, 0, x);			if (codec > -1) {				snprintf(costr, sizeof(costr), " %d", codec);				strncat(m, costr, sizeof(m) - strlen(m) - 1);				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x, 0));				strncat(a, costr, sizeof(a) - strlen(a) - 1);				if (x == AST_RTP_DTMF) {					/* Indicate we support DTMF...  Not sure about 16,					   but MSN supports it so dang it, we will too... */					snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec);					strncat(a, costr, sizeof(a) - strlen(a) - 1);				}			}		}	}	strncat(m, "\r\n", sizeof(m) - strlen(m) - 1);	len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);	snprintf(costr, sizeof(costr), "%d", len);	add_line(resp, v);	add_line(resp, o);	add_line(resp, s);	add_line(resp, c);	add_line(resp, t);	add_line(resp, m);	add_line(resp, a);	return 0;}static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs){	struct mgcp_request resp;	char local[256];	char tmp[80];	int x;	int capability;	struct mgcp_endpoint *p = sub->parent;	capability = p->capability;	if (codecs)		capability = codecs;	if (ast_strlen_zero(sub->cxident) && rtp) {		/* We don't have a CXident yet, store the destination and		   wait a bit */		ast_rtp_get_peer(rtp, &sub->tmpdest);		return 0;	}	snprintf(local, sizeof(local), "p:20");	for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {		if (p->capability & x) {			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, 0));			strncat(local, tmp, sizeof(local) - strlen(local) - 1);		}	}	reqprep(&resp, p, "MDCX");	add_header(&resp, "C", sub->callid);	add_header(&resp, "L", local);	add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);	/* X header should not be sent. kept for compatibility */	add_header(&resp, "X", sub->txident);	add_header(&resp, "I", sub->cxident);	/*add_header(&resp, "S", "");*/	add_sdp(&resp, sub, rtp);	/* fill in new fields */	resp.cmd = MGCP_CMD_MDCX;	resp.trid = oseq;	return send_request(p, sub, &resp, oseq); /* SC */}static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp){	struct mgcp_request resp;	char local[256];	char tmp[80];	int x;	struct mgcp_endpoint *p = sub->parent;	snprintf(local, sizeof(local), "p:20");	for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {		if (p->capability & x) {			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, 0));			strncat(local, tmp, sizeof(local) - strlen(local) - 1);		}	}	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", 			p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);	}	reqprep(&resp, p, "CRCX");	add_header(&resp, "C", sub->callid);	add_header(&resp, "L", local);	add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);	/* X header should not be sent. kept for compatibility */	add_header(&resp, "X", sub->txident);	/*add_header(&resp, "S", "");*/	add_sdp(&resp, sub, rtp);	/* fill in new fields */	resp.cmd = MGCP_CMD_CRCX;	resp.trid = oseq;	return send_request(p, sub, &resp, oseq);  /* SC */}static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone){	struct mgcp_request resp;	struct mgcp_endpoint *p = sub->parent;	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on  %s@%s-%d in cxmode: %s\n", 			tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);	}	ast_copy_string(p->curtone, tone, sizeof(p->curtone));	reqprep(&resp, p, "RQNT");	add_header(&resp, "X", p->rqnt_ident); /* SC */	switch (p->hookstate) {	case MGCP_ONHOOK:		add_header(&resp, "R", "L/hd(N)");		break;	case MGCP_OFFHOOK:		add_header_offhook(sub, &resp);		break;	}	if (!ast_strlen_zero(tone)) {		add_header(&resp, "S", tone);	}	/* fill in new fields */	resp.cmd = MGCP_CMD_RQNT;	resp.trid = oseq;	return send_request(p, NULL, &resp, oseq); /* SC */}static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername){	struct mgcp_request resp;	char tone2[256];	char *l, *n;	time_t t;	struct tm tm;	struct mgcp_endpoint *p = sub->parent;		time(&t);	ast_localtime(&t, &tm, NULL);	n = callername;	l = callernum;	if (!n)		n = "";	if (!l)		l = "";	/* Keep track of last callerid for blacklist and callreturn */	ast_copy_string(p->lastcallerid, l, sizeof(p->lastcallerid));	snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 		tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);	ast_copy_string(p->curtone, tone, sizeof(p->curtone));	reqprep(&resp, p, "RQNT");	add_header(&resp, "X", p->rqnt_ident); /* SC */	switch (p->hookstate) {	case MGCP_ONHOOK:		add_header(&resp, "R", "L/hd(N)");		break;	case MGCP_OFFHOOK:		add_header_offhook(sub, &resp);		break;	}	if (!ast_strlen_zero(tone2)) {		add_header(&resp, "S", tone2);	}	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on  %s@%s-%d in cxmode: %s\n", 			tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);	}	/* fill in new fields */	resp.cmd = MGCP_CMD_RQNT;	resp.trid = oseq;	return send_request(p, NULL, &resp, oseq);  /* SC */}static int transmit_modify_request(struct mgcp_subchannel *sub){	struct mgcp_request resp;	struct mgcp_endpoint *p = sub->parent;	if (ast_strlen_zero(sub->cxident)) {		/* We don't have a CXident yet, store the destination and		   wait a bit */		return 0;	}	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", 			p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);	}	reqprep(&resp, p, "MDCX");	add_header(&resp, "C", sub->callid);	add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);	/* X header should not be sent. kept for compatibility */	add_header(&resp, "X", sub->txident);	add_header(&resp, "I", sub->cxident);	switch (sub->parent->hookstate) {	case MGCP_ONHOOK:		add_header(&resp, "R", "L/hd(N)");		break;	case MGCP_OFFHOOK:		add_header_offhook(sub, &resp);		break;	}	/* fill in new fields */	resp.cmd = MGCP_CMD_MDCX;	resp.trid = oseq;	return send_request(p, sub, &resp, oseq); /* SC */}static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp){	struct mgcp_endpoint *p = sub->parent;	if (p && p->sub && p->sub->owner && p->sub->owner->_state >= AST_STATE_RINGING && (p->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)))		add_header(resp, "R", "L/hu(N),L/hf(N)");	else		add_header(resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");}static int transmit_audit_endpoint(struct mgcp_endpoint *p){	struct mgcp_request resp;	reqprep(&resp, p, "AUEP");	/* removed unknown param VS */	/*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/	add_header(&resp, "F", "A");	/* fill in new fields */	resp.cmd = MGCP_CMD_AUEP;	resp.trid = oseq;	return send_request(p, NULL, &resp, oseq);  /* SC */}static int transmit_connection_del(struct mgcp_subchannel *sub){	struct mgcp_endpoint *p = sub->parent;	struct mgcp_request resp;	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", 			sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);	}	reqprep(&resp, p, "DLCX");	/* check if call id is avail */	if (sub->callid[0])		add_header(&resp, "C", sub->callid);	/* X header should not be sent. kept for compatibility */	add_header(&resp, "X", sub->txident);	/* check if cxident is avail */	if (sub->cxident[0])		add_header(&resp, "I", sub->cxident);	/* fill in new fields */	resp.cmd = MGCP_CMD_DLCX;	resp.trid = oseq;	return send_request(p, sub, &resp, oseq);  /* SC */}static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident){	struct mgcp_request resp;	if (mgcpdebug) {		ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", 			cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");	}	reqprep(&resp, p, "DLCX");	/* check if call id is avail */	if (callid && *callid)		add_heade

⌨️ 快捷键说明

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