From 1e6991f95e6a70146a64407ab01bbbe45f93745f Mon Sep 17 00:00:00 2001 From: Maximilian Fridrich Date: Fri, 29 Apr 2022 10:47:38 +0200 Subject: [PATCH] core_unreal: Flip stream direction of second channel. 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 | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/main/core_unreal.c b/main/core_unreal.c index a79fca417f..d43272c874 100644 --- a/main/core_unreal.c +++ b/main/core_unreal.c @@ -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 */