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

📄 chan_iax2.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2006, Digium, Inc. * * Mark Spencer <markster@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 * * \brief Implementation of Inter-Asterisk eXchange Version 2 * * \author Mark Spencer <markster@digium.com> * * \par See also * \arg \ref Config_iax * * \ingroup channel_drivers *//*** MODULEINFO	<use>dahdi</use>        <depend>res_features</depend> ***/#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 140605 $")#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/mman.h>#include <dirent.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <sys/time.h>#include <sys/signal.h>#include <signal.h>#include <string.h>#include <strings.h>#include <errno.h>#include <unistd.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>#include <regex.h>#if defined(HAVE_ZAPTEL) || defined (HAVE_DAHDI)#include <sys/ioctl.h>#include "asterisk/dahdi_compat.h"#endif#include "asterisk/lock.h"#include "asterisk/frame.h" #include "asterisk/channel.h"#include "asterisk/logger.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/config.h"#include "asterisk/options.h"#include "asterisk/cli.h"#include "asterisk/translate.h"#include "asterisk/md5.h"#include "asterisk/cdr.h"#include "asterisk/crypto.h"#include "asterisk/acl.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/app.h"#include "asterisk/astdb.h"#include "asterisk/musiconhold.h"#include "asterisk/features.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/localtime.h"#include "asterisk/aes.h"#include "asterisk/dnsmgr.h"#include "asterisk/devicestate.h"#include "asterisk/netsock.h"#include "asterisk/stringfields.h"#include "asterisk/linkedlists.h"#include "asterisk/astobj2.h"#include "iax2.h"#include "iax2-parser.h"#include "iax2-provision.h"#include "jitterbuf.h"/* Define SCHED_MULTITHREADED to run the scheduler in a special   multithreaded mode. */#define SCHED_MULTITHREADED/* Define DEBUG_SCHED_MULTITHREADED to keep track of where each   thread is actually doing. */#define DEBUG_SCHED_MULTITHREAD#ifndef IPTOS_MINCOST#define IPTOS_MINCOST 0x02#endif#ifdef SO_NO_CHECKstatic int nochecksums = 0;#endif#define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))#define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))#define DEFAULT_THREAD_COUNT 10#define DEFAULT_MAX_THREAD_COUNT 100#define DEFAULT_RETRY_TIME 1000#define MEMORY_SIZE 100#define DEFAULT_DROP 3#define DEBUG_SUPPORT#define MIN_REUSE_TIME		60	/* Don't reuse a call number within 60 seconds *//* Sample over last 100 units to determine historic jitter */#define GAMMA (0.01)static struct ast_codec_pref prefs;static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";static char context[80] = "default";static char language[MAX_LANGUAGE] = "";static char regcontext[AST_MAX_CONTEXT] = "";static int maxauthreq = 3;static int max_retries = 4;static int ping_time = 21;static int lagrq_time = 10;static int maxjitterbuffer=1000;static int resyncthreshold=1000;static int maxjitterinterps=10;static int trunkfreq = 20;static int authdebug = 1;static int autokill = 0;static int iaxcompat = 0;static int iaxdefaultdpcache=10 * 60;	/* Cache dialplan entries for 10 minutes by default */static int iaxdefaulttimeout = 5;		/* Default to wait no more than 5 seconds for a reply to come back */static unsigned int tos = 0;static int min_reg_expire;static int max_reg_expire;static int timingfd = -1;				/* Timing file descriptor */static struct ast_netsock_list *netsock;static struct ast_netsock_list *outsock;		/*!< used if sourceaddress specified and bindaddr == INADDR_ANY */static int defaultsockfd = -1;int (*iax2_regfunk)(const char *username, int onoff) = NULL;/* Ethernet, etc */#define IAX_CAPABILITY_FULLBANDWIDTH 	0xFFFF/* T1, maybe ISDN */#define IAX_CAPABILITY_MEDBANDWIDTH 	(IAX_CAPABILITY_FULLBANDWIDTH & 	\					 ~AST_FORMAT_SLINEAR &			\					 ~AST_FORMAT_ULAW &			\					 ~AST_FORMAT_ALAW &			\					 ~AST_FORMAT_G722) /* A modem */#define IAX_CAPABILITY_LOWBANDWIDTH	(IAX_CAPABILITY_MEDBANDWIDTH & 		\					 ~AST_FORMAT_G726 &			\					 ~AST_FORMAT_G726_AAL2 &		\					 ~AST_FORMAT_ADPCM)#define IAX_CAPABILITY_LOWFREE		(IAX_CAPABILITY_LOWBANDWIDTH & 		\					 ~AST_FORMAT_G723_1)#define DEFAULT_MAXMS		2000		/* Must be faster than 2 seconds by default */#define DEFAULT_FREQ_OK		60 * 1000	/* How often to check for the host to be up */#define DEFAULT_FREQ_NOTOK	10 * 1000	/* How often to check, if the host is down... */static	struct io_context *io;static	struct sched_context *sched;static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;static int iaxdebug = 0;static int iaxtrunkdebug = 0;static int test_losspct = 0;#ifdef IAXTESTSstatic int test_late = 0;static int test_resync = 0;static int test_jit = 0;static int test_jitpct = 0;#endif /* IAXTESTS */static char accountcode[AST_MAX_ACCOUNT_CODE];static char mohinterpret[MAX_MUSICCLASS];static char mohsuggest[MAX_MUSICCLASS];static int amaflags = 0;static int adsi = 0;static int delayreject = 0;static int iax2_encryption = 0;static struct ast_flags globalflags = { 0 };static pthread_t netthreadid = AST_PTHREADT_NULL;static pthread_t schedthreadid = AST_PTHREADT_NULL;AST_MUTEX_DEFINE_STATIC(sched_lock);static ast_cond_t sched_cond;enum {	IAX_STATE_STARTED = 		(1 << 0),	IAX_STATE_AUTHENTICATED = 	(1 << 1),	IAX_STATE_TBD = 		(1 << 2),	IAX_STATE_UNCHANGED = 		(1 << 3),} iax2_state;struct iax2_context {	char context[AST_MAX_CONTEXT];	struct iax2_context *next;};enum {	IAX_HASCALLERID = 	(1 << 0),	/*!< CallerID has been specified */	IAX_DELME =		(1 << 1),	/*!< Needs to be deleted */	IAX_TEMPONLY =		(1 << 2),	/*!< Temporary (realtime) */	IAX_TRUNK =		(1 << 3),	/*!< Treat as a trunk */	IAX_NOTRANSFER =	(1 << 4),	/*!< Don't native bridge */	IAX_USEJITTERBUF =	(1 << 5),	/*!< Use jitter buffer */	IAX_DYNAMIC =		(1 << 6),	/*!< dynamic peer */	IAX_SENDANI = 		(1 << 7),	/*!< Send ANI along with CallerID */        /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */	IAX_ALREADYGONE =	(1 << 9),	/*!< Already disconnected */	IAX_PROVISION =		(1 << 10),	/*!< This is a provisioning request */	IAX_QUELCH = 		(1 << 11),	/*!< Whether or not we quelch audio */	IAX_ENCRYPTED =		(1 << 12),	/*!< Whether we should assume encrypted tx/rx */	IAX_KEYPOPULATED = 	(1 << 13),	/*!< Whether we have a key populated */	IAX_CODEC_USER_FIRST = 	(1 << 14),	/*!< are we willing to let the other guy choose the codec? */	IAX_CODEC_NOPREFS =  	(1 << 15), 	/*!< Force old behaviour by turning off prefs */	IAX_CODEC_NOCAP = 	(1 << 16),	/*!< only consider requested format and ignore capabilities*/	IAX_RTCACHEFRIENDS = 	(1 << 17), 	/*!< let realtime stay till your reload */	IAX_RTUPDATE = 		(1 << 18), 	/*!< Send a realtime update */	IAX_RTAUTOCLEAR = 	(1 << 19), 	/*!< erase me on expire */ 	IAX_FORCEJITTERBUF =	(1 << 20),	/*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 	IAX_RTIGNOREREGEXPIRE =	(1 << 21),	/*!< When using realtime, ignore registration expiration */	IAX_TRUNKTIMESTAMPS =	(1 << 22),	/*!< Send trunk timestamps */	IAX_TRANSFERMEDIA = 	(1 << 23),      /*!< When doing IAX2 transfers, transfer media only */	IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */	IAX_DELAYPBXSTART =	(1 << 25),	/*!< Don't start a PBX on the channel until the peer sends us a						     response, so that we've achieved a three-way handshake with						     them before sending voice or anything else*/	IAX_ALLOWFWDOWNLOAD = (1 << 26),	/*!< Allow the FWDOWNL command? */} iax2_flags;static int global_rtautoclear = 120;static int reload_config(void);static int iax2_reload(int fd, int argc, char *argv[]);struct iax2_user {	AST_DECLARE_STRING_FIELDS(		AST_STRING_FIELD(name);		AST_STRING_FIELD(secret);		AST_STRING_FIELD(dbsecret);		AST_STRING_FIELD(accountcode);		AST_STRING_FIELD(mohinterpret);		AST_STRING_FIELD(mohsuggest);		AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */		AST_STRING_FIELD(language);		AST_STRING_FIELD(cid_num);		AST_STRING_FIELD(cid_name);	);		int authmethods;	int encmethods;	int amaflags;	int adsi;	unsigned int flags;	int capability;	int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */	int curauthreq; /*!< Current number of outstanding AUTHREQs */	struct ast_codec_pref prefs;	struct ast_ha *ha;	struct iax2_context *contexts;	struct ast_variable *vars;};struct iax2_peer {	AST_DECLARE_STRING_FIELDS(		AST_STRING_FIELD(name);		AST_STRING_FIELD(username);		AST_STRING_FIELD(secret);		AST_STRING_FIELD(dbsecret);		AST_STRING_FIELD(outkey);	    /*!< What key we use to talk to this peer */		AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */		AST_STRING_FIELD(context);      /*!< For transfers only */		AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */		AST_STRING_FIELD(mailbox);	    /*!< Mailbox */		AST_STRING_FIELD(mohinterpret);		AST_STRING_FIELD(mohsuggest);		AST_STRING_FIELD(inkeys);		/*!< Key(s) this peer can use to authenticate to us */		/* Suggested caller id if registering */		AST_STRING_FIELD(cid_num);		/*!< Default context (for transfer really) */		AST_STRING_FIELD(cid_name);		/*!< Default context (for transfer really) */		AST_STRING_FIELD(zonetag);		/*!< Time Zone */	);	struct ast_codec_pref prefs;	struct ast_dnsmgr_entry *dnsmgr;		/*!< DNS refresh manager */	struct sockaddr_in addr;	int formats;	int sockfd;					/*!< Socket to use for transmission */	struct in_addr mask;	int adsi;	unsigned int flags;	/* Dynamic Registration fields */	struct sockaddr_in defaddr;			/*!< Default address if there is one */	int authmethods;				/*!< Authentication methods (IAX_AUTH_*) */	int encmethods;					/*!< Encryption methods (IAX_ENCRYPT_*) */	int expire;					/*!< Schedule entry for expiry */	int expiry;					/*!< How soon to expire */	int capability;					/*!< Capability */	/* Qualification */	int callno;					/*!< Call number of POKE request */	int pokeexpire;					/*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */	int lastms;					/*!< How long last response took (in ms), or -1 for no response */	int maxms;					/*!< Max ms we will accept for the host to be up, 0 to not monitor */	int pokefreqok;					/*!< How often to check if the host is up */	int pokefreqnotok;				/*!< How often to check when the host has been determined to be down */	int historicms;					/*!< How long recent average responses took */	int smoothing;					/*!< Sample over how many units to determine historic ms */		struct ast_ha *ha;};#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))static struct iax2_trunk_peer {	ast_mutex_t lock;	int sockfd;	struct sockaddr_in addr;	struct timeval txtrunktime;		/*!< Transmit trunktime */	struct timeval rxtrunktime;		/*!< Receive trunktime */	struct timeval lasttxtime;		/*!< Last transmitted trunktime */	struct timeval trunkact;		/*!< Last trunk activity */	unsigned int lastsent;			/*!< Last sent time */	/* Trunk data and length */	unsigned char *trunkdata;	unsigned int trunkdatalen;	unsigned int trunkdataalloc;	struct iax2_trunk_peer *next;	int trunkerror;	int calls;} *tpeers = NULL;AST_MUTEX_DEFINE_STATIC(tpeerlock);struct iax_firmware {	struct iax_firmware *next;	int fd;	int mmaplen;	int dead;	struct ast_iax2_firmware_header *fwh;	unsigned char *buf;};enum iax_reg_state {	REG_STATE_UNREGISTERED = 0,	REG_STATE_REGSENT,	REG_STATE_AUTHSENT,	REG_STATE_REGISTERED,	REG_STATE_REJECTED,	REG_STATE_TIMEOUT,	REG_STATE_NOAUTH};enum iax_transfer_state {	TRANSFER_NONE = 0,	TRANSFER_BEGIN,	TRANSFER_READY,	TRANSFER_RELEASED,	TRANSFER_PASSTHROUGH,	TRANSFER_MBEGIN,	TRANSFER_MREADY,	TRANSFER_MRELEASED,	TRANSFER_MPASSTHROUGH,	TRANSFER_MEDIA,	TRANSFER_MEDIAPASS};struct iax2_registry {	struct sockaddr_in addr;		/*!< Who we connect to for registration purposes */	char username[80];	char secret[80];			/*!< Password or key name in []'s */	char random[80];	int expire;				/*!< Sched ID of expiration */	int refresh;				/*!< How often to refresh */	enum iax_reg_state regstate;	int messages;				/*!< Message count, low 8 bits = new, high 8 bits = old */	int callno;				/*!< Associated call number if applicable */	struct sockaddr_in us;			/*!< Who the server thinks we are */	struct ast_dnsmgr_entry *dnsmgr;	/*!< DNS refresh manager */	AST_LIST_ENTRY(iax2_registry) entry;};static AST_LIST_HEAD_STATIC(registrations, iax2_registry);/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */#define MIN_RETRY_TIME		100#define MAX_RETRY_TIME  	10000#define MAX_JITTER_BUFFER 	50#define MIN_JITTER_BUFFER 	10#define DEFAULT_TRUNKDATA	640 * 10	/*!< 40ms, uncompressed linear * 10 channels */#define MAX_TRUNKDATA		640 * 200	/*!< 40ms, uncompressed linear * 200 channels */#define MAX_TIMESTAMP_SKEW	160		/*!< maximum difference between actual and predicted ts for sending *//* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */#define TS_GAP_FOR_JB_RESYNC	5000static int iaxthreadcount = DEFAULT_THREAD_COUNT;static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;static int iaxdynamicthreadcount = 0;static int iaxdynamicthreadnum = 0;static int iaxactivethreadcount = 0;struct iax_rr {	int jitter;	int losspct;	int losscnt;	int packets;	int delay;

⌨️ 快捷键说明

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