Merge "pjproject_bundled: Add MALLOC_DEBUG capability"
[asterisk/asterisk.git] / bridges / bridge_holding.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Jonathan Rose <jrose@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 Bridging technology for storing channels in a bridge for
22  *        the purpose of holding, parking, queues, and other such
23  *        states where a channel may need to be in a bridge but not
24  *        actually communicating with anything.
25  *
26  * \author Jonathan Rose <jrose@digium.com>
27  *
28  * \ingroup bridges
29  */
30
31 /*** MODULEINFO
32         <support_level>core</support_level>
33  ***/
34
35 #include "asterisk.h"
36
37 ASTERISK_REGISTER_FILE()
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44
45 #include "asterisk/module.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/bridge.h"
48 #include "asterisk/bridge_technology.h"
49 #include "asterisk/frame.h"
50 #include "asterisk/musiconhold.h"
51 #include "asterisk/format_cache.h"
52
53 enum holding_roles {
54         HOLDING_ROLE_PARTICIPANT,
55         HOLDING_ROLE_ANNOUNCER,
56 };
57
58 enum idle_modes {
59         IDLE_MODE_NONE,
60         IDLE_MODE_MOH,
61         IDLE_MODE_RINGING,
62         IDLE_MODE_SILENCE,
63         IDLE_MODE_HOLD,
64 };
65
66 /*! \brief Structure which contains per-channel role information */
67 struct holding_channel {
68         struct ast_silence_generator *silence_generator;
69         enum holding_roles role;
70         enum idle_modes idle_mode;
71         /*! TRUE if the entertainment is started. */
72         unsigned int entertainment_active:1;
73 };
74
75 typedef void (*deferred_cb)(struct ast_bridge_channel *bridge_channel);
76
77 struct deferred_data {
78         /*! Deferred holding technology callback */
79         deferred_cb callback;
80 };
81
82 static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size);
83
84 /*!
85  * \internal
86  * \brief Defer an action to a bridge_channel.
87  * \since 12.0.0
88  *
89  * \param bridge_channel Which channel to operate on.
90  * \param callback action to defer.
91  *
92  * \retval 0 on success.
93  * \retval -1 on error.
94  */
95 static int defer_action(struct ast_bridge_channel *bridge_channel, deferred_cb callback)
96 {
97         struct deferred_data data = { .callback = callback };
98         int res;
99
100         res = ast_bridge_channel_queue_callback(bridge_channel, 0, deferred_action,
101                 &data, sizeof(data));
102         if (res) {
103                 ast_log(LOG_WARNING, "Bridge %s: Could not defer action on %s.\n",
104                         bridge_channel->bridge->uniqueid, ast_channel_name(bridge_channel->chan));
105         }
106         return res;
107 }
108
109 /*!
110  * \internal
111  * \brief Setup participant idle mode from channel.
112  * \since 12.0.0
113  *
114  * \param bridge_channel Channel to setup idle mode.
115  *
116  * \return Nothing
117  */
118 static void participant_idle_mode_setup(struct ast_bridge_channel *bridge_channel)
119 {
120         const char *idle_mode = ast_bridge_channel_get_role_option(bridge_channel, "holding_participant", "idle_mode");
121         struct holding_channel *hc = bridge_channel->tech_pvt;
122
123         ast_assert(hc != NULL);
124
125         if (ast_strlen_zero(idle_mode)) {
126                 hc->idle_mode = IDLE_MODE_MOH;
127         } else if (!strcmp(idle_mode, "musiconhold")) {
128                 hc->idle_mode = IDLE_MODE_MOH;
129         } else if (!strcmp(idle_mode, "ringing")) {
130                 hc->idle_mode = IDLE_MODE_RINGING;
131         } else if (!strcmp(idle_mode, "none")) {
132                 hc->idle_mode = IDLE_MODE_NONE;
133         } else if (!strcmp(idle_mode, "silence")) {
134                 hc->idle_mode = IDLE_MODE_SILENCE;
135         } else if (!strcmp(idle_mode, "hold")) {
136                 hc->idle_mode = IDLE_MODE_HOLD;
137         } else {
138                 /* Invalid idle mode requested. */
139                 ast_debug(1, "channel %s idle mode '%s' doesn't match any defined idle mode\n",
140                         ast_channel_name(bridge_channel->chan), idle_mode);
141                 ast_assert(0);
142         }
143 }
144
145 static void participant_entertainment_stop(struct ast_bridge_channel *bridge_channel)
146 {
147         struct holding_channel *hc = bridge_channel->tech_pvt;
148
149         ast_assert(hc != NULL);
150
151         if (!hc->entertainment_active) {
152                 /* Already stopped */
153                 return;
154         }
155         hc->entertainment_active = 0;
156
157         switch (hc->idle_mode) {
158         case IDLE_MODE_MOH:
159                 ast_moh_stop(bridge_channel->chan);
160                 break;
161         case IDLE_MODE_RINGING:
162                 ast_indicate(bridge_channel->chan, -1);
163                 break;
164         case IDLE_MODE_NONE:
165                 break;
166         case IDLE_MODE_SILENCE:
167                 if (hc->silence_generator) {
168                         ast_channel_stop_silence_generator(bridge_channel->chan, hc->silence_generator);
169                         hc->silence_generator = NULL;
170                 }
171                 break;
172         case IDLE_MODE_HOLD:
173                 ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD);
174                 break;
175         }
176 }
177
178 static void participant_reaction_announcer_join(struct ast_bridge_channel *bridge_channel)
179 {
180         struct ast_channel *chan;
181
182         chan = bridge_channel->chan;
183         participant_entertainment_stop(bridge_channel);
184         if (ast_set_write_format(chan, ast_format_slin)) {
185                 ast_log(LOG_WARNING, "Could not make participant %s compatible.\n", ast_channel_name(chan));
186         }
187 }
188
189 /* This should only be called on verified holding_participants. */
190 static void participant_entertainment_start(struct ast_bridge_channel *bridge_channel)
191 {
192         struct holding_channel *hc = bridge_channel->tech_pvt;
193         const char *moh_class;
194         size_t moh_length;
195
196         ast_assert(hc != NULL);
197
198         if (hc->entertainment_active) {
199                 /* Already started */
200                 return;
201         }
202         hc->entertainment_active = 1;
203
204         participant_idle_mode_setup(bridge_channel);
205         switch(hc->idle_mode) {
206         case IDLE_MODE_MOH:
207                 moh_class = ast_bridge_channel_get_role_option(bridge_channel, "holding_participant", "moh_class");
208                 if (ast_moh_start(bridge_channel->chan, moh_class, NULL)) {
209                         ast_log(LOG_WARNING, "Failed to start moh, starting silence generator instead\n");
210                         hc->idle_mode = IDLE_MODE_SILENCE;
211                         hc->silence_generator = ast_channel_start_silence_generator(bridge_channel->chan);
212                 }
213                 break;
214         case IDLE_MODE_RINGING:
215                 ast_indicate(bridge_channel->chan, AST_CONTROL_RINGING);
216                 break;
217         case IDLE_MODE_NONE:
218                 break;
219         case IDLE_MODE_SILENCE:
220                 hc->silence_generator = ast_channel_start_silence_generator(bridge_channel->chan);
221                 break;
222         case IDLE_MODE_HOLD:
223                 moh_class = ast_bridge_channel_get_role_option(bridge_channel, "holding_participant", "moh_class");
224                 moh_length = moh_class ? strlen(moh_class + 1) : 0;
225                 ast_indicate_data(bridge_channel->chan, AST_CONTROL_HOLD, moh_class, moh_length);
226                 break;
227         }
228 }
229
230 static void handle_participant_join(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *announcer_channel)
231 {
232         struct ast_channel *us = bridge_channel->chan;
233
234         /* If the announcer channel isn't present, we need to set up ringing, music on hold, or whatever. */
235         if (!announcer_channel) {
236                 defer_action(bridge_channel, participant_entertainment_start);
237                 return;
238         }
239
240         /* We need to get compatible with the announcer. */
241         if (ast_set_write_format(us, ast_format_slin)) {
242                 ast_log(LOG_WARNING, "Could not make participant %s compatible.\n", ast_channel_name(us));
243         }
244 }
245
246 static int holding_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
247 {
248         struct ast_bridge_channel *other_channel;
249         struct ast_bridge_channel *announcer_channel;
250         struct holding_channel *hc;
251         struct ast_channel *us = bridge_channel->chan; /* The joining channel */
252
253         ast_assert(bridge_channel->tech_pvt == NULL);
254
255         if (!(hc = ast_calloc(1, sizeof(*hc)))) {
256                 return -1;
257         }
258
259         bridge_channel->tech_pvt = hc;
260
261         /* The bridge pvt holds the announcer channel if we have one. */
262         announcer_channel = bridge->tech_pvt;
263
264         if (ast_bridge_channel_has_role(bridge_channel, "announcer")) {
265                 if (announcer_channel) {
266                         /* Another announcer already exists. */
267                         bridge_channel->tech_pvt = NULL;
268                         ast_free(hc);
269                         ast_log(LOG_WARNING, "Bridge %s: Channel %s tried to be an announcer.  Bridge already has one.\n",
270                                 bridge->uniqueid, ast_channel_name(bridge_channel->chan));
271                         return -1;
272                 }
273
274                 bridge->tech_pvt = bridge_channel;
275                 hc->role = HOLDING_ROLE_ANNOUNCER;
276
277                 /* The announcer should always be made compatible with signed linear */
278                 if (ast_set_read_format(us, ast_format_slin)) {
279                         ast_log(LOG_ERROR, "Could not make announcer %s compatible.\n", ast_channel_name(us));
280                 }
281
282                 /* Make everyone listen to the announcer. */
283                 AST_LIST_TRAVERSE(&bridge->channels, other_channel, entry) {
284                         /* Skip the reaction if we are the channel in question */
285                         if (bridge_channel == other_channel) {
286                                 continue;
287                         }
288                         defer_action(other_channel, participant_reaction_announcer_join);
289                 }
290
291                 return 0;
292         }
293
294         hc->role = HOLDING_ROLE_PARTICIPANT;
295         handle_participant_join(bridge_channel, announcer_channel);
296         return 0;
297 }
298
299 static void participant_reaction_announcer_leave(struct ast_bridge_channel *bridge_channel)
300 {
301         ast_bridge_channel_restore_formats(bridge_channel);
302         participant_entertainment_start(bridge_channel);
303 }
304
305 static void holding_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
306 {
307         struct ast_bridge_channel *other_channel;
308         struct holding_channel *hc = bridge_channel->tech_pvt;
309
310         if (!hc) {
311                 return;
312         }
313
314         switch (hc->role) {
315         case HOLDING_ROLE_ANNOUNCER:
316                 /* The announcer is leaving */
317                 bridge->tech_pvt = NULL;
318
319                 /* Reset the other channels back to moh/ringing. */
320                 AST_LIST_TRAVERSE(&bridge->channels, other_channel, entry) {
321                         defer_action(other_channel, participant_reaction_announcer_leave);
322                 }
323                 break;
324         default:
325                 /* Nothing needs to react to its departure. */
326                 participant_entertainment_stop(bridge_channel);
327                 break;
328         }
329         bridge_channel->tech_pvt = NULL;
330         ast_free(hc);
331 }
332
333 static int holding_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
334 {
335         struct holding_channel *hc = bridge_channel ? bridge_channel->tech_pvt : NULL;
336
337         /* If there is no tech_pvt, then the channel failed to allocate one when it joined and is borked. Don't listen to him. */
338         if (!hc) {
339                 /* "Accept" the frame and discard it. */
340                 return 0;
341         }
342
343         switch (hc->role) {
344         case HOLDING_ROLE_ANNOUNCER:
345                 /* Write the frame to all other channels if any. */
346                 ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
347                 break;
348         default:
349                 /* "Accept" the frame and discard it. */
350                 break;
351         }
352
353         return 0;
354 }
355
356 static void holding_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
357 {
358         struct holding_channel *hc = bridge_channel->tech_pvt;
359
360         if (!hc) {
361                 return;
362         }
363
364         switch (hc->role) {
365         case HOLDING_ROLE_PARTICIPANT:
366                 participant_entertainment_stop(bridge_channel);
367                 break;
368         default:
369                 break;
370         }
371 }
372
373 static void holding_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
374 {
375         struct holding_channel *hc = bridge_channel->tech_pvt;
376         struct ast_bridge_channel *announcer_channel = bridge->tech_pvt;
377
378         if (!hc) {
379                 return;
380         }
381
382         switch (hc->role) {
383         case HOLDING_ROLE_PARTICIPANT:
384                 if (announcer_channel) {
385                         /* There is an announcer channel in the bridge. */
386                         break;
387                 }
388                 /* We need to restart the entertainment. */
389                 participant_entertainment_start(bridge_channel);
390                 break;
391         default:
392                 break;
393         }
394 }
395
396 static struct ast_bridge_technology holding_bridge = {
397         .name = "holding_bridge",
398         .capabilities = AST_BRIDGE_CAPABILITY_HOLDING,
399         .preference = AST_BRIDGE_PREFERENCE_BASE_HOLDING,
400         .write = holding_bridge_write,
401         .join = holding_bridge_join,
402         .leave = holding_bridge_leave,
403         .suspend = holding_bridge_suspend,
404         .unsuspend = holding_bridge_unsuspend,
405 };
406
407 /*!
408  * \internal
409  * \brief Deferred action to start/stop participant entertainment.
410  * \since 12.0.0
411  *
412  * \param bridge_channel Which channel to operate on.
413  * \param payload Data to pass to the callback. (NULL if none).
414  * \param payload_size Size of the payload if payload is non-NULL.  A number otherwise.
415  *
416  * \return Nothing
417  */
418 static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
419 {
420         const struct deferred_data *data = payload;
421
422         ast_bridge_channel_lock_bridge(bridge_channel);
423         if (bridge_channel->bridge->technology != &holding_bridge
424                 || !bridge_channel->tech_pvt) {
425                 /* Not valid anymore. */
426                 ast_bridge_unlock(bridge_channel->bridge);
427                 return;
428         }
429         data->callback(bridge_channel);
430         ast_bridge_unlock(bridge_channel->bridge);
431 }
432
433 static int unload_module(void)
434 {
435         ast_bridge_technology_unregister(&holding_bridge);
436         return 0;
437 }
438
439 static int load_module(void)
440 {
441         if (ast_bridge_technology_register(&holding_bridge)) {
442                 unload_module();
443                 return AST_MODULE_LOAD_DECLINE;
444         }
445         return AST_MODULE_LOAD_SUCCESS;
446 }
447
448 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Holding bridge module");
449