diff options
author | Mark Spencer <markster@digium.com> | 2005-01-17 12:37:55 +0000 |
---|---|---|
committer | Mark Spencer <markster@digium.com> | 2005-01-17 12:37:55 +0000 |
commit | 840f035827cd7d75d1601c29d731d594afe330d4 (patch) | |
tree | 34bc6eb8b0c1666b2821cf4e797a9af81b2477e0 | |
parent | 441c545ccc7d81e9d5162e7325f017b1fe5efe97 (diff) |
Merge hold patch (bug #1840)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4823 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rwxr-xr-x | apps/app_dial.c | 10 | ||||
-rwxr-xr-x | channel.c | 24 | ||||
-rwxr-xr-x | channels/chan_zap.c | 29 | ||||
-rwxr-xr-x | include/asterisk/frame.h | 4 | ||||
-rwxr-xr-x | res/res_features.c | 25 |
5 files changed, 81 insertions, 11 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index 2828262b7..16323881c 100755 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -393,6 +393,16 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu if (!ast_test_flag(outgoing, DIAL_RINGBACKONLY)) ast_indicate(in, AST_CONTROL_PROGRESS); break; + case AST_CONTROL_HOLD: + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", o->chan->name); + ast_indicate(in, AST_CONTROL_HOLD); + break; + case AST_CONTROL_UNHOLD: + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", o->chan->name); + ast_indicate(in, AST_CONTROL_UNHOLD); + break; case AST_CONTROL_OFFHOOK: case AST_CONTROL_FLASH: /* Ignore going off hook and flash */ @@ -1478,6 +1478,10 @@ int ast_indicate(struct ast_channel *chan, int condition) /* ast_playtones_stop(chan); */ } else if (condition == AST_CONTROL_PROCEEDING) { /* Do nothing, really */ + } else if (condition == AST_CONTROL_HOLD) { + /* Do nothing.... */ + } else if (condition == AST_CONTROL_UNHOLD) { + /* Do nothing.... */ } else { /* not handled */ ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); @@ -2812,11 +2816,15 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as } if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { - *fo = f; - *rc = who; - res = 0; - ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); - break; + if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD)) { + ast_indicate(who == c0 ? c1 : c0, f->subclass); + } else { + *fo = f; + *rc = who; + res = 0; + ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); + break; + } } if ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_TEXT) || @@ -2861,9 +2869,9 @@ tackygoto: else ast_write(c0, f); } - ast_frfree(f); - } else - ast_frfree(f); + } + ast_frfree(f); + /* Swap who gets priority */ cs[2] = cs[0]; cs[0] = cs[1]; diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 292dfc191..36efc2176 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -4406,6 +4406,14 @@ static int zt_indicate(struct ast_channel *chan, int condition) #endif res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION); break; +#ifdef ZAPATA_PRI + case AST_CONTROL_HOLD: + res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD); + break; + case AST_CONTROL_UNHOLD: + res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL); + break; +#endif case AST_CONTROL_RADIO_KEY: if (p->radio) res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); @@ -8178,6 +8186,27 @@ static void *pri_dchannel(void *vpri) ast_mutex_unlock(&pri->pvts[chanpos]->lock); } break; + case PRI_EVENT_NOTIFY: + chanpos = pri_find_principle(pri, e->notify.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n", + PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span); + } else { + struct ast_frame f = { AST_FRAME_CONTROL, }; + ast_mutex_lock(&pri->pvts[chanpos]->lock); + switch(e->notify.info) { + case PRI_NOTIFY_REMOTE_HOLD: + f.subclass = AST_CONTROL_HOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; + case PRI_NOTIFY_REMOTE_RETRIEVAL: + f.subclass = AST_CONTROL_UNHOLD; + zap_queue_frame(pri->pvts[chanpos], &f, pri); + break; + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } + break; default: ast_log(LOG_DEBUG, "Event: %d\n", e->e); } diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 035105781..c634254f6 100755 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -226,6 +226,10 @@ struct ast_frame_chain { #define AST_CONTROL_PROGRESS 14 /*! Indicate CALL PROCEEDING */ #define AST_CONTROL_PROCEEDING 15 +/*! Indicate call is placed on hold */ +#define AST_CONTROL_HOLD 16 +/*! Indicate call is left from hold */ +#define AST_CONTROL_UNHOLD 17 #define AST_SMOOTHER_FLAG_G729 (1 << 0) diff --git a/res/res_features.c b/res/res_features.c index e06222914..691969781 100755 --- a/res/res_features.c +++ b/res/res_features.c @@ -229,8 +229,10 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou pu->chan = chan; /* Start music on hold */ - if (chan != peer) + if (chan != peer) { + ast_indicate(pu->chan, AST_CONTROL_HOLD); ast_moh_start(pu->chan, NULL); + } gettimeofday(&pu->start, NULL); pu->parkingnum = x; if (timeout > 0) @@ -478,6 +480,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p } /* 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); @@ -488,11 +491,13 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p if ((res=ast_streamfile(transferer, "pbx-transfer", transferer->language))) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } if ((res=ast_waitstream(transferer, AST_DIGIT_ANY)) < 0) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } ast_stopstream(transferer); @@ -507,12 +512,15 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p if (res < 0) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } if (!strcmp(newext, ast_parking_ext())) { ast_moh_stop(transferee); - if (ast_autoservice_stop(transferee)) + res = ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); + if (res) res = -1; else if (!ast_park_call(transferee, transferer, 0, NULL)) { /* We return non-zero, but tell the PBX not to hang the channel when @@ -533,6 +541,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name); ast_moh_stop(transferee); res=ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); if (!transferee->pbx) { /* Doh! Use our handy async_goto functions */ if (option_verbose > 2) @@ -559,12 +568,14 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p if (res) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } res = ast_waitstream(transferer, AST_DIGIT_ANY); ast_stopstream(transferer); ast_moh_stop(transferee); res = ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); if (res) { if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Hungup during autoservice stop on '%s'\n", transferee->name); @@ -606,6 +617,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st } /* 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); @@ -613,11 +625,13 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st if ((res=ast_streamfile(transferer, "pbx-transfer", transferer->language))) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } if ((res=ast_waitstream(transferer, AST_DIGIT_ANY)) < 0) { ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); return res; } if ((ast_app_dtget(transferer, transferer_real_context, xferto, sizeof(xferto), 100, transferdigittimeout))) { @@ -649,6 +663,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st } ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); transferer->_softhangup = 0; return FEATURE_RETURN_SUCCESS; } @@ -722,6 +737,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st ast_log(LOG_WARNING, "Unable to create channel Local/%s do you have chan_local?\n",dialstr); ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); if (!ast_strlen_zero(xferfailsound)) { res = ast_streamfile(transferer, xferfailsound, transferer->language); if (!res && (ast_waitstream(transferer, "") < 0)) { @@ -734,6 +750,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context); ast_moh_stop(transferee); ast_autoservice_stop(transferee); + ast_indicate(transferee, AST_CONTROL_UNHOLD); res = ast_streamfile(transferer, "beeperr", transferer->language); if (!res && (ast_waitstream(transferer, "") < 0)) { return -1; @@ -748,7 +765,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st } ast_moh_stop(transferee); ast_autoservice_stop(transferee); - + ast_indicate(transferee, AST_CONTROL_UNHOLD); return FEATURE_RETURN_SUCCESS; } @@ -1098,6 +1115,7 @@ static void *do_parking_thread(void *ignore) if (tms > pu->parkingtime) { /* Stop music on hold */ ast_moh_stop(pu->chan); + ast_indicate(pu->chan, AST_CONTROL_UNHOLD); /* Get chan, exten from derived kludge */ if (pu->peername[0]) { peername = ast_strdupa(pu->peername); @@ -1299,6 +1317,7 @@ static int park_exec(struct ast_channel *chan, void *data) } ast_moh_stop(peer); + ast_indicate(peer, AST_CONTROL_UNHOLD); res = ast_channel_make_compatible(chan, peer); if (res < 0) { ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, peer->name); |