]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AGI: Only defer frames when in an interception routine. 43/4343/2
authorMark Michelson <mmichelson@digium.com>
Thu, 3 Nov 2016 21:42:40 +0000 (16:42 -0500)
committerGeorge Joseph <gjoseph@digium.com>
Tue, 8 Nov 2016 14:06:44 +0000 (07:06 -0700)
AGI recently was modified to defer important frames. This was because
when AGI was used in a connected line interception routine, the
resulting connected line frame would end up getting discarded by the
AGI.

However, this caused bad behavior in other cases. Specifically, during a
transfer, if someone attempted to manually set the Caller ID on a
channel in an AGI, the deferred connected line frame would end up
overwriting what had been manually set in the AGI.

Since the initial issue was specific to interception routines, this
change removes the manual frame deferral from AGI and instead uses the
new frame deferral API in interception routines.

ASTERISK-26343 #close
Reported by Morton Tryfoss

Change-Id: Iab7d39436d0ee99bfe32ad55ef91e9bd88db4208

main/channel.c
res/res_agi.c

index 6317f6f20caf4b5a8dc2ac257ac4c6470d7b1bb2..b30bb1de792f333d334aceebc3398ab4bd6236db 100644 (file)
@@ -10283,9 +10283,15 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc
 
                ast_party_connected_line_copy(ast_channel_connected(macro_chan), connected);
        }
+       ast_channel_start_defer_frames(macro_chan);
        ast_channel_unlock(macro_chan);
 
        retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
+
+       ast_channel_lock(macro_chan);
+       ast_channel_stop_defer_frames(macro_chan);
+       ast_channel_unlock(macro_chan);
+
        if (!retval) {
                struct ast_party_connected_line saved_connected;
 
@@ -10333,9 +10339,15 @@ int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct a
 
                ast_party_redirecting_copy(ast_channel_redirecting(macro_chan), redirecting);
        }
+       ast_channel_start_defer_frames(macro_chan);
        ast_channel_unlock(macro_chan);
 
        retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
+
+       ast_channel_lock(macro_chan);
+       ast_channel_stop_defer_frames(macro_chan);
+       ast_channel_unlock(macro_chan);
+
        if (!retval) {
                struct ast_party_redirecting saved_redirecting;
 
@@ -10376,9 +10388,15 @@ int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct
 
                ast_party_connected_line_copy(ast_channel_connected(sub_chan), connected);
        }
+       ast_channel_start_defer_frames(sub_chan);
        ast_channel_unlock(sub_chan);
 
        retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
+
+       ast_channel_lock(sub_chan);
+       ast_channel_stop_defer_frames(sub_chan);
+       ast_channel_unlock(sub_chan);
+
        if (!retval) {
                struct ast_party_connected_line saved_connected;
 
@@ -10419,9 +10437,15 @@ int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast
 
                ast_party_redirecting_copy(ast_channel_redirecting(sub_chan), redirecting);
        }
+       ast_channel_start_defer_frames(sub_chan);
        ast_channel_unlock(sub_chan);
 
        retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
+
+       ast_channel_lock(sub_chan);
+       ast_channel_stop_defer_frames(sub_chan);
+       ast_channel_unlock(sub_chan);
+
        if (!retval) {
                struct ast_party_redirecting saved_redirecting;
 
index 06e8a03e2513e8f9abf362342e9bd5cc7e6ce3c4..5e047d4c3dce2d5168883560719e8970b1cd31dd 100644 (file)
@@ -4091,23 +4091,6 @@ static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, ch
        return AGI_RESULT_SUCCESS;
 }
 
-AST_LIST_HEAD_NOLOCK(deferred_frames, ast_frame);
-
-static void queue_deferred_frames(struct deferred_frames *deferred_frames,
-       struct ast_channel *chan)
-{
-       struct ast_frame *f;
-
-       if (!AST_LIST_EMPTY(deferred_frames)) {
-               ast_channel_lock(chan);
-               while ((f = AST_LIST_REMOVE_HEAD(deferred_frames, frame_list))) {
-                       ast_queue_frame_head(chan, f);
-                       ast_frfree(f);
-               }
-               ast_channel_unlock(chan);
-       }
-}
-
 static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead, int argc, char *argv[])
 {
        struct ast_channel *c;
@@ -4126,9 +4109,6 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
        const char *sighup_str;
        const char *exit_on_hangup_str;
        int exit_on_hangup;
-       struct deferred_frames deferred_frames;
-
-       AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
 
        ast_channel_lock(chan);
        sighup_str = pbx_builtin_getvar_helper(chan, "AGISIGHUP");
@@ -4190,20 +4170,8 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
                                        /* Write, ignoring errors */
                                        if (write(agi->audio, f->data.ptr, f->datalen) < 0) {
                                        }
-                                       ast_frfree(f);
-                               } else if (ast_is_deferrable_frame(f)) {
-                                       struct ast_frame *dup_f;
-
-                                       if ((dup_f = ast_frisolate(f))) {
-                                               AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
-                                       }
-
-                                       if (dup_f != f) {
-                                               ast_frfree(f);
-                                       }
-                               } else {
-                                       ast_frfree(f);
                                }
+                               ast_frfree(f);
                        }
                } else if (outfd > -1) {
                        size_t len = sizeof(buf);
@@ -4251,8 +4219,6 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
                                buf[buflen - 1] = '\0';
                        }
 
-                       queue_deferred_frames(&deferred_frames, chan);
-
                        if (agidebug)
                                ast_verbose("<%s>AGI Rx << %s\n", ast_channel_name(chan), buf);
                        cmd_status = agi_handle_command(chan, agi, buf, dead);
@@ -4275,8 +4241,6 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi
                }
        }
 
-       queue_deferred_frames(&deferred_frames, chan);
-
        if (agi->speech) {
                ast_speech_destroy(agi->speech);
        }