]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
core_unreal: Flip stream direction of second channel.
authorMaximilian Fridrich <m.fridrich@commend.com>
Fri, 29 Apr 2022 08:47:38 +0000 (10:47 +0200)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Thu, 5 May 2022 13:15:50 +0000 (08:15 -0500)
When a new unreal (local) channel is created, a second (;2) channel is
created as a counterpart which clones the topology of the first
channel. This creates issues when an outgoing stream is sendonly or
recvonly as the stream state of the inbound channel will be the same
as the stream state of the outbound channel.

Now the stream state is flipped for the streams of the 2nd channel in
ast_unreal_new_channels if the outgoing stream topology is recvonly or
sendonly.

ASTERISK-29655
Reported by: Michael Auracher

ASTERISK-29638
Reported by: Michael Auracher

Change-Id: I0cea29635bb20b7bf7fd0fb95498cd44dab98fbf

main/core_unreal.c

index a79fca417fd53e6b7e2211e1fd07625f8ca4c2e9..d43272c8742419209507fa8006efc0f14c88a4e3 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 */