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