diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-07-19 20:44:39 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-07-19 20:44:39 +0000 |
commit | 6049bb6539153c2f400f1f2dbc763c74d796204b (patch) | |
tree | 3c36781db3a5a7a08967cbe8d83acb5d82e581cb /res | |
parent | 28df168d0f9fd12f5914263015dc26898e834146 (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.c | 2 | ||||
-rw-r--r-- | res/res_features.c | 46 | ||||
-rw-r--r-- | res/res_musiconhold.c | 35 |
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); } |