Merge phase 1 support for the new bridging architecture.
[asterisk/asterisk.git] / channels / chan_bridge.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, 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  * \author Joshua Colp <jcolp@digium.com>
22  *
23  * \brief Bridge Interaction Channel
24  *
25  * \ingroup channel_drivers
26  */
27
28 #include "asterisk.h"
29
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31
32 #include <fcntl.h>
33 #include <sys/signal.h>
34
35 #include "asterisk/lock.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/config.h"
38 #include "asterisk/module.h"
39 #include "asterisk/pbx.h"
40 #include "asterisk/sched.h"
41 #include "asterisk/io.h"
42 #include "asterisk/rtp.h"
43 #include "asterisk/acl.h"
44 #include "asterisk/callerid.h"
45 #include "asterisk/file.h"
46 #include "asterisk/cli.h"
47 #include "asterisk/app.h"
48 #include "asterisk/bridging.h"
49
50 static struct ast_channel *bridge_request(const char *type, int format, void *data, int *cause);
51 static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
52 static int bridge_hangup(struct ast_channel *ast);
53 static struct ast_frame *bridge_read(struct ast_channel *ast);
54 static int bridge_write(struct ast_channel *ast, struct ast_frame *f);
55 static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
56
57 static const struct ast_channel_tech bridge_tech = {
58         .type = "Bridge",
59         .description = "Bridge Interaction Channel",
60         .capabilities = -1,
61         .requester = bridge_request,
62         .call = bridge_call,
63         .hangup = bridge_hangup,
64         .read = bridge_read,
65         .write = bridge_write,
66         .write_video = bridge_write,
67         .exception = bridge_read,
68         .bridged_channel = bridge_bridgedchannel,
69 };
70
71 struct bridge_pvt {
72         ast_mutex_t lock;           /*!< Lock that protects this structure */
73         struct ast_channel *input;  /*!< Input channel - talking to source */
74         struct ast_channel *output; /*!< Output channel - talking to bridge */
75 };
76
77 /*! \brief Called when the user of this channel wants to get the actual channel in the bridge */
78 static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
79 {
80         struct bridge_pvt *p = chan->tech_pvt;
81         return (chan == p->input) ? p->output : bridge;
82 }
83
84 /*! \brief Called when a frame should be read from the channel */
85 static struct ast_frame  *bridge_read(struct ast_channel *ast)
86 {
87         return &ast_null_frame;
88 }
89
90 /*! \brief Called when a frame should be written out to a channel */
91 static int bridge_write(struct ast_channel *ast, struct ast_frame *f)
92 {
93         struct bridge_pvt *p = ast->tech_pvt;
94         struct ast_channel *other;
95
96         ast_mutex_lock(&p->lock);
97
98         other = (p->input == ast ? p->output : p->input);
99
100         while (other && ast_channel_trylock(other)) {
101                 ast_mutex_unlock(&p->lock);
102                 do {
103                         CHANNEL_DEADLOCK_AVOIDANCE(ast);
104                 } while (ast_mutex_trylock(&p->lock));
105                 other = (p->input == ast ? p->output : p->input);
106         }
107
108         /* We basically queue the frame up on the other channel if present */
109         if (other) {
110                 ast_queue_frame(other, f);
111                 ast_channel_unlock(other);
112         }
113
114         ast_mutex_unlock(&p->lock);
115
116         return 0;
117 }
118
119 /*! \brief Called when the channel should actually be dialed */
120 static int bridge_call(struct ast_channel *ast, char *dest, int timeout)
121 {
122         struct bridge_pvt *p = ast->tech_pvt;
123
124         /* If no bridge has been provided on the input channel, bail out */
125         if (!ast->bridge) {
126                 return -1;
127         }
128
129         /* Impart the output channel upon the given bridge of the input channel */
130         ast_bridge_impart(p->input->bridge, p->output, NULL, NULL);
131
132         return 0;
133 }
134
135 /*! \brief Helper function to not deadlock when queueing the hangup frame */
136 static void bridge_queue_hangup(struct bridge_pvt *p, struct ast_channel *us)
137 {
138         struct ast_channel *other = (p->input == us ? p->output : p->input);
139
140         while (other && ast_channel_trylock(other)) {
141                 ast_mutex_unlock(&p->lock);
142                 do {
143                         CHANNEL_DEADLOCK_AVOIDANCE(us);
144                 } while (ast_mutex_trylock(&p->lock));
145                 other = (p->input == us ? p->output : p->input);
146         }
147
148         /* We basically queue the frame up on the other channel if present */
149         if (other) {
150                 ast_queue_hangup(other);
151                 ast_channel_unlock(other);
152         }
153
154         return;
155 }
156
157 /*! \brief Called when a channel should be hung up */
158 static int bridge_hangup(struct ast_channel *ast)
159 {
160         struct bridge_pvt *p = ast->tech_pvt;
161
162         ast_mutex_lock(&p->lock);
163
164         /* Figure out which channel this is... and set it to NULL as it has gone, but also queue up a hangup frame. */
165         if (p->input == ast) {
166                 if (p->output) {
167                         bridge_queue_hangup(p, ast);
168                 }
169                 p->input = NULL;
170         } else if (p->output == ast) {
171                 if (p->input) {
172                         bridge_queue_hangup(p, ast);
173                 }
174                 p->output = NULL;
175         }
176
177         /* Deal with the Asterisk portion of it */
178         ast->tech_pvt = NULL;
179
180         /* If both sides have been terminated free the structure and be done with things */
181         if (!p->input && !p->output) {
182                 ast_mutex_unlock(&p->lock);
183                 ast_mutex_destroy(&p->lock);
184                 ast_free(p);
185         } else {
186                 ast_mutex_unlock(&p->lock);
187         }
188
189         return 0;
190 }
191
192 /*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
193 static struct ast_channel *bridge_request(const char *type, int format, void *data, int *cause)
194 {
195         struct bridge_pvt *p = NULL;
196
197         /* Try to allocate memory for our very minimal pvt structure */
198         if (!(p = ast_calloc(1, sizeof(*p)))) {
199                 return NULL;
200         }
201
202         /* Try to grab two Asterisk channels to use as input and output channels */
203         if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-input", p))) {
204                 ast_free(p);
205                 return NULL;
206         }
207         if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", 0, "Bridge/%p-output", p))) {
208                 ast_channel_free(p->input);
209                 ast_free(p);
210                 return NULL;
211         }
212
213         /* Setup the lock on the pvt structure, we will need that */
214         ast_mutex_init(&p->lock);
215
216         /* Setup parameters on both new channels */
217         p->input->tech = p->output->tech = &bridge_tech;
218         p->input->tech_pvt = p->output->tech_pvt = p;
219         p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR;
220         p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR;
221         p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR;
222         p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR;
223         p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR;
224
225         return p->input;
226 }
227
228 /*! \brief Load module into PBX, register channel */
229 static int load_module(void)
230 {
231         /* Make sure we can register our channel type */
232         if (ast_channel_register(&bridge_tech)) {
233                 ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
234                 return AST_MODULE_LOAD_FAILURE;
235         }
236         return AST_MODULE_LOAD_SUCCESS;
237 }
238
239 /*! \brief Unload the bridge interaction channel from Asterisk */
240 static int unload_module(void)
241 {
242         ast_channel_unregister(&bridge_tech);
243         return 0;
244 }
245
246 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Bridge Interaction Channel");