aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-19 20:44:39 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-19 20:44:39 +0000
commit6049bb6539153c2f400f1f2dbc763c74d796204b (patch)
tree3c36781db3a5a7a08967cbe8d83acb5d82e581cb /channels
parent28df168d0f9fd12f5914263015dc26898e834146 (diff)
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
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_agent.c17
-rw-r--r--channels/chan_alsa.c41
-rw-r--r--channels/chan_h323.c10
-rw-r--r--channels/chan_iax2.c69
-rw-r--r--channels/chan_jingle.c16
-rw-r--r--channels/chan_mgcp.c351
-rw-r--r--channels/chan_misdn.c4
-rw-r--r--channels/chan_oss.c22
-rw-r--r--channels/chan_phone.c7
-rw-r--r--channels/chan_sip.c86
-rw-r--r--channels/chan_skinny.c16
-rw-r--r--channels/chan_vpb.cc8
-rw-r--r--channels/chan_zap.c96
13 files changed, 414 insertions, 329 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index 1c440f3b8..1c3f8d8df 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -595,7 +595,7 @@ static int agent_indicate(struct ast_channel *ast, int condition, const void *da
int res = -1;
ast_mutex_lock(&p->lock);
if (p->chan)
- res = ast_indicate(p->chan, condition);
+ res = ast_indicate_data(p->chan, condition, data, datalen);
else
res = 0;
ast_mutex_unlock(&p->lock);
@@ -773,7 +773,9 @@ static int agent_hangup(struct ast_channel *ast)
ast_channel_unlock(p->chan);
} else if (p->loginstart) {
ast_channel_lock(p->chan);
- ast_moh_start(p->chan, p->moh);
+ ast_indicate_data(p->chan, AST_CONTROL_HOLD,
+ S_OR(p->moh, NULL),
+ !ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
ast_channel_unlock(p->chan);
}
}
@@ -965,7 +967,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
ast_log( LOG_ERROR, "A blocker exists after agent channel ownership acquired\n" );
CRASH;
}
- ast_moh_stop(p->chan);
+ ast_indicate(p->chan, AST_CONTROL_UNHOLD);
}
return tmp;
}
@@ -1964,12 +1966,9 @@ static int __login_exec(struct ast_channel *chan, void *data, int callbackmode)
res = ast_safe_sleep(chan, 500);
ast_mutex_unlock(&p->lock);
} else if (!res) {
-#ifdef HONOR_MUSIC_CLASS
- /* check if the moh class was changed with setmusiconhold */
- if (*(chan->musicclass))
- ast_copy_string(p->moh, chan->musicclass, sizeof(p->moh));
-#endif
- ast_moh_start(chan, p->moh);
+ ast_indicate_data(chan, AST_CONTROL_HOLD,
+ S_OR(p->moh, NULL),
+ !ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
if (p->loginstart == 0)
time(&p->loginstart);
manager_event(EVENT_FLAG_AGENT, "Agentlogin",
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 5c921b918..aeadc340c 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -61,6 +61,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
+#include "asterisk/musiconhold.h"
#include "busy.h"
#include "ringtone.h"
@@ -127,6 +128,7 @@ static const char config[] = "alsa.conf";
static char context[AST_MAX_CONTEXT] = "default";
static char language[MAX_LANGUAGE] = "";
static char exten[AST_MAX_EXTENSION] = "s";
+static char mohinterpret[MAX_MUSICCLASS];
static int hookstate=0;
@@ -764,7 +766,9 @@ static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
{
int res = 0;
+
ast_mutex_lock(&alsalock);
+
switch(cond) {
case AST_CONTROL_BUSY:
res = 1;
@@ -773,7 +777,6 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
res = 2;
break;
case AST_CONTROL_RINGING:
- res = 0;
break;
case -1:
res = -1;
@@ -781,14 +784,24 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
case AST_CONTROL_VIDUPDATE:
res = -1;
break;
+ case AST_CONTROL_HOLD:
+ ast_verbose( " << Console Has Been Placed on Hold >> \n");
+ ast_moh_start(chan, data, mohinterpret);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_verbose( " << Console Has Been Retrieved from Hold >> \n");
+ ast_moh_stop(chan);
+ break;
default:
ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
res = -1;
}
- if (res > -1) {
+
+ if (res > -1)
write(sndcmd[1], &res, sizeof(res));
- }
+
ast_mutex_unlock(&alsalock);
+
return res;
}
@@ -1068,14 +1081,15 @@ static int load_module(void *mod)
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
+ strcpy(mohinterpret, "default");
+
if ((cfg = ast_config_load(config))) {
v = ast_variable_browse(cfg, "general");
- while(v) {
+ for (; v; v = v->next) {
/* handle jb conf */
- if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
- v = v->next;
+ if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
continue;
- }
+
if (!strcasecmp(v->name, "autoanswer"))
autoanswer = ast_true(v->value);
else if (!strcasecmp(v->name, "silencesuppression"))
@@ -1083,16 +1097,17 @@ static int load_module(void *mod)
else if (!strcasecmp(v->name, "silencethreshold"))
silencethreshold = atoi(v->value);
else if (!strcasecmp(v->name, "context"))
- strncpy(context, v->value, sizeof(context)-1);
+ ast_copy_string(context, v->value, sizeof(context));
else if (!strcasecmp(v->name, "language"))
- strncpy(language, v->value, sizeof(language)-1);
+ ast_copy_string(language, v->value, sizeof(language));
else if (!strcasecmp(v->name, "extension"))
- strncpy(exten, v->value, sizeof(exten)-1);
+ ast_copy_string(exten, v->value, sizeof(exten));
else if (!strcasecmp(v->name, "input_device"))
- strncpy(indevname, v->value, sizeof(indevname)-1);
+ ast_copy_string(indevname, v->value, sizeof(indevname));
else if (!strcasecmp(v->name, "output_device"))
- strncpy(outdevname, v->value, sizeof(outdevname)-1);
- v=v->next;
+ ast_copy_string(outdevname, v->value, sizeof(outdevname));
+ else if (!strcasecmp(v->name, "mohinterpret"))
+ ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
}
ast_config_destroy(cfg);
}
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index a638b19a7..b5e3b18d0 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -702,6 +702,16 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
if (token)
free(token);
return -1;
+ case AST_CONTROL_HOLD:
+ ast_moh_start(c, data, NULL);
+ if (token)
+ free(token);
+ return 0;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(c);
+ if (token)
+ free(token);
+ return 0;
case AST_CONTROL_PROCEEDING:
case -1:
if (token)
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index f08547064..046cd7e6f 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -217,6 +217,8 @@ 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;
@@ -283,6 +285,8 @@ struct iax2_user {
int authmethods;
int encmethods;
char accountcode[AST_MAX_ACCOUNT_CODE];
+ char mohinterpret[MAX_MUSICCLASS];
+ char mohsuggest[MAX_MUSICCLASS];
char inkeys[80]; /*!< Key(s) this user can use to authenticate to us */
char language[MAX_LANGUAGE];
int amaflags;
@@ -310,6 +314,8 @@ struct iax2_peer {
char regexten[AST_MAX_EXTENSION]; /*!< Extension to register (if regcontext is used) */
char peercontext[AST_MAX_EXTENSION]; /*!< Context to pass to peer */
char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox */
+ char mohinterpret[MAX_MUSICCLASS];
+ char mohsuggest[MAX_MUSICCLASS];
struct ast_codec_pref prefs;
struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
struct sockaddr_in addr;
@@ -590,6 +596,8 @@ struct chan_iax2_pvt {
int calling_pres;
char dproot[AST_MAX_EXTENSION];
char accountcode[AST_MAX_ACCOUNT_CODE];
+ char mohinterpret[MAX_MUSICCLASS];
+ char mohsuggest[MAX_MUSICCLASS];
int amaflags;
struct iax2_dpcache *dpentries;
struct ast_variable *vars;
@@ -1226,6 +1234,8 @@ static int find_callno(unsigned short callno, unsigned short dcallno, struct soc
iaxs[x]->amaflags = amaflags;
ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode));
+ ast_copy_string(iaxs[x]->mohinterpret, mohinterpret, sizeof(iaxs[x]->mohinterpret));
+ ast_copy_string(iaxs[x]->mohsuggest, mohsuggest, sizeof(iaxs[x]->mohsuggest));
} else {
ast_log(LOG_WARNING, "Out of resources\n");
ast_mutex_unlock(&iaxsl[x]);
@@ -2577,6 +2587,8 @@ struct create_addr_info {
char prefs[32];
char context[AST_MAX_CONTEXT];
char peercontext[AST_MAX_CONTEXT];
+ char mohinterpret[MAX_MUSICCLASS];
+ char mohsuggest[MAX_MUSICCLASS];
};
static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
@@ -2634,6 +2646,8 @@ static int create_addr(const char *peername, struct sockaddr_in *sin, struct cre
ast_copy_string(cai->username, peer->username, sizeof(cai->username));
ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
+ ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
+ ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
if (ast_strlen_zero(peer->dbsecret)) {
ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
} else {
@@ -2881,6 +2895,9 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
iaxs[callno]->encmethods = cai.encmethods;
iaxs[callno]->adsi = cai.adsi;
+
+ ast_copy_string(iaxs[callno]->mohinterpret, cai.mohinterpret, sizeof(iaxs[callno]->mohinterpret));
+ ast_copy_string(iaxs[callno]->mohsuggest, cai.mohsuggest, sizeof(iaxs[callno]->mohsuggest));
if (pds.key)
ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
@@ -3168,9 +3185,23 @@ static int iax2_answer(struct ast_channel *c)
static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
{
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
+
if (option_debug && iaxdebug)
ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
- return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
+
+ if (!strcasecmp(iaxs[callno]->mohinterpret, "passthrough"))
+ return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
+
+ switch (condition) {
+ case AST_CONTROL_HOLD:
+ ast_moh_start(c, data, iaxs[callno]->mohinterpret);
+ return 0;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(c);
+ return 0;
+ default:
+ return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
+ }
}
static int iax2_transfer(struct ast_channel *c, const char *dest)
@@ -4703,6 +4734,10 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
}
if (!ast_strlen_zero(user->accountcode))
ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode));
+ if (!ast_strlen_zero(user->mohinterpret))
+ ast_copy_string(iaxs[callno]->mohinterpret, user->mohinterpret, sizeof(iaxs[callno]->mohinterpret));
+ if (!ast_strlen_zero(user->mohsuggest))
+ ast_copy_string(iaxs[callno]->mohsuggest, user->mohsuggest, sizeof(iaxs[callno]->mohsuggest));
if (user->amaflags)
iaxs[callno]->amaflags = user->amaflags;
if (!ast_strlen_zero(user->language))
@@ -6668,9 +6703,12 @@ retryowner:
ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
if (ies.musiconhold) {
- if (iaxs[fr->callno]->owner &&
- ast_bridged_channel(iaxs[fr->callno]->owner))
- ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL);
+ if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
+ const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
+ ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD,
+ S_OR(mohsuggest, NULL),
+ !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
+ }
}
}
break;
@@ -6686,9 +6724,8 @@ retryowner:
}
ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
- if (iaxs[fr->callno]->owner &&
- ast_bridged_channel(iaxs[fr->callno]->owner))
- ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner));
+ if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner))
+ ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD);
}
break;
case IAX_COMMAND_TXACC:
@@ -8244,6 +8281,10 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, in
ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
+ } else if (!strcasecmp(v->name, "mohinterpret")) {
+ ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
} else if (!strcasecmp(v->name, "dbsecret")) {
ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
} else if (!strcasecmp(v->name, "trunk")) {
@@ -8502,6 +8543,10 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
ast_set_flag(user, IAX_HASCALLERID);
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
+ } else if (!strcasecmp(v->name, "mohinterpret")) {
+ ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
} else if (!strcasecmp(v->name, "language")) {
ast_copy_string(user->language, v->value, sizeof(user->language));
} else if (!strcasecmp(v->name, "amaflags")) {
@@ -8878,6 +8923,10 @@ static int set_config(char *config_file, int reload)
ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(accountcode, v->value, sizeof(accountcode));
+ } else if (!strcasecmp(v->name, "mohinterpret")) {
+ ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
} else if (!strcasecmp(v->name, "amaflags")) {
format = ast_cdr_amaflags2int(v->value);
if (format < 0) {
@@ -8956,8 +9005,10 @@ static int reload_config(void)
struct iax2_registry *reg;
struct iax2_peer *peer = NULL;
- ast_copy_string(accountcode, "", sizeof(accountcode));
- ast_copy_string(language, "", sizeof(language));
+ strcpy(accountcode, "");
+ strcpy(language, "");
+ strcpy(mohinterpret, "default");
+ strcpy(mohsuggest, "");
amaflags = 0;
delayreject = 0;
ast_clear_flag((&globalflags), IAX_NOTRANSFER);
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index cefecc783..6ea1462ee 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -1116,9 +1116,21 @@ static int jingle_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
static int jingle_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
{
- ast_log(LOG_NOTICE, "XXX Implement jingle indicate XXX\n");
+ int res = 0;
- return -1;
+ switch (condition) {
+ case AST_CONTROL_HOLD:
+ ast_moh_start(ast, data, NULL);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(ast);
+ break;
+ default:
+ ast_log(LOG_NOTICE, "Don't know how to indicate condition '%d'\n", condition);
+ res = -1;
+ }
+
+ return res;
}
static int jingle_digit(struct ast_channel *ast, char digit)
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();
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index e76e28f43..d862a4633 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -4291,7 +4291,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
bc->holded_bc=bridged_ch->bc;
misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
- ast_moh_start(bridged, NULL);
+ /* XXX This should queue an AST_CONTROL_HOLD frame on this channel
+ * instead of starting moh on the bridged channel directly */
+ ast_moh_start(bridged, NULL, NULL);
} else {
misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 36db65fc3..548e8d6dd 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -74,6 +74,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
+#include "asterisk/musiconhold.h"
/* ringtones we use */
#include "busy.h"
@@ -136,6 +137,13 @@ START_CONFIG
; context = default ; default context for outgoing calls
; language = "" ; default language
+ ; Default Music on Hold class to use when this channel is placed on hold in
+ ; the case that the music class is not set on the channel with
+ ; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
+ ; putting this one on hold did not suggest a class to use.
+ ;
+ ; mohinterpret=default
+
; If you set overridecontext to 'yes', then the whole dial string
; will be interpreted as an extension, which is extremely useful
; to dial SIP, IAX and other extensions which use the '@' character.
@@ -365,6 +373,7 @@ struct chan_oss_pvt {
char language[MAX_LANGUAGE];
char cid_name[256]; /*XXX */
char cid_num[256]; /*XXX */
+ char mohinterpret[MAX_MUSICCLASS];
/* buffers used in oss_write */
char oss_write_buf[FRAME_SIZE*2];
@@ -953,14 +962,24 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_
case AST_CONTROL_VIDUPDATE:
res = -1;
break;
+ case AST_CONTROL_HOLD:
+ ast_verbose( " << Console Has Been Placed on Hold >> \n");
+ ast_moh_start(c, data, o->mohinterpret);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_verbose( " << Console Has Been Retrieved from Hold >> \n");
+ ast_moh_stop(c);
+ break;
default:
ast_log(LOG_WARNING,
"Don't know how to display condition %d on %s\n",
cond, c->name);
return -1;
}
+
if (res > -1)
ring(o, res);
+
return 0;
}
@@ -1434,6 +1453,8 @@ static struct chan_oss_pvt * store_config(struct ast_config *cfg, char *ctg)
o->name = ast_strdup(ctg);
}
+ strcpy(o->mohinterpret, "default");
+
o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
/* fill other fields from configuration */
for (v = ast_variable_browse(cfg, ctg);v; v=v->next) {
@@ -1452,6 +1473,7 @@ static struct chan_oss_pvt * store_config(struct ast_config *cfg, char *ctg)
M_UINT("queuesize", o->queuesize)
M_STR("context", o->ctx)
M_STR("language", o->language)
+ M_STR("mohinterpret", o->mohinterpret)
M_STR("extension", o->ext)
M_F("mixer", store_mixer(o, v->value))
M_F("callerid", store_callerid(o, v->value))
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 99ce67a71..12ccba585 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -64,6 +64,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/callerid.h"
#include "asterisk/causes.h"
#include "asterisk/stringfields.h"
+#include "asterisk/musiconhold.h"
#include "DialTone.h"
@@ -219,6 +220,12 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
p->lastformat = -1;
res = 0;
break;
+ case AST_CONTROL_HOLD:
+ ast_moh_start(chan, data, NULL);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(chan);
+ break;
default:
ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name);
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 2db0dcc33..b9442ee1f 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -452,7 +452,8 @@ static const struct cfsip_options {
*/
#define DEFAULT_SIP_PORT 5060 /*!< From RFC 3261 (former 2543) */
#define DEFAULT_CONTEXT "default"
-#define DEFAULT_MUSICCLASS "default"
+#define DEFAULT_MOHINTERPRET "default"
+#define DEFAULT_MOHSUGGEST ""
#define DEFAULT_VMEXTEN "asterisk"
#define DEFAULT_CALLERID "asterisk"
#define DEFAULT_NOTIFYMIME "application/simple-message-summary"
@@ -486,7 +487,9 @@ static char default_fromdomain[AST_MAX_EXTENSION];
static char default_notifymime[AST_MAX_EXTENSION];
static int default_qualify; /*!< Default Qualify= setting */
static char default_vmexten[AST_MAX_EXTENSION];
-static char default_musicclass[MAX_MUSICCLASS]; /*!< Global music on hold class */
+static char default_mohinterpret[MAX_MUSICCLASS]; /*!< Global setting for moh class to use when put on hold */
+static char default_mohsuggest[MAX_MUSICCLASS]; /*!< Global setting for moh class to suggest when putting
+ * a bridged channel on hold */
static int default_maxcallbitrate; /*!< Maximum bitrate for call */
static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
@@ -868,7 +871,8 @@ static struct sip_pvt {
AST_STRING_FIELD(fromname); /*!< Name to show in the user field */
AST_STRING_FIELD(tohost); /*!< Host we should put in the "to" field */
AST_STRING_FIELD(language); /*!< Default language for this call */
- AST_STRING_FIELD(musicclass); /*!< Music on Hold class */
+ AST_STRING_FIELD(mohinterpret); /*!< MOH class to use when put on hold */
+ AST_STRING_FIELD(mohsuggest); /*!< MOH class to suggest when putting a peer on hold */
AST_STRING_FIELD(rdnis); /*!< Referring DNIS */
AST_STRING_FIELD(theirtag); /*!< Their tag */
AST_STRING_FIELD(username); /*!< [user] name */
@@ -986,7 +990,8 @@ struct sip_user {
char cid_name[80]; /*!< Caller ID name */
char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */
char language[MAX_LANGUAGE]; /*!< Default language for this user */
- char musicclass[MAX_MUSICCLASS];/*!< Music on Hold class */
+ char mohinterpret[MAX_MUSICCLASS];/*!< Music on Hold class */
+ char mohsuggest[MAX_MUSICCLASS];/*!< Music on Hold class */
char useragent[256]; /*!< User agent in SIP request */
struct ast_codec_pref prefs; /*!< codec prefs */
ast_group_t callgroup; /*!< Call group */
@@ -1032,7 +1037,8 @@ struct sip_peer {
char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
char language[MAX_LANGUAGE]; /*!< Default language for prompts */
- char musicclass[MAX_MUSICCLASS];/*!< Music on Hold class */
+ char mohinterpret[MAX_MUSICCLASS];/*!< Music on Hold class */
+ char mohsuggest[MAX_MUSICCLASS];/*!< Music on Hold class */
char useragent[256]; /*!< User agent in SIP request (saved from registration) */
struct ast_codec_pref prefs; /*!< codec prefs */
int lastmsgssent;
@@ -3541,21 +3547,16 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
}
res = -1;
break;
- case AST_CONTROL_HOLD: /* The other part of the bridge are put on hold */
- if (sipdebug)
- ast_log(LOG_DEBUG, "Bridged channel now on hold - %s\n", p->callid);
- res = -1;
+ case AST_CONTROL_HOLD:
+ ast_moh_start(ast, data, p->mohinterpret);
break;
- case AST_CONTROL_UNHOLD: /* The other part of the bridge are back from hold */
- if (sipdebug)
- ast_log(LOG_DEBUG, "Bridged channel is back from hold, let's talk! : %s\n", p->callid);
- res = -1;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(ast);
break;
case AST_CONTROL_VIDUPDATE: /* Request a video frame update */
if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
transmit_info_with_vidupdate(p);
/* ast_rtcp_send_h261fur(p->vrtp); */
- res = 0;
} else
res = -1;
break;
@@ -3681,8 +3682,6 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
tmp->amaflags = i->amaflags;
if (!ast_strlen_zero(i->language))
ast_string_field_set(tmp, language, i->language);
- if (!ast_strlen_zero(i->musicclass))
- ast_string_field_set(tmp, musicclass, i->musicclass);
i->owner = tmp;
ast_mutex_lock(&usecnt_lock);
usecnt++;
@@ -4086,7 +4085,8 @@ static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *si
else
ast_string_field_set(p, callid, callid);
/* Assign default music on hold class */
- ast_string_field_set(p, musicclass, default_musicclass);
+ ast_string_field_set(p, mohinterpret, default_mohinterpret);
+ ast_string_field_set(p, mohsuggest, default_mohsuggest);
p->capability = global_capability;
p->allowtransfer = global_allowtransfer;
if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
@@ -4935,13 +4935,16 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req)
/* We have a bridge */
/* Turn on/off music on hold if we are holding/unholding */
if (sin.sin_addr.s_addr && !sendonly) {
- ast_moh_stop(bridgepeer);
+ ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
/* Activate a re-invite */
ast_queue_frame(p->owner, &ast_null_frame);
- } else if (!sin.sin_addr.s_addr || sendonly ) {
+ } else if (!sin.sin_addr.s_addr || sendonly) {
/* No address for RTP, we're on hold */
- ast_moh_start(bridgepeer, NULL);
+ ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+
if (sendonly)
ast_rtp_stop(p->rtp);
/* RTCP needs to go ahead, even if we're on hold!!! */
@@ -8682,7 +8685,8 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
ast_string_field_set(p, subscribecontext, user->subscribecontext);
ast_string_field_set(p, accountcode, user->accountcode);
ast_string_field_set(p, language, user->language);
- ast_string_field_set(p, musicclass, user->musicclass);
+ ast_string_field_set(p, mohsuggest, user->mohsuggest);
+ ast_string_field_set(p, mohinterpret, user->mohinterpret);
p->allowtransfer = user->allowtransfer;
p->amaflags = user->amaflags;
p->callgroup = user->callgroup;
@@ -8769,6 +8773,8 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
ast_string_field_set(p, peersecret, peer->secret);
ast_string_field_set(p, peermd5secret, peer->md5secret);
ast_string_field_set(p, subscribecontext, peer->subscribecontext);
+ ast_string_field_set(p, mohinterpret, peer->mohinterpret);
+ ast_string_field_set(p, mohsuggest, peer->mohsuggest);
if (peer->callingpres) /* Peer calling pres setting will override RPID */
p->callingpres = peer->callingpres;
if (peer->maxms && peer->lastms)
@@ -9949,7 +9955,8 @@ static int sip_show_settings(int fd, int argc, char *argv[])
ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No");
ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)"));
- ast_cli(fd, " Musicclass: %s\n", default_musicclass);
+ ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret);
+ ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest);
ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten);
@@ -13373,8 +13380,7 @@ static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int
if (sipdebug && option_debug > 3)
ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
- /* Stop music on hold on this channel */
- ast_moh_stop(current.chan2);
+ ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
}
ast_set_flag(&p->flags[0], SIP_GOTREFER);
@@ -13603,7 +13609,7 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
bridged_to = ast_bridged_channel(c);
if (bridged_to) {
/* Don't actually hangup here... */
- ast_moh_stop(bridged_to);
+ ast_queue_control(c, AST_CONTROL_UNHOLD);
ast_async_goto(bridged_to, p->context, p->refer->refer_to,1);
} else
ast_queue_hangup(p->owner);
@@ -15021,7 +15027,8 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int
/* set default context */
strcpy(user->context, default_context);
strcpy(user->language, default_language);
- strcpy(user->musicclass, default_musicclass);
+ strcpy(user->mohinterpret, default_mohinterpret);
+ strcpy(user->mohsuggest, default_mohsuggest);
for (; v; v = v->next) {
if (handle_common_options(&userflags[0], &mask[0], v))
continue;
@@ -15056,8 +15063,11 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int
user->pickupgroup = ast_get_group(v->value);
} else if (!strcasecmp(v->name, "language")) {
ast_copy_string(user->language, v->value, sizeof(user->language));
- } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
+ } else if (!strcasecmp(v->name, "mohinterpret")
+ || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
+ ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
} else if (!strcasecmp(v->name, "call-limit")) {
@@ -15124,7 +15134,8 @@ static void set_peer_defaults(struct sip_peer *peer)
strcpy(peer->context, default_context);
strcpy(peer->subscribecontext, default_subscribecontext);
strcpy(peer->language, default_language);
- strcpy(peer->musicclass, default_musicclass);
+ strcpy(peer->mohinterpret, default_mohinterpret);
+ strcpy(peer->mohsuggest, default_mohsuggest);
peer->addr.sin_family = AF_INET;
peer->defaddr.sin_family = AF_INET;
peer->capability = global_capability;
@@ -15324,8 +15335,11 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
}
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
- } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
+ } else if (!strcasecmp(v->name, "mohinterpret")
+ || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
+ ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
} else if (!strcasecmp(v->name, "subscribemwi")) {
@@ -15516,7 +15530,8 @@ static int reload_config(enum channelreloadreason reason)
default_fromdomain[0] = '\0';
default_qualify = DEFAULT_QUALIFY;
default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
- ast_copy_string(default_musicclass, DEFAULT_MUSICCLASS, sizeof(default_musicclass));
+ ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
+ ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */
@@ -15607,8 +15622,11 @@ static int reload_config(enum channelreloadreason reason)
global_notifyringing = ast_true(v->value);
} else if (!strcasecmp(v->name, "alwaysauthreject")) {
global_alwaysauthreject = ast_true(v->value);
- } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(default_musicclass, v->value, sizeof(default_musicclass));
+ } else if (!strcasecmp(v->name, "mohinterpret")
+ || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
+ ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
} else if (!strcasecmp(v->name, "language")) {
ast_copy_string(default_language, v->value, sizeof(default_language));
} else if (!strcasecmp(v->name, "regcontext")) {
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index c74c090a9..e925b2e3c 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -733,7 +733,7 @@ static pthread_t tcp_thread;
static pthread_t accept_t;
static char context[AST_MAX_CONTEXT] = "default";
static char language[MAX_LANGUAGE] = "";
-static char musicclass[MAX_MUSICCLASS] = "";
+static char mohinterpret[MAX_MUSICCLASS] = "default";
static char cid_num[AST_MAX_EXTENSION] = "";
static char cid_name[AST_MAX_EXTENSION] = "";
static char linelabel[AST_MAX_EXTENSION] ="";
@@ -911,7 +911,7 @@ struct skinny_line {
char lastcallerid[AST_MAX_EXTENSION]; /* Last Caller*ID */
char call_forward[AST_MAX_EXTENSION];
char mailbox[AST_MAX_EXTENSION];
- char musicclass[MAX_MUSICCLASS];
+ char mohinterpret[MAX_MUSICCLASS];
char lastnumberdialed[AST_MAX_EXTENSION]; /* Last number that was dialed - used for redial */
int curtone; /* Current tone being played */
ast_group_t callgroup;
@@ -1847,8 +1847,8 @@ static struct skinny_device *build_device(const char *cat, struct ast_variable *
} else {
amaflags = y;
}
- } else if (!strcasecmp(v->name, "musiconhold")) {
- ast_copy_string(musicclass, v->value, sizeof(musicclass));
+ } else if (!strcasecmp(v->name, "mohinterpret") || !strcasecmp(v->name, "musiconhold")) {
+ ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
} else if (!strcasecmp(v->name, "callgroup")) {
cur_callergroup = ast_get_group(v->value);
} else if (!strcasecmp(v->name, "pickupgroup")) {
@@ -1913,7 +1913,7 @@ static struct skinny_device *build_device(const char *cat, struct ast_variable *
ast_copy_string(l->cid_name, cid_name, sizeof(l->cid_name));
ast_copy_string(l->label, linelabel, sizeof(l->label));
ast_copy_string(l->language, language, sizeof(l->language));
- ast_copy_string(l->musicclass, musicclass, sizeof(l->musicclass));
+ ast_copy_string(l->mohinterpret, mohinterpret, sizeof(l->mohinterpret));
ast_copy_string(l->mailbox, mailbox, sizeof(l->mailbox));
ast_copy_string(l->mailbox, mailbox, sizeof(l->mailbox));
if (!ast_strlen_zero(mailbox)) {
@@ -2502,6 +2502,12 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s
case -1:
transmit_tone(s, SKINNY_SILENCE);
break;
+ case AST_CONTROL_HOLD:
+ ast_moh_start(ast, data, l->mohinterpret);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(ast);
+ break;
case AST_CONTROL_PROCEEDING:
break;
default:
diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc
index d615e606a..fa17bf694 100644
--- a/channels/chan_vpb.cc
+++ b/channels/chan_vpb.cc
@@ -53,6 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/callerid.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
+#include "asterisk/musiconhold.h"
}
#include <sys/socket.h>
@@ -1777,7 +1778,12 @@ static int vpb_indicate(struct ast_channel *ast, int condition, const void *data
vpb_timer_start(p->busy_timer);
}
break;
-
+ case AST_CONTROL_HOLD:
+ ast_moh_start(ast, (const char *) data, NULL);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_moh_stop(ast);
+ break;
default:
res = 0;
break;
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 7d369a916..1e005b00a 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -206,7 +206,8 @@ static char defaultcic[64] = "";
static char defaultozz[64] = "";
static char language[MAX_LANGUAGE] = "";
-static char musicclass[MAX_MUSICCLASS] = "";
+static char mohinterpret[MAX_MUSICCLASS] = "default";
+static char mohsuggest[MAX_MUSICCLASS] = "";
static char progzone[10] = "";
static int usedistinctiveringdetection = 0;
@@ -613,7 +614,8 @@ static struct zt_pvt {
char defcontext[AST_MAX_CONTEXT];
char exten[AST_MAX_EXTENSION];
char language[MAX_LANGUAGE];
- char musicclass[MAX_MUSICCLASS];
+ char mohinterpret[MAX_MUSICCLASS];
+ char mohsuggest[MAX_MUSICCLASS];
#ifdef PRI_ANI
char cid_ani[AST_MAX_EXTENSION];
#endif
@@ -2424,7 +2426,7 @@ static int zt_hangup(struct ast_channel *ast)
if (p->owner->_state != AST_STATE_UP)
p->subs[SUB_REAL].needanswer = 1;
if (ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+ ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
} else if (p->subs[SUB_THREEWAY].zfd > -1) {
swap_subs(p, SUB_THREEWAY, SUB_REAL);
unalloc_sub(p, SUB_THREEWAY);
@@ -2445,8 +2447,11 @@ static int zt_hangup(struct ast_channel *ast)
if (p->subs[SUB_CALLWAIT].inthreeway) {
/* This is actually part of a three way, placed on hold. Place the third part
on music on hold now */
- if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
- ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
+ if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
+ ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+ }
p->subs[SUB_THREEWAY].inthreeway = 0;
/* Make it the call wait now */
swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
@@ -2457,8 +2462,11 @@ static int zt_hangup(struct ast_channel *ast)
if (p->subs[SUB_CALLWAIT].inthreeway) {
/* The other party of the three way call is currently in a call-wait state.
Start music on hold for them, and take the main guy out of the third call */
- if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
- ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
+ if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
+ ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+ }
p->subs[SUB_CALLWAIT].inthreeway = 0;
}
p->subs[SUB_REAL].inthreeway = 0;
@@ -3404,7 +3412,7 @@ static int attempt_transfer(struct zt_pvt *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->subs[SUB_THREEWAY].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
+ ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
}
@@ -3429,10 +3437,9 @@ static int attempt_transfer(struct zt_pvt *p)
ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
unalloc_sub(p, SUB_THREEWAY);
} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
+ ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+ if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)
ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
- }
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_THREEWAY].owner));
if (p->subs[SUB_THREEWAY].owner->cdr) {
/* Move CDR from second channel to current one */
p->subs[SUB_REAL].owner->cdr =
@@ -3897,7 +3904,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
/* Okay -- probably call waiting*/
if (ast_bridged_channel(p->owner))
- ast_moh_stop(ast_bridged_channel(p->owner));
+ ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
p->subs[index].needunhold = 1;
break;
case AST_STATE_RESERVED:
@@ -4054,11 +4061,17 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
p->callwaitingrepeat = 0;
p->cidcwexpire = 0;
/* Start music on hold if appropriate */
- if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner))
- ast_moh_start(ast_bridged_channel(p->subs[SUB_CALLWAIT].owner), NULL);
+ if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
+ ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+ }
p->subs[SUB_CALLWAIT].needhold = 1;
- if (ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+ if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
+ ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+ }
p->subs[SUB_REAL].needunhold = 1;
} else if (!p->subs[SUB_THREEWAY].owner) {
char cid_num[256];
@@ -4116,8 +4129,11 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
/* Start music on hold if appropriate */
- if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
- ast_moh_start(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), NULL);
+ if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
+ ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
+ S_OR(p->mohsuggest, NULL),
+ !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+ }
p->subs[SUB_THREEWAY].needhold = 1;
}
}
@@ -4155,7 +4171,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
otherindex = SUB_REAL;
}
if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[otherindex].owner));
+ ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
p->subs[otherindex].needunhold = 1;
p->owner = p->subs[SUB_REAL].owner;
if (ast->_state == AST_STATE_RINGING) {
@@ -4170,7 +4186,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
p->owner = p->subs[SUB_REAL].owner;
if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+ ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
p->subs[SUB_REAL].needunhold = 1;
zt_enable_ec(p);
}
@@ -4358,7 +4374,7 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
p->owner = p->subs[SUB_REAL].owner;
if (p->owner && ast_bridged_channel(p->owner))
- ast_moh_stop(ast_bridged_channel(p->owner));
+ ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
p->subs[SUB_REAL].needunhold = 1;
}
switch (res) {
@@ -4402,7 +4418,7 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
p->callwaitingrepeat = 0;
p->cidcwexpire = 0;
if (ast_bridged_channel(p->owner))
- ast_moh_stop(ast_bridged_channel(p->owner));
+ ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
p->subs[SUB_REAL].needunhold = 1;
} else
ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
@@ -5005,26 +5021,30 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data
#endif
res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
break;
-#ifdef HAVE_PRI
case AST_CONTROL_HOLD:
- if (p->pri) {
+#ifdef HAVE_PRI
+ if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
if (!pri_grab(p, p->pri)) {
res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
pri_rel(p->pri);
} else
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
+ } else
+#endif
+ ast_moh_start(chan, data, p->mohinterpret);
break;
case AST_CONTROL_UNHOLD:
- if (p->pri) {
+#ifdef HAVE_PRI
+ if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
if (!pri_grab(p, p->pri)) {
res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
pri_rel(p->pri);
} else
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- }
- break;
+ } else
#endif
+ ast_moh_stop(chan);
+ break;
case AST_CONTROL_RADIO_KEY:
if (p->radio)
res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
@@ -5176,8 +5196,6 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
}
if (!ast_strlen_zero(i->language))
ast_string_field_set(tmp, language, i->language);
- if (!ast_strlen_zero(i->musicclass))
- ast_string_field_set(tmp, musicclass, i->musicclass);
if (!i->owner)
i->owner = tmp;
if (!ast_strlen_zero(i->accountcode))
@@ -5882,7 +5900,7 @@ static void *ss_thread(void *data)
unalloc_sub(p, SUB_THREEWAY);
p->owner = p->subs[SUB_REAL].owner;
if (ast_bridged_channel(p->subs[SUB_REAL].owner))
- ast_moh_stop(ast_bridged_channel(p->subs[SUB_REAL].owner));
+ ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
ast_hangup(chan);
return NULL;
} else {
@@ -7301,7 +7319,8 @@ static struct zt_pvt *mkintf(int channel, int signalling, int outsignalling, int
tmp->transfer = transfer;
ast_copy_string(tmp->defcontext,context,sizeof(tmp->defcontext));
ast_copy_string(tmp->language, language, sizeof(tmp->language));
- ast_copy_string(tmp->musicclass, musicclass, sizeof(tmp->musicclass));
+ ast_copy_string(tmp->mohinterpret, mohinterpret, sizeof(tmp->mohinterpret));
+ ast_copy_string(tmp->mohsuggest, mohsuggest, sizeof(tmp->mohsuggest));
ast_copy_string(tmp->context, context, sizeof(tmp->context));
ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));
tmp->cid_ton = 0;
@@ -9662,9 +9681,9 @@ static int zap_show_channels(int fd, int argc, char **argv)
ast_mutex_lock(lock);
#ifdef HAVE_PRI
- ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MusicOnHold");
+ ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
#else
- ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MusicOnHold");
+ ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
#endif
tmp = start;
@@ -9673,7 +9692,7 @@ static int zap_show_channels(int fd, int argc, char **argv)
snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
} else
ast_copy_string(tmps, "pseudo", sizeof(tmps));
- ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->musicclass);
+ ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
tmp = tmp->next;
}
ast_mutex_unlock(lock);
@@ -10525,8 +10544,11 @@ static int setup_zap(int reload)
ast_copy_string(language, v->value, sizeof(language));
} else if (!strcasecmp(v->name, "progzone")) {
ast_copy_string(progzone, v->value, sizeof(progzone));
- } else if (!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
- ast_copy_string(musicclass, v->value, sizeof(musicclass));
+ } else if (!strcasecmp(v->name, "mohinterpret")
+ ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
+ ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
+ } else if (!strcasecmp(v->name, "mohsuggest")) {
+ ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
} else if (!strcasecmp(v->name, "stripmsd")) {
stripmsd = atoi(v->value);
} else if (!strcasecmp(v->name, "jitterbuffers")) {