Merge "astobj2: Create function to copy weak proxied objects from container."
[asterisk/asterisk.git] / apps / app_confbridge.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007-2008, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * David Vossel <dvossel@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief Conference Bridge application
23  *
24  * \author\verbatim Joshua Colp <jcolp@digium.com> \endverbatim
25  * \author\verbatim David Vossel <dvossel@digium.com> \endverbatim
26  *
27  * This is a conference bridge application utilizing the bridging core.
28  * \ingroup applications
29  */
30
31 /*! \li \ref app_confbridge.c uses the configuration file \ref confbridge.conf
32  * \addtogroup configuration_file Configuration Files
33  */
34
35 /*!
36  * \page confbridge.conf confbridge.conf
37  * \verbinclude confbridge.conf.sample
38  */
39
40 /*** MODULEINFO
41         <support_level>core</support_level>
42  ***/
43
44 #include "asterisk.h"
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <string.h>
50 #include <signal.h>
51
52 #include "asterisk/cli.h"
53 #include "asterisk/file.h"
54 #include "asterisk/channel.h"
55 #include "asterisk/pbx.h"
56 #include "asterisk/pbx.h"
57 #include "asterisk/module.h"
58 #include "asterisk/lock.h"
59 #include "asterisk/bridge.h"
60 #include "asterisk/musiconhold.h"
61 #include "asterisk/say.h"
62 #include "asterisk/audiohook.h"
63 #include "asterisk/astobj2.h"
64 #include "confbridge/include/confbridge.h"
65 #include "asterisk/paths.h"
66 #include "asterisk/manager.h"
67 #include "asterisk/test.h"
68 #include "asterisk/stasis.h"
69 #include "asterisk/stasis_bridges.h"
70 #include "asterisk/stasis_channels.h"
71 #include "asterisk/json.h"
72 #include "asterisk/format_cache.h"
73 #include "asterisk/taskprocessor.h"
74 #include "asterisk/stream.h"
75 #include "asterisk/message.h"
76
77 /*** DOCUMENTATION
78         <application name="ConfBridge" language="en_US">
79                 <synopsis>
80                         Conference bridge application.
81                 </synopsis>
82                 <syntax>
83                         <parameter name="conference" required="true">
84                                 <para>Name of the conference bridge.  You are not limited to just
85                                 numbers.</para>
86                         </parameter>
87                         <parameter name="bridge_profile">
88                                 <para>The bridge profile name from confbridge.conf.  When left blank,
89                                 a dynamically built bridge profile created by the CONFBRIDGE dialplan
90                                 function is searched for on the channel and used.  If no dynamic
91                                 profile is present, the 'default_bridge' profile found in
92                                 confbridge.conf is used. </para>
93                                 <para>It is important to note that while user profiles may be unique
94                                 for each participant, mixing bridge profiles on a single conference
95                                 is _NOT_ recommended and will produce undefined results.</para>
96                         </parameter>
97                         <parameter name="user_profile">
98                                 <para>The user profile name from confbridge.conf.  When left blank,
99                                 a dynamically built user profile created by the CONFBRIDGE dialplan
100                                 function is searched for on the channel and used.  If no dynamic
101                                 profile is present, the 'default_user' profile found in
102                                 confbridge.conf is used.</para>
103                         </parameter>
104                         <parameter name="menu">
105                                 <para>The name of the DTMF menu in confbridge.conf to be applied to
106                                 this channel.  When left blank, a dynamically built menu profile
107                                 created by the CONFBRIDGE dialplan function is searched for on
108                                 the channel and used. If no dynamic profile is present, the
109                                 'default_menu' profile found in confbridge.conf is used.</para>
110                         </parameter>
111                 </syntax>
112                 <description>
113                         <para>Enters the user into a specified conference bridge.  The user can
114                         exit the conference by hangup or DTMF menu option.</para>
115                         <para>This application sets the following channel variable upon completion:</para>
116                         <variablelist>
117                                 <variable name="CONFBRIDGE_RESULT">
118                                         <value name="FAILED">The channel encountered an error and could not enter the conference.</value>
119                                         <value name="HANGUP">The channel exited the conference by hanging up.</value>
120                                         <value name="KICKED">The channel was kicked from the conference.</value>
121                                         <value name="ENDMARKED">The channel left the conference as a result of the last marked user leaving.</value>
122                                         <value name="DTMF">The channel pressed a DTMF sequence to exit the conference.</value>
123                                         <value name="TIMEOUT">The channel reached its configured timeout.</value>
124                                 </variable>
125                         </variablelist>
126                 </description>
127                 <see-also>
128                         <ref type="application">ConfBridge</ref>
129                         <ref type="function">CONFBRIDGE</ref>
130                         <ref type="function">CONFBRIDGE_INFO</ref>
131                 </see-also>
132         </application>
133         <function name="CONFBRIDGE" language="en_US">
134                 <synopsis>
135                         Set a custom dynamic bridge, user, or menu profile on a channel for the
136                         ConfBridge application using the same options available in confbridge.conf.
137                 </synopsis>
138                 <syntax>
139                         <parameter name="type" required="true">
140                                 <para>To what type of conference profile the option applies.</para>
141                                 <enumlist>
142                                         <enum name="bridge"></enum>
143                                         <enum name="menu"></enum>
144                                         <enum name="user"></enum>
145                                 </enumlist>
146                         </parameter>
147                         <parameter name="option" required="true">
148                                 <para>Option refers to a <filename>confbridge.conf</filename> option
149                                 that is being set dynamically on this channel, or <literal>clear</literal>
150                                 to remove already applied profile options from the channel.</para>
151                         </parameter>
152                 </syntax>
153                 <description>
154                         <para>A custom profile uses the default profile type settings defined in
155                         <filename>confbridge.conf</filename> as defaults if the profile template
156                         is not explicitly specified first.</para>
157                         <para>For <literal>bridge</literal> profiles the default template is <literal>default_bridge</literal>.</para>
158                         <para>For <literal>menu</literal> profiles the default template is <literal>default_menu</literal>.</para>
159                         <para>For <literal>user</literal> profiles the default template is <literal>default_user</literal>.</para>
160                         <para>---- Example 1 ----</para>
161                         <para>In this example the custom user profile set on the channel will
162                         automatically be used by the ConfBridge application.</para>
163                         <para>exten => 1,1,Answer()</para>
164                         <para>; In this example the effect of the following line is</para>
165                         <para>; implied:</para>
166                         <para>; same => n,Set(CONFBRIDGE(user,template)=default_user)</para>
167                         <para>same => n,Set(CONFBRIDGE(user,announce_join_leave)=yes)</para>
168                         <para>same => n,Set(CONFBRIDGE(user,startmuted)=yes)</para>
169                         <para>same => n,ConfBridge(1) </para>
170                         <para>---- Example 2 ----</para>
171                         <para>This example shows how to use a predefined user profile in
172                         <filename>confbridge.conf</filename> as a template for a dynamic profile.
173                         Here we make an admin/marked user out of the <literal>my_user</literal>
174                         profile that you define in <filename>confbridge.conf</filename>.</para>
175                         <para>exten => 1,1,Answer()</para>
176                         <para>same => n,Set(CONFBRIDGE(user,template)=my_user)</para>
177                         <para>same => n,Set(CONFBRIDGE(user,admin)=yes)</para>
178                         <para>same => n,Set(CONFBRIDGE(user,marked)=yes)</para>
179                         <para>same => n,ConfBridge(1)</para>
180                 </description>
181         </function>
182         <function name="CONFBRIDGE_INFO" language="en_US">
183                 <synopsis>
184                         Get information about a ConfBridge conference.
185                 </synopsis>
186                 <syntax>
187                         <parameter name="type" required="true">
188                                 <para>What conference information is requested.</para>
189                                 <enumlist>
190                                         <enum name="admins">
191                                                 <para>Get the number of admin users in the conference.</para>
192                                         </enum>
193                                         <enum name="locked">
194                                                 <para>Determine if the conference is locked. (0 or 1)</para>
195                                         </enum>
196                                         <enum name="marked">
197                                                 <para>Get the number of marked users in the conference.</para>
198                                         </enum>
199                                         <enum name="muted">
200                                                 <para>Determine if the conference is muted. (0 or 1)</para>
201                                         </enum>
202                                         <enum name="parties">
203                                                 <para>Get the number of users in the conference.</para>
204                                         </enum>
205                                 </enumlist>
206                         </parameter>
207                         <parameter name="conf" required="true">
208                                 <para>The name of the conference being referenced.</para>
209                         </parameter>
210                 </syntax>
211                 <description>
212                         <para>This function returns a non-negative integer for valid conference
213                         names and an empty string for invalid conference names.</para>
214                 </description>
215         </function>
216         <manager name="ConfbridgeList" language="en_US">
217                 <synopsis>
218                         List participants in a conference.
219                 </synopsis>
220                 <syntax>
221                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
222                         <parameter name="Conference" required="true">
223                                 <para>Conference number.</para>
224                         </parameter>
225                 </syntax>
226                 <description>
227                         <para>Lists all users in a particular ConfBridge conference.
228                         ConfbridgeList will follow as separate events, followed by a final event called
229                         ConfbridgeListComplete.</para>
230                 </description>
231         </manager>
232         <managerEvent language="en_US" name="ConfbridgeList">
233                 <managerEventInstance class="EVENT_FLAG_REPORTING">
234                         <synopsis>Raised as part of the ConfbridgeList action response list.</synopsis>
235                         <syntax>
236                                 <parameter name="Conference">
237                                         <para>The name of the Confbridge conference.</para>
238                                 </parameter>
239                                 <parameter name="Admin">
240                                         <para>Identifies this user as an admin user.</para>
241                                         <enumlist>
242                                                 <enum name="Yes"/>
243                                                 <enum name="No"/>
244                                         </enumlist>
245                                 </parameter>
246                                 <parameter name="MarkedUser">
247                                         <para>Identifies this user as a marked user.</para>
248                                         <enumlist>
249                                                 <enum name="Yes"/>
250                                                 <enum name="No"/>
251                                         </enumlist>
252                                 </parameter>
253                                 <parameter name="WaitMarked">
254                                         <para>Must this user wait for a marked user to join?</para>
255                                         <enumlist>
256                                                 <enum name="Yes"/>
257                                                 <enum name="No"/>
258                                         </enumlist>
259                                 </parameter>
260                                 <parameter name="EndMarked">
261                                         <para>Does this user get kicked after the last marked user leaves?</para>
262                                         <enumlist>
263                                                 <enum name="Yes"/>
264                                                 <enum name="No"/>
265                                         </enumlist>
266                                 </parameter>
267                                 <parameter name="Waiting">
268                                         <para>Is this user waiting for a marked user to join?</para>
269                                         <enumlist>
270                                                 <enum name="Yes"/>
271                                                 <enum name="No"/>
272                                         </enumlist>
273                                 </parameter>
274                                 <parameter name="Muted">
275                                         <para>The current mute status.</para>
276                                         <enumlist>
277                                                 <enum name="Yes"/>
278                                                 <enum name="No"/>
279                                         </enumlist>
280                                 </parameter>
281                                 <parameter name="Talking">
282                                         <para>Is this user talking?</para>
283                                         <enumlist>
284                                                 <enum name="Yes"/>
285                                                 <enum name="No"/>
286                                         </enumlist>
287                                 </parameter>
288                                 <parameter name="AnsweredTime">
289                                         <para>The number of seconds the channel has been up.</para>
290                                 </parameter>
291                                 <channel_snapshot/>
292                         </syntax>
293                 </managerEventInstance>
294         </managerEvent>
295         <manager name="ConfbridgeListRooms" language="en_US">
296                 <synopsis>
297                         List active conferences.
298                 </synopsis>
299                 <syntax>
300                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
301                 </syntax>
302                 <description>
303                         <para>Lists data about all active conferences.
304                                 ConfbridgeListRooms will follow as separate events, followed by a final event called
305                                 ConfbridgeListRoomsComplete.</para>
306                 </description>
307         </manager>
308         <manager name="ConfbridgeMute" language="en_US">
309                 <synopsis>
310                         Mute a Confbridge user.
311                 </synopsis>
312                 <syntax>
313                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
314                         <parameter name="Conference" required="true" />
315                         <parameter name="Channel" required="true">
316                                 <para>If this parameter is not a complete channel name, the first channel with this prefix will be used.</para>
317                                 <para>If this parameter is "all", all channels will be muted.</para>
318                                 <para>If this parameter is "participants", all non-admin channels will be muted.</para>
319                         </parameter>
320                 </syntax>
321                 <description>
322                 </description>
323         </manager>
324         <manager name="ConfbridgeUnmute" language="en_US">
325                 <synopsis>
326                         Unmute a Confbridge user.
327                 </synopsis>
328                 <syntax>
329                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
330                         <parameter name="Conference" required="true" />
331                         <parameter name="Channel" required="true">
332                                 <para>If this parameter is not a complete channel name, the first channel with this prefix will be used.</para>
333                                 <para>If this parameter is "all", all channels will be unmuted.</para>
334                                 <para>If this parameter is "participants", all non-admin channels will be unmuted.</para>
335                         </parameter>
336                 </syntax>
337                 <description>
338                 </description>
339         </manager>
340         <manager name="ConfbridgeKick" language="en_US">
341                 <synopsis>
342                         Kick a Confbridge user.
343                 </synopsis>
344                 <syntax>
345                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
346                         <parameter name="Conference" required="true" />
347                         <parameter name="Channel" required="true" >
348                                 <para>If this parameter is "all", all channels will be kicked from the conference.</para>
349                                 <para>If this parameter is "participants", all non-admin channels will be kicked from the conference.</para>
350                         </parameter>
351                 </syntax>
352                 <description>
353                 </description>
354         </manager>
355         <manager name="ConfbridgeLock" language="en_US">
356                 <synopsis>
357                         Lock a Confbridge conference.
358                 </synopsis>
359                 <syntax>
360                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
361                         <parameter name="Conference" required="true" />
362                 </syntax>
363                 <description>
364                 </description>
365         </manager>
366         <manager name="ConfbridgeUnlock" language="en_US">
367                 <synopsis>
368                         Unlock a Confbridge conference.
369                 </synopsis>
370                 <syntax>
371                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
372                         <parameter name="Conference" required="true" />
373                 </syntax>
374                 <description>
375                 </description>
376         </manager>
377         <manager name="ConfbridgeStartRecord" language="en_US">
378                 <synopsis>
379                         Start recording a Confbridge conference.
380                 </synopsis>
381                 <syntax>
382                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
383                         <parameter name="Conference" required="true" />
384                         <parameter name="RecordFile" required="false" />
385                 </syntax>
386                 <description>
387                         <para>Start recording a conference. If recording is already present an error will be returned. If RecordFile is not provided, the default record file specified in the conference's bridge profile will be used, if that is not present either a file will automatically be generated in the monitor directory.</para>
388                 </description>
389         </manager>
390         <manager name="ConfbridgeStopRecord" language="en_US">
391                 <synopsis>
392                         Stop recording a Confbridge conference.
393                 </synopsis>
394                 <syntax>
395                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
396                         <parameter name="Conference" required="true" />
397                 </syntax>
398                 <description>
399                 </description>
400         </manager>
401         <manager name="ConfbridgeSetSingleVideoSrc" language="en_US">
402                 <synopsis>
403                         Set a conference user as the single video source distributed to all other participants.
404                 </synopsis>
405                 <syntax>
406                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
407                         <parameter name="Conference" required="true" />
408                         <parameter name="Channel" required="true">
409                                 <para>If this parameter is not a complete channel name, the first channel with this prefix will be used.</para>
410                         </parameter>
411                 </syntax>
412                 <description>
413                 </description>
414         </manager>
415
416 ***/
417
418 /*!
419  * \par Playing back a file to a channel in a conference
420  * You might notice in this application that while playing a sound file
421  * to a channel the actual conference bridge lock is not held. This is done so
422  * that other channels are not blocked from interacting with the conference bridge.
423  * Unfortunately because of this it is possible for things to change after the sound file
424  * is done being played. Data must therefore be checked after reacquiring the conference
425  * bridge lock if it is important.
426  */
427
428 static const char app[] = "ConfBridge";
429
430 /*! Number of buckets our conference bridges container can have */
431 #define CONFERENCE_BRIDGE_BUCKETS 53
432
433 /*! Initial recording filename space. */
434 #define RECORD_FILENAME_INITIAL_SPACE   128
435
436 /*! \brief Container to hold all conference bridges in progress */
437 struct ao2_container *conference_bridges;
438
439 static void leave_conference(struct confbridge_user *user);
440 static int play_sound_number(struct confbridge_conference *conference, int say_number);
441 static int execute_menu_entry(struct confbridge_conference *conference,
442         struct confbridge_user *user,
443         struct ast_bridge_channel *bridge_channel,
444         struct conf_menu_entry *menu_entry,
445         struct conf_menu *menu);
446
447 /*! \brief Hashing function used for conference bridges container */
448 static int conference_bridge_hash_cb(const void *obj, const int flags)
449 {
450         const struct confbridge_conference *conference = obj;
451         const char *name = obj;
452         int hash;
453
454         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
455         default:
456         case OBJ_POINTER:
457                 name = conference->name;
458                 /* Fall through */
459         case OBJ_KEY:
460                 hash = ast_str_case_hash(name);
461                 break;
462         case OBJ_PARTIAL_KEY:
463                 /* Should never happen in hash callback. */
464                 ast_assert(0);
465                 hash = 0;
466                 break;
467         }
468         return hash;
469 }
470
471 /*! \brief Comparison function used for conference bridges container */
472 static int conference_bridge_cmp_cb(void *obj, void *arg, int flags)
473 {
474         const struct confbridge_conference *left = obj;
475         const struct confbridge_conference *right = arg;
476         const char *right_name = arg;
477         int cmp;
478
479         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
480         default:
481         case OBJ_POINTER:
482                 right_name = right->name;
483                 /* Fall through */
484         case OBJ_KEY:
485                 cmp = strcasecmp(left->name, right_name);
486                 break;
487         case OBJ_PARTIAL_KEY:
488                 cmp = strncasecmp(left->name, right_name, strlen(right_name));
489                 break;
490         }
491         return cmp ? 0 : CMP_MATCH;
492 }
493
494 const char *conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
495 {
496         switch (sound) {
497         case CONF_SOUND_HAS_JOINED:
498                 return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
499         case CONF_SOUND_HAS_LEFT:
500                 return S_OR(custom_sounds->hasleft, "conf-hasleft");
501         case CONF_SOUND_KICKED:
502                 return S_OR(custom_sounds->kicked, "conf-kicked");
503         case CONF_SOUND_MUTED:
504                 return S_OR(custom_sounds->muted, "conf-muted");
505         case CONF_SOUND_UNMUTED:
506                 return S_OR(custom_sounds->unmuted, "conf-unmuted");
507         case CONF_SOUND_BINAURAL_ON:
508                 return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
509         case CONF_SOUND_BINAURAL_OFF:
510                 return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
511         case CONF_SOUND_ONLY_ONE:
512                 return S_OR(custom_sounds->onlyone, "conf-onlyone");
513         case CONF_SOUND_THERE_ARE:
514                 return S_OR(custom_sounds->thereare, "conf-thereare");
515         case CONF_SOUND_OTHER_IN_PARTY:
516                 return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
517         case CONF_SOUND_PLACE_IN_CONF:
518                 return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
519         case CONF_SOUND_WAIT_FOR_LEADER:
520                 return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
521         case CONF_SOUND_LEADER_HAS_LEFT:
522                 return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
523         case CONF_SOUND_GET_PIN:
524                 return S_OR(custom_sounds->getpin, "conf-getpin");
525         case CONF_SOUND_INVALID_PIN:
526                 return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
527         case CONF_SOUND_ONLY_PERSON:
528                 return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
529         case CONF_SOUND_LOCKED:
530                 return S_OR(custom_sounds->locked, "conf-locked");
531         case CONF_SOUND_LOCKED_NOW:
532                 return S_OR(custom_sounds->lockednow, "conf-lockednow");
533         case CONF_SOUND_UNLOCKED_NOW:
534                 return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
535         case CONF_SOUND_ERROR_MENU:
536                 return S_OR(custom_sounds->errormenu, "conf-errormenu");
537         case CONF_SOUND_JOIN:
538                 return S_OR(custom_sounds->join, "confbridge-join");
539         case CONF_SOUND_LEAVE:
540                 return S_OR(custom_sounds->leave, "confbridge-leave");
541         case CONF_SOUND_PARTICIPANTS_MUTED:
542                 return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
543         case CONF_SOUND_PARTICIPANTS_UNMUTED:
544                 return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
545         case CONF_SOUND_BEGIN:
546                 return S_OR(custom_sounds->begin, "confbridge-conf-begin");
547         }
548
549         return "";
550 }
551
552
553 static void send_conf_stasis(struct confbridge_conference *conference, struct ast_channel *chan,
554         struct stasis_message_type *type, struct ast_json *extras, int channel_topic)
555 {
556         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
557         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
558
559         json_object = ast_json_pack("{s: s}",
560                 "conference", conference->name);
561         if (!json_object) {
562                 return;
563         }
564
565         if (extras) {
566                 ast_json_object_update(json_object, extras);
567         }
568
569         ast_bridge_lock(conference->bridge);
570         msg = ast_bridge_blob_create(type,
571                 conference->bridge,
572                 chan,
573                 json_object);
574         ast_bridge_unlock(conference->bridge);
575         if (!msg) {
576                 return;
577         }
578
579         if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_ENABLE_EVENTS)) {
580                 conf_send_event_to_participants(conference, chan, msg);
581         }
582
583         if (channel_topic) {
584                 stasis_publish(ast_channel_topic(chan), msg);
585         } else {
586                 stasis_publish(ast_bridge_topic(conference->bridge), msg);
587         }
588 }
589
590 static void send_conf_start_event(struct confbridge_conference *conference)
591 {
592         send_conf_stasis(conference, NULL, confbridge_start_type(), NULL, 0);
593 }
594
595 static void send_conf_end_event(struct confbridge_conference *conference)
596 {
597         send_conf_stasis(conference, NULL, confbridge_end_type(), NULL, 0);
598 }
599
600 static void send_join_event(struct confbridge_user *user, struct confbridge_conference *conference)
601 {
602         struct ast_json *json_object;
603
604         json_object = ast_json_pack("{s: b, s: b}",
605                 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
606                 "muted", user->muted);
607         if (!json_object) {
608                 return;
609         }
610         send_conf_stasis(conference, user->chan, confbridge_join_type(), json_object, 0);
611         ast_json_unref(json_object);
612 }
613
614 static void send_leave_event(struct confbridge_user *user, struct confbridge_conference *conference)
615 {
616         struct ast_json *json_object;
617
618         json_object = ast_json_pack("{s: b}",
619                 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
620         );
621         if (!json_object) {
622                 return;
623         }
624         send_conf_stasis(conference, user->chan, confbridge_leave_type(), json_object, 0);
625         ast_json_unref(json_object);
626 }
627
628 static void send_start_record_event(struct confbridge_conference *conference)
629 {
630         send_conf_stasis(conference, NULL, confbridge_start_record_type(), NULL, 0);
631 }
632
633 static void send_stop_record_event(struct confbridge_conference *conference)
634 {
635         send_conf_stasis(conference, NULL, confbridge_stop_record_type(), NULL, 0);
636 }
637
638 static void send_mute_event(struct confbridge_user *user, struct confbridge_conference *conference)
639 {
640         struct ast_json *json_object;
641
642         json_object = ast_json_pack("{s: b}",
643                 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
644         );
645         if (!json_object) {
646                 return;
647         }
648         send_conf_stasis(conference, user->chan, confbridge_mute_type(), json_object, 1);
649         ast_json_unref(json_object);
650 }
651
652 static void send_unmute_event(struct confbridge_user *user, struct confbridge_conference *conference)
653 {
654         struct ast_json *json_object;
655
656         json_object = ast_json_pack("{s: b}",
657                 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
658         );
659         if (!json_object) {
660                 return;
661         }
662         send_conf_stasis(conference, user->chan, confbridge_unmute_type(), json_object, 1);
663         ast_json_unref(json_object);
664 }
665
666 static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
667 {
668         char *rec_file = conference->b_profile.rec_file;
669         char *ext;
670         time_t now;
671
672         if (ast_str_strlen(*filename)
673                 && ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND)
674                 && !is_new) {
675                 return;
676         }
677
678         time(&now);
679
680         ast_str_reset(*filename);
681         if (ast_strlen_zero(rec_file)) {
682                 ast_str_set(filename, 0, "confbridge-%s-%u.wav", conference->name,
683                         (unsigned int) now);
684         } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_TIMESTAMP)) {
685                 /* insert time before file extension */
686                 ext = strrchr(rec_file, '.');
687                 if (ext) {
688                         ast_str_set_substr(filename, 0, rec_file, ext - rec_file);
689                         ast_str_append(filename, 0, "-%u%s", (unsigned int) now, ext);
690                 } else {
691                         ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int) now);
692                 }
693         } else {
694                 ast_str_set(filename, 0, "%s", rec_file);
695         }
696         ast_str_append(filename, 0, ",%s%s,%s",
697                 ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND) ? "a" : "",
698                 conference->b_profile.rec_options,
699                 conference->b_profile.rec_command);
700 }
701
702 static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
703 {
704         if (!ast_strlen_zero(rec_file)) {
705                 if (!*orig_rec_file) {
706                         *orig_rec_file = ast_str_create(RECORD_FILENAME_INITIAL_SPACE);
707                 }
708
709                 if (*orig_rec_file
710                         && strcmp(ast_str_buffer(*orig_rec_file), rec_file)) {
711                         ast_str_set(orig_rec_file, 0, "%s", rec_file);
712                         return 1;
713                 }
714         }
715         return 0;
716 }
717
718 struct confbridge_conference *conf_find_bridge(const char *conference_name)
719 {
720         return ao2_find(conference_bridges, conference_name, OBJ_KEY);
721 }
722
723 /*!
724  * \internal
725  * \brief Returns whether or not conference is being recorded.
726  *
727  * \param conference The bridge to check for recording
728  *
729  * \note Must be called with the conference locked
730  *
731  * \retval 1, conference is recording.
732  * \retval 0, conference is NOT recording.
733  */
734 static int conf_is_recording(struct confbridge_conference *conference)
735 {
736         return conference->record_chan != NULL;
737 }
738
739 /*!
740  * \internal
741  * \brief Stop recording a conference bridge
742  *
743  * \param conference The conference bridge on which to stop the recording
744  *
745  * \note Must be called with the conference locked
746  *
747  * \retval -1 Failure
748  * \retval 0 Success
749  */
750 static int conf_stop_record(struct confbridge_conference *conference)
751 {
752         struct ast_channel *chan;
753         struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
754
755         if (!conf_is_recording(conference)) {
756                 return -1;
757         }
758
759         /* Remove the recording channel from the conference bridge. */
760         chan = conference->record_chan;
761         conference->record_chan = NULL;
762         ast_queue_frame(chan, &f);
763         ast_channel_unref(chan);
764
765         ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
766         send_stop_record_event(conference);
767
768         return 0;
769 }
770
771 /*!
772  * \internal
773  * \brief Start recording the conference
774  *
775  * \param conference The conference bridge to start recording
776  *
777  * \note Must be called with the conference locked
778  *
779  * \retval 0 success
780  * \retval non-zero failure
781  */
782 static int conf_start_record(struct confbridge_conference *conference)
783 {
784         struct ast_app *mixmonapp;
785         struct ast_channel *chan;
786         struct ast_format_cap *cap;
787         struct ast_bridge_features *features;
788
789         if (conf_is_recording(conference)) {
790                 return -1;
791         }
792
793         mixmonapp = pbx_findapp("MixMonitor");
794         if (!mixmonapp) {
795                 ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
796                 return -1;
797         }
798
799         features = ast_bridge_features_new();
800         if (!features) {
801                 return -1;
802         }
803         ast_set_flag(&features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
804
805         cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
806         if (!cap) {
807                 ast_bridge_features_destroy(features);
808                 return -1;
809         }
810         ast_format_cap_append(cap, ast_format_slin, 0);
811
812         /* Create the recording channel. */
813         chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
814         ao2_ref(cap, -1);
815         if (!chan) {
816                 ast_bridge_features_destroy(features);
817                 return -1;
818         }
819
820         /* Start recording. */
821         set_rec_filename(conference, &conference->record_filename,
822                 is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
823         ast_answer(chan);
824         pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
825
826         /* Put the channel into the conference bridge. */
827         ast_channel_ref(chan);
828         conference->record_chan = chan;
829         if (ast_bridge_impart(conference->bridge, chan, NULL, features,
830                 AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
831                 ast_hangup(chan);
832                 ast_channel_unref(chan);
833                 conference->record_chan = NULL;
834                 return -1;
835         }
836
837         ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
838         send_start_record_event(conference);
839
840         return 0;
841 }
842
843 /* \brief Playback the given filename and monitor for any dtmf interrupts.
844  *
845  * This function is used to playback sound files on a given channel and optionally
846  * allow dtmf interrupts to occur.
847  *
848  * If the optional bridge_channel parameter is given then sound file playback
849  * is played on that channel and dtmf interruptions are allowed. However, if
850  * bridge_channel is not set then the channel parameter is expected to be set
851  * instead and non interruptible playback is played on that channel.
852  *
853  * \param bridge_channel Bridge channel to play file on
854  * \param channel Optional channel to play file on if bridge_channel not given
855  * \param filename The file name to playback
856  *
857  * \retval -1 failure during playback, 0 on file was fully played, 1 on dtmf interrupt.
858  */
859 static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel,
860                      const char *filename)
861 {
862         struct ast_channel *chan;
863         const char *stop_digits;
864         int digit;
865
866         if (bridge_channel) {
867                 chan = bridge_channel->chan;
868                 stop_digits = AST_DIGIT_ANY;
869         } else {
870                 chan = channel;
871                 stop_digits = AST_DIGIT_NONE;
872         }
873
874         digit = ast_stream_and_wait(chan, filename, stop_digits);
875         if (digit < 0) {
876                 ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
877                 return -1;
878         }
879
880         if (digit > 0) {
881                 ast_stopstream(bridge_channel->chan);
882                 ast_bridge_channel_feature_digit_add(bridge_channel, digit);
883                 return 1;
884         }
885
886         return 0;
887 }
888
889 /*!
890  * \internal
891  * \brief Complain if the given sound file does not exist.
892  *
893  * \param filename Sound file to check if exists.
894  *
895  * \retval non-zero if the file exists.
896  */
897 static int sound_file_exists(const char *filename)
898 {
899         if (ast_fileexists(filename, NULL, NULL)) {
900                 return -1;
901         }
902         ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
903         return 0;
904 }
905
906 /*!
907  * \brief Announce number of users in the conference bridge to the caller
908  *
909  * \param conference Conference bridge to peek at
910  * \param user Optional Caller
911  * \param bridge_channel The bridged channel involved
912  *
913  * \note if caller is NULL, the announcment will be sent to all participants in the conference.
914  * \return Returns 0 on success, -1 if the user hung up
915  */
916 static int announce_user_count(struct confbridge_conference *conference, struct confbridge_user *user,
917                                struct ast_bridge_channel *bridge_channel)
918 {
919         const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
920         const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
921         const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
922
923         if (conference->activeusers <= 1) {
924                 /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
925                 return 0;
926         } else if (conference->activeusers == 2) {
927                 if (user) {
928                         /* Eep, there is one other person */
929                         if (play_file(bridge_channel, user->chan, only_one) < 0) {
930                                 return -1;
931                         }
932                 } else {
933                         play_sound_file(conference, only_one);
934                 }
935         } else {
936                 /* Alas multiple others in here */
937                 if (user) {
938                         if (ast_stream_and_wait(user->chan,
939                                 there_are,
940                                 "")) {
941                                 return -1;
942                         }
943                         if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
944                                 return -1;
945                         }
946                         if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
947                                 return -1;
948                         }
949                 } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
950                         play_sound_file(conference, there_are);
951                         play_sound_number(conference, conference->activeusers - 1);
952                         play_sound_file(conference, other_in_party);
953                 }
954         }
955         return 0;
956 }
957
958 /*!
959  * \brief Play back an audio file to a channel
960  *
961  * \param user User to play audio prompt to
962  * \param filename Prompt to play
963  *
964  * \return Returns 0 on success, -1 if the user hung up
965  * \note Generally this should be called when the conference is unlocked to avoid blocking
966  * the entire conference while the sound is played. But don't unlock the conference bridge
967  * in the middle of a state transition.
968  */
969 static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
970 {
971         return ast_stream_and_wait(user->chan, filename, "");
972 }
973
974 static void handle_video_on_join(struct confbridge_conference *conference, struct ast_channel *chan, int marked)
975 {
976         /* Right now, only marked users are automatically set as the single src of video.*/
977         if (!marked) {
978                 return;
979         }
980
981         if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED)) {
982                 int set = 1;
983                 struct confbridge_user *user = NULL;
984
985                 ao2_lock(conference);
986                 /* see if anyone is already the video src */
987                 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
988                         if (user->chan == chan) {
989                                 continue;
990                         }
991                         if (ast_bridge_is_video_src(conference->bridge, user->chan)) {
992                                 set = 0;
993                                 break;
994                         }
995                 }
996                 ao2_unlock(conference);
997                 if (set) {
998                         ast_bridge_set_single_src_video_mode(conference->bridge, chan);
999                 }
1000         } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
1001                 /* we joined and are video capable, we override anyone else that may have already been the video feed */
1002                 ast_bridge_set_single_src_video_mode(conference->bridge, chan);
1003         }
1004 }
1005
1006 static void handle_video_on_exit(struct confbridge_conference *conference, struct ast_channel *chan)
1007 {
1008         struct confbridge_user *user = NULL;
1009
1010         /* if this isn't a video source, nothing to update */
1011         if (!ast_bridge_is_video_src(conference->bridge, chan)) {
1012                 return;
1013         }
1014
1015         ast_bridge_remove_video_src(conference->bridge, chan);
1016
1017         /* If in follow talker mode, make sure to restore this mode on the
1018          * bridge when a source is removed.  It is possible this channel was
1019          * only set temporarily as a video source by an AMI or DTMF action. */
1020         if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
1021                 ast_bridge_set_talker_src_video_mode(conference->bridge);
1022         }
1023
1024         /* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
1025         if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) &&
1026                 !ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
1027                 return;
1028         }
1029
1030         /* Make the next available marked user the video src.  */
1031         ao2_lock(conference);
1032         AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1033                 if (user->chan == chan) {
1034                         continue;
1035                 }
1036                 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1037                         ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
1038                         break;
1039                 }
1040         }
1041         ao2_unlock(conference);
1042 }
1043
1044 struct hangup_data
1045 {
1046         struct confbridge_conference *conference;
1047         ast_mutex_t lock;
1048         ast_cond_t cond;
1049         int hungup;
1050 };
1051
1052 /*!
1053  * \brief Hang up the announcer channel
1054  *
1055  * This hangs up the announcer channel in the conference. This
1056  * runs in the playback queue taskprocessor since we do not want
1057  * to hang up the channel while it's trying to play an announcement.
1058  *
1059  * This task is performed synchronously, so there is no need to
1060  * perform any cleanup on the passed-in data.
1061  *
1062  * \param data A hangup_data structure
1063  * \return 0
1064  */
1065 static int hangup_playback(void *data)
1066 {
1067         struct hangup_data *hangup = data;
1068
1069         ast_autoservice_stop(hangup->conference->playback_chan);
1070
1071         ast_hangup(hangup->conference->playback_chan);
1072         hangup->conference->playback_chan = NULL;
1073
1074         ast_mutex_lock(&hangup->lock);
1075         hangup->hungup = 1;
1076         ast_cond_signal(&hangup->cond);
1077         ast_mutex_unlock(&hangup->lock);
1078
1079         return 0;
1080 }
1081
1082 static void hangup_data_init(struct hangup_data *hangup, struct confbridge_conference *conference)
1083 {
1084         ast_mutex_init(&hangup->lock);
1085         ast_cond_init(&hangup->cond, NULL);
1086
1087         hangup->conference = conference;
1088         hangup->hungup = 0;
1089 }
1090
1091 static void hangup_data_destroy(struct hangup_data *hangup)
1092 {
1093         ast_mutex_destroy(&hangup->lock);
1094         ast_cond_destroy(&hangup->cond);
1095 }
1096
1097 /*!
1098  * \brief Destroy a conference bridge
1099  *
1100  * \param obj The conference bridge object
1101  *
1102  * \return Returns nothing
1103  */
1104 static void destroy_conference_bridge(void *obj)
1105 {
1106         struct confbridge_conference *conference = obj;
1107
1108         ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
1109
1110         if (conference->playback_chan) {
1111                 if (conference->playback_queue) {
1112                         struct hangup_data hangup;
1113                         hangup_data_init(&hangup, conference);
1114
1115                         if (!ast_taskprocessor_push(conference->playback_queue, hangup_playback, &hangup)) {
1116                                 ast_mutex_lock(&hangup.lock);
1117                                 while (!hangup.hungup) {
1118                                         ast_cond_wait(&hangup.cond, &hangup.lock);
1119                                 }
1120                                 ast_mutex_unlock(&hangup.lock);
1121                         }
1122
1123                         hangup_data_destroy(&hangup);
1124                 } else {
1125                         /* Playback queue is not yet allocated. Just hang up the channel straight */
1126                         ast_hangup(conference->playback_chan);
1127                         conference->playback_chan = NULL;
1128                 }
1129         }
1130
1131         /* Destroying a conference bridge is simple, all we have to do is destroy the bridging object */
1132         if (conference->bridge) {
1133                 ast_bridge_destroy(conference->bridge, 0);
1134                 conference->bridge = NULL;
1135         }
1136
1137         ast_channel_cleanup(conference->record_chan);
1138         ast_free(conference->orig_rec_file);
1139         ast_free(conference->record_filename);
1140
1141         conf_bridge_profile_destroy(&conference->b_profile);
1142         ast_taskprocessor_unreference(conference->playback_queue);
1143 }
1144
1145 /*! \brief Call the proper join event handler for the user for the conference bridge's current state
1146  * \internal
1147  * \param user The conference bridge user that is joining
1148  * \retval 0 success
1149  * \retval -1 failure
1150  */
1151 static int handle_conf_user_join(struct confbridge_user *user)
1152 {
1153         conference_event_fn handler;
1154         if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1155                 handler = user->conference->state->join_marked;
1156         } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1157                 handler = user->conference->state->join_waitmarked;
1158         } else {
1159                 handler = user->conference->state->join_unmarked;
1160         }
1161
1162         ast_assert(handler != NULL);
1163
1164         if (!handler) {
1165                 conf_invalid_event_fn(user);
1166                 return -1;
1167         }
1168
1169         handler(user);
1170
1171         return 0;
1172 }
1173
1174 /*! \brief Call the proper leave event handler for the user for the conference bridge's current state
1175  * \internal
1176  * \param user The conference bridge user that is leaving
1177  * \retval 0 success
1178  * \retval -1 failure
1179  */
1180 static int handle_conf_user_leave(struct confbridge_user *user)
1181 {
1182         conference_event_fn handler;
1183         if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1184                 handler = user->conference->state->leave_marked;
1185         } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1186                 handler = user->conference->state->leave_waitmarked;
1187         } else {
1188                 handler = user->conference->state->leave_unmarked;
1189         }
1190
1191         ast_assert(handler != NULL);
1192
1193         if (!handler) {
1194                 /* This should never happen. If it does, though, it is bad. The user will not have been removed
1195                  * from the appropriate list, so counts will be off and stuff. The conference won't be torn down, etc.
1196                  * Shouldn't happen, though. */
1197                 conf_invalid_event_fn(user);
1198                 return -1;
1199         }
1200
1201         handler(user);
1202
1203         return 0;
1204 }
1205
1206 void conf_update_user_mute(struct confbridge_user *user)
1207 {
1208         int mute_user;
1209         int mute_system;
1210         int mute_effective;
1211
1212         /* User level mute request. */
1213         mute_user = user->muted;
1214
1215         /* System level mute request. */
1216         mute_system = user->playing_moh
1217                 /*
1218                  * Do not allow waitmarked users to talk to anyone unless there
1219                  * is a marked user present.
1220                  */
1221                 || (!user->conference->markedusers
1222                         && ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED));
1223
1224         mute_effective = mute_user || mute_system;
1225
1226         ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1227                 ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1228                 mute_user, mute_system);
1229         user->features.mute = mute_effective;
1230         ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1231                 "Mode: %s\r\n"
1232                 "Conference: %s\r\n"
1233                 "Channel: %s",
1234                 mute_effective ? "muted" : "unmuted",
1235                 user->conference->b_profile.name,
1236                 ast_channel_name(user->chan));
1237 }
1238
1239 /*
1240  * \internal
1241  * \brief Mute/unmute a single user.
1242  */
1243 static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
1244 {
1245         /* Set user level mute request. */
1246         user->muted = mute ? 1 : 0;
1247
1248         conf_update_user_mute(user);
1249         ast_test_suite_event_notify("CONF_MUTE",
1250                 "Message: participant %s %s\r\n"
1251                 "Conference: %s\r\n"
1252                 "Channel: %s",
1253                 ast_channel_name(user->chan),
1254                 mute ? "muted" : "unmuted",
1255                 conference->b_profile.name,
1256                 ast_channel_name(user->chan));
1257         if (mute) {
1258                 send_mute_event(user, conference);
1259         } else {
1260                 send_unmute_event(user, conference);
1261         }
1262 }
1263
1264 void conf_moh_stop(struct confbridge_user *user)
1265 {
1266         user->playing_moh = 0;
1267         if (!user->suspended_moh) {
1268                 int in_bridge;
1269
1270                 /*
1271                  * Locking the ast_bridge here is the only way to hold off the
1272                  * call to ast_bridge_join() in confbridge_exec() from
1273                  * interfering with the bridge and MOH operations here.
1274                  */
1275                 ast_bridge_lock(user->conference->bridge);
1276
1277                 /*
1278                  * Temporarily suspend the user from the bridge so we have
1279                  * control to stop MOH if needed.
1280                  */
1281                 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1282                 ast_moh_stop(user->chan);
1283                 if (in_bridge) {
1284                         ast_bridge_unsuspend(user->conference->bridge, user->chan);
1285                 }
1286
1287                 ast_bridge_unlock(user->conference->bridge);
1288         }
1289 }
1290
1291 void conf_moh_start(struct confbridge_user *user)
1292 {
1293         user->playing_moh = 1;
1294         if (!user->suspended_moh) {
1295                 int in_bridge;
1296
1297                 /*
1298                  * Locking the ast_bridge here is the only way to hold off the
1299                  * call to ast_bridge_join() in confbridge_exec() from
1300                  * interfering with the bridge and MOH operations here.
1301                  */
1302                 ast_bridge_lock(user->conference->bridge);
1303
1304                 /*
1305                  * Temporarily suspend the user from the bridge so we have
1306                  * control to start MOH if needed.
1307                  */
1308                 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1309                 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1310                 if (in_bridge) {
1311                         ast_bridge_unsuspend(user->conference->bridge, user->chan);
1312                 }
1313
1314                 ast_bridge_unlock(user->conference->bridge);
1315         }
1316 }
1317
1318 /*!
1319  * \internal
1320  * \brief Unsuspend MOH for the conference user.
1321  *
1322  * \param user Conference user to unsuspend MOH on.
1323  *
1324  * \return Nothing
1325  */
1326 static void conf_moh_unsuspend(struct confbridge_user *user)
1327 {
1328         ao2_lock(user->conference);
1329         if (--user->suspended_moh == 0 && user->playing_moh) {
1330                 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1331         }
1332         ao2_unlock(user->conference);
1333 }
1334
1335 /*!
1336  * \internal
1337  * \brief Suspend MOH for the conference user.
1338  *
1339  * \param user Conference user to suspend MOH on.
1340  *
1341  * \return Nothing
1342  */
1343 static void conf_moh_suspend(struct confbridge_user *user)
1344 {
1345         ao2_lock(user->conference);
1346         if (user->suspended_moh++ == 0 && user->playing_moh) {
1347                 ast_moh_stop(user->chan);
1348         }
1349         ao2_unlock(user->conference);
1350 }
1351
1352 int conf_handle_inactive_waitmarked(struct confbridge_user *user)
1353 {
1354         /* If we have not been quieted play back that they are waiting for the leader */
1355         if (!ast_test_flag(&user->u_profile, USER_OPT_QUIET) && play_prompt_to_user(user,
1356                         conf_get_sound(CONF_SOUND_WAIT_FOR_LEADER, user->conference->b_profile.sounds))) {
1357                 /* user hungup while the sound was playing */
1358                 return -1;
1359         }
1360         return 0;
1361 }
1362
1363 int conf_handle_only_unmarked(struct confbridge_user *user)
1364 {
1365         /* If audio prompts have not been quieted or this prompt quieted play it on out */
1366         if (!ast_test_flag(&user->u_profile, USER_OPT_QUIET | USER_OPT_NOONLYPERSON)) {
1367                 if (play_prompt_to_user(user,
1368                         conf_get_sound(CONF_SOUND_ONLY_PERSON, user->conference->b_profile.sounds))) {
1369                         /* user hungup while the sound was playing */
1370                         return -1;
1371                 }
1372         }
1373         return 0;
1374 }
1375
1376 int conf_add_post_join_action(struct confbridge_user *user, int (*func)(struct confbridge_user *user))
1377 {
1378         struct post_join_action *action;
1379         if (!(action = ast_calloc(1, sizeof(*action)))) {
1380                 return -1;
1381         }
1382         action->func = func;
1383         AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1384         return 0;
1385 }
1386
1387
1388 void conf_handle_first_join(struct confbridge_conference *conference)
1389 {
1390         ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference->name);
1391 }
1392
1393 void conf_handle_second_active(struct confbridge_conference *conference)
1394 {
1395         /* If we are the second participant we may need to stop music on hold on the first */
1396         struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1397
1398         if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1399                 conf_moh_stop(first_user);
1400         }
1401         conf_update_user_mute(first_user);
1402 }
1403
1404 void conf_ended(struct confbridge_conference *conference)
1405 {
1406         struct pbx_find_info q = { .stacklen = 0 };
1407
1408         /* Called with a reference to conference */
1409         ao2_unlink(conference_bridges, conference);
1410         send_conf_end_event(conference);
1411         if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1412                         pbx_find_extension(NULL, NULL, &q, conference->b_profile.regcontext,
1413                                 conference->name, 1, NULL, "", E_MATCH)) {
1414                 ast_context_remove_extension(conference->b_profile.regcontext,
1415                                 conference->name, 1, NULL);
1416         }
1417         ao2_lock(conference);
1418         conf_stop_record(conference);
1419         ao2_unlock(conference);
1420 }
1421
1422 /*!
1423  * \internal
1424  * \brief Allocate playback channel for a conference.
1425  * \pre expects conference to be locked before calling this function
1426  */
1427 static int alloc_playback_chan(struct confbridge_conference *conference)
1428 {
1429         struct ast_format_cap *cap;
1430         char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1431
1432         cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
1433         if (!cap) {
1434                 return -1;
1435         }
1436         ast_format_cap_append(cap, ast_format_slin, 0);
1437         conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1438                 conference->name, NULL);
1439         ao2_ref(cap, -1);
1440         if (!conference->playback_chan) {
1441                 return -1;
1442         }
1443
1444         /* To make sure playback_chan has the same language as the bridge */
1445         ast_channel_lock(conference->playback_chan);
1446         ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1447         ast_channel_unlock(conference->playback_chan);
1448
1449         ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1450                 ast_channel_name(conference->playback_chan), conference->name);
1451
1452         ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1453                 "Confbridge/%s", conference->name);
1454         conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1455         if (!conference->playback_queue) {
1456                 ast_hangup(conference->playback_chan);
1457                 conference->playback_chan = NULL;
1458                 return -1;
1459         }
1460         return 0;
1461 }
1462
1463 /*!
1464  * \brief Push the announcer channel into the bridge
1465  *
1466  * \param conference Conference bridge to push the announcer to
1467  * \retval 0 Success
1468  * \retval -1 Failed to push the channel to the bridge
1469  */
1470 static int push_announcer(struct confbridge_conference *conference)
1471 {
1472         if (conf_announce_channel_push(conference->playback_chan)) {
1473                 ast_hangup(conference->playback_chan);
1474                 conference->playback_chan = NULL;
1475                 return -1;
1476         }
1477
1478         ast_autoservice_start(conference->playback_chan);
1479         return 0;
1480 }
1481
1482 /*!
1483  * \brief Join a conference bridge
1484  *
1485  * \param conference_name The conference name
1486  * \param user Conference bridge user structure
1487  *
1488  * \return A pointer to the conference bridge struct, or NULL if the conference room wasn't found.
1489  */
1490 static struct confbridge_conference *join_conference_bridge(const char *conference_name, struct confbridge_user *user)
1491 {
1492         struct confbridge_conference *conference;
1493         struct post_join_action *action;
1494         int max_members_reached = 0;
1495
1496         /* We explictly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same */
1497         ao2_lock(conference_bridges);
1498
1499         ast_debug(1, "Trying to find conference bridge '%s'\n", conference_name);
1500
1501         /* Attempt to find an existing conference bridge */
1502         conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
1503         if (conference && conference->b_profile.max_members) {
1504                 max_members_reached = conference->b_profile.max_members > conference->activeusers ? 0 : 1;
1505         }
1506
1507         /* When finding a conference bridge that already exists make sure that it is not locked, and if so that we are not an admin */
1508         if (conference && (max_members_reached || conference->locked) && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
1509                 ao2_unlock(conference_bridges);
1510                 ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", conference_name);
1511                 ast_stream_and_wait(user->chan,
1512                         conf_get_sound(CONF_SOUND_LOCKED, conference->b_profile.sounds),
1513                         "");
1514                 ao2_ref(conference, -1);
1515                 return NULL;
1516         }
1517
1518         /* If no conference bridge was found see if we can create one */
1519         if (!conference) {
1520                 /* Try to allocate memory for a new conference bridge, if we fail... this won't end well. */
1521                 if (!(conference = ao2_alloc(sizeof(*conference), destroy_conference_bridge))) {
1522                         ao2_unlock(conference_bridges);
1523                         ast_log(LOG_ERROR, "Conference '%s' could not be created.\n", conference_name);
1524                         return NULL;
1525                 }
1526
1527                 /* Setup for the record channel */
1528                 conference->record_filename = ast_str_create(RECORD_FILENAME_INITIAL_SPACE);
1529                 if (!conference->record_filename) {
1530                         ao2_ref(conference, -1);
1531                         ao2_unlock(conference_bridges);
1532                         return NULL;
1533                 }
1534
1535                 /* Setup conference bridge parameters */
1536                 ast_copy_string(conference->name, conference_name, sizeof(conference->name));
1537                 conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
1538
1539                 /* Create an actual bridge that will do the audio mixing */
1540                 conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
1541                         AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY,
1542                         app, conference_name, NULL);
1543                 if (!conference->bridge) {
1544                         ao2_ref(conference, -1);
1545                         ao2_unlock(conference_bridges);
1546                         ast_log(LOG_ERROR, "Conference '%s' mixing bridge could not be created.\n", conference_name);
1547                         return NULL;
1548                 }
1549
1550                 /* Set the internal sample rate on the bridge from the bridge profile */
1551                 ast_bridge_set_internal_sample_rate(conference->bridge, conference->b_profile.internal_sample_rate);
1552                 /* Set the internal mixing interval on the bridge from the bridge profile */
1553                 ast_bridge_set_mixing_interval(conference->bridge, conference->b_profile.mix_interval);
1554                 ast_bridge_set_binaural_active(conference->bridge, ast_test_flag(&conference->b_profile, BRIDGE_OPT_BINAURAL_ACTIVE));
1555
1556                 if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
1557                         ast_bridge_set_talker_src_video_mode(conference->bridge);
1558                 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
1559                         ast_bridge_set_sfu_video_mode(conference->bridge);
1560                         ast_bridge_set_video_update_discard(conference->bridge, conference->b_profile.video_update_discard);
1561                         ast_bridge_set_remb_send_interval(conference->bridge, conference->b_profile.remb_send_interval);
1562                         if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE)) {
1563                                 ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE);
1564                         } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST)) {
1565                                 ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST);
1566                         } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
1567                                 ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST);
1568                         }
1569                 }
1570
1571                 if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_ENABLE_EVENTS)) {
1572                         ast_bridge_set_send_sdp_label(conference->bridge, 1);
1573                 }
1574
1575                 /* Link it into the conference bridges container */
1576                 if (!ao2_link(conference_bridges, conference)) {
1577                         ao2_ref(conference, -1);
1578                         ao2_unlock(conference_bridges);
1579                         ast_log(LOG_ERROR,
1580                                 "Conference '%s' could not be added to the conferences list.\n", conference_name);
1581                         return NULL;
1582                 }
1583
1584                 /* Set the initial state to EMPTY */
1585                 conference->state = CONF_STATE_EMPTY;
1586
1587                 if (alloc_playback_chan(conference)) {
1588                         ao2_unlink(conference_bridges, conference);
1589                         ao2_ref(conference, -1);
1590                         ao2_unlock(conference_bridges);
1591                         ast_log(LOG_ERROR, "Could not allocate announcer channel for conference '%s'\n", conference_name);
1592                         return NULL;
1593                 }
1594
1595                 if (push_announcer(conference)) {
1596                         ao2_unlink(conference_bridges, conference);
1597                         ao2_ref(conference, -1);
1598                         ao2_unlock(conference_bridges);
1599                         ast_log(LOG_ERROR, "Could not add announcer channel for conference '%s' bridge\n", conference_name);
1600                         return NULL;
1601                 }
1602
1603                 if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_CONFERENCE)) {
1604                         ao2_lock(conference);
1605                         conf_start_record(conference);
1606                         ao2_unlock(conference);
1607                 }
1608
1609                 send_conf_start_event(conference);
1610
1611                 if (!ast_strlen_zero(conference->b_profile.regcontext)) {
1612                         if (!ast_exists_extension(NULL, conference->b_profile.regcontext, conference->name, 1, NULL)) {
1613                                 ast_add_extension(conference->b_profile.regcontext, 1, conference->name, 1, NULL, NULL, "Noop", NULL, NULL, "ConfBridge");
1614                         }
1615                 }
1616
1617                 ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
1618         }
1619
1620         ao2_unlock(conference_bridges);
1621
1622         /* Setup conference bridge user parameters */
1623         user->conference = conference;
1624
1625         ao2_lock(conference);
1626
1627         /* Determine if the new user should join the conference muted. */
1628         if (ast_test_flag(&user->u_profile, USER_OPT_STARTMUTED)
1629                 || (!ast_test_flag(&user->u_profile, USER_OPT_ADMIN) && conference->muted)) {
1630                 /* Set user level mute request. */
1631                 user->muted = 1;
1632         }
1633
1634         /*
1635          * Suspend any MOH until the user actually joins the bridge of
1636          * the conference.  This way any pre-join file playback does not
1637          * need to worry about MOH.
1638          */
1639         user->suspended_moh = 1;
1640
1641         if (handle_conf_user_join(user)) {
1642                 /* Invalid event, nothing was done, so we don't want to process a leave. */
1643                 ao2_unlock(conference);
1644                 ao2_ref(conference, -1);
1645                 user->conference = NULL;
1646                 return NULL;
1647         }
1648
1649         if (ast_check_hangup(user->chan)) {
1650                 ao2_unlock(conference);
1651                 leave_conference(user);
1652                 return NULL;
1653         }
1654
1655         ao2_unlock(conference);
1656
1657         /* If an announcement is to be played play it */
1658         if (!ast_strlen_zero(user->u_profile.announcement)) {
1659                 if (play_prompt_to_user(user,
1660                         user->u_profile.announcement)) {
1661                         leave_conference(user);
1662                         return NULL;
1663                 }
1664         }
1665
1666         /* Announce number of users if need be */
1667         if (ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCEUSERCOUNT)) {
1668                 if (announce_user_count(conference, user, NULL)) {
1669                         leave_conference(user);
1670                         return NULL;
1671                 }
1672         }
1673
1674         if (ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCEUSERCOUNTALL) &&
1675                 (conference->activeusers > user->u_profile.announce_user_count_all_after)) {
1676                 int user_count_res;
1677
1678                 /*
1679                  * We have to autoservice the new user because he has not quite
1680                  * joined the conference yet.
1681                  */
1682                 ast_autoservice_start(user->chan);
1683                 user_count_res = announce_user_count(conference, NULL, NULL);
1684                 ast_autoservice_stop(user->chan);
1685                 if (user_count_res) {
1686                         leave_conference(user);
1687                         return NULL;
1688                 }
1689         }
1690
1691         /* Handle post-join actions */
1692         while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
1693                 action->func(user);
1694                 ast_free(action);
1695         }
1696
1697         return conference;
1698 }
1699
1700 /*!
1701  * \brief Leave a conference
1702  *
1703  * \param user The conference user
1704  */
1705 static void leave_conference(struct confbridge_user *user)
1706 {
1707         struct post_join_action *action;
1708
1709         ao2_lock(user->conference);
1710         handle_conf_user_leave(user);
1711         ao2_unlock(user->conference);
1712
1713         /* Discard any post-join actions */
1714         while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
1715                 ast_free(action);
1716         }
1717
1718         /* Done mucking with the conference, huzzah */
1719         ao2_ref(user->conference, -1);
1720         user->conference = NULL;
1721 }
1722
1723 static void playback_common(struct confbridge_conference *conference, const char *filename, int say_number)
1724 {
1725         /* Don't try to play if the playback channel has been hung up */
1726         if (!conference->playback_chan) {
1727                 return;
1728         }
1729
1730         ast_autoservice_stop(conference->playback_chan);
1731
1732         /* The channel is all under our control, in goes the prompt */
1733         if (!ast_strlen_zero(filename)) {
1734                 ast_stream_and_wait(conference->playback_chan, filename, "");
1735         } else if (say_number >= 0) {
1736                 ast_say_number(conference->playback_chan, say_number, "",
1737                         ast_channel_language(conference->playback_chan), NULL);
1738         }
1739
1740         ast_autoservice_start(conference->playback_chan);
1741 }
1742
1743 struct playback_task_data {
1744         struct confbridge_conference *conference;
1745         const char *filename;
1746         int say_number;
1747         int playback_finished;
1748         ast_mutex_t lock;
1749         ast_cond_t cond;
1750 };
1751
1752 /*!
1753  * \brief Play an announcement into a confbridge
1754  *
1755  * This runs in the playback queue taskprocessor. This ensures that
1756  * all playbacks are handled in sequence and do not play over top one
1757  * another.
1758  *
1759  * This task runs synchronously so there is no need for performing any
1760  * sort of cleanup on the input parameter.
1761  *
1762  * \param data A playback_task_data
1763  * \return 0
1764  */
1765 static int playback_task(void *data)
1766 {
1767         struct playback_task_data *ptd = data;
1768
1769         playback_common(ptd->conference, ptd->filename, ptd->say_number);
1770
1771         ast_mutex_lock(&ptd->lock);
1772         ptd->playback_finished = 1;
1773         ast_cond_signal(&ptd->cond);
1774         ast_mutex_unlock(&ptd->lock);
1775
1776         return 0;
1777 }
1778
1779 static void playback_task_data_init(struct playback_task_data *ptd, struct confbridge_conference *conference,
1780                 const char *filename, int say_number)
1781 {
1782         ast_mutex_init(&ptd->lock);
1783         ast_cond_init(&ptd->cond, NULL);
1784
1785         ptd->filename = filename;
1786         ptd->say_number = say_number;
1787         ptd->conference = conference;
1788         ptd->playback_finished = 0;
1789 }
1790
1791 static void playback_task_data_destroy(struct playback_task_data *ptd)
1792 {
1793         ast_mutex_destroy(&ptd->lock);
1794         ast_cond_destroy(&ptd->cond);
1795 }
1796
1797 static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)
1798 {
1799         struct playback_task_data ptd;
1800
1801         /* Do not waste resources trying to play files that do not exist */
1802         if (ast_strlen_zero(filename)) {
1803                 if (say_number < 0) {
1804                         return 0;
1805                 }
1806         } else if (!sound_file_exists(filename)) {
1807                 return 0;
1808         }
1809
1810         playback_task_data_init(&ptd, conference, filename, say_number);
1811         if (ast_taskprocessor_push(conference->playback_queue, playback_task, &ptd)) {
1812                 if (!ast_strlen_zero(filename)) {
1813                         ast_log(LOG_WARNING, "Unable to play file '%s' to conference %s\n",
1814                                 filename, conference->name);
1815                 } else {
1816                         ast_log(LOG_WARNING, "Unable to say number '%d' to conference %s\n",
1817                                 say_number, conference->name);
1818                 }
1819                 playback_task_data_destroy(&ptd);
1820                 return -1;
1821         }
1822
1823         /* Wait for the playback to complete */
1824         ast_mutex_lock(&ptd.lock);
1825         while (!ptd.playback_finished) {
1826                 ast_cond_wait(&ptd.cond, &ptd.lock);
1827         }
1828         ast_mutex_unlock(&ptd.lock);
1829
1830         playback_task_data_destroy(&ptd);
1831
1832         return 0;
1833 }
1834
1835 int play_sound_file(struct confbridge_conference *conference, const char *filename)
1836 {
1837         return play_sound_helper(conference, filename, -1);
1838 }
1839
1840 struct async_playback_task_data {
1841         struct confbridge_conference *conference;
1842         int say_number;
1843         struct ast_channel *initiator;
1844         char filename[0];
1845 };
1846
1847 struct async_datastore_data {
1848         ast_mutex_t lock;
1849         ast_cond_t cond;
1850         int wait;
1851 };
1852
1853 static void async_datastore_data_destroy(void *data)
1854 {
1855         struct async_datastore_data *add = data;
1856
1857         ast_mutex_destroy(&add->lock);
1858         ast_cond_destroy(&add->cond);
1859
1860         ast_free(add);
1861 }
1862
1863 /*!
1864  * \brief Datastore used for timing of async announcement playback
1865  *
1866  * Announcements that are played to the entire conference can be played
1867  * asynchronously (i.e. The channel that queues the playback does not wait
1868  * for the playback to complete before continuing)
1869  *
1870  * The thing about async announcements is that the channel that queues the
1871  * announcement is either not in the bridge or is in some other way "occupied"
1872  * at the time the announcement is queued. Because of that, the initiator of
1873  * the announcement may enter after the announcement has already started,
1874  * resulting in the sound being "clipped".
1875  *
1876  * This datastore makes it so that the channel that queues the async announcement
1877  * can say "I'm ready now". This way the announcement does not start until the
1878  * initiator of the announcement is ready to hear the sound.
1879  */
1880 static struct ast_datastore_info async_datastore_info = {
1881         .type = "Confbridge async playback",
1882         .destroy = async_datastore_data_destroy,
1883 };
1884
1885 static struct async_datastore_data *async_datastore_data_alloc(void)
1886 {
1887         struct async_datastore_data *add;
1888
1889         add = ast_malloc(sizeof(*add));
1890         if (!add) {
1891                 return NULL;
1892         }
1893
1894         ast_mutex_init(&add->lock);
1895         ast_cond_init(&add->cond, NULL);
1896         add->wait = 1;
1897
1898         return add;
1899 }
1900
1901 /*!
1902  * \brief Prepare the async playback datastore
1903  *
1904  * This is done prior to queuing an async announcement. If the
1905  * datastore has not yet been created, it is allocated and initialized.
1906  * If it already exists, we set it to be in "waiting" mode.
1907  *
1908  * \param initiator The channel that is queuing the async playback
1909  * \retval 0 Success
1910  * \retval -1 Failure :(
1911  */
1912 static int setup_async_playback_datastore(struct ast_channel *initiator)
1913 {
1914         struct ast_datastore *async_datastore;
1915
1916         async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
1917         if (async_datastore) {
1918                 struct async_datastore_data *add;
1919
1920                 add = async_datastore->data;
1921                 add->wait = 1;
1922
1923                 return 0;
1924         }
1925
1926         async_datastore = ast_datastore_alloc(&async_datastore_info, NULL);
1927         if (!async_datastore) {
1928                 return -1;
1929         }
1930
1931         async_datastore->data = async_datastore_data_alloc();
1932         if (!async_datastore->data) {
1933                 ast_datastore_free(async_datastore);
1934                 return -1;
1935         }
1936
1937         ast_channel_datastore_add(initiator, async_datastore);
1938         return 0;
1939 }
1940
1941 static struct async_playback_task_data *async_playback_task_data_alloc(
1942         struct confbridge_conference *conference, const char *filename, int say_number,
1943         struct ast_channel *initiator)
1944 {
1945         struct async_playback_task_data *aptd;
1946
1947         aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
1948         if (!aptd) {
1949                 return NULL;
1950         }
1951
1952         /* Safe */
1953         strcpy(aptd->filename, filename);
1954         aptd->say_number = say_number;
1955
1956         /* You may think that we need to bump the conference refcount since we are pushing
1957          * this task to the taskprocessor.
1958          *
1959          * In this case, that actually causes a problem. The destructor for the conference
1960          * pushes a hangup task into the taskprocessor and waits for it to complete before
1961          * continuing. If the destructor gets called from a taskprocessor task, we're
1962          * deadlocked.
1963          *
1964          * So is there a risk of the conference being freed out from under us? No. Since
1965          * the destructor pushes a task into the taskprocessor and waits for it to complete,
1966          * the destructor cannot free the conference out from under us. No further tasks
1967          * can be queued onto the taskprocessor after the hangup since no channels are referencing
1968          * the conference at that point any more.
1969          */
1970         aptd->conference = conference;
1971
1972         aptd->initiator = initiator;
1973         if (initiator) {
1974                 ast_channel_ref(initiator);
1975                 ast_channel_lock(aptd->initiator);
1976                 /* We don't really care if this fails. If the datastore fails to get set up
1977                  * we'll still play the announcement. It's possible that the sound will be
1978                  * clipped for the initiator, but that's not the end of the world.
1979                  */
1980                 setup_async_playback_datastore(aptd->initiator);
1981                 ast_channel_unlock(aptd->initiator);
1982         }
1983
1984         return aptd;
1985 }
1986
1987 static void async_playback_task_data_destroy(struct async_playback_task_data *aptd)
1988 {
1989         ast_channel_cleanup(aptd->initiator);
1990         ast_free(aptd);
1991 }
1992
1993 /*!
1994  * \brief Wait for the initiator of an async playback to be ready
1995  *
1996  * See the description on the async_datastore_info structure for more
1997  * information about what this is about.
1998  *
1999  * \param initiator The channel that queued the async announcement
2000  */
2001 static void wait_for_initiator(struct ast_channel *initiator)
2002 {
2003         struct ast_datastore *async_datastore;
2004         struct async_datastore_data *add;
2005
2006         ast_channel_lock(initiator);
2007         async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2008         ast_channel_unlock(initiator);
2009
2010         if (!async_datastore) {
2011                 return;
2012         }
2013
2014         add = async_datastore->data;
2015
2016         ast_mutex_lock(&add->lock);
2017         while (add->wait) {
2018                 ast_cond_wait(&add->cond, &add->lock);
2019         }
2020         ast_mutex_unlock(&add->lock);
2021 }
2022
2023 /*!
2024  * \brief Play an announcement into a confbridge asynchronously
2025  *
2026  * This runs in the playback queue taskprocessor. This ensures that
2027  * all playbacks are handled in sequence and do not play over top one
2028  * another.
2029  *
2030  * \param data An async_playback_task_data
2031  * \return 0
2032  */
2033 static int async_playback_task(void *data)
2034 {
2035         struct async_playback_task_data *aptd = data;
2036
2037         /* Wait for the initiator to get back in the bridge or be hung up */
2038         if (aptd->initiator) {
2039                 wait_for_initiator(aptd->initiator);
2040         }
2041
2042         playback_common(aptd->conference, aptd->filename, aptd->say_number);
2043
2044         async_playback_task_data_destroy(aptd);
2045         return 0;
2046 }
2047
2048 static int async_play_sound_helper(struct confbridge_conference *conference,
2049         const char *filename, int say_number, struct ast_channel *initiator)
2050 {
2051         struct async_playback_task_data *aptd;
2052
2053         /* Do not waste resources trying to play files that do not exist */
2054         if (ast_strlen_zero(filename)) {
2055                 if (say_number < 0) {
2056                         return 0;
2057                 }
2058         } else if (!sound_file_exists(filename)) {
2059                 return 0;
2060         }
2061
2062         aptd = async_playback_task_data_alloc(conference, filename, say_number, initiator);
2063         if (!aptd) {
2064                 return -1;
2065         }
2066
2067         if (ast_taskprocessor_push(conference->playback_queue, async_playback_task, aptd)) {
2068                 if (!ast_strlen_zero(filename)) {
2069                         ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2070                                 filename, conference->name);
2071                 } else {
2072                         ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2073                                 say_number, conference->name);
2074                 }
2075                 async_playback_task_data_destroy(aptd);
2076                 return -1;
2077         }
2078
2079         return 0;
2080 }
2081
2082 int async_play_sound_file(struct confbridge_conference *conference,
2083         const char *filename, struct ast_channel *initiator)
2084 {
2085         return async_play_sound_helper(conference, filename, -1, initiator);
2086 }
2087
2088 void async_play_sound_ready(struct ast_channel *chan)
2089 {
2090         struct ast_datastore *async_datastore;
2091         struct async_datastore_data *add;
2092
2093         ast_channel_lock(chan);
2094         async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2095         ast_channel_unlock(chan);
2096         if (!async_datastore) {
2097                 return;
2098         }
2099
2100         add = async_datastore->data;
2101
2102         ast_mutex_lock(&add->lock);
2103         add->wait = 0;
2104         ast_cond_signal(&add->cond);
2105         ast_mutex_unlock(&add->lock);
2106 }
2107
2108 /*!
2109  * \brief Play number into the conference bridge
2110  *
2111  * \param conference The conference bridge to say the number into
2112  * \param say_number number to say
2113  *
2114  * \retval 0 success
2115  * \retval -1 failure
2116  */
2117 static int play_sound_number(struct confbridge_conference *conference, int say_number)
2118 {
2119         return play_sound_helper(conference, NULL, say_number);
2120 }
2121
2122 static int conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
2123 {
2124         struct confbridge_user *user = hook_pvt;
2125         RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
2126         struct ast_json *talking_extras;
2127
2128         conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2129         if (!conference) {
2130                 /* Remove the hook since the conference does not exist. */
2131                 return -1;
2132         }
2133
2134         ao2_lock(conference);
2135         user->talking = talking;
2136         ao2_unlock(conference);
2137
2138         talking_extras = ast_json_pack("{s: s, s: b}",
2139                 "talking_status", talking ? "on" : "off",
2140                 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2141         if (!talking_extras) {
2142                 return 0;
2143         }
2144
2145         send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2146         ast_json_unref(talking_extras);
2147         return 0;
2148 }
2149
2150 static int conf_get_pin(struct ast_channel *chan, struct confbridge_user *user)
2151 {
2152         char pin_guess[MAX_PIN+1] = { 0, };
2153         const char *pin = user->u_profile.pin;
2154         char *tmp = pin_guess;
2155         int i, res;
2156         unsigned int len = MAX_PIN;
2157
2158         /*
2159          * NOTE: We have not joined a conference yet so we have to use
2160          * the bridge profile requested by the user.
2161          */
2162
2163         /* give them three tries to get the pin right */
2164         for (i = 0; i < 3; i++) {
2165                 if (ast_app_getdata(chan,
2166                         conf_get_sound(CONF_SOUND_GET_PIN, user->b_profile.sounds),
2167                         tmp, len, 0) >= 0) {
2168                         if (!strcasecmp(pin, pin_guess)) {
2169                                 return 0;
2170                         }
2171                 }
2172                 ast_streamfile(chan,
2173                         conf_get_sound(CONF_SOUND_INVALID_PIN, user->b_profile.sounds),
2174                         ast_channel_language(chan));
2175                 res = ast_waitstream(chan, AST_DIGIT_ANY);
2176                 if (res > 0) {
2177                         /* Account for digit already read during ivalid pin playback
2178                          * resetting pin buf. */
2179                         pin_guess[0] = res;
2180                         pin_guess[1] = '\0';
2181                         tmp = pin_guess + 1;
2182                         len = MAX_PIN - 1;
2183                 } else {
2184                         /* reset pin buf as empty buffer. */
2185                         tmp = pin_guess;
2186                         len = MAX_PIN;
2187                 }
2188         }
2189         return -1;
2190 }
2191
2192 static int user_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
2193 {
2194         ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END, 0);
2195         pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "TIMEOUT");
2196         return -1;
2197 }
2198
2199 static int conf_rec_name(struct confbridge_user *user, const char *conf_name)
2200 {
2201         char destdir[PATH_MAX];
2202         int res;
2203         int duration = 20;
2204
2205         snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2206
2207         if (ast_mkdir(destdir, 0777) != 0) {
2208                 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2209                 return -1;
2210         }
2211         snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2212                  "%s/confbridge-name-%s-%s", destdir,
2213                  conf_name, ast_channel_uniqueid(user->chan));
2214
2215         if (!(ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW))) {
2216                 res = ast_play_and_record(user->chan,
2217                         "vm-rec-name",
2218                         user->name_rec_location,
2219                         10,
2220                         "sln",
2221                         &duration,
2222                         NULL,
2223                         ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE),
2224                         0,
2225                         NULL);
2226         } else {
2227                 res = ast_record_review(user->chan,
2228                         "vm-rec-name",
2229                         user->name_rec_location,
2230                         10,
2231                         "sln",
2232                         &duration,
2233                         NULL);
2234         }
2235
2236         if (res == -1) {
2237                 ast_filedelete(user->name_rec_location, NULL);
2238                 user->name_rec_location[0] = '\0';
2239                 return -1;
2240         }
2241         return 0;
2242 }
2243
2244 struct async_delete_name_rec_task_data {
2245         struct confbridge_conference *conference;
2246         char filename[0];
2247 };
2248
2249 static struct async_delete_name_rec_task_data *async_delete_name_rec_task_data_alloc(
2250         struct confbridge_conference *conference, const char *filename)
2251 {
2252         struct async_delete_name_rec_task_data *atd;
2253
2254         atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2255         if (!atd) {
2256                 return NULL;
2257         }
2258
2259         /* Safe */
2260         strcpy(atd->filename, filename);
2261         atd->conference = conference;
2262
2263         return atd;
2264 }
2265
2266 static void async_delete_name_rec_task_data_destroy(struct async_delete_name_rec_task_data *atd)
2267 {
2268         ast_free(atd);
2269 }
2270
2271 /*!
2272  * \brief Delete user's name file asynchronously
2273  *
2274  * This runs in the playback queue taskprocessor. This ensures that
2275  * sound file is removed after playback is finished and not before.
2276  *
2277  * \param data An async_delete_name_rec_task_data
2278  * \return 0
2279  */
2280 static int async_delete_name_rec_task(void *data)
2281 {
2282         struct async_delete_name_rec_task_data *atd = data;
2283
2284         ast_filedelete(atd->filename, NULL);
2285         ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2286                 atd->conference->name, atd->filename);
2287
2288         async_delete_name_rec_task_data_destroy(atd);
2289         return 0;
2290 }
2291
2292 static int async_delete_name_rec(struct confbridge_conference *conference,
2293         const char *filename)
2294 {
2295         struct async_delete_name_rec_task_data *atd;
2296
2297         if (ast_strlen_zero(filename)) {
2298                 return 0;
2299         } else if (!sound_file_exists(filename)) {
2300                 return 0;
2301         }
2302
2303         atd = async_delete_name_rec_task_data_alloc(conference, filename);
2304         if (!atd) {
2305                 return -1;
2306         }
2307
2308         if (ast_taskprocessor_push(conference->playback_queue, async_delete_name_rec_task, atd)) {
2309                 ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2310                         conference->name, filename);
2311                 async_delete_name_rec_task_data_destroy(atd);
2312                 return -1;
2313         }
2314
2315         return 0;
2316 }
2317
2318 static int join_callback(struct ast_bridge_channel *bridge_channel, void *ignore)
2319 {
2320         async_play_sound_ready(bridge_channel->chan);
2321         return 0;
2322 }
2323
2324 struct confbridge_hook_data {
2325         struct confbridge_conference *conference;
2326         struct confbridge_user *user;
2327         enum ast_bridge_hook_type hook_type;
2328 };
2329
2330 static int send_event_hook_callback(struct ast_bridge_channel *bridge_channel, void *data)
2331 {
2332         struct confbridge_hook_data *hook_data = data;
2333
2334         if (hook_data->hook_type == AST_BRIDGE_HOOK_TYPE_JOIN) {
2335                 send_join_event(hook_data->user, hook_data->conference);
2336         } else {
2337                 send_leave_event(hook_data->user, hook_data->conference);
2338         }
2339
2340         return 0;
2341 }
2342
2343 /*! \brief The ConfBridge application */
2344 static int confbridge_exec(struct ast_channel *chan, const char *data)
2345 {
2346         int res = 0, volume_adjustments[2];
2347         int quiet = 0;
2348         int async_delete_task_pushed = 0;
2349         char *parse;
2350         const char *b_profile_name = NULL;
2351         const char *u_profile_name = NULL;
2352         const char *menu_profile_name = NULL;
2353         struct confbridge_conference *conference = NULL;
2354         struct confbridge_user user = {
2355                 .chan = chan,
2356                 .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2357                 .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2358                 .tech_args.drop_silence = 0,
2359         };
2360         struct confbridge_hook_data *join_hook_data;
2361         struct confbridge_hook_data *leave_hook_data;
2362
2363         AST_DECLARE_APP_ARGS(args,
2364                 AST_APP_ARG(conf_name);
2365                 AST_APP_ARG(b_profile_name);
2366                 AST_APP_ARG(u_profile_name);
2367                 AST_APP_ARG(menu_profile_name);
2368         );
2369
2370         if (ast_channel_state(chan) != AST_STATE_UP) {
2371                 ast_answer(chan);
2372         }
2373
2374         if (ast_bridge_features_init(&user.features)) {
2375                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2376                 res = -1;
2377                 goto confbridge_cleanup;
2378         }
2379
2380         /* We need to make a copy of the input string if we are going to modify it! */
2381         parse = ast_strdupa(data);
2382
2383         AST_STANDARD_APP_ARGS(args, parse);
2384
2385         if (ast_strlen_zero(args.conf_name)) {
2386                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2387                 ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2388                 res = -1;
2389                 goto confbridge_cleanup;
2390         }
2391
2392         if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2393                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2394                 ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2395                 res = -1;
2396                 goto confbridge_cleanup;
2397         }
2398
2399         /* bridge profile name */
2400         if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2401                 b_profile_name = args.b_profile_name;
2402         }
2403         if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2404                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2405                 ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2406                         b_profile_name : DEFAULT_BRIDGE_PROFILE);
2407                 res = -1;
2408                 goto confbridge_cleanup;
2409         }
2410
2411         /* user profile name */
2412         if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2413                 u_profile_name = args.u_profile_name;
2414         }
2415         if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2416                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2417                 ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2418                         u_profile_name : DEFAULT_USER_PROFILE);
2419                 res = -1;
2420                 goto confbridge_cleanup;
2421         }
2422
2423         quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2424
2425         /* ask for a PIN immediately after finding user profile.  This has to be
2426          * prompted for requardless of quiet setting. */
2427         if (!ast_strlen_zero(user.u_profile.pin)) {
2428                 if (conf_get_pin(chan, &user)) {
2429                         pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2430                         res = -1; /* invalid PIN */
2431                         goto confbridge_cleanup;
2432                 }
2433         }
2434
2435         /* See if we need them to record a intro name */
2436         if (!quiet &&
2437                 (ast_test_flag(&user.u_profile, USER_OPT_ANNOUNCE_JOIN_LEAVE) ||
2438                 (ast_test_flag(&user.u_profile, USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW)))) {
2439                 if (conf_rec_name(&user, args.conf_name)) {
2440                         pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2441                         res = -1; /* Hangup during name recording */
2442                         goto confbridge_cleanup;
2443                 }
2444         }
2445
2446         /* menu name */
2447         if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2448                 menu_profile_name = args.menu_profile_name;
2449         }
2450
2451         if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2452                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2453                 ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2454                         menu_profile_name : DEFAULT_MENU_PROFILE);
2455                 res = -1;
2456                 goto confbridge_cleanup;
2457         }
2458
2459         /* Set if DTMF should pass through for this user or not */
2460         if (ast_test_flag(&user.u_profile, USER_OPT_DTMF_PASS)) {
2461                 user.features.dtmf_passthrough = 1;
2462         } else {
2463                 user.features.dtmf_passthrough = 0;
2464         }
2465
2466         /* Set dsp threshold values if present */
2467         if (user.u_profile.talking_threshold) {
2468                 user.tech_args.talking_threshold = user.u_profile.talking_threshold;
2469         }
2470         if (user.u_profile.silence_threshold) {
2471                 user.tech_args.silence_threshold = user.u_profile.silence_threshold;
2472         }
2473
2474         /* Set a talker indicate call back if talking detection is requested */
2475         if (ast_test_flag(&user.u_profile, USER_OPT_TALKER_DETECT)) {
2476                 if (ast_bridge_talk_detector_hook(&user.features, conf_handle_talker_cb,
2477                         &user, NULL, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
2478                         pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2479                         res = -1;
2480                         goto confbridge_cleanup;
2481                 }
2482         }
2483
2484         /* Look for a conference bridge matching the provided name */
2485         if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2486                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2487                 res = -1;
2488                 goto confbridge_cleanup;
2489         }
2490
2491         /* Keep a copy of volume adjustments so we can restore them later if need be */
2492         volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2493         volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2494
2495         if (ast_test_flag(&user.u_profile, USER_OPT_DROP_SILENCE)) {
2496                 user.tech_args.drop_silence = 1;
2497         }
2498
2499         if (ast_test_flag(&user.u_profile, USER_OPT_JITTERBUFFER)) {
2500                 ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2501         }
2502
2503         if (ast_test_flag(&user.u_profile, USER_OPT_DENOISE)) {
2504                 ast_func_write(chan, "DENOISE(rx)", "on");
2505         }
2506
2507         /* if this user has a intro, play it before entering */
2508         if (!ast_strlen_zero(user.name_rec_location)) {
2509                 ast_autoservice_start(chan);
2510                 play_sound_file(conference, user.name_rec_location);
2511                 play_sound_file(conference,
2512                         conf_get_sound(CONF_SOUND_HAS_JOINED, conference->b_profile.sounds));
2513                 ast_autoservice_stop(chan);
2514         }
2515
2516         /* Play the Join sound to both the conference and the user entering. */
2517         if (!quiet) {
2518                 const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2519
2520                 if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2521                         ast_stream_and_wait(chan, join_sound, "");
2522                         ast_autoservice_start(chan);
2523                         play_sound_file(conference, join_sound);
2524                         ast_autoservice_stop(chan);
2525                 } else {
2526                         async_play_sound_file(conference, join_sound, chan);
2527                 }
2528         }
2529
2530         if (user.u_profile.timeout) {
2531                 ast_bridge_interval_hook(&user.features,
2532                         0,
2533                         user.u_profile.timeout * 1000,
2534                         user_timeout,
2535                         NULL,
2536                         NULL,
2537                         AST_BRIDGE_HOOK_REMOVE_ON_PULL);
2538         }
2539
2540         /* See if we need to automatically set this user as a video source or not */
2541         handle_video_on_join(conference, user.chan, ast_test_flag(&user.u_profile, USER_OPT_MARKEDUSER));
2542
2543         conf_moh_unsuspend(&user);
2544
2545         join_hook_data = ast_malloc(sizeof(*join_hook_data));
2546         if (!join_hook_data) {
2547                 res = -1;
2548                 goto confbridge_cleanup;
2549         }
2550         join_hook_data->user = &user;
2551         join_hook_data->conference = conference;
2552         join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2553         res = ast_bridge_join_hook(&user.features, send_event_hook_callback,
2554                 join_hook_data, ast_free_ptr, 0);
2555         if (res) {
2556                 ast_free(join_hook_data);
2557                 ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2558                 goto confbridge_cleanup;
2559         }
2560
2561         leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2562         if (!leave_hook_data) {
2563                 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2564                 res = -1;
2565                 goto confbridge_cleanup;
2566         }
2567         leave_hook_data->user = &user;
2568         leave_hook_data->conference = conference;
2569         leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2570         res = ast_bridge_leave_hook(&user.features, send_event_hook_callback,
2571                 leave_hook_data, ast_free_ptr, 0);
2572         if (res) {
2573                 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2574                 ast_free(leave_hook_data);
2575                 ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2576                 goto confbridge_cleanup;
2577         }
2578
2579         if (ast_bridge_join_hook(&user.features, join_callback, NULL, NULL, 0)) {
2580                 async_play_sound_ready(user.chan);
2581         }
2582
2583         ast_bridge_join(conference->bridge,
2584                 chan,
2585                 NULL,
2586                 &user.features,
2587                 &user.tech_args,
2588                 0);
2589
2590         /* This is a catch-all in case joining the bridge failed or for some reason
2591          * an async announcement got queued up and hasn't been told to play yet
2592          */
2593         async_play_sound_ready(chan);
2594
2595         if (!user.kicked && ast_check_hangup(chan)) {
2596                 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2597         }
2598
2599         /* if we're shutting down, don't attempt to do further processing */
2600         if (ast_shutting_down()) {
2601                 /*
2602                  * Not taking any new calls at this time.  We cannot create
2603                  * the announcer channel if this is the first channel into
2604                  * the conference and we certainly cannot create any
2605                  * recording channel.
2606                  */
2607                 leave_conference(&user);
2608                 conference = NULL;
2609                 goto confbridge_cleanup;
2610         }
2611
2612         /* If this user was a video source, we need to clean up and possibly pick a new source. */
2613         handle_video_on_exit(conference, user.chan);
2614
2615         /* if this user has a intro, play it when leaving */
2616         if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2617                 async_play_sound_file(conference, user.name_rec_location, NULL);
2618                 async_play_sound_file(conference,
2619                         conf_get_sound(CONF_SOUND_HAS_LEFT, conference->b_profile.sounds), NULL);
2620                 async_delete_name_rec(conference, user.name_rec_location);
2621                 async_delete_task_pushed = 1;
2622         }
2623
2624         /* play the leave sound */
2625         if (!quiet) {
2626                 const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2627                 async_play_sound_file(conference, leave_sound, NULL);
2628         }
2629
2630         /* If the user was kicked from the conference play back the audio prompt for it */
2631         if (!quiet && user.kicked) {
2632                 res = ast_stream_and_wait(chan,
2633                         conf_get_sound(CONF_SOUND_KICKED, conference->b_profile.sounds),
2634                         "");
2635         }
2636
2637         /* Easy as pie, depart this channel from the conference bridge */
2638         leave_conference(&user);
2639         conference = NULL;
2640
2641         /* Restore volume adjustments to previous values in case they were changed */
2642         if (volume_adjustments[0]) {
2643                 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2644         }
2645         if (volume_adjustments[1]) {
2646                 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2647         }
2648
2649 confbridge_cleanup:
2650         if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2651                 ast_filedelete(user.name_rec_location, NULL);
2652         }
2653         ast_bridge_features_cleanup(&user.features);
2654         conf_bridge_profile_destroy(&user.b_profile);
2655         return res;
2656 }
2657
2658 static int action_toggle_mute(struct confbridge_conference *conference,
2659                               struct confbridge_user *user,
2660                               struct ast_bridge_channel *bridge_channel)
2661 {
2662         int mute;
2663
2664         /* Toggle user level mute request. */
2665         mute = !user->muted;
2666         generic_mute_unmute_user(conference, user, mute);
2667
2668         return play_file(bridge_channel, NULL,
2669                 conf_get_sound(mute ? CONF_SOUND_MUTED : CONF_SOUND_UNMUTED,
2670                         conference->b_profile.sounds)) < 0;
2671 }
2672
2673 static int action_toggle_binaural(struct confbridge_conference *conference,
2674                 struct confbridge_user *user,
2675                 struct ast_bridge_channel *bridge_channel)
2676 {
2677         unsigned int binaural;
2678         ast_bridge_channel_lock_bridge(bridge_channel);
2679         binaural = !bridge_channel->binaural_suspended;
2680         bridge_channel->binaural_suspended = binaural;
2681         ast_bridge_unlock(bridge_channel->bridge);
2682         return play_file(bridge_channel, NULL, (binaural ?
2683                                 conf_get_sound(CONF_SOUND_BINAURAL_OFF, user->b_profile.sounds) :
2684                                 conf_get_sound(CONF_SOUND_BINAURAL_ON, user->b_profile.sounds))) < 0;
2685 }
2686
2687 static int action_toggle_mute_participants(struct confbridge_conference *conference, struct confbridge_user *user)
2688 {
2689         struct confbridge_user *cur_user = NULL;
2690         const char *sound_to_play;
2691         int mute;
2692
2693         ao2_lock(conference);
2694
2695         /* Toggle bridge level mute request. */
2696         mute = !conference->muted;
2697         conference->muted = mute;
2698
2699         AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) {
2700                 if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
2701                         /* Set user level to bridge level mute request. */
2702                         cur_user->muted = mute;
2703                         conf_update_user_mute(cur_user);
2704                 }
2705         }
2706
2707         ao2_unlock(conference);
2708
2709         sound_to_play = conf_get_sound(
2710                 mute ? CONF_SOUND_PARTICIPANTS_MUTED : CONF_SOUND_PARTICIPANTS_UNMUTED,
2711                 conference->b_profile.sounds);
2712
2713         if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
2714                 /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
2715                 ast_stream_and_wait(user->chan, sound_to_play, "");
2716
2717                 /* Announce to the group that all participants are muted */
2718                 ast_autoservice_start(user->chan);
2719                 play_sound_file(conference, sound_to_play);
2720                 ast_autoservice_stop(user->chan);
2721         } else {
2722                 /* Playing the sound asynchronously lets the sound be heard by everyone at once */
2723                 async_play_sound_file(conference, sound_to_play, user->chan);
2724         }
2725
2726         return 0;
2727 }
2728
2729 static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
2730 {
2731         char *file_copy = ast_strdupa(playback_file);
2732         char *file = NULL;
2733
2734         while ((file = strsep(&file_copy, "&"))) {
2735                 if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
2736                         ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2737                         return -1;
2738                 }
2739         }
2740         return 0;
2741 }
2742
2743 static int action_playback_and_continue(struct confbridge_conference *conference,
2744         struct confbridge_user *user,
2745         struct ast_bridge_channel *bridge_channel,
2746         struct conf_menu *menu,
2747         const char *playback_file,
2748         const char *cur_dtmf,
2749         int *stop_prompts)
2750 {
2751         int i;
2752         int digit = 0;
2753         char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
2754         struct conf_menu_entry new_menu_entry = { { 0, }, };
2755         char *file_copy = ast_strdupa(playback_file);
2756         char *file = NULL;
2757
2758         while ((file = strsep(&file_copy, "&"))) {
2759                 if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
2760                         ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2761                         return -1;
2762                 }
2763
2764                 /* now wait for more digits. */
2765                 if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
2766                         /* streaming finished and no DTMF was entered */
2767                         continue;
2768                 } else if (digit == -1) {
2769                         /* error */
2770                         return -1;
2771                 } else {
2772                         break; /* dtmf was entered */
2773                 }
2774         }
2775         if (!digit) {
2776                 /* streaming finished on all files and no DTMF was entered */
2777                 return -1;
2778         }
2779         ast_stopstream(bridge_channel->chan);
2780
2781         /* If we get here, then DTMF has been entered, This means no
2782          * additional prompts should be played for this menu entry */
2783         *stop_prompts = 1;
2784
2785         /* If a digit was pressed during the payback, update
2786          * the dtmf string and look for a new menu entry in the
2787          * menu structure */
2788         ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
2789         for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
2790                 dtmf[i] = cur_dtmf[i];
2791                 if (!dtmf[i]) {
2792                         dtmf[i] = (char) digit;
2793                         dtmf[i + 1] = '\0';
2794                         i = -1;
2795                         break;
2796                 }
2797         }
2798         /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
2799          * If this is the case, no new DTMF sequence should be looked for. */
2800         if (i != -1) {
2801                 return 0;
2802         }
2803
2804         if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
2805                 execute_menu_entry(conference,
2806                         user,
2807                         bridge_channel,
2808                         &new_menu_entry, menu);
2809                 conf_menu_entry_destroy(&new_menu_entry);
2810         }
2811         return 0;
2812 }
2813
2814 static int action_kick_last(struct confbridge_conference *conference,
2815         struct ast_bridge_channel *bridge_channel,
2816         struct confbridge_user *user)
2817 {
2818         struct confbridge_user *last_user = NULL;
2819         int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
2820
2821         if (!isadmin) {
2822                 play_file(bridge_channel, NULL,
2823                         conf_get_sound(CONF_SOUND_ERROR_MENU, conference->b_profile.sounds));
2824                 ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
2825                         ast_channel_name(bridge_channel->chan),
2826                         conference->name);
2827                 return -1;
2828         }
2829
2830         ao2_lock(conference);
2831         last_user = AST_LIST_LAST(&conference->active_list);
2832         if (!last_user) {
2833                 ao2_unlock(conference);
2834                 return 0;
2835         }
2836
2837         if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
2838                 ao2_unlock(conference);
2839                 play_file(bridge_channel, NULL,
2840                         conf_get_sound(CONF_SOUND_ERROR_MENU, conference->b_profile.sounds));
2841         } else if (!last_user->kicked) {
2842                 last_user->kicked = 1;
2843                 pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
2844                 ast_bridge_remove(conference->bridge, last_user->chan);
2845                 ao2_unlock(conference);
2846         }
2847
2848         return 0;
2849 }
2850
2851 static int action_dialplan_exec(struct ast_bridge_channel *bridge_channel, struct conf_menu_action *menu_action)
2852 {
2853         struct ast_pbx_args args;
2854         struct ast_pbx *pbx;
2855         char *exten;
2856         char *context;
2857         int priority;
2858         int res;
2859
2860         memset(&args, 0, sizeof(args));
2861         args.no_hangup_chan = 1;
2862
2863         ast_channel_lock(bridge_channel->chan);
2864
2865         /*save off*/
2866         exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
2867         context = ast_strdupa(ast_channel_context(bridge_channel->chan));
2868         priority = ast_channel_priority(bridge_channel->chan);
2869         pbx = ast_channel_pbx(bridge_channel->chan);
2870         ast_channel_pbx_set(bridge_channel->chan, NULL);
2871
2872         /*set new*/
2873         ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
2874         ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
2875         ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
2876
2877         ast_channel_unlock(bridge_channel->chan);
2878
2879         /*execute*/
2880         res = ast_pbx_run_args(bridge_channel->chan, &args);
2881
2882         /*restore*/
2883         ast_channel_lock(bridge_channel->chan);
2884
2885         ast_channel_exten_set(bridge_channel->chan, exten);
2886         ast_channel_context_set(bridge_channel->chan, context);
2887         ast_channel_priority_set(bridge_channel->chan, priority);
2888         ast_channel_pbx_set(bridge_channel->chan, pbx);
2889
2890         ast_channel_unlock(bridge_channel->chan);
2891
2892         return res;
2893 }
2894
2895 static int execute_menu_entry(struct confbridge_conference *conference,
2896         struct confbridge_user *user,
2897         struct ast_bridge_channel *bridge_channel,
2898         struct conf_menu_entry *menu_entry,
2899         struct conf_menu *menu)
2900 {
2901         struct conf_menu_action *menu_action;
2902         int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
2903         int stop_prompts = 0;
2904         int res = 0;
2905
2906         AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
2907                 switch (menu_action->id) {
2908                 case MENU_ACTION_TOGGLE_MUTE:
2909                         res |= action_toggle_mute(conference, user, bridge_channel);
2910                         break;
2911                 case MENU_ACTION_TOGGLE_BINAURAL:
2912                         action_toggle_binaural(conference, user, bridge_channel);
2913                         break;
2914                 case MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS:
2915                         if (!isadmin) {
2916                                 break;
2917                         }
2918                         action_toggle_mute_participants(conference, user);
2919                         break;
2920                 case MENU_ACTION_PARTICIPANT_COUNT:
2921                         announce_user_count(conference, user, bridge_channel);
2922                         break;
2923                 case MENU_ACTION_PLAYBACK:
2924                         if (!stop_prompts) {
2925                                 res |= action_playback(bridge_channel, menu_action->data.playback_file);
2926                                 ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
2927                                         "Message: %s\r\nChannel: %s",
2928                                         menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
2929                         }
2930                         break;
2931                 case MENU_ACTION_RESET_LISTENING:
2932                         ast_audiohook_volume_set(user->chan, AST_AUDIOHOOK_DIRECTION_WRITE, 0);
2933                         break;
2934                 case MENU_ACTION_RESET_TALKING:
2935                         ast_audiohook_volume_set(user->chan, AST_AUDIOHOOK_DIRECTION_READ, 0);
2936                         break;
2937                 case MENU_ACTION_INCREASE_LISTENING:
2938                         ast_audiohook_volume_adjust(user->chan,
2939                                 AST_AUDIOHOOK_DIRECTION_WRITE, 1);
2940                         break;
2941                 case MENU_ACTION_DECREASE_LISTENING:
2942                         ast_audiohook_volume_adjust(user->chan,
2943                                 AST_AUDIOHOOK_DIRECTION_WRITE, -1);
2944                         break;
2945                 case MENU_ACTION_INCREASE_TALKING:
2946                         ast_audiohook_volume_adjust(user->chan,
2947                                 AST_AUDIOHOOK_DIRECTION_READ, 1);
2948                         break;
2949                 case MENU_ACTION_DECREASE_TALKING:
2950                         ast_audiohook_volume_adjust(user->chan,
2951                                 AST_AUDIOHOOK_DIRECTION_READ, -1);
2952                         break;
2953                 case MENU_ACTION_PLAYBACK_AND_CONTINUE:
2954                         if (!(stop_prompts)) {
2955                                 res |= action_playback_and_continue(conference,
2956                                         user,
2957                                         bridge_channel,
2958                                         menu,
2959                                         menu_action->data.playback_file,
2960                                         menu_entry->dtmf,
2961                                         &stop_prompts);
2962                         }
2963                         break;
2964                 case MENU_ACTION_DIALPLAN_EXEC:
2965                         res |= action_dialplan_exec(bridge_channel, menu_action);
2966                         break;
2967                 case MENU_ACTION_ADMIN_TOGGLE_LOCK:
2968                         if (!isadmin) {
2969                                 break;
2970                         }
2971                         conference->locked = (!conference->locked ? 1 : 0);
2972                         res |= play_file(bridge_channel, NULL,
2973                                 conf_get_sound(
2974                                         conference->locked ? CONF_SOUND_LOCKED_NOW : CONF_SOUND_UNLOCKED_NOW,
2975                                         conference->b_profile.sounds)) < 0;
2976                         break;
2977                 case MENU_ACTION_ADMIN_KICK_LAST:
2978                         res |= action_kick_last(conference, bridge_channel, user);
2979                         break;
2980                 case MENU_ACTION_LEAVE:
2981                         pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
2982                         ao2_lock(conference);
2983                         ast_bridge_remove(conference->bridge, bridge_channel->chan);
2984                         ast_test_suite_event_notify("CONF_MENU_LEAVE",
2985                                 "Channel: %s",
2986                                 ast_channel_name(bridge_channel->chan));
2987                         ao2_unlock(conference);
2988                         break;
2989                 case MENU_ACTION_NOOP:
2990                         break;
2991                 case MENU_ACTION_SET_SINGLE_VIDEO_SRC:
2992                         ao2_lock(conference);
2993                         if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
2994                                 ast_bridge_set_single_src_video_mode(conference->bridge, bridge_channel->chan);
2995                         }
2996                         ao2_unlock(conference);
2997                         break;
2998                 case MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC:
2999                         handle_video_on_exit(conference, bridge_channel->chan);
3000                         break;
3001                 }
3002         }
3003         return res;
3004 }
3005
3006 int conf_handle_dtmf(struct ast_bridge_channel *bridge_channel,
3007         struct confbridge_user *user,
3008         struct conf_menu_entry *menu_entry,
3009         struct conf_menu *menu)
3010 {
3011         /* See if music on hold is playing */
3012         conf_moh_suspend(user);
3013
3014         /* execute the list of actions associated with this menu entry */
3015         execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3016
3017         /* See if music on hold needs to be started back up again */
3018         conf_moh_unsuspend(user);
3019
3020         async_play_sound_ready(bridge_channel->chan);
3021
3022         return 0;
3023 }
3024
3025 static int kick_conference_participant(struct confbridge_conference *conference,
3026         const char *channel)
3027 {
3028         int res = -1;
3029         int match;
3030         struct confbridge_user *user = NULL;
3031         int all = !strcasecmp("all", channel);
3032         int participants = !strcasecmp("participants", channel);
3033
3034         SCOPED_AO2LOCK(bridge_lock, conference);
3035
3036         AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3037                 if (user->kicked) {
3038                         continue;
3039                 }
3040                 match = !strcasecmp(channel, ast_channel_name(user->chan));
3041                 if (match || all
3042                                 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3043                         user->kicked = 1;
3044                         pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3045                         ast_bridge_remove(conference->bridge, user->chan);
3046                         res = 0;
3047                         if (match) {
3048                                 return res;
3049                         }
3050                 }
3051         }
3052         AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3053                 if (user->kicked) {
3054                         continue;
3055                 }
3056                 match = !strcasecmp(channel, ast_channel_name(user->chan));
3057                 if (match || all
3058                                 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3059                         user->kicked = 1;
3060                         pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3061                         ast_bridge_remove(conference->bridge, user->chan);
3062                         res = 0;
3063                         if (match) {
3064                                 return res;
3065                         }
3066                 }
3067         }
3068
3069         return res;
3070 }
3071
3072 static char *complete_confbridge_name(const char *line, const char *word, int pos, int state)
3073 {
3074         int which = 0;
3075         struct confbridge_conference *conference;
3076         char *res = NULL;
3077         int wordlen = strlen(word);
3078         struct ao2_iterator iter;
3079
3080         iter = ao2_iterator_init(conference_bridges, 0);
3081         while ((conference = ao2_iterator_next(&iter))) {
3082                 if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3083                         res = ast_strdup(conference->name);
3084                         ao2_ref(conference, -1);
3085                         break;
3086                 }
3087                 ao2_ref(conference, -1);
3088         }
3089         ao2_iterator_destroy(&iter);
3090
3091         return res;
3092 }
3093
3094 static char *complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
3095 {
3096         int which = 0;
3097         RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3098         struct confbridge_user *user;
3099         char *res = NULL;
3100         int wordlen = strlen(word);
3101
3102         conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3103         if (!conference) {
3104                 return NULL;
3105         }
3106
3107         if (!strncasecmp("all", word, wordlen) && ++which > state) {
3108                 return ast_strdup("all");
3109         }
3110
3111         if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3112                 return ast_strdup("participants");
3113         }
3114
3115         {
3116                 SCOPED_AO2LOCK(bridge_lock, conference);
3117                 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3118                         if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3119                                 res = ast_strdup(ast_channel_name(user->chan));
3120                                 return res;
3121                         }
3122                 }
3123                 AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3124                         if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3125                                 res = ast_strdup(ast_channel_name(user->chan));
3126                                 return res;
3127                         }
3128                 }
3129         }
3130
3131         return NULL;
3132 }
3133
3134 static char *handle_cli_confbridge_kick(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3135 {
3136         struct confbridge_conference *conference;
3137         int not_found;
3138
3139         switch (cmd) {
3140         case CLI_INIT:
3141                 e->command = "confbridge kick";
3142                 e->usage =
3143                         "Usage: confbridge kick <conference> <channel>\n"
3144                         "       K