Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Functions | Variables
app_confbridge.c File Reference

Conference Bridge application. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include "asterisk/cli.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/bridge.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/audiohook.h"
#include "asterisk/astobj2.h"
#include "confbridge/include/confbridge.h"
#include "asterisk/paths.h"
#include "asterisk/manager.h"
#include "asterisk/test.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/json.h"
#include "asterisk/format_cache.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/stream.h"
#include "asterisk/message.h"
Include dependency graph for app_confbridge.c:

Go to the source code of this file.

Data Structures

struct  async_datastore_data
 
struct  async_delete_name_rec_task_data
 
struct  async_playback_task_data
 
struct  confbridge_hook_data
 
struct  hangup_data
 
struct  playback_task_data
 

Macros

#define CONFERENCE_BRIDGE_BUCKETS   53
 
#define RECORD_FILENAME_INITIAL_SPACE   128
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int action_confbridgekick (struct mansession *s, const struct message *m)
 
static int action_confbridgelist (struct mansession *s, const struct message *m)
 
static int action_confbridgelist_item (struct mansession *s, const char *id_text, struct confbridge_conference *conference, struct confbridge_user *user, int waiting)
 
static int action_confbridgelistrooms (struct mansession *s, const struct message *m)
 
static int action_confbridgelock (struct mansession *s, const struct message *m)
 
static int action_confbridgemute (struct mansession *s, const struct message *m)
 
static int action_confbridgesetsinglevideosrc (struct mansession *s, const struct message *m)
 
static int action_confbridgestartrecord (struct mansession *s, const struct message *m)
 
static int action_confbridgestoprecord (struct mansession *s, const struct message *m)
 
static int action_confbridgeunlock (struct mansession *s, const struct message *m)
 
static int action_confbridgeunmute (struct mansession *s, const struct message *m)
 
static int action_dialplan_exec (struct ast_bridge_channel *bridge_channel, struct conf_menu_action *menu_action)
 
static int action_kick_last (struct confbridge_conference *conference, struct ast_bridge_channel *bridge_channel, struct confbridge_user *user)
 
static int action_lock_unlock_helper (struct mansession *s, const struct message *m, int lock)
 
static int action_mute_unmute_helper (struct mansession *s, const struct message *m, int mute)
 
static int action_playback (struct ast_bridge_channel *bridge_channel, const char *playback_file)
 
static int action_playback_and_continue (struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel, struct conf_menu *menu, const char *playback_file, const char *cur_dtmf, int *stop_prompts)
 
static int action_toggle_binaural (struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
 
static int action_toggle_mute (struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
 
static int action_toggle_mute_participants (struct confbridge_conference *conference, struct confbridge_user *user)
 
static int alloc_playback_chan (struct confbridge_conference *conference)
 
static int announce_user_count (struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
 Announce number of users in the conference bridge to the caller. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct async_datastore_dataasync_datastore_data_alloc (void)
 
static void async_datastore_data_destroy (void *data)
 
static int async_delete_name_rec (struct confbridge_conference *conference, const char *filename)
 
static int async_delete_name_rec_task (void *data)
 Delete user's name file asynchronously. More...
 
static struct async_delete_name_rec_task_dataasync_delete_name_rec_task_data_alloc (struct confbridge_conference *conference, const char *filename)
 
static void async_delete_name_rec_task_data_destroy (struct async_delete_name_rec_task_data *atd)
 
int async_play_sound_file (struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
 Play sound file into conference bridge asynchronously. More...
 
static int async_play_sound_helper (struct confbridge_conference *conference, const char *filename, int say_number, struct ast_channel *initiator)
 
void async_play_sound_ready (struct ast_channel *chan)
 Indicate the initiator of an async sound file is ready for it to play. More...
 
static int async_playback_task (void *data)
 Play an announcement into a confbridge asynchronously. More...
 
static struct async_playback_task_dataasync_playback_task_data_alloc (struct confbridge_conference *conference, const char *filename, int say_number, struct ast_channel *initiator)
 
static void async_playback_task_data_destroy (struct async_playback_task_data *aptd)
 
static int cli_mute_unmute_helper (int mute, struct ast_cli_args *a)
 
static char * complete_confbridge_name (const char *line, const char *word, int pos, int state)
 
static char * complete_confbridge_participant (const char *conference_name, const char *line, const char *word, int pos, int state)
 
int conf_add_post_join_action (struct confbridge_user *user, int(*func)(struct confbridge_user *user))
 Queue a function to run with the given conference bridge user as an argument once the state transition is complete. More...
 
void conf_add_user_active (struct confbridge_conference *conference, struct confbridge_user *user)
 Add a conference bridge user as an unmarked active user of the conference. More...
 
void conf_add_user_marked (struct confbridge_conference *conference, struct confbridge_user *user)
 Add a conference bridge user as a marked active user of the conference. More...
 
void conf_add_user_waiting (struct confbridge_conference *conference, struct confbridge_user *user)
 Add a conference bridge user as an waiting user of the conference. More...
 
void conf_ended (struct confbridge_conference *conference)
 Callback to be called when the conference has become empty. More...
 
struct confbridge_conferenceconf_find_bridge (const char *conference_name)
 Find a confbridge by name. More...
 
static int conf_get_pin (struct ast_channel *chan, struct confbridge_user *user)
 
const char * conf_get_sound (enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
 Looks to see if sound file is stored in bridge profile sounds, if not default sound is provided. More...
 
int conf_handle_dtmf (struct ast_bridge_channel *bridge_channel, struct confbridge_user *user, struct conf_menu_entry *menu_entry, struct conf_menu *menu)
 Once a DTMF sequence matches a sequence in the user's DTMF menu, this function will get called to perform the menu action. More...
 
void conf_handle_first_join (struct confbridge_conference *conference)
 Callback to execute any time we transition from zero to one active users. More...
 
int conf_handle_inactive_waitmarked (struct confbridge_user *user)
 Handle actions every time a waitmarked user joins w/o a marked user present. More...
 
int conf_handle_only_person (struct confbridge_user *user)
 Handle actions whenever an user joins an empty conference. More...
 
void conf_handle_second_active (struct confbridge_conference *conference)
 Handle when a conference moves to having more than one active participant. More...
 
static int conf_handle_talker_cb (struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
 
static int conf_is_recording (struct confbridge_conference *conference)
 
void conf_moh_start (struct confbridge_user *user)
 Start MOH for the conference user. More...
 
void conf_moh_stop (struct confbridge_user *user)
 Stop MOH for the conference user. More...
 
static void conf_moh_suspend (struct confbridge_user *user)
 
static void conf_moh_unsuspend (struct confbridge_user *user)
 
void conf_mute_only_active (struct confbridge_conference *conference)
 Attempt to mute/play MOH to the only user in the conference if they require it. More...
 
static int conf_rec_name (struct confbridge_user *user, const char *conf_name)
 
void conf_remove_user_active (struct confbridge_conference *conference, struct confbridge_user *user)
 Remove a conference bridge user from the unmarked active conference users in the conference. More...
 
void conf_remove_user_marked (struct confbridge_conference *conference, struct confbridge_user *user)
 Remove a conference bridge user from the marked active conference users in the conference. More...
 
void conf_remove_user_waiting (struct confbridge_conference *conference, struct confbridge_user *user)
 Remove a conference bridge user from the waiting conference users in the conference. More...
 
static int conf_start_record (struct confbridge_conference *conference)
 
static int conf_stop_record (struct confbridge_conference *conference)
 
void conf_update_user_mute (struct confbridge_user *user)
 Update the actual mute status of the user and set it on the bridge. More...
 
static int confbridge_exec (struct ast_channel *chan, const char *data)
 The ConfBridge application. More...
 
void confbridge_handle_atxfer (struct ast_attended_transfer_message *msg)
 Create join/leave events for attended transfers. More...
 
static void confbridge_unlock_and_unref (void *obj)
 
static int conference_bridge_cmp_cb (void *obj, void *arg, int flags)
 Comparison function used for conference bridges container. More...
 
static int conference_bridge_hash_cb (const void *obj, const int flags)
 Hashing function used for conference bridges container. More...
 
static int confkick_exec (struct ast_channel *chan, const char *data)
 
static void destroy_conference_bridge (void *obj)
 Destroy a conference bridge. More...
 
static int execute_menu_entry (struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel, struct conf_menu_entry *menu_entry, struct conf_menu *menu)
 
static int func_confbridge_channels (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int func_confbridge_info (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int generic_lock_unlock_helper (int lock, const char *conference_name)
 
static int generic_mute_unmute_helper (int mute, const char *conference_name, const char *chan_name)
 
static void generic_mute_unmute_user (struct confbridge_conference *conference, struct confbridge_user *user, int mute)
 
static char * handle_cli_confbridge_kick (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_cli_confbridge_list_item (struct ast_cli_args *a, struct confbridge_user *user, int waiting)
 
static char * handle_cli_confbridge_lock (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_start_record (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_stop_record (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_unlock (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_confbridge_unmute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_conf_user_join (struct confbridge_user *user)
 Call the proper join event handler for the user for the conference bridge's current state. More...
 
static int handle_conf_user_leave (struct confbridge_user *user)
 Call the proper leave event handler for the user for the conference bridge's current state. More...
 
static void handle_video_on_exit (struct confbridge_conference *conference, struct ast_channel *chan)
 
static void handle_video_on_join (struct confbridge_conference *conference, struct ast_channel *chan, int marked)
 
static void hangup_data_destroy (struct hangup_data *hangup)
 
static void hangup_data_init (struct hangup_data *hangup, struct confbridge_conference *conference)
 
static int hangup_playback (void *data)
 Hang up the announcer channel. More...
 
static int is_new_rec_file (const char *rec_file, struct ast_str **orig_rec_file)
 
static int join_callback (struct ast_bridge_channel *bridge_channel, void *ignore)
 
static struct confbridge_conferencejoin_conference_bridge (const char *conference_name, struct confbridge_user *user)
 Join a conference bridge. More...
 
static int kick_conference_participant (struct confbridge_conference *conference, const char *channel)
 
static void leave_conference (struct confbridge_user *user)
 Leave a conference. More...
 
static int load_module (void)
 Load the module. More...
 
static int play_file (struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
 Playback the given filename and monitor for any dtmf interrupts. More...
 
static int play_prompt_to_user (struct confbridge_user *user, const char *filename)
 Play back an audio file to a channel. More...
 
int play_sound_file (struct confbridge_conference *conference, const char *filename)
 Play sound file into conference bridge. More...
 
static int play_sound_helper (struct confbridge_conference *conference, const char *filename, int say_number)
 
static int play_sound_number (struct confbridge_conference *conference, int say_number)
 Play number into the conference bridge. More...
 
static void playback_common (struct confbridge_conference *conference, const char *filename, int say_number)
 
static int playback_task (void *data)
 Play an announcement into a confbridge. More...
 
static void playback_task_data_destroy (struct playback_task_data *ptd)
 
static void playback_task_data_init (struct playback_task_data *ptd, struct confbridge_conference *conference, const char *filename, int say_number)
 
static int push_announcer (struct confbridge_conference *conference)
 Push the announcer channel into the bridge. More...
 
static int register_channel_tech (struct ast_channel_tech *tech)
 
static int reload (void)
 
static void send_conf_end_event (struct confbridge_conference *conference)
 
static void send_conf_start_event (struct confbridge_conference *conference)
 
static void send_conf_stasis (struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *extras, int channel_topic)
 
static void send_conf_stasis_snapshots (struct confbridge_conference *conference, struct ast_channel_snapshot *chan_snapshot, struct stasis_message_type *type, struct ast_json *extras)
 
static int send_event_hook_callback (struct ast_bridge_channel *bridge_channel, void *data)
 
static void send_join_event (struct confbridge_user *user, struct confbridge_conference *conference)
 
static void send_leave_event (struct confbridge_user *user, struct confbridge_conference *conference)
 
static void send_mute_event (struct confbridge_user *user, struct confbridge_conference *conference)
 
static void send_start_record_event (struct confbridge_conference *conference)
 
static void send_stop_record_event (struct confbridge_conference *conference)
 
static void send_unmute_event (struct confbridge_user *user, struct confbridge_conference *conference)
 
static void set_rec_filename (struct confbridge_conference *conference, struct ast_str **filename, int is_new)
 
static int setup_async_playback_datastore (struct ast_channel *initiator)
 Prepare the async playback datastore. More...
 
static int sound_file_exists (const char *filename)
 
static int unload_module (void)
 Called when module is being unloaded. More...
 
static void unregister_channel_tech (struct ast_channel_tech *tech)
 
static int user_timeout (struct ast_bridge_channel *bridge_channel, void *ignore)
 
static void wait_for_initiator (struct ast_channel *initiator)
 Wait for the initiator of an async playback to be ready. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Conference Bridge Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, .optional_modules = "codec_speex,func_jitterbuffer", }
 
static const char app [] = "ConfBridge"
 
static const char app2 [] = "ConfKick"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_datastore_info async_datastore_info
 Datastore used for timing of async announcement playback. More...
 
static struct ast_cli_entry cli_confbridge []
 
static struct ast_custom_function confbridge_channels_function
 
static struct ast_custom_function confbridge_function
 
static struct ast_custom_function confbridge_info_function
 
struct ao2_containerconference_bridges
 Container to hold all conference bridges in progress. More...
 

Detailed Description

Conference Bridge application.

Author
Joshua Colp <jcolp@digium.com> 
David Vossel <dvossel@digium.com> 

This is a conference bridge application utilizing the bridging core.

Definition in file app_confbridge.c.

Macro Definition Documentation

◆ CONFERENCE_BRIDGE_BUCKETS

#define CONFERENCE_BRIDGE_BUCKETS   53

Number of buckets our conference bridges container can have

Definition at line 551 of file app_confbridge.c.

◆ RECORD_FILENAME_INITIAL_SPACE

#define RECORD_FILENAME_INITIAL_SPACE   128

Initial recording filename space.

Definition at line 554 of file app_confbridge.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4686 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4686 of file app_confbridge.c.

◆ action_confbridgekick()

static int action_confbridgekick ( struct mansession s,
const struct message m 
)
static

Definition at line 4219 of file app_confbridge.c.

4220{
4221 const char *conference_name = astman_get_header(m, "Conference");
4222 const char *channel = astman_get_header(m, "Channel");
4223 struct confbridge_conference *conference;
4224 int found;
4225
4226 if (ast_strlen_zero(conference_name)) {
4227 astman_send_error(s, m, "No Conference name provided.");
4228 return 0;
4229 }
4231 astman_send_error(s, m, "No active conferences.");
4232 return 0;
4233 }
4234
4235 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4236 if (!conference) {
4237 astman_send_error(s, m, "No Conference by that name found.");
4238 return 0;
4239 }
4240
4241 found = !kick_conference_participant(conference, channel);
4242 ao2_ref(conference, -1);
4243
4244 if (found) {
4245 astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4246 } else {
4247 astman_send_error(s, m, "No Channel by that name found in Conference.");
4248 }
4249 return 0;
4250}
static int kick_conference_participant(struct confbridge_conference *conference, const char *channel)
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define OBJ_KEY
Definition: astobj2.h:1151
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1969
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2001
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1630
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
The structure that represents a conference bridge.
Definition: confbridge.h:246

References ao2_container_count(), ao2_find, ao2_ref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), conference_bridges, kick_conference_participant(), and OBJ_KEY.

Referenced by load_module().

◆ action_confbridgelist()

static int action_confbridgelist ( struct mansession s,
const struct message m 
)
static

Definition at line 4051 of file app_confbridge.c.

4052{
4053 const char *actionid = astman_get_header(m, "ActionID");
4054 const char *conference_name = astman_get_header(m, "Conference");
4055 struct confbridge_user *user;
4056 struct confbridge_conference *conference;
4057 char id_text[80];
4058 int total = 0;
4059
4060 id_text[0] = '\0';
4061 if (!ast_strlen_zero(actionid)) {
4062 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
4063 }
4064 if (ast_strlen_zero(conference_name)) {
4065 astman_send_error(s, m, "No Conference name provided.");
4066 return 0;
4067 }
4069 astman_send_error(s, m, "No active conferences.");
4070 return 0;
4071 }
4072 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4073 if (!conference) {
4074 astman_send_error(s, m, "No Conference by that name found.");
4075 return 0;
4076 }
4077
4078 astman_send_listack(s, m, "Confbridge user list will follow", "start");
4079
4080 ao2_lock(conference);
4081 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4082 total += action_confbridgelist_item(s, id_text, conference, user, 0);
4083 }
4084 AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
4085 total += action_confbridgelist_item(s, id_text, conference, user, 1);
4086 }
4087 ao2_unlock(conference);
4088 ao2_ref(conference, -1);
4089
4090 astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
4092
4093 return 0;
4094}
static int action_confbridgelist_item(struct mansession *s, const char *id_text, struct confbridge_conference *conference, struct confbridge_user *user, int waiting)
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:2011
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:2047
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2055
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
static int total
Definition: res_adsi.c:970
static char user[512]
struct confbridge_conference::@94 active_list
struct confbridge_conference::@95 waiting_list
The structure that represents a conference bridge user.
Definition: confbridge.h:273
structure to hold users read from users.conf

References action_confbridgelist_item(), confbridge_conference::active_list, ao2_container_count(), ao2_find, ao2_lock, ao2_ref, ao2_unlock, AST_LIST_TRAVERSE, ast_strlen_zero(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), conference_bridges, OBJ_KEY, total, user, and confbridge_conference::waiting_list.

Referenced by load_module().

◆ action_confbridgelist_item()

static int action_confbridgelist_item ( struct mansession s,
const char *  id_text,
struct confbridge_conference conference,
struct confbridge_user user,
int  waiting 
)
static

Definition at line 4001 of file app_confbridge.c.

4002{
4003 struct ast_channel_snapshot *snapshot;
4004 struct ast_str *snap_str;
4005
4007 if (!snapshot) {
4008 return 0;
4009 }
4010
4011 snap_str = ast_manager_build_channel_state_string(snapshot);
4012 if (!snap_str) {
4013 ao2_ref(snapshot, -1);
4014 return 0;
4015 }
4016
4017 astman_append(s,
4018 "Event: ConfbridgeList\r\n"
4019 "%s"
4020 "Conference: %s\r\n"
4021 "Admin: %s\r\n"
4022 "MarkedUser: %s\r\n"
4023 "WaitMarked: %s\r\n"
4024 "EndMarked: %s\r\n"
4025 "EndMarkedAny: %s\r\n"
4026 "Waiting: %s\r\n"
4027 "Muted: %s\r\n"
4028 "Talking: %s\r\n"
4029 "AnsweredTime: %d\r\n"
4030 "%s"
4031 "\r\n",
4032 id_text,
4033 conference->name,
4039 AST_YESNO(waiting),
4040 AST_YESNO(user->muted),
4041 AST_YESNO(user->talking),
4043 ast_str_buffer(snap_str));
4044
4045 ast_free(snap_str);
4046 ao2_ref(snapshot, -1);
4047
4048 return 1;
4049}
#define ast_free(a)
Definition: astmm.h:180
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2864
@ USER_OPT_ENDMARKED
Definition: confbridge.h:60
@ USER_OPT_WAITMARKED
Definition: confbridge.h:59
@ USER_OPT_MARKEDUSER
Definition: confbridge.h:54
@ USER_OPT_ENDMARKEDANY
Definition: confbridge.h:74
@ USER_OPT_ADMIN
Definition: confbridge.h:52
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:143
Structure representing a snapshot of channel state.
Support for dynamic strings.
Definition: strings.h:623
char name[MAX_CONF_NAME]
Definition: confbridge.h:247
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ao2_ref, ast_channel_get_up_time(), ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_free, ast_manager_build_channel_state_string(), ast_str_buffer(), ast_test_flag, AST_YESNO, astman_append(), confbridge_conference::name, USER_OPT_ADMIN, USER_OPT_ENDMARKED, USER_OPT_ENDMARKEDANY, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by action_confbridgelist().

◆ action_confbridgelistrooms()

static int action_confbridgelistrooms ( struct mansession s,
const struct message m 
)
static

Definition at line 4096 of file app_confbridge.c.

4097{
4098 const char *actionid = astman_get_header(m, "ActionID");
4099 struct confbridge_conference *conference;
4100 struct ao2_iterator iter;
4101 char id_text[512] = "";
4102 int totalitems = 0;
4103
4104 if (!ast_strlen_zero(actionid)) {
4105 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
4106 }
4107
4109 astman_send_error(s, m, "No active conferences.");
4110 return 0;
4111 }
4112
4113 astman_send_listack(s, m, "Confbridge conferences will follow", "start");
4114
4115 /* Traverse the conference list */
4117 while ((conference = ao2_iterator_next(&iter))) {
4118 totalitems++;
4119
4120 ao2_lock(conference);
4121 astman_append(s,
4122 "Event: ConfbridgeListRooms\r\n"
4123 "%s"
4124 "Conference: %s\r\n"
4125 "Parties: %u\r\n"
4126 "Marked: %u\r\n"
4127 "Locked: %s\r\n"
4128 "Muted: %s\r\n"
4129 "\r\n",
4130 id_text,
4131 conference->name,
4132 conference->activeusers + conference->waitingusers,
4133 conference->markedusers,
4134 AST_YESNO(conference->locked),
4135 AST_YESNO(conference->muted));
4136 ao2_unlock(conference);
4137
4138 ao2_ref(conference, -1);
4139 }
4140 ao2_iterator_destroy(&iter);
4141
4142 /* Send final confirmation */
4143 astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
4145 return 0;
4146}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
unsigned int muted
Definition: confbridge.h:255
unsigned int activeusers
Definition: confbridge.h:251
unsigned int waitingusers
Definition: confbridge.h:253
unsigned int markedusers
Definition: confbridge.h:252
unsigned int locked
Definition: confbridge.h:254

References confbridge_conference::activeusers, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_strlen_zero(), AST_YESNO, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), conference_bridges, confbridge_conference::locked, confbridge_conference::markedusers, confbridge_conference::muted, confbridge_conference::name, and confbridge_conference::waitingusers.

Referenced by load_module().

◆ action_confbridgelock()

static int action_confbridgelock ( struct mansession s,
const struct message m 
)
static

Definition at line 4214 of file app_confbridge.c.

4215{
4216 return action_lock_unlock_helper(s, m, 1);
4217}
static int action_lock_unlock_helper(struct mansession *s, const struct message *m, int lock)

References action_lock_unlock_helper().

Referenced by load_module().

◆ action_confbridgemute()

static int action_confbridgemute ( struct mansession s,
const struct message m 
)
static

Definition at line 4185 of file app_confbridge.c.

4186{
4187 return action_mute_unmute_helper(s, m, 1);
4188}
static int action_mute_unmute_helper(struct mansession *s, const struct message *m, int mute)

References action_mute_unmute_helper().

Referenced by load_module().

◆ action_confbridgesetsinglevideosrc()

static int action_confbridgesetsinglevideosrc ( struct mansession s,
const struct message m 
)
static

Definition at line 4331 of file app_confbridge.c.

4332{
4333 const char *conference_name = astman_get_header(m, "Conference");
4334 const char *channel = astman_get_header(m, "Channel");
4335 struct confbridge_user *user;
4336 struct confbridge_conference *conference;
4337
4338 if (ast_strlen_zero(conference_name)) {
4339 astman_send_error(s, m, "No Conference name provided.");
4340 return 0;
4341 }
4342 if (ast_strlen_zero(channel)) {
4343 astman_send_error(s, m, "No channel name provided.");
4344 return 0;
4345 }
4347 astman_send_error(s, m, "No active conferences.");
4348 return 0;
4349 }
4350
4351 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4352 if (!conference) {
4353 astman_send_error(s, m, "No Conference by that name found.");
4354 return 0;
4355 }
4356
4357 /* find channel and set as video src. */
4358 ao2_lock(conference);
4359 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4360 if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4362 break;
4363 }
4364 }
4365 ao2_unlock(conference);
4366 ao2_ref(conference, -1);
4367
4368 /* do not access user after conference unlock. We are just
4369 * using this check to see if it was found or not */
4370 if (!user) {
4371 astman_send_error(s, m, "No channel by that name found in conference.");
4372 return 0;
4373 }
4374 astman_send_ack(s, m, "Conference single video source set.");
4375 return 0;
4376}
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
Set a bridge to feed a single video source to all participants.
Definition: bridge.c:3749
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_bridge * bridge
Definition: confbridge.h:249

References confbridge_conference::active_list, ao2_container_count(), ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_bridge_set_single_src_video_mode(), ast_channel_name(), AST_LIST_TRAVERSE, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), confbridge_conference::bridge, conference_bridges, OBJ_KEY, and user.

Referenced by load_module().

◆ action_confbridgestartrecord()

static int action_confbridgestartrecord ( struct mansession s,
const struct message m 
)
static

Definition at line 4252 of file app_confbridge.c.

4253{
4254 const char *conference_name = astman_get_header(m, "Conference");
4255 const char *recordfile = astman_get_header(m, "RecordFile");
4256 struct confbridge_conference *conference;
4257
4258 if (ast_strlen_zero(conference_name)) {
4259 astman_send_error(s, m, "No Conference name provided.");
4260 return 0;
4261 }
4263 astman_send_error(s, m, "No active conferences.");
4264 return 0;
4265 }
4266
4267 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4268 if (!conference) {
4269 astman_send_error(s, m, "No Conference by that name found.");
4270 return 0;
4271 }
4272
4273 ao2_lock(conference);
4274 if (conf_is_recording(conference)) {
4275 astman_send_error(s, m, "Conference is already being recorded.");
4276 ao2_unlock(conference);
4277 ao2_ref(conference, -1);
4278 return 0;
4279 }
4280
4281 if (!ast_strlen_zero(recordfile)) {
4282 ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4283 }
4284
4285 if (conf_start_record(conference)) {
4286 astman_send_error(s, m, "Internal error starting conference recording.");
4287 ao2_unlock(conference);
4288 ao2_ref(conference, -1);
4289 return 0;
4290 }
4291 ao2_unlock(conference);
4292
4293 ao2_ref(conference, -1);
4294 astman_send_ack(s, m, "Conference Recording Started.");
4295 return 0;
4296}
static int conf_start_record(struct confbridge_conference *conference)
static int conf_is_recording(struct confbridge_conference *conference)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char rec_file[PATH_MAX]
Definition: confbridge.h:230
struct bridge_profile b_profile
Definition: confbridge.h:250

References ao2_container_count(), ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_copy_string(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), confbridge_conference::b_profile, conf_is_recording(), conf_start_record(), conference_bridges, OBJ_KEY, and bridge_profile::rec_file.

Referenced by load_module().

◆ action_confbridgestoprecord()

static int action_confbridgestoprecord ( struct mansession s,
const struct message m 
)
static

Definition at line 4297 of file app_confbridge.c.

4298{
4299 const char *conference_name = astman_get_header(m, "Conference");
4300 struct confbridge_conference *conference;
4301
4302 if (ast_strlen_zero(conference_name)) {
4303 astman_send_error(s, m, "No Conference name provided.");
4304 return 0;
4305 }
4307 astman_send_error(s, m, "No active conferences.");
4308 return 0;
4309 }
4310
4311 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4312 if (!conference) {
4313 astman_send_error(s, m, "No Conference by that name found.");
4314 return 0;
4315 }
4316
4317 ao2_lock(conference);
4318 if (conf_stop_record(conference)) {
4319 ao2_unlock(conference);
4320 astman_send_error(s, m, "Internal error while stopping recording.");
4321 ao2_ref(conference, -1);
4322 return 0;
4323 }
4324 ao2_unlock(conference);
4325
4326 ao2_ref(conference, -1);
4327 astman_send_ack(s, m, "Conference Recording Stopped.");
4328 return 0;
4329}
static int conf_stop_record(struct confbridge_conference *conference)

References ao2_container_count(), ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), conf_stop_record(), conference_bridges, and OBJ_KEY.

Referenced by load_module().

◆ action_confbridgeunlock()

static int action_confbridgeunlock ( struct mansession s,
const struct message m 
)
static

Definition at line 4210 of file app_confbridge.c.

4211{
4212 return action_lock_unlock_helper(s, m, 0);
4213}

References action_lock_unlock_helper().

Referenced by load_module().

◆ action_confbridgeunmute()

static int action_confbridgeunmute ( struct mansession s,
const struct message m 
)
static

Definition at line 4181 of file app_confbridge.c.

4182{
4183 return action_mute_unmute_helper(s, m, 0);
4184}

References action_mute_unmute_helper().

Referenced by load_module().

◆ action_dialplan_exec()

static int action_dialplan_exec ( struct ast_bridge_channel bridge_channel,
struct conf_menu_action menu_action 
)
static

Definition at line 3155 of file app_confbridge.c.

3156{
3157 struct ast_pbx_args args;
3158 struct ast_pbx *pbx;
3159 char *exten;
3160 char *context;
3161 int priority;
3162 int res;
3163
3164 memset(&args, 0, sizeof(args));
3165 args.no_hangup_chan = 1;
3166
3167 ast_channel_lock(bridge_channel->chan);
3168
3169 /*save off*/
3170 exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3171 context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3172 priority = ast_channel_priority(bridge_channel->chan);
3173 pbx = ast_channel_pbx(bridge_channel->chan);
3174 ast_channel_pbx_set(bridge_channel->chan, NULL);
3175
3176 /*set new*/
3177 ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3178 ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3179 ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3180
3181 ast_channel_unlock(bridge_channel->chan);
3182
3183 /*execute*/
3184 res = ast_pbx_run_args(bridge_channel->chan, &args);
3185
3186 /*restore*/
3187 ast_channel_lock(bridge_channel->chan);
3188
3189 ast_channel_exten_set(bridge_channel->chan, exten);
3190 ast_channel_context_set(bridge_channel->chan, context);
3191 ast_channel_priority_set(bridge_channel->chan, priority);
3192 ast_channel_pbx_set(bridge_channel->chan, pbx);
3193
3194 ast_channel_unlock(bridge_channel->chan);
3195
3196 return res;
3197}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static int priority
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
#define ast_channel_lock(chan)
Definition: channel.h:2968
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2969
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
Definition: pbx.c:4735
#define NULL
Definition: resample.c:96
struct ast_channel * chan
Options for ast_pbx_run()
Definition: pbx.h:407
Definition: pbx.h:214
char exten[AST_MAX_EXTENSION]
Definition: confbridge.h:128
struct conf_menu_action::@88::@90 dialplan_args
char context[AST_MAX_CONTEXT]
Definition: confbridge.h:127
union conf_menu_action::@88 data
const char * args

References args, ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_lock, ast_channel_pbx(), ast_channel_pbx_set(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_unlock, ast_pbx_run_args(), ast_strdupa, ast_bridge_channel::chan, conf_menu_action::context, voicemailpwcheck::context, conf_menu_action::data, conf_menu_action::dialplan_args, conf_menu_action::exten, NULL, conf_menu_action::priority, and priority.

Referenced by execute_menu_entry().

◆ action_kick_last()

static int action_kick_last ( struct confbridge_conference conference,
struct ast_bridge_channel bridge_channel,
struct confbridge_user user 
)
static

Definition at line 3118 of file app_confbridge.c.

3121{
3122 struct confbridge_user *last_user = NULL;
3123 int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3124
3125 if (!isadmin) {
3126 play_file(bridge_channel, NULL,
3128 ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
3129 ast_channel_name(bridge_channel->chan),
3130 conference->name);
3131 return -1;
3132 }
3133
3135 last_user = AST_LIST_LAST(&conference->active_list);
3136 if (!last_user) {
3138 return 0;
3139 }
3140
3141 if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3143 play_file(bridge_channel, NULL,
3145 } else if (!last_user->kicked) {
3146 last_user->kicked = 1;
3147 pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3150 }
3151
3152 return 0;
3153}
const char * conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
Looks to see if sound file is stored in bridge profile sounds, if not default sound is provided.
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
Playback the given filename and monitor for any dtmf interrupts.
#define ast_log
Definition: astobj2.c:42
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1951
@ CONF_SOUND_ERROR_MENU
Definition: confbridge.h:187
#define LOG_WARNING
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
struct bridge_profile_sounds * sounds
Definition: confbridge.h:238
unsigned int kicked
Definition: confbridge.h:284
struct confbridge_conference * conference
Definition: confbridge.h:274
struct ast_channel * chan
Definition: confbridge.h:279
struct user_profile u_profile
Definition: confbridge.h:276

References confbridge_conference::active_list, ao2_lock, ao2_unlock, ast_bridge_remove(), ast_channel_name(), AST_LIST_LAST, ast_log, ast_test_flag, confbridge_conference::b_profile, confbridge_conference::bridge, confbridge_user::chan, ast_bridge_channel::chan, conf_get_sound(), CONF_SOUND_ERROR_MENU, confbridge_user::conference, confbridge_user::kicked, LOG_WARNING, confbridge_conference::name, NULL, pbx_builtin_setvar_helper(), play_file(), bridge_profile::sounds, confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by execute_menu_entry().

◆ action_lock_unlock_helper()

static int action_lock_unlock_helper ( struct mansession s,
const struct message m,
int  lock 
)
static

Definition at line 4190 of file app_confbridge.c.

4191{
4192 const char *conference_name = astman_get_header(m, "Conference");
4193 int res = 0;
4194
4195 if (ast_strlen_zero(conference_name)) {
4196 astman_send_error(s, m, "No Conference name provided.");
4197 return 0;
4198 }
4200 astman_send_error(s, m, "No active conferences.");
4201 return 0;
4202 }
4203 if ((res = generic_lock_unlock_helper(lock, conference_name))) {
4204 astman_send_error(s, m, "No Conference by that name found.");
4205 return 0;
4206 }
4207 astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
4208 return 0;
4209}
static int generic_lock_unlock_helper(int lock, const char *conference_name)
ast_mutex_t lock
Definition: app_sla.c:331

References ao2_container_count(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), conference_bridges, generic_lock_unlock_helper(), and lock.

Referenced by action_confbridgelock(), and action_confbridgeunlock().

◆ action_mute_unmute_helper()

static int action_mute_unmute_helper ( struct mansession s,
const struct message m,
int  mute 
)
static

Definition at line 4148 of file app_confbridge.c.

4149{
4150 const char *conference_name = astman_get_header(m, "Conference");
4151 const char *channel_name = astman_get_header(m, "Channel");
4152 int res = 0;
4153
4154 if (ast_strlen_zero(conference_name)) {
4155 astman_send_error(s, m, "No Conference name provided.");
4156 return 0;
4157 }
4158 if (ast_strlen_zero(channel_name)) {
4159 astman_send_error(s, m, "No channel name provided.");
4160 return 0;
4161 }
4163 astman_send_error(s, m, "No active conferences.");
4164 return 0;
4165 }
4166
4167 res = generic_mute_unmute_helper(mute, conference_name, channel_name);
4168
4169 if (res == -1) {
4170 astman_send_error(s, m, "No Conference by that name found.");
4171 return 0;
4172 } else if (res == -2) {
4173 astman_send_error(s, m, "No Channel by that name found in Conference.");
4174 return 0;
4175 }
4176
4177 astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
4178 return 0;
4179}
static int generic_mute_unmute_helper(int mute, const char *conference_name, const char *chan_name)

References ao2_container_count(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), conference_bridges, and generic_mute_unmute_helper().

Referenced by action_confbridgemute(), and action_confbridgeunmute().

◆ action_playback()

static int action_playback ( struct ast_bridge_channel bridge_channel,
const char *  playback_file 
)
static

Definition at line 3033 of file app_confbridge.c.

3034{
3035 char *file_copy = ast_strdupa(playback_file);
3036 char *file = NULL;
3037
3038 while ((file = ast_strsep(&file_copy, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
3039 if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
3040 ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
3041 return -1;
3042 }
3043 }
3044 return 0;
3045}
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1878
@ AST_STRSEP_TRIM
Definition: strings.h:256
@ AST_STRSEP_STRIP
Definition: strings.h:255
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835

References ast_log, ast_strdupa, ast_stream_and_wait(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, ast_bridge_channel::chan, make_ari_stubs::file, LOG_WARNING, and NULL.

Referenced by execute_menu_entry().

◆ action_playback_and_continue()

static int action_playback_and_continue ( struct confbridge_conference conference,
struct confbridge_user user,
struct ast_bridge_channel bridge_channel,
struct conf_menu menu,
const char *  playback_file,
const char *  cur_dtmf,
int *  stop_prompts 
)
static

Definition at line 3047 of file app_confbridge.c.

3054{
3055 int i;
3056 int digit = 0;
3057 char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
3058 struct conf_menu_entry new_menu_entry = { { 0, }, };
3059 char *file_copy = ast_strdupa(playback_file);
3060 char *file = NULL;
3061
3062 while ((file = ast_strsep(&file_copy, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
3063 if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
3064 ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
3065 return -1;
3066 }
3067
3068 /* now wait for more digits. */
3069 if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
3070 /* streaming finished and no DTMF was entered */
3071 continue;
3072 } else if (digit == -1) {
3073 /* error */
3074 return -1;
3075 } else {
3076 break; /* dtmf was entered */
3077 }
3078 }
3079 if (!digit) {
3080 /* streaming finished on all files and no DTMF was entered */
3081 return -1;
3082 }
3083 ast_stopstream(bridge_channel->chan);
3084
3085 /* If we get here, then DTMF has been entered, This means no
3086 * additional prompts should be played for this menu entry */
3087 *stop_prompts = 1;
3088
3089 /* If a digit was pressed during the payback, update
3090 * the dtmf string and look for a new menu entry in the
3091 * menu structure */
3092 ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
3093 for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
3094 dtmf[i] = cur_dtmf[i];
3095 if (!dtmf[i]) {
3096 dtmf[i] = (char) digit;
3097 dtmf[i + 1] = '\0';
3098 i = -1;
3099 break;
3100 }
3101 }
3102 /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
3103 * If this is the case, no new DTMF sequence should be looked for. */
3104 if (i != -1) {
3105 return 0;
3106 }
3107
3108 if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
3109 execute_menu_entry(conference,
3110 user,
3111 bridge_channel,
3112 &new_menu_entry, menu);
3113 conf_menu_entry_destroy(&new_menu_entry);
3114 }
3115 return 0;
3116}
char digit
static int execute_menu_entry(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel, struct conf_menu_entry *menu_entry, struct conf_menu *menu)
#define MAXIMUM_DTMF_FEATURE_STRING
Maximum length of a DTMF feature string.
const char * ast_channel_language(const struct ast_channel *chan)
int conf_find_menu_entry_by_sequence(const char *dtmf_sequence, struct conf_menu *menu, struct conf_menu_entry *result)
Finds a menu_entry in a menu structure matched by DTMF sequence.
void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry)
Destroys and frees all the actions stored in a menu_entry structure.
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
#define AST_DIGIT_ANY
Definition: file.h:48
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
Definition: confbridge.h:138
char dtmf[MAXIMUM_DTMF_FEATURE_STRING]
Definition: confbridge.h:140

References ast_channel_language(), ast_copy_string(), AST_DIGIT_ANY, ast_log, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, ast_waitstream(), ast_bridge_channel::chan, conf_find_menu_entry_by_sequence(), conf_menu_entry_destroy(), digit, conf_menu_entry::dtmf, execute_menu_entry(), make_ari_stubs::file, LOG_WARNING, MAXIMUM_DTMF_FEATURE_STRING, and NULL.

Referenced by execute_menu_entry().

◆ action_toggle_binaural()

static int action_toggle_binaural ( struct confbridge_conference conference,
struct confbridge_user user,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 2977 of file app_confbridge.c.

2980{
2981 unsigned int binaural;
2982 ast_bridge_channel_lock_bridge(bridge_channel);
2983 binaural = !bridge_channel->binaural_suspended;
2984 bridge_channel->binaural_suspended = binaural;
2985 ast_bridge_unlock(bridge_channel->bridge);
2986 return play_file(bridge_channel, NULL, (binaural ?
2987 conf_get_sound(CONF_SOUND_BINAURAL_OFF, user->b_profile.sounds) :
2988 conf_get_sound(CONF_SOUND_BINAURAL_ON, user->b_profile.sounds))) < 0;
2989}
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
@ CONF_SOUND_BINAURAL_ON
Definition: confbridge.h:193
@ CONF_SOUND_BINAURAL_OFF
Definition: confbridge.h:194
struct ast_bridge * bridge
Bridge this channel is participating in.
unsigned int binaural_suspended

References ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_bridge_channel::binaural_suspended, ast_bridge_channel::bridge, conf_get_sound(), CONF_SOUND_BINAURAL_OFF, CONF_SOUND_BINAURAL_ON, NULL, and play_file().

Referenced by execute_menu_entry().

◆ action_toggle_mute()

static int action_toggle_mute ( struct confbridge_conference conference,
struct confbridge_user user,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 2962 of file app_confbridge.c.

2965{
2966 int mute;
2967
2968 /* Toggle user level mute request. */
2969 mute = !user->muted;
2970 generic_mute_unmute_user(conference, user, mute);
2971
2972 return play_file(bridge_channel, NULL,
2974 conference->b_profile.sounds)) < 0;
2975}
static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
@ CONF_SOUND_UNMUTED
Definition: confbridge.h:174
@ CONF_SOUND_MUTED
Definition: confbridge.h:173

References confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_MUTED, CONF_SOUND_UNMUTED, confbridge_hook_data::conference, generic_mute_unmute_user(), NULL, play_file(), and bridge_profile::sounds.

Referenced by execute_menu_entry().

◆ action_toggle_mute_participants()

static int action_toggle_mute_participants ( struct confbridge_conference conference,
struct confbridge_user user 
)
static

Definition at line 2991 of file app_confbridge.c.

2992{
2993 struct confbridge_user *cur_user = NULL;
2994 const char *sound_to_play;
2995 int mute;
2996
2998
2999 /* Toggle bridge level mute request. */
3000 mute = !conference->muted;
3001 conference->muted = mute;
3002
3004 if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
3005 /* Set user level to bridge level mute request. */
3006 cur_user->muted = mute;
3007 conf_update_user_mute(cur_user);
3008 }
3009 }
3010
3012
3013 sound_to_play = conf_get_sound(
3016
3017 if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
3018 /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
3019 ast_stream_and_wait(user->chan, sound_to_play, "");
3020
3021 /* Announce to the group that all participants are muted */
3023 play_sound_file(conference, sound_to_play);
3025 } else {
3026 /* Playing the sound asynchronously lets the sound be heard by everyone at once */
3027 async_play_sound_file(conference, sound_to_play, user->chan);
3028 }
3029
3030 return 0;
3031}
int async_play_sound_file(struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
Play sound file into conference bridge asynchronously.
int play_sound_file(struct confbridge_conference *conference, const char *filename)
Play sound file into conference bridge.
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
@ CONF_SOUND_PARTICIPANTS_UNMUTED
Definition: confbridge.h:191
@ CONF_SOUND_PARTICIPANTS_MUTED
Definition: confbridge.h:190
char language[MAX_LANGUAGE]
Definition: confbridge.h:229
unsigned int muted
Definition: confbridge.h:283
struct confbridge_user::@98 list

References confbridge_conference::active_list, ao2_lock, ao2_unlock, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_language(), AST_LIST_TRAVERSE, ast_stream_and_wait(), ast_test_flag, async_play_sound_file(), confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_PARTICIPANTS_MUTED, CONF_SOUND_PARTICIPANTS_UNMUTED, conf_update_user_mute(), confbridge_user::conference, bridge_profile::language, confbridge_user::list, confbridge_conference::muted, confbridge_user::muted, NULL, play_sound_file(), bridge_profile::sounds, confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by execute_menu_entry().

◆ alloc_playback_chan()

static int alloc_playback_chan ( struct confbridge_conference conference)
static

Definition at line 1583 of file app_confbridge.c.

1584{
1585 struct ast_format_cap *cap;
1586 char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1587
1589 if (!cap) {
1590 return -1;
1591 }
1593 conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1594 conference->name, NULL);
1595 ao2_ref(cap, -1);
1596 if (!conference->playback_chan) {
1597 return -1;
1598 }
1599
1600 /* To make sure playback_chan has the same language as the bridge */
1601 ast_channel_lock(conference->playback_chan);
1602 ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1603 ast_channel_unlock(conference->playback_chan);
1604
1605 ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1606 ast_channel_name(conference->playback_chan), conference->name);
1607
1608 ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1609 "Confbridge/%s", conference->name);
1610 conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1611 if (!conference->playback_queue) {
1612 ast_hangup(conference->playback_chan);
1613 conference->playback_chan = NULL;
1614 return -1;
1615 }
1616 return 0;
1617}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2560
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6373
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
#define ast_debug(level,...)
Log a DEBUG message.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_channel * playback_chan
Definition: confbridge.h:256
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:262
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61

References ao2_ref, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_hangup(), ast_request(), ast_taskprocessor_build_name(), ast_taskprocessor_get(), AST_TASKPROCESSOR_MAX_NAME, confbridge_conference::b_profile, bridge_profile::language, confbridge_conference::name, NULL, confbridge_conference::playback_chan, confbridge_conference::playback_queue, and TPS_REF_DEFAULT.

Referenced by join_conference_bridge().

◆ announce_user_count()

static int announce_user_count ( struct confbridge_conference conference,
struct confbridge_user user,
struct ast_bridge_channel bridge_channel 
)
static

Announce number of users in the conference bridge to the caller.

Parameters
conferenceConference bridge to peek at
userOptional Caller
bridge_channelThe bridged channel involved
Note
if caller is NULL, the announcment will be sent to all participants in the conference.
Return values
0on success.
-1if the user hung up.

Definition at line 1076 of file app_confbridge.c.

1078{
1079 const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
1080 const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
1081 const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
1082
1083 if (conference->activeusers <= 1) {
1084 /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
1085 return 0;
1086 } else if (conference->activeusers == 2) {
1087 if (user) {
1088 /* Eep, there is one other person */
1089 if (play_file(bridge_channel, user->chan, only_one) < 0) {
1090 return -1;
1091 }
1092 } else {
1093 play_sound_file(conference, only_one);
1094 }
1095 } else {
1096 /* Alas multiple others in here */
1097 if (user) {
1098 if (ast_stream_and_wait(user->chan,
1099 there_are,
1100 "")) {
1101 return -1;
1102 }
1103 if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
1104 return -1;
1105 }
1106 if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
1107 return -1;
1108 }
1109 } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
1110 play_sound_file(conference, there_are);
1111 play_sound_number(conference, conference->activeusers - 1);
1112 play_sound_file(conference, other_in_party);
1113 }
1114 }
1115 return 0;
1116}
static int play_sound_number(struct confbridge_conference *conference, int say_number)
Play number into the conference bridge.
static int sound_file_exists(const char *filename)
@ CONF_SOUND_OTHER_IN_PARTY
Definition: confbridge.h:177
@ CONF_SOUND_THERE_ARE
Definition: confbridge.h:176
@ CONF_SOUND_ONLY_ONE
Definition: confbridge.h:175
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8257

References confbridge_conference::activeusers, ast_channel_language(), ast_say_number(), ast_stream_and_wait(), confbridge_conference::b_profile, ast_channel::bridge_channel, conf_get_sound(), CONF_SOUND_ONLY_ONE, CONF_SOUND_OTHER_IN_PARTY, CONF_SOUND_THERE_ARE, NULL, play_file(), play_sound_file(), play_sound_number(), sound_file_exists(), and bridge_profile::sounds.

Referenced by execute_menu_entry(), and join_conference_bridge().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 4686 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data * async_datastore_data_alloc ( void  )
static

Definition at line 2174 of file app_confbridge.c.

2175{
2176 struct async_datastore_data *add;
2177
2178 add = ast_malloc(sizeof(*add));
2179 if (!add) {
2180 return NULL;
2181 }
2182
2183 ast_mutex_init(&add->lock);
2184 ast_cond_init(&add->cond, NULL);
2185 add->wait = 1;
2186
2187 return add;
2188}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186

References ast_cond_init, ast_malloc, ast_mutex_init, async_datastore_data::cond, async_datastore_data::lock, NULL, and async_datastore_data::wait.

Referenced by setup_async_playback_datastore().

◆ async_datastore_data_destroy()

static void async_datastore_data_destroy ( void *  data)
static

Definition at line 2142 of file app_confbridge.c.

2143{
2144 struct async_datastore_data *add = data;
2145
2146 ast_mutex_destroy(&add->lock);
2147 ast_cond_destroy(&add->cond);
2148
2149 ast_free(add);
2150}
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_mutex_destroy(a)
Definition: lock.h:188

References ast_cond_destroy, ast_free, ast_mutex_destroy, async_datastore_data::cond, and async_datastore_data::lock.

◆ async_delete_name_rec()

static int async_delete_name_rec ( struct confbridge_conference conference,
const char *  filename 
)
static

Definition at line 2581 of file app_confbridge.c.

2583{
2585
2587 return 0;
2588 } else if (!sound_file_exists(filename)) {
2589 return 0;
2590 }
2591
2593 if (!atd) {
2594 return -1;
2595 }
2596
2598 ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2601 return -1;
2602 }
2603
2604 return 0;
2605}
static void async_delete_name_rec_task_data_destroy(struct async_delete_name_rec_task_data *atd)
static int async_delete_name_rec_task(void *data)
Delete user's name file asynchronously.
static struct async_delete_name_rec_task_data * async_delete_name_rec_task_data_alloc(struct confbridge_conference *conference, const char *filename)
struct confbridge_conference * conference
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

References ast_log, ast_strlen_zero(), ast_taskprocessor_push(), async_delete_name_rec_task(), async_delete_name_rec_task_data_alloc(), async_delete_name_rec_task_data_destroy(), async_delete_name_rec_task_data::conference, async_delete_name_rec_task_data::filename, LOG_WARNING, confbridge_conference::name, confbridge_conference::playback_queue, and sound_file_exists().

Referenced by confbridge_exec().

◆ async_delete_name_rec_task()

static int async_delete_name_rec_task ( void *  data)
static

Delete user's name file asynchronously.

This runs in the playback queue taskprocessor. This ensures that sound file is removed after playback is finished and not before.

Parameters
dataAn async_delete_name_rec_task_data
Returns
0

Definition at line 2569 of file app_confbridge.c.

2570{
2571 struct async_delete_name_rec_task_data *atd = data;
2572
2574 ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2575 atd->conference->name, atd->filename);
2576
2578 return 0;
2579}
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1141
#define LOG_DEBUG

References ast_filedelete(), ast_log, async_delete_name_rec_task_data_destroy(), async_delete_name_rec_task_data::conference, async_delete_name_rec_task_data::filename, LOG_DEBUG, confbridge_conference::name, and NULL.

Referenced by async_delete_name_rec().

◆ async_delete_name_rec_task_data_alloc()

static struct async_delete_name_rec_task_data * async_delete_name_rec_task_data_alloc ( struct confbridge_conference conference,
const char *  filename 
)
static

Definition at line 2538 of file app_confbridge.c.

2540{
2542
2543 atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2544 if (!atd) {
2545 return NULL;
2546 }
2547
2548 /* Safe */
2549 strcpy(atd->filename, filename);
2550 atd->conference = conference;
2551
2552 return atd;
2553}

References ast_malloc, async_delete_name_rec_task_data::conference, async_delete_name_rec_task_data::filename, and NULL.

Referenced by async_delete_name_rec().

◆ async_delete_name_rec_task_data_destroy()

static void async_delete_name_rec_task_data_destroy ( struct async_delete_name_rec_task_data atd)
static

Definition at line 2555 of file app_confbridge.c.

2556{
2557 ast_free(atd);
2558}

References ast_free.

Referenced by async_delete_name_rec(), and async_delete_name_rec_task().

◆ async_play_sound_file()

int async_play_sound_file ( struct confbridge_conference conference,
const char *  filename,
struct ast_channel initiator 
)

Play sound file into conference bridge asynchronously.

If the initiator parameter is non-NULL, then the playback will wait for that initiator channel to get back in the bridge before playing the sound file. This way, the initiator has no danger of hearing a "clipped" file.

Parameters
conferenceThe conference bridge to play sound file into
filenameSound file to play
initiatorChannel that initiated playback.
Return values
0success
-1failure

Definition at line 2371 of file app_confbridge.c.

2373{
2374 return async_play_sound_helper(conference, filename, -1, initiator);
2375}
static int async_play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number, struct ast_channel *initiator)

References async_play_sound_helper(), async_playback_task_data::conference, async_playback_task_data::filename, and async_playback_task_data::initiator.

Referenced by action_toggle_mute_participants(), confbridge_exec(), and leave_marked().

◆ async_play_sound_helper()

static int async_play_sound_helper ( struct confbridge_conference conference,
const char *  filename,
int  say_number,
struct ast_channel initiator 
)
static

Definition at line 2337 of file app_confbridge.c.

2339{
2340 struct async_playback_task_data *aptd;
2341
2342 /* Do not waste resources trying to play files that do not exist */
2344 if (say_number < 0) {
2345 return 0;
2346 }
2347 } else if (!sound_file_exists(filename)) {
2348 return 0;
2349 }
2350
2352 if (!aptd) {
2353 return -1;
2354 }
2355
2357 if (!ast_strlen_zero(filename)) {
2358 ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2360 } else {
2361 ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2363 }
2365 return -1;
2366 }
2367
2368 return 0;
2369}
static void async_playback_task_data_destroy(struct async_playback_task_data *aptd)
static struct async_playback_task_data * async_playback_task_data_alloc(struct confbridge_conference *conference, const char *filename, int say_number, struct ast_channel *initiator)
static int async_playback_task(void *data)
Play an announcement into a confbridge asynchronously.
struct confbridge_conference * conference
struct ast_channel * initiator

References ast_log, ast_strlen_zero(), ast_taskprocessor_push(), async_playback_task(), async_playback_task_data_alloc(), async_playback_task_data_destroy(), async_playback_task_data::conference, async_playback_task_data::filename, async_playback_task_data::initiator, LOG_WARNING, confbridge_conference::name, confbridge_conference::playback_queue, async_playback_task_data::say_number, and sound_file_exists().

Referenced by async_play_sound_file().

◆ async_play_sound_ready()

void async_play_sound_ready ( struct ast_channel chan)

Indicate the initiator of an async sound file is ready for it to play.

When playing an async sound file, the initiator is typically either out of the bridge or not in a position to hear the queued announcement. This function lets the announcement thread know that the initiator is now ready for the sound to play.

If an async announcement was queued and no initiator channel was provided, then this is a no-op

Parameters
chanThe channel that initiated the async announcement

Definition at line 2377 of file app_confbridge.c.

2378{
2379 struct ast_datastore *async_datastore;
2380 struct async_datastore_data *add;
2381
2382 ast_channel_lock(chan);
2383 async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2384 ast_channel_unlock(chan);
2385 if (!async_datastore) {
2386 return;
2387 }
2388
2389 add = async_datastore->data;
2390
2391 ast_mutex_lock(&add->lock);
2392 add->wait = 0;
2393 ast_cond_signal(&add->cond);
2394 ast_mutex_unlock(&add->lock);
2395}
static struct ast_datastore_info async_datastore_info
Datastore used for timing of async announcement playback.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2418
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, async_datastore_info, async_datastore_data::cond, ast_datastore::data, async_datastore_data::lock, NULL, and async_datastore_data::wait.

Referenced by conf_handle_dtmf(), confbridge_exec(), and join_callback().

◆ async_playback_task()

static int async_playback_task ( void *  data)
static

Play an announcement into a confbridge asynchronously.

This runs in the playback queue taskprocessor. This ensures that all playbacks are handled in sequence and do not play over top one another.

Parameters
dataAn async_playback_task_data
Returns
0

Definition at line 2322 of file app_confbridge.c.

2323{
2324 struct async_playback_task_data *aptd = data;
2325
2326 /* Wait for the initiator to get back in the bridge or be hung up */
2327 if (aptd->initiator) {
2329 }
2330
2331 playback_common(aptd->conference, aptd->filename, aptd->say_number);
2332
2334 return 0;
2335}
static void playback_common(struct confbridge_conference *conference, const char *filename, int say_number)
static void wait_for_initiator(struct ast_channel *initiator)
Wait for the initiator of an async playback to be ready.

References async_playback_task_data_destroy(), async_playback_task_data::conference, async_playback_task_data::filename, async_playback_task_data::initiator, playback_common(), async_playback_task_data::say_number, and wait_for_initiator().

Referenced by async_play_sound_helper().

◆ async_playback_task_data_alloc()

static struct async_playback_task_data * async_playback_task_data_alloc ( struct confbridge_conference conference,
const char *  filename,
int  say_number,
struct ast_channel initiator 
)
static

Definition at line 2230 of file app_confbridge.c.

2233{
2234 struct async_playback_task_data *aptd;
2235
2236 aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
2237 if (!aptd) {
2238 return NULL;
2239 }
2240
2241 /* Safe */
2242 strcpy(aptd->filename, filename);
2243 aptd->say_number = say_number;
2244
2245 /* You may think that we need to bump the conference refcount since we are pushing
2246 * this task to the taskprocessor.
2247 *
2248 * In this case, that actually causes a problem. The destructor for the conference
2249 * pushes a hangup task into the taskprocessor and waits for it to complete before
2250 * continuing. If the destructor gets called from a taskprocessor task, we're
2251 * deadlocked.
2252 *
2253 * So is there a risk of the conference being freed out from under us? No. Since
2254 * the destructor pushes a task into the taskprocessor and waits for it to complete,
2255 * the destructor cannot free the conference out from under us. No further tasks
2256 * can be queued onto the taskprocessor after the hangup since no channels are referencing
2257 * the conference at that point any more.
2258 */
2259 aptd->conference = conference;
2260
2261 aptd->initiator = initiator;
2262 if (initiator) {
2265 /* We don't really care if this fails. If the datastore fails to get set up
2266 * we'll still play the announcement. It's possible that the sound will be
2267 * clipped for the initiator, but that's not the end of the world.
2268 */
2271 }
2272
2273 return aptd;
2274}
static int setup_async_playback_datastore(struct ast_channel *initiator)
Prepare the async playback datastore.
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2993

References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_malloc, async_playback_task_data::conference, async_playback_task_data::filename, async_playback_task_data::initiator, NULL, async_playback_task_data::say_number, and setup_async_playback_datastore().

Referenced by async_play_sound_helper().

◆ async_playback_task_data_destroy()

static void async_playback_task_data_destroy ( struct async_playback_task_data aptd)
static

Definition at line 2276 of file app_confbridge.c.

2277{
2279 ast_free(aptd);
2280}
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3015

References ast_channel_cleanup, ast_free, and async_playback_task_data::initiator.

Referenced by async_play_sound_helper(), and async_playback_task().

◆ cli_mute_unmute_helper()

static int cli_mute_unmute_helper ( int  mute,
struct ast_cli_args a 
)
static

Definition at line 3670 of file app_confbridge.c.

3671{
3672 int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
3673
3674 if (res == -1) {
3675 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3676 return -1;
3677 } else if (res == -2) {
3678 if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3679 ast_cli(a->fd, "No participants found in conference %s\n", a->argv[2]);
3680 } else {
3681 ast_cli(a->fd, "No channel named '%s' found in conference %s\n", a->argv[3], a->argv[2]);
3682 }
3683 return -1;
3684 }
3685 ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
3686 return 0;
3687}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct test_val a

References a, ast_cli(), and generic_mute_unmute_helper().

Referenced by handle_cli_confbridge_mute(), and handle_cli_confbridge_unmute().

◆ complete_confbridge_name()

static char * complete_confbridge_name ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 3376 of file app_confbridge.c.

3377{
3378 int which = 0;
3379 struct confbridge_conference *conference;
3380 char *res = NULL;
3381 int wordlen = strlen(word);
3382 struct ao2_iterator iter;
3383
3385 while ((conference = ao2_iterator_next(&iter))) {
3386 if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3387 res = ast_strdup(conference->name);
3388 ao2_ref(conference, -1);
3389 break;
3390 }
3391 ao2_ref(conference, -1);
3392 }
3393 ao2_iterator_destroy(&iter);
3394
3395 return res;
3396}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
short word

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_strdup, conference_bridges, confbridge_conference::name, and NULL.

Referenced by handle_cli_confbridge_kick(), handle_cli_confbridge_list(), handle_cli_confbridge_lock(), handle_cli_confbridge_mute(), handle_cli_confbridge_start_record(), handle_cli_confbridge_stop_record(), handle_cli_confbridge_unlock(), and handle_cli_confbridge_unmute().

◆ complete_confbridge_participant()

static char * complete_confbridge_participant ( const char *  conference_name,
const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 3398 of file app_confbridge.c.

3399{
3400 int which = 0;
3401 RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3402 struct confbridge_user *user;
3403 char *res = NULL;
3404 int wordlen = strlen(word);
3405
3406 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3407 if (!conference) {
3408 return NULL;
3409 }
3410
3411 if (!strncasecmp("all", word, wordlen) && ++which > state) {
3412 return ast_strdup("all");
3413 }
3414
3415 if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3416 return ast_strdup("participants");
3417 }
3418
3419 {
3420 SCOPED_AO2LOCK(bridge_lock, conference);
3422 if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3423 res = ast_strdup(ast_channel_name(user->chan));
3424 return res;
3425 }
3426 }
3428 if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3429 res = ast_strdup(ast_channel_name(user->chan));
3430 return res;
3431 }
3432 }
3433 }
3434
3435 return NULL;
3436}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References confbridge_conference::active_list, ao2_cleanup, ao2_find, ast_channel_name(), AST_LIST_TRAVERSE, ast_strdup, confbridge_user::conference, conference_bridges, confbridge_user::list, NULL, OBJ_KEY, RAII_VAR, SCOPED_AO2LOCK, user, and confbridge_conference::waiting_list.

Referenced by handle_cli_confbridge_kick(), handle_cli_confbridge_mute(), and handle_cli_confbridge_unmute().

◆ conf_add_post_join_action()

int conf_add_post_join_action ( struct confbridge_user user,
int(*)(struct confbridge_user *user func 
)

Queue a function to run with the given conference bridge user as an argument once the state transition is complete.

Parameters
userThe conference bridge user to pass to the function
funcThe function to queue
Return values
0success
non-zerofailure

Definition at line 1532 of file app_confbridge.c.

1533{
1534 struct post_join_action *action;
1535 if (!(action = ast_calloc(1, sizeof(*action)))) {
1536 return -1;
1537 }
1538 action->func = func;
1539 AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1540 return 0;
1541}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
int(* func)(struct confbridge_user *user)
Definition: confbridge.h:268
struct post_join_action::@96 list

References ast_calloc, AST_LIST_INSERT_TAIL, post_join_action::func, and post_join_action::list.

Referenced by conf_default_join_waitmarked(), join_marked(), join_unmarked(), and transition_to_marked().

◆ conf_add_user_active()

void conf_add_user_active ( struct confbridge_conference conference,
struct confbridge_user user 
)

Add a conference bridge user as an unmarked active user of the conference.

Parameters
conferenceThe conference bridge to add the user to
userThe conference bridge user to add to the conference

Definition at line 4485 of file app_confbridge.c.

4486{
4487 AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4488 conference->activeusers++;
4489}

References confbridge_conference::active_list, confbridge_conference::activeusers, and AST_LIST_INSERT_TAIL.

Referenced by join_active(), and join_unmarked().

◆ conf_add_user_marked()

void conf_add_user_marked ( struct confbridge_conference conference,
struct confbridge_user user 
)

Add a conference bridge user as a marked active user of the conference.

Parameters
conferenceThe conference bridge to add the user to
userThe conference bridge user to add to the conference

Definition at line 4491 of file app_confbridge.c.

4492{
4493 AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4494 conference->activeusers++;
4495 conference->markedusers++;
4496}

References confbridge_conference::active_list, confbridge_conference::activeusers, AST_LIST_INSERT_TAIL, and confbridge_conference::markedusers.

Referenced by join_marked().

◆ conf_add_user_waiting()

void conf_add_user_waiting ( struct confbridge_conference conference,
struct confbridge_user user 
)

Add a conference bridge user as an waiting user of the conference.

Parameters
conferenceThe conference bridge to add the user to
userThe conference bridge user to add to the conference

Definition at line 4498 of file app_confbridge.c.

4499{
4500 AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4501 conference->waitingusers++;
4502}

References AST_LIST_INSERT_TAIL, confbridge_conference::waiting_list, and confbridge_conference::waitingusers.

Referenced by conf_default_join_waitmarked().

◆ conf_ended()

void conf_ended ( struct confbridge_conference conference)

Callback to be called when the conference has become empty.

Parameters
conferenceThe conference bridge

Definition at line 1560 of file app_confbridge.c.

1561{
1562 struct pbx_find_info q = { .stacklen = 0 };
1563
1564 /* Called with a reference to conference */
1565 ao2_unlink(conference_bridges, conference);
1566 send_conf_end_event(conference);
1567 if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1569 conference->name, 1, NULL, "", E_MATCH)) {
1571 conference->name, 1, NULL);
1572 }
1573 ao2_lock(conference);
1574 conf_stop_record(conference);
1575 ao2_unlock(conference);
1576}
static void send_conf_end_event(struct confbridge_conference *conference)
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
@ E_MATCH
Definition: extconf.h:217
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4948
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: ael_main.c:152
char regcontext[AST_MAX_CONTEXT]
Definition: confbridge.h:239
int stacklen
Definition: extconf.h:237

References ao2_lock, ao2_unlink, ao2_unlock, ast_context_remove_extension(), ast_strlen_zero(), confbridge_conference::b_profile, conf_stop_record(), conference_bridges, E_MATCH, confbridge_conference::name, NULL, pbx_find_extension(), bridge_profile::regcontext, send_conf_end_event(), and pbx_find_info::stacklen.

Referenced by transition_to_empty().

◆ conf_find_bridge()

struct confbridge_conference * conf_find_bridge ( const char *  conference_name)

Find a confbridge by name.

Since
13.22.0
15.5.0
Parameters
conference_nameThe name to search for
Returns
ConfBridge (which must be unreffed) or NULL.

Definition at line 875 of file app_confbridge.c.

876{
877 return ao2_find(conference_bridges, conference_name, OBJ_KEY);
878}

References ao2_find, conference_bridges, and OBJ_KEY.

Referenced by confbridge_publish_manager_event().

◆ conf_get_pin()

static int conf_get_pin ( struct ast_channel chan,
struct confbridge_user user 
)
static

Definition at line 2439 of file app_confbridge.c.

2440{
2441 char pin_guess[MAX_PIN+1] = { 0, };
2442 const char *pin = user->u_profile.pin;
2443 char *tmp = pin_guess;
2444 int i, res;
2445 unsigned int len = MAX_PIN;
2446
2447 /*
2448 * NOTE: We have not joined a conference yet so we have to use
2449 * the bridge profile requested by the user.
2450 */
2451
2452 /* give them three tries to get the pin right */
2453 for (i = 0; i < 3; i++) {
2454 if (ast_app_getdata(chan,
2455 conf_get_sound(CONF_SOUND_GET_PIN, user->b_profile.sounds),
2456 tmp, len, 0) >= 0) {
2457 if (!strcasecmp(pin, pin_guess)) {
2458 return 0;
2459 }
2460 }
2461 ast_streamfile(chan,
2462 conf_get_sound(CONF_SOUND_INVALID_PIN, user->b_profile.sounds),
2463 ast_channel_language(chan));
2464 res = ast_waitstream(chan, AST_DIGIT_ANY);
2465 if (res > 0) {
2466 /* Account for digit already read during ivalid pin playback
2467 * resetting pin buf. */
2468 pin_guess[0] = res;
2469 pin_guess[1] = '\0';
2470 tmp = pin_guess + 1;
2471 len = MAX_PIN - 1;
2472 } else {
2473 /* reset pin buf as empty buffer. */
2474 tmp = pin_guess;
2475 len = MAX_PIN;
2476 }
2477 }
2478 return -1;
2479}
#define MAX_PIN
Definition: app_meetme.c:828
static int tmp()
Definition: bt_open.c:389
@ CONF_SOUND_INVALID_PIN
Definition: confbridge.h:182
@ CONF_SOUND_GET_PIN
Definition: confbridge.h:181
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_getdata_result ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
Definition: main/app.c:188

References ast_app_getdata(), ast_channel_language(), AST_DIGIT_ANY, ast_streamfile(), ast_waitstream(), conf_get_sound(), CONF_SOUND_GET_PIN, CONF_SOUND_INVALID_PIN, len(), MAX_PIN, and tmp().

Referenced by confbridge_exec().

◆ conf_get_sound()

const char * conf_get_sound ( enum conf_sounds  sound,
struct bridge_profile_sounds custom_sounds 
)

Looks to see if sound file is stored in bridge profile sounds, if not default sound is provided.

Definition at line 614 of file app_confbridge.c.

615{
616 switch (sound) {
618 return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
620 return S_OR(custom_sounds->hasleft, "conf-hasleft");
622 return S_OR(custom_sounds->kicked, "conf-kicked");
623 case CONF_SOUND_MUTED:
624 return S_OR(custom_sounds->muted, "conf-muted");
626 return S_OR(custom_sounds->unmuted, "conf-unmuted");
628 return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
630 return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
632 return S_OR(custom_sounds->onlyone, "conf-onlyone");
634 return S_OR(custom_sounds->thereare, "conf-thereare");
636 return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
638 return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
640 return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
642 return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
644 return S_OR(custom_sounds->getpin, "conf-getpin");
646 return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
648 return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
650 return S_OR(custom_sounds->locked, "conf-locked");
652 return S_OR(custom_sounds->lockednow, "conf-lockednow");
654 return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
656 return S_OR(custom_sounds->errormenu, "conf-errormenu");
657 case CONF_SOUND_JOIN:
658 return S_OR(custom_sounds->join, "confbridge-join");
659 case CONF_SOUND_LEAVE:
660 return S_OR(custom_sounds->leave, "confbridge-leave");
662 return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
664 return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
665 case CONF_SOUND_BEGIN:
666 return S_OR(custom_sounds->begin, "confbridge-conf-begin");
667 }
668
669 return "";
670}
@ CONF_SOUND_JOIN
Definition: confbridge.h:188
@ CONF_SOUND_LOCKED_NOW
Definition: confbridge.h:185
@ CONF_SOUND_ONLY_PERSON
Definition: confbridge.h:183
@ CONF_SOUND_BEGIN
Definition: confbridge.h:192
@ CONF_SOUND_WAIT_FOR_LEADER
Definition: confbridge.h:179
@ CONF_SOUND_HAS_LEFT
Definition: confbridge.h:171
@ CONF_SOUND_LEAVE
Definition: confbridge.h:189
@ CONF_SOUND_LEADER_HAS_LEFT
Definition: confbridge.h:180
@ CONF_SOUND_PLACE_IN_CONF
Definition: confbridge.h:178
@ CONF_SOUND_HAS_JOINED
Definition: confbridge.h:170
@ CONF_SOUND_UNLOCKED_NOW
Definition: confbridge.h:186
@ CONF_SOUND_LOCKED
Definition: confbridge.h:184
@ CONF_SOUND_KICKED
Definition: confbridge.h:172
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
const ast_string_field waitforleader
Definition: confbridge.h:224
const ast_string_field invalidpin
Definition: confbridge.h:224
const ast_string_field placeintoconf
Definition: confbridge.h:224
const ast_string_field onlyone
Definition: confbridge.h:224
const ast_string_field otherinparty
Definition: confbridge.h:224
const ast_string_field unlockednow
Definition: confbridge.h:224
const ast_string_field binauralon
Definition: confbridge.h:224
const ast_string_field getpin
Definition: confbridge.h:224
const ast_string_field errormenu
Definition: confbridge.h:224
const ast_string_field participantsunmuted
Definition: confbridge.h:224
const ast_string_field participantsmuted
Definition: confbridge.h:224
const ast_string_field leave
Definition: confbridge.h:224
const ast_string_field locked
Definition: confbridge.h:224
const ast_string_field join
Definition: confbridge.h:224
const ast_string_field kicked
Definition: confbridge.h:224
const ast_string_field hasleft
Definition: confbridge.h:224
const ast_string_field unmuted
Definition: confbridge.h:224
const ast_string_field leaderhasleft
Definition: confbridge.h:224
const ast_string_field lockednow
Definition: confbridge.h:224
const ast_string_field hasjoin
Definition: confbridge.h:224
const ast_string_field binauraloff
Definition: confbridge.h:224
const ast_string_field onlyperson
Definition: confbridge.h:224
const ast_string_field thereare
Definition: confbridge.h:224
const ast_string_field muted
Definition: confbridge.h:224
const ast_string_field begin
Definition: confbridge.h:224

References bridge_profile_sounds::begin, bridge_profile_sounds::binauraloff, bridge_profile_sounds::binauralon, CONF_SOUND_BEGIN, CONF_SOUND_BINAURAL_OFF, CONF_SOUND_BINAURAL_ON, CONF_SOUND_ERROR_MENU, CONF_SOUND_GET_PIN, CONF_SOUND_HAS_JOINED, CONF_SOUND_HAS_LEFT, CONF_SOUND_INVALID_PIN, CONF_SOUND_JOIN, CONF_SOUND_KICKED, CONF_SOUND_LEADER_HAS_LEFT, CONF_SOUND_LEAVE, CONF_SOUND_LOCKED, CONF_SOUND_LOCKED_NOW, CONF_SOUND_MUTED, CONF_SOUND_ONLY_ONE, CONF_SOUND_ONLY_PERSON, CONF_SOUND_OTHER_IN_PARTY, CONF_SOUND_PARTICIPANTS_MUTED, CONF_SOUND_PARTICIPANTS_UNMUTED, CONF_SOUND_PLACE_IN_CONF, CONF_SOUND_THERE_ARE, CONF_SOUND_UNLOCKED_NOW, CONF_SOUND_UNMUTED, CONF_SOUND_WAIT_FOR_LEADER, bridge_profile_sounds::errormenu, bridge_profile_sounds::getpin, bridge_profile_sounds::hasjoin, bridge_profile_sounds::hasleft, bridge_profile_sounds::invalidpin, bridge_profile_sounds::join, bridge_profile_sounds::kicked, bridge_profile_sounds::leaderhasleft, bridge_profile_sounds::leave, bridge_profile_sounds::locked, bridge_profile_sounds::lockednow, bridge_profile_sounds::muted, bridge_profile_sounds::onlyone, bridge_profile_sounds::onlyperson, bridge_profile_sounds::otherinparty, bridge_profile_sounds::participantsmuted, bridge_profile_sounds::participantsunmuted, bridge_profile_sounds::placeintoconf, S_OR, bridge_profile_sounds::thereare, bridge_profile_sounds::unlockednow, bridge_profile_sounds::unmuted, and bridge_profile_sounds::waitforleader.

Referenced by action_kick_last(), action_toggle_binaural(), action_toggle_mute(), action_toggle_mute_participants(), announce_user_count(), conf_get_pin(), conf_handle_inactive_waitmarked(), conf_handle_only_person(), confbridge_exec(), execute_menu_entry(), handle_cli_confbridge_show_bridge_profile(), join_conference_bridge(), leave_marked(), and post_join_play_begin().

◆ conf_handle_dtmf()

int conf_handle_dtmf ( struct ast_bridge_channel bridge_channel,
struct confbridge_user user,
struct conf_menu_entry menu_entry,
struct conf_menu menu 
)

Once a DTMF sequence matches a sequence in the user's DTMF menu, this function will get called to perform the menu action.

Parameters
bridge_channelBridged channel this is involving
userthe conference user to perform the action on.
menu_entrythe menu entry that invoked this callback to occur.
menuan AO2 referenced pointer to the entire menu structure the menu_entry derived from.
Note
The menu_entry is a deep copy of the entry found in the menu structure. This allows for the menu_entry to be accessed without requiring the menu lock. If the menu must be accessed, the menu lock must be held. Reference counting of the menu structure is handled outside of the scope of this function.
Return values
0success
-1failure

Definition at line 3310 of file app_confbridge.c.

3314{
3315 /* See if music on hold is playing */
3317
3318 /* execute the list of actions associated with this menu entry */
3319 execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3320
3321 /* See if music on hold needs to be started back up again */
3323
3324 async_play_sound_ready(bridge_channel->chan);
3325
3326 return 0;
3327}
static void conf_moh_unsuspend(struct confbridge_user *user)
static void conf_moh_suspend(struct confbridge_user *user)
void async_play_sound_ready(struct ast_channel *chan)
Indicate the initiator of an async sound file is ready for it to play.

References async_play_sound_ready(), ast_bridge_channel::chan, conf_moh_suspend(), conf_moh_unsuspend(), and execute_menu_entry().

Referenced by menu_hook_callback().

◆ conf_handle_first_join()

void conf_handle_first_join ( struct confbridge_conference conference)

Callback to execute any time we transition from zero to one active users.

Parameters
conferenceThe conference bridge with a single active user joined

Definition at line 1544 of file app_confbridge.c.

1545{
1546 ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference->name);
1547}
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
@ AST_DEVICE_INUSE
Definition: devicestate.h:55

References AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), and confbridge_conference::name.

Referenced by join_marked(), join_unmarked(), and join_waitmarked().

◆ conf_handle_inactive_waitmarked()

int conf_handle_inactive_waitmarked ( struct confbridge_user user)

Handle actions every time a waitmarked user joins w/o a marked user present.

Parameters
userThe waitmarked user
Return values
0success
-1failure

Definition at line 1508 of file app_confbridge.c.

1509{
1510 /* If we have not been quieted play back that they are waiting for the leader */
1512 conf_get_sound(CONF_SOUND_WAIT_FOR_LEADER, user->conference->b_profile.sounds))) {
1513 /* user hungup while the sound was playing */
1514 return -1;
1515 }
1516 return 0;
1517}
static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
Play back an audio file to a channel.
@ USER_OPT_QUIET
Definition: confbridge.h:57

References ast_test_flag, conf_get_sound(), CONF_SOUND_WAIT_FOR_LEADER, play_prompt_to_user(), and USER_OPT_QUIET.

Referenced by conf_default_join_waitmarked().

◆ conf_handle_only_person()

int conf_handle_only_person ( struct confbridge_user user)

Handle actions whenever an user joins an empty conference.

Parameters
userThe user

Definition at line 1519 of file app_confbridge.c.

1520{
1521 /* If audio prompts have not been quieted or this prompt quieted play it on out */
1524 conf_get_sound(CONF_SOUND_ONLY_PERSON, user->conference->b_profile.sounds))) {
1525 /* user hungup while the sound was playing */
1526 return -1;
1527 }
1528 }
1529 return 0;
1530}
@ USER_OPT_NOONLYPERSON
Definition: confbridge.h:53

References ast_test_flag, conf_get_sound(), CONF_SOUND_ONLY_PERSON, play_prompt_to_user(), USER_OPT_NOONLYPERSON, and USER_OPT_QUIET.

Referenced by join_marked(), and join_unmarked().

◆ conf_handle_second_active()

void conf_handle_second_active ( struct confbridge_conference conference)

Handle when a conference moves to having more than one active participant.

Parameters
conferenceThe conference bridge with more than one active participant

Definition at line 1549 of file app_confbridge.c.

1550{
1551 /* If we are the second participant we may need to stop music on hold on the first */
1552 struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1553
1554 if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1555 conf_moh_stop(first_user);
1556 }
1557 conf_update_user_mute(first_user);
1558}
void conf_moh_stop(struct confbridge_user *user)
Stop MOH for the conference user.
@ USER_OPT_MUSICONHOLD
Definition: confbridge.h:56
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421

References confbridge_conference::active_list, AST_LIST_FIRST, ast_test_flag, conf_moh_stop(), conf_update_user_mute(), confbridge_user::conference, confbridge_user::u_profile, and USER_OPT_MUSICONHOLD.

Referenced by join_active(), join_marked(), and join_unmarked().

◆ conf_handle_talker_cb()

static int conf_handle_talker_cb ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt,
int  talking 
)
static

Definition at line 2411 of file app_confbridge.c.

2412{
2413 struct confbridge_user *user = hook_pvt;
2415 struct ast_json *talking_extras;
2416
2417 conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2418 if (!conference) {
2419 /* Remove the hook since the conference does not exist. */
2420 return -1;
2421 }
2422
2423 ao2_lock(conference);
2424 user->talking = talking;
2425 ao2_unlock(conference);
2426
2427 talking_extras = ast_json_pack("{s: s, s: b}",
2428 "talking_status", talking ? "on" : "off",
2429 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2430 if (!talking_extras) {
2431 return 0;
2432 }
2433
2434 send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2435 ast_json_unref(talking_extras);
2436 return 0;
2437}
static void send_conf_stasis(struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *extras, int channel_topic)
struct stasis_message_type * confbridge_talking_type(void)
get the confbridge talking stasis message type
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
Abstract JSON element (object, array, string, int, ...).

References ao2_cleanup, ao2_find, ao2_lock, ao2_unlock, ast_json_pack(), ast_json_unref(), ast_test_flag, ast_bridge_channel::chan, confbridge_talking_type(), confbridge_user::conference, conference_bridges, NULL, OBJ_KEY, RAII_VAR, send_conf_stasis(), and USER_OPT_ADMIN.

Referenced by confbridge_exec().

◆ conf_is_recording()

static int conf_is_recording ( struct confbridge_conference conference)
static

Definition at line 891 of file app_confbridge.c.

892{
893 return conference->record_chan != NULL;
894}
struct ast_channel * record_chan
Definition: confbridge.h:257

References NULL, and confbridge_conference::record_chan.

Referenced by action_confbridgestartrecord(), conf_start_record(), conf_stop_record(), and handle_cli_confbridge_start_record().

◆ conf_moh_start()

void conf_moh_start ( struct confbridge_user user)

Start MOH for the conference user.

Parameters
userConference user to start MOH on.

Definition at line 1451 of file app_confbridge.c.

1452{
1453 user->playing_moh = 1;
1454 if (!user->suspended_moh) {
1455 int in_bridge;
1456
1457 /*
1458 * Locking the ast_bridge here is the only way to hold off the
1459 * call to ast_bridge_join() in confbridge_exec() from
1460 * interfering with the bridge and MOH operations here.
1461 */
1462 ast_bridge_lock(user->conference->bridge);
1463
1464 /*
1465 * Temporarily suspend the user from the bridge so we have
1466 * control to start MOH if needed.
1467 */
1468 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1469 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1470 if (in_bridge) {
1471 ast_bridge_unsuspend(user->conference->bridge, user->chan);
1472 }
1473
1474 ast_bridge_unlock(user->conference->bridge);
1475 }
1476}
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3007
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3028
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7788

References ast_bridge_lock, ast_bridge_suspend(), ast_bridge_unlock, ast_bridge_unsuspend(), ast_moh_start(), and NULL.

Referenced by conf_mute_moh_inactive_waitmarked(), conf_mute_only_active(), and leave_marked().

◆ conf_moh_stop()

void conf_moh_stop ( struct confbridge_user user)

Stop MOH for the conference user.

Parameters
userConference user to stop MOH on.

Definition at line 1424 of file app_confbridge.c.

1425{
1426 user->playing_moh = 0;
1427 if (!user->suspended_moh) {
1428 int in_bridge;
1429
1430 /*
1431 * Locking the ast_bridge here is the only way to hold off the
1432 * call to ast_bridge_join() in confbridge_exec() from
1433 * interfering with the bridge and MOH operations here.
1434 */
1435 ast_bridge_lock(user->conference->bridge);
1436
1437 /*
1438 * Temporarily suspend the user from the bridge so we have
1439 * control to stop MOH if needed.
1440 */
1441 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1442 ast_moh_stop(user->chan);
1443 if (in_bridge) {
1444 ast_bridge_unsuspend(user->conference->bridge, user->chan);
1445 }
1446
1447 ast_bridge_unlock(user->conference->bridge);
1448 }
1449}
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7798

References ast_bridge_lock, ast_bridge_suspend(), ast_bridge_unlock, ast_bridge_unsuspend(), and ast_moh_stop().

Referenced by conf_default_leave_waitmarked(), conf_handle_second_active(), leave_marked(), leave_unmarked(), and transition_to_marked().

◆ conf_moh_suspend()

static void conf_moh_suspend ( struct confbridge_user user)
static

Definition at line 1499 of file app_confbridge.c.

1500{
1501 ao2_lock(user->conference);
1502 if (user->suspended_moh++ == 0 && user->playing_moh) {
1503 ast_moh_stop(user->chan);
1504 }
1505 ao2_unlock(user->conference);
1506}

References ao2_lock, ao2_unlock, and ast_moh_stop().

Referenced by conf_handle_dtmf().

◆ conf_moh_unsuspend()

static void conf_moh_unsuspend ( struct confbridge_user user)
static

Definition at line 1484 of file app_confbridge.c.

1485{
1486 ao2_lock(user->conference);
1487 if (--user->suspended_moh == 0 && user->playing_moh) {
1488 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1489 }
1490 ao2_unlock(user->conference);
1491}

References ao2_lock, ao2_unlock, ast_moh_start(), and NULL.

Referenced by conf_handle_dtmf(), and confbridge_exec().

◆ conf_mute_only_active()

void conf_mute_only_active ( struct confbridge_conference conference)

Attempt to mute/play MOH to the only user in the conference if they require it.

Parameters
conferenceA conference bridge containing a single user

Definition at line 4517 of file app_confbridge.c.

4518{
4520
4521 /* Turn on MOH if the single participant is set up for it */
4522 if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4523 conf_moh_start(only_user);
4524 }
4525 conf_update_user_mute(only_user);
4526}
void conf_moh_start(struct confbridge_user *user)
Start MOH for the conference user.

References confbridge_conference::active_list, AST_LIST_FIRST, ast_test_flag, conf_moh_start(), conf_update_user_mute(), confbridge_user::conference, confbridge_user::u_profile, and USER_OPT_MUSICONHOLD.

Referenced by transition_to_single(), and transition_to_single_marked().

◆ conf_rec_name()

static int conf_rec_name ( struct confbridge_user user,
const char *  conf_name 
)
static

Definition at line 2488 of file app_confbridge.c.

2489{
2490 char destdir[PATH_MAX];
2491 int res;
2492 int duration = 20;
2493
2494 snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2495
2496 if (ast_mkdir(destdir, 0777) != 0) {
2497 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2498 return -1;
2499 }
2500 snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2501 "%s/confbridge-name-%s-%s", destdir,
2502 conf_name, ast_channel_uniqueid(user->chan));
2503
2505 res = ast_play_and_record(user->chan,
2506 "vm-rec-name",
2507 user->name_rec_location,
2508 10,
2509 "sln",
2510 &duration,
2511 NULL,
2513 0,
2514 NULL);
2515 } else {
2516 res = ast_record_review(user->chan,
2517 "vm-rec-name",
2518 user->name_rec_location,
2519 10,
2520 "sln",
2521 &duration,
2522 NULL);
2523 }
2524
2525 if (res == -1) {
2526 ast_filedelete(user->name_rec_location, NULL);
2527 user->name_rec_location[0] = '\0';
2528 return -1;
2529 }
2530 return 0;
2531}
#define PATH_MAX
Definition: asterisk.h:40
@ USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW
Definition: confbridge.h:68
@ THRESHOLD_SILENCE
Definition: dsp.h:73
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:2009
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
Definition: main/app.c:2154
int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
Allow to record message and have a review option.
Definition: main/app.c:2646
int errno
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2479

References ast_channel_uniqueid(), ast_config_AST_SPOOL_DIR, ast_dsp_get_threshold_from_settings(), ast_filedelete(), ast_log, ast_mkdir(), ast_play_and_record(), ast_record_review(), ast_test_flag, errno, LOG_WARNING, NULL, PATH_MAX, THRESHOLD_SILENCE, and USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW.

Referenced by confbridge_exec().

◆ conf_remove_user_active()

void conf_remove_user_active ( struct confbridge_conference conference,
struct confbridge_user user 
)

Remove a conference bridge user from the unmarked active conference users in the conference.

Parameters
conferenceThe conference bridge to remove the user from
userThe conference bridge user to remove from the conference

Definition at line 4504 of file app_confbridge.c.

4505{
4506 AST_LIST_REMOVE(&conference->active_list, user, list);
4507 conference->activeusers--;
4508}
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856

References confbridge_conference::active_list, confbridge_conference::activeusers, and AST_LIST_REMOVE.

Referenced by leave_active(), and leave_unmarked().

◆ conf_remove_user_marked()

void conf_remove_user_marked ( struct confbridge_conference conference,
struct confbridge_user user 
)

Remove a conference bridge user from the marked active conference users in the conference.

Parameters
conferenceThe conference bridge to remove the user from
userThe conference bridge user to remove from the conference

Definition at line 4510 of file app_confbridge.c.

4511{
4512 AST_LIST_REMOVE(&conference->active_list, user, list);
4513 conference->activeusers--;
4514 conference->markedusers--;
4515}

References confbridge_conference::active_list, confbridge_conference::activeusers, AST_LIST_REMOVE, and confbridge_conference::markedusers.

Referenced by leave_marked().

◆ conf_remove_user_waiting()

void conf_remove_user_waiting ( struct confbridge_conference conference,
struct confbridge_user user 
)

Remove a conference bridge user from the waiting conference users in the conference.

Parameters
conferenceThe conference bridge to remove the user from
userThe conference bridge user to remove from the conference

Definition at line 4528 of file app_confbridge.c.

4529{
4530 AST_LIST_REMOVE(&conference->waiting_list, user, list);
4531 conference->waitingusers--;
4532}

References AST_LIST_REMOVE, confbridge_user::conference, confbridge_user::list, confbridge_conference::waiting_list, and confbridge_conference::waitingusers.

Referenced by conf_default_leave_waitmarked().

◆ conf_start_record()

static int conf_start_record ( struct confbridge_conference conference)
static

Definition at line 939 of file app_confbridge.c.

940{
941 struct ast_app *mixmonapp;
942 struct ast_channel *chan;
943 struct ast_format_cap *cap;
944 struct ast_bridge_features *features;
945
946 if (conf_is_recording(conference)) {
947 return -1;
948 }
949
950 mixmonapp = pbx_findapp("MixMonitor");
951 if (!mixmonapp) {
952 ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
953 return -1;
954 }
955
956 features = ast_bridge_features_new();
957 if (!features) {
958 return -1;
959 }
961
963 if (!cap) {
965 return -1;
966 }
968
969 /* Create the recording channel. */
970 chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
971 ao2_ref(cap, -1);
972 if (!chan) {
974 return -1;
975 }
976
977 /* Start recording. */
978 set_rec_filename(conference, &conference->record_filename,
979 is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
980 ast_answer(chan);
981 pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
982
983 /* Put the channel into the conference bridge. */
984 ast_channel_ref(chan);
985 conference->record_chan = chan;
986 if (ast_bridge_impart(conference->bridge, chan, NULL, features,
988 ast_hangup(chan);
989 ast_channel_unref(chan);
990 conference->record_chan = NULL;
991 return -1;
992 }
993
994 ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
995 send_start_record_event(conference);
996
997 return 0;
998}
static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
static void send_start_record_event(struct confbridge_conference *conference)
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2824
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
ast_app: A registered application
Definition: pbx_app.c:45
Structure that contains features information.
struct ast_flags feature_flags
Main Channel structure associated with a channel.
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:228
struct ast_str * orig_rec_file
Definition: confbridge.h:259
struct ast_str * record_filename
Definition: confbridge.h:258
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ao2_ref, ast_answer(), AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, ast_bridge_features_destroy(), ast_bridge_features_new(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_channel_ref, ast_channel_unref, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_hangup(), ast_log, ast_request(), ast_set_flag, ast_str_buffer(), ast_test_suite_event_notify, confbridge_conference::b_profile, confbridge_conference::bridge, conf_is_recording(), ast_bridge_features::feature_flags, is_new_rec_file(), LOG_WARNING, confbridge_conference::name, bridge_profile::name, NULL, confbridge_conference::orig_rec_file, pbx_exec(), pbx_findapp(), bridge_profile::rec_file, confbridge_conference::record_chan, confbridge_conference::record_filename, send_start_record_event(), and set_rec_filename().

Referenced by action_confbridgestartrecord(), handle_cli_confbridge_start_record(), and join_conference_bridge().

◆ conf_stop_record()

static int conf_stop_record ( struct confbridge_conference conference)
static

Definition at line 907 of file app_confbridge.c.

908{
909 struct ast_channel *chan;
910 struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
911
912 if (!conf_is_recording(conference)) {
913 return -1;
914 }
915
916 /* Remove the recording channel from the conference bridge. */
917 chan = conference->record_chan;
918 conference->record_chan = NULL;
919 ast_queue_frame(chan, &f);
920 ast_channel_unref(chan);
921
922 ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
923 send_stop_record_event(conference);
924
925 return 0;
926}
static void send_stop_record_event(struct confbridge_conference *conference)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1158
@ AST_FRAME_CONTROL
@ AST_CONTROL_HANGUP
Data structure associated with a single frame of data.

References ast_channel_unref, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), ast_test_suite_event_notify, confbridge_conference::b_profile, conf_is_recording(), bridge_profile::name, NULL, confbridge_conference::record_chan, and send_stop_record_event().

Referenced by action_confbridgestoprecord(), conf_ended(), and handle_cli_confbridge_stop_record().

◆ conf_update_user_mute()

void conf_update_user_mute ( struct confbridge_user user)

Update the actual mute status of the user and set it on the bridge.

Parameters
userUser to update the mute status.

Definition at line 1366 of file app_confbridge.c.

1367{
1368 int mute_user;
1369 int mute_system;
1370 int mute_effective;
1371
1372 /* User level mute request. */
1373 mute_user = user->muted;
1374
1375 /* System level mute request. */
1376 mute_system = user->playing_moh
1377 /*
1378 * Do not allow waitmarked users to talk to anyone unless there
1379 * is a marked user present.
1380 */
1381 || (!user->conference->markedusers
1382 && ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED));
1383
1384 mute_effective = mute_user || mute_system;
1385
1386 ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1387 ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1388 mute_user, mute_system);
1389 user->features.mute = mute_effective;
1390 ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1391 "Mode: %s\r\n"
1392 "Conference: %s\r\n"
1393 "Channel: %s",
1394 mute_effective ? "muted" : "unmuted",
1395 user->conference->b_profile.name,
1396 ast_channel_name(user->chan));
1397}

References ast_channel_name(), ast_debug, ast_test_flag, ast_test_suite_event_notify, and USER_OPT_WAITMARKED.

Referenced by action_toggle_mute_participants(), conf_handle_second_active(), conf_mute_moh_inactive_waitmarked(), conf_mute_only_active(), generic_mute_unmute_user(), join_active(), join_marked(), join_unmarked(), leave_marked(), and transition_to_marked().

◆ confbridge_exec()

static int confbridge_exec ( struct ast_channel chan,
const char *  data 
)
static

The ConfBridge application.

Definition at line 2633 of file app_confbridge.c.

2634{
2635 int res = 0, volume_adjustments[2];
2636 int quiet = 0;
2637 int async_delete_task_pushed = 0;
2638 char *parse;
2639 const char *b_profile_name = NULL;
2640 const char *u_profile_name = NULL;
2641 const char *menu_profile_name = NULL;
2642 struct confbridge_conference *conference = NULL;
2643 struct confbridge_user user = {
2644 .chan = chan,
2645 .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2646 .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2647 .tech_args.drop_silence = 0,
2648 };
2649 struct confbridge_hook_data *join_hook_data;
2650 struct confbridge_hook_data *leave_hook_data;
2651
2653 AST_APP_ARG(conf_name);
2654 AST_APP_ARG(b_profile_name);
2655 AST_APP_ARG(u_profile_name);
2656 AST_APP_ARG(menu_profile_name);
2657 );
2658
2659 if (ast_bridge_features_init(&user.features)) {
2660 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2661 res = -1;
2662 goto confbridge_cleanup;
2663 }
2664
2665 /* We need to make a copy of the input string if we are going to modify it! */
2666 parse = ast_strdupa(data);
2667
2669
2670 if (ast_strlen_zero(args.conf_name)) {
2671 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2672 ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2673 res = -1;
2674 goto confbridge_cleanup;
2675 }
2676
2677 if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2678 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2679 ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2680 res = -1;
2681 goto confbridge_cleanup;
2682 }
2683
2684 /* bridge profile name */
2685 if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2686 b_profile_name = args.b_profile_name;
2687 }
2688 if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2689 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2690 ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2691 b_profile_name : DEFAULT_BRIDGE_PROFILE);
2692 res = -1;
2693 goto confbridge_cleanup;
2694 }
2695
2696 /* user profile name */
2697 if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2698 u_profile_name = args.u_profile_name;
2699 }
2700 if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2701 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2702 ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2703 u_profile_name : DEFAULT_USER_PROFILE);
2704 res = -1;
2705 goto confbridge_cleanup;
2706 }
2707
2708 /* If channel hasn't been answered already, answer it, unless we're explicitly not supposed to */
2709 if ((ast_channel_state(chan) != AST_STATE_UP) && (ast_test_flag(&user.u_profile, USER_OPT_ANSWER_CHANNEL))) {
2710 ast_answer(chan);
2711 }
2712
2713 quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2714
2715 /* ask for a PIN immediately after finding user profile. This has to be
2716 * prompted for requardless of quiet setting. */
2717 if (!ast_strlen_zero(user.u_profile.pin)) {
2718 if (conf_get_pin(chan, &user)) {
2719 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2720 res = -1; /* invalid PIN */
2721 goto confbridge_cleanup;
2722 }
2723 }
2724
2725 /* See if we need them to record a intro name */
2726 if (!quiet &&
2729 if (conf_rec_name(&user, args.conf_name)) {
2730 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2731 res = -1; /* Hangup during name recording */
2732 goto confbridge_cleanup;
2733 }
2734 }
2735
2736 /* menu name */
2737 if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2738 menu_profile_name = args.menu_profile_name;
2739 }
2740
2741 if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2742 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2743 ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2744 menu_profile_name : DEFAULT_MENU_PROFILE);
2745 res = -1;
2746 goto confbridge_cleanup;
2747 }
2748
2749 /* Set if DTMF should pass through for this user or not */
2750 if (ast_test_flag(&user.u_profile, USER_OPT_DTMF_PASS)) {
2751 user.features.dtmf_passthrough = 1;
2752 } else {
2753 user.features.dtmf_passthrough = 0;
2754 }
2755
2756 /* Set if text messaging is enabled for this user or not */
2757 if (ast_test_flag(&user.u_profile, USER_OPT_TEXT_MESSAGING)) {
2758 user.features.text_messaging = 1;
2759 } else {
2760 user.features.text_messaging = 0;
2761 }
2762
2763 /* Set dsp threshold values if present */
2764 if (user.u_profile.talking_threshold) {
2765 user.tech_args.talking_threshold = user.u_profile.talking_threshold;
2766 }
2767 if (user.u_profile.silence_threshold) {
2768 user.tech_args.silence_threshold = user.u_profile.silence_threshold;
2769 }
2770
2771 /* Set a talker indicate call back if talking detection is requested */
2772 if (ast_test_flag(&user.u_profile, USER_OPT_TALKER_DETECT)) {
2775 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2776 res = -1;
2777 goto confbridge_cleanup;
2778 }
2779 }
2780
2781 /* Look for a conference bridge matching the provided name */
2782 if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2783 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2784 res = -1;
2785 goto confbridge_cleanup;
2786 }
2787
2788 /* Keep a copy of volume adjustments so we can restore them later if need be */
2789 volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2790 volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2791
2792 if (ast_test_flag(&user.u_profile, USER_OPT_DROP_SILENCE)) {
2793 user.tech_args.drop_silence = 1;
2794 }
2795
2796 if (ast_test_flag(&user.u_profile, USER_OPT_JITTERBUFFER)) {
2797 ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2798 }
2799
2800 if (ast_test_flag(&user.u_profile, USER_OPT_DENOISE)) {
2801 ast_func_write(chan, "DENOISE(rx)", "on");
2802 }
2803
2804 /* if this user has a intro, play it before entering */
2805 if (!ast_strlen_zero(user.name_rec_location)) {
2807 play_sound_file(conference, user.name_rec_location);
2811 }
2812
2813 if (!quiet) {
2814 const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2815
2816 /* if hear_own_join_sound is enabled play the Join sound to everyone */
2818 if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2819 ast_stream_and_wait(chan, join_sound, "");
2821 play_sound_file(conference, join_sound);
2823 } else {
2824 async_play_sound_file(conference, join_sound, chan);
2825 }
2826 /* if hear_own_join_sound is disabled only play the Join sound to just the conference */
2827 } else {
2829 play_sound_file(conference, join_sound);
2831 }
2832 }
2833
2834 if (user.u_profile.timeout) {
2836 0,
2837 user.u_profile.timeout * 1000,
2839 NULL,
2840 NULL,
2842 }
2843
2844 /* See if we need to automatically set this user as a video source or not */
2846
2848
2849 join_hook_data = ast_malloc(sizeof(*join_hook_data));
2850 if (!join_hook_data) {
2851 res = -1;
2852 goto confbridge_cleanup;
2853 }
2854 join_hook_data->user = &user;
2855 join_hook_data->conference = conference;
2856 join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2858 join_hook_data, ast_free_ptr, 0);
2859 if (res) {
2860 ast_free(join_hook_data);
2861 ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2862 goto confbridge_cleanup;
2863 }
2864
2865 leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2866 if (!leave_hook_data) {
2867 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2868 res = -1;
2869 goto confbridge_cleanup;
2870 }
2871 leave_hook_data->user = &user;
2872 leave_hook_data->conference = conference;
2873 leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2875 leave_hook_data, ast_free_ptr, 0);
2876 if (res) {
2877 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2878 ast_free(leave_hook_data);
2879 ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2880 goto confbridge_cleanup;
2881 }
2882
2883 if (ast_bridge_join_hook(&user.features, join_callback, NULL, NULL, 0)) {
2885 }
2886
2888 chan,
2889 NULL,
2890 &user.features,
2891 &user.tech_args,
2892 0);
2893
2894 /* This is a catch-all in case joining the bridge failed or for some reason
2895 * an async announcement got queued up and hasn't been told to play yet
2896 */
2898
2899 if (!user.kicked && ast_check_hangup(chan)) {
2900 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2901 }
2902
2903 /* if we're shutting down, don't attempt to do further processing */
2904 if (ast_shutting_down()) {
2905 /*
2906 * Not taking any new calls at this time. We cannot create
2907 * the announcer channel if this is the first channel into
2908 * the conference and we certainly cannot create any
2909 * recording channel.
2910 */
2912 conference = NULL;
2913 goto confbridge_cleanup;
2914 }
2915
2916 /* If this user was a video source, we need to clean up and possibly pick a new source. */
2918
2919 /* if this user has a intro, play it when leaving */
2920 if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2921 async_play_sound_file(conference, user.name_rec_location, NULL);
2924 async_delete_name_rec(conference, user.name_rec_location);
2925 async_delete_task_pushed = 1;
2926 }
2927
2928 /* play the leave sound */
2929 if (!quiet) {
2930 const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2931 async_play_sound_file(conference, leave_sound, NULL);
2932 }
2933
2934 /* If the user was kicked from the conference play back the audio prompt for it */
2935 if (!quiet && user.kicked) {
2936 res = ast_stream_and_wait(chan,
2938 "");
2939 }
2940
2941 /* Easy as pie, depart this channel from the conference bridge */
2943 conference = NULL;
2944
2945 /* Restore volume adjustments to previous values in case they were changed */
2946 if (volume_adjustments[0]) {
2947 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2948 }
2949 if (volume_adjustments[1]) {
2950 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2951 }
2952
2953confbridge_cleanup:
2954 if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2955 ast_filedelete(user.name_rec_location, NULL);
2956 }
2959 return res;
2960}
static int quiet
Definition: ael_main.c:123
static int send_event_hook_callback(struct ast_bridge_channel *bridge_channel, void *data)
static int join_callback(struct ast_bridge_channel *bridge_channel, void *ignore)
static const char app[]
static void leave_conference(struct confbridge_user *user)
Leave a conference.
static int conf_get_pin(struct ast_channel *chan, struct confbridge_user *user)
static int conf_rec_name(struct confbridge_user *user, const char *conf_name)
static void handle_video_on_join(struct confbridge_conference *conference, struct ast_channel *chan, int marked)
static struct confbridge_conference * join_conference_bridge(const char *conference_name, struct confbridge_user *user)
Join a conference bridge.
static int async_delete_name_rec(struct confbridge_conference *conference, const char *filename)
static int user_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
static int conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
static void handle_video_on_exit(struct confbridge_conference *conference, struct ast_channel *chan)
int ast_shutting_down(void)
Definition: asterisk.c:1877
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
@ AST_AUDIOHOOK_DIRECTION_READ
Definition: audiohook.h:49
@ AST_AUDIOHOOK_DIRECTION_WRITE
Definition: audiohook.h:50
int ast_audiohook_volume_get(struct ast_channel *chan, enum ast_audiohook_direction direction)
Retrieve the volume adjustment value on frames read from or written to a channel.
Definition: audiohook.c:1341
int ast_audiohook_volume_set(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
Adjust the volume on frames read from or written to a channel.
Definition: audiohook.c:1321
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1621
@ AST_BRIDGE_HOOK_TYPE_JOIN
@ AST_BRIDGE_HOOK_TYPE_LEAVE
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3319
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, ast_bridge_talking_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel talk detection hook to a bridge features structure.
Definition: bridge.c:3295
int ast_bridge_join_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel join hook to a bridge features structure.
Definition: bridge.c:3275
int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel leave hook to a bridge features structure.
Definition: bridge.c:3285
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
void conf_bridge_profile_destroy(struct bridge_profile *b_profile)
Destroy a bridge profile found by 'conf_find_bridge_profile'.
const struct bridge_profile * conf_find_bridge_profile(struct ast_channel *chan, const char *bridge_profile_name, struct bridge_profile *result)
Find a bridge profile given a bridge profile's name and store that profile in result structure.
int conf_set_menu_to_user(struct ast_channel *chan, struct confbridge_user *user, const char *menu_profile_name)
find a menu profile given a menu profile's name and apply the menu in DTMF hooks.
const struct user_profile * conf_find_user_profile(struct ast_channel *chan, const char *user_profile_name, struct user_profile *result)
find a user profile given a user profile's name and store that profile in result structure.
#define DEFAULT_SILENCE_THRESHOLD
Definition: confbridge.h:49
@ USER_OPT_HEAR_OWN_JOIN_SOUND
Definition: confbridge.h:73
@ USER_OPT_TEXT_MESSAGING
Definition: confbridge.h:71
@ USER_OPT_DENOISE
Definition: confbridge.h:61
@ USER_OPT_DTMF_PASS
Definition: confbridge.h:65
@ USER_OPT_TALKER_DETECT
Definition: confbridge.h:63
@ USER_OPT_DROP_SILENCE
Definition: confbridge.h:64
@ USER_OPT_ANSWER_CHANNEL
Definition: confbridge.h:72
@ USER_OPT_JITTERBUFFER
Definition: confbridge.h:67
@ USER_OPT_ANNOUNCE_JOIN_LEAVE
Definition: confbridge.h:62
#define DEFAULT_TALKING_THRESHOLD
Definition: confbridge.h:46
#define DEFAULT_MENU_PROFILE
Definition: confbridge.h:43
#define DEFAULT_BRIDGE_PROFILE
Definition: confbridge.h:42
#define DEFAULT_USER_PROFILE
Definition: confbridge.h:41
#define MAX_CONF_NAME
Definition: confbridge.h:35
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_ERROR
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
struct confbridge_conference * conference
struct confbridge_user * user
enum ast_bridge_hook_type hook_type

References app, args, ast_answer(), AST_APP_ARG, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_volume_get(), ast_audiohook_volume_set(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_features_cleanup(), ast_bridge_features_init(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, AST_BRIDGE_HOOK_TYPE_JOIN, AST_BRIDGE_HOOK_TYPE_LEAVE, ast_bridge_interval_hook(), ast_bridge_join(), ast_bridge_join_hook(), ast_bridge_leave_hook(), ast_bridge_talk_detector_hook(), ast_channel_language(), ast_channel_name(), ast_check_hangup(), AST_DECLARE_APP_ARGS, ast_filedelete(), ast_free, ast_free_ptr(), ast_func_write(), ast_log, ast_malloc, ast_shutting_down(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, async_delete_name_rec(), async_play_sound_file(), async_play_sound_ready(), confbridge_conference::b_profile, confbridge_conference::bridge, confbridge_user::chan, conf_bridge_profile_destroy(), conf_find_bridge_profile(), conf_find_user_profile(), conf_get_pin(), conf_get_sound(), conf_handle_talker_cb(), conf_moh_unsuspend(), conf_rec_name(), conf_set_menu_to_user(), CONF_SOUND_HAS_JOINED, CONF_SOUND_HAS_LEFT, CONF_SOUND_JOIN, CONF_SOUND_KICKED, CONF_SOUND_LEAVE, confbridge_hook_data::conference, DEFAULT_BRIDGE_PROFILE, DEFAULT_MENU_PROFILE, DEFAULT_SILENCE_THRESHOLD, DEFAULT_TALKING_THRESHOLD, DEFAULT_USER_PROFILE, handle_video_on_exit(), handle_video_on_join(), confbridge_hook_data::hook_type, join_callback(), join_conference_bridge(), bridge_profile::language, leave_conference(), LOG_ERROR, LOG_WARNING, MAX_CONF_NAME, NULL, pbx_builtin_setvar_helper(), play_sound_file(), quiet, send_event_hook_callback(), bridge_profile::sounds, confbridge_hook_data::user, user, USER_OPT_ANNOUNCE_JOIN_LEAVE, USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW, USER_OPT_ANSWER_CHANNEL, USER_OPT_DENOISE, USER_OPT_DROP_SILENCE, USER_OPT_DTMF_PASS, USER_OPT_HEAR_OWN_JOIN_SOUND, USER_OPT_JITTERBUFFER, USER_OPT_MARKEDUSER, USER_OPT_QUIET, USER_OPT_TALKER_DETECT, USER_OPT_TEXT_MESSAGING, and user_timeout().

Referenced by load_module().

◆ confbridge_handle_atxfer()

void confbridge_handle_atxfer ( struct ast_attended_transfer_message msg)

Create join/leave events for attended transfers.

Since
13.28
16.5
Parameters
msgThe attended transfer stasis message

Definition at line 1649 of file app_confbridge.c.

1650{
1651 struct ast_channel_snapshot *old_snapshot;
1652 struct ast_channel_snapshot *new_snapshot;
1653 char *confbr_name = NULL;
1654 char *comma;
1656 struct confbridge_user *user = NULL;
1657 int found_user = 0;
1658 struct ast_json *json_object;
1659
1661 && strcmp(msg->to_transferee.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1662 && msg->target) {
1663 /* We're transferring a bridge to an extension */
1664 old_snapshot = msg->to_transferee.channel_snapshot;
1665 new_snapshot = msg->target;
1666 } else if (msg->to_transfer_target.channel_snapshot
1667 && strcmp(msg->to_transfer_target.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1668 && msg->transferee) {
1669 /* We're transferring a call to a bridge */
1670 old_snapshot = msg->to_transfer_target.channel_snapshot;
1671 new_snapshot = msg->transferee;
1672 } else {
1673 ast_log(LOG_ERROR, "Could not determine proper channels\n");
1674 return;
1675 }
1676
1677 /*
1678 * old_snapshot->data should have the original parameters passed to
1679 * the ConfBridge app:
1680 * conference[,bridge_profile[,user_profile[,menu]]]
1681 * We'll use "conference" to look up the bridge.
1682 *
1683 * We _could_ use old_snapshot->bridgeid to get the bridge but
1684 * that would involve locking the conference_bridges container
1685 * and iterating over it looking for a matching bridge.
1686 */
1687 if (ast_strlen_zero(old_snapshot->dialplan->data)) {
1688 ast_log(LOG_ERROR, "Channel '%s' didn't have app data set\n", old_snapshot->base->name);
1689 return;
1690 }
1691 confbr_name = ast_strdupa(old_snapshot->dialplan->data);
1692 comma = strchr(confbr_name, ',');
1693 if (comma) {
1694 *comma = '\0';
1695 }
1696
1697 ast_debug(1, "Confbr: %s Leaving: %s Joining: %s\n", confbr_name, old_snapshot->base->name, new_snapshot->base->name);
1698
1699 conference = ao2_find(conference_bridges, confbr_name, OBJ_SEARCH_KEY);
1700 if (!conference) {
1701 ast_log(LOG_ERROR, "Conference bridge '%s' not found\n", confbr_name);
1702 return;
1703 }
1704 ao2_lock(conference);
1705
1706 /*
1707 * We need to grab the user profile for the departing user in order to
1708 * properly format the join/leave messages.
1709 */
1710 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1711 if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1712 found_user = 1;
1713 break;
1714 }
1715 }
1716
1717 /*
1718 * If we didn't find the user in the active list, try the waiting list.
1719 */
1720 if (!found_user && conference->waitingusers) {
1721 AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
1722 if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1723 found_user = 1;
1724 break;
1725 }
1726 }
1727 }
1728
1729 if (!found_user) {
1730 ast_log(LOG_ERROR, "Unable to find user profile for channel '%s' in bridge '%s'\n",
1731 old_snapshot->base->name, confbr_name);
1732 return;
1733 }
1734
1735 /*
1736 * We're going to use the existing user profile to create the messages.
1737 */
1738 json_object = ast_json_pack("{s: b}",
1739 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
1740 );
1741 if (!json_object) {
1742 return;
1743 }
1744
1745 send_conf_stasis_snapshots(conference, old_snapshot, confbridge_leave_type(), json_object);
1746 ast_json_unref(json_object);
1747
1748 json_object = ast_json_pack("{s: b, s: b}",
1749 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
1750 "muted", user->muted);
1751 if (!json_object) {
1752 return;
1753 }
1754 send_conf_stasis_snapshots(conference, new_snapshot, confbridge_join_type(), json_object);
1755 ast_json_unref(json_object);
1756}
static void send_conf_stasis_snapshots(struct confbridge_conference *conference, struct ast_channel_snapshot *chan_snapshot, struct stasis_message_type *type, struct ast_json *extras)
static void confbridge_unlock_and_unref(void *obj)
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
struct stasis_message_type * confbridge_join_type(void)
get the confbridge join stasis message type
struct stasis_message_type * confbridge_leave_type(void)
get the confbridge leave stasis message type
struct ast_bridge_channel_snapshot_pair to_transfer_target
struct ast_channel_snapshot * transferee
struct ast_bridge_channel_snapshot_pair to_transferee
struct ast_channel_snapshot * target
struct ast_channel_snapshot * channel_snapshot
const ast_string_field name
const ast_string_field data
const ast_string_field appl
struct ast_channel_snapshot_dialplan * dialplan
struct ast_channel_snapshot_base * base

References ao2_find, ao2_lock, ast_channel_snapshot_dialplan::appl, ast_channel_name(), ast_debug, ast_json_pack(), ast_json_unref(), AST_LIST_TRAVERSE, ast_log, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel_snapshot::base, ast_bridge_channel_snapshot_pair::channel_snapshot, confbridge_join_type(), confbridge_leave_type(), confbridge_unlock_and_unref(), conference_bridges, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, LOG_ERROR, ast_channel_snapshot_base::name, NULL, OBJ_SEARCH_KEY, RAII_VAR, send_conf_stasis_snapshots(), ast_attended_transfer_message::target, ast_attended_transfer_message::to_transfer_target, ast_attended_transfer_message::to_transferee, ast_attended_transfer_message::transferee, and USER_OPT_ADMIN.

Referenced by confbridge_atxfer_cb().

◆ confbridge_unlock_and_unref()

static void confbridge_unlock_and_unref ( void *  obj)
static

Definition at line 1638 of file app_confbridge.c.

1639{
1640 struct confbridge_conference *conference = obj;
1641
1642 if (!obj) {
1643 return;
1644 }
1645 ao2_unlock(conference);
1646 ao2_ref(conference, -1);
1647}

References ao2_ref, and ao2_unlock.

Referenced by confbridge_handle_atxfer().

◆ conference_bridge_cmp_cb()

static int conference_bridge_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Comparison function used for conference bridges container.

Definition at line 592 of file app_confbridge.c.

593{
594 const struct confbridge_conference *left = obj;
595 const struct confbridge_conference *right = arg;
596 const char *right_name = arg;
597 int cmp;
598
599 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
600 default:
601 case OBJ_POINTER:
602 right_name = right->name;
603 /* Fall through */
604 case OBJ_KEY:
605 cmp = strcasecmp(left->name, right_name);
606 break;
607 case OBJ_PARTIAL_KEY:
608 cmp = strncasecmp(left->name, right_name, strlen(right_name));
609 break;
610 }
611 return cmp ? 0 : CMP_MATCH;
612}
@ CMP_MATCH
Definition: astobj2.h:1027
#define OBJ_POINTER
Definition: astobj2.h:1150
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1152

References CMP_MATCH, confbridge_conference::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by load_module().

◆ conference_bridge_hash_cb()

static int conference_bridge_hash_cb ( const void *  obj,
const int  flags 
)
static

Hashing function used for conference bridges container.

Definition at line 568 of file app_confbridge.c.

569{
570 const struct confbridge_conference *conference = obj;
571 const char *name = obj;
572 int hash;
573
574 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
575 default:
576 case OBJ_POINTER:
577 name = conference->name;
578 /* Fall through */
579 case OBJ_KEY:
580 hash = ast_str_case_hash(name);
581 break;
582 case OBJ_PARTIAL_KEY:
583 /* Should never happen in hash callback. */
584 ast_assert(0);
585 hash = 0;
586 break;
587 }
588 return hash;
589}
static const char name[]
Definition: format_mp3.c:68
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_str_case_hash(), name, confbridge_conference::name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by load_module().

◆ confkick_exec()

static int confkick_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 4438 of file app_confbridge.c.

4439{
4440 char *parse;
4441 struct confbridge_conference *conference;
4442 int not_found;
4443
4445 AST_APP_ARG(confbridge);
4446 AST_APP_ARG(channel);
4447 );
4448
4449 if (ast_strlen_zero(data)) {
4450 ast_log(LOG_WARNING, "No conference bridge specified.\n");
4451 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4452 return 0;
4453 }
4454
4455 parse = ast_strdupa(data);
4457
4458 conference = ao2_find(conference_bridges, args.confbridge, OBJ_KEY);
4459 if (!conference) {
4460 ast_log(LOG_WARNING, "No conference bridge named '%s' found!\n", args.confbridge);
4461 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4462 return 0;
4463 }
4464 if (ast_strlen_zero(args.channel)) {
4465 not_found = kick_conference_participant(conference, "all");
4466 } else {
4467 not_found = kick_conference_participant(conference, args.channel);
4468 }
4469
4470 ao2_ref(conference, -1);
4471 if (not_found) {
4472 if (ast_strlen_zero(args.channel) || !strcasecmp("all", args.channel) || !strcasecmp("participants", args.channel)) {
4473 ast_log(LOG_WARNING, "No participants found in conference bridge '%s'!\n", args.confbridge);
4474 } else {
4475 ast_log(LOG_WARNING, "No participant named '%s' found in conference bridge '%s'!\n", args.channel, args.confbridge);
4476 }
4477 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4478 return 0;
4479 }
4480 ast_debug(1, "Kicked '%s' out of conference '%s'\n", args.channel, args.confbridge);
4481 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "SUCCESS");
4482 return 0;
4483}

References ao2_find, ao2_ref, args, AST_APP_ARG, ast_debug, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), conference_bridges, kick_conference_participant(), LOG_WARNING, OBJ_KEY, and pbx_builtin_setvar_helper().

Referenced by load_module().

◆ destroy_conference_bridge()

static void destroy_conference_bridge ( void *  obj)
static

Destroy a conference bridge.

Parameters
objThe conference bridge object

Definition at line 1264 of file app_confbridge.c.

1265{
1266 struct confbridge_conference *conference = obj;
1267
1268 ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
1269
1270 if (conference->playback_chan) {
1271 if (conference->playback_queue) {
1272 struct hangup_data hangup;
1274
1276 ast_mutex_lock(&hangup.lock);
1277 while (!hangup.hungup) {
1278 ast_cond_wait(&hangup.cond, &hangup.lock);
1279 }
1280 ast_mutex_unlock(&hangup.lock);
1281 }
1282
1284 } else {
1285 /* Playback queue is not yet allocated. Just hang up the channel straight */
1288 }
1289 }
1290
1291 /* Destroying a conference bridge is simple, all we have to do is destroy the bridging object */
1292 if (conference->bridge) {
1295 }
1296
1300
1303}
static void hangup_data_init(struct hangup_data *hangup, struct confbridge_conference *conference)
static void hangup_data_destroy(struct hangup_data *hangup)
static int hangup_playback(void *data)
Hang up the announcer channel.
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
static int hangup(void *data)
Definition: chan_pjsip.c:2519
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
struct confbridge_conference * conference
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.

References ast_bridge_destroy(), ast_channel_cleanup, ast_cond_wait, ast_debug, ast_free, ast_hangup(), ast_mutex_lock, ast_mutex_unlock, ast_taskprocessor_push(), ast_taskprocessor_unreference(), confbridge_conference::b_profile, confbridge_conference::bridge, conf_bridge_profile_destroy(), hangup_data::conference, hangup(), hangup_data_destroy(), hangup_data_init(), hangup_playback(), confbridge_conference::name, NULL, confbridge_conference::orig_rec_file, confbridge_conference::playback_chan, confbridge_conference::playback_queue, confbridge_conference::record_chan, and confbridge_conference::record_filename.

Referenced by join_conference_bridge().

◆ execute_menu_entry()

static int execute_menu_entry ( struct confbridge_conference conference,
struct confbridge_user user,
struct ast_bridge_channel bridge_channel,
struct conf_menu_entry menu_entry,
struct conf_menu menu 
)
static

Definition at line 3199 of file app_confbridge.c.

3204{
3205 struct conf_menu_action *menu_action;
3206 int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3207 int stop_prompts = 0;
3208 int res = 0;
3209
3210 AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
3211 switch (menu_action->id) {
3213 res |= action_toggle_mute(conference, user, bridge_channel);
3214 break;
3216 action_toggle_binaural(conference, user, bridge_channel);
3217 break;
3219 if (!isadmin) {
3220 break;
3221 }
3223 break;
3225 announce_user_count(conference, user, bridge_channel);
3226 break;
3228 if (!stop_prompts) {
3229 res |= action_playback(bridge_channel, menu_action->data.playback_file);
3230 ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
3231 "Message: %s\r\nChannel: %s",
3232 menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
3233 }
3234 break;
3237 break;
3240 break;
3244 break;
3248 break;
3252 break;
3256 break;
3258 if (!(stop_prompts)) {
3259 res |= action_playback_and_continue(conference,
3260 user,
3261 bridge_channel,
3262 menu,
3263 menu_action->data.playback_file,
3264 menu_entry->dtmf,
3265 &stop_prompts);
3266 }
3267 break;
3269 res |= action_dialplan_exec(bridge_channel, menu_action);
3270 break;
3272 if (!isadmin) {
3273 break;
3274 }
3275 conference->locked = (!conference->locked ? 1 : 0);
3276 res |= play_file(bridge_channel, NULL,
3279 conference->b_profile.sounds)) < 0;
3280 break;
3282 res |= action_kick_last(conference, bridge_channel, user);
3283 break;
3284 case MENU_ACTION_LEAVE:
3285 pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
3286 ao2_lock(conference);
3287 ast_bridge_remove(conference->bridge, bridge_channel->chan);
3288 ast_test_suite_event_notify("CONF_MENU_LEAVE",
3289 "Channel: %s",
3290 ast_channel_name(bridge_channel->chan));
3291 ao2_unlock(conference);
3292 break;
3293 case MENU_ACTION_NOOP:
3294 break;
3296 ao2_lock(conference);
3297 if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
3298 ast_bridge_set_single_src_video_mode(conference->bridge, bridge_channel->chan);
3299 }
3300 ao2_unlock(conference);
3301 break;
3303 handle_video_on_exit(conference, bridge_channel->chan);
3304 break;
3305 }
3306 }
3307 return res;
3308}
static int action_dialplan_exec(struct ast_bridge_channel *bridge_channel, struct conf_menu_action *menu_action)
static int action_playback_and_continue(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel, struct conf_menu *menu, const char *playback_file, const char *cur_dtmf, int *stop_prompts)
static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
static int action_toggle_mute(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
static int action_toggle_mute_participants(struct confbridge_conference *conference, struct confbridge_user *user)
static int announce_user_count(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
Announce number of users in the conference bridge to the caller.
static int action_kick_last(struct confbridge_conference *conference, struct ast_bridge_channel *bridge_channel, struct confbridge_user *user)
static int action_toggle_binaural(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
int ast_audiohook_volume_adjust(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
Adjust the volume on frames read from or written to a channel.
Definition: audiohook.c:1361
@ BRIDGE_OPT_VIDEO_SRC_SFU
Definition: confbridge.h:85
@ MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC
Definition: confbridge.h:112
@ MENU_ACTION_SET_SINGLE_VIDEO_SRC
Definition: confbridge.h:111
@ MENU_ACTION_ADMIN_KICK_LAST
Definition: confbridge.h:108
@ MENU_ACTION_TOGGLE_BINAURAL
Definition: confbridge.h:115
@ MENU_ACTION_PLAYBACK
Definition: confbridge.h:98
@ MENU_ACTION_LEAVE
Definition: confbridge.h:109
@ MENU_ACTION_RESET_LISTENING
Definition: confbridge.h:102
@ MENU_ACTION_INCREASE_TALKING
Definition: confbridge.h:104
@ MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS
Definition: confbridge.h:114
@ MENU_ACTION_INCREASE_LISTENING
Definition: confbridge.h:100
@ MENU_ACTION_DIALPLAN_EXEC
Definition: confbridge.h:106
@ MENU_ACTION_DECREASE_LISTENING
Definition: confbridge.h:101
@ MENU_ACTION_PLAYBACK_AND_CONTINUE
Definition: confbridge.h:99
@ MENU_ACTION_ADMIN_TOGGLE_LOCK
Definition: confbridge.h:107
@ MENU_ACTION_DECREASE_TALKING
Definition: confbridge.h:105
@ MENU_ACTION_PARTICIPANT_COUNT
Definition: confbridge.h:113
@ MENU_ACTION_TOGGLE_MUTE
Definition: confbridge.h:97
@ MENU_ACTION_NOOP
Definition: confbridge.h:110
@ MENU_ACTION_RESET_TALKING
Definition: confbridge.h:103
enum conf_menu_action_id id
Definition: confbridge.h:123
struct conf_menu_action::@89 action
char playback_file[PATH_MAX]
Definition: confbridge.h:125
struct conf_menu_entry::@91 actions

References conf_menu_action::action, action_dialplan_exec(), action_kick_last(), action_playback(), action_playback_and_continue(), action_toggle_binaural(), action_toggle_mute(), action_toggle_mute_participants(), conf_menu_entry::actions, announce_user_count(), ao2_lock, ao2_unlock, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_volume_adjust(), ast_audiohook_volume_set(), ast_bridge_remove(), ast_bridge_set_single_src_video_mode(), ast_channel_name(), AST_LIST_TRAVERSE, ast_test_flag, ast_test_suite_event_notify, confbridge_conference::b_profile, confbridge_conference::bridge, BRIDGE_OPT_VIDEO_SRC_SFU, ast_bridge_channel::chan, conf_get_sound(), CONF_SOUND_LOCKED_NOW, CONF_SOUND_UNLOCKED_NOW, conf_menu_action::data, conf_menu_entry::dtmf, handle_video_on_exit(), conf_menu_action::id, confbridge_conference::locked, MENU_ACTION_ADMIN_KICK_LAST, MENU_ACTION_ADMIN_TOGGLE_LOCK, MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS, MENU_ACTION_DECREASE_LISTENING, MENU_ACTION_DECREASE_TALKING, MENU_ACTION_DIALPLAN_EXEC, MENU_ACTION_INCREASE_LISTENING, MENU_ACTION_INCREASE_TALKING, MENU_ACTION_LEAVE, MENU_ACTION_NOOP, MENU_ACTION_PARTICIPANT_COUNT, MENU_ACTION_PLAYBACK, MENU_ACTION_PLAYBACK_AND_CONTINUE, MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC, MENU_ACTION_RESET_LISTENING, MENU_ACTION_RESET_TALKING, MENU_ACTION_SET_SINGLE_VIDEO_SRC, MENU_ACTION_TOGGLE_BINAURAL, MENU_ACTION_TOGGLE_MUTE, NULL, pbx_builtin_setvar_helper(), play_file(), conf_menu_action::playback_file, bridge_profile::sounds, and USER_OPT_ADMIN.

Referenced by action_playback_and_continue(), and conf_handle_dtmf().

◆ func_confbridge_channels()

static int func_confbridge_channels ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 3917 of file app_confbridge.c.

3918{
3919 char *parse, *outbuf;
3920 struct confbridge_conference *conference;
3921 struct confbridge_user *user;
3922 int bytes, count = 0;
3923 size_t outlen;
3926 AST_APP_ARG(confno);
3927 );
3928
3929 /* parse all the required arguments and make sure they exist. */
3930 if (ast_strlen_zero(data)) {
3931 return -1;
3932 }
3933 parse = ast_strdupa(data);
3935 if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
3936 ast_log(LOG_WARNING, "Usage: %s(category,confno)", cmd);
3937 return -1;
3938 }
3940 if (!conference) {
3941 ast_debug(1, "No such conference: %s\n", args.confno);
3942 return -1;
3943 }
3944
3945 outbuf = buf;
3946 outlen = len;
3947
3949 if (!strcasecmp(args.type, "parties")) {
3951 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3952 outbuf += bytes;
3953 outlen -= bytes;
3954 }
3956 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3957 outbuf += bytes;
3958 outlen -= bytes;
3959 }
3960 } else if (!strcasecmp(args.type, "active")) {
3962 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3963 outbuf += bytes;
3964 outlen -= bytes;
3965 }
3966 } else if (!strcasecmp(args.type, "waiting")) {
3968 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3969 outbuf += bytes;
3970 outlen -= bytes;
3971 }
3972 } else if (!strcasecmp(args.type, "admins")) {
3974 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
3975 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3976 outbuf += bytes;
3977 outlen -= bytes;
3978 }
3979 }
3980 } else if (!strcasecmp(args.type, "marked")) {
3982 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
3983 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
3984 outbuf += bytes;
3985 outlen -= bytes;
3986 }
3987 }
3988 } else {
3989 ast_log(LOG_ERROR, "Invalid keyword '%s' passed to %s.\n", args.type, cmd);
3990 }
3992 ao2_ref(conference, -1);
3993 return 0;
3994}
static const char type[]
Definition: chan_ooh323.c:109
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References confbridge_conference::active_list, ao2_find, ao2_lock, ao2_ref, ao2_unlock, args, AST_APP_ARG, ast_channel_name(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, buf, confbridge_user::conference, conference_bridges, len(), confbridge_user::list, LOG_ERROR, LOG_WARNING, OBJ_KEY, type, user, USER_OPT_ADMIN, USER_OPT_MARKEDUSER, and confbridge_conference::waiting_list.

◆ func_confbridge_info()

static int func_confbridge_info ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 4378 of file app_confbridge.c.

4379{
4380 char *parse;
4381 struct confbridge_conference *conference;
4382 struct confbridge_user *user;
4383 int count = 0;
4386 AST_APP_ARG(confno);
4387 );
4388
4389 /* parse all the required arguments and make sure they exist. */
4390 if (ast_strlen_zero(data)) {
4391 return -1;
4392 }
4393 parse = ast_strdupa(data);
4395 if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
4396 return -1;
4397 }
4399 if (!conference) {
4400 snprintf(buf, len, "0");
4401 return 0;
4402 }
4403
4404 /* get the correct count for the type requested */
4406 if (!strcasecmp(args.type, "parties")) {
4408 count++;
4409 }
4411 count++;
4412 }
4413 } else if (!strcasecmp(args.type, "admins")) {
4415 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
4416 count++;
4417 }
4418 }
4419 } else if (!strcasecmp(args.type, "marked")) {
4421 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
4422 count++;
4423 }
4424 }
4425 } else if (!strcasecmp(args.type, "locked")) {
4426 count = conference->locked;
4427 } else if (!strcasecmp(args.type, "muted")) {
4428 count = conference->muted;
4429 } else {
4430 ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
4431 }
4432 snprintf(buf, len, "%d", count);
4434 ao2_ref(conference, -1);
4435 return 0;
4436}

References confbridge_conference::active_list, ao2_find, ao2_lock, ao2_ref, ao2_unlock, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_LIST_TRAVERSE, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, buf, confbridge_user::conference, conference_bridges, len(), confbridge_user::list, confbridge_conference::locked, LOG_ERROR, confbridge_conference::muted, OBJ_KEY, type, user, USER_OPT_ADMIN, USER_OPT_MARKEDUSER, and confbridge_conference::waiting_list.

◆ generic_lock_unlock_helper()

static int generic_lock_unlock_helper ( int  lock,
const char *  conference_name 
)
static

Definition at line 3599 of file app_confbridge.c.

3600{
3601 struct confbridge_conference *conference;
3602 int res = 0;
3603
3604 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3605 if (!conference) {
3606 return -1;
3607 }
3608 ao2_lock(conference);
3609 conference->locked = lock;
3610 ast_test_suite_event_notify("CONF_LOCK", "Message: conference %s\r\nConference: %s", conference->locked ? "locked" : "unlocked", conference->b_profile.name);
3611 ao2_unlock(conference);
3612 ao2_ref(conference, -1);
3613
3614 return res;
3615}

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_test_suite_event_notify, confbridge_conference::b_profile, conference_bridges, lock, confbridge_conference::locked, bridge_profile::name, and OBJ_KEY.

Referenced by action_lock_unlock_helper(), handle_cli_confbridge_lock(), and handle_cli_confbridge_unlock().

◆ generic_mute_unmute_helper()

static int generic_mute_unmute_helper ( int  mute,
const char *  conference_name,
const char *  chan_name 
)
static

Definition at line 3624 of file app_confbridge.c.

3626{
3627 RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3628 struct confbridge_user *user;
3629 int all = !strcasecmp("all", chan_name);
3630 int participants = !strcasecmp("participants", chan_name);
3631 int res = -2;
3632
3633 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3634 if (!conference) {
3635 return -1;
3636 }
3637
3638 {
3639 SCOPED_AO2LOCK(bridge_lock, conference);
3641 int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3642 strlen(chan_name));
3643 if (match || all
3644 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3646 res = 0;
3647 if (match) {
3648 return res;
3649 }
3650 }
3651 }
3652
3654 int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3655 strlen(chan_name));
3656 if (match || all
3657 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3659 res = 0;
3660 if (match) {
3661 return res;
3662 }
3663 }
3664 }
3665 }
3666
3667 return res;
3668}
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362

References confbridge_conference::active_list, ao2_cleanup, ao2_find, ast_channel_name(), AST_LIST_TRAVERSE, ast_test_flag, confbridge_user::conference, conference_bridges, generic_mute_unmute_user(), confbridge_user::list, match(), NULL, OBJ_KEY, RAII_VAR, SCOPED_AO2LOCK, user, USER_OPT_ADMIN, and confbridge_conference::waiting_list.

Referenced by action_mute_unmute_helper(), and cli_mute_unmute_helper().

◆ generic_mute_unmute_user()

static void generic_mute_unmute_user ( struct confbridge_conference conference,
struct confbridge_user user,
int  mute 
)
static

Definition at line 1403 of file app_confbridge.c.

1404{
1405 /* Set user level mute request. */
1406 user->muted = mute ? 1 : 0;
1407
1409 ast_test_suite_event_notify("CONF_MUTE",
1410 "Message: participant %s %s\r\n"
1411 "Conference: %s\r\n"
1412 "Channel: %s",
1413 ast_channel_name(user->chan),
1414 mute ? "muted" : "unmuted",
1415 conference->b_profile.name,
1416 ast_channel_name(user->chan));
1417 if (mute) {
1418 send_mute_event(user, conference);
1419 } else {
1420 send_unmute_event(user, conference);
1421 }
1422}
static void send_mute_event(struct confbridge_user *user, struct confbridge_conference *conference)
static void send_unmute_event(struct confbridge_user *user, struct confbridge_conference *conference)

References ast_channel_name(), ast_test_suite_event_notify, confbridge_conference::b_profile, conf_update_user_mute(), hangup_data::conference, bridge_profile::name, send_mute_event(), and send_unmute_event().

Referenced by action_toggle_mute(), and generic_mute_unmute_helper().

◆ handle_cli_confbridge_kick()

static char * handle_cli_confbridge_kick ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3438 of file app_confbridge.c.

3439{
3440 struct confbridge_conference *conference;
3441 int not_found;
3442
3443 switch (cmd) {
3444 case CLI_INIT:
3445 e->command = "confbridge kick";
3446 e->usage =
3447 "Usage: confbridge kick <conference> <channel>\n"
3448 " Kicks a channel out of the conference bridge.\n"
3449 " (all to kick everyone, participants to kick non-admins).\n";
3450 return NULL;
3451 case CLI_GENERATE:
3452 if (a->pos == 2) {
3453 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3454 }
3455 if (a->pos == 3) {
3456 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3457 }
3458 return NULL;
3459 }
3460
3461 if (a->argc != 4) {
3462 return CLI_SHOWUSAGE;
3463 }
3464
3465 conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
3466 if (!conference) {
3467 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3468 return CLI_SUCCESS;
3469 }
3470 not_found = kick_conference_participant(conference, a->argv[3]);
3471 ao2_ref(conference, -1);
3472 if (not_found) {
3473 if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3474 ast_cli(a->fd, "No participants found!\n");
3475 } else {
3476 ast_cli(a->fd, "No participant named '%s' found!\n", a->argv[3]);
3477 }
3478 return CLI_SUCCESS;
3479 }
3480 ast_cli(a->fd, "Kicked '%s' out of conference '%s'\n", a->argv[3], a->argv[2]);
3481 return CLI_SUCCESS;
3482}
static char * complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

References a, ao2_find, ao2_ref, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), conference_bridges, kick_conference_participant(), NULL, OBJ_KEY, and ast_cli_entry::usage.

◆ handle_cli_confbridge_list()

static char * handle_cli_confbridge_list ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3520 of file app_confbridge.c.

3521{
3522 struct confbridge_conference *conference;
3523
3524 switch (cmd) {
3525 case CLI_INIT:
3526 e->command = "confbridge list";
3527 e->usage =
3528 "Usage: confbridge list [<name>]\n"
3529 " Lists all currently active conference bridges or a specific conference bridge.\n"
3530 "\n"
3531 " When a conference bridge name is provided, flags may be shown for users. Below\n"
3532 " are the flags and what they represent.\n"
3533 "\n"
3534 " Flags:\n"
3535 " A - The user is an admin\n"
3536 " M - The user is a marked user\n"
3537 " W - The user must wait for a marked user to join\n"
3538 " E - The user will be kicked after the last marked user leaves the conference\n"
3539 " m - The user is muted\n"
3540 " w - The user is waiting for a marked user to join\n";
3541 return NULL;
3542 case CLI_GENERATE:
3543 if (a->pos == 2) {
3544 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3545 }
3546 return NULL;
3547 }
3548
3549 if (a->argc == 2) {
3550 struct ao2_iterator iter;
3551
3552 ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
3553 ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
3555 while ((conference = ao2_iterator_next(&iter))) {
3556 ast_cli(a->fd, "%-32s %6u %6u %-6s %s\n",
3557 conference->name,
3558 conference->activeusers + conference->waitingusers,
3559 conference->markedusers,
3560 AST_CLI_YESNO(conference->locked),
3561 AST_CLI_YESNO(conference->muted));
3562 ao2_ref(conference, -1);
3563 }
3564 ao2_iterator_destroy(&iter);
3565 return CLI_SUCCESS;
3566 }
3567
3568 if (a->argc == 3) {
3569 struct confbridge_user *user;
3570
3572 if (!conference) {
3573 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3574 return CLI_SUCCESS;
3575 }
3576 ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu CallerID\n");
3577 ast_cli(a->fd, "============================== ====== ================ ================ ================ ================\n");
3581 }
3584 }
3586 ao2_ref(conference, -1);
3587 return CLI_SUCCESS;
3588 }
3589
3590 return CLI_SHOWUSAGE;
3591}
static void handle_cli_confbridge_list_item(struct ast_cli_args *a, struct confbridge_user *user, int waiting)
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71

References a, confbridge_conference::active_list, confbridge_conference::activeusers, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), AST_CLI_YESNO, AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), confbridge_user::conference, conference_bridges, handle_cli_confbridge_list_item(), confbridge_user::list, confbridge_conference::locked, confbridge_conference::markedusers, confbridge_conference::muted, confbridge_conference::name, NULL, OBJ_KEY, ast_cli_entry::usage, user, confbridge_conference::waiting_list, and confbridge_conference::waitingusers.

◆ handle_cli_confbridge_list_item()

static void handle_cli_confbridge_list_item ( struct ast_cli_args a,
struct confbridge_user user,
int  waiting 
)
static

Definition at line 3484 of file app_confbridge.c.

3485{
3486 char flag_str[6 + 1];/* Max flags + terminator */
3487 int pos = 0;
3488
3489 /* Build flags column string. */
3490 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
3491 flag_str[pos++] = 'A';
3492 }
3493 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
3494 flag_str[pos++] = 'M';
3495 }
3496 if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
3497 flag_str[pos++] = 'W';
3498 }
3499 if (ast_test_flag(&user->u_profile, USER_OPT_ENDMARKED)) {
3500 flag_str[pos++] = 'E';
3501 }
3502 if (user->muted) {
3503 flag_str[pos++] = 'm';
3504 }
3505 if (waiting) {
3506 flag_str[pos++] = 'w';
3507 }
3508 flag_str[pos] = '\0';
3509
3510 ast_cli(a->fd, "%-30s %-6s %-16s %-16s %-16s %s\n",
3511 ast_channel_name(user->chan),
3512 flag_str,
3513 user->u_profile.name,
3514 user->conference->b_profile.name,
3515 user->menu_name,
3517 ast_channel_caller(user->chan)->id.number.str, "<unknown>"));
3518}
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
struct ast_party_id id
Caller party ID.
Definition: channel.h:422
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:344
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:299
char * str
Subscriber phone number (Malloced)
Definition: channel.h:293

References a, ast_channel_caller(), ast_channel_name(), ast_cli(), ast_test_flag, ast_party_caller::id, ast_party_id::number, S_COR, ast_party_number::str, USER_OPT_ADMIN, USER_OPT_ENDMARKED, USER_OPT_MARKEDUSER, USER_OPT_WAITMARKED, and ast_party_number::valid.

Referenced by handle_cli_confbridge_list().

◆ handle_cli_confbridge_lock()

static char * handle_cli_confbridge_lock ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3751 of file app_confbridge.c.

3752{
3753 switch (cmd) {
3754 case CLI_INIT:
3755 e->command = "confbridge lock";
3756 e->usage =
3757 "Usage: confbridge lock <conference>\n"
3758 " Lock a conference. While locked, no new non-admins\n"
3759 " may join the conference.\n";
3760 return NULL;
3761 case CLI_GENERATE:
3762 if (a->pos == 2) {
3763 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3764 }
3765 return NULL;
3766 }
3767 if (a->argc != 3) {
3768 return CLI_SHOWUSAGE;
3769 }
3770 if (generic_lock_unlock_helper(1, a->argv[2])) {
3771 ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3772 } else {
3773 ast_cli(a->fd, "Conference %s is locked.\n", a->argv[2]);
3774 }
3775 return CLI_SUCCESS;
3776}

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), generic_lock_unlock_helper(), NULL, and ast_cli_entry::usage.

◆ handle_cli_confbridge_mute()

static char * handle_cli_confbridge_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3689 of file app_confbridge.c.

3690{
3691 switch (cmd) {
3692 case CLI_INIT:
3693 e->command = "confbridge mute";
3694 e->usage =
3695 "Usage: confbridge mute <conference> <channel>\n"
3696 " Mute a channel in a conference.\n"
3697 " (all to mute everyone, participants to mute non-admins)\n"
3698 " If the specified channel is a prefix,\n"
3699 " the action will be taken on the first\n"
3700 " matching channel.\n";
3701 return NULL;
3702 case CLI_GENERATE:
3703 if (a->pos == 2) {
3704 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3705 }
3706 if (a->pos == 3) {
3707 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3708 }
3709 return NULL;
3710 }
3711 if (a->argc != 4) {
3712 return CLI_SHOWUSAGE;
3713 }
3714
3716
3717 return CLI_SUCCESS;
3718}
static int cli_mute_unmute_helper(int mute, struct ast_cli_args *a)

References a, CLI_GENERATE, CLI_INIT, cli_mute_unmute_helper(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), NULL, and ast_cli_entry::usage.

◆ handle_cli_confbridge_start_record()

static char * handle_cli_confbridge_start_record ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3804 of file app_confbridge.c.

3805{
3806 const char *rec_file = NULL;
3807 struct confbridge_conference *conference;
3808
3809 switch (cmd) {
3810 case CLI_INIT:
3811 e->command = "confbridge record start";
3812 e->usage =
3813 "Usage: confbridge record start <conference> <file>\n"
3814 " <file> is optional, Otherwise the bridge profile\n"
3815 " record file will be used. If the bridge profile\n"
3816 " has no record file specified, a file will automatically\n"
3817 " be generated in the monitor directory\n";
3818 return NULL;
3819 case CLI_GENERATE:
3820 if (a->pos == 3) {
3821 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3822 }
3823 return NULL;
3824 }
3825 if (a->argc < 4) {
3826 return CLI_SHOWUSAGE;
3827 }
3828 if (a->argc == 5) {
3829 rec_file = a->argv[4];
3830 }
3831
3832 conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3833 if (!conference) {
3834 ast_cli(a->fd, "Conference not found.\n");
3835 return CLI_FAILURE;
3836 }
3837 ao2_lock(conference);
3838 if (conf_is_recording(conference)) {
3839 ast_cli(a->fd, "Conference is already being recorded.\n");
3840 ao2_unlock(conference);
3841 ao2_ref(conference, -1);
3842 return CLI_SUCCESS;
3843 }
3844 if (!ast_strlen_zero(rec_file)) {
3845 ast_copy_string(conference->b_profile.rec_file, rec_file, sizeof(conference->b_profile.rec_file));
3846 }
3847
3848 if (conf_start_record(conference)) {
3849 ast_cli(a->fd, "Could not start recording due to internal error.\n");
3850 ao2_unlock(conference);
3851 ao2_ref(conference, -1);
3852 return CLI_FAILURE;
3853 }
3854 ao2_unlock(conference);
3855
3856 ast_cli(a->fd, "Recording started\n");
3857 ao2_ref(conference, -1);
3858 return CLI_SUCCESS;
3859}
#define CLI_FAILURE
Definition: cli.h:46

References a, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), ast_copy_string(), ast_strlen_zero(), confbridge_conference::b_profile, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), conf_is_recording(), conf_start_record(), conference_bridges, NULL, OBJ_KEY, bridge_profile::rec_file, and ast_cli_entry::usage.

◆ handle_cli_confbridge_stop_record()

static char * handle_cli_confbridge_stop_record ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3861 of file app_confbridge.c.

3862{
3863 struct confbridge_conference *conference;
3864 int ret;
3865
3866 switch (cmd) {
3867 case CLI_INIT:
3868 e->command = "confbridge record stop";
3869 e->usage =
3870 "Usage: confbridge record stop <conference>\n"
3871 " Stop a previously started recording.\n";
3872 return NULL;
3873 case CLI_GENERATE:
3874 if (a->pos == 3) {
3875 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3876 }
3877 return NULL;
3878 }
3879 if (a->argc != 4) {
3880 return CLI_SHOWUSAGE;
3881 }
3882
3883 conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3884 if (!conference) {
3885 ast_cli(a->fd, "Conference not found.\n");
3886 return CLI_SUCCESS;
3887 }
3888 ao2_lock(conference);
3889 ret = conf_stop_record(conference);
3890 ao2_unlock(conference);
3891 ast_cli(a->fd, "Recording %sstopped.\n", ret ? "could not be " : "");
3892 ao2_ref(conference, -1);
3893 return CLI_SUCCESS;
3894}

References a, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), conf_stop_record(), conference_bridges, NULL, OBJ_KEY, and ast_cli_entry::usage.

◆ handle_cli_confbridge_unlock()

static char * handle_cli_confbridge_unlock ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3778 of file app_confbridge.c.

3779{
3780 switch (cmd) {
3781 case CLI_INIT:
3782 e->command = "confbridge unlock";
3783 e->usage =
3784 "Usage: confbridge unlock <conference>\n"
3785 " Unlock a previously locked conference.\n";
3786 return NULL;
3787 case CLI_GENERATE:
3788 if (a->pos == 2) {
3789 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3790 }
3791 return NULL;
3792 }
3793 if (a->argc != 3) {
3794 return CLI_SHOWUSAGE;
3795 }
3796 if (generic_lock_unlock_helper(0, a->argv[2])) {
3797 ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3798 } else {
3799 ast_cli(a->fd, "Conference %s is unlocked.\n", a->argv[2]);
3800 }
3801 return CLI_SUCCESS;
3802}

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), generic_lock_unlock_helper(), NULL, and ast_cli_entry::usage.

◆ handle_cli_confbridge_unmute()

static char * handle_cli_confbridge_unmute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3720 of file app_confbridge.c.

3721{
3722 switch (cmd) {
3723 case CLI_INIT:
3724 e->command = "confbridge unmute";
3725 e->usage =
3726 "Usage: confbridge unmute <conference> <channel>\n"
3727 " Unmute a channel in a conference.\n"
3728 " (all to unmute everyone, participants to unmute non-admins)\n"
3729 " If the specified channel is a prefix,\n"
3730 " the action will be taken on the first\n"
3731 " matching channel.\n";
3732 return NULL;
3733 case CLI_GENERATE:
3734 if (a->pos == 2) {
3735 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3736 }
3737 if (a->pos == 3) {
3738 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3739 }
3740 return NULL;
3741 }
3742 if (a->argc != 4) {
3743 return CLI_SHOWUSAGE;
3744 }
3745
3747
3748 return CLI_SUCCESS;
3749}

References a, CLI_GENERATE, CLI_INIT, cli_mute_unmute_helper(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), NULL, and ast_cli_entry::usage.

◆ handle_conf_user_join()

static int handle_conf_user_join ( struct confbridge_user user)
static

Call the proper join event handler for the user for the conference bridge's current state.

Definition at line 1311 of file app_confbridge.c.

1312{
1314 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1315 handler = user->conference->state->join_marked;
1316 } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1317 handler = user->conference->state->join_waitmarked;
1318 } else {
1319 handler = user->conference->state->join_unmarked;
1320 }
1321
1323
1324 if (!handler) {
1326 return -1;
1327 }
1328
1329 handler(user);
1330
1331 return 0;
1332}
void conf_invalid_event_fn(struct confbridge_user *user)
A handler for join/leave events that are invalid in a particular state.
Definition: conf_state.c:42
void(* conference_event_fn)(struct confbridge_user *user)
Definition: conf_state.h:40
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59

References ast_assert, ast_test_flag, conf_invalid_event_fn(), handler(), NULL, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by join_conference_bridge().

◆ handle_conf_user_leave()

static int handle_conf_user_leave ( struct confbridge_user user)
static

Call the proper leave event handler for the user for the conference bridge's current state.

Definition at line 1340 of file app_confbridge.c.

1341{
1343 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1344 handler = user->conference->state->leave_marked;
1345 } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1346 handler = user->conference->state->leave_waitmarked;
1347 } else {
1348 handler = user->conference->state->leave_unmarked;
1349 }
1350
1352
1353 if (!handler) {
1354 /* This should never happen. If it does, though, it is bad. The user will not have been removed
1355 * from the appropriate list, so counts will be off and stuff. The conference won't be torn down, etc.
1356 * Shouldn't happen, though. */
1358 return -1;
1359 }
1360
1361 handler(user);
1362
1363 return 0;
1364}

References ast_assert, ast_test_flag, conf_invalid_event_fn(), handler(), NULL, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by leave_conference().

◆ handle_video_on_exit()

static void handle_video_on_exit ( struct confbridge_conference conference,
struct ast_channel chan 
)
static

Definition at line 1168 of file app_confbridge.c.

1169{
1170 struct confbridge_user *user = NULL;
1171
1172 /* if this isn't a video source, nothing to update */
1174 return;
1175 }
1176
1178
1179 /* If in follow talker mode, make sure to restore this mode on the
1180 * bridge when a source is removed. It is possible this channel was
1181 * only set temporarily as a video source by an AMI or DTMF action. */
1184 }
1185
1186 /* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
1189 return;
1190 }
1191
1192 /* Make the next available marked user the video src. */
1195 if (user->chan == chan) {
1196 continue;
1197 }
1198 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1200 break;
1201 }
1202 }
1204}
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
Set the bridge to pick the strongest talker supporting video as the single source video feed.
Definition: bridge.c:3766
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
remove a channel as a source of video for the bridge.
Definition: bridge.c:3917
int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
Determine if a channel is a video src for the bridge.
Definition: bridge.c:3891
@ BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER
Definition: confbridge.h:81
@ BRIDGE_OPT_VIDEO_SRC_LAST_MARKED
Definition: confbridge.h:79
@ BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED
Definition: confbridge.h:80

References confbridge_conference::active_list, ao2_lock, ao2_unlock, ast_bridge_is_video_src(), ast_bridge_remove_video_src(), ast_bridge_set_single_src_video_mode(), ast_bridge_set_talker_src_video_mode(), AST_LIST_TRAVERSE, ast_test_flag, confbridge_conference::b_profile, confbridge_conference::bridge, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED, confbridge_user::chan, confbridge_user::conference, confbridge_user::list, NULL, and USER_OPT_MARKEDUSER.

Referenced by confbridge_exec(), and execute_menu_entry().

◆ handle_video_on_join()

static void handle_video_on_join ( struct confbridge_conference conference,
struct ast_channel chan,
int  marked 
)
static

Definition at line 1136 of file app_confbridge.c.

1137{
1138 /* Right now, only marked users are automatically set as the single src of video.*/
1139 if (!marked) {
1140 return;
1141 }
1142
1144 int set = 1;
1145 struct confbridge_user *user = NULL;
1146
1148 /* see if anyone is already the video src */
1150 if (user->chan == chan) {
1151 continue;
1152 }
1154 set = 0;
1155 break;
1156 }
1157 }
1159 if (set) {
1161 }
1163 /* we joined and are video capable, we override anyone else that may have already been the video feed */
1165 }
1166}
static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_logic.c:238

References confbridge_conference::active_list, ao2_lock, ao2_unlock, ast_bridge_is_video_src(), ast_bridge_set_single_src_video_mode(), AST_LIST_TRAVERSE, ast_test_flag, confbridge_conference::b_profile, confbridge_conference::bridge, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED, confbridge_user::chan, confbridge_user::conference, confbridge_user::list, NULL, and set().

Referenced by confbridge_exec().

◆ hangup_data_destroy()

static void hangup_data_destroy ( struct hangup_data hangup)
static

Definition at line 1253 of file app_confbridge.c.

1254{
1255 ast_mutex_destroy(&hangup->lock);
1256 ast_cond_destroy(&hangup->cond);
1257}

References ast_cond_destroy, ast_mutex_destroy, and hangup().

Referenced by destroy_conference_bridge().

◆ hangup_data_init()

static void hangup_data_init ( struct hangup_data hangup,
struct confbridge_conference conference 
)
static

Definition at line 1244 of file app_confbridge.c.

1245{
1246 ast_mutex_init(&hangup->lock);
1247 ast_cond_init(&hangup->cond, NULL);
1248
1249 hangup->conference = conference;
1250 hangup->hungup = 0;
1251}

References ast_cond_init, ast_mutex_init, hangup_data::conference, hangup(), and NULL.

Referenced by destroy_conference_bridge().

◆ hangup_playback()

static int hangup_playback ( void *  data)
static

Hang up the announcer channel.

This hangs up the announcer channel in the conference. This runs in the playback queue taskprocessor since we do not want to hang up the channel while it's trying to play an announcement.

This task is performed synchronously, so there is no need to perform any cleanup on the passed-in data.

Parameters
dataA hangup_data structure
Returns
0

Definition at line 1227 of file app_confbridge.c.

1228{
1229 struct hangup_data *hangup = data;
1230
1231 ast_autoservice_stop(hangup->conference->playback_chan);
1232
1233 ast_hangup(hangup->conference->playback_chan);
1234 hangup->conference->playback_chan = NULL;
1235
1236 ast_mutex_lock(&hangup->lock);
1237 hangup->hungup = 1;
1238 ast_cond_signal(&hangup->cond);
1239 ast_mutex_unlock(&hangup->lock);
1240
1241 return 0;
1242}

References ast_autoservice_stop(), ast_cond_signal, ast_hangup(), ast_mutex_lock, ast_mutex_unlock, hangup(), and NULL.

Referenced by destroy_conference_bridge().

◆ is_new_rec_file()

static int is_new_rec_file ( const char *  rec_file,
struct ast_str **  orig_rec_file 
)
static

Definition at line 859 of file app_confbridge.c.

860{
861 if (!ast_strlen_zero(rec_file)) {
862 if (!*orig_rec_file) {
864 }
865
866 if (*orig_rec_file
867 && strcmp(ast_str_buffer(*orig_rec_file), rec_file)) {
868 ast_str_set(orig_rec_file, 0, "%s", rec_file);
869 return 1;
870 }
871 }
872 return 0;
873}
#define RECORD_FILENAME_INITIAL_SPACE
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113

References ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), and RECORD_FILENAME_INITIAL_SPACE.

Referenced by conf_start_record().

◆ join_callback()

static int join_callback ( struct ast_bridge_channel bridge_channel,
void *  ignore 
)
static

Definition at line 2607 of file app_confbridge.c.

2608{
2609 async_play_sound_ready(bridge_channel->chan);
2610 return 0;
2611}

References async_play_sound_ready(), and ast_bridge_channel::chan.

Referenced by confbridge_exec().

◆ join_conference_bridge()

static struct confbridge_conference * join_conference_bridge ( const char *  conference_name,
struct confbridge_user user 
)
static

Join a conference bridge.

Parameters
conference_nameThe conference name
userConference bridge user structure
Returns
A pointer to the conference bridge struct, or NULL if the conference room wasn't found.

Definition at line 1766 of file app_confbridge.c.

1767{
1768 struct confbridge_conference *conference;
1769 struct post_join_action *action;
1770 int max_members_reached = 0;
1771
1772 /* We explicitly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same time */
1774
1775 ast_debug(1, "Trying to find conference bridge '%s'\n", conference_name);
1776
1777 /* Attempt to find an existing conference bridge */
1778 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
1779 if (conference && conference->b_profile.max_members) {
1780 max_members_reached = conference->b_profile.max_members > conference->activeusers ? 0 : 1;
1781 }
1782
1783 /* When finding a conference bridge that already exists make sure that it is not locked, and if so that we are not an admin */
1784 if (conference && (max_members_reached || conference->locked) && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
1786 ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", conference_name);
1789 "");
1790 ao2_ref(conference, -1);
1791 return NULL;
1792 }
1793
1794 /* If no conference bridge was found see if we can create one */
1795 if (!conference) {
1796 /* Try to allocate memory for a new conference bridge, if we fail... this won't end well. */
1797 if (!(conference = ao2_alloc(sizeof(*conference), destroy_conference_bridge))) {
1799 ast_log(LOG_ERROR, "Conference '%s' could not be created.\n", conference_name);
1800 return NULL;
1801 }
1802
1803 /* Setup for the record channel */
1805 if (!conference->record_filename) {
1806 ao2_ref(conference, -1);
1808 return NULL;
1809 }
1810
1811 /* Setup conference bridge parameters */
1812 ast_copy_string(conference->name, conference_name, sizeof(conference->name));
1813 conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
1814
1815 /* Create an actual bridge that will do the audio mixing */
1818 app, conference_name, NULL);
1819 if (!conference->bridge) {
1820 ao2_ref(conference, -1);
1822 ast_log(LOG_ERROR, "Conference '%s' mixing bridge could not be created.\n", conference_name);
1823 return NULL;
1824 }
1825
1826 /* Set the internal sample rate on the bridge from the bridge profile */
1828 /* Set the maximum sample rate on the bridge from the bridge profile */
1830 /* Set the internal mixing interval on the bridge from the bridge profile */
1833
1836 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
1841 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST)) {
1843 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
1851 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_FORCE)) {
1854 }
1855 }
1856
1857 /* Always set the minimum interval between video updates, to avoid infinite video updates. */
1859
1861 ast_bridge_set_send_sdp_label(conference->bridge, 1);
1862 }
1863
1864 /* Link it into the conference bridges container */
1865 if (!ao2_link(conference_bridges, conference)) {
1866 ao2_ref(conference, -1);
1869 "Conference '%s' could not be added to the conferences list.\n", conference_name);
1870 return NULL;
1871 }
1872
1873 /* Set the initial state to EMPTY */
1874 conference->state = CONF_STATE_EMPTY;
1875
1876 if (alloc_playback_chan(conference)) {
1877 ao2_unlink(conference_bridges, conference);
1878 ao2_ref(conference, -1);
1880 ast_log(LOG_ERROR, "Could not allocate announcer channel for conference '%s'\n", conference_name);
1881 return NULL;
1882 }
1883
1884 if (push_announcer(conference)) {
1885 ao2_unlink(conference_bridges, conference);
1886 ao2_ref(conference, -1);
1888 ast_log(LOG_ERROR, "Could not add announcer channel for conference '%s' bridge\n", conference_name);
1889 return NULL;
1890 }
1891
1893 ao2_lock(conference);
1894 conf_start_record(conference);
1895 ao2_unlock(conference);
1896 }
1897
1898 send_conf_start_event(conference);
1899
1900 if (!ast_strlen_zero(conference->b_profile.regcontext)) {
1901 if (!ast_exists_extension(NULL, conference->b_profile.regcontext, conference->name, 1, NULL)) {
1902 ast_add_extension(conference->b_profile.regcontext, 1, conference->name, 1, NULL, NULL, "Noop", NULL, NULL, "ConfBridge");
1903 }
1904 }
1905
1906 ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
1907 }
1908
1910
1911 /* Setup conference bridge user parameters */
1912 user->conference = conference;
1913
1914 ao2_lock(conference);
1915
1916 /* Determine if the new user should join the conference muted. */
1917 if (ast_test_flag(&user->u_profile, USER_OPT_STARTMUTED)
1918 || (!ast_test_flag(&user->u_profile, USER_OPT_ADMIN) && conference->muted)) {
1919 /* Set user level mute request. */
1920 user->muted = 1;
1921 }
1922
1923 /*
1924 * Suspend any MOH until the user actually joins the bridge of
1925 * the conference. This way any pre-join file playback does not
1926 * need to worry about MOH.
1927 */
1928 user->suspended_moh = 1;
1929
1931 /* Invalid event, nothing was done, so we don't want to process a leave. */
1932 ao2_unlock(conference);
1933 ao2_ref(conference, -1);
1934 user->conference = NULL;
1935 return NULL;
1936 }
1937
1938 if (ast_check_hangup(user->chan)) {
1939 ao2_unlock(conference);
1941 return NULL;
1942 }
1943
1944 ao2_unlock(conference);
1945
1946 /* If an announcement is to be played play it */
1947 if (!ast_strlen_zero(user->u_profile.announcement)) {
1949 user->u_profile.announcement)) {
1951 return NULL;
1952 }
1953 }
1954
1955 /* Announce number of users if need be */
1956 if (ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCEUSERCOUNT)) {
1957 if (announce_user_count(conference, user, NULL)) {
1959 return NULL;
1960 }
1961 }
1962
1964 (conference->activeusers > user->u_profile.announce_user_count_all_after)) {
1965 int user_count_res;
1966
1967 /*
1968 * We have to autoservice the new user because he has not quite
1969 * joined the conference yet.
1970 */
1972 user_count_res = announce_user_count(conference, NULL, NULL);
1974 if (user_count_res) {
1976 return NULL;
1977 }
1978 }
1979
1980 /* Handle post-join actions */
1981 while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
1982 action->func(user);
1983 ast_free(action);
1984 }
1985
1986 return conference;
1987}
static int push_announcer(struct confbridge_conference *conference)
Push the announcer channel into the bridge.
static void send_conf_start_event(struct confbridge_conference *conference)
static void destroy_conference_bridge(void *obj)
Destroy a conference bridge.
static int handle_conf_user_join(struct confbridge_user *user)
Call the proper join event handler for the user for the conference bridge's current state.
static int alloc_playback_chan(struct confbridge_conference *conference)
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
void ast_bridge_set_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate)
Force the REMB report estimated bitrate to a specific max value.
Definition: bridge.c:3807
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:934
void ast_bridge_set_binaural_active(struct ast_bridge *bridge, unsigned int binaural_active)
Activates the use of binaural signals in a conference bridge.
Definition: bridge.c:3705
@ AST_BRIDGE_VIDEO_SFU_REMB_LOWEST
Definition: bridge.h:135
@ AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL
Definition: bridge.h:143
@ AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE
Definition: bridge.h:133
@ AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST
Definition: bridge.h:137
@ AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL
Definition: bridge.h:139
@ AST_BRIDGE_VIDEO_SFU_REMB_FORCE
Definition: bridge.h:145
@ AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL
Definition: bridge.h:141
void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge)
Set the bridge to be a selective forwarding unit.
Definition: bridge.c:3774
void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the maximum mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3719
void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard)
Set the amount of time to discard subsequent video updates after a video update has been sent.
Definition: bridge.c:3782
void ast_brige_set_remb_behavior(struct ast_bridge *bridge, enum ast_bridge_video_sfu_remb_behavior behavior)
Set the REMB report generation behavior on a bridge.
Definition: bridge.c:3798
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:94
void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
Adjust the internal mixing interval of a bridge used during multimix mode.
Definition: bridge.c:3698
void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label)
Controls whether to send a "label" attribute in each stream in an SDP.
Definition: bridge.c:3966
void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval)
Set the interval at which a combined REMB frame will be sent to video sources.
Definition: bridge.c:3789
void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the internal mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3712
@ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
void conf_bridge_profile_copy(struct bridge_profile *dst, struct bridge_profile *src)
copies a bridge profile
struct confbridge_state * CONF_STATE_EMPTY
Conference state with no active or waiting users.
@ USER_OPT_ANNOUNCEUSERCOUNTALL
Definition: confbridge.h:66
@ USER_OPT_ANNOUNCEUSERCOUNT
Definition: confbridge.h:58
@ USER_OPT_STARTMUTED
Definition: confbridge.h:55
@ BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE
Definition: confbridge.h:86
@ BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL
Definition: confbridge.h:92
@ BRIDGE_OPT_REMB_BEHAVIOR_LOWEST
Definition: confbridge.h:87
@ BRIDGE_OPT_BINAURAL_ACTIVE
Definition: confbridge.h:84
@ BRIDGE_OPT_RECORD_CONFERENCE
Definition: confbridge.h:78
@ BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL
Definition: confbridge.h:91
@ BRIDGE_OPT_ENABLE_EVENTS
Definition: confbridge.h:89
@ BRIDGE_OPT_REMB_BEHAVIOR_FORCE
Definition: confbridge.h:93
@ BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL
Definition: confbridge.h:90
@ BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST
Definition: confbridge.h:88
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6928
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
unsigned int remb_send_interval
Definition: confbridge.h:241
unsigned int maximum_sample_rate
Definition: confbridge.h:236
unsigned int remb_estimated_bitrate
Definition: confbridge.h:242
unsigned int mix_interval
Definition: confbridge.h:237
unsigned int video_update_discard
Definition: confbridge.h:240
unsigned int internal_sample_rate
Definition: confbridge.h:235
unsigned int max_members
Definition: confbridge.h:234
struct confbridge_state * state
Definition: confbridge.h:248

References confbridge_conference::activeusers, alloc_playback_chan(), announce_user_count(), ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, app, ast_add_extension(), ast_autoservice_start(), ast_autoservice_stop(), ast_bridge_base_new(), AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_FLAG_MASQUERADE_ONLY, AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY, ast_bridge_set_binaural_active(), ast_bridge_set_internal_sample_rate(), ast_bridge_set_maximum_sample_rate(), ast_bridge_set_mixing_interval(), ast_bridge_set_remb_estimated_bitrate(), ast_bridge_set_remb_send_interval(), ast_bridge_set_send_sdp_label(), ast_bridge_set_sfu_video_mode(), ast_bridge_set_talker_src_video_mode(), ast_bridge_set_video_update_discard(), AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE, AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL, AST_BRIDGE_VIDEO_SFU_REMB_FORCE, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL, ast_brige_set_remb_behavior(), ast_check_hangup(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_free, AST_LIST_REMOVE_HEAD, ast_log, ast_str_create, ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, confbridge_conference::b_profile, confbridge_conference::bridge, BRIDGE_OPT_BINAURAL_ACTIVE, BRIDGE_OPT_ENABLE_EVENTS, BRIDGE_OPT_RECORD_CONFERENCE, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL, BRIDGE_OPT_REMB_BEHAVIOR_FORCE, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER, BRIDGE_OPT_VIDEO_SRC_SFU, conf_bridge_profile_copy(), conf_get_sound(), CONF_SOUND_LOCKED, conf_start_record(), CONF_STATE_EMPTY, conference_bridges, destroy_conference_bridge(), post_join_action::func, handle_conf_user_join(), bridge_profile::internal_sample_rate, leave_conference(), post_join_action::list, confbridge_conference::locked, LOG_ERROR, bridge_profile::max_members, bridge_profile::maximum_sample_rate, bridge_profile::mix_interval, confbridge_conference::muted, confbridge_conference::name, NULL, OBJ_KEY, play_prompt_to_user(), push_announcer(), confbridge_conference::record_filename, RECORD_FILENAME_INITIAL_SPACE, bridge_profile::regcontext, bridge_profile::remb_estimated_bitrate, bridge_profile::remb_send_interval, send_conf_start_event(), bridge_profile::sounds, confbridge_conference::state, USER_OPT_ADMIN, USER_OPT_ANNOUNCEUSERCOUNT, USER_OPT_ANNOUNCEUSERCOUNTALL, USER_OPT_STARTMUTED, and bridge_profile::video_update_discard.

Referenced by confbridge_exec().

◆ kick_conference_participant()

static int kick_conference_participant ( struct confbridge_conference conference,
const char *  channel 
)
static

Definition at line 3329 of file app_confbridge.c.

3331{
3332 int res = -1;
3333 int match;
3334 struct confbridge_user *user = NULL;
3335 int all = !strcasecmp("all", channel);
3336 int participants = !strcasecmp("participants", channel);
3337
3338 SCOPED_AO2LOCK(bridge_lock, conference);
3339
3341 if (user->kicked) {
3342 continue;
3343 }
3344 match = !strcasecmp(channel, ast_channel_name(user->chan));
3345 if (match || all
3346 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3347 user->kicked = 1;
3348 pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3350 res = 0;
3351 if (match) {
3352 return res;
3353 }
3354 }
3355 }
3357 if (user->kicked) {
3358 continue;
3359 }
3360 match = !strcasecmp(channel, ast_channel_name(user->chan));
3361 if (match || all
3362 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3363 user->kicked = 1;
3364 pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3366 res = 0;
3367 if (match) {
3368 return res;
3369 }
3370 }
3371 }
3372
3373 return res;
3374}

References confbridge_conference::active_list, ast_bridge_remove(), ast_channel_name(), AST_LIST_TRAVERSE, ast_test_flag, confbridge_conference::bridge, confbridge_user::conference, confbridge_user::list, match(), NULL, pbx_builtin_setvar_helper(), SCOPED_AO2LOCK, USER_OPT_ADMIN, and confbridge_conference::waiting_list.

Referenced by action_confbridgekick(), confkick_exec(), and handle_cli_confbridge_kick().

◆ leave_conference()

static void leave_conference ( struct confbridge_user user)
static

Leave a conference.

Parameters
userThe conference user

Definition at line 1994 of file app_confbridge.c.

1995{
1996 struct post_join_action *action;
1997
1998 ao2_lock(user->conference);
2000 ao2_unlock(user->conference);
2001
2002 /* Discard any post-join actions */
2003 while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
2004 ast_free(action);
2005 }
2006
2007 /* Done mucking with the conference, huzzah */
2008 ao2_ref(user->conference, -1);
2009 user->conference = NULL;
2010}
static int handle_conf_user_leave(struct confbridge_user *user)
Call the proper leave event handler for the user for the conference bridge's current state.

References ao2_lock, ao2_ref, ao2_unlock, ast_free, AST_LIST_REMOVE_HEAD, handle_conf_user_leave(), post_join_action::list, and NULL.

Referenced by confbridge_exec(), and join_conference_bridge().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 4620 of file app_confbridge.c.

4621{
4622 int res = 0;
4623
4624 if (conf_load_config()) {
4625 ast_log(LOG_ERROR, "Unable to load config. Not loading module.\n");
4627 }
4628
4631 unload_module();
4633 }
4634
4635 /* Create a container to hold the conference bridges */
4639 if (!conference_bridges) {
4640 unload_module();
4642 }
4643
4644 /* Setup manager stasis subscriptions */
4645 res |= manager_confbridge_init();
4646
4649
4653
4655
4665 res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
4666 if (res) {
4667 unload_module();
4669 }
4670
4672}
static int action_confbridgemute(struct mansession *s, const struct message *m)
static int action_confbridgeunlock(struct mansession *s, const struct message *m)
static int action_confbridgekick(struct mansession *s, const struct message *m)
static int register_channel_tech(struct ast_channel_tech *tech)
static int action_confbridgesetsinglevideosrc(struct mansession *s, const struct message *m)
static int action_confbridgeunmute(struct mansession *s, const struct message *m)
static int action_confbridgestoprecord(struct mansession *s, const struct message *m)
static struct ast_custom_function confbridge_function
#define CONFERENCE_BRIDGE_BUCKETS
static int action_confbridgelist(struct mansession *s, const struct message *m)
static const char app2[]
static int conference_bridge_cmp_cb(void *obj, void *arg, int flags)
Comparison function used for conference bridges container.
static struct ast_custom_function confbridge_info_function
static int confbridge_exec(struct ast_channel *chan, const char *data)
The ConfBridge application.
static int action_confbridgestartrecord(struct mansession *s, const struct message *m)
static int conference_bridge_hash_cb(const void *obj, const int flags)
Hashing function used for conference bridges container.
static int action_confbridgelistrooms(struct mansession *s, const struct message *m)
static int unload_module(void)
Called when module is being unloaded.
static int action_confbridgelock(struct mansession *s, const struct message *m)
static struct ast_custom_function confbridge_channels_function
static struct ast_cli_entry cli_confbridge[]
static int confkick_exec(struct ast_channel *chan, const char *data)
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
struct ast_channel_tech * conf_announce_get_tech(void)
Get ConfBridge announce channel technology struct.
struct ast_channel_tech * conf_record_get_tech(void)
Get ConfBridge record channel technology struct.
int conf_load_config(void)
load confbridge.conf file
int manager_confbridge_init(void)
register stasis message routers to handle manager events for confbridge messages
#define EVENT_FLAG_REPORTING
Definition: manager.h:84
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define EVENT_FLAG_CALL
Definition: manager.h:76
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
Definition: pbx.h:1567
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
@ AST_CFE_WRITE
Definition: pbx.h:1551
#define ARRAY_LEN(a)
Definition: utils.h:666

References action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgelock(), action_confbridgemute(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_confbridgeunlock(), action_confbridgeunmute(), AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, app, app2, ARRAY_LEN, AST_CFE_WRITE, ast_cli_register_multiple, ast_custom_function_register, ast_custom_function_register_escalating, ast_log, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, cli_confbridge, conf_announce_get_tech(), conf_load_config(), conf_record_get_tech(), confbridge_channels_function, confbridge_exec(), confbridge_function, confbridge_info_function, CONFERENCE_BRIDGE_BUCKETS, conference_bridge_cmp_cb(), conference_bridge_hash_cb(), conference_bridges, confkick_exec(), EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, LOG_ERROR, manager_confbridge_init(), NULL, register_channel_tech(), and unload_module().

◆ play_file()

static int play_file ( struct ast_bridge_channel bridge_channel,
struct ast_channel channel,
const char *  filename 
)
static

Playback the given filename and monitor for any dtmf interrupts.

This function is used to playback sound files on a given channel and optionally allow dtmf interrupts to occur.

If the optional bridge_channel parameter is given then sound file playback is played on that channel and dtmf interruptions are allowed. However, if bridge_channel is not set then the channel parameter is expected to be set instead and non interruptible playback is played on that channel.

Parameters
bridge_channelBridge channel to play file on
channelOptional channel to play file on if bridge_channel not given
filenameThe file name to playback
Return values
-1failure during playback.
0on file was fully played.
1on dtmf interrupt.

Definition at line 1018 of file app_confbridge.c.

1020{
1021 struct ast_channel *chan;
1022 const char *stop_digits;
1023 int digit;
1024
1025 if (bridge_channel) {
1026 chan = bridge_channel->chan;
1027 stop_digits = AST_DIGIT_ANY;
1028 } else {
1029 chan = channel;
1030 stop_digits = AST_DIGIT_NONE;
1031 }
1032
1033 digit = ast_stream_and_wait(chan, filename, stop_digits);
1034 if (digit < 0) {
1035 ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
1036 return -1;
1037 }
1038
1039 if (digit > 0) {
1042 return 1;
1043 }
1044
1045 return 0;
1046}
void ast_bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits.
#define AST_DIGIT_NONE
Definition: file.h:47
struct ast_bridge_channel * bridge_channel

References ast_bridge_channel_feature_digit_add(), AST_DIGIT_ANY, AST_DIGIT_NONE, ast_log, ast_stopstream(), ast_stream_and_wait(), ast_channel::bridge_channel, ast_bridge_channel::chan, digit, and LOG_WARNING.

Referenced by action_kick_last(), action_toggle_binaural(), action_toggle_mute(), announce_user_count(), check_bridge_play_sound(), and execute_menu_entry().

◆ play_prompt_to_user()

static int play_prompt_to_user ( struct confbridge_user user,
const char *  filename 
)
static

Play back an audio file to a channel.

Parameters
userUser to play audio prompt to
filenamePrompt to play
Return values
0on success.
-1if the user hung up.
Note
Generally this should be called when the conference is unlocked to avoid blocking the entire conference while the sound is played. But don't unlock the conference bridge in the middle of a state transition.

Definition at line 1131 of file app_confbridge.c.

1132{
1133 return ast_stream_and_wait(user->chan, filename, "");
1134}

References ast_stream_and_wait().

Referenced by conf_handle_inactive_waitmarked(), conf_handle_only_person(), and join_conference_bridge().

◆ play_sound_file()

int play_sound_file ( struct confbridge_conference conference,
const char *  filename 
)

Play sound file into conference bridge.

Parameters
conferenceThe conference bridge to play sound file into
filenameSound file to play
Return values
0success
-1failure

Definition at line 2124 of file app_confbridge.c.

2125{
2126 return play_sound_helper(conference, filename, -1);
2127}
static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)

References playback_task_data::conference, playback_task_data::filename, and play_sound_helper().

Referenced by action_toggle_mute_participants(), announce_user_count(), confbridge_exec(), and post_join_play_begin().

◆ play_sound_helper()

static int play_sound_helper ( struct confbridge_conference conference,
const char *  filename,
int  say_number 
)
static

Definition at line 2086 of file app_confbridge.c.

2087{
2088 struct playback_task_data ptd;
2089
2090 /* Do not waste resources trying to play files that do not exist */
2092 if (say_number < 0) {
2093 return 0;
2094 }
2095 } else if (!sound_file_exists(filename)) {
2096 return 0;
2097 }
2098
2101 if (!ast_strlen_zero(filename)) {
2102 ast_log(LOG_WARNING, "Unable to play file '%s' to conference %s\n",
2104 } else {
2105 ast_log(LOG_WARNING, "Unable to say number '%d' to conference %s\n",
2107 }
2109 return -1;
2110 }
2111
2112 /* Wait for the playback to complete */
2113 ast_mutex_lock(&ptd.lock);
2114 while (!ptd.playback_finished) {
2115 ast_cond_wait(&ptd.cond, &ptd.lock);
2116 }
2117 ast_mutex_unlock(&ptd.lock);
2118
2120
2121 return 0;
2122}
static void playback_task_data_init(struct playback_task_data *ptd, struct confbridge_conference *conference, const char *filename, int say_number)
static void playback_task_data_destroy(struct playback_task_data *ptd)
static int playback_task(void *data)
Play an announcement into a confbridge.
struct confbridge_conference * conference
const char * filename

References ast_cond_wait, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_taskprocessor_push(), playback_task_data::cond, playback_task_data::conference, playback_task_data::filename, playback_task_data::lock, LOG_WARNING, confbridge_conference::name, playback_task_data::playback_finished, confbridge_conference::playback_queue, playback_task(), playback_task_data_destroy(), playback_task_data_init(), playback_task_data::say_number, and sound_file_exists().

Referenced by play_sound_file(), and play_sound_number().

◆ play_sound_number()

static int play_sound_number ( struct confbridge_conference conference,
int  say_number 
)
static

Play number into the conference bridge.

Parameters
conferenceThe conference bridge to say the number into
say_numbernumber to say
Return values
0success
-1failure

Definition at line 2406 of file app_confbridge.c.

2407{
2408 return play_sound_helper(conference, NULL, say_number);
2409}

References NULL, and play_sound_helper().

Referenced by announce_user_count().

◆ playback_common()

static void playback_common ( struct confbridge_conference conference,
const char *  filename,
int  say_number 
)
static

Definition at line 2012 of file app_confbridge.c.

2013{
2014 /* Don't try to play if the playback channel has been hung up */
2015 if (!conference->playback_chan) {
2016 return;
2017 }
2018
2020
2021 /* The channel is all under our control, in goes the prompt */
2022 if (!ast_strlen_zero(filename)) {
2023 ast_stream_and_wait(conference->playback_chan, filename, "");
2024 } else if (say_number >= 0) {
2025 ast_say_number(conference->playback_chan, say_number, "",
2027 }
2028
2030}

References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_language(), ast_say_number(), ast_stream_and_wait(), ast_strlen_zero(), NULL, and confbridge_conference::playback_chan.

Referenced by async_playback_task(), and playback_task().

◆ playback_task()

static int playback_task ( void *  data)
static

Play an announcement into a confbridge.

This runs in the playback queue taskprocessor. This ensures that all playbacks are handled in sequence and do not play over top one another.

This task runs synchronously so there is no need for performing any sort of cleanup on the input parameter.

Parameters
dataA playback_task_data
Returns
0

Definition at line 2054 of file app_confbridge.c.

2055{
2056 struct playback_task_data *ptd = data;
2057
2059
2060 ast_mutex_lock(&ptd->lock);
2061 ptd->playback_finished = 1;
2062 ast_cond_signal(&ptd->cond);
2063 ast_mutex_unlock(&ptd->lock);
2064
2065 return 0;
2066}

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, playback_task_data::cond, playback_task_data::conference, playback_task_data::filename, playback_task_data::lock, playback_common(), playback_task_data::playback_finished, and playback_task_data::say_number.

Referenced by play_sound_helper().

◆ playback_task_data_destroy()

static void playback_task_data_destroy ( struct playback_task_data ptd)
static

Definition at line 2080 of file app_confbridge.c.

2081{
2082 ast_mutex_destroy(&ptd->lock);
2083 ast_cond_destroy(&ptd->cond);
2084}

References ast_cond_destroy, ast_mutex_destroy, playback_task_data::cond, and playback_task_data::lock.

Referenced by play_sound_helper().

◆ playback_task_data_init()

static void playback_task_data_init ( struct playback_task_data ptd,
struct confbridge_conference conference,
const char *  filename,
int  say_number 
)
static

Definition at line 2068 of file app_confbridge.c.

2070{
2071 ast_mutex_init(&ptd->lock);
2072 ast_cond_init(&ptd->cond, NULL);
2073
2074 ptd->filename = filename;
2075 ptd->say_number = say_number;
2076 ptd->conference = conference;
2077 ptd->playback_finished = 0;
2078}

References ast_cond_init, ast_mutex_init, playback_task_data::cond, playback_task_data::conference, playback_task_data::filename, playback_task_data::lock, NULL, playback_task_data::playback_finished, and playback_task_data::say_number.

Referenced by play_sound_helper().

◆ push_announcer()

static int push_announcer ( struct confbridge_conference conference)
static

Push the announcer channel into the bridge.

Parameters
conferenceConference bridge to push the announcer to
Return values
0Success
-1Failed to push the channel to the bridge

Definition at line 1626 of file app_confbridge.c.

1627{
1628 if (conf_announce_channel_push(conference->playback_chan)) {
1629 ast_hangup(conference->playback_chan);
1630 conference->playback_chan = NULL;
1631 return -1;
1632 }
1633
1635 return 0;
1636}
int conf_announce_channel_push(struct ast_channel *ast)
Push the announcer channel into the conference.

References ast_autoservice_start(), ast_hangup(), conf_announce_channel_push(), NULL, and confbridge_conference::playback_chan.

Referenced by join_conference_bridge().

◆ register_channel_tech()

static int register_channel_tech ( struct ast_channel_tech tech)
static

Definition at line 4557 of file app_confbridge.c.

4558{
4560 if (!tech->capabilities) {
4561 return -1;
4562 }
4564 if (ast_channel_register(tech)) {
4565 ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
4566 tech->type, tech->description);
4567 return -1;
4568 }
4569 return 0;
4570}
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
struct ast_format_cap * capabilities
Definition: channel.h:652
const char *const type
Definition: channel.h:649
const char *const description
Definition: channel.h:650

References ast_channel_register(), ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_channel_tech::capabilities, ast_channel_tech::description, LOG_ERROR, and ast_channel_tech::type.

Referenced by load_module().

◆ reload()

static int reload ( void  )
static

Definition at line 4674 of file app_confbridge.c.

4675{
4676 return conf_reload_config();
4677}
int conf_reload_config(void)
reload confbridge.conf file

References conf_reload_config().

◆ send_conf_end_event()

static void send_conf_end_event ( struct confbridge_conference conference)
static

Definition at line 752 of file app_confbridge.c.

753{
754 send_conf_stasis(conference, NULL, confbridge_end_type(), NULL, 0);
755}
struct stasis_message_type * confbridge_end_type(void)
get the confbridge end stasis message type

References confbridge_end_type(), NULL, and send_conf_stasis().

Referenced by conf_ended().

◆ send_conf_start_event()

static void send_conf_start_event ( struct confbridge_conference conference)
static

Definition at line 747 of file app_confbridge.c.

748{
750}
struct stasis_message_type * confbridge_start_type(void)
get the confbridge start stasis message type

References confbridge_start_type(), NULL, and send_conf_stasis().

Referenced by join_conference_bridge().

◆ send_conf_stasis()

static void send_conf_stasis ( struct confbridge_conference conference,
struct ast_channel chan,
struct stasis_message_type type,
struct ast_json extras,
int  channel_topic 
)
static

Definition at line 673 of file app_confbridge.c.

675{
676 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
677 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
678
679 json_object = ast_json_pack("{s: s}",
680 "conference", conference->name);
681 if (!json_object) {
682 return;
683 }
684
685 if (extras) {
686 ast_json_object_update(json_object, extras);
687 }
688
689 ast_bridge_lock(conference->bridge);
691 conference->bridge,
692 chan,
693 json_object);
694 ast_bridge_unlock(conference->bridge);
695 if (!msg) {
696 return;
697 }
698
700 conf_send_event_to_participants(conference, chan, msg);
701 }
702
703 if (channel_topic) {
705 } else {
706 stasis_publish(ast_bridge_topic(conference->bridge), msg);
707 }
708}
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
void conf_send_event_to_participants(struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message *msg)
Send events to bridge participants.
int ast_json_object_update(struct ast_json *object, struct ast_json *other)
Update object with all of the fields of other.
Definition: json.c:426
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1512
struct stasis_message * ast_bridge_blob_create(struct stasis_message_type *type, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_json *blob)
Creates a ast_bridge_blob message.
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.

References ao2_cleanup, ast_bridge_blob_create(), ast_bridge_lock, ast_bridge_topic(), ast_bridge_unlock, ast_channel_topic(), ast_json_object_update(), ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_conference::b_profile, confbridge_conference::bridge, BRIDGE_OPT_ENABLE_EVENTS, conf_send_event_to_participants(), confbridge_conference::name, NULL, RAII_VAR, stasis_publish(), and type.

Referenced by conf_handle_talker_cb(), send_conf_end_event(), send_conf_start_event(), send_join_event(), send_leave_event(), send_mute_event(), send_start_record_event(), send_stop_record_event(), and send_unmute_event().

◆ send_conf_stasis_snapshots()

static void send_conf_stasis_snapshots ( struct confbridge_conference conference,
struct ast_channel_snapshot chan_snapshot,
struct stasis_message_type type,
struct ast_json extras 
)
static

Definition at line 710 of file app_confbridge.c.

713{
714 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
715 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
716 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
717
718 json_object = ast_json_pack("{s: s}",
719 "conference", conference->name);
720 if (!json_object) {
721 return;
722 }
723
724 if (extras) {
725 ast_json_object_update(json_object, extras);
726 }
727
728 ast_bridge_lock(conference->bridge);
729 bridge_snapshot = ast_bridge_snapshot_create(conference->bridge);
730 ast_bridge_unlock(conference->bridge);
731 if (!bridge_snapshot) {
732 return;
733 }
734
736 bridge_snapshot,
737 chan_snapshot,
738 json_object);
739 if (!msg) {
740 return;
741 }
742
743 stasis_publish(ast_bridge_topic(conference->bridge), msg);
744}
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct stasis_message * ast_bridge_blob_create_from_snapshots(struct stasis_message_type *type, struct ast_bridge_snapshot *bridge_snapshot, struct ast_channel_snapshot *chan_snapshot, struct ast_json *blob)
Creates a ast_bridge_blob message from snapshots.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314

References ao2_cleanup, ast_bridge_blob_create_from_snapshots(), ast_bridge_lock, ast_bridge_snapshot_create(), ast_bridge_topic(), ast_bridge_unlock, ast_json_object_update(), ast_json_pack(), ast_json_unref(), confbridge_conference::bridge, confbridge_conference::name, NULL, RAII_VAR, stasis_publish(), and type.

Referenced by confbridge_handle_atxfer().

◆ send_event_hook_callback()

static int send_event_hook_callback ( struct ast_bridge_channel bridge_channel,
void *  data 
)
static

Definition at line 2619 of file app_confbridge.c.

2620{
2621 struct confbridge_hook_data *hook_data = data;
2622
2623 if (hook_data->hook_type == AST_BRIDGE_HOOK_TYPE_JOIN) {
2624 send_join_event(hook_data->user, hook_data->conference);
2625 } else {
2626 send_leave_event(hook_data->user, hook_data->conference);
2627 }
2628
2629 return 0;
2630}
static void send_join_event(struct confbridge_user *user, struct confbridge_conference *conference)
static void send_leave_event(struct confbridge_user *user, struct confbridge_conference *conference)

References AST_BRIDGE_HOOK_TYPE_JOIN, confbridge_hook_data::conference, confbridge_hook_data::hook_type, send_join_event(), send_leave_event(), and confbridge_hook_data::user.

Referenced by confbridge_exec().

◆ send_join_event()

static void send_join_event ( struct confbridge_user user,
struct confbridge_conference conference 
)
static

Definition at line 757 of file app_confbridge.c.

758{
759 struct ast_json *json_object;
760
761 json_object = ast_json_pack("{s: b, s: b}",
762 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
763 "muted", user->muted);
764 if (!json_object) {
765 return;
766 }
767 send_conf_stasis(conference, user->chan, confbridge_join_type(), json_object, 0);
768 ast_json_unref(json_object);
769}

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_join_type(), send_conf_stasis(), and USER_OPT_ADMIN.

Referenced by send_event_hook_callback().

◆ send_leave_event()

static void send_leave_event ( struct confbridge_user user,
struct confbridge_conference conference 
)
static

Definition at line 771 of file app_confbridge.c.

772{
773 struct ast_json *json_object;
774
775 json_object = ast_json_pack("{s: b}",
776 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
777 );
778 if (!json_object) {
779 return;
780 }
781 send_conf_stasis(conference, user->chan, confbridge_leave_type(), json_object, 0);
782 ast_json_unref(json_object);
783}

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_leave_type(), send_conf_stasis(), and USER_OPT_ADMIN.

Referenced by send_event_hook_callback().

◆ send_mute_event()

static void send_mute_event ( struct confbridge_user user,
struct confbridge_conference conference 
)
static

Definition at line 795 of file app_confbridge.c.

796{
797 struct ast_json *json_object;
798
799 json_object = ast_json_pack("{s: b}",
800 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
801 );
802 if (!json_object) {
803 return;
804 }
805 send_conf_stasis(conference, user->chan, confbridge_mute_type(), json_object, 1);
806 ast_json_unref(json_object);
807}
struct stasis_message_type * confbridge_mute_type(void)
get the confbridge mute stasis message type

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_mute_type(), send_conf_stasis(), and USER_OPT_ADMIN.

Referenced by generic_mute_unmute_user().

◆ send_start_record_event()

static void send_start_record_event ( struct confbridge_conference conference)
static

Definition at line 785 of file app_confbridge.c.

786{
788}
struct stasis_message_type * confbridge_start_record_type(void)
get the confbridge start_record stasis message type

References confbridge_start_record_type(), NULL, and send_conf_stasis().

Referenced by conf_start_record().

◆ send_stop_record_event()

static void send_stop_record_event ( struct confbridge_conference conference)
static

Definition at line 790 of file app_confbridge.c.

791{
793}
struct stasis_message_type * confbridge_stop_record_type(void)
get the confbridge stop_record stasis message type

References confbridge_stop_record_type(), NULL, and send_conf_stasis().

Referenced by conf_stop_record().

◆ send_unmute_event()

static void send_unmute_event ( struct confbridge_user user,
struct confbridge_conference conference 
)
static

Definition at line 809 of file app_confbridge.c.

810{
811 struct ast_json *json_object;
812
813 json_object = ast_json_pack("{s: b}",
814 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
815 );
816 if (!json_object) {
817 return;
818 }
819 send_conf_stasis(conference, user->chan, confbridge_unmute_type(), json_object, 1);
820 ast_json_unref(json_object);
821}
struct stasis_message_type * confbridge_unmute_type(void)
get the confbridge unmute stasis message type

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_unmute_type(), send_conf_stasis(), and USER_OPT_ADMIN.

Referenced by generic_mute_unmute_user().

◆ set_rec_filename()

static void set_rec_filename ( struct confbridge_conference conference,
struct ast_str **  filename,
int  is_new 
)
static

Definition at line 823 of file app_confbridge.c.

824{
825 char *rec_file = conference->b_profile.rec_file;
826 char *ext;
827 time_t now;
828
829 if (ast_str_strlen(*filename)
831 && !is_new) {
832 return;
833 }
834
835 time(&now);
836
837 ast_str_reset(*filename);
838 if (ast_strlen_zero(rec_file)) {
839 ast_str_set(filename, 0, "confbridge-%s-%u.wav", conference->name,
840 (unsigned int) now);
841 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_TIMESTAMP)) {
842 /* insert time before file extension */
843 ext = strrchr(rec_file, '.');
844 if (ext) {
845 ast_str_set_substr(filename, 0, rec_file, ext - rec_file);
846 ast_str_append(filename, 0, "-%u%s", (unsigned int) now, ext);
847 } else {
848 ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int) now);
849 }
850 } else {
851 ast_str_set(filename, 0, "%s", rec_file);
852 }
853 ast_str_append(filename, 0, ",%s%s,%s",
854 ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND) ? "a" : "",
855 conference->b_profile.rec_options,
856 conference->b_profile.rec_command);
857}
@ BRIDGE_OPT_RECORD_FILE_TIMESTAMP
Definition: confbridge.h:83
@ BRIDGE_OPT_RECORD_FILE_APPEND
Definition: confbridge.h:82
const char * ext
Definition: http.c:150
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
char * ast_str_set_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring.
Definition: strings.h:1055
char rec_options[128]
Definition: confbridge.h:231
char rec_command[128]
Definition: confbridge.h:232

References ast_str_append(), ast_str_reset(), ast_str_set(), ast_str_set_substr(), ast_str_strlen(), ast_strlen_zero(), ast_test_flag, confbridge_conference::b_profile, BRIDGE_OPT_RECORD_FILE_APPEND, BRIDGE_OPT_RECORD_FILE_TIMESTAMP, ext, confbridge_conference::name, bridge_profile::rec_command, bridge_profile::rec_file, and bridge_profile::rec_options.

Referenced by conf_start_record().

◆ setup_async_playback_datastore()

static int setup_async_playback_datastore ( struct ast_channel initiator)
static

Prepare the async playback datastore.

This is done prior to queuing an async announcement. If the datastore has not yet been created, it is allocated and initialized. If it already exists, we set it to be in "waiting" mode.

Parameters
initiatorThe channel that is queuing the async playback
Return values
0Success
-1Failure :(

Definition at line 2201 of file app_confbridge.c.

2202{
2203 struct ast_datastore *async_datastore;
2204
2205 async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2206 if (async_datastore) {
2207 struct async_datastore_data *add;
2208
2209 add = async_datastore->data;
2210 add->wait = 1;
2211
2212 return 0;
2213 }
2214
2215 async_datastore = ast_datastore_alloc(&async_datastore_info, NULL);
2216 if (!async_datastore) {
2217 return -1;
2218 }
2219
2220 async_datastore->data = async_datastore_data_alloc();
2221 if (!async_datastore->data) {
2222 ast_datastore_free(async_datastore);
2223 return -1;
2224 }
2225
2226 ast_channel_datastore_add(initiator, async_datastore);
2227 return 0;
2228}
static struct async_datastore_data * async_datastore_data_alloc(void)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2404
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68

References ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), async_datastore_data_alloc(), async_datastore_info, ast_datastore::data, NULL, and async_datastore_data::wait.

Referenced by async_playback_task_data_alloc().

◆ sound_file_exists()

static int sound_file_exists ( const char *  filename)
static

Definition at line 1056 of file app_confbridge.c.

1057{
1058 if (ast_fileexists(filename, NULL, NULL)) {
1059 return -1;
1060 }
1061 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
1062 return 0;
1063}
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129

References ast_fileexists(), ast_log, LOG_WARNING, and NULL.

Referenced by announce_user_count(), async_delete_name_rec(), async_play_sound_helper(), and play_sound_helper().

◆ unload_module()

static int unload_module ( void  )
static

Called when module is being unloaded.

Definition at line 4573 of file app_confbridge.c.

4574{
4577
4581
4583
4584 ast_manager_unregister("ConfbridgeList");
4585 ast_manager_unregister("ConfbridgeListRooms");
4586 ast_manager_unregister("ConfbridgeMute");
4587 ast_manager_unregister("ConfbridgeUnmute");
4588 ast_manager_unregister("ConfbridgeKick");
4589 ast_manager_unregister("ConfbridgeUnlock");
4590 ast_manager_unregister("ConfbridgeLock");
4591 ast_manager_unregister("ConfbridgeStartRecord");
4592 ast_manager_unregister("ConfbridgeStopRecord");
4593 ast_manager_unregister("ConfbridgeSetSingleVideoSrc");
4594
4595 /* Unsubscribe from stasis confbridge message type and clean it up. */
4597
4598 /* Get rid of the conference bridges container. Since we only allow dynamic ones none will be active. */
4601
4603
4606
4607 return 0;
4608}
static void unregister_channel_tech(struct ast_channel_tech *tech)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void conf_destroy_config(void)
destroy the information loaded from the confbridge.conf file
void manager_confbridge_shutdown(void)
unregister stasis message routers to handle manager events for confbridge messages
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7608
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

References ao2_cleanup, app, app2, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_manager_unregister(), ast_unregister_application(), cli_confbridge, conf_announce_get_tech(), conf_destroy_config(), conf_record_get_tech(), confbridge_channels_function, confbridge_function, confbridge_info_function, conference_bridges, manager_confbridge_shutdown(), NULL, and unregister_channel_tech().

Referenced by load_module().

◆ unregister_channel_tech()

static void unregister_channel_tech ( struct ast_channel_tech tech)
static

Definition at line 4541 of file app_confbridge.c.

4542{
4545}
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570

References ao2_cleanup, ast_channel_unregister(), and ast_channel_tech::capabilities.

Referenced by unload_module().

◆ user_timeout()

static int user_timeout ( struct ast_bridge_channel bridge_channel,
void *  ignore 
)
static

Definition at line 2481 of file app_confbridge.c.

2482{
2484 pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "TIMEOUT");
2485 return -1;
2486}
@ BRIDGE_CHANNEL_STATE_END
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).

References ast_bridge_channel_leave_bridge(), BRIDGE_CHANNEL_STATE_END, ast_bridge_channel::chan, and pbx_builtin_setvar_helper().

Referenced by confbridge_exec().

◆ wait_for_initiator()

static void wait_for_initiator ( struct ast_channel initiator)
static

Wait for the initiator of an async playback to be ready.

See the description on the async_datastore_info structure for more information about what this is about.

Parameters
initiatorThe channel that queued the async announcement

Definition at line 2290 of file app_confbridge.c.

2291{
2292 struct ast_datastore *async_datastore;
2293 struct async_datastore_data *add;
2294
2295 ast_channel_lock(initiator);
2296 async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2297 ast_channel_unlock(initiator);
2298
2299 if (!async_datastore) {
2300 return;
2301 }
2302
2303 add = async_datastore->data;
2304
2305 ast_mutex_lock(&add->lock);
2306 while (add->wait) {
2307 ast_cond_wait(&add->cond, &add->lock);
2308 }
2309 ast_mutex_unlock(&add->lock);
2310}

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, async_datastore_info, async_datastore_data::cond, ast_datastore::data, async_datastore_data::lock, NULL, and async_datastore_data::wait.

Referenced by async_playback_task().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Conference Bridge Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, .optional_modules = "codec_speex,func_jitterbuffer", }
static

Definition at line 4686 of file app_confbridge.c.

◆ app

const char app[] = "ConfBridge"
static
Playing back a file to a channel in a conference
You might notice in this application that while playing a sound file to a channel the actual conference bridge lock is not held. This is done so that other channels are not blocked from interacting with the conference bridge. Unfortunately because of this it is possible for things to change after the sound file is done being played. Data must therefore be checked after reacquiring the conference bridge lock if it is important.

Definition at line 547 of file app_confbridge.c.

Referenced by confbridge_exec(), join_conference_bridge(), load_module(), and unload_module().

◆ app2

const char app2[] = "ConfKick"
static

Definition at line 548 of file app_confbridge.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 4686 of file app_confbridge.c.

◆ async_datastore_info

struct ast_datastore_info async_datastore_info
static
Initial value:
= {
.type = "Confbridge async playback",
}
static void async_datastore_data_destroy(void *data)

Datastore used for timing of async announcement playback.

Announcements that are played to the entire conference can be played asynchronously (i.e. The channel that queues the playback does not wait for the playback to complete before continuing)

The thing about async announcements is that the channel that queues the announcement is either not in the bridge or is in some other way "occupied" at the time the announcement is queued. Because of that, the initiator of the announcement may enter after the announcement has already started, resulting in the sound being "clipped".

This datastore makes it so that the channel that queues the async announcement can say "I'm ready now". This way the announcement does not start until the initiator of the announcement is ready to hear the sound.

Definition at line 2169 of file app_confbridge.c.

Referenced by async_play_sound_ready(), setup_async_playback_datastore(), and wait_for_initiator().

◆ cli_confbridge

struct ast_cli_entry cli_confbridge[]
static

Definition at line 3896 of file app_confbridge.c.

Referenced by load_module(), and unload_module().

◆ confbridge_channels_function

struct ast_custom_function confbridge_channels_function
static
Initial value:
= {
.name = "CONFBRIDGE_CHANNELS",
}
static int func_confbridge_channels(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 3996 of file app_confbridge.c.

Referenced by load_module(), and unload_module().

◆ confbridge_function

struct ast_custom_function confbridge_function
static
Initial value:
= {
.name = "CONFBRIDGE",
}
int func_confbridge_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)

Definition at line 3906 of file app_confbridge.c.

Referenced by load_module(), and unload_module().

◆ confbridge_info_function

struct ast_custom_function confbridge_info_function
static
Initial value:
= {
.name = "CONFBRIDGE_INFO",
}
static int func_confbridge_info(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 3912 of file app_confbridge.c.

Referenced by load_module(), and unload_module().

◆ conference_bridges

struct ao2_container* conference_bridges