Merge "func_jitterbuffer: Add audio/video sync support."
[asterisk/asterisk.git] / bridges / bridge_simple.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Simple two channel bridging module
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  *
25  * \ingroup bridges
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #include "asterisk/module.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/bridge.h"
43 #include "asterisk/bridge_technology.h"
44 #include "asterisk/frame.h"
45 #include "asterisk/stream.h"
46
47 static void simple_bridge_stream_topology_changed(struct ast_bridge *bridge,
48                 struct ast_bridge_channel *bridge_channel);
49
50 static int simple_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
51 {
52         struct ast_channel *c0 = AST_LIST_FIRST(&bridge->channels)->chan;
53         struct ast_channel *c1 = AST_LIST_LAST(&bridge->channels)->chan;
54
55         /*
56          * If this is the first channel we can't make it compatible...
57          * unless we make it compatible with itself.  O.o
58          */
59         if (c0 == c1) {
60                 return 0;
61         }
62
63         if (ast_channel_make_compatible(c0, c1)) {
64                 return -1;
65         }
66
67         /* Align stream topologies */
68         simple_bridge_stream_topology_changed(bridge, NULL);
69         return 0;
70 }
71
72 static int simple_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
73 {
74         const struct ast_control_t38_parameters *t38_parameters;
75         int defer = 0;
76
77         if (!ast_bridge_queue_everyone_else(bridge, bridge_channel, frame)) {
78                 /* This frame was successfully queued so no need to defer */
79                 return 0;
80         }
81
82         /* Depending on the frame defer it so when the next channel joins it receives it */
83         switch (frame->frametype) {
84         case AST_FRAME_CONTROL:
85                 switch (frame->subclass.integer) {
86                 case AST_CONTROL_T38_PARAMETERS:
87                         t38_parameters = frame->data.ptr;
88                         switch (t38_parameters->request_response) {
89                         case AST_T38_REQUEST_NEGOTIATE:
90                                 defer = -1;
91                                 break;
92                         default:
93                                 break;
94                         }
95                         break;
96                 default:
97                         break;
98                 }
99                 break;
100         default:
101                 break;
102         }
103
104         return defer;
105 }
106
107 static struct ast_bridge_technology simple_bridge = {
108         .name = "simple_bridge",
109         .capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX,
110         .preference = AST_BRIDGE_PREFERENCE_BASE_1TO1MIX,
111         .join = simple_bridge_join,
112         .write = simple_bridge_write,
113         .stream_topology_changed = simple_bridge_stream_topology_changed,
114 };
115
116 static struct ast_stream_topology *simple_bridge_request_stream_topology_update(
117         struct ast_stream_topology *existing_topology,
118         struct ast_stream_topology *requested_topology)
119 {
120         struct ast_stream *stream;
121         struct ast_format_cap *audio_formats = NULL;
122         struct ast_stream_topology *new_topology;
123         int i;
124
125         new_topology = ast_stream_topology_clone(requested_topology);
126         if (!new_topology) {
127                 return NULL;
128         }
129
130         /* We find an existing stream with negotiated audio formats that we can place into
131          * any audio streams in the new topology to ensure that negotiation succeeds. Some
132          * endpoints incorrectly terminate the call if SDP negotiation fails.
133          */
134         for (i = 0; i < ast_stream_topology_get_count(existing_topology); ++i) {
135                 stream = ast_stream_topology_get_stream(existing_topology, i);
136
137                 if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_AUDIO ||
138                         ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED) {
139                         continue;
140                 }
141
142                 audio_formats = ast_stream_get_formats(stream);
143                 break;
144         }
145
146         if (audio_formats) {
147                 for (i = 0; i < ast_stream_topology_get_count(new_topology); ++i) {
148                         stream = ast_stream_topology_get_stream(new_topology, i);
149
150                         if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_AUDIO ||
151                                 ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED) {
152                                 continue;
153                         }
154
155                         ast_format_cap_append_from_cap(ast_stream_get_formats(stream), audio_formats,
156                                 AST_MEDIA_TYPE_AUDIO);
157                 }
158         }
159
160         return new_topology;
161 }
162
163 static void simple_bridge_stream_topology_changed(struct ast_bridge *bridge,
164                 struct ast_bridge_channel *bridge_channel)
165 {
166         struct ast_channel *req_chan;
167         struct ast_channel *existing_chan;
168         struct ast_stream_topology *req_top;
169         struct ast_stream_topology *existing_top;
170         struct ast_stream_topology *new_top;
171
172         if (bridge_channel) {
173                 ast_bridge_channel_stream_map(bridge_channel);
174
175                 if (ast_channel_get_stream_topology_change_source(bridge_channel->chan)
176                         == &simple_bridge) {
177                         return;
178                 }
179         }
180
181         req_chan = AST_LIST_FIRST(&bridge->channels)->chan;
182         existing_chan = AST_LIST_LAST(&bridge->channels)->chan;
183         if (req_chan == existing_chan) {
184                 /* Wait until both channels are in the bridge to align topologies. */
185                 return;
186         }
187
188         /* Align topologies according to size or first channel to join */
189         ast_channel_lock_both(req_chan, existing_chan);
190         req_top = ast_channel_get_stream_topology(req_chan);
191         existing_top = ast_channel_get_stream_topology(existing_chan);
192         if (ast_stream_topology_get_count(req_top) < ast_stream_topology_get_count(existing_top)) {
193                 SWAP(req_top, existing_top);
194                 SWAP(req_chan, existing_chan);
195         }
196         new_top = simple_bridge_request_stream_topology_update(existing_top, req_top);
197         ast_channel_unlock(req_chan);
198         ast_channel_unlock(existing_chan);
199
200         if (!new_top) {
201                 /* Failure.  We'll just have to live with the current topology. */
202                 return;
203         }
204
205         ast_channel_request_stream_topology_change(existing_chan, new_top, &simple_bridge);
206         ast_stream_topology_free(new_top);
207 }
208
209 static int unload_module(void)
210 {
211         ast_bridge_technology_unregister(&simple_bridge);
212         return 0;
213 }
214
215 static int load_module(void)
216 {
217         if (ast_bridge_technology_register(&simple_bridge)) {
218                 unload_module();
219                 return AST_MODULE_LOAD_DECLINE;
220         }
221         return AST_MODULE_LOAD_SUCCESS;
222 }
223
224 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple two channel bridging module");