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

📄 chan_mgcp.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 Media Gateway Control Protocol * * \author Mark Spencer <markster@digium.com> * * \par See also * \arg \ref Config_mgcp * * \ingroup channel_drivers *//*** MODULEINFO        <depend>res_features</depend> ***/#include "asterisk.h"ASTERISK_FILE_VERSION(__FILE__, "$Revision: 123113 $")#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <errno.h>#include <stdlib.h>#include <fcntl.h>#include <netdb.h>#include <sys/signal.h>#include <signal.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <arpa/inet.h>#include <ctype.h>#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/cli.h"#include "asterisk/say.h"#include "asterisk/cdr.h"#include "asterisk/astdb.h"#include "asterisk/features.h"#include "asterisk/app.h"#include "asterisk/musiconhold.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/dsp.h"#include "asterisk/devicestate.h"#include "asterisk/stringfields.h"#include "asterisk/abstract_jb.h"#ifndef IPTOS_MINCOST#define IPTOS_MINCOST 0x02#endif/* * Define to work around buggy dlink MGCP phone firmware which * appears not to know that "rt" is part of the "G" package. *//* #define DLINK_BUGGY_FIRMWARE	*/#define MGCPDUMPER#define DEFAULT_EXPIRY	120#define MAX_EXPIRY	3600#define CANREINVITE	1#ifndef INADDR_NONE#define INADDR_NONE (in_addr_t)(-1)#endif/*! 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;static const char tdesc[] = "Media Gateway Control Protocol (MGCP)";static const char config[] = "mgcp.conf";#define MGCP_DTMF_RFC2833	(1 << 0)#define MGCP_DTMF_INBAND	(1 << 1)#define MGCP_DTMF_HYBRID	(1 << 2)#define DEFAULT_MGCP_GW_PORT	2427 /*!< From RFC 2705 */#define DEFAULT_MGCP_CA_PORT	2727 /*!< From RFC 2705 */#define MGCP_MAX_PACKET		1500 /*!< Also from RFC 2543, should sub headers tho */#define DEFAULT_RETRANS		1000 /*!< How frequently to retransmit */#define MAX_RETRANS		5    /*!< Try only 5 times for retransmissions *//*! MGCP rtp stream modes { */#define MGCP_CX_SENDONLY	0#define MGCP_CX_RECVONLY	1#define MGCP_CX_SENDRECV	2#define MGCP_CX_CONF		3#define MGCP_CX_CONFERENCE	3#define MGCP_CX_MUTE		4#define MGCP_CX_INACTIVE	4/*! } */static char *mgcp_cxmodes[] = {	"sendonly",	"recvonly",	"sendrecv",	"confrnce",	"inactive"};enum {	MGCP_CMD_EPCF,	MGCP_CMD_CRCX,	MGCP_CMD_MDCX,	MGCP_CMD_DLCX,	MGCP_CMD_RQNT,	MGCP_CMD_NTFY,	MGCP_CMD_AUEP,	MGCP_CMD_AUCX,	MGCP_CMD_RSIP};static char context[AST_MAX_EXTENSION] = "default";static char language[MAX_LANGUAGE] = "";static char musicclass[MAX_MUSICCLASS] = "";static char cid_num[AST_MAX_EXTENSION] = "";static char cid_name[AST_MAX_EXTENSION] = "";static int dtmfmode = 0;static int nat = 0;static ast_group_t cur_callergroup = 0;static ast_group_t cur_pickupgroup = 0;static int tos = 0;static int immediate = 0;static int callwaiting = 0;static int callreturn = 0;static int slowsequence = 0;static int threewaycalling = 0;/*! This is for flashhook transfers */static int transfer = 0;static int cancallforward = 0;static int singlepath = 0;static int canreinvite = CANREINVITE;static char accountcode[AST_MAX_ACCOUNT_CODE] = "";static char mailbox[AST_MAX_EXTENSION];static int amaflags = 0;static int adsi = 0;static unsigned int oseq;/*! Wait up to 16 seconds for first digit (FXO logic) */static int firstdigittimeout = 16000;/*! How long to wait for following digits (FXO logic) */static int gendigittimeout = 8000;/*! How long to wait for an extra digit, if there is an ambiguous match */static int matchdigittimeout = 3000;/*! Protect the monitoring thread, so only one process can kill or start it, and not    when it's doing something critical. */AST_MUTEX_DEFINE_STATIC(netlock);AST_MUTEX_DEFINE_STATIC(monlock);/*! This is the thread for the monitor which checks for input on the channels    which are not currently in use. */static pthread_t monitor_thread = AST_PTHREADT_NULL;static int restart_monitor(void);static int capability = AST_FORMAT_ULAW;static int nonCodecCapability = AST_RTP_DTMF;static char ourhost[MAXHOSTNAMELEN];static struct in_addr __ourip;static int ourport;static int mgcpdebug = 0;static struct sched_context *sched;static struct io_context *io;/*! The private structures of the  mgcp channels are linked for  ! selecting outgoing channels */   #define MGCP_MAX_HEADERS	64#define MGCP_MAX_LINES		64struct mgcp_request {	int len;	char *verb;	char *identifier;	char *endpoint;	char *version;	int headers;			/*!< MGCP Headers */	char *header[MGCP_MAX_HEADERS];	int lines;			/*!< SDP Content */	char *line[MGCP_MAX_LINES];	char data[MGCP_MAX_PACKET];	int cmd;                        /*!< int version of verb = command */	unsigned int trid;              /*!< int version of identifier = transaction id */	struct mgcp_request *next;      /*!< next in the queue */};/*! \brief mgcp_message: MGCP message for queuing up */struct mgcp_message {	struct mgcp_endpoint *owner_ep;	struct mgcp_subchannel *owner_sub;	int retrans;	unsigned long expire;	unsigned int seqno;	int len;	struct mgcp_message *next;	char buf[0];};#define RESPONSE_TIMEOUT 30	/*!< in seconds */struct mgcp_response {	time_t whensent;	int len;	int seqno;	struct mgcp_response *next;	char buf[0];};#define MAX_SUBS 2#define SUB_REAL 0#define SUB_ALT  1struct mgcp_subchannel {	/*! subchannel magic string. 	   Needed to prove that any subchannel pointer passed by asterisk 	   really points to a valid subchannel memory area.	   Ugly.. But serves the purpose for the time being.	 */#define MGCP_SUBCHANNEL_MAGIC "!978!"	char magic[6]; 	ast_mutex_t lock;	int id;	struct ast_channel *owner;	struct mgcp_endpoint *parent;	struct ast_rtp *rtp;	struct sockaddr_in tmpdest;	char txident[80]; /*! \todo FIXME txident is replaced by rqnt_ident in endpoint. 			This should be obsoleted */	char cxident[80];	char callid[80];	int cxmode;	struct mgcp_request *cx_queue; /*!< pending CX commands */	ast_mutex_t cx_queue_lock;     /*!< CX queue lock */	int nat;	int iseq;                      /*!< Not used? RTP? */	int outgoing;	int alreadygone;	struct mgcp_subchannel *next;  /*!< for out circular linked list */};#define MGCP_ONHOOK  1#define MGCP_OFFHOOK 2#define TYPE_TRUNK 1#define TYPE_LINE  2struct mgcp_endpoint {	ast_mutex_t lock;	char name[80];	struct mgcp_subchannel *sub;		/*!< Pointer to our current connection, channel and stuff */	char accountcode[AST_MAX_ACCOUNT_CODE];	char exten[AST_MAX_EXTENSION];		/*!< Extention where to start */	char context[AST_MAX_EXTENSION];	char language[MAX_LANGUAGE];	char cid_num[AST_MAX_EXTENSION];	/*!< Caller*ID number */	char cid_name[AST_MAX_EXTENSION];	/*!< Caller*ID name */	char lastcallerid[AST_MAX_EXTENSION];	/*!< Last Caller*ID */	char call_forward[AST_MAX_EXTENSION];	/*!< Last Caller*ID */	char mailbox[AST_MAX_EXTENSION];	char musicclass[MAX_MUSICCLASS];	char curtone[80];			/*!< Current tone */	char dtmf_buf[AST_MAX_EXTENSION];	/*!< place to collect digits be */	ast_group_t callgroup;	ast_group_t pickupgroup;	int callwaiting;	int hascallwaiting;	int transfer;	int threewaycalling;	int singlepath;	int cancallforward;	int canreinvite;	int callreturn;	int dnd; /* How does this affect callwait? Do we just deny a mgcp_request if we're dnd? */	int hascallerid;	int hidecallerid;	int dtmfmode;	int amaflags;	int type;	int slowsequence;			/*!< MS: Sequence the endpoint as a whole */	int group;	int iseq; /*!< Not used? */	int lastout; /*!< tracking this on the subchannels.  Is it needed here? */	int needdestroy; /*!< Not used? */	int capability;	int nonCodecCapability;	int onhooktime;	int msgstate; /*!< voicemail message state */	int immediate;	int hookstate;	int adsi;	char rqnt_ident[80];             /*!< request identifier */	struct mgcp_request *rqnt_queue; /*!< pending RQNT commands */	ast_mutex_t rqnt_queue_lock;	struct mgcp_request *cmd_queue;  /*!< pending commands other than RQNT */	ast_mutex_t cmd_queue_lock;	int delme;                       /*!< needed for reload */	int needaudit;                   /*!< needed for reload */	struct ast_dsp *dsp; /*!< XXX Should there be a dsp/subchannel? XXX */	/* owner is tracked on the subchannels, and the *sub indicates whos in charge */	/* struct ast_channel *owner; */	/* struct ast_rtp *rtp; */	/* struct sockaddr_in tmpdest; */	/* message go the the endpoint and not the channel so they stay here */	struct mgcp_endpoint *next;	struct mgcp_gateway *parent;};static struct mgcp_gateway {	/* A gateway containing one or more endpoints */	char name[80];	int isnamedottedip; /*!< is the name FQDN or dotted ip */	struct sockaddr_in addr;	struct sockaddr_in defaddr;	struct in_addr ourip;	int dynamic;	int expire;		/*!< XXX Should we ever expire dynamic registrations? XXX */	struct mgcp_endpoint *endpoints;	struct ast_ha *ha;/* obsolete	time_t lastouttime;	int lastout;	int messagepending;*//* Wildcard endpoint name */	char wcardep[30];	struct mgcp_message *msgs; /*!< gw msg queue */	ast_mutex_t msgs_lock;     /*!< queue lock */  	int retransid;             /*!< retrans timer id */	int delme;                 /*!< needed for reload */	struct mgcp_response *responses;	struct mgcp_gateway *next;} *gateways;AST_MUTEX_DEFINE_STATIC(mgcp_reload_lock);static int mgcp_reloading = 0;/*! \brief gatelock: mutex for gateway/endpoint lists */AST_MUTEX_DEFINE_STATIC(gatelock);static int mgcpsock  = -1;static struct sockaddr_in bindaddr;static struct ast_frame  *mgcp_read(struct ast_channel *ast);static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest);static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);static int transmit_modify_request(struct mgcp_subchannel *sub);static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs);static int transmit_connection_del(struct mgcp_subchannel *sub);static int transmit_audit_endpoint(struct mgcp_endpoint *p);static void start_rtp(struct mgcp_subchannel *sub);static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,                              int result, unsigned int ident, struct mgcp_request *resp);static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);static int mgcp_do_reload(void);static int mgcp_reload(int fd, int argc, char *argv[]);static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);static int mgcp_hangup(struct ast_channel *ast);static int mgcp_answer(struct ast_channel *ast);static struct ast_frame *mgcp_read(struct ast_channel *ast);static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame);static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);static int mgcp_devicestate(void *data);static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp);static const struct ast_channel_tech mgcp_tech = {	.type = "MGCP",	.description = tdesc,	.capabilities = AST_FORMAT_ULAW,	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,	.requester = mgcp_request,	.devicestate = mgcp_devicestate,	.call = mgcp_call,	.hangup = mgcp_hangup,	.answer = mgcp_answer,	.read = mgcp_read,	.write = mgcp_write,	.indicate = mgcp_indicate,	.fixup = mgcp_fixup,	.send_digit_begin = mgcp_senddigit_begin,	.send_digit_end = mgcp_senddigit_end,	.bridge = ast_rtp_bridge,};static int has_voicemail(struct mgcp_endpoint *p){	return ast_app_has_voicemail(p->mailbox, NULL);}static int unalloc_sub(struct mgcp_subchannel *sub){	struct mgcp_endpoint *p = sub->parent;	if (p->sub == sub) {		ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name);		return -1;	}	ast_log(LOG_DEBUG, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name);	sub->owner = NULL;	if (!ast_strlen_zero(sub->cxident)) {		transmit_connection_del(sub);	}	sub->cxident[0] = '\0';

⌨️ 快捷键说明

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