]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
core_unreal & app_dial: Flip stream direction of second channel.
authorMaximilian Fridrich <m.fridrich@commend.com>
Wed, 13 Apr 2022 13:12:03 +0000 (15:12 +0200)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Tue, 26 Apr 2022 15:45:29 +0000 (10:45 -0500)
When executing dial, the topology of the inbound channel is cloned and
used for the outbound channel. This creates issues when an incoming
stream is sendonly or recvonly as the stream state of the outbound
channel will be the same as the stream state of the inbound channel.

Now the stream state is flipped for the outgoing stream in
dial_exec_full if the incoming stream topology is recvonly or sendonly.

The same is the case for unreal (local) channels which create a second
(;2) channel as a counterpart which clones the topology of the
first channel. Now the stream state is flipped for the streams of
the 2nd channel in ast_unreal_new_channels if the incoming stream
topology is recvonly or sendonly.

ASTERISK-29655
Reported by: Michael Auracher

ASTERISK-29638
Reported by: Michael Auracher

Change-Id: I294dc834ac9a5f048b101b691669959e9df630e1

apps/app_dial.c
main/core_unreal.c

index ee77551143ba7dae70cd9f8e5e0b3a667ba3b007..fdcf66bbea95eb73aa2750216d0f907dcb8123ec 100644 (file)
@@ -2587,9 +2587,11 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                struct ast_channel *tc; /* channel for this destination */
                char *number;
                char *tech;
+               int i;
                size_t tech_len;
                size_t number_len;
                struct ast_stream_topology *topology;
+               struct ast_stream *stream;
 
                cur = ast_strip(cur);
                if (ast_strlen_zero(cur)) {
@@ -2655,6 +2657,21 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 
                ast_channel_unlock(chan);
 
+               for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
+                       stream = ast_stream_topology_get_stream(topology, i);
+                       /* For both recvonly and sendonly the stream state reflects our state, that is we
+                        * are receiving only and we are sending only. Since we are requesting a
+                        * channel for the peer, we need to swap this to reflect what we will be doing.
+                        * That is, if we are receiving from Alice then we want to be sending to Bob,
+                        * so swap recvonly to sendonly and vice versa.
+                        */
+                       if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
+                               ast_stream_set_state(stream, AST_STREAM_STATE_SENDONLY);
+                       } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
+                               ast_stream_set_state(stream, AST_STREAM_STATE_RECVONLY);
+                       }
+               }
+
                tc = ast_request_with_stream_topology(tmp->tech, topology, NULL, chan, tmp->number, &cause);
 
                ast_stream_topology_free(topology);
index dec992d1831bb3291c19d256f931fc6fce996b16..861e18844a1392c2dff11801ce371833b8ae70ce 100644 (file)
@@ -1168,7 +1168,9 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
        struct ast_assigned_ids id1 = {NULL, NULL};
        struct ast_assigned_ids id2 = {NULL, NULL};
        int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
-       struct ast_stream_topology *topology;
+       int i;
+       struct ast_stream_topology *chan_topology;
+       struct ast_stream *stream;
 
        /* set unique ids for the two channels */
        if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
@@ -1186,14 +1188,27 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
                id2.uniqueid = uniqueid2;
        }
 
-       /* We need to create a topology to place on the first channel, as we can't
+       /* We need to create a topology to place on the second channel, as we can't
         * share a single one between both.
         */
-       topology = ast_stream_topology_clone(p->reqtopology);
-       if (!topology) {
+       chan_topology = ast_stream_topology_clone(p->reqtopology);
+       if (!chan_topology) {
                return NULL;
        }
 
+       for (i = 0; i < ast_stream_topology_get_count(chan_topology); ++i) {
+               stream = ast_stream_topology_get_stream(chan_topology, i);
+               /* We need to make sure that the ;2 channel has the opposite stream topology
+                * of the first channel if the stream is one-way. I.e. if the first channel
+                * is recvonly, the second channel has to be sendonly and vice versa.
+                */
+               if (ast_stream_get_state(stream) == AST_STREAM_STATE_RECVONLY) {
+                       ast_stream_set_state(stream, AST_STREAM_STATE_SENDONLY);
+               } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
+                       ast_stream_set_state(stream, AST_STREAM_STATE_RECVONLY);
+               }
+       }
+
        /*
         * Allocate two new Asterisk channels
         *
@@ -1206,7 +1221,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
                "%s/%s-%08x;1", tech->type, p->name, (unsigned)generated_seqno);
        if (!owner) {
                ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
-               ast_stream_topology_free(topology);
+               ast_stream_topology_free(chan_topology);
                return NULL;
        }
 
@@ -1221,7 +1236,8 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
        ast_channel_nativeformats_set(owner, p->reqcap);
 
        if (ast_channel_is_multistream(owner)) {
-               ast_channel_set_stream_topology(owner, topology);
+               ast_channel_set_stream_topology(owner, p->reqtopology);
+               p->reqtopology = NULL;
        }
 
        /* Determine our read/write format and set it on each channel */
@@ -1279,8 +1295,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
        ast_channel_nativeformats_set(chan, p->reqcap);
 
        if (ast_channel_is_multistream(chan)) {
-               ast_channel_set_stream_topology(chan, p->reqtopology);
-               p->reqtopology = NULL;
+               ast_channel_set_stream_topology(chan, chan_topology);
        }
 
        /* Format was already determined when setting up owner */