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

📄 chan_gtalk.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	iq = iks_new("iq");	gtalk = iks_new("session");	dcodecs = iks_new("description");	transport = iks_new("transport");	payload_telephone = iks_new("payload-type");	if (!(iq && gtalk && dcodecs && transport && payload_telephone)){		if(iq)			iks_delete(iq);		if(gtalk)			iks_delete(gtalk);		if(dcodecs)			iks_delete(dcodecs);		if(transport)			iks_delete(transport);		if(payload_telephone)			iks_delete(payload_telephone);		ast_log(LOG_ERROR, "Could not allocate iksemel nodes\n");		return 0;	}	iks_insert_attrib(dcodecs, "xmlns", "http://www.google.com/session/phone");	iks_insert_attrib(dcodecs, "xml:lang", "en");	for (x = 0; x < 32; x++) {		if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))			break;		if (!(client->capability & pref_codec))			continue;		if (alreadysent & pref_codec)			continue;		codecs_num = add_codec_to_answer(p, pref_codec, dcodecs);		alreadysent |= pref_codec;	}		if (codecs_num) {		/* only propose DTMF within an audio session */		iks_insert_attrib(payload_telephone, "id", "106");		iks_insert_attrib(payload_telephone, "name", "telephone-event");		iks_insert_attrib(payload_telephone, "clockrate", "8000");	}	iks_insert_attrib(transport,"xmlns","http://www.google.com/transport/p2p");		iks_insert_attrib(iq, "type", "set");	iks_insert_attrib(iq, "to", to);	iks_insert_attrib(iq, "from", from);	iks_insert_attrib(iq, "id", client->connection->mid);	ast_aji_increment_mid(client->connection->mid);	iks_insert_attrib(gtalk, "xmlns", "http://www.google.com/session");	iks_insert_attrib(gtalk, "type",initiator ? "initiate": "accept");	iks_insert_attrib(gtalk, "initiator", initiator ? from : to);	iks_insert_attrib(gtalk, "id", sid);	iks_insert_node(iq, gtalk);	iks_insert_node(gtalk, dcodecs);	iks_insert_node(gtalk, transport);	iks_insert_node(dcodecs, payload_telephone);	iks_send(client->connection->p, iq);	iks_delete(payload_telephone);	iks_delete(transport);	iks_delete(dcodecs);	iks_delete(gtalk);	iks_delete(iq);	return 1;}static int gtalk_invite_response(struct gtalk_pvt *p, char *to , char *from, char *sid, int initiator){	iks *iq, *session, *transport;	iq = iks_new("iq");	session = iks_new("session");	transport = iks_new("transport");	if(!(iq && session && transport)) {		if(iq)			iks_delete(iq);		if(session)			iks_delete(session);		if(transport)			iks_delete(transport);		ast_log(LOG_ERROR, " Unable to allocate IKS node\n");		return -1;	}	iks_insert_attrib(iq, "from", from);	iks_insert_attrib(iq, "to", to);	iks_insert_attrib(iq, "type", "set");	iks_insert_attrib(iq, "id",p->parent->connection->mid);	ast_aji_increment_mid(p->parent->connection->mid);	iks_insert_attrib(session, "type", "transport-accept");	iks_insert_attrib(session, "id", sid);	iks_insert_attrib(session, "initiator", initiator ? from : to);	iks_insert_attrib(session, "xmlns", "http://www.google.com/session");	iks_insert_attrib(transport, "xmlns", "http://www.google.com/transport/p2p");	iks_insert_node(iq,session);	iks_insert_node(session,transport);	iks_send(p->parent->connection->p, iq);	iks_delete(transport);	iks_delete(session);	iks_delete(iq);	return 1;}static int gtalk_ringing_ack(void *data, ikspak *pak){	struct gtalk_pvt *p = data;	if (p->ringrule)		iks_filter_remove_rule(p->parent->connection->f, p->ringrule);	p->ringrule = NULL;	if (p->owner)		ast_queue_control(p->owner, AST_CONTROL_RINGING);	return IKS_FILTER_EAT;}static int gtalk_answer(struct ast_channel *ast){	struct gtalk_pvt *p = ast->tech_pvt;	int res = 0;		if (option_debug)		ast_log(LOG_DEBUG, "Answer!\n");	ast_mutex_lock(&p->lock);	gtalk_invite(p, p->them, p->us,p->sid, 0);	ast_mutex_unlock(&p->lock);	return res;}static enum ast_rtp_get_result gtalk_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp){	struct gtalk_pvt *p = chan->tech_pvt;	enum ast_rtp_get_result res = AST_RTP_GET_FAILED;	if (!p)		return res;	ast_mutex_lock(&p->lock);	if (p->rtp){		*rtp = p->rtp;		res = AST_RTP_TRY_PARTIAL;	}	ast_mutex_unlock(&p->lock);	return res;}static int gtalk_get_codec(struct ast_channel *chan){	struct gtalk_pvt *p = chan->tech_pvt;	return p->peercapability;}static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active){	struct gtalk_pvt *p;	p = chan->tech_pvt;	if (!p)		return -1;	ast_mutex_lock(&p->lock);/*	if (rtp)		ast_rtp_get_peer(rtp, &p->redirip);	else		memset(&p->redirip, 0, sizeof(p->redirip));	p->redircodecs = codecs; */	/* Reset lastrtprx timer */	ast_mutex_unlock(&p->lock);	return 0;}static int gtalk_response(struct gtalk *client, char *from, ikspak *pak, const char *reasonstr, const char *reasonstr2){	iks *response = NULL, *error = NULL, *reason = NULL;	int res = -1;	response = iks_new("iq");	if (response) {		iks_insert_attrib(response, "type", "result");		iks_insert_attrib(response, "from", from);		iks_insert_attrib(response, "to", iks_find_attrib(pak->x, "from"));		iks_insert_attrib(response, "id", iks_find_attrib(pak->x, "id"));		if (reasonstr) {			error = iks_new("error");			if (error) {				iks_insert_attrib(error, "type", "cancel");				reason = iks_new(reasonstr);				if (reason)					iks_insert_node(error, reason);				iks_insert_node(response, error);			}		}		iks_send(client->connection->p, response);		if (reason)			iks_delete(reason);		if (error)			iks_delete(error);		iks_delete(response);		res = 0;	}	return res;}static int gtalk_is_answered(struct gtalk *client, ikspak *pak){	struct gtalk_pvt *tmp;	char *from;	iks *codec;	char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ];	int peernoncodeccapability;	ast_log(LOG_DEBUG, "The client is %s\n", client->name);	/* Make sure our new call doesn't exist yet */	for (tmp = client->p; tmp; tmp = tmp->next) {		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))			break;	}	/* codec points to the first <payload-type/> tag */	codec = iks_child(iks_child(iks_child(pak->x)));	while (codec) {		ast_rtp_set_m_type(tmp->rtp, atoi(iks_find_attrib(codec, "id")));		ast_rtp_set_rtpmap_type(tmp->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);		codec = iks_next(codec);	}		/* Now gather all of the codecs that we are asked for */	ast_rtp_get_current_formats(tmp->rtp, &tmp->peercapability, &peernoncodeccapability);		/* at this point, we received an awser from the remote Gtalk client,	   which allows us to compare capabilities */	tmp->jointcapability = tmp->capability & tmp->peercapability;	if (!tmp->jointcapability) {		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->capability),			ast_getformatname_multiple(s2, BUFSIZ, tmp->peercapability),			ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcapability));		/* close session if capabilities don't match */		ast_queue_hangup(tmp->owner);		return -1;	}			from = iks_find_attrib(pak->x, "to");	if(!from)		from = client->connection->jid->full;	if (tmp) {		if (tmp->owner)			ast_queue_control(tmp->owner, AST_CONTROL_ANSWER);	} else		ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");	gtalk_response(client, from, pak, NULL, NULL);	return 1;}static int gtalk_is_accepted(struct gtalk *client, ikspak *pak){	struct gtalk_pvt *tmp;	char *from;	ast_log(LOG_DEBUG, "The client is %s\n", client->name);	/* find corresponding call */	for (tmp = client->p; tmp; tmp = tmp->next) {		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))			break;	}	from = iks_find_attrib(pak->x, "to");	if(!from)		from = client->connection->jid->full;	if (!tmp)		ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");	/* answer 'iq' packet to let the remote peer know that we're alive */	gtalk_response(client, from, pak, NULL, NULL);	return 1;}static int gtalk_handle_dtmf(struct gtalk *client, ikspak *pak){	struct gtalk_pvt *tmp;	iks *dtmfnode = NULL, *dtmfchild = NULL;	char *dtmf;	char *from;	/* Make sure our new call doesn't exist yet */	for (tmp = client->p; tmp; tmp = tmp->next) {		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || iks_find_with_attrib(pak->x, "gtalk", "sid", tmp->sid))			break;	}	from = iks_find_attrib(pak->x, "to");	if(!from)		from = client->connection->jid->full;	if (tmp) {		if(iks_find_with_attrib(pak->x, "dtmf-method", "method", "rtp")) {			gtalk_response(client, from, pak,					"feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'",					"unsupported-dtmf-method xmlns='http://jabber.org/protocol/gtalk/info/dtmf#errors'");			return -1;		}		if ((dtmfnode = iks_find(pak->x, "dtmf"))) {			if((dtmf = iks_find_attrib(dtmfnode, "code"))) {				if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-up")) {					struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };					f.subclass = dtmf[0];					ast_queue_frame(tmp->owner, &f);					ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);				} else if(iks_find_with_attrib(pak->x, "dtmf", "action", "button-down")) {					struct ast_frame f = {AST_FRAME_DTMF_END, };					f.subclass = dtmf[0];					ast_queue_frame(tmp->owner, &f);					ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);				} else if(iks_find_attrib(pak->x, "dtmf")) { /* 250 millasecond default */					struct ast_frame f = {AST_FRAME_DTMF, };					f.subclass = dtmf[0];					ast_queue_frame(tmp->owner, &f);					ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);				}			}		} else if ((dtmfnode = iks_find_with_attrib(pak->x, "gtalk", "action", "session-info"))) {			if((dtmfchild = iks_find(dtmfnode, "dtmf"))) {				if((dtmf = iks_find_attrib(dtmfchild, "code"))) {					if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-up")) {						struct ast_frame f = {AST_FRAME_DTMF_END, };						f.subclass = dtmf[0];						ast_queue_frame(tmp->owner, &f);						ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);					} else if(iks_find_with_attrib(dtmfnode, "dtmf", "action", "button-down")) {						struct ast_frame f = {AST_FRAME_DTMF_BEGIN, };						f.subclass = dtmf[0];						ast_queue_frame(tmp->owner, &f);						ast_verbose("GOOGLE! DTMF-relay event received: %c\n", f.subclass);					}				}			}		}		gtalk_response(client, from, pak, NULL, NULL);		return 1;	} else		ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");	gtalk_response(client, from, pak, NULL, NULL);	return 1;}static int gtalk_hangup_farend(struct gtalk *client, ikspak *pak){	struct gtalk_pvt *tmp;	char *from;	ast_log(LOG_DEBUG, "The client is %s\n", client->name);	/* Make sure our new call doesn't exist yet */	for (tmp = client->p; tmp; tmp = tmp->next) {		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))			break;	}	from = iks_find_attrib(pak->x, "to");	if(!from)		from = client->connection->jid->full;	if (tmp) {		tmp->alreadygone = 1;		if (tmp->owner)			ast_queue_hangup(tmp->owner);	} else		ast_log(LOG_NOTICE, "Whoa, didn't find call!\n");	gtalk_response(client, from, pak, NULL, NULL);	return 1;}static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, char *sid, char *from, char *to){	struct gtalk_candidate *tmp;	struct aji_client *c = client->connection;	struct gtalk_candidate *ours1 = NULL, *ours2 = NULL;	struct sockaddr_in sin;	struct sockaddr_in dest;	struct in_addr us;	iks *iq, *gtalk, *candidate, *transport;	char user[17], pass[17], preference[5], port[7];	iq = iks_new("iq");	gtalk = iks_new("session");	candidate = iks_new("candidate");	transport = iks_new("transport");	if (!iq || !gtalk || !candidate || !transport) {		ast_log(LOG_ERROR, "Memory allocation error\n");		goto safeout;	}	ours1 = ast_calloc(1, sizeof(*ours1));	ours2 = ast_calloc(1, sizeof(*ours2));	if (!ours1 || !ours2)		goto safeout;	iks_insert_attrib(transport, "xmlns","http://www.google.com/transport/p2p");	iks_insert_node(iq, gtalk);	iks_insert_node(gtalk,transport);	iks_insert_node(transport, candidate);	for (; p; p = p->next) {		if (!strcasecmp(p->sid, sid))			break;	}	if (!p) {		ast_log(LOG_NOTICE, "No matching gtalk session - SID %s!\n", sid);		goto safeout;	}	ast_rtp_get_us(p->rtp, &sin);

⌨️ 快捷键说明

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