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

📄 chan_iax2.c

📁 Asterisk中信道部分的源码 。。。。
💻 C
📖 第 1 页 / 共 5 页
字号:
	int dropped;	int ooo;};struct chan_iax2_pvt {	/*! Socket to send/receive on for this call */	int sockfd;	/*! Last received voice format */	int voiceformat;	/*! Last received video format */	int videoformat;	/*! Last sent voice format */	int svoiceformat;	/*! Last sent video format */	int svideoformat;	/*! What we are capable of sending */	int capability;	/*! Last received timestamp */	unsigned int last;	/*! Last sent timestamp - never send the same timestamp twice in a single call */	unsigned int lastsent;	/*! Timestamp of the last video frame sent */	unsigned int lastvsent;	/*! Next outgoing timestamp if everything is good */	unsigned int nextpred;	/*! True if the last voice we transmitted was not silence/CNG */	int notsilenttx;	/*! Ping time */	unsigned int pingtime;	/*! Max time for initial response */	int maxtime;	/*! Peer Address */	struct sockaddr_in addr;	/*! Actual used codec preferences */	struct ast_codec_pref prefs;	/*! Requested codec preferences */	struct ast_codec_pref rprefs;	/*! Our call number */	unsigned short callno;	/*! Peer callno */	unsigned short peercallno;	/*! Negotiated format, this is only used to remember what format was	    chosen for an unauthenticated call so that the channel can get	    created later using the right format */	int chosenformat;	/*! Peer selected format */	int peerformat;	/*! Peer capability */	int peercapability;	/*! timeval that we base our transmission on */	struct timeval offset;	/*! timeval that we base our delivery on */	struct timeval rxcore;	/*! The jitterbuffer */        jitterbuf *jb;	/*! active jb read scheduler id */        int jbid;                       	/*! LAG */	int lag;	/*! Error, as discovered by the manager */	int error;	/*! Owner if we have one */	struct ast_channel *owner;	/*! What's our state? */	struct ast_flags state;	/*! Expiry (optional) */	int expiry;	/*! Next outgoing sequence number */	unsigned char oseqno;	/*! Next sequence number they have not yet acknowledged */	unsigned char rseqno;	/*! Next incoming sequence number */	unsigned char iseqno;	/*! Last incoming sequence number we have acknowledged */	unsigned char aseqno;	AST_DECLARE_STRING_FIELDS(		/*! Peer name */		AST_STRING_FIELD(peer);		/*! Default Context */		AST_STRING_FIELD(context);		/*! Caller ID if available */		AST_STRING_FIELD(cid_num);		AST_STRING_FIELD(cid_name);		/*! Hidden Caller ID (i.e. ANI) if appropriate */		AST_STRING_FIELD(ani);		/*! DNID */		AST_STRING_FIELD(dnid);		/*! RDNIS */		AST_STRING_FIELD(rdnis);		/*! Requested Extension */		AST_STRING_FIELD(exten);		/*! Expected Username */		AST_STRING_FIELD(username);		/*! Expected Secret */		AST_STRING_FIELD(secret);		/*! MD5 challenge */		AST_STRING_FIELD(challenge);		/*! Public keys permitted keys for incoming authentication */		AST_STRING_FIELD(inkeys);		/*! Private key for outgoing authentication */		AST_STRING_FIELD(outkey);		/*! Preferred language */		AST_STRING_FIELD(language);		/*! Hostname/peername for naming purposes */		AST_STRING_FIELD(host);		AST_STRING_FIELD(dproot);		AST_STRING_FIELD(accountcode);		AST_STRING_FIELD(mohinterpret);		AST_STRING_FIELD(mohsuggest);	);		/*! permitted authentication methods */	int authmethods;	/*! permitted encryption methods */	int encmethods;	/*! Encryption AES-128 Key */	aes_encrypt_ctx ecx;	/*! Decryption AES-128 Key */	aes_decrypt_ctx dcx;	/*! 32 bytes of semi-random data */	unsigned char semirand[32];	/*! Associated registry */	struct iax2_registry *reg;	/*! Associated peer for poking */	struct iax2_peer *peerpoke;	/*! IAX_ flags */	unsigned int flags;	int adsi;	/*! Transferring status */	enum iax_transfer_state transferring;	/*! Transfer identifier */	int transferid;	/*! Who we are IAX transfering to */	struct sockaddr_in transfer;	/*! What's the new call number for the transfer */	unsigned short transfercallno;	/*! Transfer decrypt AES-128 Key */	aes_encrypt_ctx tdcx;	/*! Status of knowledge of peer ADSI capability */	int peeradsicpe;	/*! Who we are bridged to */	unsigned short bridgecallno;		int pingid;			/*!< Transmit PING request */	int lagid;			/*!< Retransmit lag request */	int autoid;			/*!< Auto hangup for Dialplan requestor */	int authid;			/*!< Authentication rejection ID */	int authfail;			/*!< Reason to report failure */	int initid;			/*!< Initial peer auto-congest ID (based on qualified peers) */	int calling_ton;	int calling_tns;	int calling_pres;	int amaflags;	struct iax2_dpcache *dpentries;	struct ast_variable *vars;	/*! last received remote rr */	struct iax_rr remote_rr;	/*! Current base time: (just for stats) */	int min;	/*! Dropped frame count: (just for stats) */	int frames_dropped;	/*! received frame count: (just for stats) */	int frames_received;};static struct ast_iax2_queue {	AST_LIST_HEAD(, iax_frame) queue;	int count;} iaxq;/*! * This module will get much higher performance when doing a lot of * user and peer lookups if the number of buckets is increased from 1. * However, to maintain old behavior for Asterisk 1.4, these are set to * 1 by default.  When using multiple buckets, search order through these * containers is considered random, so you will not be able to depend on * the order the entires are specified in iax.conf for matching order. */#ifdef LOW_MEMORY#define MAX_PEER_BUCKETS 1/* #define MAX_PEER_BUCKETS 17 */#else#define MAX_PEER_BUCKETS 1/* #define MAX_PEER_BUCKETS 563 */#endifstatic struct ao2_container *peers;#define MAX_USER_BUCKETS MAX_PEER_BUCKETSstatic struct ao2_container *users;static struct ast_firmware_list {	struct iax_firmware *wares;	ast_mutex_t lock;} waresl;/*! Extension exists */#define CACHE_FLAG_EXISTS		(1 << 0)/*! Extension is nonexistent */#define CACHE_FLAG_NONEXISTENT		(1 << 1)/*! Extension can exist */#define CACHE_FLAG_CANEXIST		(1 << 2)/*! Waiting to hear back response */#define CACHE_FLAG_PENDING		(1 << 3)/*! Timed out */#define CACHE_FLAG_TIMEOUT		(1 << 4)/*! Request transmitted */#define CACHE_FLAG_TRANSMITTED		(1 << 5)/*! Timeout */#define CACHE_FLAG_UNKNOWN		(1 << 6)/*! Matchmore */#define CACHE_FLAG_MATCHMORE		(1 << 7)static struct iax2_dpcache {	char peercontext[AST_MAX_CONTEXT];	char exten[AST_MAX_EXTENSION];	struct timeval orig;	struct timeval expiry;	int flags;	unsigned short callno;	int waiters[256];	struct iax2_dpcache *next;	struct iax2_dpcache *peer;	/*!< For linking in peers */} *dpcache;AST_MUTEX_DEFINE_STATIC(dpcache_lock);static void reg_source_db(struct iax2_peer *p);static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);#define IAX_IOSTATE_IDLE		0#define IAX_IOSTATE_READY		1#define IAX_IOSTATE_PROCESSING	2#define IAX_IOSTATE_SCHEDREADY	3#define IAX_TYPE_POOL    1#define IAX_TYPE_DYNAMIC 2struct iax2_pkt_buf {	AST_LIST_ENTRY(iax2_pkt_buf) entry;	size_t len;	unsigned char buf[1];};struct iax2_thread {	AST_LIST_ENTRY(iax2_thread) list;	int type;	int iostate;#ifdef SCHED_MULTITHREADED	void (*schedfunc)(const void *);	const void *scheddata;#endif#ifdef DEBUG_SCHED_MULTITHREAD	char curfunc[80];#endif		int actions;	pthread_t threadid;	int threadnum;	struct sockaddr_in iosin;	unsigned char readbuf[4096]; 	unsigned char *buf;	ssize_t buf_len;	size_t buf_size;	int iofd;	time_t checktime;	ast_mutex_t lock;	ast_cond_t cond;	unsigned int ready_for_signal:1;	/*! if this thread is processing a full frame,	  some information about that frame will be stored	  here, so we can avoid dispatching any more full	  frames for that callno to other threads */	struct {		unsigned short callno;		struct sockaddr_in sin;		unsigned char type;		unsigned char csub;	} ffinfo;	/*! Queued up full frames for processing.  If more full frames arrive for	 *  a call which this thread is already processing a full frame for, they	 *  are queued up here. */	AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;};/* Thread lists */static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);static AST_LIST_HEAD_STATIC(active_list, iax2_thread);static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);static void *iax2_process_thread(void *data);static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond){	ast_mutex_lock(lock);	ast_cond_signal(cond);	ast_mutex_unlock(lock);}static void iax_debug_output(const char *data){	if (iaxdebug)		ast_verbose("%s", data);}static void iax_error_output(const char *data){	ast_log(LOG_WARNING, "%s", data);}static void jb_error_output(const char *fmt, ...){	va_list args;	char buf[1024];	va_start(args, fmt);	vsnprintf(buf, 1024, fmt, args);	va_end(args);	ast_log(LOG_ERROR, buf);}static void jb_warning_output(const char *fmt, ...){	va_list args;	char buf[1024];	va_start(args, fmt);	vsnprintf(buf, 1024, fmt, args);	va_end(args);	ast_log(LOG_WARNING, buf);}static void jb_debug_output(const char *fmt, ...){	va_list args;	char buf[1024];	va_start(args, fmt);	vsnprintf(buf, 1024, fmt, args);	va_end(args);	ast_verbose(buf);}/* XXX We probably should use a mutex when working with this XXX */static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];static struct timeval lastused[ARRAY_LEN(iaxs)];/*! * \brief Another container of iax2_pvt structures * * Active IAX2 pvt structs are also stored in this container, if they are a part * of an active call where we know the remote side's call number.  The reason * for this is that incoming media frames do not contain our call number.  So, * instead of having to iterate the entire iaxs array, we use this container to * look up calls where the remote side is using a given call number. */static struct ao2_container *iax_peercallno_pvts;/* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use   but keeps the division between trunked and non-trunked better. */#define TRUNK_CALL_START	ARRAY_LEN(iaxs) / 2static int maxtrunkcall = TRUNK_CALL_START;static int maxnontrunkcall = 1;static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);static int expire_registry(const void *data);static int iax2_answer(struct ast_channel *c);static int iax2_call(struct ast_channel *c, char *dest, int timeout);static int iax2_devicestate(void *data);static int iax2_digit_begin(struct ast_channel *c, char digit);static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);static int iax2_do_register(struct iax2_registry *reg);static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);static int iax2_hangup(struct ast_channel *c);static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);static int iax2_sendtext(struct ast_channel *c, const char *text);static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);static int iax2_transfer(struct ast_channel *c, const char *dest);static int iax2_write(struct ast_channel *c, struct ast_frame *f);static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);static struct ast_frame *iax2_read(struct ast_channel *c);static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);static void prune_peers(void);static const struct ast_channel_tech iax2_tech = {	.type = "IAX2",	.description = tdesc,	.capabilities = IAX_CAPABILITY_FULLBANDWIDTH,	.properties = AST_CHAN_TP_WANTSJITTER,	.requester = iax2_request,	.devicestate = iax2_devicestate,	.send_digit_begin = iax2_digit_begin,	.send_digit_end = iax2_digit_end,	.send_text = iax2_sendtext,	.send_image = iax2_sendimage,	.send_html = iax2_sendhtml,	.call = iax2_call,	.hangup = iax2_hangup,	.answer = iax2_answer,	.read = iax2_read,	.write = iax2_write,	.write_video = iax2_write,	.indicate = iax2_indicate,	.setoption = iax2_setoption,	.bridge = iax2_bridge,	.transfer = iax2_transfer,	.fixup = iax2_fixup,};/* WARNING: insert_idle_thread should only ever be called within the * context of an iax2_process_thread() thread. */static void insert_idle_thread(struct iax2_thread *thread){	if (thread->type == IAX_TYPE_DYNAMIC) {		AST_LIST_LOCK(&dynamic_list);		AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);		AST_LIST_UNLOCK(&dynamic_list);	} else {		AST_LIST_LOCK(&idle_list);		AST_LIST_INSERT_TAIL(&idle_list, thread, list);		AST_LIST_UNLOCK(&idle_list);	}	return;}static struct iax2_thread *find_idle_thread(void){	pthread_attr_t attr;	struct iax2_thread *thread = NULL;	/* Pop the head of the list off */	AST_LIST_LOCK(&idle_list);	thread = AST_LIST_REMOVE_HEAD(&idle_list, list);	AST_LIST_UNLOCK(&idle_list);

⌨️ 快捷键说明

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