2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2011, Digium, Inc.
6 * David Vossel <dvossel@digium.com>
7 * Joshua Colp <jcolp@digium.com>
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.
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.
25 #include "asterisk/app.h"
26 #include "asterisk/logger.h"
27 #include "asterisk/linkedlists.h"
28 #include "asterisk/channel.h"
29 #include "asterisk/bridge.h"
30 #include "asterisk/bridge_features.h"
31 #include "conf_state.h"
33 /* Maximum length of a conference bridge name */
34 #define MAX_CONF_NAME AST_MAX_EXTENSION
35 /* Maximum length of a conference pin */
37 /* Maximum length of bridge/user/menu profile names */
38 #define MAX_PROFILE_NAME 128
40 #define DEFAULT_USER_PROFILE "default_user"
41 #define DEFAULT_BRIDGE_PROFILE "default_bridge"
42 #define DEFAULT_MENU_PROFILE "default_menu"
44 #define DEFAULT_TALKING_THRESHOLD 160
45 #define DEFAULT_SILENCE_THRESHOLD 2500
47 enum user_profile_flags {
48 USER_OPT_ADMIN = (1 << 0), /*!< Set if the caller is an administrator */
49 USER_OPT_NOONLYPERSON = (1 << 1), /*!< Set if the "you are currently the only person in this conference" sound file should not be played */
50 USER_OPT_MARKEDUSER = (1 << 2), /*!< Set if the caller is a marked user */
51 USER_OPT_STARTMUTED = (1 << 3), /*!< Set if the caller should be initially set muted */
52 USER_OPT_MUSICONHOLD = (1 << 4), /*!< Set if music on hold should be played if nobody else is in the conference bridge */
53 USER_OPT_QUIET = (1 << 5), /*!< Set if no audio prompts should be played */
54 USER_OPT_ANNOUNCEUSERCOUNT = (1 << 6), /*!< Set if the number of users should be announced to the caller */
55 USER_OPT_WAITMARKED = (1 << 7), /*!< Set if the user must wait for a marked user before starting */
56 USER_OPT_ENDMARKED = (1 << 8), /*!< Set if the user should be kicked after the last Marked user exits */
57 USER_OPT_DENOISE = (1 << 9), /*!< Sets if denoise filter should be used on audio before mixing. */
58 USER_OPT_ANNOUNCE_JOIN_LEAVE = (1 << 10), /*!< Sets if the user's name should be recorded and announced on join and leave. */
59 USER_OPT_TALKER_DETECT = (1 << 11), /*!< Sets if start and stop talking events should generated for this user over AMI. */
60 USER_OPT_DROP_SILENCE = (1 << 12), /*!< Sets if silence should be dropped from the mix or not. */
61 USER_OPT_DTMF_PASS = (1 << 13), /*!< Sets if dtmf should be passed into the conference or not */
62 USER_OPT_ANNOUNCEUSERCOUNTALL = (1 << 14), /*!< Sets if the number of users should be announced to everyone. */
63 USER_OPT_JITTERBUFFER = (1 << 15), /*!< Places a jitterbuffer on the user. */
64 USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW = (1 << 16), /*!< modifies ANNOUNCE_JOIN_LEAVE - user reviews the recording before continuing */
67 enum bridge_profile_flags {
68 BRIDGE_OPT_RECORD_CONFERENCE = (1 << 0), /*!< Set if the conference should be recorded */
69 BRIDGE_OPT_VIDEO_SRC_LAST_MARKED = (1 << 1), /*!< Set if conference should feed video of last marked user to all participants. */
70 BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED = (1 << 2), /*!< Set if conference should feed video of first marked user to all participants. */
71 BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER = (1 << 3), /*!< Set if conference set the video feed to follow the loudest talker. */
72 BRIDGE_OPT_RECORD_FILE_APPEND = (1 << 4), /*!< Set if the record file should be appended to between start/stops. */
73 BRIDGE_OPT_RECORD_FILE_TIMESTAMP = (1 << 5), /*< Set if the record file should have a timestamp appended */
76 enum conf_menu_action_id {
77 MENU_ACTION_TOGGLE_MUTE = 1,
79 MENU_ACTION_PLAYBACK_AND_CONTINUE,
80 MENU_ACTION_INCREASE_LISTENING,
81 MENU_ACTION_DECREASE_LISTENING,
82 MENU_ACTION_RESET_LISTENING,
83 MENU_ACTION_RESET_TALKING,
84 MENU_ACTION_INCREASE_TALKING,
85 MENU_ACTION_DECREASE_TALKING,
86 MENU_ACTION_DIALPLAN_EXEC,
87 MENU_ACTION_ADMIN_TOGGLE_LOCK,
88 MENU_ACTION_ADMIN_KICK_LAST,
91 MENU_ACTION_SET_SINGLE_VIDEO_SRC,
92 MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC,
93 MENU_ACTION_PARTICIPANT_COUNT,
94 MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS,
97 /*! The conference menu action contains both
98 * the action id that represents the action that
99 * must take place, along with any data associated
100 * with that action. */
101 struct conf_menu_action {
102 enum conf_menu_action_id id;
104 char playback_file[PATH_MAX];
106 char context[AST_MAX_CONTEXT];
107 char exten[AST_MAX_EXTENSION];
111 AST_LIST_ENTRY(conf_menu_action) action;
114 /*! Conference menu entries contain the DTMF sequence
115 * and the list of actions that are associated with that
117 struct conf_menu_entry {
118 /*! the DTMF sequence that triggers the actions */
119 char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
120 /*! The actions associated with this menu entry. */
121 AST_LIST_HEAD_NOLOCK(, conf_menu_action) actions;
122 AST_LIST_ENTRY(conf_menu_entry) entry;
125 /*! Conference menu structure. Contains a list
126 * of DTMF sequences coupled with the actions those
127 * sequences invoke.*/
129 char name[MAX_PROFILE_NAME];
130 AST_LIST_HEAD_NOLOCK(, conf_menu_entry) entries;
133 struct user_profile {
134 char name[MAX_PROFILE_NAME];
137 char announcement[PATH_MAX];
139 unsigned int announce_user_count_all_after;
140 /*! The time in ms of talking before a user is considered to be talking by the dsp. */
141 unsigned int talking_threshold;
142 /*! The time in ms of silence before a user is considered to be silent by the dsp. */
143 unsigned int silence_threshold;
147 CONF_SOUND_HAS_JOINED,
153 CONF_SOUND_THERE_ARE,
154 CONF_SOUND_OTHER_IN_PARTY,
155 CONF_SOUND_PLACE_IN_CONF,
156 CONF_SOUND_WAIT_FOR_LEADER,
157 CONF_SOUND_LEADER_HAS_LEFT,
159 CONF_SOUND_INVALID_PIN,
160 CONF_SOUND_ONLY_PERSON,
162 CONF_SOUND_LOCKED_NOW,
163 CONF_SOUND_UNLOCKED_NOW,
164 CONF_SOUND_ERROR_MENU,
167 CONF_SOUND_PARTICIPANTS_MUTED,
168 CONF_SOUND_PARTICIPANTS_UNMUTED,
172 struct bridge_profile_sounds {
173 AST_DECLARE_STRING_FIELDS(
174 AST_STRING_FIELD(hasjoin);
175 AST_STRING_FIELD(hasleft);
176 AST_STRING_FIELD(kicked);
177 AST_STRING_FIELD(muted);
178 AST_STRING_FIELD(unmuted);
179 AST_STRING_FIELD(onlyone);
180 AST_STRING_FIELD(thereare);
181 AST_STRING_FIELD(otherinparty);
182 AST_STRING_FIELD(placeintoconf);
183 AST_STRING_FIELD(waitforleader);
184 AST_STRING_FIELD(leaderhasleft);
185 AST_STRING_FIELD(getpin);
186 AST_STRING_FIELD(invalidpin);
187 AST_STRING_FIELD(onlyperson);
188 AST_STRING_FIELD(locked);
189 AST_STRING_FIELD(lockednow);
190 AST_STRING_FIELD(unlockednow);
191 AST_STRING_FIELD(errormenu);
192 AST_STRING_FIELD(leave);
193 AST_STRING_FIELD(join);
194 AST_STRING_FIELD(participantsmuted);
195 AST_STRING_FIELD(participantsunmuted);
196 AST_STRING_FIELD(begin);
200 struct bridge_profile {
201 char name[MAX_PROFILE_NAME];
202 char language[MAX_LANGUAGE]; /*!< Language used for playback_chan */
203 char rec_file[PATH_MAX];
204 char rec_options[128];
205 char rec_command[128];
207 unsigned int max_members; /*!< The maximum number of participants allowed in the conference */
208 unsigned int internal_sample_rate; /*!< The internal sample rate of the bridge. 0 when set to auto adjust mode. */
209 unsigned int mix_interval; /*!< The internal mixing interval used by the bridge. When set to 0 the bridgewill use a default interval. */
210 struct bridge_profile_sounds *sounds;
213 /*! \brief The structure that represents a conference bridge */
214 struct confbridge_conference {
215 char name[MAX_CONF_NAME]; /*!< Name of the conference bridge */
216 struct confbridge_state *state; /*!< Conference state information */
217 struct ast_bridge *bridge; /*!< Bridge structure doing the mixing */
218 struct bridge_profile b_profile; /*!< The Bridge Configuration Profile */
219 unsigned int activeusers; /*!< Number of active users present */
220 unsigned int markedusers; /*!< Number of marked users present */
221 unsigned int waitingusers; /*!< Number of waiting users present */
222 unsigned int locked:1; /*!< Is this conference bridge locked? */
223 unsigned int muted:1; /*!< Is this conference bridge muted? */
224 struct ast_channel *playback_chan; /*!< Channel used for playback into the conference bridge */
225 struct ast_channel *record_chan; /*!< Channel used for recording the conference */
226 struct ast_str *record_filename; /*!< Recording filename. */
227 struct ast_str *orig_rec_file; /*!< Previous b_profile.rec_file. */
228 ast_mutex_t playback_lock; /*!< Lock used for playback channel */
229 AST_LIST_HEAD_NOLOCK(, confbridge_user) active_list; /*!< List of users participating in the conference bridge */
230 AST_LIST_HEAD_NOLOCK(, confbridge_user) waiting_list; /*!< List of users waiting to join the conference bridge */
233 extern struct ao2_container *conference_bridges;
235 struct post_join_action {
236 int (*func)(struct confbridge_user *user);
237 AST_LIST_ENTRY(post_join_action) list;
240 /*! \brief The structure that represents a conference bridge user */
241 struct confbridge_user {
242 struct confbridge_conference *conference; /*!< Conference bridge they are participating in */
243 struct bridge_profile b_profile; /*!< The Bridge Configuration Profile */
244 struct user_profile u_profile; /*!< The User Configuration Profile */
245 char menu_name[MAX_PROFILE_NAME]; /*!< The name of the DTMF menu assigned to this user */
246 char name_rec_location[PATH_MAX]; /*!< Location of the User's name recorded file if it exists */
247 struct ast_channel *chan; /*!< Asterisk channel participating */
248 struct ast_bridge_features features; /*!< Bridge features structure */
249 struct ast_bridge_tech_optimizations tech_args; /*!< Bridge technology optimizations for talk detection */
250 unsigned int suspended_moh; /*!< Count of active suspended MOH actions. */
251 unsigned int muted:1; /*!< Has the user requested to be muted? */
252 unsigned int kicked:1; /*!< User has been kicked from the conference */
253 unsigned int playing_moh:1; /*!< MOH is currently being played to the user */
254 AST_LIST_HEAD_NOLOCK(, post_join_action) post_join_list; /*!< List of sounds to play after joining */;
255 AST_LIST_ENTRY(confbridge_user) list; /*!< Linked list information */
258 /*! \brief load confbridge.conf file */
259 int conf_load_config(void);
261 /*! \brief reload confbridge.conf file */
262 int conf_reload_config(void);
264 /*! \brief destroy the information loaded from the confbridge.conf file*/
265 void conf_destroy_config(void);
268 * \brief find a user profile given a user profile's name and store
269 * that profile in result structure.
271 * \param chan channel the user profile is requested for
272 * \param user_profile_name name of the profile requested (optional)
273 * \param result data contained by the user profile will be copied to this struct pointer
275 * \details If user_profile_name is not provided, this function will
276 * check for the presence of a user profile set by the CONFBRIDGE
277 * function on a channel datastore. If that doesn't exist, the
278 * default_user profile is used.
280 * \retval user profile on success
281 * \retval NULL on failure
283 const struct user_profile *conf_find_user_profile(struct ast_channel *chan, const char *user_profile_name, struct user_profile *result);
286 * \brief Find a bridge profile given a bridge profile's name and store
287 * that profile in result structure.
289 * \param chan channel the bridge profile is requested for
290 * \param bridge_profile_name name of the profile requested (optional)
291 * \param result data contained by the bridge profile will be copied to this struct pointer
293 * \details If bridge_profile_name is not provided, this function will
294 * check for the presence of a bridge profile set by the CONFBRIDGE
295 * function on a channel datastore. If that doesn't exist, the
296 * default_bridge profile is used.
298 * \retval bridge profile on success
299 * \retval NULL on failure
301 const struct bridge_profile *conf_find_bridge_profile(struct ast_channel *chan, const char *bridge_profile_name, struct bridge_profile *result);
304 * \brief find a menu profile given a menu profile's name and apply
305 * the menu in DTMF hooks.
307 * \param chan channel the menu profile is requested for
308 * \param user user profile the menu is being applied to
309 * \param menu_profile_name name of the profile requested (optional)
311 * \details If menu_profile_name is not provided, this function will
312 * check for the presence of a menu profile set by the CONFBRIDGE
313 * function on a channel datastore. If that doesn't exist, the
314 * default_menu profile is used.
316 * \retval 0 on success
317 * \retval -1 on failure
319 int conf_set_menu_to_user(struct ast_channel *chan, struct confbridge_user *user, const char *menu_profile_name);
322 * \brief Destroy a bridge profile found by 'conf_find_bridge_profile'
324 void conf_bridge_profile_destroy(struct bridge_profile *b_profile);
327 * \brief copies a bridge profile
328 * \note conf_bridge_profile_destroy must be called on the dst structure
330 void conf_bridge_profile_copy(struct bridge_profile *dst, struct bridge_profile *src);
333 * \brief Finds a menu_entry in a menu structure matched by DTMF sequence.
335 * \note the menu entry found must be destroyed using conf_menu_entry_destroy()
337 * \retval 1 success, entry is found and stored in result
338 * \retval 0 failure, no entry found for given DTMF sequence
340 int conf_find_menu_entry_by_sequence(const char *dtmf_sequence, struct conf_menu *menu, struct conf_menu_entry *result);
343 * \brief Destroys and frees all the actions stored in a menu_entry structure
345 void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry);
348 * \brief Once a DTMF sequence matches a sequence in the user's DTMF menu, this function will get
349 * called to perform the menu action.
351 * \param bridge_channel Bridged channel this is involving
352 * \param user the conference user to perform the action on.
353 * \param menu_entry the menu entry that invoked this callback to occur.
354 * \param menu an AO2 referenced pointer to the entire menu structure the menu_entry
357 * \note The menu_entry is a deep copy of the entry found in the menu structure. This allows
358 * for the menu_entry to be accessed without requiring the menu lock. If the menu must
359 * be accessed, the menu lock must be held. Reference counting of the menu structure is
360 * handled outside of the scope of this function.
365 int conf_handle_dtmf(
366 struct ast_bridge_channel *bridge_channel,
367 struct confbridge_user *user,
368 struct conf_menu_entry *menu_entry,
369 struct conf_menu *menu);
372 /*! \brief Looks to see if sound file is stored in bridge profile sounds, if not
373 * default sound is provided.*/
374 const char *conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds);
376 int func_confbridge_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value);
379 * \brief Play sound file into conference bridge
381 * \param conference The conference bridge to play sound file into
382 * \param filename Sound file to play
387 int play_sound_file(struct confbridge_conference *conference, const char *filename);
389 /*! \brief Callback to be called when the conference has become empty
390 * \param conference The conference bridge
392 void conf_ended(struct confbridge_conference *conference);
395 * \brief Update the actual mute status of the user and set it on the bridge.
397 * \param user User to update the mute status.
401 void conf_update_user_mute(struct confbridge_user *user);
404 * \brief Stop MOH for the conference user.
406 * \param user Conference user to stop MOH on.
410 void conf_moh_stop(struct confbridge_user *user);
413 * \brief Start MOH for the conference user.
415 * \param user Conference user to start MOH on.
419 void conf_moh_start(struct confbridge_user *user);
421 /*! \brief Attempt to mute/play MOH to the only user in the conference if they require it
422 * \param conference A conference bridge containing a single user
424 void conf_mute_only_active(struct confbridge_conference *conference);
426 /*! \brief Callback to execute any time we transition from zero to one active users
427 * \param conference The conference bridge with a single active user joined
431 void conf_handle_first_join(struct confbridge_conference *conference);
433 /*! \brief Handle actions every time a waitmarked user joins w/o a marked user present
434 * \param user The waitmarked user
438 int conf_handle_inactive_waitmarked(struct confbridge_user *user);
440 /*! \brief Handle actions whenever an unmarked user joins an inactive conference
441 * \note These actions seem like they could apply just as well to a marked user
442 * and possibly be made to happen any time transitioning to a single state.
444 * \param user The unmarked user
446 int conf_handle_only_unmarked(struct confbridge_user *user);
448 /*! \brief Handle when a conference moves to having more than one active participant
449 * \param conference The conference bridge with more than one active participant
451 void conf_handle_second_active(struct confbridge_conference *conference);
453 /*! \brief Add a conference bridge user as an unmarked active user of the conference
454 * \param conference The conference bridge to add the user to
455 * \param user The conference bridge user to add to the conference
457 void conf_add_user_active(struct confbridge_conference *conference, struct confbridge_user *user);
459 /*! \brief Add a conference bridge user as a marked active user of the conference
460 * \param conference The conference bridge to add the user to
461 * \param user The conference bridge user to add to the conference
463 void conf_add_user_marked(struct confbridge_conference *conference, struct confbridge_user *user);
465 /*! \brief Add a conference bridge user as an waiting user of the conference
466 * \param conference The conference bridge to add the user to
467 * \param user The conference bridge user to add to the conference
469 void conf_add_user_waiting(struct confbridge_conference *conference, struct confbridge_user *user);
471 /*! \brief Remove a conference bridge user from the unmarked active conference users in the conference
472 * \param conference The conference bridge to remove the user from
473 * \param user The conference bridge user to remove from the conference
475 void conf_remove_user_active(struct confbridge_conference *conference, struct confbridge_user *user);
477 /*! \brief Remove a conference bridge user from the marked active conference users in the conference
478 * \param conference The conference bridge to remove the user from
479 * \param user The conference bridge user to remove from the conference
481 void conf_remove_user_marked(struct confbridge_conference *conference, struct confbridge_user *user);
483 /*! \brief Remove a conference bridge user from the waiting conference users in the conference
484 * \param conference The conference bridge to remove the user from
485 * \param user The conference bridge user to remove from the conference
487 void conf_remove_user_waiting(struct confbridge_conference *conference, struct confbridge_user *user);
489 /*! \brief Queue a function to run with the given conference bridge user as an argument once the state transition is complete
490 * \param user The conference bridge user to pass to the function
491 * \param func The function to queue
493 * \retval non-zero failure
495 int conf_add_post_join_action(struct confbridge_user *user, int (*func)(struct confbridge_user *user));
499 * \brief get the confbridge start stasis message type
501 * \retval stasis message type for confbridge start messages if it's available
502 * \retval NULL if it isn't
504 struct stasis_message_type *confbridge_start_type(void);
508 * \brief get the confbridge end stasis message type
510 * \retval stasis message type for confbridge end messages if it's available
511 * \retval NULL if it isn't
513 struct stasis_message_type *confbridge_end_type(void);
517 * \brief get the confbridge join stasis message type
519 * \retval stasis message type for confbridge join messages if it's available
520 * \retval NULL if it isn't
522 struct stasis_message_type *confbridge_join_type(void);
526 * \brief get the confbridge leave stasis message type
528 * \retval stasis message type for confbridge leave messages if it's available
529 * \retval NULL if it isn't
531 struct stasis_message_type *confbridge_leave_type(void);
535 * \brief get the confbridge start_record stasis message type
537 * \retval stasis message type for confbridge start_record messages if it's available
538 * \retval NULL if it isn't
540 struct stasis_message_type *confbridge_start_record_type(void);
544 * \brief get the confbridge stop_record stasis message type
546 * \retval stasis message type for confbridge stop_record messages if it's available
547 * \retval NULL if it isn't
549 struct stasis_message_type *confbridge_stop_record_type(void);
553 * \brief get the confbridge mute stasis message type
555 * \retval stasis message type for confbridge mute messages if it's available
556 * \retval NULL if it isn't
558 struct stasis_message_type *confbridge_mute_type(void);
562 * \brief get the confbridge unmute stasis message type
564 * \retval stasis message type for confbridge unmute messages if it's available
565 * \retval NULL if it isn't
567 struct stasis_message_type *confbridge_unmute_type(void);
571 * \brief get the confbridge talking stasis message type
573 * \retval stasis message type for confbridge talking messages if it's available
574 * \retval NULL if it isn't
576 struct stasis_message_type *confbridge_talking_type(void);
580 * \brief register stasis message routers to handle manager events for confbridge messages
583 * \retval non-zero failure
585 int manager_confbridge_init(void);
589 * \brief unregister stasis message routers to handle manager events for confbridge messages
591 void manager_confbridge_shutdown(void);
594 * \brief Get ConfBridge record channel technology struct.
597 * \return ConfBridge record channel technology.
599 struct ast_channel_tech *conf_record_get_tech(void);
602 * \brief Get ConfBridge announce channel technology struct.
605 * \return ConfBridge announce channel technology.
607 struct ast_channel_tech *conf_announce_get_tech(void);
610 * \brief Remove the announcer channel from the conference.
613 * \param chan Either channel in the announcer channel pair.
617 void conf_announce_channel_depart(struct ast_channel *chan);
620 * \brief Push the announcer channel into the conference.
623 * \param ast Either channel in the announcer channel pair.
625 * \retval 0 on success.
626 * \retval -1 on error.
628 int conf_announce_channel_push(struct ast_channel *ast);