Fix crash from bridge channel hangup race condition in ConfBridge
[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 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <fcntl.h>
37 #include <sys/signal.h>
38
39 #include "asterisk/lock.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/config.h"
42 #include "asterisk/module.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/sched.h"
45 #include "asterisk/io.h"
46 #include "asterisk/acl.h"
47 #include "asterisk/callerid.h"
48 #include "asterisk/file.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/app.h"
51 #include "asterisk/bridging.h"
52 #include "asterisk/astobj2.h"
53
54 static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
55 static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
56 static int bridge_hangup(struct ast_channel *ast);
57 static struct ast_frame *bridge_read(struct ast_channel *ast);
58 static int bridge_write(struct ast_channel *ast, struct ast_frame *f);
59 static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
60
61 static struct ast_channel_tech bridge_tech = {
62         .type = "Bridge",
63         .description = "Bridge Interaction Channel",
64         .requester = bridge_request,
65         .call = bridge_call,
66         .hangup = bridge_hangup,
67         .read = bridge_read,
68         .write = bridge_write,
69         .write_video = bridge_write,
70         .exception = bridge_read,
71         .bridged_channel = bridge_bridgedchannel,
72 };
73
74 struct bridge_pvt {
75         struct ast_channel *input;  /*!< Input channel - talking to source */
76         struct ast_channel *output; /*!< Output channel - talking to bridge */
77 };
78
79 /*! \brief Called when the user of this channel wants to get the actual channel in the bridge */
80 static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
81 {
82         struct bridge_pvt *p = chan->tech_pvt;
83         return (chan == p->input) ? p->output : bridge;
84 }
85
86 /*! \brief Called when a frame should be read from the channel */
87 static struct ast_frame  *bridge_read(struct ast_channel *ast)
88 {
89         return &ast_null_frame;
90 }
91
92 /*! \brief Called when a frame should be written out to a channel */
93 static int bridge_write(struct ast_channel *ast, struct ast_frame *f)
94 {
95         struct bridge_pvt *p = ast->tech_pvt;
96         struct ast_channel *other = NULL;
97
98         ao2_lock(p);
99         /* only write frames to output. */
100         if (p->input == ast) {
101                 other = p->output;
102                 if (other) {
103                         ast_channel_ref(other);
104                 }
105         }
106         ao2_unlock(p);
107
108         if (other) {
109                 ast_channel_unlock(ast);
110                 ast_queue_frame(other, f);
111                 ast_channel_lock(ast);
112                 other = ast_channel_unref(other);
113         }
114
115         return 0;
116 }
117
118 /*! \brief Called when the channel should actually be dialed */
119 static int bridge_call(struct ast_channel *ast, char *dest, int timeout)
120 {
121         struct bridge_pvt *p = ast->tech_pvt;
122
123         /* If no bridge has been provided on the input channel, bail out */
124         if (!ast->bridge) {
125                 return -1;
126         }
127
128         /* Impart the output channel upon the given bridge of the input channel */
129         ast_bridge_impart(p->input->bridge, p->output, NULL, NULL, 0);
130
131         return 0;
132 }
133
134 /*! \brief Called when a channel should be hung up */
135 static int bridge_hangup(struct ast_channel *ast)
136 {
137         struct bridge_pvt *p = ast->tech_pvt;
138
139         if (!p) {
140                 return 0;
141         }
142
143         ao2_lock(p);
144         if (p->input == ast) {
145                 p->input = NULL;
146         } else if (p->output == ast) {
147                 p->output = NULL;
148         }
149         ao2_unlock(p);
150
151         ast->tech_pvt = NULL;
152         ao2_ref(p, -1);
153
154         return 0;
155 }
156
157 /*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
158 static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
159 {
160         struct bridge_pvt *p = NULL;
161         struct ast_format slin;
162
163         /* Try to allocate memory for our very minimal pvt structure */
164         if (!(p = ao2_alloc(sizeof(*p), NULL))) {
165                 return NULL;
166         }
167
168         /* Try to grab two Asterisk channels to use as input and output channels */
169         if (!(p->input = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-input", p))) {
170                 ao2_ref(p, -1);
171                 return NULL;
172         }
173         if (!(p->output = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", requestor ? requestor->linkedid : NULL, 0, "Bridge/%p-output", p))) {
174                 p->input = ast_channel_release(p->input);
175                 ao2_ref(p, -1);
176                 return NULL;
177         }
178
179         /* Setup parameters on both new channels */
180         p->input->tech = p->output->tech = &bridge_tech;
181
182         ao2_ref(p, 2);
183         p->input->tech_pvt = p->output->tech_pvt = p;
184
185         ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
186
187         ast_format_cap_add(p->input->nativeformats, &slin);
188         ast_format_cap_add(p->output->nativeformats, &slin);
189         ast_format_copy(&p->input->readformat, &slin);
190         ast_format_copy(&p->output->readformat, &slin);
191         ast_format_copy(&p->input->rawreadformat, &slin);
192         ast_format_copy(&p->output->rawreadformat, &slin);
193         ast_format_copy(&p->input->writeformat, &slin);
194         ast_format_copy(&p->output->writeformat, &slin);
195         ast_format_copy(&p->input->rawwriteformat, &slin);
196         ast_format_copy(&p->output->rawwriteformat, &slin);
197
198         ast_answer(p->output);
199         ast_answer(p->input);
200
201         /* remove the reference from the alloc. The channels now own the pvt. */
202         ao2_ref(p, -1);
203         return p->input;
204 }
205
206 /*! \brief Load module into PBX, register channel */
207 static int load_module(void)
208 {
209         if (!(bridge_tech.capabilities = ast_format_cap_alloc())) {
210                 return AST_MODULE_LOAD_FAILURE;
211         }
212
213         ast_format_cap_add_all(bridge_tech.capabilities);
214         /* Make sure we can register our channel type */
215         if (ast_channel_register(&bridge_tech)) {
216                 ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
217                 return AST_MODULE_LOAD_FAILURE;
218         }
219         return AST_MODULE_LOAD_SUCCESS;
220 }
221
222 /*! \brief Unload the bridge interaction channel from Asterisk */
223 static int unload_module(void)
224 {
225         ast_channel_unregister(&bridge_tech);
226         bridge_tech.capabilities = ast_format_cap_destroy(bridge_tech.capabilities);
227         return 0;
228 }
229
230 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bridge Interaction Channel",
231         .load = load_module,
232         .unload = unload_module,
233         .load_pri = AST_MODPRI_CHANNEL_DRIVER,
234 );