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

Conference Bridge application. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define CONFERENCE_BRIDGE_BUCKETS   53
 
#define RECORD_FILENAME_INITIAL_SPACE   128
 

Functions

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

Variables

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

Detailed Description

Conference Bridge application.

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

This is a conference bridge application utilizing the bridging core.

Definition in file app_confbridge.c.

Macro Definition Documentation

◆ CONFERENCE_BRIDGE_BUCKETS

#define CONFERENCE_BRIDGE_BUCKETS   53

Number of buckets our conference bridges container can have

Definition at line 468 of file app_confbridge.c.

◆ RECORD_FILENAME_INITIAL_SPACE

#define RECORD_FILENAME_INITIAL_SPACE   128

Initial recording filename space.

Definition at line 471 of file app_confbridge.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4513 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4513 of file app_confbridge.c.

◆ action_confbridgekick()

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

Definition at line 4048 of file app_confbridge.c.

4049 {
4050  const char *conference_name = astman_get_header(m, "Conference");
4051  const char *channel = astman_get_header(m, "Channel");
4052  struct confbridge_conference *conference;
4053  int found;
4054 
4055  if (ast_strlen_zero(conference_name)) {
4056  astman_send_error(s, m, "No Conference name provided.");
4057  return 0;
4058  }
4060  astman_send_error(s, m, "No active conferences.");
4061  return 0;
4062  }
4063 
4064  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4065  if (!conference) {
4066  astman_send_error(s, m, "No Conference by that name found.");
4067  return 0;
4068  }
4069 
4070  found = !kick_conference_participant(conference, channel);
4071  ao2_ref(conference, -1);
4072 
4073  if (found) {
4074  astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4075  } else {
4076  astman_send_error(s, m, "No Channel by that name found in Conference.");
4077  }
4078  return 0;
4079 }
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:3166
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3198
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:2827
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:245

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

3881 {
3882  const char *actionid = astman_get_header(m, "ActionID");
3883  const char *conference_name = astman_get_header(m, "Conference");
3884  struct confbridge_user *user;
3885  struct confbridge_conference *conference;
3886  char id_text[80];
3887  int total = 0;
3888 
3889  id_text[0] = '\0';
3890  if (!ast_strlen_zero(actionid)) {
3891  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3892  }
3893  if (ast_strlen_zero(conference_name)) {
3894  astman_send_error(s, m, "No Conference name provided.");
3895  return 0;
3896  }
3898  astman_send_error(s, m, "No active conferences.");
3899  return 0;
3900  }
3901  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3902  if (!conference) {
3903  astman_send_error(s, m, "No Conference by that name found.");
3904  return 0;
3905  }
3906 
3907  astman_send_listack(s, m, "Confbridge user list will follow", "start");
3908 
3909  ao2_lock(conference);
3910  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3911  total += action_confbridgelist_item(s, id_text, conference, user, 0);
3912  }
3913  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3914  total += action_confbridgelist_item(s, id_text, conference, user, 1);
3915  }
3916  ao2_unlock(conference);
3917  ao2_ref(conference, -1);
3918 
3919  astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
3921 
3922  return 0;
3923 }
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:3208
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:3244
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3252
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
static int total
Definition: res_adsi.c:968
static char user[512]
struct confbridge_conference::@86 waiting_list
struct confbridge_conference::@85 active_list
The structure that represents a conference bridge user.
Definition: confbridge.h:272
structure to hold users read from users.conf

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

Referenced by load_module().

◆ action_confbridgelist_item()

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

Definition at line 3832 of file app_confbridge.c.

3833 {
3834  struct ast_channel_snapshot *snapshot;
3835  struct ast_str *snap_str;
3836 
3838  if (!snapshot) {
3839  return 0;
3840  }
3841 
3842  snap_str = ast_manager_build_channel_state_string(snapshot);
3843  if (!snap_str) {
3844  ao2_ref(snapshot, -1);
3845  return 0;
3846  }
3847 
3848  astman_append(s,
3849  "Event: ConfbridgeList\r\n"
3850  "%s"
3851  "Conference: %s\r\n"
3852  "Admin: %s\r\n"
3853  "MarkedUser: %s\r\n"
3854  "WaitMarked: %s\r\n"
3855  "EndMarked: %s\r\n"
3856  "Waiting: %s\r\n"
3857  "Muted: %s\r\n"
3858  "Talking: %s\r\n"
3859  "AnsweredTime: %d\r\n"
3860  "%s"
3861  "\r\n",
3862  id_text,
3863  conference->name,
3864  AST_YESNO(ast_test_flag(&user->u_profile, USER_OPT_ADMIN)),
3868  AST_YESNO(waiting),
3869  AST_YESNO(user->muted),
3870  AST_YESNO(user->talking),
3872  ast_str_buffer(snap_str));
3873 
3874  ast_free(snap_str);
3875  ao2_ref(snapshot, -1);
3876 
3877  return 1;
3878 }
#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:2846
@ USER_OPT_ENDMARKED
Definition: confbridge.h:60
@ USER_OPT_WAITMARKED
Definition: confbridge.h:59
@ USER_OPT_MARKEDUSER
Definition: confbridge.h:54
@ USER_OPT_ADMIN
Definition: confbridge.h:52
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3087
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:143
Structure representing a snapshot of channel state.
Support for dynamic strings.
Definition: strings.h:604
char name[MAX_CONF_NAME]
Definition: confbridge.h:246
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ao2_ref, ast_channel_get_up_time(), ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_free, ast_manager_build_channel_state_string(), ast_str_buffer(), ast_test_flag, AST_YESNO, astman_append(), confbridge_conference::name, USER_OPT_ADMIN, USER_OPT_ENDMARKED, USER_OPT_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 3925 of file app_confbridge.c.

3926 {
3927  const char *actionid = astman_get_header(m, "ActionID");
3928  struct confbridge_conference *conference;
3929  struct ao2_iterator iter;
3930  char id_text[512] = "";
3931  int totalitems = 0;
3932 
3933  if (!ast_strlen_zero(actionid)) {
3934  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3935  }
3936 
3938  astman_send_error(s, m, "No active conferences.");
3939  return 0;
3940  }
3941 
3942  astman_send_listack(s, m, "Confbridge conferences will follow", "start");
3943 
3944  /* Traverse the conference list */
3946  while ((conference = ao2_iterator_next(&iter))) {
3947  totalitems++;
3948 
3949  ao2_lock(conference);
3950  astman_append(s,
3951  "Event: ConfbridgeListRooms\r\n"
3952  "%s"
3953  "Conference: %s\r\n"
3954  "Parties: %u\r\n"
3955  "Marked: %u\r\n"
3956  "Locked: %s\r\n"
3957  "Muted: %s\r\n"
3958  "\r\n",
3959  id_text,
3960  conference->name,
3961  conference->activeusers + conference->waitingusers,
3962  conference->markedusers,
3963  AST_YESNO(conference->locked),
3964  AST_YESNO(conference->muted));
3965  ao2_unlock(conference);
3966 
3967  ao2_ref(conference, -1);
3968  }
3969  ao2_iterator_destroy(&iter);
3970 
3971  /* Send final confirmation */
3972  astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
3974  return 0;
3975 }
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
unsigned int muted
Definition: confbridge.h:254
unsigned int activeusers
Definition: confbridge.h:250
unsigned int waitingusers
Definition: confbridge.h:252
unsigned int markedusers
Definition: confbridge.h:251
unsigned int locked
Definition: confbridge.h:253

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

4044 {
4045  return action_lock_unlock_helper(s, m, 1);
4046 }
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 4014 of file app_confbridge.c.

4015 {
4016  return action_mute_unmute_helper(s, m, 1);
4017 }
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 4160 of file app_confbridge.c.

4161 {
4162  const char *conference_name = astman_get_header(m, "Conference");
4163  const char *channel = astman_get_header(m, "Channel");
4164  struct confbridge_user *user;
4165  struct confbridge_conference *conference;
4166 
4167  if (ast_strlen_zero(conference_name)) {
4168  astman_send_error(s, m, "No Conference name provided.");
4169  return 0;
4170  }
4171  if (ast_strlen_zero(channel)) {
4172  astman_send_error(s, m, "No channel name provided.");
4173  return 0;
4174  }
4176  astman_send_error(s, m, "No active conferences.");
4177  return 0;
4178  }
4179 
4180  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4181  if (!conference) {
4182  astman_send_error(s, m, "No Conference by that name found.");
4183  return 0;
4184  }
4185 
4186  /* find channel and set as video src. */
4187  ao2_lock(conference);
4188  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4189  if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4190  ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
4191  break;
4192  }
4193  }
4194  ao2_unlock(conference);
4195  ao2_ref(conference, -1);
4196 
4197  /* do not access user after conference unlock. We are just
4198  * using this check to see if it was found or not */
4199  if (!user) {
4200  astman_send_error(s, m, "No channel by that name found in conference.");
4201  return 0;
4202  }
4203  astman_send_ack(s, m, "Conference single video source set.");
4204  return 0;
4205 }
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
Set a bridge to feed a single video source to all participants.
Definition: bridge.c:3749
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_bridge * bridge
Definition: confbridge.h:248

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

Referenced by load_module().

◆ action_confbridgestartrecord()

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

Definition at line 4081 of file app_confbridge.c.

4082 {
4083  const char *conference_name = astman_get_header(m, "Conference");
4084  const char *recordfile = astman_get_header(m, "RecordFile");
4085  struct confbridge_conference *conference;
4086 
4087  if (ast_strlen_zero(conference_name)) {
4088  astman_send_error(s, m, "No Conference name provided.");
4089  return 0;
4090  }
4092  astman_send_error(s, m, "No active conferences.");
4093  return 0;
4094  }
4095 
4096  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4097  if (!conference) {
4098  astman_send_error(s, m, "No Conference by that name found.");
4099  return 0;
4100  }
4101 
4102  ao2_lock(conference);
4103  if (conf_is_recording(conference)) {
4104  astman_send_error(s, m, "Conference is already being recorded.");
4105  ao2_unlock(conference);
4106  ao2_ref(conference, -1);
4107  return 0;
4108  }
4109 
4110  if (!ast_strlen_zero(recordfile)) {
4111  ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4112  }
4113 
4114  if (conf_start_record(conference)) {
4115  astman_send_error(s, m, "Internal error starting conference recording.");
4116  ao2_unlock(conference);
4117  ao2_ref(conference, -1);
4118  return 0;
4119  }
4120  ao2_unlock(conference);
4121 
4122  ao2_ref(conference, -1);
4123  astman_send_ack(s, m, "Conference Recording Started.");
4124  return 0;
4125 }
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:406
char rec_file[PATH_MAX]
Definition: confbridge.h:229
struct bridge_profile b_profile
Definition: confbridge.h:249

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

4127 {
4128  const char *conference_name = astman_get_header(m, "Conference");
4129  struct confbridge_conference *conference;
4130 
4131  if (ast_strlen_zero(conference_name)) {
4132  astman_send_error(s, m, "No Conference name provided.");
4133  return 0;
4134  }
4136  astman_send_error(s, m, "No active conferences.");
4137  return 0;
4138  }
4139 
4140  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4141  if (!conference) {
4142  astman_send_error(s, m, "No Conference by that name found.");
4143  return 0;
4144  }
4145 
4146  ao2_lock(conference);
4147  if (conf_stop_record(conference)) {
4148  ao2_unlock(conference);
4149  astman_send_error(s, m, "Internal error while stopping recording.");
4150  ao2_ref(conference, -1);
4151  return 0;
4152  }
4153  ao2_unlock(conference);
4154 
4155  ao2_ref(conference, -1);
4156  astman_send_ack(s, m, "Conference Recording Stopped.");
4157  return 0;
4158 }
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 4039 of file app_confbridge.c.

4040 {
4041  return action_lock_unlock_helper(s, m, 0);
4042 }

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

4011 {
4012  return action_mute_unmute_helper(s, m, 0);
4013 }

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

3071 {
3072  struct ast_pbx_args args;
3073  struct ast_pbx *pbx;
3074  char *exten;
3075  char *context;
3076  int priority;
3077  int res;
3078 
3079  memset(&args, 0, sizeof(args));
3080  args.no_hangup_chan = 1;
3081 
3082  ast_channel_lock(bridge_channel->chan);
3083 
3084  /*save off*/
3085  exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3086  context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3087  priority = ast_channel_priority(bridge_channel->chan);
3088  pbx = ast_channel_pbx(bridge_channel->chan);
3089  ast_channel_pbx_set(bridge_channel->chan, NULL);
3090 
3091  /*set new*/
3092  ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3093  ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3094  ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3095 
3096  ast_channel_unlock(bridge_channel->chan);
3097 
3098  /*execute*/
3099  res = ast_pbx_run_args(bridge_channel->chan, &args);
3100 
3101  /*restore*/
3102  ast_channel_lock(bridge_channel->chan);
3103 
3104  ast_channel_exten_set(bridge_channel->chan, exten);
3105  ast_channel_context_set(bridge_channel->chan, context);
3106  ast_channel_priority_set(bridge_channel->chan, priority);
3107  ast_channel_pbx_set(bridge_channel->chan, pbx);
3108 
3109  ast_channel_unlock(bridge_channel->chan);
3110 
3111  return res;
3112 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static int priority
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
const char * ast_channel_context(const struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
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:4742
#define NULL
Definition: resample.c:96
struct ast_channel * chan
Options for ast_pbx_run()
Definition: pbx.h:390
Definition: pbx.h:214
struct conf_menu_action::@79::@81 dialplan_args
union conf_menu_action::@79 data
const char * args

References args, ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_lock, ast_channel_pbx(), ast_channel_pbx_set(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_unlock, ast_pbx_run_args(), ast_strdupa, ast_bridge_channel::chan, context, conf_menu_action::data, conf_menu_action::dialplan_args, exten, NULL, 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 3033 of file app_confbridge.c.

3036 {
3037  struct confbridge_user *last_user = NULL;
3038  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3039 
3040  if (!isadmin) {
3041  play_file(bridge_channel, NULL,
3043  ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
3044  ast_channel_name(bridge_channel->chan),
3045  conference->name);
3046  return -1;
3047  }
3048 
3050  last_user = AST_LIST_LAST(&conference->active_list);
3051  if (!last_user) {
3053  return 0;
3054  }
3055 
3056  if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3058  play_file(bridge_channel, NULL,
3060  } else if (!last_user->kicked) {
3061  last_user->kicked = 1;
3062  pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3063  ast_bridge_remove(conference->bridge, last_user->chan);
3065  }
3066 
3067  return 0;
3068 }
const char * conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
Looks to see if sound file is stored in bridge profile sounds, if not default sound is provided.
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
Playback the given filename and monitor for any dtmf interrupts.
#define ast_log
Definition: astobj2.c:42
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1951
@ CONF_SOUND_ERROR_MENU
Definition: confbridge.h:186
#define LOG_WARNING
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
struct bridge_profile_sounds * sounds
Definition: confbridge.h:237
unsigned int kicked
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:273
struct ast_channel * chan
Definition: confbridge.h:278
struct user_profile u_profile
Definition: confbridge.h:275

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

4020 {
4021  const char *conference_name = astman_get_header(m, "Conference");
4022  int res = 0;
4023 
4024  if (ast_strlen_zero(conference_name)) {
4025  astman_send_error(s, m, "No Conference name provided.");
4026  return 0;
4027  }
4029  astman_send_error(s, m, "No active conferences.");
4030  return 0;
4031  }
4032  if ((res = generic_lock_unlock_helper(lock, conference_name))) {
4033  astman_send_error(s, m, "No Conference by that name found.");
4034  return 0;
4035  }
4036  astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
4037  return 0;
4038 }
static int generic_lock_unlock_helper(int lock, const char *conference_name)
ast_mutex_t lock
Definition: app_meetme.c:1093

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

3978 {
3979  const char *conference_name = astman_get_header(m, "Conference");
3980  const char *channel_name = astman_get_header(m, "Channel");
3981  int res = 0;
3982 
3983  if (ast_strlen_zero(conference_name)) {
3984  astman_send_error(s, m, "No Conference name provided.");
3985  return 0;
3986  }
3987  if (ast_strlen_zero(channel_name)) {
3988  astman_send_error(s, m, "No channel name provided.");
3989  return 0;
3990  }
3992  astman_send_error(s, m, "No active conferences.");
3993  return 0;
3994  }
3995 
3996  res = generic_mute_unmute_helper(mute, conference_name, channel_name);
3997 
3998  if (res == -1) {
3999  astman_send_error(s, m, "No Conference by that name found.");
4000  return 0;
4001  } else if (res == -2) {
4002  astman_send_error(s, m, "No Channel by that name found in Conference.");
4003  return 0;
4004  }
4005 
4006  astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
4007  return 0;
4008 }
static int generic_mute_unmute_helper(int mute, const char *conference_name, const char *chan_name)
static int mute
Definition: chan_alsa.c:148

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

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

2949 {
2950  char *file_copy = ast_strdupa(playback_file);
2951  char *file = NULL;
2952 
2953  while ((file = strsep(&file_copy, "&"))) {
2954  if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
2955  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2956  return -1;
2957  }
2958  }
2959  return 0;
2960 }
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:1855
char * strsep(char **str, const char *delims)

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

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

2969 {
2970  int i;
2971  int digit = 0;
2972  char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
2973  struct conf_menu_entry new_menu_entry = { { 0, }, };
2974  char *file_copy = ast_strdupa(playback_file);
2975  char *file = NULL;
2976 
2977  while ((file = strsep(&file_copy, "&"))) {
2978  if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
2979  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2980  return -1;
2981  }
2982 
2983  /* now wait for more digits. */
2984  if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
2985  /* streaming finished and no DTMF was entered */
2986  continue;
2987  } else if (digit == -1) {
2988  /* error */
2989  return -1;
2990  } else {
2991  break; /* dtmf was entered */
2992  }
2993  }
2994  if (!digit) {
2995  /* streaming finished on all files and no DTMF was entered */
2996  return -1;
2997  }
2998  ast_stopstream(bridge_channel->chan);
2999 
3000  /* If we get here, then DTMF has been entered, This means no
3001  * additional prompts should be played for this menu entry */
3002  *stop_prompts = 1;
3003 
3004  /* If a digit was pressed during the payback, update
3005  * the dtmf string and look for a new menu entry in the
3006  * menu structure */
3007  ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
3008  for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
3009  dtmf[i] = cur_dtmf[i];
3010  if (!dtmf[i]) {
3011  dtmf[i] = (char) digit;
3012  dtmf[i + 1] = '\0';
3013  i = -1;
3014  break;
3015  }
3016  }
3017  /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
3018  * If this is the case, no new DTMF sequence should be looked for. */
3019  if (i != -1) {
3020  return 0;
3021  }
3022 
3023  if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
3024  execute_menu_entry(conference,
3025  user,
3026  bridge_channel,
3027  &new_menu_entry, menu);
3028  conf_menu_entry_destroy(&new_menu_entry);
3029  }
3030  return 0;
3031 }
char digit
static int execute_menu_entry(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel, struct conf_menu_entry *menu_entry, struct conf_menu *menu)
#define MAXIMUM_DTMF_FEATURE_STRING
Maximum length of a DTMF feature string.
const char * ast_channel_language(const struct ast_channel *chan)
int conf_find_menu_entry_by_sequence(const char *dtmf_sequence, struct conf_menu *menu, struct conf_menu_entry *result)
Finds a menu_entry in a menu structure matched by DTMF sequence.
void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry)
Destroys and frees all the actions stored in a menu_entry structure.
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1291
#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:1817
Definition: confbridge.h:137
char dtmf[MAXIMUM_DTMF_FEATURE_STRING]
Definition: confbridge.h:139

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

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

2895 {
2896  unsigned int binaural;
2897  ast_bridge_channel_lock_bridge(bridge_channel);
2898  binaural = !bridge_channel->binaural_suspended;
2899  bridge_channel->binaural_suspended = binaural;
2900  ast_bridge_unlock(bridge_channel->bridge);
2901  return play_file(bridge_channel, NULL, (binaural ?
2902  conf_get_sound(CONF_SOUND_BINAURAL_OFF, user->b_profile.sounds) :
2903  conf_get_sound(CONF_SOUND_BINAURAL_ON, user->b_profile.sounds))) < 0;
2904 }
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
@ CONF_SOUND_BINAURAL_ON
Definition: confbridge.h:192
@ CONF_SOUND_BINAURAL_OFF
Definition: confbridge.h:193
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 2877 of file app_confbridge.c.

2880 {
2881  int mute;
2882 
2883  /* Toggle user level mute request. */
2884  mute = !user->muted;
2885  generic_mute_unmute_user(conference, user, mute);
2886 
2887  return play_file(bridge_channel, NULL,
2889  conference->b_profile.sounds)) < 0;
2890 }
static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
@ CONF_SOUND_UNMUTED
Definition: confbridge.h:173
@ CONF_SOUND_MUTED
Definition: confbridge.h:172

References confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_MUTED, CONF_SOUND_UNMUTED, confbridge_hook_data::conference, generic_mute_unmute_user(), mute, 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 2906 of file app_confbridge.c.

2907 {
2908  struct confbridge_user *cur_user = NULL;
2909  const char *sound_to_play;
2910  int mute;
2911 
2913 
2914  /* Toggle bridge level mute request. */
2915  mute = !conference->muted;
2916  conference->muted = mute;
2917 
2919  if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
2920  /* Set user level to bridge level mute request. */
2921  cur_user->muted = mute;
2922  conf_update_user_mute(cur_user);
2923  }
2924  }
2925 
2927 
2928  sound_to_play = conf_get_sound(
2931 
2932  if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
2933  /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
2934  ast_stream_and_wait(user->chan, sound_to_play, "");
2935 
2936  /* Announce to the group that all participants are muted */
2937  ast_autoservice_start(user->chan);
2938  play_sound_file(conference, sound_to_play);
2939  ast_autoservice_stop(user->chan);
2940  } else {
2941  /* Playing the sound asynchronously lets the sound be heard by everyone at once */
2942  async_play_sound_file(conference, sound_to_play, user->chan);
2943  }
2944 
2945  return 0;
2946 }
int async_play_sound_file(struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
Play sound file into conference bridge asynchronously.
int play_sound_file(struct confbridge_conference *conference, const char *filename)
Play sound file into conference bridge.
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
@ CONF_SOUND_PARTICIPANTS_UNMUTED
Definition: confbridge.h:190
@ CONF_SOUND_PARTICIPANTS_MUTED
Definition: confbridge.h:189
char language[MAX_LANGUAGE]
Definition: confbridge.h:228
unsigned int muted
Definition: confbridge.h:282
struct confbridge_user::@89 list

References confbridge_conference::active_list, ao2_lock, ao2_unlock, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_language(), AST_LIST_TRAVERSE, ast_stream_and_wait(), ast_test_flag, async_play_sound_file(), confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_PARTICIPANTS_MUTED, CONF_SOUND_PARTICIPANTS_UNMUTED, conf_update_user_mute(), confbridge_user::conference, bridge_profile::language, confbridge_user::list, mute, 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 1500 of file app_confbridge.c.

1501 {
1502  struct ast_format_cap *cap;
1503  char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1504 
1506  if (!cap) {
1507  return -1;
1508  }
1510  conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1511  conference->name, NULL);
1512  ao2_ref(cap, -1);
1513  if (!conference->playback_chan) {
1514  return -1;
1515  }
1516 
1517  /* To make sure playback_chan has the same language as the bridge */
1518  ast_channel_lock(conference->playback_chan);
1519  ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1520  ast_channel_unlock(conference->playback_chan);
1521 
1522  ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1523  ast_channel_name(conference->playback_chan), conference->name);
1524 
1525  ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1526  "Confbridge/%s", conference->name);
1527  conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1528  if (!conference->playback_queue) {
1529  ast_hangup(conference->playback_chan);
1530  conference->playback_chan = NULL;
1531  return -1;
1532  }
1533  return 0;
1534 }
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2542
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:6432
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
#define ast_debug(level,...)
Log a DEBUG message.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct ast_channel * playback_chan
Definition: confbridge.h:255
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:261
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
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.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61

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

Referenced by join_conference_bridge().

◆ announce_user_count()

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

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

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

Definition at line 993 of file app_confbridge.c.

995 {
996  const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
997  const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
998  const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
999 
1000  if (conference->activeusers <= 1) {
1001  /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
1002  return 0;
1003  } else if (conference->activeusers == 2) {
1004  if (user) {
1005  /* Eep, there is one other person */
1006  if (play_file(bridge_channel, user->chan, only_one) < 0) {
1007  return -1;
1008  }
1009  } else {
1010  play_sound_file(conference, only_one);
1011  }
1012  } else {
1013  /* Alas multiple others in here */
1014  if (user) {
1015  if (ast_stream_and_wait(user->chan,
1016  there_are,
1017  "")) {
1018  return -1;
1019  }
1020  if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
1021  return -1;
1022  }
1023  if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
1024  return -1;
1025  }
1026  } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
1027  play_sound_file(conference, there_are);
1028  play_sound_number(conference, conference->activeusers - 1);
1029  play_sound_file(conference, other_in_party);
1030  }
1031  }
1032  return 0;
1033 }
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:176
@ CONF_SOUND_THERE_ARE
Definition: confbridge.h:175
@ CONF_SOUND_ONLY_ONE
Definition: confbridge.h:174
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:8318

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

Referenced by execute_menu_entry(), and join_conference_bridge().

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 4513 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data* async_datastore_data_alloc ( void  )
static

Definition at line 2089 of file app_confbridge.c.

2090 {
2091  struct async_datastore_data *add;
2092 
2093  add = ast_malloc(sizeof(*add));
2094  if (!add) {
2095  return NULL;
2096  }
2097 
2098  ast_mutex_init(&add->lock);
2099  ast_cond_init(&add->cond, NULL);
2100  add->wait = 1;
2101 
2102  return add;
2103 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_mutex_init(pmutex)
Definition: lock.h:184

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

2058 {
2059  struct async_datastore_data *add = data;
2060 
2061  ast_mutex_destroy(&add->lock);
2062  ast_cond_destroy(&add->cond);
2063 
2064  ast_free(add);
2065 }
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_mutex_destroy(a)
Definition: lock.h:186

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

2498 {
2499  struct async_delete_name_rec_task_data *atd;
2500 
2501  if (ast_strlen_zero(filename)) {
2502  return 0;
2503  } else if (!sound_file_exists(filename)) {
2504  return 0;
2505  }
2506 
2508  if (!atd) {
2509  return -1;
2510  }
2511 
2513  ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2516  return -1;
2517  }
2518 
2519  return 0;
2520 }
static struct async_delete_name_rec_task_data * async_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)
static int async_delete_name_rec_task(void *data)
Delete user's name file asynchronously.
struct confbridge_conference * conference
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

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

Referenced by confbridge_exec().

◆ async_delete_name_rec_task()

static int async_delete_name_rec_task ( void *  data)
static

Delete user's name file asynchronously.

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

Parameters
dataAn async_delete_name_rec_task_data
Returns
0

Definition at line 2484 of file app_confbridge.c.

2485 {
2486  struct async_delete_name_rec_task_data *atd = data;
2487 
2488  ast_filedelete(atd->filename, NULL);
2489  ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2490  atd->conference->name, atd->filename);
2491 
2493  return 0;
2494 }
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1139
#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 2453 of file app_confbridge.c.

2455 {
2456  struct async_delete_name_rec_task_data *atd;
2457 
2458  atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2459  if (!atd) {
2460  return NULL;
2461  }
2462 
2463  /* Safe */
2464  strcpy(atd->filename, filename);
2465  atd->conference = conference;
2466 
2467  return atd;
2468 }

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

2471 {
2472  ast_free(atd);
2473 }

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

2288 {
2289  return async_play_sound_helper(conference, filename, -1, initiator);
2290 }
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 2252 of file app_confbridge.c.

2254 {
2255  struct async_playback_task_data *aptd;
2256 
2257  /* Do not waste resources trying to play files that do not exist */
2258  if (ast_strlen_zero(filename)) {
2259  if (say_number < 0) {
2260  return 0;
2261  }
2262  } else if (!sound_file_exists(filename)) {
2263  return 0;
2264  }
2265 
2267  if (!aptd) {
2268  return -1;
2269  }
2270 
2272  if (!ast_strlen_zero(filename)) {
2273  ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2275  } else {
2276  ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2278  }
2280  return -1;
2281  }
2282 
2283  return 0;
2284 }
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 2292 of file app_confbridge.c.

2293 {
2294  struct ast_datastore *async_datastore;
2295  struct async_datastore_data *add;
2296 
2297  ast_channel_lock(chan);
2298  async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2299  ast_channel_unlock(chan);
2300  if (!async_datastore) {
2301  return;
2302  }
2303 
2304  add = async_datastore->data;
2305 
2306  ast_mutex_lock(&add->lock);
2307  add->wait = 0;
2308  ast_cond_signal(&add->cond);
2309  ast_mutex_unlock(&add->lock);
2310 }
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:2398
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
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 2237 of file app_confbridge.c.

2238 {
2239  struct async_playback_task_data *aptd = data;
2240 
2241  /* Wait for the initiator to get back in the bridge or be hung up */
2242  if (aptd->initiator) {
2244  }
2245 
2246  playback_common(aptd->conference, aptd->filename, aptd->say_number);
2247 
2249  return 0;
2250 }
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 2145 of file app_confbridge.c.

2148 {
2149  struct async_playback_task_data *aptd;
2150 
2151  aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
2152  if (!aptd) {
2153  return NULL;
2154  }
2155 
2156  /* Safe */
2157  strcpy(aptd->filename, filename);
2158  aptd->say_number = say_number;
2159 
2160  /* You may think that we need to bump the conference refcount since we are pushing
2161  * this task to the taskprocessor.
2162  *
2163  * In this case, that actually causes a problem. The destructor for the conference
2164  * pushes a hangup task into the taskprocessor and waits for it to complete before
2165  * continuing. If the destructor gets called from a taskprocessor task, we're
2166  * deadlocked.
2167  *
2168  * So is there a risk of the conference being freed out from under us? No. Since
2169  * the destructor pushes a task into the taskprocessor and waits for it to complete,
2170  * the destructor cannot free the conference out from under us. No further tasks
2171  * can be queued onto the taskprocessor after the hangup since no channels are referencing
2172  * the conference at that point any more.
2173  */
2174  aptd->conference = conference;
2175 
2176  aptd->initiator = initiator;
2177  if (initiator) {
2179  ast_channel_lock(aptd->initiator);
2180  /* We don't really care if this fails. If the datastore fails to get set up
2181  * we'll still play the announcement. It's possible that the sound will be
2182  * clipped for the initiator, but that's not the end of the world.
2183  */
2186  }
2187 
2188  return aptd;
2189 }
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:2947

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

2192 {
2194  ast_free(aptd);
2195 }
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969

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

3586 {
3587  int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
3588 
3589  if (res == -1) {
3590  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3591  return -1;
3592  } else if (res == -2) {
3593  if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3594  ast_cli(a->fd, "No participants found in conference %s\n", a->argv[2]);
3595  } else {
3596  ast_cli(a->fd, "No channel named '%s' found in conference %s\n", a->argv[3], a->argv[2]);
3597  }
3598  return -1;
3599  }
3600  ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
3601  return 0;
3602 }
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct test_val a

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

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

3292 {
3293  int which = 0;
3294  struct confbridge_conference *conference;
3295  char *res = NULL;
3296  int wordlen = strlen(word);
3297  struct ao2_iterator iter;
3298 
3300  while ((conference = ao2_iterator_next(&iter))) {
3301  if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3302  res = ast_strdup(conference->name);
3303  ao2_ref(conference, -1);
3304  break;
3305  }
3306  ao2_ref(conference, -1);
3307  }
3308  ao2_iterator_destroy(&iter);
3309 
3310  return res;
3311 }
#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_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 3313 of file app_confbridge.c.

3314 {
3315  int which = 0;
3316  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3317  struct confbridge_user *user;
3318  char *res = NULL;
3319  int wordlen = strlen(word);
3320 
3321  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3322  if (!conference) {
3323  return NULL;
3324  }
3325 
3326  if (!strncasecmp("all", word, wordlen) && ++which > state) {
3327  return ast_strdup("all");
3328  }
3329 
3330  if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3331  return ast_strdup("participants");
3332  }
3333 
3334  {
3335  SCOPED_AO2LOCK(bridge_lock, conference);
3337  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3338  res = ast_strdup(ast_channel_name(user->chan));
3339  return res;
3340  }
3341  }
3343  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3344  res = ast_strdup(ast_channel_name(user->chan));
3345  return res;
3346  }
3347  }
3348  }
3349 
3350  return NULL;
3351 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
#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:936

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

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

◆ conf_add_post_join_action()

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

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

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

Definition at line 1449 of file app_confbridge.c.

1450 {
1451  struct post_join_action *action;
1452  if (!(action = ast_calloc(1, sizeof(*action)))) {
1453  return -1;
1454  }
1455  action->func = func;
1456  AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1457  return 0;
1458 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
int(* func)(struct confbridge_user *user)
Definition: confbridge.h:267
struct post_join_action::@87 list

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

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

◆ conf_add_user_active()

void conf_add_user_active ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

Definition at line 4314 of file app_confbridge.c.

4315 {
4316  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4317  conference->activeusers++;
4318 }

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

Referenced by join_active(), and join_unmarked().

◆ conf_add_user_marked()

void conf_add_user_marked ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

Definition at line 4320 of file app_confbridge.c.

4321 {
4322  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4323  conference->activeusers++;
4324  conference->markedusers++;
4325 }

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

Referenced by join_marked().

◆ conf_add_user_waiting()

void conf_add_user_waiting ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

Definition at line 4327 of file app_confbridge.c.

4328 {
4329  AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4330  conference->waitingusers++;
4331 }

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

1478 {
1479  struct pbx_find_info q = { .stacklen = 0 };
1480 
1481  /* Called with a reference to conference */
1482  ao2_unlink(conference_bridges, conference);
1483  send_conf_end_event(conference);
1484  if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1485  pbx_find_extension(NULL, NULL, &q, conference->b_profile.regcontext,
1486  conference->name, 1, NULL, "", E_MATCH)) {
1488  conference->name, 1, NULL);
1489  }
1490  ao2_lock(conference);
1491  conf_stop_record(conference);
1492  ao2_unlock(conference);
1493 }
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:218
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4955
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:238
int stacklen
Definition: extconf.h:238

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

793 {
794  return ao2_find(conference_bridges, conference_name, OBJ_KEY);
795 }

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

2355 {
2356  char pin_guess[MAX_PIN+1] = { 0, };
2357  const char *pin = user->u_profile.pin;
2358  char *tmp = pin_guess;
2359  int i, res;
2360  unsigned int len = MAX_PIN;
2361 
2362  /*
2363  * NOTE: We have not joined a conference yet so we have to use
2364  * the bridge profile requested by the user.
2365  */
2366 
2367  /* give them three tries to get the pin right */
2368  for (i = 0; i < 3; i++) {
2369  if (ast_app_getdata(chan,
2370  conf_get_sound(CONF_SOUND_GET_PIN, user->b_profile.sounds),
2371  tmp, len, 0) >= 0) {
2372  if (!strcasecmp(pin, pin_guess)) {
2373  return 0;
2374  }
2375  }
2376  ast_streamfile(chan,
2377  conf_get_sound(CONF_SOUND_INVALID_PIN, user->b_profile.sounds),
2378  ast_channel_language(chan));
2379  res = ast_waitstream(chan, AST_DIGIT_ANY);
2380  if (res > 0) {
2381  /* Account for digit already read during ivalid pin playback
2382  * resetting pin buf. */
2383  pin_guess[0] = res;
2384  pin_guess[1] = '\0';
2385  tmp = pin_guess + 1;
2386  len = MAX_PIN - 1;
2387  } else {
2388  /* reset pin buf as empty buffer. */
2389  tmp = pin_guess;
2390  len = MAX_PIN;
2391  }
2392  }
2393  return -1;
2394 }
#define MAX_PIN
Definition: app_meetme.c:822
static int tmp()
Definition: bt_open.c:389
@ CONF_SOUND_INVALID_PIN
Definition: confbridge.h:181
@ CONF_SOUND_GET_PIN
Definition: confbridge.h:180
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
Definition: main/app.c:188

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

Referenced by confbridge_exec().

◆ conf_get_sound()

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

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

Definition at line 531 of file app_confbridge.c.

532 {
533  switch (sound) {
535  return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
536  case CONF_SOUND_HAS_LEFT:
537  return S_OR(custom_sounds->hasleft, "conf-hasleft");
538  case CONF_SOUND_KICKED:
539  return S_OR(custom_sounds->kicked, "conf-kicked");
540  case CONF_SOUND_MUTED:
541  return S_OR(custom_sounds->muted, "conf-muted");
542  case CONF_SOUND_UNMUTED:
543  return S_OR(custom_sounds->unmuted, "conf-unmuted");
545  return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
547  return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
548  case CONF_SOUND_ONLY_ONE:
549  return S_OR(custom_sounds->onlyone, "conf-onlyone");
551  return S_OR(custom_sounds->thereare, "conf-thereare");
553  return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
555  return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
557  return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
559  return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
560  case CONF_SOUND_GET_PIN:
561  return S_OR(custom_sounds->getpin, "conf-getpin");
563  return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
565  return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
566  case CONF_SOUND_LOCKED:
567  return S_OR(custom_sounds->locked, "conf-locked");
569  return S_OR(custom_sounds->lockednow, "conf-lockednow");
571  return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
573  return S_OR(custom_sounds->errormenu, "conf-errormenu");
574  case CONF_SOUND_JOIN:
575  return S_OR(custom_sounds->join, "confbridge-join");
576  case CONF_SOUND_LEAVE:
577  return S_OR(custom_sounds->leave, "confbridge-leave");
579  return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
581  return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
582  case CONF_SOUND_BEGIN:
583  return S_OR(custom_sounds->begin, "confbridge-conf-begin");
584  }
585 
586  return "";
587 }
@ CONF_SOUND_JOIN
Definition: confbridge.h:187
@ CONF_SOUND_LOCKED_NOW
Definition: confbridge.h:184
@ CONF_SOUND_ONLY_PERSON
Definition: confbridge.h:182
@ CONF_SOUND_BEGIN
Definition: confbridge.h:191
@ CONF_SOUND_WAIT_FOR_LEADER
Definition: confbridge.h:178
@ CONF_SOUND_HAS_LEFT
Definition: confbridge.h:170
@ CONF_SOUND_LEAVE
Definition: confbridge.h:188
@ CONF_SOUND_LEADER_HAS_LEFT
Definition: confbridge.h:179
@ CONF_SOUND_PLACE_IN_CONF
Definition: confbridge.h:177
@ CONF_SOUND_HAS_JOINED
Definition: confbridge.h:169
@ CONF_SOUND_UNLOCKED_NOW
Definition: confbridge.h:185
@ CONF_SOUND_LOCKED
Definition: confbridge.h:183
@ CONF_SOUND_KICKED
Definition: confbridge.h:171
#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:223
const ast_string_field invalidpin
Definition: confbridge.h:223
const ast_string_field placeintoconf
Definition: confbridge.h:223
const ast_string_field onlyone
Definition: confbridge.h:223
const ast_string_field otherinparty
Definition: confbridge.h:223
const ast_string_field unlockednow
Definition: confbridge.h:223
const ast_string_field binauralon
Definition: confbridge.h:223
const ast_string_field getpin
Definition: confbridge.h:223
const ast_string_field errormenu
Definition: confbridge.h:223
const ast_string_field participantsunmuted
Definition: confbridge.h:223
const ast_string_field participantsmuted
Definition: confbridge.h:223
const ast_string_field leave
Definition: confbridge.h:223
const ast_string_field locked
Definition: confbridge.h:223
const ast_string_field join
Definition: confbridge.h:223
const ast_string_field kicked
Definition: confbridge.h:223
const ast_string_field hasleft
Definition: confbridge.h:223
const ast_string_field unmuted
Definition: confbridge.h:223
const ast_string_field leaderhasleft
Definition: confbridge.h:223
const ast_string_field lockednow
Definition: confbridge.h:223
const ast_string_field hasjoin
Definition: confbridge.h:223
const ast_string_field binauraloff
Definition: confbridge.h:223
const ast_string_field onlyperson
Definition: confbridge.h:223
const ast_string_field thereare
Definition: confbridge.h:223
const ast_string_field muted
Definition: confbridge.h:223
const ast_string_field begin
Definition: confbridge.h:223

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

3229 {
3230  /* See if music on hold is playing */
3232 
3233  /* execute the list of actions associated with this menu entry */
3234  execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3235 
3236  /* See if music on hold needs to be started back up again */
3238 
3239  async_play_sound_ready(bridge_channel->chan);
3240 
3241  return 0;
3242 }
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 1461 of file app_confbridge.c.

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

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

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

◆ conf_handle_inactive_waitmarked()

int conf_handle_inactive_waitmarked ( struct confbridge_user user)

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

Parameters
userThe waitmarked user
Return values
0success
-1failure

Definition at line 1425 of file app_confbridge.c.

1426 {
1427  /* If we have not been quieted play back that they are waiting for the leader */
1429  conf_get_sound(CONF_SOUND_WAIT_FOR_LEADER, user->conference->b_profile.sounds))) {
1430  /* user hungup while the sound was playing */
1431  return -1;
1432  }
1433  return 0;
1434 }
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 1436 of file app_confbridge.c.

1437 {
1438  /* If audio prompts have not been quieted or this prompt quieted play it on out */
1439  if (!ast_test_flag(&user->u_profile, USER_OPT_QUIET | USER_OPT_NOONLYPERSON)) {
1441  conf_get_sound(CONF_SOUND_ONLY_PERSON, user->conference->b_profile.sounds))) {
1442  /* user hungup while the sound was playing */
1443  return -1;
1444  }
1445  }
1446  return 0;
1447 }
@ USER_OPT_NOONLYPERSON
Definition: confbridge.h:53

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

Referenced by join_marked(), and join_unmarked().

◆ conf_handle_second_active()

void conf_handle_second_active ( struct confbridge_conference conference)

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

Parameters
conferenceThe conference bridge with more than one active participant

Definition at line 1466 of file app_confbridge.c.

1467 {
1468  /* If we are the second participant we may need to stop music on hold on the first */
1469  struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1470 
1471  if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1472  conf_moh_stop(first_user);
1473  }
1474  conf_update_user_mute(first_user);
1475 }
void conf_moh_stop(struct confbridge_user *user)
Stop MOH for the conference user.
@ USER_OPT_MUSICONHOLD
Definition: confbridge.h:56
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421

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

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

◆ conf_handle_talker_cb()

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

Definition at line 2326 of file app_confbridge.c.

2327 {
2328  struct confbridge_user *user = hook_pvt;
2330  struct ast_json *talking_extras;
2331 
2332  conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2333  if (!conference) {
2334  /* Remove the hook since the conference does not exist. */
2335  return -1;
2336  }
2337 
2338  ao2_lock(conference);
2339  user->talking = talking;
2340  ao2_unlock(conference);
2341 
2342  talking_extras = ast_json_pack("{s: s, s: b}",
2343  "talking_status", talking ? "on" : "off",
2344  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2345  if (!talking_extras) {
2346  return 0;
2347  }
2348 
2349  send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2350  ast_json_unref(talking_extras);
2351  return 0;
2352 }
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:591
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 808 of file app_confbridge.c.

809 {
810  return conference->record_chan != NULL;
811 }
struct ast_channel * record_chan
Definition: confbridge.h:256

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

1369 {
1370  user->playing_moh = 1;
1371  if (!user->suspended_moh) {
1372  int in_bridge;
1373 
1374  /*
1375  * Locking the ast_bridge here is the only way to hold off the
1376  * call to ast_bridge_join() in confbridge_exec() from
1377  * interfering with the bridge and MOH operations here.
1378  */
1379  ast_bridge_lock(user->conference->bridge);
1380 
1381  /*
1382  * Temporarily suspend the user from the bridge so we have
1383  * control to start MOH if needed.
1384  */
1385  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1386  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1387  if (in_bridge) {
1388  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1389  }
1390 
1391  ast_bridge_unlock(user->conference->bridge);
1392  }
1393 }
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3007
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3028
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7849

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

1342 {
1343  user->playing_moh = 0;
1344  if (!user->suspended_moh) {
1345  int in_bridge;
1346 
1347  /*
1348  * Locking the ast_bridge here is the only way to hold off the
1349  * call to ast_bridge_join() in confbridge_exec() from
1350  * interfering with the bridge and MOH operations here.
1351  */
1352  ast_bridge_lock(user->conference->bridge);
1353 
1354  /*
1355  * Temporarily suspend the user from the bridge so we have
1356  * control to stop MOH if needed.
1357  */
1358  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1359  ast_moh_stop(user->chan);
1360  if (in_bridge) {
1361  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1362  }
1363 
1364  ast_bridge_unlock(user->conference->bridge);
1365  }
1366 }
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7859

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

1417 {
1418  ao2_lock(user->conference);
1419  if (user->suspended_moh++ == 0 && user->playing_moh) {
1420  ast_moh_stop(user->chan);
1421  }
1422  ao2_unlock(user->conference);
1423 }

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

1402 {
1403  ao2_lock(user->conference);
1404  if (--user->suspended_moh == 0 && user->playing_moh) {
1405  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1406  }
1407  ao2_unlock(user->conference);
1408 }

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

4347 {
4348  struct confbridge_user *only_user = AST_LIST_FIRST(&conference->active_list);
4349 
4350  /* Turn on MOH if the single participant is set up for it */
4351  if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4352  conf_moh_start(only_user);
4353  }
4354  conf_update_user_mute(only_user);
4355 }
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 2403 of file app_confbridge.c.

2404 {
2405  char destdir[PATH_MAX];
2406  int res;
2407  int duration = 20;
2408 
2409  snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2410 
2411  if (ast_mkdir(destdir, 0777) != 0) {
2412  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2413  return -1;
2414  }
2415  snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2416  "%s/confbridge-name-%s-%s", destdir,
2417  conf_name, ast_channel_uniqueid(user->chan));
2418 
2420  res = ast_play_and_record(user->chan,
2421  "vm-rec-name",
2422  user->name_rec_location,
2423  10,
2424  "sln",
2425  &duration,
2426  NULL,
2428  0,
2429  NULL);
2430  } else {
2431  res = ast_record_review(user->chan,
2432  "vm-rec-name",
2433  user->name_rec_location,
2434  10,
2435  "sln",
2436  &duration,
2437  NULL);
2438  }
2439 
2440  if (res == -1) {
2441  ast_filedelete(user->name_rec_location, NULL);
2442  user->name_rec_location[0] = '\0';
2443  return -1;
2444  }
2445  return 0;
2446 }
#define PATH_MAX
Definition: asterisk.h:40
@ USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW
Definition: confbridge.h:68
@ THRESHOLD_SILENCE
Definition: dsp.h:73
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1999
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:2214
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:2706
int errno
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2377

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

4334 {
4335  AST_LIST_REMOVE(&conference->active_list, user, list);
4336  conference->activeusers--;
4337 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:856

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

Referenced by leave_active(), and leave_unmarked().

◆ conf_remove_user_marked()

void conf_remove_user_marked ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

Definition at line 4339 of file app_confbridge.c.

4340 {
4341  AST_LIST_REMOVE(&conference->active_list, user, list);
4342  conference->activeusers--;
4343  conference->markedusers--;
4344 }

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

Referenced by leave_marked().

◆ conf_remove_user_waiting()

void conf_remove_user_waiting ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

Definition at line 4357 of file app_confbridge.c.

4358 {
4359  AST_LIST_REMOVE(&conference->waiting_list, user, list);
4360  conference->waitingusers--;
4361 }

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

857 {
858  struct ast_app *mixmonapp;
859  struct ast_channel *chan;
860  struct ast_format_cap *cap;
861  struct ast_bridge_features *features;
862 
863  if (conf_is_recording(conference)) {
864  return -1;
865  }
866 
867  mixmonapp = pbx_findapp("MixMonitor");
868  if (!mixmonapp) {
869  ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
870  return -1;
871  }
872 
873  features = ast_bridge_features_new();
874  if (!features) {
875  return -1;
876  }
878 
880  if (!cap) {
881  ast_bridge_features_destroy(features);
882  return -1;
883  }
885 
886  /* Create the recording channel. */
887  chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
888  ao2_ref(cap, -1);
889  if (!chan) {
890  ast_bridge_features_destroy(features);
891  return -1;
892  }
893 
894  /* Start recording. */
895  set_rec_filename(conference, &conference->record_filename,
896  is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
897  ast_answer(chan);
898  pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
899 
900  /* Put the channel into the conference bridge. */
901  ast_channel_ref(chan);
902  conference->record_chan = chan;
903  if (ast_bridge_impart(conference->bridge, chan, NULL, features,
905  ast_hangup(chan);
906  ast_channel_unref(chan);
907  conference->record_chan = NULL;
908  return -1;
909  }
910 
911  ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
912  send_start_record_event(conference);
913 
914  return 0;
915 }
static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
static void send_start_record_event(struct confbridge_conference *conference)
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2806
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
ast_app: A registered application
Definition: pbx_app.c:45
Structure that contains features information.
struct ast_flags feature_flags
Main Channel structure associated with a channel.
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:227
struct ast_str * orig_rec_file
Definition: confbridge.h:258
struct ast_str * record_filename
Definition: confbridge.h:257
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define ast_set_flag(p, flag)
Definition: utils.h:70

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

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

◆ conf_stop_record()

static int conf_stop_record ( struct confbridge_conference conference)
static

Definition at line 824 of file app_confbridge.c.

825 {
826  struct ast_channel *chan;
827  struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
828 
829  if (!conf_is_recording(conference)) {
830  return -1;
831  }
832 
833  /* Remove the recording channel from the conference bridge. */
834  chan = conference->record_chan;
835  conference->record_chan = NULL;
836  ast_queue_frame(chan, &f);
837  ast_channel_unref(chan);
838 
839  ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
840  send_stop_record_event(conference);
841 
842  return 0;
843 }
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:1133
@ AST_FRAME_CONTROL
@ AST_CONTROL_HANGUP
Data structure associated with a single frame of data.

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

Referenced by action_confbridgestoprecord(), and conf_ended().

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

1284 {
1285  int mute_user;
1286  int mute_system;
1287  int mute_effective;
1288 
1289  /* User level mute request. */
1290  mute_user = user->muted;
1291 
1292  /* System level mute request. */
1293  mute_system = user->playing_moh
1294  /*
1295  * Do not allow waitmarked users to talk to anyone unless there
1296  * is a marked user present.
1297  */
1298  || (!user->conference->markedusers
1299  && ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED));
1300 
1301  mute_effective = mute_user || mute_system;
1302 
1303  ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1304  ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1305  mute_user, mute_system);
1306  user->features.mute = mute_effective;
1307  ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1308  "Mode: %s\r\n"
1309  "Conference: %s\r\n"
1310  "Channel: %s",
1311  mute_effective ? "muted" : "unmuted",
1312  user->conference->b_profile.name,
1313  ast_channel_name(user->chan));
1314 }

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

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

◆ confbridge_exec()

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

The ConfBridge application.

Definition at line 2548 of file app_confbridge.c.

2549 {
2550  int res = 0, volume_adjustments[2];
2551  int quiet = 0;
2552  int async_delete_task_pushed = 0;
2553  char *parse;
2554  const char *b_profile_name = NULL;
2555  const char *u_profile_name = NULL;
2556  const char *menu_profile_name = NULL;
2557  struct confbridge_conference *conference = NULL;
2558  struct confbridge_user user = {
2559  .chan = chan,
2560  .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2561  .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2562  .tech_args.drop_silence = 0,
2563  };
2564  struct confbridge_hook_data *join_hook_data;
2565  struct confbridge_hook_data *leave_hook_data;
2566 
2568  AST_APP_ARG(conf_name);
2569  AST_APP_ARG(b_profile_name);
2570  AST_APP_ARG(u_profile_name);
2571  AST_APP_ARG(menu_profile_name);
2572  );
2573 
2574  if (ast_bridge_features_init(&user.features)) {
2575  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2576  res = -1;
2577  goto confbridge_cleanup;
2578  }
2579 
2580  /* We need to make a copy of the input string if we are going to modify it! */
2581  parse = ast_strdupa(data);
2582 
2584 
2585  if (ast_strlen_zero(args.conf_name)) {
2586  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2587  ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2588  res = -1;
2589  goto confbridge_cleanup;
2590  }
2591 
2592  if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2593  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2594  ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2595  res = -1;
2596  goto confbridge_cleanup;
2597  }
2598 
2599  /* bridge profile name */
2600  if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2601  b_profile_name = args.b_profile_name;
2602  }
2603  if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2604  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2605  ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2606  b_profile_name : DEFAULT_BRIDGE_PROFILE);
2607  res = -1;
2608  goto confbridge_cleanup;
2609  }
2610 
2611  /* user profile name */
2612  if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2613  u_profile_name = args.u_profile_name;
2614  }
2615  if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2616  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2617  ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2618  u_profile_name : DEFAULT_USER_PROFILE);
2619  res = -1;
2620  goto confbridge_cleanup;
2621  }
2622 
2623  /* If channel hasn't been answered already, answer it, unless we're explicitly not supposed to */
2624  if ((ast_channel_state(chan) != AST_STATE_UP) && (ast_test_flag(&user.u_profile, USER_OPT_ANSWER_CHANNEL))) {
2625  ast_answer(chan);
2626  }
2627 
2628  quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2629 
2630  /* ask for a PIN immediately after finding user profile. This has to be
2631  * prompted for requardless of quiet setting. */
2632  if (!ast_strlen_zero(user.u_profile.pin)) {
2633  if (conf_get_pin(chan, &user)) {
2634  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2635  res = -1; /* invalid PIN */
2636  goto confbridge_cleanup;
2637  }
2638  }
2639 
2640  /* See if we need them to record a intro name */
2641  if (!quiet &&
2644  if (conf_rec_name(&user, args.conf_name)) {
2645  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2646  res = -1; /* Hangup during name recording */
2647  goto confbridge_cleanup;
2648  }
2649  }
2650 
2651  /* menu name */
2652  if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2653  menu_profile_name = args.menu_profile_name;
2654  }
2655 
2656  if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2657  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2658  ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2659  menu_profile_name : DEFAULT_MENU_PROFILE);
2660  res = -1;
2661  goto confbridge_cleanup;
2662  }
2663 
2664  /* Set if DTMF should pass through for this user or not */
2665  if (ast_test_flag(&user.u_profile, USER_OPT_DTMF_PASS)) {
2666  user.features.dtmf_passthrough = 1;
2667  } else {
2668  user.features.dtmf_passthrough = 0;
2669  }
2670 
2671  /* Set if text messaging is enabled for this user or not */
2672  if (ast_test_flag(&user.u_profile, USER_OPT_TEXT_MESSAGING)) {
2673  user.features.text_messaging = 1;
2674  } else {
2675  user.features.text_messaging = 0;
2676  }
2677 
2678  /* Set dsp threshold values if present */
2679  if (user.u_profile.talking_threshold) {
2680  user.tech_args.talking_threshold = user.u_profile.talking_threshold;
2681  }
2682  if (user.u_profile.silence_threshold) {
2683  user.tech_args.silence_threshold = user.u_profile.silence_threshold;
2684  }
2685 
2686  /* Set a talker indicate call back if talking detection is requested */
2687  if (ast_test_flag(&user.u_profile, USER_OPT_TALKER_DETECT)) {
2690  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2691  res = -1;
2692  goto confbridge_cleanup;
2693  }
2694  }
2695 
2696  /* Look for a conference bridge matching the provided name */
2697  if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2698  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2699  res = -1;
2700  goto confbridge_cleanup;
2701  }
2702 
2703  /* Keep a copy of volume adjustments so we can restore them later if need be */
2704  volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2705  volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2706 
2707  if (ast_test_flag(&user.u_profile, USER_OPT_DROP_SILENCE)) {
2708  user.tech_args.drop_silence = 1;
2709  }
2710 
2711  if (ast_test_flag(&user.u_profile, USER_OPT_JITTERBUFFER)) {
2712  ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2713  }
2714 
2715  if (ast_test_flag(&user.u_profile, USER_OPT_DENOISE)) {
2716  ast_func_write(chan, "DENOISE(rx)", "on");
2717  }
2718 
2719  /* if this user has a intro, play it before entering */
2720  if (!ast_strlen_zero(user.name_rec_location)) {
2721  ast_autoservice_start(chan);
2722  play_sound_file(conference, user.name_rec_location);
2725  ast_autoservice_stop(chan);
2726  }
2727 
2728  if (!quiet) {
2729  const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2730 
2731  /* if hear_own_join_sound is enabled play the Join sound to everyone */
2732  if (ast_test_flag(&user.u_profile, USER_OPT_HEAR_OWN_JOIN_SOUND) ) {
2733  if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2734  ast_stream_and_wait(chan, join_sound, "");
2735  ast_autoservice_start(chan);
2736  play_sound_file(conference, join_sound);
2737  ast_autoservice_stop(chan);
2738  } else {
2739  async_play_sound_file(conference, join_sound, chan);
2740  }
2741  /* if hear_own_join_sound is disabled only play the Join sound to just the conference */
2742  } else {
2743  ast_autoservice_start(chan);
2744  play_sound_file(conference, join_sound);
2745  ast_autoservice_stop(chan);
2746  }
2747  }
2748 
2749  if (user.u_profile.timeout) {
2750  ast_bridge_interval_hook(&user.features,
2751  0,
2752  user.u_profile.timeout * 1000,
2753  user_timeout,
2754  NULL,
2755  NULL,
2757  }
2758 
2759  /* See if we need to automatically set this user as a video source or not */
2761 
2763 
2764  join_hook_data = ast_malloc(sizeof(*join_hook_data));
2765  if (!join_hook_data) {
2766  res = -1;
2767  goto confbridge_cleanup;
2768  }
2769  join_hook_data->user = &user;
2770  join_hook_data->conference = conference;
2771  join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2773  join_hook_data, ast_free_ptr, 0);
2774  if (res) {
2775  ast_free(join_hook_data);
2776  ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2777  goto confbridge_cleanup;
2778  }
2779 
2780  leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2781  if (!leave_hook_data) {
2782  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2783  res = -1;
2784  goto confbridge_cleanup;
2785  }
2786  leave_hook_data->user = &user;
2787  leave_hook_data->conference = conference;
2788  leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2790  leave_hook_data, ast_free_ptr, 0);
2791  if (res) {
2792  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2793  ast_free(leave_hook_data);
2794  ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2795  goto confbridge_cleanup;
2796  }
2797 
2798  if (ast_bridge_join_hook(&user.features, join_callback, NULL, NULL, 0)) {
2800  }
2801 
2803  chan,
2804  NULL,
2805  &user.features,
2806  &user.tech_args,
2807  0);
2808 
2809  /* This is a catch-all in case joining the bridge failed or for some reason
2810  * an async announcement got queued up and hasn't been told to play yet
2811  */
2812  async_play_sound_ready(chan);
2813 
2814  if (!user.kicked && ast_check_hangup(chan)) {
2815  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2816  }
2817 
2818  /* if we're shutting down, don't attempt to do further processing */
2819  if (ast_shutting_down()) {
2820  /*
2821  * Not taking any new calls at this time. We cannot create
2822  * the announcer channel if this is the first channel into
2823  * the conference and we certainly cannot create any
2824  * recording channel.
2825  */
2827  conference = NULL;
2828  goto confbridge_cleanup;
2829  }
2830 
2831  /* If this user was a video source, we need to clean up and possibly pick a new source. */
2833 
2834  /* if this user has a intro, play it when leaving */
2835  if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2836  async_play_sound_file(conference, user.name_rec_location, NULL);
2839  async_delete_name_rec(conference, user.name_rec_location);
2840  async_delete_task_pushed = 1;
2841  }
2842 
2843  /* play the leave sound */
2844  if (!quiet) {
2845  const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2846  async_play_sound_file(conference, leave_sound, NULL);
2847  }
2848 
2849  /* If the user was kicked from the conference play back the audio prompt for it */
2850  if (!quiet && user.kicked) {
2851  res = ast_stream_and_wait(chan,
2853  "");
2854  }
2855 
2856  /* Easy as pie, depart this channel from the conference bridge */
2858  conference = NULL;
2859 
2860  /* Restore volume adjustments to previous values in case they were changed */
2861  if (volume_adjustments[0]) {
2862  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2863  }
2864  if (volume_adjustments[1]) {
2865  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2866  }
2867 
2868 confbridge_cleanup:
2869  if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2870  ast_filedelete(user.name_rec_location, NULL);
2871  }
2872  ast_bridge_features_cleanup(&user.features);
2873  conf_bridge_profile_destroy(&user.b_profile);
2874  return res;
2875 }
static int quiet
Definition: ael_main.c:123
static int send_event_hook_callback(struct ast_bridge_channel *bridge_channel, void *data)
static struct confbridge_conference * join_conference_bridge(const char *conference_name, struct confbridge_user *user)
Join a conference bridge.
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 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:1870
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:1291
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:1271
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1621
@ AST_BRIDGE_HOOK_TYPE_JOIN
@ AST_BRIDGE_HOOK_TYPE_LEAVE
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3620
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3319
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, ast_bridge_talking_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel talk detection hook to a bridge features structure.
Definition: bridge.c:3295
int ast_bridge_join_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel join hook to a bridge features structure.
Definition: bridge.c:3275
int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel leave hook to a bridge features structure.
Definition: bridge.c:3285
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3653
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1844
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
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.
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.
void conf_bridge_profile_destroy(struct bridge_profile *b_profile)
Destroy a bridge profile found by 'conf_find_bridge_profile'.
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.
#define DEFAULT_SILENCE_THRESHOLD
Definition: confbridge.h:49
@ USER_OPT_HEAR_OWN_JOIN_SOUND
Definition: confbridge.h:73
@ USER_OPT_TEXT_MESSAGING
Definition: confbridge.h:71
@ USER_OPT_DENOISE
Definition: confbridge.h:61
@ USER_OPT_DTMF_PASS
Definition: confbridge.h:65
@ USER_OPT_TALKER_DETECT
Definition: confbridge.h:63
@ USER_OPT_DROP_SILENCE
Definition: confbridge.h:64
@ USER_OPT_ANSWER_CHANNEL
Definition: confbridge.h:72
@ USER_OPT_JITTERBUFFER
Definition: confbridge.h:67
@ USER_OPT_ANNOUNCE_JOIN_LEAVE
Definition: confbridge.h:62
#define DEFAULT_TALKING_THRESHOLD
Definition: confbridge.h:46
#define DEFAULT_MENU_PROFILE
Definition: confbridge.h:43
#define DEFAULT_BRIDGE_PROFILE
Definition: confbridge.h:42
#define DEFAULT_USER_PROFILE
Definition: confbridge.h:41
#define MAX_CONF_NAME
Definition: confbridge.h:35
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_ERROR
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
struct confbridge_conference * conference
struct confbridge_user * user
enum ast_bridge_hook_type hook_type

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

Referenced by load_module().

◆ confbridge_handle_atxfer()

void confbridge_handle_atxfer ( struct ast_attended_transfer_message msg)

Create join/leave events for attended transfers.

Since
13.28
16.5
Parameters
msgThe attended transfer stasis message

Definition at line 1566 of file app_confbridge.c.

1567 {
1568  struct ast_channel_snapshot *old_snapshot;
1569  struct ast_channel_snapshot *new_snapshot;
1570  char *confbr_name = NULL;
1571  char *comma;
1573  struct confbridge_user *user = NULL;
1574  int found_user = 0;
1575  struct ast_json *json_object;
1576 
1578  && strcmp(msg->to_transferee.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1579  && msg->target) {
1580  /* We're transferring a bridge to an extension */
1581  old_snapshot = msg->to_transferee.channel_snapshot;
1582  new_snapshot = msg->target;
1583  } else if (msg->to_transfer_target.channel_snapshot
1584  && strcmp(msg->to_transfer_target.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1585  && msg->transferee) {
1586  /* We're transferring a call to a bridge */
1587  old_snapshot = msg->to_transfer_target.channel_snapshot;
1588  new_snapshot = msg->transferee;
1589  } else {
1590  ast_log(LOG_ERROR, "Could not determine proper channels\n");
1591  return;
1592  }
1593 
1594  /*
1595  * old_snapshot->data should have the original parameters passed to
1596  * the ConfBridge app:
1597  * conference[,bridge_profile[,user_profile[,menu]]]
1598  * We'll use "conference" to look up the bridge.
1599  *
1600  * We _could_ use old_snapshot->bridgeid to get the bridge but
1601  * that would involve locking the conference_bridges container
1602  * and iterating over it looking for a matching bridge.
1603  */
1604  if (ast_strlen_zero(old_snapshot->dialplan->data)) {
1605  ast_log(LOG_ERROR, "Channel '%s' didn't have app data set\n", old_snapshot->base->name);
1606  return;
1607  }
1608  confbr_name = ast_strdupa(old_snapshot->dialplan->data);
1609  comma = strchr(confbr_name, ',');
1610  if (comma) {
1611  *comma = '\0';
1612  }
1613 
1614  ast_debug(1, "Confbr: %s Leaving: %s Joining: %s\n", confbr_name, old_snapshot->base->name, new_snapshot->base->name);
1615 
1616  conference = ao2_find(conference_bridges, confbr_name, OBJ_SEARCH_KEY);
1617  if (!conference) {
1618  ast_log(LOG_ERROR, "Conference bridge '%s' not found\n", confbr_name);
1619  return;
1620  }
1621  ao2_lock(conference);
1622 
1623  /*
1624  * We need to grab the user profile for the departing user in order to
1625  * properly format the join/leave messages.
1626  */
1627  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1628  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1629  found_user = 1;
1630  break;
1631  }
1632  }
1633 
1634  /*
1635  * If we didn't find the user in the active list, try the waiting list.
1636  */
1637  if (!found_user && conference->waitingusers) {
1638  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
1639  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1640  found_user = 1;
1641  break;
1642  }
1643  }
1644  }
1645 
1646  if (!found_user) {
1647  ast_log(LOG_ERROR, "Unable to find user profile for channel '%s' in bridge '%s'\n",
1648  old_snapshot->base->name, confbr_name);
1649  return;
1650  }
1651 
1652  /*
1653  * We're going to use the existing user profile to create the messages.
1654  */
1655  json_object = ast_json_pack("{s: b}",
1656  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
1657  );
1658  if (!json_object) {
1659  return;
1660  }
1661 
1662  send_conf_stasis_snapshots(conference, old_snapshot, confbridge_leave_type(), json_object);
1663  ast_json_unref(json_object);
1664 
1665  json_object = ast_json_pack("{s: b, s: b}",
1666  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
1667  "muted", user->muted);
1668  if (!json_object) {
1669  return;
1670  }
1671  send_conf_stasis_snapshots(conference, new_snapshot, confbridge_join_type(), json_object);
1672  ast_json_unref(json_object);
1673 }
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_leave_type(void)
get the confbridge leave stasis message type
struct stasis_message_type * confbridge_join_type(void)
get the confbridge join 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 1555 of file app_confbridge.c.

1556 {
1557  struct confbridge_conference *conference = obj;
1558 
1559  if (!obj) {
1560  return;
1561  }
1562  ao2_unlock(conference);
1563  ao2_ref(conference, -1);
1564 }

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

510 {
511  const struct confbridge_conference *left = obj;
512  const struct confbridge_conference *right = arg;
513  const char *right_name = arg;
514  int cmp;
515 
516  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
517  default:
518  case OBJ_POINTER:
519  right_name = right->name;
520  /* Fall through */
521  case OBJ_KEY:
522  cmp = strcasecmp(left->name, right_name);
523  break;
524  case OBJ_PARTIAL_KEY:
525  cmp = strncasecmp(left->name, right_name, strlen(right_name));
526  break;
527  }
528  return cmp ? 0 : CMP_MATCH;
529 }
@ 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 485 of file app_confbridge.c.

486 {
487  const struct confbridge_conference *conference = obj;
488  const char *name = obj;
489  int hash;
490 
491  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
492  default:
493  case OBJ_POINTER:
494  name = conference->name;
495  /* Fall through */
496  case OBJ_KEY:
497  hash = ast_str_case_hash(name);
498  break;
499  case OBJ_PARTIAL_KEY:
500  /* Should never happen in hash callback. */
501  ast_assert(0);
502  hash = 0;
503  break;
504  }
505  return hash;
506 }
static const char name[]
Definition: format_mp3.c:68
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1281
#define ast_assert(a)
Definition: utils.h:734

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

4268 {
4269  char *parse;
4270  struct confbridge_conference *conference;
4271  int not_found;
4272 
4274  AST_APP_ARG(confbridge);
4275  AST_APP_ARG(channel);
4276  );
4277 
4278  if (ast_strlen_zero(data)) {
4279  ast_log(LOG_WARNING, "No conference bridge specified.\n");
4280  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4281  return 0;
4282  }
4283 
4284  parse = ast_strdupa(data);
4286 
4287  conference = ao2_find(conference_bridges, args.confbridge, OBJ_KEY);
4288  if (!conference) {
4289  ast_log(LOG_WARNING, "No conference bridge named '%s' found!\n", args.confbridge);
4290  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4291  return 0;
4292  }
4293  if (ast_strlen_zero(args.channel)) {
4294  not_found = kick_conference_participant(conference, "all");
4295  } else {
4296  not_found = kick_conference_participant(conference, args.channel);
4297  }
4298 
4299  ao2_ref(conference, -1);
4300  if (not_found) {
4301  if (ast_strlen_zero(args.channel) || !strcasecmp("all", args.channel) || !strcasecmp("participants", args.channel)) {
4302  ast_log(LOG_WARNING, "No participants found in conference bridge '%s'!\n", args.confbridge);
4303  } else {
4304  ast_log(LOG_WARNING, "No participant named '%s' found in conference bridge '%s'!\n", args.channel, args.confbridge);
4305  }
4306  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4307  return 0;
4308  }
4309  ast_debug(1, "Kicked '%s' out of conference '%s'\n", args.channel, args.confbridge);
4310  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "SUCCESS");
4311  return 0;
4312 }

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

1182 {
1183  struct confbridge_conference *conference = obj;
1184 
1185  ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
1186 
1187  if (conference->playback_chan) {
1188  if (conference->playback_queue) {
1189  struct hangup_data hangup;
1191 
1193  ast_mutex_lock(&hangup.lock);
1194  while (!hangup.hungup) {
1195  ast_cond_wait(&hangup.cond, &hangup.lock);
1196  }
1197  ast_mutex_unlock(&hangup.lock);
1198  }
1199 
1201  } else {
1202  /* Playback queue is not yet allocated. Just hang up the channel straight */
1205  }
1206  }
1207 
1208  /* Destroying a conference bridge is simple, all we have to do is destroy the bridging object */
1209  if (conference->bridge) {
1211  conference->bridge = NULL;
1212  }
1213 
1217 
1220 }
static void hangup_data_init(struct hangup_data *hangup, struct confbridge_conference *conference)
static void hangup_data_destroy(struct hangup_data *hangup)
static int hangup_playback(void *data)
Hang up the announcer channel.
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
static int hangup(void *data)
Definition: chan_pjsip.c:2504
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
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 3114 of file app_confbridge.c.

3119 {
3120  struct conf_menu_action *menu_action;
3121  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3122  int stop_prompts = 0;
3123  int res = 0;
3124 
3125  AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
3126  switch (menu_action->id) {
3128  res |= action_toggle_mute(conference, user, bridge_channel);
3129  break;
3131  action_toggle_binaural(conference, user, bridge_channel);
3132  break;
3134  if (!isadmin) {
3135  break;
3136  }
3138  break;
3140  announce_user_count(conference, user, bridge_channel);
3141  break;
3142  case MENU_ACTION_PLAYBACK:
3143  if (!stop_prompts) {
3144  res |= action_playback(bridge_channel, menu_action->data.playback_file);
3145  ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
3146  "Message: %s\r\nChannel: %s",
3147  menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
3148  }
3149  break;
3152  break;
3155  break;
3159  break;
3163  break;
3167  break;
3171  break;
3173  if (!(stop_prompts)) {
3174  res |= action_playback_and_continue(conference,
3175  user,
3176  bridge_channel,
3177  menu,
3178  menu_action->data.playback_file,
3179  menu_entry->dtmf,
3180  &stop_prompts);
3181  }
3182  break;
3184  res |= action_dialplan_exec(bridge_channel, menu_action);
3185  break;
3187  if (!isadmin) {
3188  break;
3189  }
3190  conference->locked = (!conference->locked ? 1 : 0);
3191  res |= play_file(bridge_channel, NULL,
3194  conference->b_profile.sounds)) < 0;
3195  break;
3197  res |= action_kick_last(conference, bridge_channel, user);
3198  break;
3199  case MENU_ACTION_LEAVE:
3200  pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
3201  ao2_lock(conference);
3202  ast_bridge_remove(conference->bridge, bridge_channel->chan);
3203  ast_test_suite_event_notify("CONF_MENU_LEAVE",
3204  "Channel: %s",
3205  ast_channel_name(bridge_channel->chan));
3206  ao2_unlock(conference);
3207  break;
3208  case MENU_ACTION_NOOP:
3209  break;
3211  ao2_lock(conference);
3212  if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
3213  ast_bridge_set_single_src_video_mode(conference->bridge, bridge_channel->chan);
3214  }
3215  ao2_unlock(conference);
3216  break;
3218  handle_video_on_exit(conference, bridge_channel->chan);
3219  break;
3220  }
3221  }
3222  return res;
3223 }
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:1311
@ BRIDGE_OPT_VIDEO_SRC_SFU
Definition: confbridge.h:84
@ MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC
Definition: confbridge.h:111
@ MENU_ACTION_SET_SINGLE_VIDEO_SRC
Definition: confbridge.h:110
@ MENU_ACTION_ADMIN_KICK_LAST
Definition: confbridge.h:107
@ MENU_ACTION_TOGGLE_BINAURAL
Definition: confbridge.h:114
@ MENU_ACTION_PLAYBACK
Definition: confbridge.h:97
@ MENU_ACTION_LEAVE
Definition: confbridge.h:108
@ MENU_ACTION_RESET_LISTENING
Definition: confbridge.h:101
@ MENU_ACTION_INCREASE_TALKING
Definition: confbridge.h:103
@ MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS
Definition: confbridge.h:113
@ MENU_ACTION_INCREASE_LISTENING
Definition: confbridge.h:99
@ MENU_ACTION_DIALPLAN_EXEC
Definition: confbridge.h:105
@ MENU_ACTION_DECREASE_LISTENING
Definition: confbridge.h:100
@ MENU_ACTION_PLAYBACK_AND_CONTINUE
Definition: confbridge.h:98
@ MENU_ACTION_ADMIN_TOGGLE_LOCK
Definition: confbridge.h:106
@ MENU_ACTION_DECREASE_TALKING
Definition: confbridge.h:104
@ MENU_ACTION_PARTICIPANT_COUNT
Definition: confbridge.h:112
@ MENU_ACTION_TOGGLE_MUTE
Definition: confbridge.h:96
@ MENU_ACTION_NOOP
Definition: confbridge.h:109
@ MENU_ACTION_RESET_TALKING
Definition: confbridge.h:102
enum conf_menu_action_id id
Definition: confbridge.h:122
char playback_file[PATH_MAX]
Definition: confbridge.h:124
struct conf_menu_action::@80 action
struct conf_menu_entry::@82 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_info()

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

Definition at line 4207 of file app_confbridge.c.

4208 {
4209  char *parse;
4210  struct confbridge_conference *conference;
4211  struct confbridge_user *user;
4212  int count = 0;
4214  AST_APP_ARG(type);
4215  AST_APP_ARG(confno);
4216  );
4217 
4218  /* parse all the required arguments and make sure they exist. */
4219  if (ast_strlen_zero(data)) {
4220  return -1;
4221  }
4222  parse = ast_strdupa(data);
4224  if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
4225  return -1;
4226  }
4228  if (!conference) {
4229  snprintf(buf, len, "0");
4230  return 0;
4231  }
4232 
4233  /* get the correct count for the type requested */
4235  if (!strcasecmp(args.type, "parties")) {
4237  count++;
4238  }
4240  count++;
4241  }
4242  } else if (!strcasecmp(args.type, "admins")) {
4244  if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
4245  count++;
4246  }
4247  }
4248  } else if (!strcasecmp(args.type, "marked")) {
4250  if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
4251  count++;
4252  }
4253  }
4254  } else if (!strcasecmp(args.type, "locked")) {
4255  count = conference->locked;
4256  } else if (!strcasecmp(args.type, "muted")) {
4257  count = conference->muted;
4258  } else {
4259  ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
4260  }
4261  snprintf(buf, len, "%d", count);
4263  ao2_ref(conference, -1);
4264  return 0;
4265 }
static const char type[]
Definition: chan_ooh323.c:109
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References confbridge_conference::active_list, ao2_find, ao2_lock, ao2_ref, ao2_unlock, args, AST_APP_ARG, AST_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, parse(), type, user, USER_OPT_ADMIN, USER_OPT_MARKEDUSER, and confbridge_conference::waiting_list.

◆ generic_lock_unlock_helper()

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

Definition at line 3514 of file app_confbridge.c.

3515 {
3516  struct confbridge_conference *conference;
3517  int res = 0;
3518 
3519  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3520  if (!conference) {
3521  return -1;
3522  }
3523  ao2_lock(conference);
3524  conference->locked = lock;
3525  ast_test_suite_event_notify("CONF_LOCK", "Message: conference %s\r\nConference: %s", conference->locked ? "locked" : "unlocked", conference->b_profile.name);
3526  ao2_unlock(conference);
3527  ao2_ref(conference, -1);
3528 
3529  return res;
3530 }

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

3541 {
3542  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3543  struct confbridge_user *user;
3544  int all = !strcasecmp("all", chan_name);
3545  int participants = !strcasecmp("participants", chan_name);
3546  int res = -2;
3547 
3548  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3549  if (!conference) {
3550  return -1;
3551  }
3552 
3553  {
3554  SCOPED_AO2LOCK(bridge_lock, conference);
3556  int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3557  strlen(chan_name));
3558  if (match || all
3559  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3561  res = 0;
3562  if (match) {
3563  return res;
3564  }
3565  }
3566  }
3567 
3569  int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3570  strlen(chan_name));
3571  if (match || all
3572  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3574  res = 0;
3575  if (match) {
3576  return res;
3577  }
3578  }
3579  }
3580  }
3581 
3582  return res;
3583 }
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:2312

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(), mute, NULL, OBJ_KEY, RAII_VAR, SCOPED_AO2LOCK, user, USER_OPT_ADMIN, and confbridge_conference::waiting_list.

Referenced by action_mute_unmute_helper(), and cli_mute_unmute_helper().

◆ generic_mute_unmute_user()

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

Definition at line 1320 of file app_confbridge.c.

1321 {
1322  /* Set user level mute request. */
1323  user->muted = mute ? 1 : 0;
1324 
1326  ast_test_suite_event_notify("CONF_MUTE",
1327  "Message: participant %s %s\r\n"
1328  "Conference: %s\r\n"
1329  "Channel: %s",
1330  ast_channel_name(user->chan),
1331  mute ? "muted" : "unmuted",
1332  conference->b_profile.name,
1333  ast_channel_name(user->chan));
1334  if (mute) {
1335  send_mute_event(user, conference);
1336  } else {
1337  send_unmute_event(user, conference);
1338  }
1339 }
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, mute, 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 3353 of file app_confbridge.c.

3354 {
3355  struct confbridge_conference *conference;
3356  int not_found;
3357 
3358  switch (cmd) {
3359  case CLI_INIT:
3360  e->command = "confbridge kick";
3361  e->usage =
3362  "Usage: confbridge kick <conference> <channel>\n"
3363  " Kicks a channel out of the conference bridge.\n"
3364  " (all to kick everyone, participants to kick non-admins).\n";
3365  return NULL;
3366  case CLI_GENERATE:
3367  if (a->pos == 2) {
3368  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3369  }
3370  if (a->pos == 3) {
3371  return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3372  }
3373  return NULL;
3374  }
3375 
3376  if (a->argc != 4) {
3377  return CLI_SHOWUSAGE;
3378  }
3379 
3380  conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
3381  if (!conference) {
3382  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3383  return CLI_SUCCESS;
3384  }
3385  not_found = kick_conference_participant(conference, a->argv[3]);
3386  ao2_ref(conference, -1);
3387  if (not_found) {
3388  if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3389  ast_cli(a->fd, "No participants found!\n");
3390  } else {
3391  ast_cli(a->fd, "No participant named '%s' found!\n", a->argv[3]);
3392  }
3393  return CLI_SUCCESS;
3394  }
3395  ast_cli(a->fd, "Kicked '%s' out of conference '%s'\n", a->argv[3], a->argv[2]);
3396  return CLI_SUCCESS;
3397 }
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 3435 of file app_confbridge.c.

3436 {
3437  struct confbridge_conference *conference;
3438 
3439  switch (cmd) {
3440  case CLI_INIT:
3441  e->command = "confbridge list";
3442  e->usage =
3443  "Usage: confbridge list [<name>]\n"
3444  " Lists all currently active conference bridges or a specific conference bridge.\n"
3445  "\n"
3446  " When a conference bridge name is provided, flags may be shown for users. Below\n"
3447  " are the flags and what they represent.\n"
3448  "\n"
3449  " Flags:\n"
3450  " A - The user is an admin\n"
3451  " M - The user is a marked user\n"
3452  " W - The user must wait for a marked user to join\n"
3453  " E - The user will be kicked after the last marked user leaves the conference\n"
3454  " m - The user is muted\n"
3455  " w - The user is waiting for a marked user to join\n";
3456  return NULL;
3457  case CLI_GENERATE:
3458  if (a->pos == 2) {
3459  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3460  }
3461  return NULL;
3462  }
3463 
3464  if (a->argc == 2) {
3465  struct ao2_iterator iter;
3466 
3467  ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
3468  ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
3470  while ((conference = ao2_iterator_next(&iter))) {
3471  ast_cli(a->fd, "%-32s %6u %6u %-6s %s\n",
3472  conference->name,
3473  conference->activeusers + conference->waitingusers,
3474  conference->markedusers,
3475  AST_CLI_YESNO(conference->locked),
3476  AST_CLI_YESNO(conference->muted));
3477  ao2_ref(conference, -1);
3478  }
3479  ao2_iterator_destroy(&iter);
3480  return CLI_SUCCESS;
3481  }
3482 
3483  if (a->argc == 3) {
3484  struct confbridge_user *user;
3485 
3487  if (!conference) {
3488  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3489  return CLI_SUCCESS;
3490  }
3491  ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu CallerID\n");
3492  ast_cli(a->fd, "============================== ====== ================ ================ ================ ================\n");
3496  }
<