From 6049bb6539153c2f400f1f2dbc763c74d796204b Mon Sep 17 00:00:00 2001 From: kpfleming Date: Wed, 19 Jul 2006 20:44:39 +0000 Subject: merge Russell's 'hold_handling' branch, finally implementing music-on-hold handling the way it was decided at AstriDevCon Europe 2006 (and the way people really want it to be) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@37988 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_mgcp.c | 351 +++++++++++++++++++-------------------------------- 1 file changed, 133 insertions(+), 218 deletions(-) (limited to 'channels/chan_mgcp.c') diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 5ad6cb733..0d1a857a1 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -28,48 +28,6 @@ * \ingroup channel_drivers */ -/* FO: Changes - * -- add distinctive ring signalling (part of RFC 3660) - */ - -/* JS: Changes - -- add support for the wildcard endpoint - -- seteable wildcard with wcardep on mgcp.conf - -- added package indicator on RQNT, i.e "dl" --> "L/dl" - -- removed MDCX just before DLCX, do we need this ? -*/ - -/* JS: TODO - -- reload for wildcard endpoint probably buggy - -- when hf is notified we're sending CRCX after MDCX, without waiting for - OK on the MDCX which fails on Cisco IAD 24XX - -- honour codec order, by now the lowest codec number in "allow" is the prefered -*/ - -/* SC: Changes - -- packet retransmit mechanism (simplistic) - -- per endpoint/subchannel mgcp command sequencing. - -- better transaction handling - -- fixed some mem leaks - -- run-time configuration reload - -- distinguish CA and GW default MGCP ports - -- prevent clipping of DTMF tones in an established call - -- fixed a few crash scenarios in 3-way - -- fix for a few cases where asterisk and MGW end-up in conflicting ep states - -- enclose numeric IP in [] for outgoing requests -*/ - -/* SC: TODO - -- piggyback support - -- responseAck support - -- enhance retransmit mechanism (RTO calc. etc.) - -- embedded command support -*/ - -/* FS: Changes - -- fixed reload_config() / do_monitor to stay responsive during reloads -*/ - #include "asterisk.h" ASTERISK_FILE_VERSION(__FILE__, "$Revision$") @@ -155,13 +113,13 @@ static const char config[] = "mgcp.conf"; #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 */ +#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 */ +/*! MGCP rtp stream modes { */ #define MGCP_CX_SENDONLY 0 #define MGCP_CX_RECVONLY 1 #define MGCP_CX_SENDRECV 2 @@ -169,6 +127,7 @@ static const char config[] = "mgcp.conf"; #define MGCP_CX_CONFERENCE 3 #define MGCP_CX_MUTE 4 #define MGCP_CX_INACTIVE 4 +/*! } */ static char *mgcp_cxmodes[] = { "sendonly", @@ -178,16 +137,17 @@ static char *mgcp_cxmodes[] = { "inactive" }; -/* SC: MGCP commands */ -#define MGCP_CMD_EPCF 0 -#define MGCP_CMD_CRCX 1 -#define MGCP_CMD_MDCX 2 -#define MGCP_CMD_DLCX 3 -#define MGCP_CMD_RQNT 4 -#define MGCP_CMD_NTFY 5 -#define MGCP_CMD_AUEP 6 -#define MGCP_CMD_AUCX 7 -#define MGCP_CMD_RSIP 8 +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"; @@ -199,39 +159,22 @@ static char cid_name[AST_MAX_EXTENSION] = ""; static int dtmfmode = 0; static int nat = 0; -/* Not used. Dosn't hurt for us to always send cid */ -/* to the mgcp box. */ -/*static int use_callerid = 1;*/ -/*static int cur_signalling = -1;*/ - -/*static unsigned int cur_group = 0;*/ static ast_group_t cur_callergroup = 0; static ast_group_t cur_pickupgroup = 0; -/* XXX Is this needed? */ -/* Doesn't look like the dsp stuff for */ -/* dtmfmode is actually hooked up. */ -/*static int relaxdtmf = 0;*/ - static int tos = 0; static int immediate = 0; static int callwaiting = 0; -/* Not used. Dosn't hurt for us to always send cid */ -/* to the mgcp box. */ -/*static int callwaitingcallerid = 0;*/ - -/*static int hidecallerid = 0;*/ - static int callreturn = 0; static int slowsequence = 0; static int threewaycalling = 0; -/* This is for flashhook transfers */ +/*! This is for flashhook transfers */ static int transfer = 0; static int cancallforward = 0; @@ -240,10 +183,6 @@ static int singlepath = 0; static int canreinvite = CANREINVITE; -/*static int busycount = 3;*/ - -/*static int callprogress = 0;*/ - static char accountcode[AST_MAX_ACCOUNT_CODE] = ""; static char mailbox[AST_MAX_EXTENSION]; @@ -252,26 +191,25 @@ static int amaflags = 0; static int adsi = 0; -/* SC: transaction id should always be positive */ static unsigned int oseq; -/* Wait up to 16 seconds for first digit (FXO logic) */ +/*! Wait up to 16 seconds for first digit (FXO logic) */ static int firstdigittimeout = 16000; -/* How long to wait for following digits (FXO logic) */ +/*! 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 */ +/*! 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. */ +/*! 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. */ +/*! 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); @@ -287,8 +225,8 @@ 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 */ +/*! The private structures of the mgcp channels are linked for + ! selecting outgoing channels */ #define MGCP_MAX_HEADERS 64 #define MGCP_MAX_LINES 64 @@ -304,21 +242,11 @@ struct mgcp_request { int lines; /*!< SDP Content */ char *line[MGCP_MAX_LINES]; char data[MGCP_MAX_PACKET]; - int cmd; /*!< SC: int version of verb = command */ - unsigned int trid; /*!< SC: int version of identifier = transaction id */ - struct mgcp_request *next; /*!< SC: next in the queue */ + int cmd; /*!< int version of verb = command */ + unsigned int trid; /*!< int version of identifier = transaction id */ + struct mgcp_request *next; /*!< next in the queue */ }; -/* SC: obsolete -static struct mgcp_pkt { - int retrans; - struct mgcp_endpoint *owner; - int packetlen; - char data[MGCP_MAX_PACKET]; - struct mgcp_pkt *next; -} *packets = NULL; -*/ - /*! \brief mgcp_message: MGCP message for queuing up */ struct mgcp_message { struct mgcp_endpoint *owner_ep; @@ -331,7 +259,7 @@ struct mgcp_message { char buf[0]; }; -#define RESPONSE_TIMEOUT 30 /* in seconds */ +#define RESPONSE_TIMEOUT 30 /*!< in seconds */ struct mgcp_response { time_t whensent; @@ -347,7 +275,7 @@ struct mgcp_response { #define SUB_ALT 1 struct mgcp_subchannel { - /* SC: subchannel magic string. + /*! 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. @@ -360,18 +288,18 @@ struct mgcp_subchannel { struct mgcp_endpoint *parent; struct ast_rtp *rtp; struct sockaddr_in tmpdest; - char txident[80]; /* FIXME SC: txident is replaced by rqnt_ident in endpoint. + 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; /*!< SC: pending CX commands */ - ast_mutex_t cx_queue_lock; /*!< SC: CX queue lock */ + 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 iseq; /*!< Not used? RTP? */ int outgoing; int alreadygone; - struct mgcp_subchannel *next; /* for out circular linked list */ + struct mgcp_subchannel *next; /*!< for out circular linked list */ }; #define MGCP_ONHOOK 1 @@ -423,13 +351,13 @@ struct mgcp_endpoint { int immediate; int hookstate; int adsi; - char rqnt_ident[80]; /*!< SC: request identifier */ - struct mgcp_request *rqnt_queue; /*!< SC: pending RQNT commands */ + 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; /*!< SC: pending commands other than RQNT */ + struct mgcp_request *cmd_queue; /*!< pending commands other than RQNT */ ast_mutex_t cmd_queue_lock; - int delme; /*!< SC: needed for reload */ - int needaudit; /*!< SC: needed for reload */ + 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; */ @@ -443,7 +371,7 @@ struct mgcp_endpoint { static struct mgcp_gateway { /* A gateway containing one or more endpoints */ char name[80]; - int isnamedottedip; /*!< SC: is the name FQDN or dotted ip */ + int isnamedottedip; /*!< is the name FQDN or dotted ip */ struct sockaddr_in addr; struct sockaddr_in defaddr; struct in_addr ourip; @@ -451,17 +379,17 @@ static struct mgcp_gateway { int expire; /*!< XXX Should we ever expire dynamic registrations? XXX */ struct mgcp_endpoint *endpoints; struct ast_ha *ha; -/* SC: obsolete +/* obsolete time_t lastouttime; int lastout; int messagepending; */ -/* JS: Wildcard endpoint name */ +/* Wildcard endpoint name */ char wcardep[30]; - struct mgcp_message *msgs; /*!< SC: gw msg queue */ - ast_mutex_t msgs_lock; /*!< SC: queue lock */ - int retransid; /*!< SC: retrans timer id */ - int delme; /*!< SC: needed for reload */ + 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; @@ -552,7 +480,7 @@ static int unalloc_sub(struct mgcp_subchannel *sub) return 0; } -/* SC: modified for new transport mechanism */ +/* modified for new transport mechanism */ static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len) { int res; @@ -594,7 +522,7 @@ static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req) return res; } -/* SC: modified for new transport framework */ +/* modified for new transport framework */ static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p) { struct mgcp_message *cur, *q = NULL, *w, *prev; @@ -736,7 +664,7 @@ static int retrans_pkt(void *data) return res; } -/* SC: modified for the new transaction mechanism */ +/* modified for the new transaction mechanism */ static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno) { @@ -802,7 +730,7 @@ static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub return 0; } -/* SC: modified for new transport */ +/* modified for new transport */ static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno) { @@ -875,7 +803,7 @@ static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, } } - /* XXX SC: find tail. We could also keep tail in the data struct for faster access */ + /* XXX find tail. We could also keep tail in the data struct for faster access */ for (t = *queue; t && t->next; t = t->next); r->next = NULL; @@ -1004,7 +932,7 @@ static int mgcp_hangup(struct ast_channel *ast) } if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) { - /* SC: check whether other channel is active. */ + /* check whether other channel is active. */ if (!sub->next->owner) { if (p->dtmfmode & MGCP_DTMF_HYBRID) p->dtmfmode &= ~MGCP_DTMF_INBAND; @@ -1056,10 +984,10 @@ static int mgcp_hangup(struct ast_channel *ast) sub->rtp = NULL; } - /* SC: Decrement use count */ + /* Decrement use count */ ast_atomic_fetchadd_int(&__mod_desc->usecnt, -1); ast_update_use_count(); - /* SC: Decrement use count */ + /* Decrement use count */ if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) { p->hidecallerid = 0; @@ -1101,7 +1029,7 @@ static int mgcp_show_endpoints(int fd, int argc, char *argv[]) e = g->endpoints; ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr) : ast_inet_ntoa(iabuf, sizeof(iabuf), g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static"); while(e) { - /* JS: Don't show wilcard endpoint */ + /* Don't show wilcard endpoint */ if (strcmp(e->name, g->wcardep) !=0) ast_cli(fd, " -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle"); hasendpoints = 1; @@ -1197,7 +1125,7 @@ static int mgcp_answer(struct ast_channel *ast) } else { transmit_modify_request(sub); } - /* SC: verbose level check */ + /* verbose level check */ if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_answer(%s) on %s@%s-%d\n", ast->name, p->name, p->parent->name, sub->id); @@ -1428,9 +1356,15 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz case AST_CONTROL_CONGESTION: transmit_notify_request(sub, "G/cg"); break; + case AST_CONTROL_HOLD: + ast_moh_start(ast, data, NULL); + break; + case AST_CONTROL_UNHOLD: + ast_moh_stop(ast); + break; case -1: transmit_notify_request(sub, ""); - break; + break; default: ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); res = -1; @@ -1458,7 +1392,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state) if (i->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID)) { i->dsp = ast_dsp_new(); ast_dsp_set_features(i->dsp,DSP_FEATURE_DTMF_DETECT); - /* SC: this is to prevent clipping of dtmf tones during dsp processing */ + /* this is to prevent clipping of dtmf tones during dsp processing */ ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_NOQUELCH); } else { i->dsp = NULL; @@ -1496,7 +1430,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state) tmp = NULL; } } - /* SC: verbose level check */ + /* verbose level check */ if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_new(%s) created in state: %s\n", tmp->name, ast_state2str(state)); @@ -1637,14 +1571,14 @@ static struct mgcp_subchannel *find_subchannel_and_lock(char *name, int msgid, s ast_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr), ntohs(g->addr.sin_port)); } } - /* SC: not dynamic, check if the name matches */ + /* not dynamic, check if the name matches */ else if (name) { if (strcasecmp(g->name, at)) { g = g->next; continue; } } - /* SC: not dynamic, no name, check if the addr matches */ + /* not dynamic, no name, check if the addr matches */ else if (!name && sin) { if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || (g->addr.sin_port != sin->sin_port)) { @@ -1662,7 +1596,7 @@ static struct mgcp_subchannel *find_subchannel_and_lock(char *name, int msgid, s ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n", p->name, g->name); if (msgid) { -#if 0 /* SC: new transport mech */ +#if 0 /* new transport mech */ sub = p->sub; do { if (option_debug) @@ -1971,7 +1905,7 @@ static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *ver return -1; } req->header[req->headers] = req->data + req->len; - /* SC: check if we need brackets around the gw name */ + /* check if we need brackets around the gw name */ if (p->parent->isnamedottedip) snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@[%s] MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name); else @@ -2148,12 +2082,12 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp add_header(&resp, "C", sub->callid); add_header(&resp, "L", local); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); add_header(&resp, "I", sub->cxident); /*add_header(&resp, "S", "");*/ add_sdp(&resp, sub, rtp); - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_MDCX; resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ @@ -2182,11 +2116,11 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp add_header(&resp, "C", sub->callid); add_header(&resp, "L", local); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); /*add_header(&resp, "S", "");*/ add_sdp(&resp, sub, rtp); - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_CRCX; resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ @@ -2215,7 +2149,7 @@ static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone) if (!ast_strlen_zero(tone)) { add_header(&resp, "S", tone); } - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_RQNT; resp.trid = oseq; return send_request(p, NULL, &resp, oseq); /* SC */ @@ -2262,7 +2196,7 @@ static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, ch ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); } - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_RQNT; resp.trid = oseq; return send_request(p, NULL, &resp, oseq); /* SC */ @@ -2285,7 +2219,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub) reqprep(&resp, p, "MDCX"); add_header(&resp, "C", sub->callid); add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); - /* SC: X header should not be sent. kept for compatibility */ + /* X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); add_header(&resp, "I", sub->cxident); switch (sub->parent->hookstate) { @@ -2296,7 +2230,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub) add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N), L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); break; } - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_MDCX; resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ @@ -2307,10 +2241,10 @@ static int transmit_audit_endpoint(struct mgcp_endpoint *p) { struct mgcp_request resp; reqprep(&resp, p, "AUEP"); - /* SC: removed unknown param VS */ + /* removed unknown param VS */ /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/ add_header(&resp, "F", "A"); - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_AUEP; resp.trid = oseq; return send_request(p, NULL, &resp, oseq); /* SC */ @@ -2326,15 +2260,15 @@ static int transmit_connection_del(struct mgcp_subchannel *sub) sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); } reqprep(&resp, p, "DLCX"); - /* SC: check if call id is avail */ + /* check if call id is avail */ if (sub->callid[0]) add_header(&resp, "C", sub->callid); - /* SC: X header should not be sent. kept for compatibility */ + /* X header should not be sent. kept for compatibility */ add_header(&resp, "X", sub->txident); - /* SC: check if cxident is avail */ + /* check if cxident is avail */ if (sub->cxident[0]) add_header(&resp, "I", sub->cxident); - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_DLCX; resp.trid = oseq; return send_request(p, sub, &resp, oseq); /* SC */ @@ -2349,13 +2283,13 @@ static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *calli cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); } reqprep(&resp, p, "DLCX"); - /* SC: check if call id is avail */ + /* check if call id is avail */ if (callid && *callid) add_header(&resp, "C", callid); - /* SC: check if cxident is avail */ + /* check if cxident is avail */ if (cxident && *cxident) add_header(&resp, "I", cxident); - /* SC: fill in new fields */ + /* fill in new fields */ resp.cmd = MGCP_CMD_DLCX; resp.trid = oseq; return send_request(p, p->sub, &resp, oseq); @@ -2427,7 +2361,7 @@ static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_su return req; } -/* SC: modified for new transport mechanism */ +/* modified for new transport mechanism */ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp) { @@ -2497,7 +2431,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub if (req->cmd == MGCP_CMD_CRCX) { if ((c = get_header(resp, "I"))) { if (!ast_strlen_zero(c) && sub) { - /* SC: if we are hanging up do not process this conn. */ + /* if we are hanging up do not process this conn. */ if (sub->owner) { if (!ast_strlen_zero(sub->cxident)) { if (strcasecmp(c, sub->cxident)) { @@ -2509,7 +2443,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub transmit_modify_with_sdp(sub, NULL, 0); } } else { - /* XXX SC: delete this one + /* XXX delete this one callid and conn id may already be lost. so the following del conn may have a side effect of cleaning up the next subchannel */ @@ -2520,7 +2454,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub } if (req->cmd == MGCP_CMD_AUEP) { - /* SC: check stale connection ids */ + /* check stale connection ids */ if ((c = get_header(resp, "I"))) { char *v, *n; int len; @@ -2548,16 +2482,16 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub if (!ast_strlen_zero(c)) { if (strstr(c, "hu")) { if (p->hookstate != MGCP_ONHOOK) { - /* SC: XXX cleanup if we think we are offhook XXX */ + /* XXX cleanup if we think we are offhook XXX */ if ((p->sub->owner || p->sub->next->owner ) && p->hookstate == MGCP_OFFHOOK) mgcp_queue_hangup(sub); p->hookstate = MGCP_ONHOOK; - /* SC: update the requested events according to the new hookstate */ + /* update the requested events according to the new hookstate */ transmit_notify_request(p->sub, ""); - /* SC: verbose level check */ + /* verbose level check */ if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name); } @@ -2566,10 +2500,10 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub if (p->hookstate != MGCP_OFFHOOK) { p->hookstate = MGCP_OFFHOOK; - /* SC: update the requested events according to the new hookstate */ + /* update the requested events according to the new hookstate */ transmit_notify_request(p->sub, ""); - /* SC: verbose level check */ + /* verbose level check */ if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name); } @@ -2580,7 +2514,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub } if (resp && resp->lines) { - /* SC: do not process sdp if we are hanging up. this may be a late response */ + /* do not process sdp if we are hanging up. this may be a late response */ if (sub && sub->owner) { if (!sub->rtp) start_rtp(sub); @@ -2596,7 +2530,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub static void start_rtp(struct mgcp_subchannel *sub) { ast_mutex_lock(&sub->lock); - /* SC: check again to be on the safe side */ + /* check again to be on the safe side */ if (sub->rtp) { ast_rtp_destroy(sub->rtp); sub->rtp = NULL; @@ -2888,7 +2822,7 @@ static int attempt_transfer(struct mgcp_endpoint *p) /* The three-way person we're about to transfer to could still be in MOH, so stop if now if appropriate */ if (ast_bridged_channel(p->sub->next->owner)) - ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); + ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD); if (p->sub->owner->_state == AST_STATE_RINGING) { ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); } @@ -2903,7 +2837,7 @@ static int attempt_transfer(struct mgcp_endpoint *p) if (p->sub->owner->_state == AST_STATE_RINGING) { ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); } - ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); + ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD); if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); @@ -2942,9 +2876,8 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev) if (sub->outgoing) { /* Answered */ if (sub->owner) { - if (ast_bridged_channel(sub->owner)) { - ast_moh_stop(ast_bridged_channel(sub->owner)); - } + if (ast_bridged_channel(sub->owner)) + ast_queue_control(sub->owner, AST_CONTROL_UNHOLD); sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { start_rtp(sub); @@ -3000,9 +2933,8 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev) ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name); ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?"); } - if (ast_bridged_channel(sub->owner)) { - ast_moh_stop(ast_bridged_channel(sub->owner)); - } + if (ast_bridged_channel(sub->owner)) + ast_queue_control(sub->owner, AST_CONTROL_UNHOLD); sub->cxmode = MGCP_CX_SENDRECV; if (!sub->rtp) { start_rtp(sub); @@ -3042,7 +2974,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) { ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); } - /* JS: For RSIP on wildcard we reset all endpoints */ + /* For RSIP on wildcard we reset all endpoints */ if (!strcmp(p->name, p->parent->wcardep)) { /* Reset all endpoints */ struct mgcp_endpoint *tmp_ep; @@ -3072,10 +3004,10 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, mgcp_queue_hangup(sub); } transmit_response(sub, "200", req, "OK"); - /* JS: We dont send NTFY or AUEP to wildcard ep */ + /* We dont send NTFY or AUEP to wildcard ep */ if (strcmp(p->name, p->parent->wcardep) != 0) { transmit_notify_request(sub, ""); - /* SC: Audit endpoint. + /* Audit endpoint. Idea is to prevent lost lines due to race conditions */ transmit_audit_endpoint(p); @@ -3124,9 +3056,8 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); } transmit_modify_request(sub); - if (sub->owner && ast_bridged_channel(sub->owner)) { - ast_moh_start(ast_bridged_channel(sub->owner), NULL); - } + if (sub->owner && ast_bridged_channel(sub->owner)) + ast_queue_control(sub->owner, AST_CONTROL_HOLD); sub->next->cxmode = MGCP_CX_RECVONLY; handle_hd_hf(sub->next, ev); } else if (sub->owner && sub->next->owner) { @@ -3139,8 +3070,8 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, } sub->cxmode = MGCP_CX_CONF; sub->next->cxmode = MGCP_CX_CONF; - if (ast_bridged_channel(sub->next->owner)) - ast_moh_stop(ast_bridged_channel(sub->next->owner)); + if (ast_bridged_channel(sub->next->owner)) + ast_queue_control(sub->next->owner, AST_CONTROL_UNHOLD); transmit_modify_request(sub); transmit_modify_request(sub->next); } else { @@ -3156,22 +3087,13 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); } transmit_modify_request(sub); - if (ast_bridged_channel(sub->owner)) - ast_moh_start(ast_bridged_channel(sub->owner), NULL); + if (ast_bridged_channel(sub->owner)) + ast_queue_control(sub->owner, AST_CONTROL_HOLD); if (ast_bridged_channel(sub->next->owner)) - ast_moh_stop(ast_bridged_channel(sub->next->owner)); + ast_queue_control(sub->next->owner, AST_CONTROL_HOLD); handle_hd_hf(sub->next, ev); -#if 0 - if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { - handle_hd_hf(sub->next, ev); - } else { - ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); - sub->next->cxmode = MGCP_CX_SENDRECV; - transmit_modify_request(sub->next); - } -#endif } } else { /* We've most likely lost one of our calls find an active call and bring it up */ @@ -3184,9 +3106,8 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, /* XXX - What do we do now? */ return -1; } - if (ast_bridged_channel(p->sub->owner)) { - ast_moh_stop(ast_bridged_channel(p->sub->owner)); - } + if (ast_bridged_channel(p->sub->owner)) + ast_queue_control(p->sub->owner, AST_CONTROL_UNHOLD); p->sub->cxmode = MGCP_CX_SENDRECV; transmit_modify_request(p->sub); } @@ -3194,12 +3115,11 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", p->name, p->parent->name); } - /*ast_moh_stop(sub->owner->bridge);*/ } else if (!strcasecmp(ev, "hu")) { p->hookstate = MGCP_ONHOOK; sub->cxmode = MGCP_CX_RECVONLY; ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); - /* JS: Do we need to send MDCX before a DLCX ? + /* Do we need to send MDCX before a DLCX ? if (sub->rtp) { transmit_modify_request(sub); } @@ -3227,7 +3147,7 @@ static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, sub->alreadygone = 1; mgcp_queue_hangup(sub); } else { - /* SC: verbose level check */ + /* verbose level check */ if (option_verbose > 2) { ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n", p->name, p->parent->name, sub->id); @@ -3486,7 +3406,7 @@ static void *do_monitor(void *data) pthread_testcancel(); /* Wait for sched or io */ res = ast_sched_wait(sched); - /* SC: copied from chan_sip.c */ + /* copied from chan_sip.c */ if ((res < 0) || (res > 1000)) res = 1000; res = ast_io_wait(io, res); @@ -3582,7 +3502,7 @@ static struct ast_channel *mgcp_request(const char *type, int format, void *data return tmpc; } -/* SC: modified for reload support */ +/* modified for reload support */ /*! \brief build_gateway: parse mgcp.conf and create gateway/endpoint structures */ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) { @@ -3595,7 +3515,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) int ep_reload = 0; canreinvite = CANREINVITE; - /* SC: locate existing gateway */ + /* locate existing gateway */ gw = gateways; while (gw) { if (!strcasecmp(cat, gw->name)) { @@ -3617,7 +3537,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) gw->retransid = -1; /* SC */ ast_mutex_init(&gw->msgs_lock); ast_copy_string(gw->name, cat, sizeof(gw->name)); - /* SC: check if the name is numeric ip */ + /* check if the name is numeric ip */ if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE) gw->isnamedottedip = 1; } @@ -3721,7 +3641,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) } else if (!strcasecmp(v->name, "threewaycalling")) { threewaycalling = ast_true(v->value); } else if (!strcasecmp(v->name, "wcardep")) { - /* SC: locate existing endpoint */ + /* locate existing endpoint */ e = gw->endpoints; while (e) { if (!strcasecmp(v->value, e->name)) { @@ -3822,7 +3742,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) } else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) { - /* SC: locate existing endpoint */ + /* locate existing endpoint */ e = gw->endpoints; while (e) { if (!strcasecmp(v->value, e->name)) { @@ -3860,7 +3780,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v) ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name); } if (!ep_reload) { - /* XXX SC: potential issue due to reload */ + /* XXX potential issue due to reload */ e->msgstate = -1; e->parent = gw; } @@ -4204,7 +4124,7 @@ static int reload_config(void) v = v->next; } - /* SC: mark existing entries for deletion */ + /* mark existing entries for deletion */ ast_mutex_lock(&gatelock); g = gateways; while (g) { @@ -4241,7 +4161,7 @@ static int reload_config(void) cat = ast_category_browse(cfg, cat); } - /* SC: prune deleted entries etc. */ + /* prune deleted entries etc. */ prune_gateways(); if (ntohl(bindaddr.sin_addr.s_addr)) { @@ -4289,7 +4209,7 @@ static int reload_config(void) ast_mutex_unlock(&netlock); ast_config_destroy(cfg); - /* SC: send audit only to the new endpoints */ + /* send audit only to the new endpoints */ g = gateways; while (g) { e = g->endpoints; @@ -4403,15 +4323,10 @@ static int unload_module(void *mod) } if (!ast_mutex_lock(&gatelock)) { - g = gateways; - while (g) { + for (g = gateways; g; g = g->next) { g->delme = 1; - e = g->endpoints; - while (e) { + for (e = g->endpoints; e; e = e->next) e->delme = 1; - e = e->next; - } - g = g->next; } prune_gateways(); -- cgit v1.2.3