summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-03-07 11:22:18 +0000
committerJoshua Colp <jcolp@digium.com>2017-03-07 12:08:51 +0000
commit3ed05badb9f6ce3c3a3848b56c0747334624e0c3 (patch)
tree91a2893ebefae4fa7b5ccc93d68e9a108b375678 /main/channel.c
parentc9296b23d1574332ccbc83f3fc7ba492cfc34cfe (diff)
core: Add stream topology changing primitives with tests.
This change adds a few things to facilitate stream topology changing: 1. Control frame types have been added for use by the channel driver to notify the application that the channel wants to change the stream topology or that a stream topology change has been accepted. They are also used by the indicate interface to the channel that the application uses to indicate it wants to do the same. 2. Legacy behavior has been adopted in ast_read() such that if a channel requests a stream topology change it is denied automatically and the current stream topology is preserved if the application is not capable of handling streams. Tests have also been written which confirm the multistream and non-multistream behavior. ASTERISK-26839 Change-Id: Ia68ef22bca8e8457265ca4f0f9de600cbcc10bc9
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/main/channel.c b/main/channel.c
index 12a30e048..15c7fa406 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4068,6 +4068,19 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
}
ast_frfree(f);
f = &ast_null_frame;
+ } else if (f->subclass.integer == AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE && dropnondefault) {
+ /* The caller of this function is incapable of handling streams so we don't accept the change request
+ * and stick to the streams currently on the channel.
+ */
+ ast_channel_stream_topology_changed(chan, ast_channel_get_stream_topology(chan));
+ ast_frfree(f);
+ f = &ast_null_frame;
+ } else if (f->subclass.integer == AST_CONTROL_STREAM_TOPOLOGY_CHANGED && dropnondefault) {
+ /* The caller of this function is incapable of handling streams so we absord the notification that the
+ * stream topology has changed.
+ */
+ ast_frfree(f);
+ f = &ast_null_frame;
}
break;
case AST_FRAME_DTMF_END:
@@ -4494,6 +4507,8 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
case AST_CONTROL_UPDATE_RTP_PEER:
case AST_CONTROL_PVT_CAUSE_CODE:
case AST_CONTROL_MASQUERADE_NOTIFY:
+ case AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE:
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
case AST_CONTROL_STREAM_STOP:
case AST_CONTROL_STREAM_SUSPEND:
case AST_CONTROL_STREAM_REVERSE:
@@ -4792,6 +4807,8 @@ static int indicate_data_internal(struct ast_channel *chan, int _condition, cons
case AST_CONTROL_MCID:
case AST_CONTROL_MASQUERADE_NOTIFY:
case AST_CONTROL_UPDATE_RTP_PEER:
+ case AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE:
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
case AST_CONTROL_STREAM_STOP:
case AST_CONTROL_STREAM_SUSPEND:
case AST_CONTROL_STREAM_REVERSE:
@@ -11147,3 +11164,27 @@ enum ast_channel_error ast_channel_errno(void)
{
return ast_channel_internal_errno();
}
+
+int ast_channel_request_stream_topology_change(struct ast_channel *chan, struct ast_stream_topology *topology)
+{
+ ast_assert(chan != NULL);
+ ast_assert(topology != NULL);
+
+ if (!ast_channel_is_multistream(chan) || !ast_channel_tech(chan)->indicate) {
+ return -1;
+ }
+
+ return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, topology, sizeof(topology));
+}
+
+int ast_channel_stream_topology_changed(struct ast_channel *chan, struct ast_stream_topology *topology)
+{
+ ast_assert(chan != NULL);
+ ast_assert(topology != NULL);
+
+ if (!ast_channel_is_multistream(chan) || !ast_channel_tech(chan)->indicate) {
+ return -1;
+ }
+
+ return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, topology, sizeof(topology));
+}