]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 278272 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 20 Jul 2010 22:30:46 +0000 (22:30 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 20 Jul 2010 22:30:46 +0000 (22:30 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r278272 | tilghman | 2010-07-20 17:26:23 -0500 (Tue, 20 Jul 2010) | 11 lines

  Merged revisions 278167 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r278167 | tilghman | 2010-07-20 15:59:06 -0500 (Tue, 20 Jul 2010) | 4 lines

    Do not queue up DTMF frames while a call is on hold.

    (Fixes ABE-2110)
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.2@278273 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/channel.h
main/autoservice.c
main/features.c

index f50229969f8b38f048c6bedd9ae0c5cbb364b94b..7dde431be7adcfb6bd43167d524699877e0cf3d3 100644 (file)
@@ -1584,6 +1584,18 @@ int ast_autoservice_start(struct ast_channel *chan);
  */
 int ast_autoservice_stop(struct ast_channel *chan);
 
+/*!
+ * \brief Ignore certain frame types
+ * \note Normally, we cache DTMF, IMAGE, HTML, TEXT, and CONTROL frames
+ * while a channel is in autoservice and queue them up when taken out of
+ * autoservice.  When this is not desireable, this API may be used to
+ * cause the channel to ignore those frametypes after the channel is put
+ * into autoservice, but before autoservice is stopped.
+ * \retval 0 success
+ * \retval -1 channel is not in autoservice
+ */
+int ast_autoservice_ignore(struct ast_channel *chan, enum ast_frame_type ftype);
+
 /*!
  * \brief Enable or disable timer ticks for a channel
  *
index 6b9633301131ac5f110d5ac35929fd12cdb45d3b..731038fef222f2833709ba6152158b947d5f342e 100644 (file)
@@ -56,6 +56,7 @@ struct asent {
         *  it gets stopped for the last time. */
        unsigned int use_count;
        unsigned int orig_end_dtmf_flag:1;
+       unsigned int ignore_frame_types;
        /*! Frames go on at the head of deferred_frames, so we have the frames
         *  from newest to oldest.  As we put them at the head of the readq, we'll
         *  end up with them in the right order for the channel's readq. */
@@ -286,7 +287,9 @@ int ast_autoservice_stop(struct ast_channel *chan)
 
        ast_channel_lock(chan);
        while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
-               ast_queue_frame_head(chan, f);
+               if (!((1 << f->frametype) & as->ignore_frame_types)) {
+                       ast_queue_frame_head(chan, f);
+               }
                ast_frfree(f);
        }
        ast_channel_unlock(chan);
@@ -296,6 +299,23 @@ int ast_autoservice_stop(struct ast_channel *chan)
        return res;
 }
 
+int ast_autoservice_ignore(struct ast_channel *chan, enum ast_frame_type ftype)
+{
+       struct asent *as;
+       int res = -1;
+
+       AST_LIST_LOCK(&aslist);
+       AST_LIST_TRAVERSE(&aslist, as, list) {
+               if (as->chan == chan) {
+                       res = 0;
+                       as->ignore_frame_types |= (1 << ftype);
+                       break;
+               }
+       }
+       AST_LIST_UNLOCK(&aslist);
+       return res;
+}
+
 void ast_autoservice_init(void)
 {
        ast_cond_init(&as_cond, NULL);
index 0668ae657f7bf962c6f998c8ce92d13b1eeff548..d2f989835718d324cbf29ed1f3ae1163199d5f2e 100644 (file)
@@ -978,6 +978,7 @@ static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct
        /* First play for caller, put other channel on auto service */
        if (ast_autoservice_start(callee_chan))
                return -1;
+       ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
        if (ast_stream_and_wait(caller_chan, audiofile, "")) {
                ast_log(LOG_WARNING, "Failed to play automon message!\n");
                ast_autoservice_stop(callee_chan);
@@ -988,6 +989,7 @@ static int play_message_in_bridged_call(struct ast_channel *caller_chan, struct
        /* Then play for callee, put other channel on auto service */
        if (ast_autoservice_start(caller_chan))
                return -1;
+       ast_autoservice_ignore(caller_chan, AST_FRAME_DTMF_END);
        if (ast_stream_and_wait(callee_chan, audiofile, "")) {
                ast_log(LOG_WARNING, "Failed to play automon message !\n");
                ast_autoservice_stop(caller_chan);
@@ -1130,6 +1132,7 @@ static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *
        if (!ast_strlen_zero(courtesytone)) {
                if (ast_autoservice_start(callee_chan))
                        return -1;
+               ast_autoservice_ignore(callee_chan, AST_FRAME_DTMF_END);
                if (ast_stream_and_wait(caller_chan, courtesytone, "")) {
                        ast_log(LOG_WARNING, "Failed to play courtesy tone!\n");
                        ast_autoservice_stop(callee_chan);
@@ -1277,6 +1280,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
        transferer_real_context = real_ctx(transferer, transferee);
        /* Start autoservice on chan while we talk to the originator */
        ast_autoservice_start(transferee);
+       ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
        ast_indicate(transferee, AST_CONTROL_HOLD);
 
        memset(xferto, 0, sizeof(xferto));
@@ -1418,6 +1422,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
        transferer_real_context = real_ctx(transferer, transferee);
        /* Start autoservice on chan while we talk to the originator */
        ast_autoservice_start(transferee);
+       ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
        ast_indicate(transferee, AST_CONTROL_HOLD);
        
        /* Transfer */
@@ -1624,6 +1629,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
                        while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
                                /* Trying to transfer again */
                                ast_autoservice_start(transferee);
+                               ast_autoservice_ignore(transferee, AST_FRAME_DTMF_END);
                                ast_indicate(transferee, AST_CONTROL_HOLD);
 
                                newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
@@ -1964,6 +1970,7 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
        }
 
        ast_autoservice_start(idle);
+       ast_autoservice_ignore(idle, AST_FRAME_DTMF_END);
        
        if (!ast_strlen_zero(feature->moh_class))
                ast_moh_start(idle, feature->moh_class, NULL);