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

📄 chan_gtalk.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	ast_find_ourip(&us, bindaddr);	/* Setup our gtalk candidates */	ast_copy_string(ours1->name, "rtp", sizeof(ours1->name));	ours1->port = ntohs(sin.sin_port);	ours1->preference = 1;	snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());	snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());	ast_copy_string(ours1->username, user, sizeof(ours1->username));	ast_copy_string(ours1->password, pass, sizeof(ours1->password));	ast_copy_string(ours1->ip, ast_inet_ntoa(us), sizeof(ours1->ip));	ours1->protocol = AJI_PROTOCOL_UDP;	ours1->type = AJI_CONNECT_LOCAL;	ours1->generation = 0;	p->ourcandidates = ours1;	if (!ast_strlen_zero(externip)) {		/* XXX We should really stun for this one not just go with externip XXX */		snprintf(user, sizeof(user), "%08lx%08lx", ast_random(), ast_random());		snprintf(pass, sizeof(pass), "%08lx%08lx", ast_random(), ast_random());		ast_copy_string(ours2->username, user, sizeof(ours2->username));		ast_copy_string(ours2->password, pass, sizeof(ours2->password));		ast_copy_string(ours2->ip, externip, sizeof(ours2->ip));		ast_copy_string(ours2->name, "rtp", sizeof(ours1->name));		ours2->port = ntohs(sin.sin_port);		ours2->preference = 0.9;		ours2->protocol = AJI_PROTOCOL_UDP;		ours2->type = AJI_CONNECT_STUN;		ours2->generation = 0;		ours1->next = ours2;		ours2 = NULL;	}	ours1 = NULL;	dest.sin_addr = __ourip;	dest.sin_port = sin.sin_port;	for (tmp = p->ourcandidates; tmp; tmp = tmp->next) {		snprintf(port, sizeof(port), "%d", tmp->port);		snprintf(preference, sizeof(preference), "%.2f", tmp->preference);		iks_insert_attrib(iq, "from", to);		iks_insert_attrib(iq, "to", from);		iks_insert_attrib(iq, "type", "set");		iks_insert_attrib(iq, "id", c->mid);		ast_aji_increment_mid(c->mid);		iks_insert_attrib(gtalk, "type", "transport-info");		iks_insert_attrib(gtalk, "id", sid);		iks_insert_attrib(gtalk, "initiator", (p->initiator) ? to : from);		iks_insert_attrib(gtalk, "xmlns", GOOGLE_NS);		iks_insert_attrib(candidate, "name", tmp->name);		iks_insert_attrib(candidate, "address", tmp->ip);		iks_insert_attrib(candidate, "port", port);		iks_insert_attrib(candidate, "username", tmp->username);		iks_insert_attrib(candidate, "password", tmp->password);		iks_insert_attrib(candidate, "preference", preference);		if (tmp->protocol == AJI_PROTOCOL_UDP)			iks_insert_attrib(candidate, "protocol", "udp");		if (tmp->protocol == AJI_PROTOCOL_SSLTCP)			iks_insert_attrib(candidate, "protocol", "ssltcp");		if (tmp->type == AJI_CONNECT_STUN)			iks_insert_attrib(candidate, "type", "stun");		if (tmp->type == AJI_CONNECT_LOCAL)			iks_insert_attrib(candidate, "type", "local");		if (tmp->type == AJI_CONNECT_RELAY)			iks_insert_attrib(candidate, "type", "relay");		iks_insert_attrib(candidate, "network", "0");		iks_insert_attrib(candidate, "generation", "0");		iks_send(c->p, iq);	}	p->laststun = 0;safeout:	if (ours1)		free(ours1);	if (ours2)		free(ours2);	if (iq)		iks_delete(iq);	if (gtalk)		iks_delete(gtalk);	if (candidate)		iks_delete(candidate);	if(transport)		iks_delete(transport);	return 1;}static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid){	struct gtalk_pvt *tmp = NULL;	struct aji_resource *resources = NULL;	struct aji_buddy *buddy;	char idroster[200];	char *data, *exten = NULL;	if (option_debug)		ast_log(LOG_DEBUG, "The client is %s for alloc\n", client->name);	if (!sid && !strchr(them, '/')) {	/* I started call! */		if (!strcasecmp(client->name, "guest")) {			buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, them);			if (buddy)				resources = buddy->resources;		} else if (client->buddy)			resources = client->buddy->resources;		while (resources) {			if (resources->cap->jingle) {				break;			}			resources = resources->next;		}		if (resources)			snprintf(idroster, sizeof(idroster), "%s/%s", them, resources->resource);		else {			ast_log(LOG_ERROR, "no gtalk capable clients to talk to.\n");			return NULL;		}	}	if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {		return NULL;	}	if (sid) {		ast_copy_string(tmp->sid, sid, sizeof(tmp->sid));		ast_copy_string(tmp->them, them, sizeof(tmp->them));		ast_copy_string(tmp->us, us, sizeof(tmp->us));	} else {		snprintf(tmp->sid, sizeof(tmp->sid), "%08lx%08lx", ast_random(), ast_random());		ast_copy_string(tmp->them, idroster, sizeof(tmp->them));		ast_copy_string(tmp->us, us, sizeof(tmp->us));		tmp->initiator = 1;	}	/* clear codecs */	tmp->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);	ast_rtp_pt_clear(tmp->rtp);	/* add user configured codec capabilites */	if (client->capability)		tmp->capability = client->capability;	else if (global_capability)		tmp->capability = global_capability;	tmp->parent = client;	if (!tmp->rtp) {		ast_log(LOG_WARNING, "Out of RTP sessions?\n");		free(tmp);		return NULL;	}	/* Set CALLERID(name) to the full JID of the remote peer */	ast_copy_string(tmp->cid_name, tmp->them, sizeof(tmp->cid_name));	if(strchr(tmp->us, '/')) {		data = ast_strdupa(tmp->us);		exten = strsep(&data, "/");	} else		exten = tmp->us;	ast_copy_string(tmp->exten,  exten, sizeof(tmp->exten));	ast_mutex_init(&tmp->lock);	ast_mutex_lock(&gtalklock);	tmp->next = client->p;	client->p = tmp;	ast_mutex_unlock(&gtalklock);	return tmp;}/*! \brief Start new gtalk channel */static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title){	struct ast_channel *tmp;	int fmt;	int what;	const char *n2;	if (title)		n2 = title;	else		n2 = i->us;	tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);	if (!tmp) {		ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");		return NULL;	}	tmp->tech = &gtalk_tech;	/* Select our native format based on codec preference until we receive	   something from another device to the contrary. */	if (i->jointcapability)		what = i->jointcapability;	else if (i->capability)		what = i->capability;	else		what = global_capability;	tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);	fmt = ast_best_codec(tmp->nativeformats);	if (i->rtp) {		ast_rtp_setstun(i->rtp, 1);		tmp->fds[0] = ast_rtp_fd(i->rtp);		tmp->fds[1] = ast_rtcp_fd(i->rtp);	}	if (i->vrtp) {		ast_rtp_setstun(i->rtp, 1);		tmp->fds[2] = ast_rtp_fd(i->vrtp);		tmp->fds[3] = ast_rtcp_fd(i->vrtp);	}	if (state == AST_STATE_RING)		tmp->rings = 1;	tmp->adsicpe = AST_ADSI_UNAVAILABLE;	tmp->writeformat = fmt;	tmp->rawwriteformat = fmt;	tmp->readformat = fmt;	tmp->rawreadformat = fmt;	tmp->tech_pvt = i;	tmp->callgroup = client->callgroup;	tmp->pickupgroup = client->pickupgroup;	tmp->cid.cid_pres = client->callingpres;	if (!ast_strlen_zero(client->accountcode))		ast_string_field_set(tmp, accountcode, client->accountcode);	if (client->amaflags)		tmp->amaflags = client->amaflags;	if (!ast_strlen_zero(client->language))		ast_string_field_set(tmp, language, client->language);	if (!ast_strlen_zero(client->musicclass))		ast_string_field_set(tmp, musicclass, client->musicclass);	i->owner = tmp;	ast_module_ref(ast_module_info->self);	ast_copy_string(tmp->context, client->context, sizeof(tmp->context));	ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));	if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))		tmp->cid.cid_dnid = ast_strdup(i->exten);	tmp->priority = 1;	if (i->rtp)		ast_jb_configure(tmp, &global_jbconf);	if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {		ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);		tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;		ast_hangup(tmp);		tmp = NULL;	}	return tmp;}static int gtalk_action(struct gtalk *client, struct gtalk_pvt *p, const char *action){	iks *request, *session = NULL;	int res = -1;	request = iks_new("iq");	if (request) {		iks_insert_attrib(request, "type", "set");		iks_insert_attrib(request, "from", p->us);		iks_insert_attrib(request, "to", p->them);		iks_insert_attrib(request, "id", client->connection->mid);		ast_aji_increment_mid(client->connection->mid);		session = iks_new("session");		if (session) {			iks_insert_attrib(session, "type", action);			iks_insert_attrib(session, "id", p->sid);			iks_insert_attrib(session, "initiator", p->initiator ? p->us : p->them);			iks_insert_attrib(session, "xmlns", "http://www.google.com/session");			iks_insert_node(request, session);			iks_send(client->connection->p, request);			iks_delete(session);			res = 0;		}		iks_delete(request);	}	return res;}static void gtalk_free_candidates(struct gtalk_candidate *candidate){	struct gtalk_candidate *last;	while (candidate) {		last = candidate;		candidate = candidate->next;		free(last);	}}static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p){	struct gtalk_pvt *cur, *prev = NULL;	cur = client->p;	while (cur) {		if (cur == p) {			if (prev)				prev->next = p->next;			else				client->p = p->next;			break;		}		prev = cur;		cur = cur->next;	}	if (p->ringrule)		iks_filter_remove_rule(p->parent->connection->f, p->ringrule);	if (p->owner)		ast_log(LOG_WARNING, "Uh oh, there's an owner, this is going to be messy.\n");	if (p->rtp)		ast_rtp_destroy(p->rtp);	if (p->vrtp)		ast_rtp_destroy(p->vrtp);	gtalk_free_candidates(p->theircandidates);	free(p);}static int gtalk_newcall(struct gtalk *client, ikspak *pak){	struct gtalk_pvt *p, *tmp = client->p;	struct ast_channel *chan;	int res;	iks *codec;	char *from = NULL;	char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ];	int peernoncodeccapability;	/* Make sure our new call doesn't exist yet */	from = iks_find_attrib(pak->x,"to");	if(!from)		from = client->connection->jid->full;		while (tmp) {		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {			ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);			gtalk_response(client, from, pak, "out-of-order", NULL);			return -1;		}		tmp = tmp->next;	} 	if (!strcasecmp(client->name, "guest")){ 		/* the guest account is not tied to any configured XMPP client, 		   let's set it now */ 		client->connection = ast_aji_get_client(from); 		if (!client->connection) { 			ast_log(LOG_ERROR, "No XMPP client to talk to, us (partial JID) : %s\n", from); 			return -1; 		} 	}	p = gtalk_alloc(client, from, pak->from->full, iks_find_attrib(pak->query, "id"));	if (!p) {		ast_log(LOG_WARNING, "Unable to allocate gtalk structure!\n");		return -1;	}	chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user);	if (!chan) {		gtalk_free_pvt(client, p);		return -1;	}	ast_mutex_lock(&p->lock);	ast_copy_string(p->them, pak->from->full, sizeof(p->them));	if (iks_find_attrib(pak->query, "id")) {		ast_copy_string(p->sid, iks_find_attrib(pak->query, "id"),				sizeof(p->sid));	}	/* codec points to the first <payload-type/> tag */		codec = iks_child(iks_child(iks_child(pak->x)));		while (codec) {		ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));		ast_rtp_set_rtpmap_type(p->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(p->rtp, &p->peercapability, &peernoncodeccapability);	p->jointcapability = p->capability & p->peercapability;	ast_mutex_unlock(&p->lock);			ast_setstate(chan, AST_STATE_RING);	if (!p->jointcapability) {		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->capability),			ast_getformatname_multiple(s2, BUFSIZ, p->peercapability),			ast_getformatname_multiple(s3, BUFSIZ, p->jointcapability));		/* close session if capabilities don't match */		gtalk_action(client, p, "reject");		p->alreadygone = 1;		gtalk_hangup(chan);		ast_channel_free(chan);		return -1;	}		res = ast_pbx_start(chan);		switch (res) {	case AST_PBX_FAILED:		ast_log(LOG_WARNING, "Failed to start PBX :(\n");		gtalk_response(client, from, pak, "service-unavailable", NULL);		break;	case AST_PBX_CALL_LIMIT:		ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");		gtalk_response(client, from, pak, "service-unavailable", NULL);		break;	case AST_PBX_SUCCESS:		gtalk_response(client, from, pak, NULL, NULL);		gtalk_invite_response(p, p->them, p->us,p->sid, 0);		gtalk_create_candidates(client, p, p->sid, p->them, p->us);		/* nothing to do */		break;	}	return 1;}static int gtalk_update_stun(struct gtalk *client, struct gtalk_pvt *p){

⌨️ 快捷键说明

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