aboutsummaryrefslogtreecommitdiffstats
path: root/res
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 /res
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 'res')
-rw-r--r--res/res_agi.c2
-rw-r--r--res/res_features.c46
-rw-r--r--res/res_musiconhold.c35
3 files changed, 50 insertions, 33 deletions
diff --git a/res/res_agi.c b/res/res_agi.c
index 7caa4c96d..1624e5455 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -1330,7 +1330,7 @@ static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, char *argv[]
static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
{
if (!strncasecmp(argv[2], "on", 2))
- ast_moh_start(chan, argc > 3 ? argv[3] : NULL);
+ ast_moh_start(chan, argc > 3 ? argv[3] : NULL, NULL);
else if (!strncasecmp(argv[2], "off", 3))
ast_moh_stop(chan);
fdprintf(agi->fd, "200 result=0\n");
diff --git a/res/res_features.c b/res/res_features.c
index 588229e16..8926afa78 100644
--- a/res/res_features.c
+++ b/res/res_features.c
@@ -83,6 +83,7 @@ static char parking_con[AST_MAX_EXTENSION]; /*!< Context for whic
static char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
static char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
+static char parkmohclass[MAX_MUSICCLASS]; /*!< Music class used for parking */
static int parking_start; /*!< First available extension for parking */
static int parking_stop; /*!< Last available extension for parking */
@@ -358,11 +359,13 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
pu->chan = chan;
- /* Start music on hold if we have two different channels */
+ /* Put the parked channel on hold if we have two different channels */
if (chan != peer) {
- ast_indicate(pu->chan, AST_CONTROL_HOLD); /* Indicate to peer that we're on hold */
- ast_moh_start(pu->chan, NULL);
+ ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ S_OR(parkmohclass, NULL),
+ !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
}
+
pu->start = ast_tvnow();
pu->parkingnum = x;
pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
@@ -423,7 +426,9 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou
ast_say_digits(peer, pu->parkingnum, "", peer->language);
if (pu->notquiteyet) {
/* Wake up parking thread if we're really done */
- ast_moh_start(pu->chan, NULL);
+ ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ S_OR(parkmohclass, NULL),
+ !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
pu->notquiteyet = 0;
pthread_kill(parking_thread, SIGURG);
}
@@ -612,12 +617,9 @@ static int builtin_disconnect(struct ast_channel *chan, struct ast_channel *peer
static int finishup(struct ast_channel *chan)
{
- int res;
-
- ast_moh_stop(chan);
- res = ast_autoservice_stop(chan);
ast_indicate(chan, AST_CONTROL_UNHOLD);
- return res;
+
+ return ast_autoservice_stop(chan);
}
/*! \brief Find the context for the transfer */
@@ -644,9 +646,8 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
set_peers(&transferer, &transferee, peer, chan, sense);
transferer_real_context = real_ctx(transferer, transferee);
/* Start autoservice on chan while we talk to the originator */
- ast_indicate(transferee, AST_CONTROL_HOLD);
ast_autoservice_start(transferee);
- ast_moh_start(transferee, NULL);
+ ast_indicate(transferee, AST_CONTROL_HOLD);
memset(xferto, 0, sizeof(xferto));
@@ -731,7 +732,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
struct ast_channel *transferer;
struct ast_channel *transferee;
const char *transferer_real_context;
- char xferto[256];
+ char xferto[256] = "";
int res;
int outstate=0;
struct ast_channel *newchan;
@@ -746,10 +747,9 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
set_peers(&transferer, &transferee, peer, chan, sense);
transferer_real_context = real_ctx(transferer, transferee);
/* Start autoservice on chan while we talk to the originator */
- ast_indicate(transferee, AST_CONTROL_HOLD);
ast_autoservice_start(transferee);
- ast_moh_start(transferee, NULL);
- memset(xferto, 0, sizeof(xferto));
+ ast_indicate(transferee, AST_CONTROL_HOLD);
+
/* Transfer */
res = ast_stream_and_wait(transferer, "pbx-transfer", transferer->language, AST_DIGIT_ANY);
if (res < 0) {
@@ -814,7 +814,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
if (check_compat(transferee, newchan))
return -1;
- ast_moh_stop(transferee);
+ ast_indicate(transferee, AST_CONTROL_UNHOLD);
if ((ast_autoservice_stop(transferee) < 0)
|| (ast_waitfordigit(transferee, 100) < 0)
@@ -1521,8 +1521,6 @@ static void *do_parking_thread(void *ignore)
}
tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
if (tms > pu->parkingtime) {
- /* Stop music on hold */
- ast_moh_stop(chan);
ast_indicate(chan, AST_CONTROL_UNHOLD);
/* Get chan, exten from derived kludge */
if (pu->peername[0]) {
@@ -1620,7 +1618,9 @@ static void *do_parking_thread(void *ignore)
if (pu->moh_trys < 3 && !chan->generatordata) {
if (option_debug)
ast_log(LOG_DEBUG, "MOH on parked call stopped by outside source. Restarting.\n");
- ast_moh_start(chan, NULL);
+ ast_indicate_data(pu->chan, AST_CONTROL_HOLD,
+ S_OR(parkmohclass, NULL),
+ !ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
pu->moh_trys++;
}
goto std; /*! \todo XXX Ick: jumping into an else statement??? XXX */
@@ -1748,7 +1748,6 @@ static int park_exec(struct ast_channel *chan, void *data)
if (!ast_strlen_zero(courtesytone)) {
int error = 0;
- ast_moh_stop(peer);
ast_indicate(peer, AST_CONTROL_UNHOLD);
if (parkedplay == 0) {
error = ast_stream_and_wait(chan, courtesytone, chan->language, "");
@@ -1770,10 +1769,8 @@ static int park_exec(struct ast_channel *chan, void *data)
ast_hangup(peer);
return -1;
}
- } else {
- ast_moh_stop(peer);
+ } else
ast_indicate(peer, AST_CONTROL_UNHOLD);
- }
res = ast_channel_make_compatible(chan, peer);
if (res < 0) {
@@ -2063,6 +2060,7 @@ static int load_config(void)
strcpy(parking_con_dial, "park-dial");
strcpy(parking_ext, "700");
strcpy(pickup_ext, "*8");
+ strcpy(parkmohclass, "default");
courtesytone[0] = '\0';
strcpy(xfersound, "beep");
strcpy(xferfailsound, "pbx-invalid");
@@ -2134,6 +2132,8 @@ static int load_config(void)
ast_copy_string(xferfailsound, var->value, sizeof(xferfailsound));
} else if (!strcasecmp(var->name, "pickupexten")) {
ast_copy_string(pickup_ext, var->value, sizeof(pickup_ext));
+ } else if (!strcasecmp(var->name, "parkedmusicclass")) {
+ ast_copy_string(parkmohclass, var->value, sizeof(parkmohclass));
}
}
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index f2d5222ad..b777ccd2d 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -549,7 +549,7 @@ static void *monmp3thread(void *data)
static int moh0_exec(struct ast_channel *chan, void *data)
{
- if (ast_moh_start(chan, data)) {
+ if (ast_moh_start(chan, data, NULL)) {
ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name);
return -1;
}
@@ -565,7 +565,7 @@ static int moh1_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n");
return -1;
}
- if (ast_moh_start(chan, NULL)) {
+ if (ast_moh_start(chan, NULL, NULL)) {
ast_log(LOG_WARNING, "Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->name);
return -1;
}
@@ -589,7 +589,7 @@ static int moh3_exec(struct ast_channel *chan, void *data)
char *class = NULL;
if (data && strlen(data))
class = data;
- if (ast_moh_start(chan, class))
+ if (ast_moh_start(chan, class, NULL))
ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name);
return 0;
@@ -884,20 +884,37 @@ static void local_ast_moh_cleanup(struct ast_channel *chan)
}
}
-static int local_ast_moh_start(struct ast_channel *chan, const char *class)
+static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
{
struct mohclass *mohclass;
-
- if (ast_strlen_zero(class))
+ const char *class;
+
+ /* The following is the order of preference for which class to use:
+ * 1) The channels explicitly set musicclass, which should *only* be
+ * set by a call to Set(CHANNEL(musicclass)=whatever) in the dialplan.
+ * 2) The mclass argument. If a channel is calling ast_moh_start() as the
+ * result of receiving a HOLD control frame, this should be the
+ * payload that came with the frame.
+ * 3) The interpclass argument. This would be from the mohinterpret
+ * option from channel drivers. This is the same as the old musicclass
+ * option.
+ * 4) The default class.
+ */
+ if (!ast_strlen_zero(chan->musicclass))
class = chan->musicclass;
- if (ast_strlen_zero(class))
+ else if (!ast_strlen_zero(mclass))
+ class = mclass;
+ else if (!ast_strlen_zero(interpclass))
+ class = interpclass;
+ else
class = "default";
+
AST_LIST_LOCK(&mohclasses);
mohclass = get_mohbyname(class);
AST_LIST_UNLOCK(&mohclasses);
if (!mohclass) {
- ast_log(LOG_WARNING, "No class: %s\n", (char *)class);
+ ast_log(LOG_WARNING, "No class: %s\n", class);
return -1;
}
@@ -1104,7 +1121,7 @@ static void moh_on_off(int on)
while ( (chan = ast_channel_walk_locked(chan)) != NULL) {
if (ast_test_flag(chan, AST_FLAG_MOH)) {
if (on)
- local_ast_moh_start(chan, NULL);
+ local_ast_moh_start(chan, NULL, NULL);
else
ast_deactivate_generator(chan);
}