Index: include/asterisk/frame.h =================================================================== --- include/asterisk/frame.h (revision 102967) +++ include/asterisk/frame.h (working copy) @@ -130,6 +130,13 @@ * The translator can not be free'd if the frame inside of it still has * this flag set. */ AST_FRFLAG_FROM_TRANSLATOR = (1 << 1), + /*! Frame was already read from ast_read. Autoservice sets this flag + * on all frames it queues back to the channel to make sure ast_read + * won't do any special processing (like DTMF emulation) based on this + * frame. This is because the frame itself can be already a rusult + * of such a processing + */ + AST_FRFLAG_READ = (1 << 2), }; /*! \brief Data structure associated with a single frame of data Index: main/autoservice.c =================================================================== --- main/autoservice.c (revision 102967) +++ main/autoservice.c (working copy) @@ -252,6 +252,9 @@ usleep(1000); while ((f = AST_LIST_REMOVE_HEAD(&dtmf_frames, frame_list))) { + /* Mark frame as already read so ast_read will not do any + additional processing (like DTMF emulation) with it */ + f->flags |= AST_FRFLAG_READ; ast_queue_frame(chan, f); ast_frfree(f); } Index: main/channel.c =================================================================== --- main/channel.c (revision 102967) +++ main/channel.c (working copy) @@ -2020,6 +2020,17 @@ ast_frfree(f); f = NULL; } + + if (f && (f->flags & AST_FRFLAG_READ)) { + /* This frame was already read from us by autoservice/dsp so we do not need + do any processing on it because it may be actually a result of + such a processing (emulated DTMF_BEGIN for example). + However, reset AST_FRFLAG_READ to make sure the frame may be queued to another + channel and read from there with all necessary processing */ + f->flags &= ~AST_FRFLAG_READ; + goto done; + } + } else { chan->blocker = pthread_self(); if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {