Asterisk - The Open Source Telephony Project GIT-master-545c459
Loading...
Searching...
No Matches
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.
 
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.
 
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.
 
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.
 
static int async_playback_task (void *data)
 Play an announcement into a confbridge asynchronously.
 
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.
 
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.
 
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.
 
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.
 
void conf_ended (struct confbridge_conference *conference)
 Callback to be called when the conference has become empty.
 
struct confbridge_conferenceconf_find_bridge (const char *conference_name)
 Find a confbridge by name.
 
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.
 
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.
 
void conf_handle_first_join (struct confbridge_conference *conference)
 Callback to execute any time we transition from zero to one active users.
 
int conf_handle_inactive_waitmarked (struct confbridge_user *user)
 Handle actions every time a waitmarked user joins w/o a marked user present.
 
int conf_handle_only_person (struct confbridge_user *user)
 Handle actions whenever an user joins an empty conference.
 
void conf_handle_second_active (struct confbridge_conference *conference)
 Handle when a conference moves to having more than one active participant.
 
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.
 
void conf_moh_stop (struct confbridge_user *user)
 Stop MOH for the conference user.
 
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.
 
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.
 
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.
 
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.
 
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.
 
static int confbridge_exec (struct ast_channel *chan, const char *data)
 The ConfBridge application.
 
void confbridge_handle_atxfer (struct ast_attended_transfer_message *msg)
 Create join/leave events for attended transfers.
 
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.
 
static int conference_bridge_hash_cb (const void *obj, const int flags)
 Hashing function used for conference bridges container.
 
static int confkick_exec (struct ast_channel *chan, const char *data)
 
static void destroy_conference_bridge (void *obj)
 Destroy a conference bridge.
 
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.
 
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.
 
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.
 
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.
 
static int kick_conference_participant (struct confbridge_conference *conference, const char *channel)
 
static void leave_conference (struct confbridge_user *user)
 Leave a conference.
 
static int load_module (void)
 Load the module.
 
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.
 
static int play_prompt_to_user (struct confbridge_user *user, const char *filename)
 Play back an audio file to a channel.
 
int play_sound_file (struct confbridge_conference *conference, const char *filename)
 Play sound file into conference bridge.
 
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.
 
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.
 
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.
 
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.
 
static int sound_file_exists (const char *filename)
 
static int unload_module (void)
 Called when module is being unloaded.
 
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.
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Conference Bridge Application" , .key = ASTERISK_GPL_KEY , .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.
 
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.
 

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 598 of file app_confbridge.c.

◆ RECORD_FILENAME_INITIAL_SPACE

#define RECORD_FILENAME_INITIAL_SPACE   128

Initial recording filename space.

Definition at line 601 of file app_confbridge.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4768 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4768 of file app_confbridge.c.

◆ action_confbridgekick()

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

Definition at line 4301 of file app_confbridge.c.

4302{
4303 const char *conference_name = astman_get_header(m, "Conference");
4304 const char *channel = astman_get_header(m, "Channel");
4305 struct confbridge_conference *conference;
4306 int found;
4307
4308 if (ast_strlen_zero(conference_name)) {
4309 astman_send_error(s, m, "No Conference name provided.");
4310 return 0;
4311 }
4313 astman_send_error(s, m, "No active conferences.");
4314 return 0;
4315 }
4316
4317 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4318 if (!conference) {
4319 astman_send_error(s, m, "No Conference by that name found.");
4320 return 0;
4321 }
4322
4323 found = !kick_conference_participant(conference, channel);
4324 ao2_ref(conference, -1);
4325
4326 if (found) {
4327 astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4328 } else {
4329 astman_send_error(s, m, "No Channel by that name found in Conference.");
4330 }
4331 return 0;
4332}
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:1921
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition manager.c:1953
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition manager.c:1582
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:247

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 4133 of file app_confbridge.c.

4134{
4135 const char *actionid = astman_get_header(m, "ActionID");
4136 const char *conference_name = astman_get_header(m, "Conference");
4137 struct confbridge_user *user;
4138 struct confbridge_conference *conference;
4139 char id_text[80];
4140 int total = 0;
4141
4142 id_text[0] = '\0';
4143 if (!ast_strlen_zero(actionid)) {
4144 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
4145 }
4146 if (ast_strlen_zero(conference_name)) {
4147 astman_send_error(s, m, "No Conference name provided.");
4148 return 0;
4149 }
4151 astman_send_error(s, m, "No active conferences.");
4152 return 0;
4153 }
4154 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4155 if (!conference) {
4156 astman_send_error(s, m, "No Conference by that name found.");
4157 return 0;
4158 }
4159
4160 astman_send_listack(s, m, "Confbridge user list will follow", "start");
4161
4162 ao2_lock(conference);
4163 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4164 total += action_confbridgelist_item(s, id_text, conference, user, 0);
4165 }
4166 AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
4167 total += action_confbridgelist_item(s, id_text, conference, user, 1);
4168 }
4169 ao2_unlock(conference);
4170 ao2_ref(conference, -1);
4171
4172 astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
4174
4175 return 0;
4176}
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:1963
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:1999
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition manager.c:2007
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static int total
Definition res_adsi.c:970
struct confbridge_conference::@94 active_list
struct confbridge_conference::@95 waiting_list
The structure that represents a conference bridge user.
Definition confbridge.h:274
structure to hold users read from phoneprov_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, 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 4083 of file app_confbridge.c.

4084{
4085 struct ast_channel_snapshot *snapshot;
4086 struct ast_str *snap_str;
4087
4089 if (!snapshot) {
4090 return 0;
4091 }
4092
4093 snap_str = ast_manager_build_channel_state_string(snapshot);
4094 if (!snap_str) {
4095 ao2_ref(snapshot, -1);
4096 return 0;
4097 }
4098
4099 astman_append(s,
4100 "Event: ConfbridgeList\r\n"
4101 "%s"
4102 "Conference: %s\r\n"
4103 "Admin: %s\r\n"
4104 "MarkedUser: %s\r\n"
4105 "WaitMarked: %s\r\n"
4106 "EndMarked: %s\r\n"
4107 "EndMarkedAny: %s\r\n"
4108 "Waiting: %s\r\n"
4109 "Muted: %s\r\n"
4110 "Talking: %s\r\n"
4111 "AnsweredTime: %d\r\n"
4112 "%s"
4113 "\r\n",
4114 id_text,
4115 conference->name,
4121 AST_YESNO(waiting),
4122 AST_YESNO(user->muted),
4123 AST_YESNO(user->talking),
4125 ast_str_buffer(snap_str));
4126
4127 ast_free(snap_str);
4128 ao2_ref(snapshot, -1);
4129
4130 return 1;
4131}
#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:2845
@ 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:1842
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.
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition strings.h:143
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Structure representing a snapshot of channel state.
Support for dynamic strings.
Definition strings.h:623
char name[MAX_CONF_NAME]
Definition confbridge.h:248
#define ast_test_flag(p, flag)
Definition utils.h:64

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 4178 of file app_confbridge.c.

4179{
4180 const char *actionid = astman_get_header(m, "ActionID");
4181 struct confbridge_conference *conference;
4182 struct ao2_iterator iter;
4183 char id_text[512] = "";
4184 int totalitems = 0;
4185
4186 if (!ast_strlen_zero(actionid)) {
4187 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
4188 }
4189
4191 astman_send_error(s, m, "No active conferences.");
4192 return 0;
4193 }
4194
4195 astman_send_listack(s, m, "Confbridge conferences will follow", "start");
4196
4197 /* Traverse the conference list */
4199 while ((conference = ao2_iterator_next(&iter))) {
4200 totalitems++;
4201
4202 ao2_lock(conference);
4203 astman_append(s,
4204 "Event: ConfbridgeListRooms\r\n"
4205 "%s"
4206 "Conference: %s\r\n"
4207 "Parties: %u\r\n"
4208 "Marked: %u\r\n"
4209 "Locked: %s\r\n"
4210 "Muted: %s\r\n"
4211 "\r\n",
4212 id_text,
4213 conference->name,
4214 conference->activeusers + conference->waitingusers,
4215 conference->markedusers,
4216 AST_YESNO(conference->locked),
4217 AST_YESNO(conference->muted));
4218 ao2_unlock(conference);
4219
4220 ao2_ref(conference, -1);
4221 }
4222 ao2_iterator_destroy(&iter);
4223
4224 /* Send final confirmation */
4225 astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
4227 return 0;
4228}
#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 activeusers
Definition confbridge.h:252
unsigned int waitingusers
Definition confbridge.h:254
unsigned int markedusers
Definition confbridge.h:253
unsigned int locked
Definition confbridge.h:255

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 4296 of file app_confbridge.c.

4297{
4298 return action_lock_unlock_helper(s, m, 1);
4299}
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 4267 of file app_confbridge.c.

4268{
4269 return action_mute_unmute_helper(s, m, 1);
4270}
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 4413 of file app_confbridge.c.

4414{
4415 const char *conference_name = astman_get_header(m, "Conference");
4416 const char *channel = astman_get_header(m, "Channel");
4417 struct confbridge_user *user;
4418 struct confbridge_conference *conference;
4419
4420 if (ast_strlen_zero(conference_name)) {
4421 astman_send_error(s, m, "No Conference name provided.");
4422 return 0;
4423 }
4424 if (ast_strlen_zero(channel)) {
4425 astman_send_error(s, m, "No channel name provided.");
4426 return 0;
4427 }
4429 astman_send_error(s, m, "No active conferences.");
4430 return 0;
4431 }
4432
4433 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4434 if (!conference) {
4435 astman_send_error(s, m, "No Conference by that name found.");
4436 return 0;
4437 }
4438
4439 /* find channel and set as video src. */
4440 ao2_lock(conference);
4441 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4442 if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4444 break;
4445 }
4446 }
4447 ao2_unlock(conference);
4448 ao2_ref(conference, -1);
4449
4450 /* do not access user after conference unlock. We are just
4451 * using this check to see if it was found or not */
4452 if (!user) {
4453 astman_send_error(s, m, "No channel by that name found in conference.");
4454 return 0;
4455 }
4456 astman_send_ack(s, m, "Conference single video source set.");
4457 return 0;
4458}
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:3958
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_bridge * bridge
Definition confbridge.h:250

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, and OBJ_KEY.

Referenced by load_module().

◆ action_confbridgestartrecord()

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

Definition at line 4334 of file app_confbridge.c.

4335{
4336 const char *conference_name = astman_get_header(m, "Conference");
4337 const char *recordfile = astman_get_header(m, "RecordFile");
4338 struct confbridge_conference *conference;
4339
4340 if (ast_strlen_zero(conference_name)) {
4341 astman_send_error(s, m, "No Conference name provided.");
4342 return 0;
4343 }
4345 astman_send_error(s, m, "No active conferences.");
4346 return 0;
4347 }
4348
4349 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4350 if (!conference) {
4351 astman_send_error(s, m, "No Conference by that name found.");
4352 return 0;
4353 }
4354
4355 ao2_lock(conference);
4356 if (conf_is_recording(conference)) {
4357 astman_send_error(s, m, "Conference is already being recorded.");
4358 ao2_unlock(conference);
4359 ao2_ref(conference, -1);
4360 return 0;
4361 }
4362
4363 if (!ast_strlen_zero(recordfile)) {
4364 ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4365 }
4366
4367 if (conf_start_record(conference)) {
4368 astman_send_error(s, m, "Internal error starting conference recording.");
4369 ao2_unlock(conference);
4370 ao2_ref(conference, -1);
4371 return 0;
4372 }
4373 ao2_unlock(conference);
4374
4375 ao2_ref(conference, -1);
4376 astman_send_ack(s, m, "Conference Recording Started.");
4377 return 0;
4378}
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:231
struct bridge_profile b_profile
Definition confbridge.h:251

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 4379 of file app_confbridge.c.

4380{
4381 const char *conference_name = astman_get_header(m, "Conference");
4382 struct confbridge_conference *conference;
4383
4384 if (ast_strlen_zero(conference_name)) {
4385 astman_send_error(s, m, "No Conference name provided.");
4386 return 0;
4387 }
4389 astman_send_error(s, m, "No active conferences.");
4390 return 0;
4391 }
4392
4393 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4394 if (!conference) {
4395 astman_send_error(s, m, "No Conference by that name found.");
4396 return 0;
4397 }
4398
4399 ao2_lock(conference);
4400 if (conf_stop_record(conference)) {
4401 ao2_unlock(conference);
4402 astman_send_error(s, m, "Internal error while stopping recording.");
4403 ao2_ref(conference, -1);
4404 return 0;
4405 }
4406 ao2_unlock(conference);
4407
4408 ao2_ref(conference, -1);
4409 astman_send_ack(s, m, "Conference Recording Stopped.");
4410 return 0;
4411}
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 4292 of file app_confbridge.c.

4293{
4294 return action_lock_unlock_helper(s, m, 0);
4295}

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 4263 of file app_confbridge.c.

4264{
4265 return action_mute_unmute_helper(s, m, 0);
4266}

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 3237 of file app_confbridge.c.

3238{
3239 struct ast_pbx_args args;
3240 struct ast_pbx *pbx;
3241 char *exten;
3242 char *context;
3243 int priority;
3244 int res;
3245
3246 memset(&args, 0, sizeof(args));
3247 args.no_hangup_chan = 1;
3248
3249 ast_channel_lock(bridge_channel->chan);
3250
3251 /*save off*/
3252 exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3253 context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3254 priority = ast_channel_priority(bridge_channel->chan);
3255 pbx = ast_channel_pbx(bridge_channel->chan);
3256 ast_channel_pbx_set(bridge_channel->chan, NULL);
3257
3258 /*set new*/
3259 ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3260 ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3261 ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3262
3263 ast_channel_unlock(bridge_channel->chan);
3264
3265 /*execute*/
3266 res = ast_pbx_run_args(bridge_channel->chan, &args);
3267
3268 /*restore*/
3269 ast_channel_lock(bridge_channel->chan);
3270
3271 ast_channel_exten_set(bridge_channel->chan, exten);
3272 ast_channel_context_set(bridge_channel->chan, context);
3273 ast_channel_priority_set(bridge_channel->chan, priority);
3274 ast_channel_pbx_set(bridge_channel->chan, pbx);
3275
3276 ast_channel_unlock(bridge_channel->chan);
3277
3278 return res;
3279}
#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:2983
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:2984
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:3295
static struct @523 args
#define NULL
Definition resample.c:96
struct ast_channel * chan
Options for ast_pbx_run()
Definition pbx.h:409
Definition pbx.h:216
char exten[AST_MAX_EXTENSION]
Definition confbridge.h:129
struct conf_menu_action::@88::@90 dialplan_args
char context[AST_MAX_CONTEXT]
Definition confbridge.h:128
union conf_menu_action::@88 data

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, 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 3200 of file app_confbridge.c.

3203{
3204 struct confbridge_user *last_user = NULL;
3205 int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3206
3207 if (!isadmin) {
3208 play_file(bridge_channel, NULL,
3210 ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
3211 ast_channel_name(bridge_channel->chan),
3212 conference->name);
3213 return -1;
3214 }
3215
3217 last_user = AST_LIST_LAST(&conference->active_list);
3218 if (!last_user) {
3220 return 0;
3221 }
3222
3223 if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3225 play_file(bridge_channel, NULL,
3227 } else if (!last_user->kicked) {
3228 last_user->kicked = 1;
3229 pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3232 }
3233
3234 return 0;
3235}
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:2150
@ CONF_SOUND_ERROR_MENU
Definition confbridge.h:188
#define LOG_WARNING
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
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:239
unsigned int kicked
Definition confbridge.h:285
struct confbridge_conference * conference
Definition confbridge.h:275
struct ast_channel * chan
Definition confbridge.h:280
struct user_profile u_profile
Definition confbridge.h:277

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 4272 of file app_confbridge.c.

4273{
4274 const char *conference_name = astman_get_header(m, "Conference");
4275 int res = 0;
4276
4277 if (ast_strlen_zero(conference_name)) {
4278 astman_send_error(s, m, "No Conference name provided.");
4279 return 0;
4280 }
4282 astman_send_error(s, m, "No active conferences.");
4283 return 0;
4284 }
4285 if ((res = generic_lock_unlock_helper(lock, conference_name))) {
4286 astman_send_error(s, m, "No Conference by that name found.");
4287 return 0;
4288 }
4289 astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
4290 return 0;
4291}
static int generic_lock_unlock_helper(int lock, const char *conference_name)
ast_mutex_t lock
Definition app_sla.c:337

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 4230 of file app_confbridge.c.

4231{
4232 const char *conference_name = astman_get_header(m, "Conference");
4233 const char *channel_name = astman_get_header(m, "Channel");
4234 int res = 0;
4235
4236 if (ast_strlen_zero(conference_name)) {
4237 astman_send_error(s, m, "No Conference name provided.");
4238 return 0;
4239 }
4240 if (ast_strlen_zero(channel_name)) {
4241 astman_send_error(s, m, "No channel name provided.");
4242 return 0;
4243 }
4245 astman_send_error(s, m, "No active conferences.");
4246 return 0;
4247 }
4248
4249 res = generic_mute_unmute_helper(mute, conference_name, channel_name);
4250
4251 if (res == -1) {
4252 astman_send_error(s, m, "No Conference by that name found.");
4253 return 0;
4254 } else if (res == -2) {
4255 astman_send_error(s, m, "No Channel by that name found in Conference.");
4256 return 0;
4257 }
4258
4259 astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
4260 return 0;
4261}
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 3115 of file app_confbridge.c.

3116{
3117 char *file_copy = ast_strdupa(playback_file);
3118 char *file = NULL;
3119
3120 while ((file = ast_strsep(&file_copy, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
3121 if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
3122 ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
3123 return -1;
3124 }
3125 }
3126 return 0;
3127}
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:1920
@ 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:1869

References ast_log, ast_strdupa, ast_stream_and_wait(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, ast_bridge_channel::chan, 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 3129 of file app_confbridge.c.

3136{
3137 int i;
3138 int digit = 0;
3139 char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
3140 struct conf_menu_entry new_menu_entry = { { 0, }, };
3141 char *file_copy = ast_strdupa(playback_file);
3142 char *file = NULL;
3143
3144 while ((file = ast_strsep(&file_copy, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
3145 if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
3146 ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
3147 return -1;
3148 }
3149
3150 /* now wait for more digits. */
3151 if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
3152 /* streaming finished and no DTMF was entered */
3153 continue;
3154 } else if (digit == -1) {
3155 /* error */
3156 return -1;
3157 } else {
3158 break; /* dtmf was entered */
3159 }
3160 }
3161 if (!digit) {
3162 /* streaming finished on all files and no DTMF was entered */
3163 return -1;
3164 }
3165 ast_stopstream(bridge_channel->chan);
3166
3167 /* If we get here, then DTMF has been entered, This means no
3168 * additional prompts should be played for this menu entry */
3169 *stop_prompts = 1;
3170
3171 /* If a digit was pressed during the payback, update
3172 * the dtmf string and look for a new menu entry in the
3173 * menu structure */
3174 ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
3175 for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
3176 dtmf[i] = cur_dtmf[i];
3177 if (!dtmf[i]) {
3178 dtmf[i] = (char) digit;
3179 dtmf[i + 1] = '\0';
3180 i = -1;
3181 break;
3182 }
3183 }
3184 /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
3185 * If this is the case, no new DTMF sequence should be looked for. */
3186 if (i != -1) {
3187 return 0;
3188 }
3189
3190 if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
3191 execute_menu_entry(conference,
3192 user,
3193 bridge_channel,
3194 &new_menu_entry, menu);
3195 conf_menu_entry_destroy(&new_menu_entry);
3196 }
3197 return 0;
3198}
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:223
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition file.c:1320
#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:1882
Definition confbridge.h:139
char dtmf[MAXIMUM_DTMF_FEATURE_STRING]
Definition confbridge.h:141

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(), 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 3059 of file app_confbridge.c.

3062{
3063 unsigned int binaural;
3064 ast_bridge_channel_lock_bridge(bridge_channel);
3065 binaural = !bridge_channel->binaural_suspended;
3066 bridge_channel->binaural_suspended = binaural;
3067 ast_bridge_unlock(bridge_channel->bridge);
3068 return play_file(bridge_channel, NULL, (binaural ?
3069 conf_get_sound(CONF_SOUND_BINAURAL_OFF, user->b_profile.sounds) :
3071}
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition bridge.h:491
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:194
@ CONF_SOUND_BINAURAL_OFF
Definition confbridge.h:195
static struct stasis_rest_handlers sounds
REST handler for /api-docs/sounds.json.
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 3044 of file app_confbridge.c.

3047{
3048 int mute;
3049
3050 /* Toggle user level mute request. */
3051 mute = !user->muted;
3052 generic_mute_unmute_user(conference, user, mute);
3053
3054 return play_file(bridge_channel, NULL,
3056 conference->b_profile.sounds)) < 0;
3057}
static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
@ CONF_SOUND_UNMUTED
Definition confbridge.h:175
@ CONF_SOUND_MUTED
Definition confbridge.h:174

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 3073 of file app_confbridge.c.

3074{
3075 struct confbridge_user *cur_user = NULL;
3076 const char *sound_to_play;
3077 int mute;
3078
3080
3081 /* Toggle bridge level mute request. */
3082 mute = !conference->muted;
3083 conference->muted = mute;
3084
3086 if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
3087 /* Set user level to bridge level mute request. */
3088 cur_user->muted = mute;
3089 conf_update_user_mute(cur_user);
3090 }
3091 }
3092
3094
3095 sound_to_play = conf_get_sound(
3098
3099 if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
3100 /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
3101 ast_stream_and_wait(user->chan, sound_to_play, "");
3102
3103 /* Announce to the group that all participants are muted */
3105 play_sound_file(conference, sound_to_play);
3107 } else {
3108 /* Playing the sound asynchronously lets the sound be heard by everyone at once */
3109 async_play_sound_file(conference, sound_to_play, user->chan);
3110 }
3111
3112 return 0;
3113}
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...
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
@ CONF_SOUND_PARTICIPANTS_UNMUTED
Definition confbridge.h:192
@ CONF_SOUND_PARTICIPANTS_MUTED
Definition confbridge.h:191
char language[MAX_LANGUAGE]
Definition confbridge.h:230
unsigned int muted
Definition confbridge.h:284
struct confbridge_user::@98 list
struct bridge_profile b_profile
Definition confbridge.h:276

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 1636 of file app_confbridge.c.

1637{
1638 struct ast_format_cap *cap;
1639 char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1640
1642 if (!cap) {
1643 return -1;
1644 }
1646 conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1647 conference->name, NULL);
1648 ao2_ref(cap, -1);
1649 if (!conference->playback_chan) {
1650 return -1;
1651 }
1652
1653 /* To make sure playback_chan has the same language as the bridge */
1654 ast_channel_lock(conference->playback_chan);
1655 ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1656 ast_channel_unlock(conference->playback_chan);
1657
1658 ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1659 ast_channel_name(conference->playback_chan), conference->name);
1660
1661 ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1662 "Confbridge/%s", conference->name);
1663 conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1664 if (!conference->playback_queue) {
1665 ast_hangup(conference->playback_chan);
1666 conference->playback_chan = NULL;
1667 return -1;
1668 }
1669 return 0;
1670}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2540
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.
@ 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:257
struct ast_taskprocessor * playback_queue
Definition confbridge.h:263
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
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).

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 announcement will be sent to all participants in the conference.
Return values
0on success.
-1if the user hung up.

Definition at line 1123 of file app_confbridge.c.

1125{
1126 const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
1127 const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
1128 const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
1129
1130 if (!user && !conference->playback_queue) {
1131 /* Announcements to the entire conference are disabled. Announcements to a
1132 * single caller are played on that caller's channel, so they still work. */
1133 return 0;
1134 }
1135
1136 if (conference->activeusers <= 1) {
1137 /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
1138 return 0;
1139 } else if (conference->activeusers == 2) {
1140 if (user) {
1141 /* Eep, there is one other person */
1142 if (play_file(bridge_channel, user->chan, only_one) < 0) {
1143 return -1;
1144 }
1145 } else {
1146 play_sound_file(conference, only_one);
1147 }
1148 } else {
1149 /* Alas multiple others in here */
1150 if (user) {
1151 if (ast_stream_and_wait(user->chan,
1152 there_are,
1153 "")) {
1154 return -1;
1155 }
1156 if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
1157 return -1;
1158 }
1159 if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
1160 return -1;
1161 }
1162 } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
1163 play_sound_file(conference, there_are);
1164 play_sound_number(conference, conference->activeusers - 1);
1165 play_sound_file(conference, other_in_party);
1166 }
1167 }
1168 return 0;
1169}
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:178
@ CONF_SOUND_THERE_ARE
Definition confbridge.h:177
@ CONF_SOUND_ONLY_ONE
Definition confbridge.h:176
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:8411

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(), confbridge_conference::playback_queue, 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 4768 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data * async_datastore_data_alloc ( void  )
static

Definition at line 2241 of file app_confbridge.c.

2242{
2243 struct async_datastore_data *add;
2244
2245 add = ast_malloc(sizeof(*add));
2246 if (!add) {
2247 return NULL;
2248 }
2249
2250 ast_mutex_init(&add->lock);
2251 ast_cond_init(&add->cond, NULL);
2252 add->wait = 1;
2253
2254 return add;
2255}
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_mutex_init(pmutex)
Definition lock.h:193

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 2209 of file app_confbridge.c.

2210{
2211 struct async_datastore_data *add = data;
2212
2213 ast_mutex_destroy(&add->lock);
2214 ast_cond_destroy(&add->cond);
2215
2216 ast_free(add);
2217}
#define ast_cond_destroy(cond)
Definition lock.h:209
#define ast_mutex_destroy(a)
Definition lock.h:195

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 2653 of file app_confbridge.c.

2655{
2657
2659 return 0;
2660 } else if (!sound_file_exists(filename)) {
2661 return 0;
2662 }
2663
2664 /* Without a playback queue there is no playback to wait for, so just remove it now */
2665 if (!conference->playback_queue) {
2667 ast_debug(1, "Conference '%s' removed user name file '%s'\n",
2669 return 0;
2670 }
2671
2673 if (!atd) {
2674 return -1;
2675 }
2676
2678 ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2681 return -1;
2682 }
2683
2684 return 0;
2685}
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)
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition file.c:1168
struct confbridge_conference * conference
#define ast_taskprocessor_push(tps, task_exe, datap)

References ast_debug, ast_filedelete(), 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, NULL, 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 2641 of file app_confbridge.c.

2642{
2643 struct async_delete_name_rec_task_data *atd = data;
2644
2646 ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2647 atd->conference->name, atd->filename);
2648
2650 return 0;
2651}
#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 2610 of file app_confbridge.c.

2612{
2614
2615 atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2616 if (!atd) {
2617 return NULL;
2618 }
2619
2620 /* Safe */
2621 strcpy(atd->filename, filename);
2622 atd->conference = conference;
2623
2624 return atd;
2625}

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 2627 of file app_confbridge.c.

2628{
2629 ast_free(atd);
2630}

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 2443 of file app_confbridge.c.

2445{
2446 return async_play_sound_helper(conference, filename, -1, initiator);
2447}
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 2404 of file app_confbridge.c.

2406{
2407 struct async_playback_task_data *aptd;
2408
2409 /* Announcements are disabled for this conference, there is nothing to play them on */
2410 if (!conference->playback_queue) {
2411 return 0;
2412 }
2413
2414 /* Do not waste resources trying to play files that do not exist */
2416 if (say_number < 0) {
2417 return 0;
2418 }
2419 } else if (!sound_file_exists(filename)) {
2420 return 0;
2421 }
2422
2424 if (!aptd) {
2425 return -1;
2426 }
2427
2429 if (!ast_strlen_zero(filename)) {
2430 ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2432 } else {
2433 ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2435 }
2437 return -1;
2438 }
2439
2440 return 0;
2441}
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 2449 of file app_confbridge.c.

2450{
2451 struct ast_datastore *async_datastore;
2452 struct async_datastore_data *add;
2453
2454 ast_channel_lock(chan);
2455 async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2456 ast_channel_unlock(chan);
2457 if (!async_datastore) {
2458 return;
2459 }
2460
2461 add = async_datastore->data;
2462
2463 ast_mutex_lock(&add->lock);
2464 add->wait = 0;
2465 ast_cond_signal(&add->cond);
2466 ast_mutex_unlock(&add->lock);
2467}
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:2390
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196
#define ast_cond_signal(cond)
Definition lock.h:210
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 2389 of file app_confbridge.c.

2390{
2391 struct async_playback_task_data *aptd = data;
2392
2393 /* Wait for the initiator to get back in the bridge or be hung up */
2394 if (aptd->initiator) {
2396 }
2397
2398 playback_common(aptd->conference, aptd->filename, aptd->say_number);
2399
2401 return 0;
2402}
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 2297 of file app_confbridge.c.

2300{
2301 struct async_playback_task_data *aptd;
2302
2303 aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
2304 if (!aptd) {
2305 return NULL;
2306 }
2307
2308 /* Safe */
2309 strcpy(aptd->filename, filename);
2310 aptd->say_number = say_number;
2311
2312 /* You may think that we need to bump the conference refcount since we are pushing
2313 * this task to the taskprocessor.
2314 *
2315 * In this case, that actually causes a problem. The destructor for the conference
2316 * pushes a hangup task into the taskprocessor and waits for it to complete before
2317 * continuing. If the destructor gets called from a taskprocessor task, we're
2318 * deadlocked.
2319 *
2320 * So is there a risk of the conference being freed out from under us? No. Since
2321 * the destructor pushes a task into the taskprocessor and waits for it to complete,
2322 * the destructor cannot free the conference out from under us. No further tasks
2323 * can be queued onto the taskprocessor after the hangup since no channels are referencing
2324 * the conference at that point any more.
2325 */
2326 aptd->conference = conference;
2327
2328 aptd->initiator = initiator;
2329 if (initiator) {
2332 /* We don't really care if this fails. If the datastore fails to get set up
2333 * we'll still play the announcement. It's possible that the sound will be
2334 * clipped for the initiator, but that's not the end of the world.
2335 */
2338 }
2339
2340 return aptd;
2341}
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:3008

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 2343 of file app_confbridge.c.

2344{
2346 ast_free(aptd);
2347}
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition channel.h:3030

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 3752 of file app_confbridge.c.

3753{
3754 int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
3755
3756 if (res == -1) {
3757 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3758 return -1;
3759 } else if (res == -2) {
3760 if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3761 ast_cli(a->fd, "No participants found in conference %s\n", a->argv[2]);
3762 } else {
3763 ast_cli(a->fd, "No channel named '%s' found in conference %s\n", a->argv[3], a->argv[2]);
3764 }
3765 return -1;
3766 }
3767 ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
3768 return 0;
3769}
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 3458 of file app_confbridge.c.

3459{
3460 int which = 0;
3461 struct confbridge_conference *conference;
3462 char *res = NULL;
3463 int wordlen = strlen(word);
3464 struct ao2_iterator iter;
3465
3467 while ((conference = ao2_iterator_next(&iter))) {
3468 if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3469 res = ast_strdup(conference->name);
3470 ao2_ref(conference, -1);
3471 break;
3472 }
3473 ao2_ref(conference, -1);
3474 }
3475 ao2_iterator_destroy(&iter);
3476
3477 return res;
3478}
#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 3480 of file app_confbridge.c.

3481{
3482 int which = 0;
3483 RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3484 struct confbridge_user *user;
3485 char *res = NULL;
3486 int wordlen = strlen(word);
3487
3488 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3489 if (!conference) {
3490 return NULL;
3491 }
3492
3493 if (!strncasecmp("all", word, wordlen) && ++which > state) {
3494 return ast_strdup("all");
3495 }
3496
3497 if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3498 return ast_strdup("participants");
3499 }
3500
3501 {
3502 SCOPED_AO2LOCK(bridge_lock, conference);
3504 if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3505 res = ast_strdup(ast_channel_name(user->chan));
3506 return res;
3507 }
3508 }
3510 if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3511 res = ast_strdup(ast_channel_name(user->chan));
3512 return res;
3513 }
3514 }
3515 }
3516
3517 return NULL;
3518}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition lock.h:611
#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:981

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, 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 1585 of file app_confbridge.c.

1586{
1587 struct post_join_action *action;
1588 if (!(action = ast_calloc(1, sizeof(*action)))) {
1589 return -1;
1590 }
1591 action->func = func;
1592 AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1593 return 0;
1594}
#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.
int(* func)(struct confbridge_user *user)
Definition confbridge.h:269
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(), 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 4567 of file app_confbridge.c.

4568{
4569 AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4570 conference->activeusers++;
4571}

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

Referenced by join_active(), join_active(), join_unmarked(), join_unmarked(), join_unmarked(), 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 4573 of file app_confbridge.c.

4574{
4575 AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4576 conference->activeusers++;
4577 conference->markedusers++;
4578}

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

Referenced by join_marked(), join_marked(), join_marked(), join_marked(), join_marked(), and 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 4580 of file app_confbridge.c.

4581{
4582 AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4583 conference->waitingusers++;
4584}

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 1613 of file app_confbridge.c.

1614{
1615 struct pbx_find_info q = { .stacklen = 0 };
1616
1617 /* Called with a reference to conference */
1618 ao2_unlink(conference_bridges, conference);
1619 send_conf_end_event(conference);
1620 if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1622 conference->name, 1, NULL, "", E_MATCH)) {
1624 conference->name, 1, NULL);
1625 }
1626 ao2_lock(conference);
1627 conf_stop_record(conference);
1628 ao2_unlock(conference);
1629}
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:3508
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:240

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 922 of file app_confbridge.c.

923{
924 return ao2_find(conference_bridges, conference_name, OBJ_KEY);
925}

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 2511 of file app_confbridge.c.

2512{
2513 char pin_guess[MAX_PIN+1] = { 0, };
2514 const char *pin = user->u_profile.pin;
2515 char *tmp = pin_guess;
2516 int i, res;
2517 unsigned int len = MAX_PIN;
2518
2519 /*
2520 * NOTE: We have not joined a conference yet so we have to use
2521 * the bridge profile requested by the user.
2522 */
2523
2524 /* give them three tries to get the pin right */
2525 for (i = 0; i < 3; i++) {
2526 if (ast_app_getdata(chan,
2527 conf_get_sound(CONF_SOUND_GET_PIN, user->b_profile.sounds),
2528 tmp, len, 0) >= 0) {
2529 if (!strcasecmp(pin, pin_guess)) {
2530 return 0;
2531 }
2532 }
2533 ast_streamfile(chan,
2534 conf_get_sound(CONF_SOUND_INVALID_PIN, user->b_profile.sounds),
2535 ast_channel_language(chan));
2536 res = ast_waitstream(chan, AST_DIGIT_ANY);
2537 if (res > 0) {
2538 /* Account for digit already read during ivalid pin playback
2539 * resetting pin buf. */
2540 pin_guess[0] = res;
2541 pin_guess[1] = '\0';
2542 tmp = pin_guess + 1;
2543 len = MAX_PIN - 1;
2544 } else {
2545 /* reset pin buf as empty buffer. */
2546 tmp = pin_guess;
2547 len = MAX_PIN;
2548 }
2549 }
2550 return -1;
2551}
#define MAX_PIN
Definition app_meetme.c:882
@ CONF_SOUND_INVALID_PIN
Definition confbridge.h:183
@ CONF_SOUND_GET_PIN
Definition confbridge.h:182
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(), and MAX_PIN.

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 661 of file app_confbridge.c.

662{
663 switch (sound) {
665 return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
667 return S_OR(custom_sounds->hasleft, "conf-hasleft");
669 return S_OR(custom_sounds->kicked, "conf-kicked");
670 case CONF_SOUND_MUTED:
671 return S_OR(custom_sounds->muted, "conf-muted");
673 return S_OR(custom_sounds->unmuted, "conf-unmuted");
675 return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
677 return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
679 return S_OR(custom_sounds->onlyone, "conf-onlyone");
681 return S_OR(custom_sounds->thereare, "conf-thereare");
683 return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
685 return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
687 return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
689 return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
691 return S_OR(custom_sounds->getpin, "conf-getpin");
693 return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
695 return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
697 return S_OR(custom_sounds->locked, "conf-locked");
699 return S_OR(custom_sounds->lockednow, "conf-lockednow");
701 return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
703 return S_OR(custom_sounds->errormenu, "conf-errormenu");
704 case CONF_SOUND_JOIN:
705 return S_OR(custom_sounds->join, "confbridge-join");
706 case CONF_SOUND_LEAVE:
707 return S_OR(custom_sounds->leave, "confbridge-leave");
709 return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
711 return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
712 case CONF_SOUND_BEGIN:
713 return S_OR(custom_sounds->begin, "confbridge-conf-begin");
714 }
715
716 return "";
717}
@ CONF_SOUND_JOIN
Definition confbridge.h:189
@ CONF_SOUND_LOCKED_NOW
Definition confbridge.h:186
@ CONF_SOUND_ONLY_PERSON
Definition confbridge.h:184
@ CONF_SOUND_BEGIN
Definition confbridge.h:193
@ CONF_SOUND_WAIT_FOR_LEADER
Definition confbridge.h:180
@ CONF_SOUND_HAS_LEFT
Definition confbridge.h:172
@ CONF_SOUND_LEAVE
Definition confbridge.h:190
@ CONF_SOUND_LEADER_HAS_LEFT
Definition confbridge.h:181
@ CONF_SOUND_PLACE_IN_CONF
Definition confbridge.h:179
@ CONF_SOUND_HAS_JOINED
Definition confbridge.h:171
@ CONF_SOUND_UNLOCKED_NOW
Definition confbridge.h:187
@ CONF_SOUND_LOCKED
Definition confbridge.h:185
@ CONF_SOUND_KICKED
Definition confbridge.h:173
#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:225
const ast_string_field invalidpin
Definition confbridge.h:225
const ast_string_field placeintoconf
Definition confbridge.h:225
const ast_string_field onlyone
Definition confbridge.h:225
const ast_string_field otherinparty
Definition confbridge.h:225
const ast_string_field unlockednow
Definition confbridge.h:225
const ast_string_field binauralon
Definition confbridge.h:225
const ast_string_field getpin
Definition confbridge.h:225
const ast_string_field errormenu
Definition confbridge.h:225
const ast_string_field participantsunmuted
Definition confbridge.h:225
const ast_string_field participantsmuted
Definition confbridge.h:225
const ast_string_field leave
Definition confbridge.h:225
const ast_string_field locked
Definition confbridge.h:225
const ast_string_field join
Definition confbridge.h:225
const ast_string_field kicked
Definition confbridge.h:225
const ast_string_field hasleft
Definition confbridge.h:225
const ast_string_field unmuted
Definition confbridge.h:225
const ast_string_field leaderhasleft
Definition confbridge.h:225
const ast_string_field lockednow
Definition confbridge.h:225
const ast_string_field hasjoin
Definition confbridge.h:225
const ast_string_field binauraloff
Definition confbridge.h:225
const ast_string_field onlyperson
Definition confbridge.h:225
const ast_string_field thereare
Definition confbridge.h:225
const ast_string_field muted
Definition confbridge.h:225
const ast_string_field begin
Definition confbridge.h:225

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 3392 of file app_confbridge.c.

3396{
3397 /* See if music on hold is playing */
3399
3400 /* execute the list of actions associated with this menu entry */
3401 execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3402
3403 /* See if music on hold needs to be started back up again */
3405
3406 async_play_sound_ready(bridge_channel->chan);
3407
3408 return 0;
3409}
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 1597 of file app_confbridge.c.

1598{
1599 ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference->name);
1600}
@ 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.
@ 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 1561 of file app_confbridge.c.

1562{
1563 /* If we have not been quieted play back that they are waiting for the leader */
1565 conf_get_sound(CONF_SOUND_WAIT_FOR_LEADER, user->conference->b_profile.sounds))) {
1566 /* user hungup while the sound was playing */
1567 return -1;
1568 }
1569 return 0;
1570}
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 1572 of file app_confbridge.c.

1573{
1574 /* If audio prompts have not been quieted or this prompt quieted play it on out */
1577 conf_get_sound(CONF_SOUND_ONLY_PERSON, user->conference->b_profile.sounds))) {
1578 /* user hungup while the sound was playing */
1579 return -1;
1580 }
1581 }
1582 return 0;
1583}
@ 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(), join_unmarked(), 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 1602 of file app_confbridge.c.

1603{
1604 /* If we are the second participant we may need to stop music on hold on the first */
1605 struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1606
1607 if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1608 conf_moh_stop(first_user);
1609 }
1610 conf_update_user_mute(first_user);
1611}
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.

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(), 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 2483 of file app_confbridge.c.

2484{
2485 struct confbridge_user *user = hook_pvt;
2487 struct ast_json *talking_extras;
2488
2489 conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2490 if (!conference) {
2491 /* Remove the hook since the conference does not exist. */
2492 return -1;
2493 }
2494
2495 ao2_lock(conference);
2496 user->talking = talking;
2497 ao2_unlock(conference);
2498
2499 talking_extras = ast_json_pack("{s: s, s: b}",
2500 "talking_status", talking ? "on" : "off",
2501 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2502 if (!talking_extras) {
2503 return 0;
2504 }
2505
2506 send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2507 ast_json_unref(talking_extras);
2508 return 0;
2509}
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 938 of file app_confbridge.c.

939{
940 return conference->record_chan != NULL;
941}
struct ast_channel * record_chan
Definition confbridge.h:258

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 1504 of file app_confbridge.c.

1505{
1506 user->playing_moh = 1;
1507 if (!user->suspended_moh) {
1508 int in_bridge;
1509
1510 /*
1511 * Locking the ast_bridge here is the only way to hold off the
1512 * call to ast_bridge_join() in confbridge_exec() from
1513 * interfering with the bridge and MOH operations here.
1514 */
1515 ast_bridge_lock(user->conference->bridge);
1516
1517 /*
1518 * Temporarily suspend the user from the bridge so we have
1519 * control to start MOH if needed.
1520 */
1521 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1522 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1523 if (in_bridge) {
1524 ast_bridge_unsuspend(user->conference->bridge, user->chan);
1525 }
1526
1527 ast_bridge_unlock(user->conference->bridge);
1528 }
1529}
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition bridge.c:3216
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition bridge.c:3237
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition bridge.h:480
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:7802

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 1477 of file app_confbridge.c.

1478{
1479 user->playing_moh = 0;
1480 if (!user->suspended_moh) {
1481 int in_bridge;
1482
1483 /*
1484 * Locking the ast_bridge here is the only way to hold off the
1485 * call to ast_bridge_join() in confbridge_exec() from
1486 * interfering with the bridge and MOH operations here.
1487 */
1488 ast_bridge_lock(user->conference->bridge);
1489
1490 /*
1491 * Temporarily suspend the user from the bridge so we have
1492 * control to stop MOH if needed.
1493 */
1494 in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1495 ast_moh_stop(user->chan);
1496 if (in_bridge) {
1497 ast_bridge_unsuspend(user->conference->bridge, user->chan);
1498 }
1499
1500 ast_bridge_unlock(user->conference->bridge);
1501 }
1502}
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition channel.c:7812

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 1552 of file app_confbridge.c.

1553{
1554 ao2_lock(user->conference);
1555 if (user->suspended_moh++ == 0 && user->playing_moh) {
1556 ast_moh_stop(user->chan);
1557 }
1558 ao2_unlock(user->conference);
1559}

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 1537 of file app_confbridge.c.

1538{
1539 ao2_lock(user->conference);
1540 if (--user->suspended_moh == 0 && user->playing_moh) {
1541 ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1542 }
1543 ao2_unlock(user->conference);
1544}

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 4599 of file app_confbridge.c.

4600{
4602
4603 /* Turn on MOH if the single participant is set up for it */
4604 if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4605 conf_moh_start(only_user);
4606 }
4607 conf_update_user_mute(only_user);
4608}
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 2560 of file app_confbridge.c.

2561{
2562 char destdir[PATH_MAX];
2563 int res;
2564 int duration = 20;
2565
2566 snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2567
2568 if (ast_mkdir(destdir, 0777) != 0) {
2569 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2570 return -1;
2571 }
2572 snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2573 "%s/confbridge-name-%s-%s", destdir,
2574 conf_name, ast_channel_uniqueid(user->chan));
2575
2577 res = ast_play_and_record(user->chan,
2578 "vm-rec-name",
2579 user->name_rec_location,
2580 10,
2581 "sln",
2582 &duration,
2583 NULL,
2585 0,
2586 NULL);
2587 } else {
2588 res = ast_record_review(user->chan,
2589 "vm-rec-name",
2590 user->name_rec_location,
2591 10,
2592 "sln",
2593 &duration,
2594 NULL);
2595 }
2596
2597 if (res == -1) {
2598 ast_filedelete(user->name_rec_location, NULL);
2599 user->name_rec_location[0] = '\0';
2600 return -1;
2601 }
2602 return 0;
2603}
#define PATH_MAX
Definition asterisk.h:40
@ USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW
Definition confbridge.h:68
@ THRESHOLD_SILENCE
Definition dsp.h:75
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition dsp.c:2196
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:2155
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:2647
int errno
const char * ast_config_AST_SPOOL_DIR
Definition options.c:155
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition utils.c:2513

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 4586 of file app_confbridge.c.

4587{
4588 AST_LIST_REMOVE(&conference->active_list, user, list);
4589 conference->activeusers--;
4590}
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.

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

Referenced by leave_active(), leave_unmarked(), 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 4592 of file app_confbridge.c.

4593{
4594 AST_LIST_REMOVE(&conference->active_list, user, list);
4595 conference->activeusers--;
4596 conference->markedusers--;
4597}

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

Referenced by leave_marked(), and 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 4610 of file app_confbridge.c.

4611{
4612 AST_LIST_REMOVE(&conference->waiting_list, user, list);
4613 conference->waitingusers--;
4614}

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 986 of file app_confbridge.c.

987{
988 struct ast_app *mixmonapp;
989 struct ast_channel *chan;
990 struct ast_format_cap *cap;
991 struct ast_bridge_features *features;
992
993 if (conf_is_recording(conference)) {
994 return -1;
995 }
996
997 mixmonapp = pbx_findapp("MixMonitor");
998 if (!mixmonapp) {
999 ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
1000 return -1;
1001 }
1002
1003 features = ast_bridge_features_new();
1004 if (!features) {
1005 return -1;
1006 }
1008
1010 if (!cap) {
1012 return -1;
1013 }
1015
1016 /* Create the recording channel. */
1017 chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
1018 ao2_ref(cap, -1);
1019 if (!chan) {
1021 return -1;
1022 }
1023
1024 /* Start recording. */
1025 set_rec_filename(conference, &conference->record_filename,
1026 is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
1027 ast_answer(chan);
1028 pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
1029
1030 /* Put the channel into the conference bridge. */
1031 ast_channel_ref(chan);
1032 conference->record_chan = chan;
1033 if (ast_bridge_impart(conference->bridge, chan, NULL, features,
1035 ast_hangup(chan);
1036 ast_channel_unref(chan);
1037 conference->record_chan = NULL;
1038 return -1;
1039 }
1040
1041 ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
1042 send_start_record_event(conference);
1043
1044 return 0;
1045}
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:2077
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition bridge.h:600
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition bridge.c:3892
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition bridge.c:3883
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3019
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition channel.c:2805
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition pbx_app.c:483
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:229
struct ast_str * orig_rec_file
Definition confbridge.h:260
struct ast_str * record_filename
Definition confbridge.h:259
#define ast_test_suite_event_notify(s, f,...)
Definition test.h:189
#define ast_set_flag(p, flag)
Definition utils.h:71

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 954 of file app_confbridge.c.

955{
956 struct ast_channel *chan;
958
959 if (!conf_is_recording(conference)) {
960 return -1;
961 }
962
963 /* Remove the recording channel from the conference bridge. */
964 chan = conference->record_chan;
965 conference->record_chan = NULL;
966 ast_queue_frame(chan, &f);
967 ast_channel_unref(chan);
968
969 ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
970 send_stop_record_event(conference);
971
972 return 0;
973}
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:1171
@ AST_FRAME_CONTROL
@ AST_CONTROL_HANGUP
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass

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(), ast_frame_subclass::integer, bridge_profile::name, NULL, confbridge_conference::record_chan, send_stop_record_event(), and ast_frame::subclass.

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 1419 of file app_confbridge.c.

1420{
1421 int mute_user;
1422 int mute_system;
1423 int mute_effective;
1424
1425 /* User level mute request. */
1426 mute_user = user->muted;
1427
1428 /* System level mute request. */
1429 mute_system = user->playing_moh
1430 /*
1431 * Do not allow waitmarked users to talk to anyone unless there
1432 * is a marked user present.
1433 */
1434 || (!user->conference->markedusers
1435 && ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED));
1436
1437 mute_effective = mute_user || mute_system;
1438
1439 ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1440 ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1441 mute_user, mute_system);
1442 user->features.mute = mute_effective;
1443 ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1444 "Mode: %s\r\n"
1445 "Conference: %s\r\n"
1446 "Channel: %s",
1447 mute_effective ? "muted" : "unmuted",
1448 user->conference->b_profile.name,
1449 ast_channel_name(user->chan));
1450}
static const char name[]
Definition format_mp3.c:68

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_active(), join_marked(), join_marked(), join_marked(), join_marked(), join_marked(), join_unmarked(), 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 2713 of file app_confbridge.c.

2714{
2715 int res = 0, volume_adjustments[2];
2716 int quiet = 0;
2717 int async_delete_task_pushed = 0;
2718 char *parse;
2719 const char *b_profile_name = NULL;
2720 const char *u_profile_name = NULL;
2721 const char *menu_profile_name = NULL;
2722 struct confbridge_conference *conference = NULL;
2723 struct confbridge_user user = {
2724 .chan = chan,
2725 .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2726 .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2727 .tech_args.drop_silence = 0,
2728 };
2729 struct confbridge_hook_data *join_hook_data;
2730 struct confbridge_hook_data *leave_hook_data;
2731
2733 AST_APP_ARG(conf_name);
2734 AST_APP_ARG(b_profile_name);
2735 AST_APP_ARG(u_profile_name);
2736 AST_APP_ARG(menu_profile_name);
2737 );
2738
2739 if (ast_bridge_features_init(&user.features)) {
2740 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2741 res = -1;
2742 goto confbridge_cleanup;
2743 }
2744
2745 /* We need to make a copy of the input string if we are going to modify it! */
2746 parse = ast_strdupa(data);
2747
2749
2750 if (ast_strlen_zero(args.conf_name)) {
2751 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2752 ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2753 res = -1;
2754 goto confbridge_cleanup;
2755 }
2756
2757 if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2758 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2759 ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2760 res = -1;
2761 goto confbridge_cleanup;
2762 }
2763
2764 /* bridge profile name */
2765 if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2766 b_profile_name = args.b_profile_name;
2767 }
2768 if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2769 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2770 ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2771 b_profile_name : DEFAULT_BRIDGE_PROFILE);
2772 res = -1;
2773 goto confbridge_cleanup;
2774 }
2775
2776 /* user profile name */
2777 if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2778 u_profile_name = args.u_profile_name;
2779 }
2780 if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2781 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2782 ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2783 u_profile_name : DEFAULT_USER_PROFILE);
2784 res = -1;
2785 goto confbridge_cleanup;
2786 }
2787
2788 /* If channel hasn't been answered already, answer it, unless we're explicitly not supposed to */
2789 if ((ast_channel_state(chan) != AST_STATE_UP) && (ast_test_flag(&user.u_profile, USER_OPT_ANSWER_CHANNEL))) {
2790 ast_answer(chan);
2791 }
2792
2793 quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2794
2795 /* ask for a PIN immediately after finding user profile. This has to be
2796 * prompted for requardless of quiet setting. */
2797 if (!ast_strlen_zero(user.u_profile.pin)) {
2798 if (conf_get_pin(chan, &user)) {
2799 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2800 res = -1; /* invalid PIN */
2801 goto confbridge_cleanup;
2802 }
2803 }
2804
2805 /* See if we need them to record a intro name. There is no point in asking for one
2806 * when announcements are disabled, since it could never be played. The conference
2807 * does not necessarily exist yet, so this caller's own bridge profile is used. */
2808 if (!quiet && ast_test_flag(&user.b_profile, BRIDGE_OPT_ANNOUNCEMENTS) &&
2811 if (conf_rec_name(&user, args.conf_name)) {
2812 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2813 res = -1; /* Hangup during name recording */
2814 goto confbridge_cleanup;
2815 }
2816 }
2817
2818 /* menu name */
2819 if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2820 menu_profile_name = args.menu_profile_name;
2821 }
2822
2823 if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2824 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2825 ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2826 menu_profile_name : DEFAULT_MENU_PROFILE);
2827 res = -1;
2828 goto confbridge_cleanup;
2829 }
2830
2831 /* Set if DTMF should pass through for this user or not */
2832 if (ast_test_flag(&user.u_profile, USER_OPT_DTMF_PASS)) {
2833 user.features.dtmf_passthrough = 1;
2834 } else {
2835 user.features.dtmf_passthrough = 0;
2836 }
2837
2838 /* Set if text messaging is enabled for this user or not */
2839 if (ast_test_flag(&user.u_profile, USER_OPT_TEXT_MESSAGING)) {
2840 user.features.text_messaging = 1;
2841 } else {
2842 user.features.text_messaging = 0;
2843 }
2844
2845 /* Set dsp threshold values if present */
2846 if (user.u_profile.talking_threshold) {
2847 user.tech_args.talking_threshold = user.u_profile.talking_threshold;
2848 }
2849 if (user.u_profile.silence_threshold) {
2850 user.tech_args.silence_threshold = user.u_profile.silence_threshold;
2851 }
2852
2853 /* Set a talker indicate call back if talking detection is requested */
2854 if (ast_test_flag(&user.u_profile, USER_OPT_TALKER_DETECT)) {
2857 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2858 res = -1;
2859 goto confbridge_cleanup;
2860 }
2861 }
2862
2863 /* Look for a conference bridge matching the provided name */
2864 if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2865 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2866 res = -1;
2867 goto confbridge_cleanup;
2868 }
2869
2870 /* Keep a copy of volume adjustments so we can restore them later if need be */
2871 volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2872 volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2873
2874 if (ast_test_flag(&user.u_profile, USER_OPT_DROP_SILENCE)) {
2875 user.tech_args.drop_silence = 1;
2876 }
2877
2878 if (ast_test_flag(&user.u_profile, USER_OPT_JITTERBUFFER)) {
2879 ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2880 }
2881
2882 if (ast_test_flag(&user.u_profile, USER_OPT_DENOISE)) {
2883 ast_func_write(chan, "DENOISE(rx)", "on");
2884 }
2885
2886 /* if this user has a intro, play it before entering */
2887 if (!ast_strlen_zero(user.name_rec_location)) {
2889 play_sound_file(conference, user.name_rec_location);
2893 }
2894
2895 if (!quiet) {
2896 const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2897
2898 /* if hear_own_join_sound is enabled play the Join sound to everyone */
2900 if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2901 ast_stream_and_wait(chan, join_sound, "");
2903 play_sound_file(conference, join_sound);
2905 } else {
2906 async_play_sound_file(conference, join_sound, chan);
2907 }
2908 /* if hear_own_join_sound is disabled only play the Join sound to just the conference */
2909 } else {
2911 play_sound_file(conference, join_sound);
2913 }
2914 }
2915
2916 if (user.u_profile.timeout) {
2918 0,
2919 user.u_profile.timeout * 1000,
2921 NULL,
2922 NULL,
2924 }
2925
2926 /* See if we need to automatically set this user as a video source or not */
2928
2930
2931 join_hook_data = ast_malloc(sizeof(*join_hook_data));
2932 if (!join_hook_data) {
2933 res = -1;
2934 goto confbridge_cleanup;
2935 }
2936 join_hook_data->user = &user;
2937 join_hook_data->conference = conference;
2938 join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2940 join_hook_data, ast_free_ptr, 0);
2941 if (res) {
2942 ast_free(join_hook_data);
2943 ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2944 goto confbridge_cleanup;
2945 }
2946
2947 leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2948 if (!leave_hook_data) {
2949 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2950 res = -1;
2951 goto confbridge_cleanup;
2952 }
2953 leave_hook_data->user = &user;
2954 leave_hook_data->conference = conference;
2955 leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2957 leave_hook_data, ast_free_ptr, 0);
2958 if (res) {
2959 /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2960 ast_free(leave_hook_data);
2961 ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2962 goto confbridge_cleanup;
2963 }
2964
2965 if (ast_bridge_join_hook(&user.features, join_callback, NULL, NULL, 0)) {
2967 }
2968
2970 chan,
2971 NULL,
2972 &user.features,
2973 &user.tech_args,
2974 0);
2975
2976 /* This is a catch-all in case joining the bridge failed or for some reason
2977 * an async announcement got queued up and hasn't been told to play yet
2978 */
2980
2981 if (!user.kicked && ast_check_hangup(chan)) {
2982 pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2983 }
2984
2985 /* if we're shutting down, don't attempt to do further processing */
2986 if (ast_shutting_down()) {
2987 /*
2988 * Not taking any new calls at this time. We cannot create
2989 * the announcer channel if this is the first channel into
2990 * the conference and we certainly cannot create any
2991 * recording channel.
2992 */
2994 conference = NULL;
2995 goto confbridge_cleanup;
2996 }
2997
2998 /* If this user was a video source, we need to clean up and possibly pick a new source. */
3000
3001 /* if this user has a intro, play it when leaving */
3002 if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
3003 async_play_sound_file(conference, user.name_rec_location, NULL);
3006 async_delete_name_rec(conference, user.name_rec_location);
3007 async_delete_task_pushed = 1;
3008 }
3009
3010 /* play the leave sound */
3011 if (!quiet) {
3012 const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
3013 async_play_sound_file(conference, leave_sound, NULL);
3014 }
3015
3016 /* If the user was kicked from the conference play back the audio prompt for it */
3017 if (!quiet && user.kicked) {
3018 res = ast_stream_and_wait(chan,
3020 "");
3021 }
3022
3023 /* Easy as pie, depart this channel from the conference bridge */
3025 conference = NULL;
3026
3027 /* Restore volume adjustments to previous values in case they were changed */
3028 if (volume_adjustments[0]) {
3029 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
3030 }
3031 if (volume_adjustments[1]) {
3032 ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
3033 }
3034
3035confbridge_cleanup:
3036 if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
3037 ast_filedelete(user.name_rec_location, NULL);
3038 }
3041 return res;
3042}
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:1889
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:1601
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:1576
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:1820
@ 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:3829
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:3528
@ 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:3504
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:3484
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:3494
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition bridge.c:3862
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition channel.c:446
ast_channel_state
ast_channel states
@ AST_STATE_UP
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
@ BRIDGE_OPT_ANNOUNCEMENTS
Definition confbridge.h:94
#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, BRIDGE_OPT_ANNOUNCEMENTS, 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_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 1702 of file app_confbridge.c.

1703{
1704 struct ast_channel_snapshot *old_snapshot;
1705 struct ast_channel_snapshot *new_snapshot;
1706 char *confbr_name = NULL;
1707 char *comma;
1709 struct confbridge_user *user = NULL;
1710 int found_user = 0;
1711 struct ast_json *json_object;
1712
1714 && strcmp(msg->to_transferee.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1715 && msg->target) {
1716 /* We're transferring a bridge to an extension */
1717 old_snapshot = msg->to_transferee.channel_snapshot;
1718 new_snapshot = msg->target;
1719 } else if (msg->to_transfer_target.channel_snapshot
1720 && strcmp(msg->to_transfer_target.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1721 && msg->transferee) {
1722 /* We're transferring a call to a bridge */
1723 old_snapshot = msg->to_transfer_target.channel_snapshot;
1724 new_snapshot = msg->transferee;
1725 } else {
1726 ast_log(LOG_ERROR, "Could not determine proper channels\n");
1727 return;
1728 }
1729
1730 /*
1731 * old_snapshot->data should have the original parameters passed to
1732 * the ConfBridge app:
1733 * conference[,bridge_profile[,user_profile[,menu]]]
1734 * We'll use "conference" to look up the bridge.
1735 *
1736 * We _could_ use old_snapshot->bridgeid to get the bridge but
1737 * that would involve locking the conference_bridges container
1738 * and iterating over it looking for a matching bridge.
1739 */
1740 if (ast_strlen_zero(old_snapshot->dialplan->data)) {
1741 ast_log(LOG_ERROR, "Channel '%s' didn't have app data set\n", old_snapshot->base->name);
1742 return;
1743 }
1744 confbr_name = ast_strdupa(old_snapshot->dialplan->data);
1745 comma = strchr(confbr_name, ',');
1746 if (comma) {
1747 *comma = '\0';
1748 }
1749
1750 ast_debug(1, "Confbr: %s Leaving: %s Joining: %s\n", confbr_name, old_snapshot->base->name, new_snapshot->base->name);
1751
1752 conference = ao2_find(conference_bridges, confbr_name, OBJ_SEARCH_KEY);
1753 if (!conference) {
1754 ast_log(LOG_ERROR, "Conference bridge '%s' not found\n", confbr_name);
1755 return;
1756 }
1757 ao2_lock(conference);
1758
1759 /*
1760 * We need to grab the user profile for the departing user in order to
1761 * properly format the join/leave messages.
1762 */
1763 AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1764 if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1765 found_user = 1;
1766 break;
1767 }
1768 }
1769
1770 /*
1771 * If we didn't find the user in the active list, try the waiting list.
1772 */
1773 if (!found_user && conference->waitingusers) {
1774 AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
1775 if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1776 found_user = 1;
1777 break;
1778 }
1779 }
1780 }
1781
1782 if (!found_user) {
1783 ast_log(LOG_ERROR, "Unable to find user profile for channel '%s' in bridge '%s'\n",
1784 old_snapshot->base->name, confbr_name);
1785 return;
1786 }
1787
1788 /*
1789 * We're going to use the existing user profile to create the messages.
1790 */
1791 json_object = ast_json_pack("{s: b}",
1792 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
1793 );
1794 if (!json_object) {
1795 return;
1796 }
1797
1798 send_conf_stasis_snapshots(conference, old_snapshot, confbridge_leave_type(), json_object);
1799 ast_json_unref(json_object);
1800
1801 json_object = ast_json_pack("{s: b, s: b}",
1802 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
1803 "muted", user->muted);
1804 if (!json_object) {
1805 return;
1806 }
1807 send_conf_stasis_snapshots(conference, new_snapshot, confbridge_join_type(), json_object);
1808 ast_json_unref(json_object);
1809}
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 1691 of file app_confbridge.c.

1692{
1693 struct confbridge_conference *conference = obj;
1694
1695 if (!obj) {
1696 return;
1697 }
1698 ao2_unlock(conference);
1699 ao2_ref(conference, -1);
1700}

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 639 of file app_confbridge.c.

640{
641 const struct confbridge_conference *left = obj;
642 const struct confbridge_conference *right = arg;
643 const char *right_name = arg;
644 int cmp;
645
646 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
647 default:
648 case OBJ_POINTER:
649 right_name = right->name;
650 /* Fall through */
651 case OBJ_KEY:
652 cmp = strcasecmp(left->name, right_name);
653 break;
654 case OBJ_PARTIAL_KEY:
655 cmp = strncasecmp(left->name, right_name, strlen(right_name));
656 break;
657 }
658 return cmp ? 0 : CMP_MATCH;
659}
@ 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 615 of file app_confbridge.c.

616{
617 const struct confbridge_conference *conference = obj;
618 const char *name = obj;
619 int hash;
620
621 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
622 default:
623 case OBJ_POINTER:
624 name = conference->name;
625 /* Fall through */
626 case OBJ_KEY:
627 hash = ast_str_case_hash(name);
628 break;
629 case OBJ_PARTIAL_KEY:
630 /* Should never happen in hash callback. */
631 ast_assert(0);
632 hash = 0;
633 break;
634 }
635 return hash;
636}
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:779

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 4520 of file app_confbridge.c.

4521{
4522 char *parse;
4523 struct confbridge_conference *conference;
4524 int not_found;
4525
4527 AST_APP_ARG(confbridge);
4528 AST_APP_ARG(channel);
4529 );
4530
4531 if (ast_strlen_zero(data)) {
4532 ast_log(LOG_WARNING, "No conference bridge specified.\n");
4533 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4534 return 0;
4535 }
4536
4537 parse = ast_strdupa(data);
4539
4540 conference = ao2_find(conference_bridges, args.confbridge, OBJ_KEY);
4541 if (!conference) {
4542 ast_log(LOG_WARNING, "No conference bridge named '%s' found!\n", args.confbridge);
4543 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4544 return 0;
4545 }
4546 if (ast_strlen_zero(args.channel)) {
4547 not_found = kick_conference_participant(conference, "all");
4548 } else {
4549 not_found = kick_conference_participant(conference, args.channel);
4550 }
4551
4552 ao2_ref(conference, -1);
4553 if (not_found) {
4554 if (ast_strlen_zero(args.channel) || !strcasecmp("all", args.channel) || !strcasecmp("participants", args.channel)) {
4555 ast_log(LOG_WARNING, "No participants found in conference bridge '%s'!\n", args.confbridge);
4556 } else {
4557 ast_log(LOG_WARNING, "No participant named '%s' found in conference bridge '%s'!\n", args.channel, args.confbridge);
4558 }
4559 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4560 return 0;
4561 }
4562 ast_debug(1, "Kicked '%s' out of conference '%s'\n", args.channel, args.confbridge);
4563 pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "SUCCESS");
4564 return 0;
4565}

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 1317 of file app_confbridge.c.

1318{
1319 struct confbridge_conference *conference = obj;
1320
1321 ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
1322
1323 if (conference->playback_chan) {
1324 if (conference->playback_queue) {
1325 struct hangup_data hangup;
1327
1329 ast_mutex_lock(&hangup.lock);
1330 while (!hangup.hungup) {
1331 ast_cond_wait(&hangup.cond, &hangup.lock);
1332 }
1333 ast_mutex_unlock(&hangup.lock);
1334 }
1335
1337 } else {
1338 /* Playback queue is not yet allocated. Just hang up the channel straight */
1341 }
1342 }
1343
1344 /* Destroying a conference bridge is simple, all we have to do is destroy the bridging object */
1345 if (conference->bridge) {
1348 }
1349
1353
1356}
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:1029
static int hangup(void *data)
#define ast_cond_wait(cond, mutex)
Definition lock.h:212
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 3281 of file app_confbridge.c.

3286{
3287 struct conf_menu_action *menu_action;
3288 int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3289 int stop_prompts = 0;
3290 int res = 0;
3291
3292 AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
3293 switch (menu_action->id) {
3295 res |= action_toggle_mute(conference, user, bridge_channel);
3296 break;
3298 action_toggle_binaural(conference, user, bridge_channel);
3299 break;
3301 if (!isadmin) {
3302 break;
3303 }
3305 break;
3307 announce_user_count(conference, user, bridge_channel);
3308 break;
3310 if (!stop_prompts) {
3311 res |= action_playback(bridge_channel, menu_action->data.playback_file);
3312 ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
3313 "Message: %s\r\nChannel: %s",
3314 menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
3315 }
3316 break;
3319 break;
3322 break;
3326 break;
3330 break;
3334 break;
3338 break;
3340 if (!(stop_prompts)) {
3341 res |= action_playback_and_continue(conference,
3342 user,
3343 bridge_channel,
3344 menu,
3345 menu_action->data.playback_file,
3346 menu_entry->dtmf,
3347 &stop_prompts);
3348 }
3349 break;
3351 res |= action_dialplan_exec(bridge_channel, menu_action);
3352 break;
3354 if (!isadmin) {
3355 break;
3356 }
3357 conference->locked = (!conference->locked ? 1 : 0);
3358 res |= play_file(bridge_channel, NULL,
3361 conference->b_profile.sounds)) < 0;
3362 break;
3364 res |= action_kick_last(conference, bridge_channel, user);
3365 break;
3366 case MENU_ACTION_LEAVE:
3367 pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
3368 ao2_lock(conference);
3369 ast_bridge_remove(conference->bridge, bridge_channel->chan);
3370 ast_test_suite_event_notify("CONF_MENU_LEAVE",
3371 "Channel: %s",
3372 ast_channel_name(bridge_channel->chan));
3373 ao2_unlock(conference);
3374 break;
3375 case MENU_ACTION_NOOP:
3376 break;
3378 ao2_lock(conference);
3379 if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
3380 ast_bridge_set_single_src_video_mode(conference->bridge, bridge_channel->chan);
3381 }
3382 ao2_unlock(conference);
3383 break;
3385 handle_video_on_exit(conference, bridge_channel->chan);
3386 break;
3387 }
3388 }
3389 return res;
3390}
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:1626
@ BRIDGE_OPT_VIDEO_SRC_SFU
Definition confbridge.h:85
@ MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC
Definition confbridge.h:113
@ MENU_ACTION_SET_SINGLE_VIDEO_SRC
Definition confbridge.h:112
@ MENU_ACTION_ADMIN_KICK_LAST
Definition confbridge.h:109
@ MENU_ACTION_TOGGLE_BINAURAL
Definition confbridge.h:116
@ MENU_ACTION_PLAYBACK
Definition confbridge.h:99
@ MENU_ACTION_LEAVE
Definition confbridge.h:110
@ MENU_ACTION_RESET_LISTENING
Definition confbridge.h:103
@ MENU_ACTION_INCREASE_TALKING
Definition confbridge.h:105
@ MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS
Definition confbridge.h:115
@ MENU_ACTION_INCREASE_LISTENING
Definition confbridge.h:101
@ MENU_ACTION_DIALPLAN_EXEC
Definition confbridge.h:107
@ MENU_ACTION_DECREASE_LISTENING
Definition confbridge.h:102
@ MENU_ACTION_PLAYBACK_AND_CONTINUE
Definition confbridge.h:100
@ MENU_ACTION_ADMIN_TOGGLE_LOCK
Definition confbridge.h:108
@ MENU_ACTION_DECREASE_TALKING
Definition confbridge.h:106
@ MENU_ACTION_PARTICIPANT_COUNT
Definition confbridge.h:114
@ MENU_ACTION_TOGGLE_MUTE
Definition confbridge.h:98
@ MENU_ACTION_NOOP
Definition confbridge.h:111
@ MENU_ACTION_RESET_TALKING
Definition confbridge.h:104
enum conf_menu_action_id id
Definition confbridge.h:124
struct conf_menu_action::@89 action
char playback_file[PATH_MAX]
Definition confbridge.h:126
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 3999 of file app_confbridge.c.

4000{
4001 char *parse, *outbuf;
4002 struct confbridge_conference *conference;
4003 struct confbridge_user *user;
4004 int bytes, count = 0;
4005 size_t outlen;
4008 AST_APP_ARG(confno);
4009 );
4010
4011 /* parse all the required arguments and make sure they exist. */
4012 if (ast_strlen_zero(data)) {
4013 return -1;
4014 }
4015 parse = ast_strdupa(data);
4017 if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
4018 ast_log(LOG_WARNING, "Usage: %s(category,confno)", cmd);
4019 return -1;
4020 }
4022 if (!conference) {
4023 ast_debug(1, "No such conference: %s\n", args.confno);
4024 return -1;
4025 }
4026
4027 outbuf = buf;
4028 outlen = len;
4029
4031 if (!strcasecmp(args.type, "parties")) {
4033 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4034 outbuf += bytes;
4035 outlen -= bytes;
4036 }
4038 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4039 outbuf += bytes;
4040 outlen -= bytes;
4041 }
4042 } else if (!strcasecmp(args.type, "active")) {
4044 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4045 outbuf += bytes;
4046 outlen -= bytes;
4047 }
4048 } else if (!strcasecmp(args.type, "waiting")) {
4050 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4051 outbuf += bytes;
4052 outlen -= bytes;
4053 }
4054 } else if (!strcasecmp(args.type, "admins")) {
4056 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
4057 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4058 outbuf += bytes;
4059 outlen -= bytes;
4060 }
4061 }
4062 } else if (!strcasecmp(args.type, "marked")) {
4064 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
4065 bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
4066 outbuf += bytes;
4067 outlen -= bytes;
4068 }
4069 }
4070 } else {
4071 ast_log(LOG_ERROR, "Invalid keyword '%s' passed to %s.\n", args.type, cmd);
4072 }
4074 ao2_ref(conference, -1);
4075 return 0;
4076}
static const char type[]
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_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 4460 of file app_confbridge.c.

4461{
4462 char *parse;
4463 struct confbridge_conference *conference;
4464 struct confbridge_user *user;
4465 int count = 0;
4468 AST_APP_ARG(confno);
4469 );
4470
4471 /* parse all the required arguments and make sure they exist. */
4472 if (ast_strlen_zero(data)) {
4473 return -1;
4474 }
4475 parse = ast_strdupa(data);
4477 if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
4478 return -1;
4479 }
4481 if (!conference) {
4482 snprintf(buf, len, "0");
4483 return 0;
4484 }
4485
4486 /* get the correct count for the type requested */
4488 if (!strcasecmp(args.type, "parties")) {
4490 count++;
4491 }
4493 count++;
4494 }
4495 } else if (!strcasecmp(args.type, "admins")) {
4497 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
4498 count++;
4499 }
4500 }
4501 } else if (!strcasecmp(args.type, "marked")) {
4503 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
4504 count++;
4505 }
4506 }
4507 } else if (!strcasecmp(args.type, "locked")) {
4508 count = conference->locked;
4509 } else if (!strcasecmp(args.type, "muted")) {
4510 count = conference->muted;
4511 } else {
4512 ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
4513 }
4514 snprintf(buf, len, "%d", count);
4516 ao2_ref(conference, -1);
4517 return 0;
4518}

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_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 3681 of file app_confbridge.c.

3682{
3683 struct confbridge_conference *conference;
3684 int res = 0;
3685
3686 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3687 if (!conference) {
3688 return -1;
3689 }
3690 ao2_lock(conference);
3691 conference->locked = lock;
3692 ast_test_suite_event_notify("CONF_LOCK", "Message: conference %s\r\nConference: %s", conference->locked ? "locked" : "unlocked", conference->b_profile.name);
3693 ao2_unlock(conference);
3694 ao2_ref(conference, -1);
3695
3696 return res;
3697}

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 3706 of file app_confbridge.c.

3708{
3709 RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3710 struct confbridge_user *user;
3711 int all = !strcasecmp("all", chan_name);
3712 int participants = !strcasecmp("participants", chan_name);
3713 int res = -2;
3714
3715 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3716 if (!conference) {
3717 return -1;
3718 }
3719
3720 {
3721 SCOPED_AO2LOCK(bridge_lock, conference);
3723 int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3724 strlen(chan_name));
3725 if (match || all
3726 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3728 res = 0;
3729 if (match) {
3730 return res;
3731 }
3732 }
3733 }
3734
3736 int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3737 strlen(chan_name));
3738 if (match || all
3739 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3741 res = 0;
3742 if (match) {
3743 return res;
3744 }
3745 }
3746 }
3747 }
3748
3749 return res;
3750}
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:2401

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_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 1456 of file app_confbridge.c.

1457{
1458 /* Set user level mute request. */
1459 user->muted = mute ? 1 : 0;
1460
1462 ast_test_suite_event_notify("CONF_MUTE",
1463 "Message: participant %s %s\r\n"
1464 "Conference: %s\r\n"
1465 "Channel: %s",
1466 ast_channel_name(user->chan),
1467 mute ? "muted" : "unmuted",
1468 conference->b_profile.name,
1469 ast_channel_name(user->chan));
1470 if (mute) {
1471 send_mute_event(user, conference);
1472 } else {
1473 send_unmute_event(user, conference);
1474 }
1475}
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 3520 of file app_confbridge.c.

3521{
3522 struct confbridge_conference *conference;
3523 int not_found;
3524
3525 switch (cmd) {
3526 case CLI_INIT:
3527 e->command = "confbridge kick";
3528 e->usage =
3529 "Usage: confbridge kick <conference> <channel>\n"
3530 " Kicks a channel out of the conference bridge.\n"
3531 " (all to kick everyone, participants to kick non-admins).\n";
3532 return NULL;
3533 case CLI_GENERATE:
3534 if (a->pos == 2) {
3535 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3536 }
3537 if (a->pos == 3) {
3538 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3539 }
3540 return NULL;
3541 }
3542
3543 if (a->argc != 4) {
3544 return CLI_SHOWUSAGE;
3545 }
3546
3547 conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
3548 if (!conference) {
3549 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3550 return CLI_SUCCESS;
3551 }
3552 not_found = kick_conference_participant(conference, a->argv[3]);
3553 ao2_ref(conference, -1);
3554 if (not_found) {
3555 if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3556 ast_cli(a->fd, "No participants found!\n");
3557 } else {
3558 ast_cli(a->fd, "No participant named '%s' found!\n", a->argv[3]);
3559 }
3560 return CLI_SUCCESS;
3561 }
3562 ast_cli(a->fd, "Kicked '%s' out of conference '%s'\n", a->argv[3], a->argv[2]);
3563 return CLI_SUCCESS;
3564}
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 3602 of file app_confbridge.c.

3603{
3604 struct confbridge_conference *conference;
3605
3606 switch (cmd) {
3607 case CLI_INIT:
3608 e->command = "confbridge list";
3609 e->usage =
3610 "Usage: confbridge list [<name>]\n"
3611 " Lists all currently active conference bridges or a specific conference bridge.\n"
3612 "\n"
3613 " When a conference bridge name is provided, flags may be shown for users. Below\n"
3614 " are the flags and what they represent.\n"
3615 "\n"
3616 " Flags:\n"
3617 " A - The user is an admin\n"
3618 " M - The user is a marked user\n"
3619 " W - The user must wait for a marked user to join\n"
3620 " E - The user will be kicked after the last marked user leaves the conference\n"
3621 " m - The user is muted\n"
3622 " w - The user is waiting for a marked user to join\n";
3623 return NULL;
3624 case CLI_GENERATE:
3625 if (a->pos == 2) {
3626 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3627 }
3628 return NULL;
3629 }
3630
3631 if (a->argc == 2) {
3632 struct ao2_iterator iter;
3633
3634 ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
3635 ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
3637 while ((conference = ao2_iterator_next(&iter))) {
3638 ast_cli(a->fd, "%-32s %6u %6u %-6s %s\n",
3639 conference->name,
3640 conference->activeusers + conference->waitingusers,
3641 conference->markedusers,
3642 AST_CLI_YESNO(conference->locked),
3643 AST_CLI_YESNO(conference->muted));
3644 ao2_ref(conference, -1);
3645 }
3646 ao2_iterator_destroy(&iter);
3647 return CLI_SUCCESS;
3648 }
3649
3650 if (a->argc == 3) {
3651 struct confbridge_user *user;
3652
3654 if (!conference) {
3655 ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3656 return CLI_SUCCESS;
3657 }
3658 ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu CallerID\n");
3659 ast_cli(a->fd, "============================== ====== ================ ================ ================ ================\n");
3663 }
3666 }
3668 ao2_ref(conference, -1);
3669 return CLI_SUCCESS;
3670 }
3671
3672 return CLI_SHOWUSAGE;
3673}
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, 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 3566 of file app_confbridge.c.

3567{
3568 char flag_str[6 + 1];/* Max flags + terminator */
3569 int pos = 0;
3570
3571 /* Build flags column string. */
3572 if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
3573 flag_str[pos++] = 'A';
3574 }
3575 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
3576 flag_str[pos++] = 'M';
3577 }
3578 if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
3579 flag_str[pos++] = 'W';
3580 }
3581 if (ast_test_flag(&user->u_profile, USER_OPT_ENDMARKED)) {
3582 flag_str[pos++] = 'E';
3583 }
3584 if (user->muted) {
3585 flag_str[pos++] = 'm';
3586 }
3587 if (waiting) {
3588 flag_str[pos++] = 'w';
3589 }
3590 flag_str[pos] = '\0';
3591
3592 ast_cli(a->fd, "%-30s %-6s %-16s %-16s %-16s %s\n",
3593 ast_channel_name(user->chan),
3594 flag_str,
3595 user->u_profile.name,
3596 user->conference->b_profile.name,
3597 user->menu_name,
3599 ast_channel_caller(user->chan)->id.number.str, "<unknown>"));
3600}
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 3833 of file app_confbridge.c.

3834{
3835 switch (cmd) {
3836 case CLI_INIT:
3837 e->command = "confbridge lock";
3838 e->usage =
3839 "Usage: confbridge lock <conference>\n"
3840 " Lock a conference. While locked, no new non-admins\n"
3841 " may join the conference.\n";
3842 return NULL;
3843 case CLI_GENERATE:
3844 if (a->pos == 2) {
3845 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3846 }
3847 return NULL;
3848 }
3849 if (a->argc != 3) {
3850 return CLI_SHOWUSAGE;
3851 }
3852 if (generic_lock_unlock_helper(1, a->argv[2])) {
3853 ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3854 } else {
3855 ast_cli(a->fd, "Conference %s is locked.\n", a->argv[2]);
3856 }
3857 return CLI_SUCCESS;
3858}

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 3771 of file app_confbridge.c.

3772{
3773 switch (cmd) {
3774 case CLI_INIT:
3775 e->command = "confbridge mute";
3776 e->usage =
3777 "Usage: confbridge mute <conference> <channel>\n"
3778 " Mute a channel in a conference.\n"
3779 " (all to mute everyone, participants to mute non-admins)\n"
3780 " If the specified channel is a prefix,\n"
3781 " the action will be taken on the first\n"
3782 " matching channel.\n";
3783 return NULL;
3784 case CLI_GENERATE:
3785 if (a->pos == 2) {
3786 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3787 }
3788 if (a->pos == 3) {
3789 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3790 }
3791 return NULL;
3792 }
3793 if (a->argc != 4) {
3794 return CLI_SHOWUSAGE;
3795 }
3796
3798
3799 return CLI_SUCCESS;
3800}
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 3886 of file app_confbridge.c.

3887{
3888 const char *rec_file = NULL;
3889 struct confbridge_conference *conference;
3890
3891 switch (cmd) {
3892 case CLI_INIT:
3893 e->command = "confbridge record start";
3894 e->usage =
3895 "Usage: confbridge record start <conference> <file>\n"
3896 " <file> is optional, Otherwise the bridge profile\n"
3897 " record file will be used. If the bridge profile\n"
3898 " has no record file specified, a file will automatically\n"
3899 " be generated in the monitor directory\n";
3900 return NULL;
3901 case CLI_GENERATE:
3902 if (a->pos == 3) {
3903 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3904 }
3905 return NULL;
3906 }
3907 if (a->argc < 4) {
3908 return CLI_SHOWUSAGE;
3909 }
3910 if (a->argc == 5) {
3911 rec_file = a->argv[4];
3912 }
3913
3914 conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3915 if (!conference) {
3916 ast_cli(a->fd, "Conference not found.\n");
3917 return CLI_FAILURE;
3918 }
3919 ao2_lock(conference);
3920 if (conf_is_recording(conference)) {
3921 ast_cli(a->fd, "Conference is already being recorded.\n");
3922 ao2_unlock(conference);
3923 ao2_ref(conference, -1);
3924 return CLI_SUCCESS;
3925 }
3926 if (!ast_strlen_zero(rec_file)) {
3927 ast_copy_string(conference->b_profile.rec_file, rec_file, sizeof(conference->b_profile.rec_file));
3928 }
3929
3930 if (conf_start_record(conference)) {
3931 ast_cli(a->fd, "Could not start recording due to internal error.\n");
3932 ao2_unlock(conference);
3933 ao2_ref(conference, -1);
3934 return CLI_FAILURE;
3935 }
3936 ao2_unlock(conference);
3937
3938 ast_cli(a->fd, "Recording started\n");
3939 ao2_ref(conference, -1);
3940 return CLI_SUCCESS;
3941}
#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 3943 of file app_confbridge.c.

3944{
3945 struct confbridge_conference *conference;
3946 int ret;
3947
3948 switch (cmd) {
3949 case CLI_INIT:
3950 e->command = "confbridge record stop";
3951 e->usage =
3952 "Usage: confbridge record stop <conference>\n"
3953 " Stop a previously started recording.\n";
3954 return NULL;
3955 case CLI_GENERATE:
3956 if (a->pos == 3) {
3957 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3958 }
3959 return NULL;
3960 }
3961 if (a->argc != 4) {
3962 return CLI_SHOWUSAGE;
3963 }
3964
3965 conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3966 if (!conference) {
3967 ast_cli(a->fd, "Conference not found.\n");
3968 return CLI_SUCCESS;
3969 }
3970 ao2_lock(conference);
3971 ret = conf_stop_record(conference);
3972 ao2_unlock(conference);
3973 ast_cli(a->fd, "Recording %sstopped.\n", ret ? "could not be " : "");
3974 ao2_ref(conference, -1);
3975 return CLI_SUCCESS;
3976}

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 3860 of file app_confbridge.c.

3861{
3862 switch (cmd) {
3863 case CLI_INIT:
3864 e->command = "confbridge unlock";
3865 e->usage =
3866 "Usage: confbridge unlock <conference>\n"
3867 " Unlock a previously locked conference.\n";
3868 return NULL;
3869 case CLI_GENERATE:
3870 if (a->pos == 2) {
3871 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3872 }
3873 return NULL;
3874 }
3875 if (a->argc != 3) {
3876 return CLI_SHOWUSAGE;
3877 }
3878 if (generic_lock_unlock_helper(0, a->argv[2])) {
3879 ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3880 } else {
3881 ast_cli(a->fd, "Conference %s is unlocked.\n", a->argv[2]);
3882 }
3883 return CLI_SUCCESS;
3884}

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 3802 of file app_confbridge.c.

3803{
3804 switch (cmd) {
3805 case CLI_INIT:
3806 e->command = "confbridge unmute";
3807 e->usage =
3808 "Usage: confbridge unmute <conference> <channel>\n"
3809 " Unmute a channel in a conference.\n"
3810 " (all to unmute everyone, participants to unmute non-admins)\n"
3811 " If the specified channel is a prefix,\n"
3812 " the action will be taken on the first\n"
3813 " matching channel.\n";
3814 return NULL;
3815 case CLI_GENERATE:
3816 if (a->pos == 2) {
3817 return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3818 }
3819 if (a->pos == 3) {
3820 return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3821 }
3822 return NULL;
3823 }
3824 if (a->argc != 4) {
3825 return CLI_SHOWUSAGE;
3826 }
3827
3829
3830 return CLI_SUCCESS;
3831}

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 1364 of file app_confbridge.c.

1365{
1367 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1368 handler = user->conference->state->join_marked;
1369 } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1370 handler = user->conference->state->join_waitmarked;
1371 } else {
1372 handler = user->conference->state->join_unmarked;
1373 }
1374
1376
1377 if (!handler) {
1379 return -1;
1380 }
1381
1382 handler(user);
1383
1384 return 0;
1385}
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 1393 of file app_confbridge.c.

1394{
1396 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1397 handler = user->conference->state->leave_marked;
1398 } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1399 handler = user->conference->state->leave_waitmarked;
1400 } else {
1401 handler = user->conference->state->leave_unmarked;
1402 }
1403
1405
1406 if (!handler) {
1407 /* This should never happen. If it does, though, it is bad. The user will not have been removed
1408 * from the appropriate list, so counts will be off and stuff. The conference won't be torn down, etc.
1409 * Shouldn't happen, though. */
1411 return -1;
1412 }
1413
1414 handler(user);
1415
1416 return 0;
1417}

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 1221 of file app_confbridge.c.

1222{
1223 struct confbridge_user *user = NULL;
1224
1225 /* if this isn't a video source, nothing to update */
1227 return;
1228 }
1229
1231
1232 /* If in follow talker mode, make sure to restore this mode on the
1233 * bridge when a source is removed. It is possible this channel was
1234 * only set temporarily as a video source by an AMI or DTMF action. */
1237 }
1238
1239 /* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
1242 return;
1243 }
1244
1245 /* Make the next available marked user the video src. */
1248 if (user->chan == chan) {
1249 continue;
1250 }
1251 if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
1253 break;
1254 }
1255 }
1257}
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:3975
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:4126
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:4100
@ 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 1189 of file app_confbridge.c.

1190{
1191 /* Right now, only marked users are automatically set as the single src of video.*/
1192 if (!marked) {
1193 return;
1194 }
1195
1197 int set = 1;
1198 struct confbridge_user *user = NULL;
1199
1201 /* see if anyone is already the video src */
1203 if (user->chan == chan) {
1204 continue;
1205 }
1207 set = 0;
1208 break;
1209 }
1210 }
1212 if (set) {
1214 }
1216 /* we joined and are video capable, we override anyone else that may have already been the video feed */
1218 }
1219}
static int set(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_logic.c:266

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 1306 of file app_confbridge.c.

1307{
1308 ast_mutex_destroy(&hangup->lock);
1309 ast_cond_destroy(&hangup->cond);
1310}

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 1297 of file app_confbridge.c.

1298{
1299 ast_mutex_init(&hangup->lock);
1300 ast_cond_init(&hangup->cond, NULL);
1301
1302 hangup->conference = conference;
1303 hangup->hungup = 0;
1304}

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 1280 of file app_confbridge.c.

1281{
1282 struct hangup_data *hangup = data;
1283
1284 ast_autoservice_stop(hangup->conference->playback_chan);
1285
1286 ast_hangup(hangup->conference->playback_chan);
1287 hangup->conference->playback_chan = NULL;
1288
1289 ast_mutex_lock(&hangup->lock);
1290 hangup->hungup = 1;
1291 ast_cond_signal(&hangup->cond);
1292 ast_mutex_unlock(&hangup->lock);
1293
1294 return 0;
1295}

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 906 of file app_confbridge.c.

907{
908 if (!ast_strlen_zero(rec_file)) {
909 if (!*orig_rec_file) {
911 }
912
913 if (*orig_rec_file
914 && strcmp(ast_str_buffer(*orig_rec_file), rec_file)) {
915 ast_str_set(orig_rec_file, 0, "%s", rec_file);
916 return 1;
917 }
918 }
919 return 0;
920}
#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 2687 of file app_confbridge.c.

2688{
2689 async_play_sound_ready(bridge_channel->chan);
2690 return 0;
2691}

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 1819 of file app_confbridge.c.

1820{
1821 struct confbridge_conference *conference;
1822 struct post_join_action *action;
1823 int max_members_reached = 0;
1824
1825 /* We explicitly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same time */
1827
1828 ast_debug(1, "Trying to find conference bridge '%s'\n", conference_name);
1829
1830 /* Attempt to find an existing conference bridge */
1831 conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
1832 if (conference && conference->b_profile.max_members) {
1833 max_members_reached = conference->b_profile.max_members > conference->activeusers ? 0 : 1;
1834 }
1835
1836 /* When finding a conference bridge that already exists make sure that it is not locked, and if so that we are not an admin */
1837 if (conference && (max_members_reached || conference->locked) && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
1839 ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", conference_name);
1842 "");
1843 ao2_ref(conference, -1);
1844 return NULL;
1845 }
1846
1847 /* If no conference bridge was found see if we can create one */
1848 if (!conference) {
1849 /* Try to allocate memory for a new conference bridge, if we fail... this won't end well. */
1850 if (!(conference = ao2_alloc(sizeof(*conference), destroy_conference_bridge))) {
1852 ast_log(LOG_ERROR, "Conference '%s' could not be created.\n", conference_name);
1853 return NULL;
1854 }
1855
1856 /* Setup for the record channel */
1858 if (!conference->record_filename) {
1859 ao2_ref(conference, -1);
1861 return NULL;
1862 }
1863
1864 /* Setup conference bridge parameters */
1865 ast_copy_string(conference->name, conference_name, sizeof(conference->name));
1866 conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
1867
1868 /* Create an actual bridge that will do the audio mixing */
1871 app, conference_name, NULL);
1872 if (!conference->bridge) {
1873 ao2_ref(conference, -1);
1875 ast_log(LOG_ERROR, "Conference '%s' mixing bridge could not be created.\n", conference_name);
1876 return NULL;
1877 }
1878
1879 /* Set the internal sample rate on the bridge from the bridge profile */
1881 /* Set the maximum sample rate on the bridge from the bridge profile */
1883 /* Set the internal mixing interval on the bridge from the bridge profile */
1886
1889 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
1894 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST)) {
1896 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
1904 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_FORCE)) {
1907 }
1908 }
1909
1910 /* Always set the minimum interval between video updates, to avoid infinite video updates. */
1912
1914 ast_bridge_set_send_sdp_label(conference->bridge, 1);
1915 }
1916
1917 /* Link it into the conference bridges container */
1918 if (!ao2_link(conference_bridges, conference)) {
1919 ao2_ref(conference, -1);
1922 "Conference '%s' could not be added to the conferences list.\n", conference_name);
1923 return NULL;
1924 }
1925
1926 /* Set the initial state to EMPTY */
1927 conference->state = CONF_STATE_EMPTY;
1928
1929 /* The announcer channel lives for as long as the conference does, so whether it
1930 * gets created is decided once here, using the profile of the channel that
1931 * creates the conference. Leaving playback_chan and playback_queue NULL is what
1932 * tells the rest of this module that announcements are not available. */
1934 if (alloc_playback_chan(conference)) {
1935 ao2_unlink(conference_bridges, conference);
1936 ao2_ref(conference, -1);
1938 ast_log(LOG_ERROR, "Could not allocate announcer channel for conference '%s'\n", conference_name);
1939 return NULL;
1940 }
1941
1942 if (push_announcer(conference)) {
1943 ao2_unlink(conference_bridges, conference);
1944 ao2_ref(conference, -1);
1946 ast_log(LOG_ERROR, "Could not add announcer channel for conference '%s' bridge\n", conference_name);
1947 return NULL;
1948 }
1949 } else {
1950 ast_debug(1, "Announcements are disabled for conference '%s', not creating an announcer channel\n",
1951 conference_name);
1952 }
1953
1955 ao2_lock(conference);
1956 conf_start_record(conference);
1957 ao2_unlock(conference);
1958 }
1959
1960 send_conf_start_event(conference);
1961
1962 if (!ast_strlen_zero(conference->b_profile.regcontext)) {
1963 if (!ast_exists_extension(NULL, conference->b_profile.regcontext, conference->name, 1, NULL)) {
1964 ast_add_extension(conference->b_profile.regcontext, 1, conference->name, 1, NULL, NULL, "Noop", NULL, NULL, "ConfBridge");
1965 }
1966 }
1967
1968 ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
1969 }
1970
1972
1973 /* Setup conference bridge user parameters */
1974 user->conference = conference;
1975
1976 ao2_lock(conference);
1977
1978 /* Determine if the new user should join the conference muted. */
1979 if (ast_test_flag(&user->u_profile, USER_OPT_STARTMUTED)
1980 || (!ast_test_flag(&user->u_profile, USER_OPT_ADMIN) && conference->muted)) {
1981 /* Set user level mute request. */
1982 user->muted = 1;
1983 }
1984
1985 /*
1986 * Suspend any MOH until the user actually joins the bridge of
1987 * the conference. This way any pre-join file playback does not
1988 * need to worry about MOH.
1989 */
1990 user->suspended_moh = 1;
1991
1993 /* Invalid event, nothing was done, so we don't want to process a leave. */
1994 ao2_unlock(conference);
1995 ao2_ref(conference, -1);
1996 user->conference = NULL;
1997 return NULL;
1998 }
1999
2000 if (ast_check_hangup(user->chan)) {
2001 ao2_unlock(conference);
2003 return NULL;
2004 }
2005
2006 ao2_unlock(conference);
2007
2008 /* If an announcement is to be played play it */
2009 if (!ast_strlen_zero(user->u_profile.announcement)) {
2011 user->u_profile.announcement)) {
2013 return NULL;
2014 }
2015 }
2016
2017 /* Announce number of users if need be */
2018 if (ast_test_flag(&user->u_profile, USER_OPT_ANNOUNCEUSERCOUNT)) {
2019 if (announce_user_count(conference, user, NULL)) {
2021 return NULL;
2022 }
2023 }
2024
2026 (conference->activeusers > user->u_profile.announce_user_count_all_after)) {
2027 int user_count_res;
2028
2029 /*
2030 * We have to autoservice the new user because he has not quite
2031 * joined the conference yet.
2032 */
2034 user_count_res = announce_user_count(conference, NULL, NULL);
2036 if (user_count_res) {
2038 return NULL;
2039 }
2040 }
2041
2042 /* Handle post-join actions */
2043 while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
2044 action->func(user);
2045 ast_free(action);
2046 }
2047
2048 return conference;
2049}
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:4016
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:1019
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:3914
@ AST_BRIDGE_VIDEO_SFU_REMB_LOWEST
Definition bridge.h:139
@ AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL
Definition bridge.h:147
@ AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE
Definition bridge.h:137
@ AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST
Definition bridge.h:141
@ AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL
Definition bridge.h:143
@ AST_BRIDGE_VIDEO_SFU_REMB_FORCE
Definition bridge.h:149
@ AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL
Definition bridge.h:145
void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge)
Set the bridge to be a selective forwarding unit.
Definition bridge.c:3983
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:3928
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:3991
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:4007
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition bridge.h:98
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:3907
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:4175
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:3998
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:3921
@ 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.
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:5206
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:2735
unsigned int remb_send_interval
Definition confbridge.h:242
unsigned int maximum_sample_rate
Definition confbridge.h:237
unsigned int remb_estimated_bitrate
Definition confbridge.h:243
unsigned int mix_interval
Definition confbridge.h:238
unsigned int video_update_discard
Definition confbridge.h:241
unsigned int internal_sample_rate
Definition confbridge.h:236
unsigned int max_members
Definition confbridge.h:235
struct confbridge_state * state
Definition confbridge.h:249

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_ANNOUNCEMENTS, 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 3411 of file app_confbridge.c.

3413{
3414 int res = -1;
3415 int match;
3416 struct confbridge_user *user = NULL;
3417 int all = !strcasecmp("all", channel);
3418 int participants = !strcasecmp("participants", channel);
3419
3420 SCOPED_AO2LOCK(bridge_lock, conference);
3421
3423 if (user->kicked) {
3424 continue;
3425 }
3426 match = !strcasecmp(channel, ast_channel_name(user->chan));
3427 if (match || all
3428 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3429 user->kicked = 1;
3430 pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3432 res = 0;
3433 if (match) {
3434 return res;
3435 }
3436 }
3437 }
3439 if (user->kicked) {
3440 continue;
3441 }
3442 match = !strcasecmp(channel, ast_channel_name(user->chan));
3443 if (match || all
3444 || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3445 user->kicked = 1;
3446 pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3448 res = 0;
3449 if (match) {
3450 return res;
3451 }
3452 }
3453 }
3454
3455 return res;
3456}

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 2056 of file app_confbridge.c.

2057{
2058 struct post_join_action *action;
2059
2060 ao2_lock(user->conference);
2062 ao2_unlock(user->conference);
2063
2064 /* Discard any post-join actions */
2065 while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
2066 ast_free(action);
2067 }
2068
2069 /* Done mucking with the conference, huzzah */
2070 ao2_ref(user->conference, -1);
2071 user->conference = NULL;
2072}
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 4702 of file app_confbridge.c.

4703{
4704 int res = 0;
4705
4706 if (conf_load_config()) {
4707 ast_log(LOG_ERROR, "Unable to load config. Not loading module.\n");
4709 }
4710
4713 unload_module();
4715 }
4716
4717 /* Create a container to hold the conference bridges */
4721 if (!conference_bridges) {
4722 unload_module();
4724 }
4725
4726 /* Setup manager stasis subscriptions */
4727 res |= manager_confbridge_init();
4728
4731
4735
4737
4747 res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
4748 if (res) {
4749 unload_module();
4751 }
4752
4754}
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:193
#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:1572
#define ast_custom_function_register(acf)
Register a custom function.
Definition pbx.h:1563
@ AST_CFE_WRITE
Definition pbx.h:1556
#define ARRAY_LEN(a)
Definition utils.h:706

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 1065 of file app_confbridge.c.

1067{
1068 struct ast_channel *chan;
1069 const char *stop_digits;
1070 int digit;
1071
1072 if (bridge_channel) {
1073 chan = bridge_channel->chan;
1074 stop_digits = AST_DIGIT_ANY;
1075 } else {
1076 chan = channel;
1077 stop_digits = AST_DIGIT_NONE;
1078 }
1079
1080 digit = ast_stream_and_wait(chan, filename, stop_digits);
1081 if (digit < 0) {
1082 ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
1083 return -1;
1084 }
1085
1086 if (digit > 0) {
1089 return 1;
1090 }
1091
1092 return 0;
1093}
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 1184 of file app_confbridge.c.

1185{
1186 return ast_stream_and_wait(user->chan, filename, "");
1187}

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 2191 of file app_confbridge.c.

2192{
2193 return play_sound_helper(conference, filename, -1);
2194}
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 2148 of file app_confbridge.c.

2149{
2150 struct playback_task_data ptd;
2151
2152 /* Announcements are disabled for this conference, there is nothing to play them on */
2153 if (!conference->playback_queue) {
2154 return 0;
2155 }
2156
2157 /* Do not waste resources trying to play files that do not exist */
2159 if (say_number < 0) {
2160 return 0;
2161 }
2162 } else if (!sound_file_exists(filename)) {
2163 return 0;
2164 }
2165
2168 if (!ast_strlen_zero(filename)) {
2169 ast_log(LOG_WARNING, "Unable to play file '%s' to conference %s\n",
2171 } else {
2172 ast_log(LOG_WARNING, "Unable to say number '%d' to conference %s\n",
2174 }
2176 return -1;
2177 }
2178
2179 /* Wait for the playback to complete */
2180 ast_mutex_lock(&ptd.lock);
2181 while (!ptd.playback_finished) {
2182 ast_cond_wait(&ptd.cond, &ptd.lock);
2183 }
2184 ast_mutex_unlock(&ptd.lock);
2185
2187
2188 return 0;
2189}
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

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 2478 of file app_confbridge.c.

2479{
2480 return play_sound_helper(conference, NULL, say_number);
2481}

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 2074 of file app_confbridge.c.

2075{
2076 /* Don't try to play if the playback channel has been hung up */
2077 if (!conference->playback_chan) {
2078 return;
2079 }
2080
2082
2083 /* The channel is all under our control, in goes the prompt */
2084 if (!ast_strlen_zero(filename)) {
2085 ast_stream_and_wait(conference->playback_chan, filename, "");
2086 } else if (say_number >= 0) {
2087 ast_say_number(conference->playback_chan, say_number, "",
2089 }
2090
2092}

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 2116 of file app_confbridge.c.

2117{
2118 struct playback_task_data *ptd = data;
2119
2121
2122 ast_mutex_lock(&ptd->lock);
2123 ptd->playback_finished = 1;
2124 ast_cond_signal(&ptd->cond);
2125 ast_mutex_unlock(&ptd->lock);
2126
2127 return 0;
2128}

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 2142 of file app_confbridge.c.

2143{
2144 ast_mutex_destroy(&ptd->lock);
2145 ast_cond_destroy(&ptd->cond);
2146}

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 2130 of file app_confbridge.c.

2132{
2133 ast_mutex_init(&ptd->lock);
2134 ast_cond_init(&ptd->cond, NULL);
2135
2136 ptd->filename = filename;
2137 ptd->say_number = say_number;
2138 ptd->conference = conference;
2139 ptd->playback_finished = 0;
2140}

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 1679 of file app_confbridge.c.

1680{
1681 if (conf_announce_channel_push(conference->playback_chan)) {
1682 ast_hangup(conference->playback_chan);
1683 conference->playback_chan = NULL;
1684 return -1;
1685 }
1686
1688 return 0;
1689}
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 4639 of file app_confbridge.c.

4640{
4642 if (!tech->capabilities) {
4643 return -1;
4644 }
4646 if (ast_channel_register(tech)) {
4647 ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
4648 tech->type, tech->description);
4649 return -1;
4650 }
4651 return 0;
4652}
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:540
@ 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 4756 of file app_confbridge.c.

4757{
4758 return conf_reload_config();
4759}
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 799 of file app_confbridge.c.

800{
801 send_conf_stasis(conference, NULL, confbridge_end_type(), NULL, 0);
802}
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 794 of file app_confbridge.c.

795{
797}
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 720 of file app_confbridge.c.

722{
723 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
724 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
725
726 json_object = ast_json_pack("{s: s}",
727 "conference", conference->name);
728 if (!json_object) {
729 return;
730 }
731
732 if (extras) {
733 ast_json_object_update(json_object, extras);
734 }
735
736 ast_bridge_lock(conference->bridge);
738 conference->bridge,
739 chan,
740 json_object);
741 ast_bridge_unlock(conference->bridge);
742 if (!msg) {
743 return;
744 }
745
747 conf_send_event_to_participants(conference, chan, msg);
748 }
749
750 if (channel_topic) {
752 } else {
753 stasis_publish(ast_bridge_topic(conference->bridge), msg);
754 }
755}
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:1589
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 757 of file app_confbridge.c.

760{
761 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
762 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
763 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
764
765 json_object = ast_json_pack("{s: s}",
766 "conference", conference->name);
767 if (!json_object) {
768 return;
769 }
770
771 if (extras) {
772 ast_json_object_update(json_object, extras);
773 }
774
775 ast_bridge_lock(conference->bridge);
776 bridge_snapshot = ast_bridge_snapshot_create(conference->bridge);
777 ast_bridge_unlock(conference->bridge);
778 if (!bridge_snapshot) {
779 return;
780 }
781
783 bridge_snapshot,
784 chan_snapshot,
785 json_object);
786 if (!msg) {
787 return;
788 }
789
790 stasis_publish(ast_bridge_topic(conference->bridge), msg);
791}
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:318

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 2699 of file app_confbridge.c.

2700{
2701 struct confbridge_hook_data *hook_data = data;
2702
2703 if (hook_data->hook_type == AST_BRIDGE_HOOK_TYPE_JOIN) {
2704 send_join_event(hook_data->user, hook_data->conference);
2705 } else {
2706 send_leave_event(hook_data->user, hook_data->conference);
2707 }
2708
2709 return 0;
2710}
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 804 of file app_confbridge.c.

805{
806 struct ast_json *json_object;
807
808 json_object = ast_json_pack("{s: b, s: b}",
809 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
810 "muted", user->muted);
811 if (!json_object) {
812 return;
813 }
814 send_conf_stasis(conference, user->chan, confbridge_join_type(), json_object, 0);
815 ast_json_unref(json_object);
816}

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 818 of file app_confbridge.c.

819{
820 struct ast_json *json_object;
821
822 json_object = ast_json_pack("{s: b}",
823 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
824 );
825 if (!json_object) {
826 return;
827 }
828 send_conf_stasis(conference, user->chan, confbridge_leave_type(), json_object, 0);
829 ast_json_unref(json_object);
830}

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 842 of file app_confbridge.c.

843{
844 struct ast_json *json_object;
845
846 json_object = ast_json_pack("{s: b}",
847 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
848 );
849 if (!json_object) {
850 return;
851 }
852 send_conf_stasis(conference, user->chan, confbridge_mute_type(), json_object, 1);
853 ast_json_unref(json_object);
854}
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 832 of file app_confbridge.c.

833{
835}
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 837 of file app_confbridge.c.

838{
840}
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 856 of file app_confbridge.c.

857{
858 struct ast_json *json_object;
859
860 json_object = ast_json_pack("{s: b}",
861 "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
862 );
863 if (!json_object) {
864 return;
865 }
866 send_conf_stasis(conference, user->chan, confbridge_unmute_type(), json_object, 1);
867 ast_json_unref(json_object);
868}
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 870 of file app_confbridge.c.

871{
872 char *rec_file = conference->b_profile.rec_file;
873 char *ext;
874 time_t now;
875
876 if (ast_str_strlen(*filename)
878 && !is_new) {
879 return;
880 }
881
882 time(&now);
883
884 ast_str_reset(*filename);
885 if (ast_strlen_zero(rec_file)) {
886 ast_str_set(filename, 0, "confbridge-%s-%u.wav", conference->name,
887 (unsigned int) now);
888 } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_TIMESTAMP)) {
889 /* insert time before file extension */
890 ext = strrchr(rec_file, '.');
891 if (ext) {
892 ast_str_set_substr(filename, 0, rec_file, ext - rec_file);
893 ast_str_append(filename, 0, "-%u%s", (unsigned int) now, ext);
894 } else {
895 ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int) now);
896 }
897 } else {
898 ast_str_set(filename, 0, "%s", rec_file);
899 }
900 ast_str_append(filename, 0, ",%s%s,%s",
901 ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND) ? "a" : "",
902 conference->b_profile.rec_options,
903 conference->b_profile.rec_command);
904}
@ BRIDGE_OPT_RECORD_FILE_TIMESTAMP
Definition confbridge.h:83
@ BRIDGE_OPT_RECORD_FILE_APPEND
Definition confbridge.h:82
const char * ext
Definition http.c:151
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
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition strings.h:730
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
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

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 2268 of file app_confbridge.c.

2269{
2270 struct ast_datastore *async_datastore;
2271
2272 async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2273 if (async_datastore) {
2274 struct async_datastore_data *add;
2275
2276 add = async_datastore->data;
2277 add->wait = 1;
2278
2279 return 0;
2280 }
2281
2282 async_datastore = ast_datastore_alloc(&async_datastore_info, NULL);
2283 if (!async_datastore) {
2284 return -1;
2285 }
2286
2287 async_datastore->data = async_datastore_data_alloc();
2288 if (!async_datastore->data) {
2289 ast_datastore_free(async_datastore);
2290 return -1;
2291 }
2292
2293 ast_channel_datastore_add(initiator, async_datastore);
2294 return 0;
2295}
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:2376
#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 1103 of file app_confbridge.c.

1104{
1105 if (ast_fileexists(filename, NULL, NULL)) {
1106 return -1;
1107 }
1108 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
1109 return 0;
1110}
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition file.c:1156

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 4655 of file app_confbridge.c.

4656{
4659
4663
4665
4666 ast_manager_unregister("ConfbridgeList");
4667 ast_manager_unregister("ConfbridgeListRooms");
4668 ast_manager_unregister("ConfbridgeMute");
4669 ast_manager_unregister("ConfbridgeUnmute");
4670 ast_manager_unregister("ConfbridgeKick");
4671 ast_manager_unregister("ConfbridgeUnlock");
4672 ast_manager_unregister("ConfbridgeLock");
4673 ast_manager_unregister("ConfbridgeStartRecord");
4674 ast_manager_unregister("ConfbridgeStopRecord");
4675 ast_manager_unregister("ConfbridgeSetSingleVideoSrc");
4676
4677 /* Unsubscribe from stasis confbridge message type and clean it up. */
4679
4680 /* Get rid of the conference bridges container. Since we only allow dynamic ones none will be active. */
4683
4685
4688
4689 return 0;
4690}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
static void unregister_channel_tech(struct ast_channel_tech *tech)
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:7782
int ast_unregister_application(const char *app)
Unregister an application.
Definition pbx_app.c:404
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 4623 of file app_confbridge.c.

4624{
4627}
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition channel.c:571

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 2553 of file app_confbridge.c.

2554{
2556 pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "TIMEOUT");
2557 return -1;
2558}
@ 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 2357 of file app_confbridge.c.

2358{
2359 struct ast_datastore *async_datastore;
2360 struct async_datastore_data *add;
2361
2362 ast_channel_lock(initiator);
2363 async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2364 ast_channel_unlock(initiator);
2365
2366 if (!async_datastore) {
2367 return;
2368 }
2369
2370 add = async_datastore->data;
2371
2372 ast_mutex_lock(&add->lock);
2373 while (add->wait) {
2374 ast_cond_wait(&add->cond, &add->lock);
2375 }
2376 ast_mutex_unlock(&add->lock);
2377}

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 = ASTERISK_GPL_KEY , .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 4768 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 594 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 595 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 4768 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 2236 of file app_confbridge.c.

2236 {
2237 .type = "Confbridge async playback",
2239};

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 3978 of file app_confbridge.c.

3978 {
3979 AST_CLI_DEFINE(handle_cli_confbridge_list, "List conference bridges and participants."),
3980 AST_CLI_DEFINE(handle_cli_confbridge_kick, "Kick participants out of conference bridges."),
3981 AST_CLI_DEFINE(handle_cli_confbridge_mute, "Mute participants."),
3982 AST_CLI_DEFINE(handle_cli_confbridge_unmute, "Unmute participants."),
3983 AST_CLI_DEFINE(handle_cli_confbridge_lock, "Lock a conference."),
3984 AST_CLI_DEFINE(handle_cli_confbridge_unlock, "Unlock a conference."),
3985 AST_CLI_DEFINE(handle_cli_confbridge_start_record, "Start recording a conference"),
3986 AST_CLI_DEFINE(handle_cli_confbridge_stop_record, "Stop recording a conference."),
3987};
static char * handle_cli_confbridge_kick(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_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 char * handle_cli_confbridge_lock(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 char * handle_cli_confbridge_stop_record(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

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 4078 of file app_confbridge.c.

4078 {
4079 .name = "CONFBRIDGE_CHANNELS",
4081};

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 3988 of file app_confbridge.c.

3988 {
3989 .name = "CONFBRIDGE",
3990 .write = func_confbridge_helper,
3991};

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 3994 of file app_confbridge.c.

3994 {
3995 .name = "CONFBRIDGE_INFO",
3996 .read = func_confbridge_info,
3997};

Referenced by load_module(), and unload_module().

◆ conference_bridges

struct ao2_container* conference_bridges