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

📄 chan_gtalk.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2005, Digium, Inc. * * Matt O'Gorman <mogorman@digium.com> * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. *//*! \file * * \author Matt O'Gorman <mogorman@digium.com> * * \brief Gtalk Channel Driver, until google/libjingle works with jingle spec *  * \ingroup channel_drivers *//*** MODULEINFO	<depend>iksemel</depend>	<depend>res_jabber</depend>	<use>gnutls</use> ***/#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 139283 $")#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <errno.h>#include <stdlib.h>#include <fcntl.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/signal.h>#include <iksemel.h>#include <pthread.h>#ifdef HAVE_GNUTLS#include <gcrypt.h>GCRY_THREAD_OPTION_PTHREAD_IMPL;#endif /* HAVE_GNUTLS */#include "asterisk/lock.h"#include "asterisk/channel.h"#include "asterisk/config.h"#include "asterisk/logger.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/options.h"#include "asterisk/lock.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/rtp.h"#include "asterisk/acl.h"#include "asterisk/callerid.h"#include "asterisk/file.h"#include "asterisk/cli.h"#include "asterisk/app.h"#include "asterisk/musiconhold.h"#include "asterisk/manager.h"#include "asterisk/stringfields.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/astobj.h"#include "asterisk/abstract_jb.h"#include "asterisk/jabber.h"#define GOOGLE_CONFIG "gtalk.conf"#define GOOGLE_NS "http://www.google.com/session"/*! Global jitterbuffer configuration - by default, jb is disabled */static struct ast_jb_conf default_jbconf ={	.flags = 0,	.max_size = -1,	.resync_threshold = -1,	.impl = ""};static struct ast_jb_conf global_jbconf;enum gtalk_protocol {	AJI_PROTOCOL_UDP = 1,	AJI_PROTOCOL_SSLTCP = 2,};enum gtalk_connect_type {	AJI_CONNECT_STUN = 1,	AJI_CONNECT_LOCAL = 2,	AJI_CONNECT_RELAY = 3,};struct gtalk_pvt {	ast_mutex_t lock;                /*!< Channel private lock */	time_t laststun;	struct gtalk *parent;	         /*!< Parent client */	char sid[100];	char us[AJI_MAX_JIDLEN];	char them[AJI_MAX_JIDLEN];	char ring[10];                   /*!< Message ID of ring */	iksrule *ringrule;               /*!< Rule for matching RING request */	int initiator;                   /*!< If we're the initiator */	int alreadygone;	int capability;	struct ast_codec_pref prefs;	struct gtalk_candidate *theircandidates;	struct gtalk_candidate *ourcandidates;	char cid_num[80];                /*!< Caller ID num */	char cid_name[80];               /*!< Caller ID name */	char exten[80];                  /*!< Called extension */	struct ast_channel *owner;       /*!< Master Channel */	struct ast_rtp *rtp;             /*!< RTP audio session */	struct ast_rtp *vrtp;            /*!< RTP video session */	int jointcapability;             /*!< Supported capability at both ends (codecs ) */	int peercapability;	struct gtalk_pvt *next;	/* Next entity */};struct gtalk_candidate {	char name[100];	enum gtalk_protocol protocol;	double preference;	char username[100];	char password[100];	enum gtalk_connect_type type;	char network[6];	int generation;	char ip[16];	int port;	int receipt;	struct gtalk_candidate *next;};struct gtalk {	ASTOBJ_COMPONENTS(struct gtalk);	struct aji_client *connection;	struct aji_buddy *buddy;	struct gtalk_pvt *p;	struct ast_codec_pref prefs;	int amaflags;			/*!< AMA Flags */	char user[AJI_MAX_JIDLEN];	char context[AST_MAX_CONTEXT];	char accountcode[AST_MAX_ACCOUNT_CODE];	/*!< Account code */	int capability;	ast_group_t callgroup;	/*!< Call group */	ast_group_t pickupgroup;	/*!< Pickup group */	int callingpres;		/*!< Calling presentation */	int allowguest;	char language[MAX_LANGUAGE];	/*!<  Default language for prompts */	char musicclass[MAX_MUSICCLASS];	/*!<  Music on Hold class */};struct gtalk_container {	ASTOBJ_CONTAINER_COMPONENTS(struct gtalk);};static const char desc[] = "Gtalk Channel";static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) *//* Forward declarations */static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause);static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);static int gtalk_digit_begin(struct ast_channel *ast, char digit);static int gtalk_digit_end(struct ast_channel *ast, char digit, unsigned int duration);static int gtalk_call(struct ast_channel *ast, char *dest, int timeout);static int gtalk_hangup(struct ast_channel *ast);static int gtalk_answer(struct ast_channel *ast);static int gtalk_action(struct gtalk *client, struct gtalk_pvt *p, const char *action);static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p);static int gtalk_newcall(struct gtalk *client, ikspak *pak);static struct ast_frame *gtalk_read(struct ast_channel *ast);static int gtalk_write(struct ast_channel *ast, struct ast_frame *f);static int gtalk_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid);static int gtalk_do_reload(int fd, int argc, char **argv);static int gtalk_show_channels(int fd, int argc, char **argv);/*----- RTP interface functions */static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp,							   struct ast_rtp *vrtp, int codecs, int nat_active);static enum ast_rtp_get_result gtalk_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp);static int gtalk_get_codec(struct ast_channel *chan);/*! \brief PBX interface structure for channel registration */static const struct ast_channel_tech gtalk_tech = {	.type = "Gtalk",	.description = "Gtalk Channel Driver",	.capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),	.requester = gtalk_request,	.send_digit_begin = gtalk_digit_begin,	.send_digit_end = gtalk_digit_end,	.bridge = ast_rtp_bridge,	.call = gtalk_call,	.hangup = gtalk_hangup,	.answer = gtalk_answer,	.read = gtalk_read,	.write = gtalk_write,	.exception = gtalk_read,	.indicate = gtalk_indicate,	.fixup = gtalk_fixup,	.send_html = gtalk_sendhtml,	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER};static struct sockaddr_in bindaddr = { 0, };	/*!< The address we bind to */static struct sched_context *sched;	/*!< The scheduling context */static struct io_context *io;	/*!< The IO context */static struct in_addr __ourip;/*! \brief RTP driver interface */static struct ast_rtp_protocol gtalk_rtp = {	type: "Gtalk",	get_rtp_info: gtalk_get_rtp_peer,	set_rtp_peer: gtalk_set_rtp_peer,	get_codec: gtalk_get_codec,};static char show_channels_usage[] = "Usage: gtalk show channels\n" "       Shows current state of the Gtalk channels.\n";static char reload_usage[] = "Usage: gtalk reload\n" "       Reload gtalk channel driver.\n";static struct ast_cli_entry gtalk_cli[] = {	{{ "gtalk", "reload", NULL}, gtalk_do_reload, "Reload GoogleTalk configuration", reload_usage },	{{ "gtalk", "show", "channels", NULL}, gtalk_show_channels, "Show GoogleTalk channels", show_channels_usage }, };static char externip[16];static struct gtalk_container gtalk_list;static void gtalk_member_destroy(struct gtalk *obj){	free(obj);}static struct gtalk *find_gtalk(char *name, char *connection){	struct gtalk *gtalk = NULL;	char *domain = NULL , *s = NULL;	if(strchr(connection, '@')) {		s = ast_strdupa(connection);		domain = strsep(&s, "@");		ast_verbose("OOOOH domain = %s\n", domain);	}	gtalk = ASTOBJ_CONTAINER_FIND(&gtalk_list, name);	if (!gtalk && strchr(name, '@'))		gtalk = ASTOBJ_CONTAINER_FIND_FULL(&gtalk_list, name, user,,, strcasecmp);	if (!gtalk) {		/* guest call */		ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {			ASTOBJ_RDLOCK(iterator);			if (!strcasecmp(iterator->name, "guest")) {				gtalk = iterator;			}			ASTOBJ_UNLOCK(iterator);			if (gtalk)				break;		});	}	return gtalk;}static int add_codec_to_answer(const struct gtalk_pvt *p, int codec, iks *dcodecs){	int res = 0;	char *format = ast_getformatname(codec);	if (!strcasecmp("ulaw", format)) {		iks *payload_eg711u, *payload_pcmu;		payload_pcmu = iks_new("payload-type");		payload_eg711u = iks_new("payload-type");			if(!payload_eg711u || !payload_pcmu) {			if(payload_pcmu)				iks_delete(payload_pcmu);			if(payload_eg711u)				iks_delete(payload_eg711u);			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_pcmu, "id", "0");		iks_insert_attrib(payload_pcmu, "name", "PCMU");		iks_insert_attrib(payload_pcmu, "clockrate","8000");		iks_insert_attrib(payload_pcmu, "bitrate","64000");		iks_insert_attrib(payload_eg711u, "id", "100");		iks_insert_attrib(payload_eg711u, "name", "EG711U");		iks_insert_attrib(payload_eg711u, "clockrate","8000");		iks_insert_attrib(payload_eg711u, "bitrate","64000");		iks_insert_node(dcodecs, payload_pcmu);		iks_insert_node(dcodecs, payload_eg711u);		res ++;	}	if (!strcasecmp("alaw", format)) {		iks *payload_eg711a, *payload_pcma;		payload_pcma = iks_new("payload-type");		payload_eg711a = iks_new("payload-type");		if(!payload_eg711a || !payload_pcma) {			if(payload_eg711a)				iks_delete(payload_eg711a);			if(payload_pcma)				iks_delete(payload_pcma);			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_pcma, "id", "8");		iks_insert_attrib(payload_pcma, "name", "PCMA");		iks_insert_attrib(payload_pcma, "clockrate","8000");		iks_insert_attrib(payload_pcma, "bitrate","64000");		payload_eg711a = iks_new("payload-type");		iks_insert_attrib(payload_eg711a, "id", "101");		iks_insert_attrib(payload_eg711a, "name", "EG711A");		iks_insert_attrib(payload_eg711a, "clockrate","8000");		iks_insert_attrib(payload_eg711a, "bitrate","64000");		iks_insert_node(dcodecs, payload_pcma);		iks_insert_node(dcodecs, payload_eg711a);		res ++;	}	if (!strcasecmp("ilbc", format)) {		iks *payload_ilbc = iks_new("payload-type");		if(!payload_ilbc) {			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_ilbc, "id", "97");		iks_insert_attrib(payload_ilbc, "name", "iLBC");		iks_insert_attrib(payload_ilbc, "clockrate","8000");		iks_insert_attrib(payload_ilbc, "bitrate","13300");		iks_insert_node(dcodecs, payload_ilbc);		res ++;	}	if (!strcasecmp("g723", format)) {		iks *payload_g723 = iks_new("payload-type");		if(!payload_g723) {			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_g723, "id", "4");		iks_insert_attrib(payload_g723, "name", "G723");		iks_insert_attrib(payload_g723, "clockrate","8000");		iks_insert_attrib(payload_g723, "bitrate","6300");		iks_insert_node(dcodecs, payload_g723);		res ++;	}	if (!strcasecmp("speex", format)) {		iks *payload_speex = iks_new("payload-type");		if(!payload_speex) {			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_speex, "id", "110");		iks_insert_attrib(payload_speex, "name", "speex");		iks_insert_attrib(payload_speex, "clockrate","8000");		iks_insert_attrib(payload_speex, "bitrate","11000");		iks_insert_node(dcodecs, payload_speex);		res++;	}	if (!strcasecmp("gsm", format)) {		iks *payload_gsm = iks_new("payload-type");		if(!payload_gsm) {			ast_log(LOG_WARNING,"Failed to allocate iks node");			return -1;		}		iks_insert_attrib(payload_gsm, "id", "103");		iks_insert_attrib(payload_gsm, "name", "gsm");		iks_insert_node(dcodecs, payload_gsm);		res++;	}	ast_rtp_lookup_code(p->rtp, 1, codec);	return res;}static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, int initiator){	struct gtalk *client = p->parent;	iks *iq, *gtalk, *dcodecs, *payload_telephone, *transport;	int x;	int pref_codec = 0;	int alreadysent = 0;	int codecs_num = 0;

⌨️ 快捷键说明

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