Asterisk - The Open Source Telephony Project  18.5.0
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)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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 <[email protected]> 
David Vossel <[email protected]> 

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

Referenced by load_module().

◆ RECORD_FILENAME_INITIAL_SPACE

#define RECORD_FILENAME_INITIAL_SPACE   128

Initial recording filename space.

Definition at line 466 of file app_confbridge.c.

Referenced by is_new_rec_file(), and join_conference_bridge().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4504 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4504 of file app_confbridge.c.

◆ action_confbridgekick()

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

Definition at line 4037 of file app_confbridge.c.

References ao2_container_count(), ao2_find, ao2_ref, ast_strlen_zero, astman_get_header(), astman_send_ack(), astman_send_error(), hangup_data::conference, kick_conference_participant(), and OBJ_KEY.

Referenced by load_module().

4038 {
4039  const char *conference_name = astman_get_header(m, "Conference");
4040  const char *channel = astman_get_header(m, "Channel");
4041  struct confbridge_conference *conference;
4042  int found;
4043 
4044  if (ast_strlen_zero(conference_name)) {
4045  astman_send_error(s, m, "No Conference name provided.");
4046  return 0;
4047  }
4049  astman_send_error(s, m, "No active conferences.");
4050  return 0;
4051  }
4052 
4053  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4054  if (!conference) {
4055  astman_send_error(s, m, "No Conference by that name found.");
4056  return 0;
4057  }
4058 
4059  found = !kick_conference_participant(conference, channel);
4060  ao2_ref(conference, -1);
4061 
4062  if (found) {
4063  astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4064  } else {
4065  astman_send_error(s, m, "No Channel by that name found in Conference.");
4066  }
4067  return 0;
4068 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
Definition: muted.c:95
static int kick_conference_participant(struct confbridge_conference *conference, const char *channel)
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_confbridgelist()

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

Definition at line 3869 of file app_confbridge.c.

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(), hangup_data::conference, OBJ_KEY, total, user, and confbridge_conference::waiting_list.

Referenced by load_module().

3870 {
3871  const char *actionid = astman_get_header(m, "ActionID");
3872  const char *conference_name = astman_get_header(m, "Conference");
3873  struct confbridge_user *user;
3874  struct confbridge_conference *conference;
3875  char id_text[80];
3876  int total = 0;
3877 
3878  id_text[0] = '\0';
3879  if (!ast_strlen_zero(actionid)) {
3880  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3881  }
3882  if (ast_strlen_zero(conference_name)) {
3883  astman_send_error(s, m, "No Conference name provided.");
3884  return 0;
3885  }
3887  astman_send_error(s, m, "No active conferences.");
3888  return 0;
3889  }
3890  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3891  if (!conference) {
3892  astman_send_error(s, m, "No Conference by that name found.");
3893  return 0;
3894  }
3895 
3896  astman_send_listack(s, m, "Confbridge user list will follow", "start");
3897 
3898  ao2_lock(conference);
3899  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3900  total += action_confbridgelist_item(s, id_text, conference, user, 0);
3901  }
3902  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3903  total += action_confbridgelist_item(s, id_text, conference, user, 1);
3904  }
3905  ao2_unlock(conference);
3906  ao2_ref(conference, -1);
3907 
3908  astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
3910 
3911  return 0;
3912 }
static char user[512]
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
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:3237
#define ao2_unlock(a)
Definition: astobj2.h:730
struct confbridge_conference::@90 active_list
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static int total
Definition: res_adsi.c:968
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
static int action_confbridgelist_item(struct mansession *s, const char *id_text, struct confbridge_conference *conference, struct confbridge_user *user, int waiting)
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
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:3201

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

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_user::chan, confbridge_user::muted, confbridge_conference::name, confbridge_user::talking, confbridge_user::u_profile, USER_OPT_ADMIN, USER_OPT_ENDMARKED, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by action_confbridgelist().

3822 {
3823  struct ast_channel_snapshot *snapshot;
3824  struct ast_str *snap_str;
3825 
3827  if (!snapshot) {
3828  return 0;
3829  }
3830 
3831  snap_str = ast_manager_build_channel_state_string(snapshot);
3832  if (!snap_str) {
3833  ao2_ref(snapshot, -1);
3834  return 0;
3835  }
3836 
3837  astman_append(s,
3838  "Event: ConfbridgeList\r\n"
3839  "%s"
3840  "Conference: %s\r\n"
3841  "Admin: %s\r\n"
3842  "MarkedUser: %s\r\n"
3843  "WaitMarked: %s\r\n"
3844  "EndMarked: %s\r\n"
3845  "Waiting: %s\r\n"
3846  "Muted: %s\r\n"
3847  "Talking: %s\r\n"
3848  "AnsweredTime: %d\r\n"
3849  "%s"
3850  "\r\n",
3851  id_text,
3852  conference->name,
3857  AST_YESNO(waiting),
3858  AST_YESNO(user->muted),
3859  AST_YESNO(user->talking),
3861  ast_str_buffer(snap_str));
3862 
3863  ast_free(snap_str);
3864  ao2_ref(snapshot, -1);
3865 
3866  return 1;
3867 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure representing a snapshot of channel state.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
Definition: channel.c:2854
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
unsigned int muted
Definition: confbridge.h:281
#define ast_free(a)
Definition: astmm.h:182
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:139
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 user_profile u_profile
Definition: confbridge.h:274
unsigned int talking
Definition: confbridge.h:284
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

◆ action_confbridgelistrooms()

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

Definition at line 3914 of file app_confbridge.c.

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(), hangup_data::conference, confbridge_conference::locked, confbridge_conference::markedusers, confbridge_conference::muted, confbridge_conference::name, and confbridge_conference::waitingusers.

Referenced by load_module().

3915 {
3916  const char *actionid = astman_get_header(m, "ActionID");
3917  struct confbridge_conference *conference;
3918  struct ao2_iterator iter;
3919  char id_text[512] = "";
3920  int totalitems = 0;
3921 
3922  if (!ast_strlen_zero(actionid)) {
3923  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3924  }
3925 
3927  astman_send_error(s, m, "No active conferences.");
3928  return 0;
3929  }
3930 
3931  astman_send_listack(s, m, "Confbridge conferences will follow", "start");
3932 
3933  /* Traverse the conference list */
3935  while ((conference = ao2_iterator_next(&iter))) {
3936  totalitems++;
3937 
3938  ao2_lock(conference);
3939  astman_append(s,
3940  "Event: ConfbridgeListRooms\r\n"
3941  "%s"
3942  "Conference: %s\r\n"
3943  "Parties: %u\r\n"
3944  "Marked: %u\r\n"
3945  "Locked: %s\r\n"
3946  "Muted: %s\r\n"
3947  "\r\n",
3948  id_text,
3949  conference->name,
3950  conference->activeusers + conference->waitingusers,
3951  conference->markedusers,
3952  AST_YESNO(conference->locked),
3953  AST_YESNO(conference->muted));
3954  ao2_unlock(conference);
3955 
3956  ao2_ref(conference, -1);
3957  }
3958  ao2_iterator_destroy(&iter);
3959 
3960  /* Send final confirmation */
3961  astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
3963  return 0;
3964 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
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:3237
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
unsigned int markedusers
Definition: confbridge.h:250
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
unsigned int locked
Definition: confbridge.h:252
#define ast_strlen_zero(foo)
Definition: strings.h:52
unsigned int waitingusers
Definition: confbridge.h:251
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
The structure that represents a conference bridge.
Definition: confbridge.h:244
unsigned int activeusers
Definition: confbridge.h:249
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:139
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
unsigned int muted
Definition: confbridge.h:253
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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:3201

◆ action_confbridgelock()

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

Definition at line 4032 of file app_confbridge.c.

References action_lock_unlock_helper().

Referenced by load_module().

4033 {
4034  return action_lock_unlock_helper(s, m, 1);
4035 }
static int action_lock_unlock_helper(struct mansession *s, const struct message *m, int lock)

◆ action_confbridgemute()

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

Definition at line 4003 of file app_confbridge.c.

References action_mute_unmute_helper().

Referenced by load_module().

4004 {
4005  return action_mute_unmute_helper(s, m, 1);
4006 }
static int action_mute_unmute_helper(struct mansession *s, const struct message *m, int mute)

◆ action_confbridgesetsinglevideosrc()

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

Definition at line 4149 of file app_confbridge.c.

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, confbridge_user::chan, hangup_data::conference, OBJ_KEY, and user.

Referenced by load_module().

4150 {
4151  const char *conference_name = astman_get_header(m, "Conference");
4152  const char *channel = astman_get_header(m, "Channel");
4153  struct confbridge_user *user;
4154  struct confbridge_conference *conference;
4155 
4156  if (ast_strlen_zero(conference_name)) {
4157  astman_send_error(s, m, "No Conference name provided.");
4158  return 0;
4159  }
4160  if (ast_strlen_zero(channel)) {
4161  astman_send_error(s, m, "No channel name provided.");
4162  return 0;
4163  }
4165  astman_send_error(s, m, "No active conferences.");
4166  return 0;
4167  }
4168 
4169  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4170  if (!conference) {
4171  astman_send_error(s, m, "No Conference by that name found.");
4172  return 0;
4173  }
4174 
4175  /* find channel and set as video src. */
4176  ao2_lock(conference);
4177  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4178  if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4179  ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
4180  break;
4181  }
4182  }
4183  ao2_unlock(conference);
4184  ao2_ref(conference, -1);
4185 
4186  /* do not access user after conference unlock. We are just
4187  * using this check to see if it was found or not */
4188  if (!user) {
4189  astman_send_error(s, m, "No channel by that name found in conference.");
4190  return 0;
4191  }
4192  astman_send_ack(s, m, "Conference single video source set.");
4193  return 0;
4194 }
static char user[512]
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_channel * chan
Definition: confbridge.h:277
#define OBJ_KEY
Definition: astobj2.h:1155
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ao2_unlock(a)
Definition: astobj2.h:730
Definition: muted.c:95
struct confbridge_conference::@90 active_list
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
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:3816
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ action_confbridgestartrecord()

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

Definition at line 4070 of file app_confbridge.c.

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(), hangup_data::conference, OBJ_KEY, and bridge_profile::rec_file.

Referenced by load_module().

4071 {
4072  const char *conference_name = astman_get_header(m, "Conference");
4073  const char *recordfile = astman_get_header(m, "RecordFile");
4074  struct confbridge_conference *conference;
4075 
4076  if (ast_strlen_zero(conference_name)) {
4077  astman_send_error(s, m, "No Conference name provided.");
4078  return 0;
4079  }
4081  astman_send_error(s, m, "No active conferences.");
4082  return 0;
4083  }
4084 
4085  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4086  if (!conference) {
4087  astman_send_error(s, m, "No Conference by that name found.");
4088  return 0;
4089  }
4090 
4091  ao2_lock(conference);
4092  if (conf_is_recording(conference)) {
4093  astman_send_error(s, m, "Conference is already being recorded.");
4094  ao2_unlock(conference);
4095  ao2_ref(conference, -1);
4096  return 0;
4097  }
4098 
4099  if (!ast_strlen_zero(recordfile)) {
4100  ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4101  }
4102 
4103  if (conf_start_record(conference)) {
4104  astman_send_error(s, m, "Internal error starting conference recording.");
4105  ao2_unlock(conference);
4106  ao2_ref(conference, -1);
4107  return 0;
4108  }
4109  ao2_unlock(conference);
4110 
4111  ao2_ref(conference, -1);
4112  astman_send_ack(s, m, "Conference Recording Started.");
4113  return 0;
4114 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
char rec_file[PATH_MAX]
Definition: confbridge.h:228
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ao2_unlock(a)
Definition: astobj2.h:730
struct bridge_profile b_profile
Definition: confbridge.h:248
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static int conf_start_record(struct confbridge_conference *conference)
static int conf_is_recording(struct confbridge_conference *conference)
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_confbridgestoprecord()

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

Definition at line 4115 of file app_confbridge.c.

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(), hangup_data::conference, and OBJ_KEY.

Referenced by load_module().

4116 {
4117  const char *conference_name = astman_get_header(m, "Conference");
4118  struct confbridge_conference *conference;
4119 
4120  if (ast_strlen_zero(conference_name)) {
4121  astman_send_error(s, m, "No Conference name provided.");
4122  return 0;
4123  }
4125  astman_send_error(s, m, "No active conferences.");
4126  return 0;
4127  }
4128 
4129  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4130  if (!conference) {
4131  astman_send_error(s, m, "No Conference by that name found.");
4132  return 0;
4133  }
4134 
4135  ao2_lock(conference);
4136  if (conf_stop_record(conference)) {
4137  ao2_unlock(conference);
4138  astman_send_error(s, m, "Internal error while stopping recording.");
4139  ao2_ref(conference, -1);
4140  return 0;
4141  }
4142  ao2_unlock(conference);
4143 
4144  ao2_ref(conference, -1);
4145  astman_send_ack(s, m, "Conference Recording Stopped.");
4146  return 0;
4147 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
static int conf_stop_record(struct confbridge_conference *conference)
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ao2_unlock(a)
Definition: astobj2.h:730
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_confbridgeunlock()

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

Definition at line 4028 of file app_confbridge.c.

References action_lock_unlock_helper().

Referenced by load_module().

4029 {
4030  return action_lock_unlock_helper(s, m, 0);
4031 }
static int action_lock_unlock_helper(struct mansession *s, const struct message *m, int lock)

◆ action_confbridgeunmute()

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

Definition at line 3999 of file app_confbridge.c.

References action_mute_unmute_helper().

Referenced by load_module().

4000 {
4001  return action_mute_unmute_helper(s, m, 0);
4002 }
static int action_mute_unmute_helper(struct mansession *s, const struct message *m, int mute)

◆ action_dialplan_exec()

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

Definition at line 3059 of file app_confbridge.c.

References 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, ast_pbx_args::no_hangup_chan, NULL, and priority.

Referenced by execute_menu_entry().

3060 {
3061  struct ast_pbx_args args;
3062  struct ast_pbx *pbx;
3063  char *exten;
3064  char *context;
3065  int priority;
3066  int res;
3067 
3068  memset(&args, 0, sizeof(args));
3069  args.no_hangup_chan = 1;
3070 
3071  ast_channel_lock(bridge_channel->chan);
3072 
3073  /*save off*/
3074  exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3075  context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3076  priority = ast_channel_priority(bridge_channel->chan);
3077  pbx = ast_channel_pbx(bridge_channel->chan);
3078  ast_channel_pbx_set(bridge_channel->chan, NULL);
3079 
3080  /*set new*/
3081  ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3082  ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3083  ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3084 
3085  ast_channel_unlock(bridge_channel->chan);
3086 
3087  /*execute*/
3088  res = ast_pbx_run_args(bridge_channel->chan, &args);
3089 
3090  /*restore*/
3091  ast_channel_lock(bridge_channel->chan);
3092 
3093  ast_channel_exten_set(bridge_channel->chan, exten);
3094  ast_channel_context_set(bridge_channel->chan, context);
3095  ast_channel_priority_set(bridge_channel->chan, priority);
3096  ast_channel_pbx_set(bridge_channel->chan, pbx);
3097 
3098  ast_channel_unlock(bridge_channel->chan);
3099 
3100  return res;
3101 }
Options for ast_pbx_run()
Definition: pbx.h:391
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
const char * args
#define NULL
Definition: resample.c:96
static int priority
int ast_channel_priority(const struct ast_channel *chan)
Definition: pbx.h:211
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
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:4739
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_exten(const struct ast_channel *chan)
struct conf_menu_action::@84::@86 dialplan_args
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
union conf_menu_action::@84 data
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_channel * chan
void ast_channel_context_set(struct ast_channel *chan, const char *value)
const char * ast_channel_context(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
void ast_channel_priority_set(struct ast_channel *chan, int value)

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

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, ast_bridge_channel::chan, confbridge_user::chan, conf_get_sound(), CONF_SOUND_ERROR_MENU, 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().

3025 {
3026  struct confbridge_user *last_user = NULL;
3027  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3028 
3029  if (!isadmin) {
3030  play_file(bridge_channel, NULL,
3032  ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
3033  ast_channel_name(bridge_channel->chan),
3034  conference->name);
3035  return -1;
3036  }
3037 
3038  ao2_lock(conference);
3039  last_user = AST_LIST_LAST(&conference->active_list);
3040  if (!last_user) {
3041  ao2_unlock(conference);
3042  return 0;
3043  }
3044 
3045  if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3046  ao2_unlock(conference);
3047  play_file(bridge_channel, NULL,
3049  } else if (!last_user->kicked) {
3050  last_user->kicked = 1;
3051  pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3052  ast_bridge_remove(conference->bridge, last_user->chan);
3053  ao2_unlock(conference);
3054  }
3055 
3056  return 0;
3057 }
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
struct ast_channel * chan
Definition: confbridge.h:277
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
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 ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
struct user_profile u_profile
Definition: confbridge.h:274
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
unsigned int kicked
Definition: confbridge.h:282
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ action_lock_unlock_helper()

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

Definition at line 4008 of file app_confbridge.c.

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

Referenced by action_confbridgelock(), and action_confbridgeunlock().

4009 {
4010  const char *conference_name = astman_get_header(m, "Conference");
4011  int res = 0;
4012 
4013  if (ast_strlen_zero(conference_name)) {
4014  astman_send_error(s, m, "No Conference name provided.");
4015  return 0;
4016  }
4018  astman_send_error(s, m, "No active conferences.");
4019  return 0;
4020  }
4021  if ((res = generic_lock_unlock_helper(lock, conference_name))) {
4022  astman_send_error(s, m, "No Conference by that name found.");
4023  return 0;
4024  }
4025  astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
4026  return 0;
4027 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static int generic_lock_unlock_helper(int lock, const char *conference_name)
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_mute_unmute_helper()

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

Definition at line 3966 of file app_confbridge.c.

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

Referenced by action_confbridgemute(), and action_confbridgeunmute().

3967 {
3968  const char *conference_name = astman_get_header(m, "Conference");
3969  const char *channel_name = astman_get_header(m, "Channel");
3970  int res = 0;
3971 
3972  if (ast_strlen_zero(conference_name)) {
3973  astman_send_error(s, m, "No Conference name provided.");
3974  return 0;
3975  }
3976  if (ast_strlen_zero(channel_name)) {
3977  astman_send_error(s, m, "No channel name provided.");
3978  return 0;
3979  }
3981  astman_send_error(s, m, "No active conferences.");
3982  return 0;
3983  }
3984 
3985  res = generic_mute_unmute_helper(mute, conference_name, channel_name);
3986 
3987  if (res == -1) {
3988  astman_send_error(s, m, "No Conference by that name found.");
3989  return 0;
3990  } else if (res == -2) {
3991  astman_send_error(s, m, "No Channel by that name found in Conference.");
3992  return 0;
3993  }
3994 
3995  astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
3996  return 0;
3997 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
static int mute
Definition: chan_alsa.c:144
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static int generic_mute_unmute_helper(int mute, const char *conference_name, const char *chan_name)
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ action_playback()

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

Definition at line 2937 of file app_confbridge.c.

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().

2938 {
2939  char *file_copy = ast_strdupa(playback_file);
2940  char *file = NULL;
2941 
2942  while ((file = strsep(&file_copy, "&"))) {
2943  if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
2944  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2945  return -1;
2946  }
2947  }
2948  return 0;
2949 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:1814
struct ast_channel * chan
char * strsep(char **str, const char *delims)

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

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, execute_menu_entry(), make_ari_stubs::file, LOG_WARNING, MAXIMUM_DTMF_FEATURE_STRING, NULL, and strsep().

Referenced by execute_menu_entry().

2958 {
2959  int i;
2960  int digit = 0;
2961  char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
2962  struct conf_menu_entry new_menu_entry = { { 0, }, };
2963  char *file_copy = ast_strdupa(playback_file);
2964  char *file = NULL;
2965 
2966  while ((file = strsep(&file_copy, "&"))) {
2967  if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
2968  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2969  return -1;
2970  }
2971 
2972  /* now wait for more digits. */
2973  if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
2974  /* streaming finished and no DTMF was entered */
2975  continue;
2976  } else if (digit == -1) {
2977  /* error */
2978  return -1;
2979  } else {
2980  break; /* dtmf was entered */
2981  }
2982  }
2983  if (!digit) {
2984  /* streaming finished on all files and no DTMF was entered */
2985  return -1;
2986  }
2987  ast_stopstream(bridge_channel->chan);
2988 
2989  /* If we get here, then DTMF has been entered, This means no
2990  * additional prompts should be played for this menu entry */
2991  *stop_prompts = 1;
2992 
2993  /* If a digit was pressed during the payback, update
2994  * the dtmf string and look for a new menu entry in the
2995  * menu structure */
2996  ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
2997  for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
2998  dtmf[i] = cur_dtmf[i];
2999  if (!dtmf[i]) {
3000  dtmf[i] = (char) digit;
3001  dtmf[i + 1] = '\0';
3002  i = -1;
3003  break;
3004  }
3005  }
3006  /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
3007  * If this is the case, no new DTMF sequence should be looked for. */
3008  if (i != -1) {
3009  return 0;
3010  }
3011 
3012  if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
3013  execute_menu_entry(conference,
3014  user,
3015  bridge_channel,
3016  &new_menu_entry, menu);
3017  conf_menu_entry_destroy(&new_menu_entry);
3018  }
3019  return 0;
3020 }
char digit
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_DIGIT_ANY
Definition: file.h:48
Definition: confbridge.h:136
#define LOG_WARNING
Definition: logger.h:274
void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry)
Destroys and frees all the actions stored in a menu_entry structure.
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define MAXIMUM_DTMF_FEATURE_STRING
Maximum length of a DTMF feature string.
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)
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.
struct ast_channel * chan
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

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

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

Referenced by execute_menu_entry().

2884 {
2885  unsigned int binaural;
2886  ast_bridge_channel_lock_bridge(bridge_channel);
2887  binaural = !bridge_channel->binaural_suspended;
2888  bridge_channel->binaural_suspended = binaural;
2889  ast_bridge_unlock(bridge_channel->bridge);
2890  return play_file(bridge_channel, NULL, (binaural ?
2893 }
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...
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
unsigned int binaural_suspended
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct bridge_profile b_profile
Definition: confbridge.h:273
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)

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

References confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_MUTED, CONF_SOUND_UNMUTED, generic_mute_unmute_user(), mute, confbridge_user::muted, NULL, play_file(), and bridge_profile::sounds.

Referenced by execute_menu_entry().

2869 {
2870  int mute;
2871 
2872  /* Toggle user level mute request. */
2873  mute = !user->muted;
2874  generic_mute_unmute_user(conference, user, mute);
2875 
2876  return play_file(bridge_channel, NULL,
2878  conference->b_profile.sounds)) < 0;
2879 }
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...
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
#define NULL
Definition: resample.c:96
static int mute
Definition: chan_alsa.c:144
struct bridge_profile b_profile
Definition: confbridge.h:248
unsigned int muted
Definition: confbridge.h:281
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)

◆ action_toggle_mute_participants()

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

Definition at line 2895 of file app_confbridge.c.

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, confbridge_user::chan, conf_get_sound(), CONF_SOUND_PARTICIPANTS_MUTED, CONF_SOUND_PARTICIPANTS_UNMUTED, conf_update_user_mute(), 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().

2896 {
2897  struct confbridge_user *cur_user = NULL;
2898  const char *sound_to_play;
2899  int mute;
2900 
2901  ao2_lock(conference);
2902 
2903  /* Toggle bridge level mute request. */
2904  mute = !conference->muted;
2905  conference->muted = mute;
2906 
2907  AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) {
2908  if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
2909  /* Set user level to bridge level mute request. */
2910  cur_user->muted = mute;
2911  conf_update_user_mute(cur_user);
2912  }
2913  }
2914 
2915  ao2_unlock(conference);
2916 
2917  sound_to_play = conf_get_sound(
2919  conference->b_profile.sounds);
2920 
2921  if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
2922  /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
2923  ast_stream_and_wait(user->chan, sound_to_play, "");
2924 
2925  /* Announce to the group that all participants are muted */
2926  ast_autoservice_start(user->chan);
2927  play_sound_file(conference, sound_to_play);
2928  ast_autoservice_stop(user->chan);
2929  } else {
2930  /* Playing the sound asynchronously lets the sound be heard by everyone at once */
2931  async_play_sound_file(conference, sound_to_play, user->chan);
2932  }
2933 
2934  return 0;
2935 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
struct ast_channel * chan
Definition: confbridge.h:277
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
#define ao2_unlock(a)
Definition: astobj2.h:730
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
static int mute
Definition: chan_alsa.c:144
struct bridge_profile b_profile
Definition: confbridge.h:248
int async_play_sound_file(struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
Play sound file into conference bridge asynchronously.
#define ao2_lock(a)
Definition: astobj2.h:718
char language[MAX_LANGUAGE]
Definition: confbridge.h:227
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
unsigned int muted
Definition: confbridge.h:281
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
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:1814
const char * ast_channel_language(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
unsigned int muted
Definition: confbridge.h:253
int play_sound_file(struct confbridge_conference *conference, const char *filename)
Play sound file into conference bridge.
struct user_profile u_profile
Definition: confbridge.h:274

◆ alloc_playback_chan()

static int alloc_playback_chan ( struct confbridge_conference conference)
static

Definition at line 1496 of file app_confbridge.c.

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().

1497 {
1498  struct ast_format_cap *cap;
1499  char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1500 
1502  if (!cap) {
1503  return -1;
1504  }
1506  conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1507  conference->name, NULL);
1508  ao2_ref(cap, -1);
1509  if (!conference->playback_chan) {
1510  return -1;
1511  }
1512 
1513  /* To make sure playback_chan has the same language as the bridge */
1514  ast_channel_lock(conference->playback_chan);
1515  ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1516  ast_channel_unlock(conference->playback_chan);
1517 
1518  ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1519  ast_channel_name(conference->playback_chan), conference->name);
1520 
1521  ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1522  "Confbridge/%s", conference->name);
1523  conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1524  if (!conference->playback_queue) {
1525  ast_hangup(conference->playback_chan);
1526  conference->playback_chan = NULL;
1527  return -1;
1528  }
1529  return 0;
1530 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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...
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:75
#define NULL
Definition: resample.c:96
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:60
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:260
struct bridge_profile b_profile
Definition: confbridge.h:248
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:6444
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
char language[MAX_LANGUAGE]
Definition: confbridge.h:227
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * playback_chan
Definition: confbridge.h:254
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

◆ 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.
Returns
Returns 0 on success, -1 if the user hung up

Definition at line 985 of file app_confbridge.c.

References confbridge_conference::activeusers, ast_channel_language(), ast_say_number(), ast_stream_and_wait(), confbridge_conference::b_profile, confbridge_user::chan, 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().

987 {
988  const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
989  const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
990  const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
991 
992  if (conference->activeusers <= 1) {
993  /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
994  return 0;
995  } else if (conference->activeusers == 2) {
996  if (user) {
997  /* Eep, there is one other person */
998  if (play_file(bridge_channel, user->chan, only_one) < 0) {
999  return -1;
1000  }
1001  } else {
1002  play_sound_file(conference, only_one);
1003  }
1004  } else {
1005  /* Alas multiple others in here */
1006  if (user) {
1007  if (ast_stream_and_wait(user->chan,
1008  there_are,
1009  "")) {
1010  return -1;
1011  }
1012  if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
1013  return -1;
1014  }
1015  if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
1016  return -1;
1017  }
1018  } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
1019  play_sound_file(conference, there_are);
1020  play_sound_number(conference, conference->activeusers - 1);
1021  play_sound_file(conference, other_in_party);
1022  }
1023  }
1024  return 0;
1025 }
struct ast_channel * chan
Definition: confbridge.h:277
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_sound_number(struct confbridge_conference *conference, int say_number)
Play number into the conference bridge.
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:248
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:1814
unsigned int activeusers
Definition: confbridge.h:249
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:8337
const char * ast_channel_language(const struct ast_channel *chan)
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
static int sound_file_exists(const char *filename)
int play_sound_file(struct confbridge_conference *conference, const char *filename)
Play sound file into conference bridge.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 4504 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data* async_datastore_data_alloc ( void  )
static

Definition at line 2085 of file app_confbridge.c.

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().

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

◆ async_datastore_data_destroy()

static void async_datastore_data_destroy ( void *  data)
static

Definition at line 2053 of file app_confbridge.c.

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

2054 {
2055  struct async_datastore_data *add = data;
2056 
2057  ast_mutex_destroy(&add->lock);
2058  ast_cond_destroy(&add->cond);
2059 
2060  ast_free(add);
2061 }
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_free(a)
Definition: astmm.h:182
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ async_delete_name_rec()

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

Definition at line 2492 of file app_confbridge.c.

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(), LOG_WARNING, confbridge_conference::name, confbridge_conference::playback_queue, and sound_file_exists().

Referenced by confbridge_exec().

2494 {
2495  struct async_delete_name_rec_task_data *atd;
2496 
2497  if (ast_strlen_zero(filename)) {
2498  return 0;
2499  } else if (!sound_file_exists(filename)) {
2500  return 0;
2501  }
2502 
2504  if (!atd) {
2505  return -1;
2506  }
2507 
2509  ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2510  conference->name, filename);
2512  return -1;
2513  }
2514 
2515  return 0;
2516 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:260
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static struct async_delete_name_rec_task_data * async_delete_name_rec_task_data_alloc(struct confbridge_conference *conference, const char *filename)
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.
static int async_delete_name_rec_task(void *data)
Delete user&#39;s name file asynchronously.
static void async_delete_name_rec_task_data_destroy(struct async_delete_name_rec_task_data *atd)
static int sound_file_exists(const char *filename)
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

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

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().

2481 {
2482  struct async_delete_name_rec_task_data *atd = data;
2483 
2484  ast_filedelete(atd->filename, NULL);
2485  ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2486  atd->conference->name, atd->filename);
2487 
2489  return 0;
2490 }
struct confbridge_conference * conference
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define LOG_DEBUG
Definition: logger.h:241
#define ast_log
Definition: astobj2.c:42
static void async_delete_name_rec_task_data_destroy(struct async_delete_name_rec_task_data *atd)
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

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

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

Referenced by async_delete_name_rec().

2451 {
2452  struct async_delete_name_rec_task_data *atd;
2453 
2454  atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2455  if (!atd) {
2456  return NULL;
2457  }
2458 
2459  /* Safe */
2460  strcpy(atd->filename, filename);
2461  atd->conference = conference;
2462 
2463  return atd;
2464 }
struct confbridge_conference * conference
#define NULL
Definition: resample.c:96
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193

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

References ast_free.

Referenced by async_delete_name_rec(), and async_delete_name_rec_task().

2467 {
2468  ast_free(atd);
2469 }
#define ast_free(a)
Definition: astmm.h:182

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

References async_play_sound_helper().

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

2284 {
2285  return async_play_sound_helper(conference, filename, -1, initiator);
2286 }
static int async_play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number, struct ast_channel *initiator)

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

References ast_log, ast_strlen_zero, ast_taskprocessor_push(), async_playback_task(), async_playback_task_data_alloc(), async_playback_task_data_destroy(), LOG_WARNING, confbridge_conference::name, confbridge_conference::playback_queue, and sound_file_exists().

Referenced by async_play_sound_file().

2250 {
2251  struct async_playback_task_data *aptd;
2252 
2253  /* Do not waste resources trying to play files that do not exist */
2254  if (ast_strlen_zero(filename)) {
2255  if (say_number < 0) {
2256  return 0;
2257  }
2258  } else if (!sound_file_exists(filename)) {
2259  return 0;
2260  }
2261 
2262  aptd = async_playback_task_data_alloc(conference, filename, say_number, initiator);
2263  if (!aptd) {
2264  return -1;
2265  }
2266 
2267  if (ast_taskprocessor_push(conference->playback_queue, async_playback_task, aptd)) {
2268  if (!ast_strlen_zero(filename)) {
2269  ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2270  filename, conference->name);
2271  } else {
2272  ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2273  say_number, conference->name);
2274  }
2276  return -1;
2277  }
2278 
2279  return 0;
2280 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:260
#define ast_strlen_zero(foo)
Definition: strings.h:52
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 void async_playback_task_data_destroy(struct async_playback_task_data *aptd)
#define ast_log
Definition: astobj2.c:42
static int async_playback_task(void *data)
Play an announcement into a confbridge asynchronously.
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.
static int sound_file_exists(const char *filename)
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

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

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, 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().

2289 {
2290  struct ast_datastore *async_datastore;
2291  struct async_datastore_data *add;
2292 
2293  ast_channel_lock(chan);
2294  async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2295  ast_channel_unlock(chan);
2296  if (!async_datastore) {
2297  return;
2298  }
2299 
2300  add = async_datastore->data;
2301 
2302  ast_mutex_lock(&add->lock);
2303  add->wait = 0;
2304  ast_cond_signal(&add->cond);
2305  ast_mutex_unlock(&add->lock);
2306 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_mutex_lock(a)
Definition: lock.h:187
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
static struct ast_datastore_info async_datastore_info
Datastore used for timing of async announcement playback.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
#define ast_mutex_unlock(a)
Definition: lock.h:188

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

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().

2234 {
2235  struct async_playback_task_data *aptd = data;
2236 
2237  /* Wait for the initiator to get back in the bridge or be hung up */
2238  if (aptd->initiator) {
2240  }
2241 
2242  playback_common(aptd->conference, aptd->filename, aptd->say_number);
2243 
2245  return 0;
2246 }
static void wait_for_initiator(struct ast_channel *initiator)
Wait for the initiator of an async playback to be ready.
struct ast_channel * initiator
static void async_playback_task_data_destroy(struct async_playback_task_data *aptd)
static void playback_common(struct confbridge_conference *conference, const char *filename, int say_number)
struct confbridge_conference * conference

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

References ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_malloc, hangup_data::conference, 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().

2144 {
2145  struct async_playback_task_data *aptd;
2146 
2147  aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
2148  if (!aptd) {
2149  return NULL;
2150  }
2151 
2152  /* Safe */
2153  strcpy(aptd->filename, filename);
2154  aptd->say_number = say_number;
2155 
2156  /* You may think that we need to bump the conference refcount since we are pushing
2157  * this task to the taskprocessor.
2158  *
2159  * In this case, that actually causes a problem. The destructor for the conference
2160  * pushes a hangup task into the taskprocessor and waits for it to complete before
2161  * continuing. If the destructor gets called from a taskprocessor task, we're
2162  * deadlocked.
2163  *
2164  * So is there a risk of the conference being freed out from under us? No. Since
2165  * the destructor pushes a task into the taskprocessor and waits for it to complete,
2166  * the destructor cannot free the conference out from under us. No further tasks
2167  * can be queued onto the taskprocessor after the hangup since no channels are referencing
2168  * the conference at that point any more.
2169  */
2170  aptd->conference = conference;
2171 
2172  aptd->initiator = initiator;
2173  if (initiator) {
2174  ast_channel_ref(initiator);
2175  ast_channel_lock(aptd->initiator);
2176  /* We don't really care if this fails. If the datastore fails to get set up
2177  * we'll still play the announcement. It's possible that the sound will be
2178  * clipped for the initiator, but that's not the end of the world.
2179  */
2182  }
2183 
2184  return aptd;
2185 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define NULL
Definition: resample.c:96
struct ast_channel * initiator
static int setup_async_playback_datastore(struct ast_channel *initiator)
Prepare the async playback datastore.
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
struct confbridge_conference * conference

◆ async_playback_task_data_destroy()

static void async_playback_task_data_destroy ( struct async_playback_task_data aptd)
static

Definition at line 2187 of file app_confbridge.c.

References ast_channel_cleanup, ast_free, and async_playback_task_data::initiator.

Referenced by async_play_sound_helper(), and async_playback_task().

2188 {
2190  ast_free(aptd);
2191 }
struct ast_channel * initiator
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_free(a)
Definition: astmm.h:182

◆ cli_mute_unmute_helper()

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

Definition at line 3574 of file app_confbridge.c.

References ast_cli_args::argv, ast_cli(), ast_cli_args::fd, and generic_mute_unmute_helper().

Referenced by handle_cli_confbridge_mute(), and handle_cli_confbridge_unmute().

3575 {
3576  int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
3577 
3578  if (res == -1) {
3579  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3580  return -1;
3581  } else if (res == -2) {
3582  if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3583  ast_cli(a->fd, "No participants found in conference %s\n", a->argv[2]);
3584  } else {
3585  ast_cli(a->fd, "No channel named '%s' found in conference %s\n", a->argv[3], a->argv[2]);
3586  }
3587  return -1;
3588  }
3589  ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
3590  return 0;
3591 }
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int mute
Definition: chan_alsa.c:144
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
static int generic_mute_unmute_helper(int mute, const char *conference_name, const char *chan_name)

◆ complete_confbridge_name()

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

Definition at line 3280 of file app_confbridge.c.

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

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

3281 {
3282  int which = 0;
3283  struct confbridge_conference *conference;
3284  char *res = NULL;
3285  int wordlen = strlen(word);
3286  struct ao2_iterator iter;
3287 
3289  while ((conference = ao2_iterator_next(&iter))) {
3290  if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3291  res = ast_strdup(conference->name);
3292  ao2_ref(conference, -1);
3293  break;
3294  }
3295  ao2_ref(conference, -1);
3296  }
3297  ao2_iterator_destroy(&iter);
3298 
3299  return res;
3300 }
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
The structure that represents a conference bridge.
Definition: confbridge.h:244
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

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

References confbridge_conference::active_list, ao2_cleanup, ao2_find, ast_channel_name(), AST_LIST_TRAVERSE, ast_strdup, confbridge_user::chan, hangup_data::conference, 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().

3303 {
3304  int which = 0;
3305  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3306  struct confbridge_user *user;
3307  char *res = NULL;
3308  int wordlen = strlen(word);
3309 
3310  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3311  if (!conference) {
3312  return NULL;
3313  }
3314 
3315  if (!strncasecmp("all", word, wordlen) && ++which > state) {
3316  return ast_strdup("all");
3317  }
3318 
3319  if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3320  return ast_strdup("participants");
3321  }
3322 
3323  {
3324  SCOPED_AO2LOCK(bridge_lock, conference);
3326  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3327  res = ast_strdup(ast_channel_name(user->chan));
3328  return res;
3329  }
3330  }
3332  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3333  res = ast_strdup(ast_channel_name(user->chan));
3334  return res;
3335  }
3336  }
3337  }
3338 
3339  return NULL;
3340 }
static char user[512]
struct ast_channel * chan
Definition: confbridge.h:277
struct confbridge_conference * conference
Definition: confbridge.h:272
#define OBJ_KEY
Definition: astobj2.h:1155
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
#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:911
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
short word

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

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

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

1446 {
1447  struct post_join_action *action;
1448  if (!(action = ast_calloc(1, sizeof(*action)))) {
1449  return -1;
1450  }
1451  action->func = func;
1452  AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1453  return 0;
1454 }
struct confbridge_user::@93 post_join_list
struct post_join_action::@92 list
int(* func)(struct confbridge_user *user)
Definition: confbridge.h:266
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

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

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

Referenced by join_active(), and join_unmarked().

4304 {
4305  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4306  conference->activeusers++;
4307 }
struct post_join_action::@92 list
struct confbridge_conference::@90 active_list
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
unsigned int activeusers
Definition: confbridge.h:249

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

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

Referenced by join_marked().

4310 {
4311  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4312  conference->activeusers++;
4313  conference->markedusers++;
4314 }
struct post_join_action::@92 list
unsigned int markedusers
Definition: confbridge.h:250
struct confbridge_conference::@90 active_list
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
unsigned int activeusers
Definition: confbridge.h:249

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

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

Referenced by conf_default_join_waitmarked().

4317 {
4318  AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4319  conference->waitingusers++;
4320 }
struct post_join_action::@92 list
unsigned int waitingusers
Definition: confbridge.h:251
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct confbridge_conference::@91 waiting_list

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

References ao2_lock, ao2_unlink, ao2_unlock, ast_context_remove_extension(), ast_strlen_zero, confbridge_conference::b_profile, conf_stop_record(), 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().

1474 {
1475  struct pbx_find_info q = { .stacklen = 0 };
1476 
1477  /* Called with a reference to conference */
1478  ao2_unlink(conference_bridges, conference);
1479  send_conf_end_event(conference);
1480  if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1481  pbx_find_extension(NULL, NULL, &q, conference->b_profile.regcontext,
1482  conference->name, 1, NULL, "", E_MATCH)) {
1484  conference->name, 1, NULL);
1485  }
1486  ao2_lock(conference);
1487  conf_stop_record(conference);
1488  ao2_unlock(conference);
1489 }
static void send_conf_end_event(struct confbridge_conference *conference)
static int conf_stop_record(struct confbridge_conference *conference)
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4952
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
int stacklen
Definition: extconf.h:238
char regcontext[AST_MAX_CONTEXT]
Definition: confbridge.h:237
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
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

◆ 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
confbridge_nameThe name to search for
Returns
ConfBridge (which must be unreffed) or NULL.

Definition at line 787 of file app_confbridge.c.

References ao2_find, and OBJ_KEY.

Referenced by confbridge_publish_manager_event().

788 {
789  return ao2_find(conference_bridges, conference_name, OBJ_KEY);
790 }
#define OBJ_KEY
Definition: astobj2.h:1155
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ conf_get_pin()

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

Definition at line 2350 of file app_confbridge.c.

References ast_app_getdata(), ast_channel_language(), AST_DIGIT_ANY, ast_streamfile(), ast_waitstream(), confbridge_user::b_profile, conf_get_sound(), CONF_SOUND_GET_PIN, CONF_SOUND_INVALID_PIN, len(), MAX_PIN, user_profile::pin, bridge_profile::sounds, tmp(), and confbridge_user::u_profile.

Referenced by confbridge_exec().

2351 {
2352  char pin_guess[MAX_PIN+1] = { 0, };
2353  const char *pin = user->u_profile.pin;
2354  char *tmp = pin_guess;
2355  int i, res;
2356  unsigned int len = MAX_PIN;
2357 
2358  /*
2359  * NOTE: We have not joined a conference yet so we have to use
2360  * the bridge profile requested by the user.
2361  */
2362 
2363  /* give them three tries to get the pin right */
2364  for (i = 0; i < 3; i++) {
2365  if (ast_app_getdata(chan,
2367  tmp, len, 0) >= 0) {
2368  if (!strcasecmp(pin, pin_guess)) {
2369  return 0;
2370  }
2371  }
2372  ast_streamfile(chan,
2374  ast_channel_language(chan));
2375  res = ast_waitstream(chan, AST_DIGIT_ANY);
2376  if (res > 0) {
2377  /* Account for digit already read during ivalid pin playback
2378  * resetting pin buf. */
2379  pin_guess[0] = res;
2380  pin_guess[1] = '\0';
2381  tmp = pin_guess + 1;
2382  len = MAX_PIN - 1;
2383  } else {
2384  /* reset pin buf as empty buffer. */
2385  tmp = pin_guess;
2386  len = MAX_PIN;
2387  }
2388  }
2389  return -1;
2390 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_DIGIT_ANY
Definition: file.h:48
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 tmp()
Definition: bt_open.c:389
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
char pin[MAX_PIN]
Definition: confbridge.h:154
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct bridge_profile b_profile
Definition: confbridge.h:273
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:197
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
struct user_profile u_profile
Definition: confbridge.h:274
#define MAX_PIN
Definition: app_meetme.c:820

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

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().

527 {
528  switch (sound) {
530  return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
531  case CONF_SOUND_HAS_LEFT:
532  return S_OR(custom_sounds->hasleft, "conf-hasleft");
533  case CONF_SOUND_KICKED:
534  return S_OR(custom_sounds->kicked, "conf-kicked");
535  case CONF_SOUND_MUTED:
536  return S_OR(custom_sounds->muted, "conf-muted");
537  case CONF_SOUND_UNMUTED:
538  return S_OR(custom_sounds->unmuted, "conf-unmuted");
540  return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
542  return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
543  case CONF_SOUND_ONLY_ONE:
544  return S_OR(custom_sounds->onlyone, "conf-onlyone");
546  return S_OR(custom_sounds->thereare, "conf-thereare");
548  return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
550  return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
552  return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
554  return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
555  case CONF_SOUND_GET_PIN:
556  return S_OR(custom_sounds->getpin, "conf-getpin");
558  return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
560  return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
561  case CONF_SOUND_LOCKED:
562  return S_OR(custom_sounds->locked, "conf-locked");
564  return S_OR(custom_sounds->lockednow, "conf-lockednow");
566  return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
568  return S_OR(custom_sounds->errormenu, "conf-errormenu");
569  case CONF_SOUND_JOIN:
570  return S_OR(custom_sounds->join, "confbridge-join");
571  case CONF_SOUND_LEAVE:
572  return S_OR(custom_sounds->leave, "confbridge-leave");
574  return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
576  return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
577  case CONF_SOUND_BEGIN:
578  return S_OR(custom_sounds->begin, "confbridge-conf-begin");
579  }
580 
581  return "";
582 }
const ast_string_field unlockednow
Definition: confbridge.h:222
const ast_string_field thereare
Definition: confbridge.h:222
const ast_string_field join
Definition: confbridge.h:222
const ast_string_field otherinparty
Definition: confbridge.h:222
const ast_string_field onlyone
Definition: confbridge.h:222
const ast_string_field hasjoin
Definition: confbridge.h:222
const ast_string_field begin
Definition: confbridge.h:222
const ast_string_field errormenu
Definition: confbridge.h:222
const ast_string_field binauraloff
Definition: confbridge.h:222
const ast_string_field waitforleader
Definition: confbridge.h:222
const ast_string_field getpin
Definition: confbridge.h:222
const ast_string_field participantsmuted
Definition: confbridge.h:222
const ast_string_field leave
Definition: confbridge.h:222
const ast_string_field lockednow
Definition: confbridge.h:222
const ast_string_field binauralon
Definition: confbridge.h:222
const ast_string_field participantsunmuted
Definition: confbridge.h:222
const ast_string_field unmuted
Definition: confbridge.h:222
const ast_string_field invalidpin
Definition: confbridge.h:222
const ast_string_field onlyperson
Definition: confbridge.h:222
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const ast_string_field muted
Definition: confbridge.h:222
const ast_string_field leaderhasleft
Definition: confbridge.h:222
const ast_string_field kicked
Definition: confbridge.h:222
const ast_string_field locked
Definition: confbridge.h:222
const ast_string_field placeintoconf
Definition: confbridge.h:222
const ast_string_field hasleft
Definition: confbridge.h:222

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

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

Referenced by menu_hook_callback().

3218 {
3219  /* See if music on hold is playing */
3220  conf_moh_suspend(user);
3221 
3222  /* execute the list of actions associated with this menu entry */
3223  execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3224 
3225  /* See if music on hold needs to be started back up again */
3226  conf_moh_unsuspend(user);
3227 
3228  async_play_sound_ready(bridge_channel->chan);
3229 
3230  return 0;
3231 }
static void conf_moh_unsuspend(struct confbridge_user *user)
static void conf_moh_suspend(struct confbridge_user *user)
struct confbridge_conference * conference
Definition: confbridge.h:272
void async_play_sound_ready(struct ast_channel *chan)
Indicate the initiator of an async sound file is ready for it to play.
static int 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)
struct ast_channel * chan

◆ 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
Return values
0success
-1failure

Definition at line 1457 of file app_confbridge.c.

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

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

1458 {
1459  ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference->name);
1460 }
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
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

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

References ast_test_flag, confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_WAIT_FOR_LEADER, confbridge_user::conference, play_prompt_to_user(), bridge_profile::sounds, confbridge_user::u_profile, and USER_OPT_QUIET.

Referenced by conf_default_join_waitmarked().

1422 {
1423  /* If we have not been quieted play back that they are waiting for the leader */
1426  /* user hungup while the sound was playing */
1427  return -1;
1428  }
1429  return 0;
1430 }
struct confbridge_conference * conference
Definition: confbridge.h:272
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
struct bridge_profile b_profile
Definition: confbridge.h:248
struct user_profile u_profile
Definition: confbridge.h:274
static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
Play back an audio file to a channel.

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

References ast_test_flag, confbridge_conference::b_profile, conf_get_sound(), CONF_SOUND_ONLY_PERSON, confbridge_user::conference, play_prompt_to_user(), bridge_profile::sounds, confbridge_user::u_profile, USER_OPT_NOONLYPERSON, and USER_OPT_QUIET.

Referenced by join_marked(), and join_unmarked().

1433 {
1434  /* If audio prompts have not been quieted or this prompt quieted play it on out */
1436  if (play_prompt_to_user(user,
1438  /* user hungup while the sound was playing */
1439  return -1;
1440  }
1441  }
1442  return 0;
1443 }
struct confbridge_conference * conference
Definition: confbridge.h:272
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
struct bridge_profile b_profile
Definition: confbridge.h:248
struct user_profile u_profile
Definition: confbridge.h:274
static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
Play back an audio file to a channel.

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

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

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

1463 {
1464  /* If we are the second participant we may need to stop music on hold on the first */
1465  struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1466 
1467  if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1468  conf_moh_stop(first_user);
1469  }
1470  conf_update_user_mute(first_user);
1471 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define ast_test_flag(p, flag)
Definition: utils.h:63
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
struct confbridge_conference::@90 active_list
void conf_moh_stop(struct confbridge_user *user)
Stop MOH for the conference user.
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct user_profile u_profile
Definition: confbridge.h:274

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

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, hangup_data::conference, confbridge_conference::name, NULL, OBJ_KEY, RAII_VAR, send_conf_stasis(), confbridge_user::talking, confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by confbridge_exec().

2323 {
2324  struct confbridge_user *user = hook_pvt;
2326  struct ast_json *talking_extras;
2327 
2328  conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2329  if (!conference) {
2330  /* Remove the hook since the conference does not exist. */
2331  return -1;
2332  }
2333 
2334  ao2_lock(conference);
2335  user->talking = talking;
2336  ao2_unlock(conference);
2337 
2338  talking_extras = ast_json_pack("{s: s, s: b}",
2339  "talking_status", talking ? "on" : "off",
2340  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2341  if (!talking_extras) {
2342  return 0;
2343  }
2344 
2345  send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2346  ast_json_unref(talking_extras);
2347  return 0;
2348 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#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:911
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
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)
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
structure to hold users read from users.conf
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_message_type * confbridge_talking_type(void)
get the confbridge talking stasis message type
Abstract JSON element (object, array, string, int, ...).
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct user_profile u_profile
Definition: confbridge.h:274
unsigned int talking
Definition: confbridge.h:284
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

◆ conf_is_recording()

static int conf_is_recording ( struct confbridge_conference conference)
static

Definition at line 803 of file app_confbridge.c.

References NULL, and confbridge_conference::record_chan.

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

804 {
805  return conference->record_chan != NULL;
806 }
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:255

◆ conf_moh_start()

void conf_moh_start ( struct confbridge_user user)

Start MOH for the conference user.

Parameters
userConference user to start MOH on.
Returns
Nothing

Definition at line 1360 of file app_confbridge.c.

References ast_bridge_lock, ast_bridge_suspend(), ast_bridge_unlock, ast_bridge_unsuspend(), ast_moh_start(), confbridge_conference::bridge, confbridge_user::chan, confbridge_user::conference, user_profile::moh_class, NULL, confbridge_user::playing_moh, confbridge_user::suspended_moh, and confbridge_user::u_profile.

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

1361 {
1362  user->playing_moh = 1;
1363  if (!user->suspended_moh) {
1364  int in_bridge;
1365 
1366  /*
1367  * Locking the ast_bridge here is the only way to hold off the
1368  * call to ast_bridge_join() in confbridge_exec() from
1369  * interfering with the bridge and MOH operations here.
1370  */
1372 
1373  /*
1374  * Temporarily suspend the user from the bridge so we have
1375  * control to start MOH if needed.
1376  */
1377  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1378  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1379  if (in_bridge) {
1380  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1381  }
1382 
1384  }
1385 }
struct ast_channel * chan
Definition: confbridge.h:277
unsigned int playing_moh
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:272
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3089
unsigned int suspended_moh
Definition: confbridge.h:280
#define NULL
Definition: resample.c:96
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:7866
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3068
struct user_profile u_profile
Definition: confbridge.h:274
char moh_class[128]
Definition: confbridge.h:155
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ conf_moh_stop()

void conf_moh_stop ( struct confbridge_user user)

Stop MOH for the conference user.

Parameters
userConference user to stop MOH on.
Returns
Nothing

Definition at line 1333 of file app_confbridge.c.

References ast_bridge_lock, ast_bridge_suspend(), ast_bridge_unlock, ast_bridge_unsuspend(), ast_moh_stop(), confbridge_conference::bridge, confbridge_user::chan, confbridge_user::conference, confbridge_user::playing_moh, and confbridge_user::suspended_moh.

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

1334 {
1335  user->playing_moh = 0;
1336  if (!user->suspended_moh) {
1337  int in_bridge;
1338 
1339  /*
1340  * Locking the ast_bridge here is the only way to hold off the
1341  * call to ast_bridge_join() in confbridge_exec() from
1342  * interfering with the bridge and MOH operations here.
1343  */
1345 
1346  /*
1347  * Temporarily suspend the user from the bridge so we have
1348  * control to stop MOH if needed.
1349  */
1350  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1351  ast_moh_stop(user->chan);
1352  if (in_bridge) {
1353  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1354  }
1355 
1357  }
1358 }
struct ast_channel * chan
Definition: confbridge.h:277
unsigned int playing_moh
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:272
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3089
unsigned int suspended_moh
Definition: confbridge.h:280
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3068
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ conf_moh_suspend()

static void conf_moh_suspend ( struct confbridge_user user)
static

Definition at line 1412 of file app_confbridge.c.

References ao2_lock, ao2_unlock, ast_moh_stop(), confbridge_user::chan, confbridge_user::conference, confbridge_user::playing_moh, and confbridge_user::suspended_moh.

Referenced by conf_handle_dtmf().

1413 {
1414  ao2_lock(user->conference);
1415  if (user->suspended_moh++ == 0 && user->playing_moh) {
1416  ast_moh_stop(user->chan);
1417  }
1418  ao2_unlock(user->conference);
1419 }
struct ast_channel * chan
Definition: confbridge.h:277
unsigned int playing_moh
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:272
unsigned int suspended_moh
Definition: confbridge.h:280
#define ao2_unlock(a)
Definition: astobj2.h:730
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ao2_lock(a)
Definition: astobj2.h:718

◆ conf_moh_unsuspend()

static void conf_moh_unsuspend ( struct confbridge_user user)
static

Definition at line 1395 of file app_confbridge.c.

References ao2_lock, ao2_unlock, ast_moh_start(), confbridge_user::chan, confbridge_user::conference, user_profile::moh_class, NULL, confbridge_user::playing_moh, confbridge_user::suspended_moh, and confbridge_user::u_profile.

Referenced by conf_handle_dtmf(), and confbridge_exec().

1396 {
1397  ao2_lock(user->conference);
1398  if (--user->suspended_moh == 0 && user->playing_moh) {
1399  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1400  }
1401  ao2_unlock(user->conference);
1402 }
struct ast_channel * chan
Definition: confbridge.h:277
unsigned int playing_moh
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:272
unsigned int suspended_moh
Definition: confbridge.h:280
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_lock(a)
Definition: astobj2.h:718
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:7866
struct user_profile u_profile
Definition: confbridge.h:274
char moh_class[128]
Definition: confbridge.h:155

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

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

Referenced by transition_to_single(), and transition_to_single_marked().

4336 {
4337  struct confbridge_user *only_user = AST_LIST_FIRST(&conference->active_list);
4338 
4339  /* Turn on MOH if the single participant is set up for it */
4340  if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4341  conf_moh_start(only_user);
4342  }
4343  conf_update_user_mute(only_user);
4344 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define ast_test_flag(p, flag)
Definition: utils.h:63
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
struct confbridge_conference::@90 active_list
void conf_moh_start(struct confbridge_user *user)
Start MOH for the conference user.
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct user_profile u_profile
Definition: confbridge.h:274

◆ conf_rec_name()

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

Definition at line 2399 of file app_confbridge.c.

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, confbridge_user::chan, errno, LOG_WARNING, confbridge_user::name_rec_location, NULL, PATH_MAX, THRESHOLD_SILENCE, confbridge_user::u_profile, and USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW.

Referenced by confbridge_exec().

2400 {
2401  char destdir[PATH_MAX];
2402  int res;
2403  int duration = 20;
2404 
2405  snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2406 
2407  if (ast_mkdir(destdir, 0777) != 0) {
2408  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2409  return -1;
2410  }
2411  snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2412  "%s/confbridge-name-%s-%s", destdir,
2413  conf_name, ast_channel_uniqueid(user->chan));
2414 
2416  res = ast_play_and_record(user->chan,
2417  "vm-rec-name",
2418  user->name_rec_location,
2419  10,
2420  "sln",
2421  &duration,
2422  NULL,
2424  0,
2425  NULL);
2426  } else {
2427  res = ast_record_review(user->chan,
2428  "vm-rec-name",
2429  user->name_rec_location,
2430  10,
2431  "sln",
2432  &duration,
2433  NULL);
2434  }
2435 
2436  if (res == -1) {
2438  user->name_rec_location[0] = '\0';
2439  return -1;
2440  }
2441  return 0;
2442 }
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
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:2489
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int errno
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:1997
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
char name_rec_location[PATH_MAX]
Definition: confbridge.h:276
#define PATH_MAX
Definition: asterisk.h:40
struct user_profile u_profile
Definition: confbridge.h:274
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231

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

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

Referenced by leave_active(), and leave_unmarked().

4323 {
4324  AST_LIST_REMOVE(&conference->active_list, user, list);
4325  conference->activeusers--;
4326 }
struct confbridge_user::@94 list
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
struct confbridge_conference::@90 active_list
unsigned int activeusers
Definition: confbridge.h:249

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

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

Referenced by leave_marked().

4329 {
4330  AST_LIST_REMOVE(&conference->active_list, user, list);
4331  conference->activeusers--;
4332  conference->markedusers--;
4333 }
struct confbridge_user::@94 list
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int markedusers
Definition: confbridge.h:250
struct confbridge_conference::@90 active_list
unsigned int activeusers
Definition: confbridge.h:249

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

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

Referenced by conf_default_leave_waitmarked().

4347 {
4348  AST_LIST_REMOVE(&conference->waiting_list, user, list);
4349  conference->waitingusers--;
4350 }
struct confbridge_user::@94 list
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int waitingusers
Definition: confbridge.h:251
struct confbridge_conference::@91 waiting_list

◆ conf_start_record()

static int conf_start_record ( struct confbridge_conference conference)
static

Definition at line 851 of file app_confbridge.c.

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, bridge_profile::name, confbridge_conference::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().

852 {
853  struct ast_app *mixmonapp;
854  struct ast_channel *chan;
855  struct ast_format_cap *cap;
856  struct ast_bridge_features *features;
857 
858  if (conf_is_recording(conference)) {
859  return -1;
860  }
861 
862  mixmonapp = pbx_findapp("MixMonitor");
863  if (!mixmonapp) {
864  ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
865  return -1;
866  }
867 
868  features = ast_bridge_features_new();
869  if (!features) {
870  return -1;
871  }
873 
875  if (!cap) {
876  ast_bridge_features_destroy(features);
877  return -1;
878  }
880 
881  /* Create the recording channel. */
882  chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
883  ao2_ref(cap, -1);
884  if (!chan) {
885  ast_bridge_features_destroy(features);
886  return -1;
887  }
888 
889  /* Start recording. */
890  set_rec_filename(conference, &conference->record_filename,
891  is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
892  ast_answer(chan);
893  pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
894 
895  /* Put the channel into the conference bridge. */
896  ast_channel_ref(chan);
897  conference->record_chan = chan;
898  if (ast_bridge_impart(conference->bridge, chan, NULL, features,
900  ast_hangup(chan);
901  ast_channel_unref(chan);
902  conference->record_chan = NULL;
903  return -1;
904  }
905 
906  ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
907  send_start_record_event(conference);
908 
909  return 0;
910 }
Main Channel structure associated with a channel.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
char rec_file[PATH_MAX]
Definition: confbridge.h:228
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:255
struct ast_str * orig_rec_file
Definition: confbridge.h:257
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
struct bridge_profile b_profile
Definition: confbridge.h:248
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:6444
struct ast_flags feature_flags
#define ast_log
Definition: astobj2.c:42
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:1924
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static int conf_is_recording(struct confbridge_conference *conference)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750
static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
ast_app: A registered application
Definition: pbx_app.c:45
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
struct ast_str * record_filename
Definition: confbridge.h:256
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
static void send_start_record_event(struct confbridge_conference *conference)
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ conf_stop_record()

static int conf_stop_record ( struct confbridge_conference conference)
static

Definition at line 819 of file app_confbridge.c.

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

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

820 {
821  struct ast_channel *chan;
822  struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
823 
824  if (!conf_is_recording(conference)) {
825  return -1;
826  }
827 
828  /* Remove the recording channel from the conference bridge. */
829  chan = conference->record_chan;
830  conference->record_chan = NULL;
831  ast_queue_frame(chan, &f);
832  ast_channel_unref(chan);
833 
834  ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
835  send_stop_record_event(conference);
836 
837  return 0;
838 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:255
struct bridge_profile b_profile
Definition: confbridge.h:248
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&#39;s frame queue.
Definition: channel.c:1139
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
static int conf_is_recording(struct confbridge_conference *conference)
Data structure associated with a single frame of data.

◆ 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.
Returns
Nothing

Definition at line 1275 of file app_confbridge.c.

References ast_channel_name(), ast_debug, ast_test_flag, ast_test_suite_event_notify, confbridge_conference::b_profile, confbridge_user::chan, confbridge_user::conference, confbridge_user::features, confbridge_conference::markedusers, ast_bridge_features::mute, confbridge_user::muted, bridge_profile::name, confbridge_user::playing_moh, confbridge_user::u_profile, 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().

1276 {
1277  int mute_user;
1278  int mute_system;
1279  int mute_effective;
1280 
1281  /* User level mute request. */
1282  mute_user = user->muted;
1283 
1284  /* System level mute request. */
1285  mute_system = user->playing_moh
1286  /*
1287  * Do not allow waitmarked users to talk to anyone unless there
1288  * is a marked user present.
1289  */
1290  || (!user->conference->markedusers
1292 
1293  mute_effective = mute_user || mute_system;
1294 
1295  ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1296  ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1297  mute_user, mute_system);
1298  user->features.mute = mute_effective;
1299  ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1300  "Mode: %s\r\n"
1301  "Conference: %s\r\n"
1302  "Channel: %s",
1303  mute_effective ? "muted" : "unmuted",
1304  user->conference->b_profile.name,
1305  ast_channel_name(user->chan));
1306 }
struct ast_channel * chan
Definition: confbridge.h:277
unsigned int playing_moh
Definition: confbridge.h:283
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
unsigned int markedusers
Definition: confbridge.h:250
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
unsigned int muted
Definition: confbridge.h:281
struct ast_bridge_features features
Definition: confbridge.h:278
const char * ast_channel_name(const struct ast_channel *chan)
struct user_profile u_profile
Definition: confbridge.h:274

◆ confbridge_exec()

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

The ConfBridge application.

Definition at line 2544 of file app_confbridge.c.

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_user::b_profile, confbridge_conference::bridge, confbridge_user::chan, hangup_data::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, hangup_data::conference, confbridge_hook_data::conference, DEFAULT_BRIDGE_PROFILE, DEFAULT_MENU_PROFILE, DEFAULT_SILENCE_THRESHOLD, DEFAULT_TALKING_THRESHOLD, DEFAULT_USER_PROFILE, ast_bridge_tech_optimizations::drop_silence, ast_bridge_features::dtmf_passthrough, confbridge_user::features, handle_video_on_exit(), handle_video_on_join(), confbridge_hook_data::hook_type, join_callback(), join_conference_bridge(), confbridge_user::kicked, bridge_profile::language, leave_conference(), LOG_ERROR, LOG_WARNING, MAX_CONF_NAME, confbridge_user::name_rec_location, NULL, parse(), pbx_builtin_setvar_helper(), user_profile::pin, play_sound_file(), quiet, send_event_hook_callback(), ast_bridge_tech_optimizations::silence_threshold, user_profile::silence_threshold, bridge_profile::sounds, ast_bridge_tech_optimizations::talking_threshold, user_profile::talking_threshold, confbridge_user::tech_args, ast_bridge_features::text_messaging, user_profile::timeout, confbridge_user::u_profile, user, confbridge_hook_data::user, USER_OPT_ANNOUNCE_JOIN_LEAVE, USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW, USER_OPT_ANSWER_CHANNEL, USER_OPT_DENOISE, USER_OPT_DROP_SILENCE, USER_OPT_DTMF_PASS, USER_OPT_JITTERBUFFER, USER_OPT_MARKEDUSER, USER_OPT_QUIET, USER_OPT_TALKER_DETECT, USER_OPT_TEXT_MESSAGING, and user_timeout().

Referenced by load_module().

2545 {
2546  int res = 0, volume_adjustments[2];
2547  int quiet = 0;
2548  int async_delete_task_pushed = 0;
2549  char *parse;
2550  const char *b_profile_name = NULL;
2551  const char *u_profile_name = NULL;
2552  const char *menu_profile_name = NULL;
2553  struct confbridge_conference *conference = NULL;
2554  struct confbridge_user user = {
2555  .chan = chan,
2556  .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2557  .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2558  .tech_args.drop_silence = 0,
2559  };
2560  struct confbridge_hook_data *join_hook_data;
2561  struct confbridge_hook_data *leave_hook_data;
2562 
2564  AST_APP_ARG(conf_name);
2565  AST_APP_ARG(b_profile_name);
2566  AST_APP_ARG(u_profile_name);
2567  AST_APP_ARG(menu_profile_name);
2568  );
2569 
2570  if (ast_bridge_features_init(&user.features)) {
2571  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2572  res = -1;
2573  goto confbridge_cleanup;
2574  }
2575 
2576  /* We need to make a copy of the input string if we are going to modify it! */
2577  parse = ast_strdupa(data);
2578 
2579  AST_STANDARD_APP_ARGS(args, parse);
2580 
2581  if (ast_strlen_zero(args.conf_name)) {
2582  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2583  ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2584  res = -1;
2585  goto confbridge_cleanup;
2586  }
2587 
2588  if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2589  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2590  ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2591  res = -1;
2592  goto confbridge_cleanup;
2593  }
2594 
2595  /* bridge profile name */
2596  if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2597  b_profile_name = args.b_profile_name;
2598  }
2599  if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2600  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2601  ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2602  b_profile_name : DEFAULT_BRIDGE_PROFILE);
2603  res = -1;
2604  goto confbridge_cleanup;
2605  }
2606 
2607  /* user profile name */
2608  if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2609  u_profile_name = args.u_profile_name;
2610  }
2611  if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2612  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2613  ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2614  u_profile_name : DEFAULT_USER_PROFILE);
2615  res = -1;
2616  goto confbridge_cleanup;
2617  }
2618 
2619  /* If channel hasn't been answered already, answer it, unless we're explicitly not supposed to */
2621  ast_answer(chan);
2622  }
2623 
2624  quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2625 
2626  /* ask for a PIN immediately after finding user profile. This has to be
2627  * prompted for requardless of quiet setting. */
2628  if (!ast_strlen_zero(user.u_profile.pin)) {
2629  if (conf_get_pin(chan, &user)) {
2630  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2631  res = -1; /* invalid PIN */
2632  goto confbridge_cleanup;
2633  }
2634  }
2635 
2636  /* See if we need them to record a intro name */
2637  if (!quiet &&
2640  if (conf_rec_name(&user, args.conf_name)) {
2641  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2642  res = -1; /* Hangup during name recording */
2643  goto confbridge_cleanup;
2644  }
2645  }
2646 
2647  /* menu name */
2648  if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2649  menu_profile_name = args.menu_profile_name;
2650  }
2651 
2652  if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2653  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2654  ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2655  menu_profile_name : DEFAULT_MENU_PROFILE);
2656  res = -1;
2657  goto confbridge_cleanup;
2658  }
2659 
2660  /* Set if DTMF should pass through for this user or not */
2662  user.features.dtmf_passthrough = 1;
2663  } else {
2664  user.features.dtmf_passthrough = 0;
2665  }
2666 
2667  /* Set if text messaging is enabled for this user or not */
2669  user.features.text_messaging = 1;
2670  } else {
2671  user.features.text_messaging = 0;
2672  }
2673 
2674  /* Set dsp threshold values if present */
2675  if (user.u_profile.talking_threshold) {
2677  }
2678  if (user.u_profile.silence_threshold) {
2680  }
2681 
2682  /* Set a talker indicate call back if talking detection is requested */
2686  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2687  res = -1;
2688  goto confbridge_cleanup;
2689  }
2690  }
2691 
2692  /* Look for a conference bridge matching the provided name */
2693  if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2694  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2695  res = -1;
2696  goto confbridge_cleanup;
2697  }
2698 
2699  /* Keep a copy of volume adjustments so we can restore them later if need be */
2700  volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2701  volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2702 
2704  user.tech_args.drop_silence = 1;
2705  }
2706 
2708  ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2709  }
2710 
2712  ast_func_write(chan, "DENOISE(rx)", "on");
2713  }
2714 
2715  /* if this user has a intro, play it before entering */
2716  if (!ast_strlen_zero(user.name_rec_location)) {
2717  ast_autoservice_start(chan);
2718  play_sound_file(conference, user.name_rec_location);
2719  play_sound_file(conference,
2721  ast_autoservice_stop(chan);
2722  }
2723 
2724  /* Play the Join sound to both the conference and the user entering. */
2725  if (!quiet) {
2726  const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2727 
2728  if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2729  ast_stream_and_wait(chan, join_sound, "");
2730  ast_autoservice_start(chan);
2731  play_sound_file(conference, join_sound);
2732  ast_autoservice_stop(chan);
2733  } else {
2734  async_play_sound_file(conference, join_sound, chan);
2735  }
2736  }
2737 
2738  if (user.u_profile.timeout) {
2740  0,
2741  user.u_profile.timeout * 1000,
2742  user_timeout,
2743  NULL,
2744  NULL,
2746  }
2747 
2748  /* See if we need to automatically set this user as a video source or not */
2750 
2751  conf_moh_unsuspend(&user);
2752 
2753  join_hook_data = ast_malloc(sizeof(*join_hook_data));
2754  if (!join_hook_data) {
2755  res = -1;
2756  goto confbridge_cleanup;
2757  }
2758  join_hook_data->user = &user;
2759  join_hook_data->conference = conference;
2760  join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2762  join_hook_data, ast_free_ptr, 0);
2763  if (res) {
2764  ast_free(join_hook_data);
2765  ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2766  goto confbridge_cleanup;
2767  }
2768 
2769  leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2770  if (!leave_hook_data) {
2771  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2772  res = -1;
2773  goto confbridge_cleanup;
2774  }
2775  leave_hook_data->user = &user;
2776  leave_hook_data->conference = conference;
2777  leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2779  leave_hook_data, ast_free_ptr, 0);
2780  if (res) {
2781  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2782  ast_free(leave_hook_data);
2783  ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2784  goto confbridge_cleanup;
2785  }
2786 
2789  }
2790 
2791  ast_bridge_join(conference->bridge,
2792  chan,
2793  NULL,
2794  &user.features,
2795  &user.tech_args,
2796  0);
2797 
2798  /* This is a catch-all in case joining the bridge failed or for some reason
2799  * an async announcement got queued up and hasn't been told to play yet
2800  */
2801  async_play_sound_ready(chan);
2802 
2803  if (!user.kicked && ast_check_hangup(chan)) {
2804  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2805  }
2806 
2807  /* if we're shutting down, don't attempt to do further processing */
2808  if (ast_shutting_down()) {
2809  /*
2810  * Not taking any new calls at this time. We cannot create
2811  * the announcer channel if this is the first channel into
2812  * the conference and we certainly cannot create any
2813  * recording channel.
2814  */
2815  leave_conference(&user);
2816  conference = NULL;
2817  goto confbridge_cleanup;
2818  }
2819 
2820  /* If this user was a video source, we need to clean up and possibly pick a new source. */
2821  handle_video_on_exit(conference, user.chan);
2822 
2823  /* if this user has a intro, play it when leaving */
2824  if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2825  async_play_sound_file(conference, user.name_rec_location, NULL);
2826  async_play_sound_file(conference,
2828  async_delete_name_rec(conference, user.name_rec_location);
2829  async_delete_task_pushed = 1;
2830  }
2831 
2832  /* play the leave sound */
2833  if (!quiet) {
2834  const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2835  async_play_sound_file(conference, leave_sound, NULL);
2836  }
2837 
2838  /* If the user was kicked from the conference play back the audio prompt for it */
2839  if (!quiet && user.kicked) {
2840  res = ast_stream_and_wait(chan,
2842  "");
2843  }
2844 
2845  /* Easy as pie, depart this channel from the conference bridge */
2846  leave_conference(&user);
2847  conference = NULL;
2848 
2849  /* Restore volume adjustments to previous values in case they were changed */
2850  if (volume_adjustments[0]) {
2851  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2852  }
2853  if (volume_adjustments[1]) {
2854  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2855  }
2856 
2857 confbridge_cleanup:
2858  if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2860  }
2863  return res;
2864 }
static char user[512]
static void conf_moh_unsuspend(struct confbridge_user *user)
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:1346
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
int ast_shutting_down(void)
Definition: asterisk.c:1834
static int join_callback(struct ast_bridge_channel *bridge_channel, void *ignore)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
struct ast_channel * chan
Definition: confbridge.h:277
static int user_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
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:1371
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:3348
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
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)
Unregisters a handler for a built in interval feature.
Definition: bridge.c:3338
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
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:3358
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&#39;s name and store that profile in result structure.
static int conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
static struct confbridge_conference * join_conference_bridge(const char *conference_name, struct confbridge_user *user)
Join a conference bridge.
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
static void handle_video_on_exit(struct confbridge_conference *conference, struct ast_channel *chan)
static int conf_get_pin(struct ast_channel *chan, struct confbridge_user *user)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
unsigned int silence_threshold
Definition: confbridge.h:162
struct confbridge_conference * conference
const char * args
static const char app[]
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
void async_play_sound_ready(struct ast_channel *chan)
Indicate the initiator of an async sound file is ready for it to play.
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int quiet
Definition: ael_main.c:123
unsigned int text_messaging
#define ast_log
Definition: astobj2.c:42
int async_play_sound_file(struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
Play sound file into conference bridge asynchronously.
#define DEFAULT_TALKING_THRESHOLD
Definition: confbridge.h:46
void conf_bridge_profile_destroy(struct bridge_profile *b_profile)
Destroy a bridge profile found by &#39;conf_find_bridge_profile&#39;.
static int async_delete_name_rec(struct confbridge_conference *conference, const char *filename)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:3382
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
char language[MAX_LANGUAGE]
Definition: confbridge.h:227
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
char pin[MAX_PIN]
Definition: confbridge.h:154
unsigned int dtmf_passthrough
struct confbridge_user * user
#define LOG_ERROR
Definition: logger.h:285
#define MAX_CONF_NAME
Definition: confbridge.h:35
static void handle_video_on_join(struct confbridge_conference *conference, struct ast_channel *chan, int marked)
unsigned int talking_threshold
Definition: confbridge.h:160
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
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&#39;s name and apply the menu in DTMF hooks. ...
#define ast_free(a)
Definition: astmm.h:182
unsigned int timeout
Definition: confbridge.h:164
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:1814
struct bridge_profile b_profile
Definition: confbridge.h:273
struct ast_bridge_features features
Definition: confbridge.h:278
The structure that represents a conference bridge.
Definition: confbridge.h:244
static int send_event_hook_callback(struct ast_bridge_channel *bridge_channel, void *data)
structure to hold users read from users.conf
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:1667
char name_rec_location[PATH_MAX]
Definition: confbridge.h:276
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...
enum ast_bridge_hook_type hook_type
const char * ast_channel_name(const struct ast_channel *chan)
#define DEFAULT_MENU_PROFILE
Definition: confbridge.h:43
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
const char * ast_channel_language(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
#define DEFAULT_BRIDGE_PROFILE
Definition: confbridge.h:42
int play_sound_file(struct confbridge_conference *conference, const char *filename)
Play sound file into conference bridge.
struct user_profile u_profile
Definition: confbridge.h:274
#define DEFAULT_USER_PROFILE
Definition: confbridge.h:41
static int conf_rec_name(struct confbridge_user *user, const char *conf_name)
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
unsigned int kicked
Definition: confbridge.h:282
#define DEFAULT_SILENCE_THRESHOLD
Definition: confbridge.h:49
struct ast_bridge_tech_optimizations tech_args
Definition: confbridge.h:279
#define AST_APP_ARG(name)
Define an application argument.
static void leave_conference(struct confbridge_user *user)
Leave a conference.
struct ast_bridge * bridge
Definition: confbridge.h:247
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&#39;s name and store that profile in result structure...

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

References confbridge_conference::active_list, 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, confbridge_user::chan, ast_bridge_channel_snapshot_pair::channel_snapshot, confbridge_join_type(), confbridge_leave_type(), confbridge_unlock_and_unref(), hangup_data::conference, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, LOG_ERROR, confbridge_user::muted, 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, confbridge_user::u_profile, USER_OPT_ADMIN, confbridge_conference::waiting_list, and confbridge_conference::waitingusers.

Referenced by confbridge_atxfer_cb().

1563 {
1564  struct ast_channel_snapshot *old_snapshot;
1565  struct ast_channel_snapshot *new_snapshot;
1566  char *confbr_name = NULL;
1567  char *comma;
1569  struct confbridge_user *user = NULL;
1570  int found_user = 0;
1571  struct ast_json *json_object;
1572 
1574  && strcmp(msg->to_transferee.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1575  && msg->target) {
1576  /* We're transferring a bridge to an extension */
1577  old_snapshot = msg->to_transferee.channel_snapshot;
1578  new_snapshot = msg->target;
1579  } else if (msg->to_transfer_target.channel_snapshot
1580  && strcmp(msg->to_transfer_target.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1581  && msg->transferee) {
1582  /* We're transferring a call to a bridge */
1583  old_snapshot = msg->to_transfer_target.channel_snapshot;
1584  new_snapshot = msg->transferee;
1585  } else {
1586  ast_log(LOG_ERROR, "Could not determine proper channels\n");
1587  return;
1588  }
1589 
1590  /*
1591  * old_snapshot->data should have the original parameters passed to
1592  * the ConfBridge app:
1593  * conference[,bridge_profile[,user_profile[,menu]]]
1594  * We'll use "conference" to look up the bridge.
1595  *
1596  * We _could_ use old_snapshot->bridgeid to get the bridge but
1597  * that would involve locking the conference_bridges container
1598  * and iterating over it looking for a matching bridge.
1599  */
1600  if (ast_strlen_zero(old_snapshot->dialplan->data)) {
1601  ast_log(LOG_ERROR, "Channel '%s' didn't have app data set\n", old_snapshot->base->name);
1602  return;
1603  }
1604  confbr_name = ast_strdupa(old_snapshot->dialplan->data);
1605  comma = strchr(confbr_name, ',');
1606  if (comma) {
1607  *comma = '\0';
1608  }
1609 
1610  ast_debug(1, "Confbr: %s Leaving: %s Joining: %s\n", confbr_name, old_snapshot->base->name, new_snapshot->base->name);
1611 
1612  conference = ao2_find(conference_bridges, confbr_name, OBJ_SEARCH_KEY);
1613  if (!conference) {
1614  ast_log(LOG_ERROR, "Conference bridge '%s' not found\n", confbr_name);
1615  return;
1616  }
1617  ao2_lock(conference);
1618 
1619  /*
1620  * We need to grab the user profile for the departing user in order to
1621  * properly format the join/leave messages.
1622  */
1623  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1624  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1625  found_user = 1;
1626  break;
1627  }
1628  }
1629 
1630  /*
1631  * If we didn't find the user in the active list, try the waiting list.
1632  */
1633  if (!found_user && conference->waitingusers) {
1634  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
1635  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1636  found_user = 1;
1637  break;
1638  }
1639  }
1640  }
1641 
1642  if (!found_user) {
1643  ast_log(LOG_ERROR, "Unable to find user profile for channel '%s' in bridge '%s'\n",
1644  old_snapshot->base->name, confbr_name);
1645  return;
1646  }
1647 
1648  /*
1649  * We're going to use the existing user profile to create the messages.
1650  */
1651  json_object = ast_json_pack("{s: b}",
1652  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
1653  );
1654  if (!json_object) {
1655  return;
1656  }
1657 
1658  send_conf_stasis_snapshots(conference, old_snapshot, confbridge_leave_type(), json_object);
1659  ast_json_unref(json_object);
1660 
1661  json_object = ast_json_pack("{s: b, s: b}",
1662  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
1663  "muted", user->muted);
1664  if (!json_object) {
1665  return;
1666  }
1667  send_conf_stasis_snapshots(conference, new_snapshot, confbridge_join_type(), json_object);
1668  ast_json_unref(json_object);
1669 }
const ast_string_field data
struct ast_channel_snapshot_base * base
struct stasis_message_type * confbridge_join_type(void)
get the confbridge join stasis message type
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel * chan
Definition: confbridge.h:277
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure representing a snapshot of channel state.
struct ast_channel_snapshot * target
#define NULL
Definition: resample.c:96
struct ast_channel_snapshot_dialplan * dialplan
struct ast_bridge_channel_snapshot_pair to_transferee
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct stasis_message_type * confbridge_leave_type(void)
get the confbridge leave stasis message type
struct ast_bridge_channel_snapshot_pair to_transfer_target
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const ast_string_field appl
#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:911
struct ast_channel_snapshot * transferee
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
struct ast_channel_snapshot * channel_snapshot
#define LOG_ERROR
Definition: logger.h:285
static void confbridge_unlock_and_unref(void *obj)
unsigned int muted
Definition: confbridge.h:281
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)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
structure to hold users read from users.conf
const char * ast_channel_name(const struct ast_channel *chan)
Abstract JSON element (object, array, string, int, ...).
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct user_profile u_profile
Definition: confbridge.h:274
const ast_string_field name

◆ confbridge_unlock_and_unref()

static void confbridge_unlock_and_unref ( void *  obj)
static

Definition at line 1551 of file app_confbridge.c.

References ao2_ref, ao2_unlock, and hangup_data::conference.

Referenced by confbridge_handle_atxfer().

1552 {
1553  struct confbridge_conference *conference = obj;
1554 
1555  if (!obj) {
1556  return;
1557  }
1558  ao2_unlock(conference);
1559  ao2_ref(conference, -1);
1560 }
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_ref(o, delta)
Definition: astobj2.h:464
The structure that represents a conference bridge.
Definition: confbridge.h:244

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

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

Referenced by load_module().

505 {
506  const struct confbridge_conference *left = obj;
507  const struct confbridge_conference *right = arg;
508  const char *right_name = arg;
509  int cmp;
510 
511  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
512  default:
513  case OBJ_POINTER:
514  right_name = right->name;
515  /* Fall through */
516  case OBJ_KEY:
517  cmp = strcasecmp(left->name, right_name);
518  break;
519  case OBJ_PARTIAL_KEY:
520  cmp = strncasecmp(left->name, right_name, strlen(right_name));
521  break;
522  }
523  return cmp ? 0 : CMP_MATCH;
524 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
The structure that represents a conference bridge.
Definition: confbridge.h:244
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

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

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

Referenced by load_module().

481 {
482  const struct confbridge_conference *conference = obj;
483  const char *name = obj;
484  int hash;
485 
486  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
487  default:
488  case OBJ_POINTER:
489  name = conference->name;
490  /* Fall through */
491  case OBJ_KEY:
492  hash = ast_str_case_hash(name);
493  break;
494  case OBJ_PARTIAL_KEY:
495  /* Should never happen in hash callback. */
496  ast_assert(0);
497  hash = 0;
498  break;
499  }
500  return hash;
501 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_assert(a)
Definition: utils.h:695
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
static const char name[]
Definition: cdr_mysql.c:74
The structure that represents a conference bridge.
Definition: confbridge.h:244
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
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:1250

◆ confkick_exec()

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

Definition at line 4256 of file app_confbridge.c.

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, hangup_data::conference, kick_conference_participant(), LOG_WARNING, OBJ_KEY, parse(), and pbx_builtin_setvar_helper().

Referenced by load_module().

4257 {
4258  char *parse;
4259  struct confbridge_conference *conference;
4260  int not_found;
4261 
4263  AST_APP_ARG(confbridge);
4265  );
4266 
4267  if (ast_strlen_zero(data)) {
4268  ast_log(LOG_WARNING, "No conference bridge specified.\n");
4269  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4270  return 0;
4271  }
4272 
4273  parse = ast_strdupa(data);
4274  AST_STANDARD_APP_ARGS(args, parse);
4275 
4276  conference = ao2_find(conference_bridges, args.confbridge, OBJ_KEY);
4277  if (!conference) {
4278  ast_log(LOG_WARNING, "No conference bridge named '%s' found!\n", args.confbridge);
4279  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4280  return 0;
4281  }
4282  if (ast_strlen_zero(args.channel)) {
4283  not_found = kick_conference_participant(conference, "all");
4284  } else {
4285  not_found = kick_conference_participant(conference, args.channel);
4286  }
4287 
4288  ao2_ref(conference, -1);
4289  if (not_found) {
4290  if (ast_strlen_zero(args.channel) || !strcasecmp("all", args.channel) || !strcasecmp("participants", args.channel)) {
4291  ast_log(LOG_WARNING, "No participants found in conference bridge '%s'!\n", args.confbridge);
4292  } else {
4293  ast_log(LOG_WARNING, "No participant named '%s' found in conference bridge '%s'!\n", args.channel, args.confbridge);
4294  }
4295  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "FAILURE");
4296  return 0;
4297  }
4298  ast_debug(1, "Kicked '%s' out of conference '%s'\n", args.channel, args.confbridge);
4299  pbx_builtin_setvar_helper(chan, "CONFKICKSTATUS", "SUCCESS");
4300  return 0;
4301 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
Definition: muted.c:95
static int kick_conference_participant(struct confbridge_conference *conference, const char *channel)
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
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...
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ destroy_conference_bridge()

static void destroy_conference_bridge ( void *  obj)
static

Destroy a conference bridge.

Parameters
objThe conference bridge object
Returns
Returns nothing

Definition at line 1173 of file app_confbridge.c.

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, hangup_data::cond, conf_bridge_profile_destroy(), hangup_data::conference, hangup_data_destroy(), hangup_data_init(), hangup_playback(), hangup_data::hungup, hangup_data::lock, 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().

1174 {
1175  struct confbridge_conference *conference = obj;
1176 
1177  ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
1178 
1179  if (conference->playback_chan) {
1180  if (conference->playback_queue) {
1181  struct hangup_data hangup;
1182  hangup_data_init(&hangup, conference);
1183 
1185  ast_mutex_lock(&hangup.lock);
1186  while (!hangup.hungup) {
1187  ast_cond_wait(&hangup.cond, &hangup.lock);
1188  }
1189  ast_mutex_unlock(&hangup.lock);
1190  }
1191 
1193  } else {
1194  /* Playback queue is not yet allocated. Just hang up the channel straight */
1195  ast_hangup(conference->playback_chan);
1196  conference->playback_chan = NULL;
1197  }
1198  }
1199 
1200  /* Destroying a conference bridge is simple, all we have to do is destroy the bridging object */
1201  if (conference->bridge) {
1202  ast_bridge_destroy(conference->bridge, 0);
1203  conference->bridge = NULL;
1204  }
1205 
1206  ast_channel_cleanup(conference->record_chan);
1207  ast_free(conference->orig_rec_file);
1208  ast_free(conference->record_filename);
1209 
1210  conf_bridge_profile_destroy(&conference->b_profile);
1212 }
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
static int hangup(void *data)
Definition: chan_pjsip.c:2483
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:255
struct ast_str * orig_rec_file
Definition: confbridge.h:257
static int hangup_playback(void *data)
Hang up the announcer channel.
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:260
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void conf_bridge_profile_destroy(struct bridge_profile *b_profile)
Destroy a bridge profile found by &#39;conf_find_bridge_profile&#39;.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ast_free(a)
Definition: astmm.h:182
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
The structure that represents a conference bridge.
Definition: confbridge.h:244
static void hangup_data_init(struct hangup_data *hangup, 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.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
struct ast_channel * playback_chan
Definition: confbridge.h:254
struct ast_str * record_filename
Definition: confbridge.h:256
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
static void hangup_data_destroy(struct hangup_data *hangup)
#define ast_mutex_unlock(a)
Definition: lock.h:188
struct ast_bridge * bridge
Definition: confbridge.h:247

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

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, confbridge_user::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, confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by action_playback_and_continue(), and conf_handle_dtmf().

3108 {
3109  struct conf_menu_action *menu_action;
3110  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
3111  int stop_prompts = 0;
3112  int res = 0;
3113 
3114  AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
3115  switch (menu_action->id) {
3117  res |= action_toggle_mute(conference, user, bridge_channel);
3118  break;
3120  action_toggle_binaural(conference, user, bridge_channel);
3121  break;
3123  if (!isadmin) {
3124  break;
3125  }
3126  action_toggle_mute_participants(conference, user);
3127  break;
3129  announce_user_count(conference, user, bridge_channel);
3130  break;
3131  case MENU_ACTION_PLAYBACK:
3132  if (!stop_prompts) {
3133  res |= action_playback(bridge_channel, menu_action->data.playback_file);
3134  ast_test_suite_event_notify("CONF_MENU_PLAYBACK",
3135  "Message: %s\r\nChannel: %s",
3136  menu_action->data.playback_file, ast_channel_name(bridge_channel->chan));
3137  }
3138  break;
3141  break;
3144  break;
3148  break;
3152  break;
3156  break;
3160  break;
3162  if (!(stop_prompts)) {
3163  res |= action_playback_and_continue(conference,
3164  user,
3165  bridge_channel,
3166  menu,
3167  menu_action->data.playback_file,
3168  menu_entry->dtmf,
3169  &stop_prompts);
3170  }
3171  break;
3173  res |= action_dialplan_exec(bridge_channel, menu_action);
3174  break;
3176  if (!isadmin) {
3177  break;
3178  }
3179  conference->locked = (!conference->locked ? 1 : 0);
3180  res |= play_file(bridge_channel, NULL,
3183  conference->b_profile.sounds)) < 0;
3184  break;
3186  res |= action_kick_last(conference, bridge_channel, user);
3187  break;
3188  case MENU_ACTION_LEAVE:
3189  pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "DTMF");
3190  ao2_lock(conference);
3191  ast_bridge_remove(conference->bridge, bridge_channel->chan);
3192  ast_test_suite_event_notify("CONF_MENU_LEAVE",
3193  "Channel: %s",
3194  ast_channel_name(bridge_channel->chan));
3195  ao2_unlock(conference);
3196  break;
3197  case MENU_ACTION_NOOP:
3198  break;
3200  ao2_lock(conference);
3201  if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
3202  ast_bridge_set_single_src_video_mode(conference->bridge, bridge_channel->chan);
3203  }
3204  ao2_unlock(conference);
3205  break;
3207  handle_video_on_exit(conference, bridge_channel->chan);
3208  break;
3209  }
3210  }
3211  return res;
3212 }
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:1346
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
static int announce_user_count(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
Announce number of users in the conference bridge to the caller.
struct ast_channel * chan
Definition: confbridge.h:277
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int action_toggle_mute_participants(struct confbridge_conference *conference, struct confbridge_user *user)
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
static void handle_video_on_exit(struct confbridge_conference *conference, struct ast_channel *chan)
static int action_toggle_mute(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
#define ao2_unlock(a)
Definition: astobj2.h:730
struct conf_menu_action::@85 action
#define NULL
Definition: resample.c:96
char dtmf[MAXIMUM_DTMF_FEATURE_STRING]
Definition: confbridge.h:138
static int action_kick_last(struct confbridge_conference *conference, struct ast_bridge_channel *bridge_channel, struct confbridge_user *user)
struct bridge_profile b_profile
Definition: confbridge.h:248
unsigned int locked
Definition: confbridge.h:252
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
char playback_file[PATH_MAX]
Definition: confbridge.h:123
static int action_toggle_binaural(struct confbridge_conference *conference, struct confbridge_user *user, struct ast_bridge_channel *bridge_channel)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
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:1397
union conf_menu_action::@84 data
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)
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:3816
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...
enum conf_menu_action_id id
Definition: confbridge.h:121
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
struct user_profile u_profile
Definition: confbridge.h:274
struct conf_menu_entry::@87 actions
static int action_dialplan_exec(struct ast_bridge_channel *bridge_channel, struct conf_menu_action *menu_action)
struct ast_bridge * bridge
Definition: confbridge.h:247

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

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, hangup_data::conference, confbridge_user::list, confbridge_conference::locked, LOG_ERROR, confbridge_conference::muted, OBJ_KEY, parse(), type, confbridge_user::u_profile, user, USER_OPT_ADMIN, USER_OPT_MARKEDUSER, and confbridge_conference::waiting_list.

4197 {
4198  char *parse;
4199  struct confbridge_conference *conference;
4200  struct confbridge_user *user;
4201  int count = 0;
4203  AST_APP_ARG(type);
4204  AST_APP_ARG(confno);
4205  );
4206 
4207  /* parse all the required arguments and make sure they exist. */
4208  if (ast_strlen_zero(data)) {
4209  return -1;
4210  }
4211  parse = ast_strdupa(data);
4212  AST_STANDARD_APP_ARGS(args, parse);
4213  if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
4214  return -1;
4215  }
4216  conference = ao2_find(conference_bridges, args.confno, OBJ_KEY);
4217  if (!conference) {
4218  snprintf(buf, len, "0");
4219  return 0;
4220  }
4221 
4222  /* get the correct count for the type requested */
4223  ao2_lock(conference);
4224  if (!strcasecmp(args.type, "parties")) {
4225  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4226  count++;
4227  }
4228  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
4229  count++;
4230  }
4231  } else if (!strcasecmp(args.type, "admins")) {
4232  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4233  if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
4234  count++;
4235  }
4236  }
4237  } else if (!strcasecmp(args.type, "marked")) {
4238  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4240  count++;
4241  }
4242  }
4243  } else if (!strcasecmp(args.type, "locked")) {
4244  count = conference->locked;
4245  } else if (!strcasecmp(args.type, "muted")) {
4246  count = conference->muted;
4247  } else {
4248  ast_log(LOG_ERROR, "Invalid keyword '%s' passed to CONFBRIDGE_INFO.\n", args.type);
4249  }
4250  snprintf(buf, len, "%d", count);
4251  ao2_unlock(conference);
4252  ao2_ref(conference, -1);
4253  return 0;
4254 }
static char user[512]
static const char type[]
Definition: chan_ooh323.c:109
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define ao2_unlock(a)
Definition: astobj2.h:730
struct confbridge_user::@94 list
const char * args
struct confbridge_conference::@90 active_list
unsigned int locked
Definition: confbridge.h:252
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
unsigned int muted
Definition: confbridge.h:253
struct user_profile u_profile
Definition: confbridge.h:274
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ generic_lock_unlock_helper()

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

Definition at line 3503 of file app_confbridge.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_test_suite_event_notify, confbridge_conference::b_profile, hangup_data::conference, hangup_data::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().

3504 {
3505  struct confbridge_conference *conference;
3506  int res = 0;
3507 
3508  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3509  if (!conference) {
3510  return -1;
3511  }
3512  ao2_lock(conference);
3513  conference->locked = lock;
3514  ast_test_suite_event_notify("CONF_LOCK", "Message: conference %s\r\nConference: %s", conference->locked ? "locked" : "unlocked", conference->b_profile.name);
3515  ao2_unlock(conference);
3516  ao2_ref(conference, -1);
3517 
3518  return res;
3519 }
#define OBJ_KEY
Definition: astobj2.h:1155
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
#define ao2_unlock(a)
Definition: astobj2.h:730
struct bridge_profile b_profile
Definition: confbridge.h:248
unsigned int locked
Definition: confbridge.h:252
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ generic_mute_unmute_helper()

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

Definition at line 3528 of file app_confbridge.c.

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

Referenced by action_mute_unmute_helper(), and cli_mute_unmute_helper().

3530 {
3531  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3532  struct confbridge_user *user;
3533  int all = !strcasecmp("all", chan_name);
3534  int participants = !strcasecmp("participants", chan_name);
3535  int res = -2;
3536 
3537  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3538  if (!conference) {
3539  return -1;
3540  }
3541 
3542  {
3543  SCOPED_AO2LOCK(bridge_lock, conference);
3545  int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3546  strlen(chan_name));
3547  if (match || all
3548  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3550  res = 0;
3551  if (match) {
3552  return res;
3553  }
3554  }
3555  }
3556 
3558  int match = !strncasecmp(chan_name, ast_channel_name(user->chan),
3559  strlen(chan_name));
3560  if (match || all
3561  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3563  res = 0;
3564  if (match) {
3565  return res;
3566  }
3567  }
3568  }
3569  }
3570 
3571  return res;
3572 }
static char user[512]
struct ast_channel * chan
Definition: confbridge.h:277
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
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:2315
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
static int mute
Definition: chan_alsa.c:144
#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:911
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
struct user_profile u_profile
Definition: confbridge.h:274

◆ generic_mute_unmute_user()

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

Definition at line 1312 of file app_confbridge.c.

References ast_channel_name(), ast_test_suite_event_notify, confbridge_conference::b_profile, confbridge_user::chan, conf_update_user_mute(), confbridge_user::muted, bridge_profile::name, send_mute_event(), and send_unmute_event().

Referenced by action_toggle_mute(), and generic_mute_unmute_helper().

1313 {
1314  /* Set user level mute request. */
1315  user->muted = mute ? 1 : 0;
1316 
1317  conf_update_user_mute(user);
1318  ast_test_suite_event_notify("CONF_MUTE",
1319  "Message: participant %s %s\r\n"
1320  "Conference: %s\r\n"
1321  "Channel: %s",
1322  ast_channel_name(user->chan),
1323  mute ? "muted" : "unmuted",
1324  conference->b_profile.name,
1325  ast_channel_name(user->chan));
1326  if (mute) {
1327  send_mute_event(user, conference);
1328  } else {
1329  send_unmute_event(user, conference);
1330  }
1331 }
struct ast_channel * chan
Definition: confbridge.h:277
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
void conf_update_user_mute(struct confbridge_user *user)
Update the actual mute status of the user and set it on the bridge.
static void send_mute_event(struct confbridge_user *user, struct confbridge_conference *conference)
static int mute
Definition: chan_alsa.c:144
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
unsigned int muted
Definition: confbridge.h:281
static void send_unmute_event(struct confbridge_user *user, struct confbridge_conference *conference)
const char * ast_channel_name(const struct ast_channel *chan)

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

References ao2_find, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), hangup_data::conference, ast_cli_args::fd, kick_conference_participant(), ast_cli_args::line, ast_cli_args::n, NULL, OBJ_KEY, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3343 {
3344  struct confbridge_conference *conference;
3345  int not_found;
3346 
3347  switch (cmd) {
3348  case CLI_INIT:
3349  e->command = "confbridge kick";
3350  e->usage =
3351  "Usage: confbridge kick <conference> <channel>\n"
3352  " Kicks a channel out of the conference bridge.\n"
3353  " (all to kick everyone, participants to kick non-admins).\n";
3354  return NULL;
3355  case CLI_GENERATE:
3356  if (a->pos == 2) {
3357  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3358  }
3359  if (a->pos == 3) {
3360  return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3361  }
3362  return NULL;
3363  }
3364 
3365  if (a->argc != 4) {
3366  return CLI_SHOWUSAGE;
3367  }
3368 
3369  conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
3370  if (!conference) {
3371  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3372  return CLI_SUCCESS;
3373  }
3374  not_found = kick_conference_participant(conference, a->argv[3]);
3375  ao2_ref(conference, -1);
3376  if (not_found) {
3377  if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3378  ast_cli(a->fd, "No participants found!\n");
3379  } else {
3380  ast_cli(a->fd, "No participant named '%s' found!\n", a->argv[3]);
3381  }
3382  return CLI_SUCCESS;
3383  }
3384  ast_cli(a->fd, "Kicked '%s' out of conference '%s'\n", a->argv[3], a->argv[2]);
3385  return CLI_SUCCESS;
3386 }
#define OBJ_KEY
Definition: astobj2.h:1155
const int argc
Definition: cli.h:160
Definition: cli.h:152
static int kick_conference_participant(struct confbridge_conference *conference, const char *channel)
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
static char * complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

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

References confbridge_conference::active_list, confbridge_conference::activeusers, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_YESNO, AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), hangup_data::conference, ast_cli_args::fd, handle_cli_confbridge_list_item(), ast_cli_args::line, confbridge_user::list, confbridge_conference::locked, confbridge_conference::markedusers, confbridge_conference::muted, ast_cli_args::n, confbridge_conference::name, NULL, OBJ_KEY, ast_cli_args::pos, ast_cli_entry::usage, user, confbridge_conference::waiting_list, confbridge_conference::waitingusers, and ast_cli_args::word.

3425 {
3426  struct confbridge_conference *conference;
3427 
3428  switch (cmd) {
3429  case CLI_INIT:
3430  e->command = "confbridge list";
3431  e->usage =
3432  "Usage: confbridge list [<name>]\n"
3433  " Lists all currently active conference bridges or a specific conference bridge.\n"
3434  "\n"
3435  " When a conference bridge name is provided, flags may be shown for users. Below\n"
3436  " are the flags and what they represent.\n"
3437  "\n"
3438  " Flags:\n"
3439  " A - The user is an admin\n"
3440  " M - The user is a marked user\n"
3441  " W - The user must wait for a marked user to join\n"
3442  " E - The user will be kicked after the last marked user leaves the conference\n"
3443  " m - The user is muted\n"
3444  " w - The user is waiting for a marked user to join\n";
3445  return NULL;
3446  case CLI_GENERATE:
3447  if (a->pos == 2) {
3448  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3449  }
3450  return NULL;
3451  }
3452 
3453  if (a->argc == 2) {
3454  struct ao2_iterator iter;
3455 
3456  ast_cli(a->fd, "Conference Bridge Name Users Marked Locked Muted\n");
3457  ast_cli(a->fd, "================================ ====== ====== ====== =====\n");
3459  while ((conference = ao2_iterator_next(&iter))) {
3460  ast_cli(a->fd, "%-32s %6u %6u %-6s %s\n",
3461  conference->name,
3462  conference->activeusers + conference->waitingusers,
3463  conference->markedusers,
3464  AST_CLI_YESNO(conference->locked),
3465  AST_CLI_YESNO(conference->muted));
3466  ao2_ref(conference, -1);
3467  }
3468  ao2_iterator_destroy(&iter);
3469  return CLI_SUCCESS;
3470  }
3471 
3472  if (a->argc == 3) {
3473  struct confbridge_user *user;
3474 
3475  conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY);
3476  if (!conference) {
3477  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3478  return CLI_SUCCESS;
3479  }
3480  ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu CallerID\n");
3481  ast_cli(a->fd, "============================== ====== ================ ================ ================ ================\n");
3482  ao2_lock(conference);
3483  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3484  handle_cli_confbridge_list_item(a, user, 0);
3485  }
3486  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3487  handle_cli_confbridge_list_item(a, user, 1);
3488  }
3489  ao2_unlock(conference);
3490  ao2_ref(conference, -1);
3491  return CLI_SUCCESS;
3492  }
3493 
3494  return CLI_SHOWUSAGE;
3495 }
static char user[512]
#define OBJ_KEY
Definition: astobj2.h:1155
const int argc
Definition: cli.h:160
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int markedusers
Definition: confbridge.h:250
const char * line
Definition: cli.h:162
struct confbridge_conference::@90 active_list
unsigned int locked
Definition: confbridge.h:252
unsigned int waitingusers
Definition: confbridge.h:251
static void handle_cli_confbridge_list_item(struct ast_cli_args *a, struct confbridge_user *user, int waiting)
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
The structure that represents a conference bridge.
Definition: confbridge.h:244
unsigned int activeusers
Definition: confbridge.h:249
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const int pos
Definition: cli.h:164
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
unsigned int muted
Definition: confbridge.h:253
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ handle_cli_confbridge_list_item()

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

Definition at line 3388 of file app_confbridge.c.

References ast_channel_caller(), ast_channel_name(), ast_cli(), ast_test_flag, confbridge_conference::b_profile, confbridge_user::chan, confbridge_user::conference, ast_cli_args::fd, ast_party_caller::id, confbridge_user::menu_name, confbridge_user::muted, user_profile::name, bridge_profile::name, ast_party_id::number, S_COR, ast_party_number::str, confbridge_user::u_profile, USER_OPT_ADMIN, USER_OPT_ENDMARKED, USER_OPT_MARKEDUSER, USER_OPT_WAITMARKED, and ast_party_number::valid.

Referenced by handle_cli_confbridge_list().

3389 {
3390  char flag_str[6 + 1];/* Max flags + terminator */
3391  int pos = 0;
3392 
3393  /* Build flags column string. */
3394  if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
3395  flag_str[pos++] = 'A';
3396  }
3398  flag_str[pos++] = 'M';
3399  }
3401  flag_str[pos++] = 'W';
3402  }
3404  flag_str[pos++] = 'E';
3405  }
3406  if (user->muted) {
3407  flag_str[pos++] = 'm';
3408  }
3409  if (waiting) {
3410  flag_str[pos++] = 'w';
3411  }
3412  flag_str[pos] = '\0';
3413 
3414  ast_cli(a->fd, "%-30s %-6s %-16s %-16s %-16s %s\n",
3415  ast_channel_name(user->chan),
3416  flag_str,
3417  user->u_profile.name,
3418  user->conference->b_profile.name,
3419  user->menu_name,
3421  ast_channel_caller(user->chan)->id.number.str, "<unknown>"));
3422 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
struct ast_channel * chan
Definition: confbridge.h:277
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:226
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct bridge_profile b_profile
Definition: confbridge.h:248
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
const int fd
Definition: cli.h:159
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
unsigned int muted
Definition: confbridge.h:281
char menu_name[MAX_PROFILE_NAME]
Definition: confbridge.h:275
const char * ast_channel_name(const struct ast_channel *chan)
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:153
struct user_profile u_profile
Definition: confbridge.h:274
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ handle_cli_confbridge_lock()

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

Definition at line 3655 of file app_confbridge.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), ast_cli_args::fd, generic_lock_unlock_helper(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3656 {
3657  switch (cmd) {
3658  case CLI_INIT:
3659  e->command = "confbridge lock";
3660  e->usage =
3661  "Usage: confbridge lock <conference>\n"
3662  " Lock a conference. While locked, no new non-admins\n"
3663  " may join the conference.\n";
3664  return NULL;
3665  case CLI_GENERATE:
3666  if (a->pos == 2) {
3667  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3668  }
3669  return NULL;
3670  }
3671  if (a->argc != 3) {
3672  return CLI_SHOWUSAGE;
3673  }
3674  if (generic_lock_unlock_helper(1, a->argv[2])) {
3675  ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3676  } else {
3677  ast_cli(a->fd, "Conference %s is locked.\n", a->argv[2]);
3678  }
3679  return CLI_SUCCESS;
3680 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
static int generic_lock_unlock_helper(int lock, const char *conference_name)

◆ handle_cli_confbridge_mute()

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

Definition at line 3593 of file app_confbridge.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, cli_mute_unmute_helper(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3594 {
3595  switch (cmd) {
3596  case CLI_INIT:
3597  e->command = "confbridge mute";
3598  e->usage =
3599  "Usage: confbridge mute <conference> <channel>\n"
3600  " Mute a channel in a conference.\n"
3601  " (all to mute everyone, participants to mute non-admins)\n"
3602  " If the specified channel is a prefix,\n"
3603  " the action will be taken on the first\n"
3604  " matching channel.\n";
3605  return NULL;
3606  case CLI_GENERATE:
3607  if (a->pos == 2) {
3608  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3609  }
3610  if (a->pos == 3) {
3611  return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3612  }
3613  return NULL;
3614  }
3615  if (a->argc != 4) {
3616  return CLI_SHOWUSAGE;
3617  }
3618 
3619  cli_mute_unmute_helper(1, a);
3620 
3621  return CLI_SUCCESS;
3622 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
static char * complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
const int n
Definition: cli.h:165
static int cli_mute_unmute_helper(int mute, struct ast_cli_args *a)
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_cli_confbridge_start_record()

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

Definition at line 3708 of file app_confbridge.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero, confbridge_conference::b_profile, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), conf_is_recording(), conf_start_record(), hangup_data::conference, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, OBJ_KEY, ast_cli_args::pos, bridge_profile::rec_file, ast_cli_entry::usage, and ast_cli_args::word.

3709 {
3710  const char *rec_file = NULL;
3711  struct confbridge_conference *conference;
3712 
3713  switch (cmd) {
3714  case CLI_INIT:
3715  e->command = "confbridge record start";
3716  e->usage =
3717  "Usage: confbridge record start <conference> <file>\n"
3718  " <file> is optional, Otherwise the bridge profile\n"
3719  " record file will be used. If the bridge profile\n"
3720  " has no record file specified, a file will automatically\n"
3721  " be generated in the monitor directory\n";
3722  return NULL;
3723  case CLI_GENERATE:
3724  if (a->pos == 3) {
3725  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3726  }
3727  return NULL;
3728  }
3729  if (a->argc < 4) {
3730  return CLI_SHOWUSAGE;
3731  }
3732  if (a->argc == 5) {
3733  rec_file = a->argv[4];
3734  }
3735 
3736  conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3737  if (!conference) {
3738  ast_cli(a->fd, "Conference not found.\n");
3739  return CLI_FAILURE;
3740  }
3741  ao2_lock(conference);
3742  if (conf_is_recording(conference)) {
3743  ast_cli(a->fd, "Conference is already being recorded.\n");
3744  ao2_unlock(conference);
3745  ao2_ref(conference, -1);
3746  return CLI_SUCCESS;
3747  }
3748  if (!ast_strlen_zero(rec_file)) {
3749  ast_copy_string(conference->b_profile.rec_file, rec_file, sizeof(conference->b_profile.rec_file));
3750  }
3751 
3752  if (conf_start_record(conference)) {
3753  ast_cli(a->fd, "Could not start recording due to internal error.\n");
3754  ao2_unlock(conference);
3755  ao2_ref(conference, -1);
3756  return CLI_FAILURE;
3757  }
3758  ao2_unlock(conference);
3759 
3760  ast_cli(a->fd, "Recording started\n");
3761  ao2_ref(conference, -1);
3762  return CLI_SUCCESS;
3763 }
#define OBJ_KEY
Definition: astobj2.h:1155
const int argc
Definition: cli.h:160
char rec_file[PATH_MAX]
Definition: confbridge.h:228
Definition: cli.h:152
#define ao2_unlock(a)
Definition: astobj2.h:730
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_strlen_zero(foo)
Definition: strings.h:52
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
const char *const * argv
Definition: cli.h:161
static int conf_start_record(struct confbridge_conference *conference)
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int conf_is_recording(struct confbridge_conference *conference)
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const int pos
Definition: cli.h:164

◆ handle_cli_confbridge_stop_record()

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

Definition at line 3765 of file app_confbridge.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), conf_stop_record(), hangup_data::conference, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, OBJ_KEY, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3766 {
3767  struct confbridge_conference *conference;
3768  int ret;
3769 
3770  switch (cmd) {
3771  case CLI_INIT:
3772  e->command = "confbridge record stop";
3773  e->usage =
3774  "Usage: confbridge record stop <conference>\n"
3775  " Stop a previously started recording.\n";
3776  return NULL;
3777  case CLI_GENERATE:
3778  if (a->pos == 3) {
3779  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3780  }
3781  return NULL;
3782  }
3783  if (a->argc != 4) {
3784  return CLI_SHOWUSAGE;
3785  }
3786 
3787  conference = ao2_find(conference_bridges, a->argv[3], OBJ_KEY);
3788  if (!conference) {
3789  ast_cli(a->fd, "Conference not found.\n");
3790  return CLI_SUCCESS;
3791  }
3792  ao2_lock(conference);
3793  ret = conf_stop_record(conference);
3794  ao2_unlock(conference);
3795  ast_cli(a->fd, "Recording %sstopped.\n", ret ? "could not be " : "");
3796  ao2_ref(conference, -1);
3797  return CLI_SUCCESS;
3798 }
#define OBJ_KEY
Definition: astobj2.h:1155
const int argc
Definition: cli.h:160
static int conf_stop_record(struct confbridge_conference *conference)
Definition: cli.h:152
#define ao2_unlock(a)
Definition: astobj2.h:730
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
The structure that represents a conference bridge.
Definition: confbridge.h:244
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_cli_confbridge_unlock()

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

Definition at line 3682 of file app_confbridge.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), ast_cli_args::fd, generic_lock_unlock_helper(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3683 {
3684  switch (cmd) {
3685  case CLI_INIT:
3686  e->command = "confbridge unlock";
3687  e->usage =
3688  "Usage: confbridge unlock <conference>\n"
3689  " Unlock a previously locked conference.\n";
3690  return NULL;
3691  case CLI_GENERATE:
3692  if (a->pos == 2) {
3693  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3694  }
3695  return NULL;
3696  }
3697  if (a->argc != 3) {
3698  return CLI_SHOWUSAGE;
3699  }
3700  if (generic_lock_unlock_helper(0, a->argv[2])) {
3701  ast_cli(a->fd, "Conference %s is not found\n", a->argv[2]);
3702  } else {
3703  ast_cli(a->fd, "Conference %s is unlocked.\n", a->argv[2]);
3704  }
3705  return CLI_SUCCESS;
3706 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
static int generic_lock_unlock_helper(int lock, const char *conference_name)

◆ handle_cli_confbridge_unmute()

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

Definition at line 3624 of file app_confbridge.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, cli_mute_unmute_helper(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_confbridge_name(), complete_confbridge_participant(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

3625 {
3626  switch (cmd) {
3627  case CLI_INIT:
3628  e->command = "confbridge unmute";
3629  e->usage =
3630  "Usage: confbridge unmute <conference> <channel>\n"
3631  " Unmute a channel in a conference.\n"
3632  " (all to unmute everyone, participants to unmute non-admins)\n"
3633  " If the specified channel is a prefix,\n"
3634  " the action will be taken on the first\n"
3635  " matching channel.\n";
3636  return NULL;
3637  case CLI_GENERATE:
3638  if (a->pos == 2) {
3639  return complete_confbridge_name(a->line, a->word, a->pos, a->n);
3640  }
3641  if (a->pos == 3) {
3642  return complete_confbridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
3643  }
3644  return NULL;
3645  }
3646  if (a->argc != 4) {
3647  return CLI_SHOWUSAGE;
3648  }
3649 
3650  cli_mute_unmute_helper(0, a);
3651 
3652  return CLI_SUCCESS;
3653 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * complete_confbridge_name(const char *line, const char *word, int pos, int state)
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
static char * complete_confbridge_participant(const char *conference_name, const char *line, const char *word, int pos, int state)
const int n
Definition: cli.h:165
static int cli_mute_unmute_helper(int mute, struct ast_cli_args *a)
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_conf_user_join()

static int handle_conf_user_join ( struct confbridge_user user)
static

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

Definition at line 1220 of file app_confbridge.c.

References ast_assert, ast_test_flag, conf_invalid_event_fn(), confbridge_user::conference, handler(), confbridge_state::join_marked, confbridge_state::join_unmarked, confbridge_state::join_waitmarked, NULL, confbridge_conference::state, confbridge_user::u_profile, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by join_conference_bridge().

1221 {
1224  handler = user->conference->state->join_marked;
1225  } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1226  handler = user->conference->state->join_waitmarked;
1227  } else {
1228  handler = user->conference->state->join_unmarked;
1229  }
1230 
1231  ast_assert(handler != NULL);
1232 
1233  if (!handler) {
1234  conf_invalid_event_fn(user);
1235  return -1;
1236  }
1237 
1238  handler(user);
1239 
1240  return 0;
1241 }
conference_event_fn join_unmarked
Definition: conf_state.h:50
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
conference_event_fn join_marked
Definition: conf_state.h:52
struct confbridge_state * state
Definition: confbridge.h:246
conference_event_fn join_waitmarked
Definition: conf_state.h:51
void conf_invalid_event_fn(struct confbridge_user *user)
A handler for join/leave events that are invalid in a particular state.
Definition: conf_state.c:45
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
void(* conference_event_fn)(struct confbridge_user *user)
Definition: conf_state.h:43
struct user_profile u_profile
Definition: confbridge.h:274

◆ handle_conf_user_leave()

static int handle_conf_user_leave ( struct confbridge_user user)
static

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

Definition at line 1249 of file app_confbridge.c.

References ast_assert, ast_test_flag, conf_invalid_event_fn(), confbridge_user::conference, handler(), confbridge_state::leave_marked, confbridge_state::leave_unmarked, confbridge_state::leave_waitmarked, NULL, confbridge_conference::state, confbridge_user::u_profile, USER_OPT_MARKEDUSER, and USER_OPT_WAITMARKED.

Referenced by leave_conference().

1250 {
1253  handler = user->conference->state->leave_marked;
1254  } else if (ast_test_flag(&user->u_profile, USER_OPT_WAITMARKED)) {
1255  handler = user->conference->state->leave_waitmarked;
1256  } else {
1257  handler = user->conference->state->leave_unmarked;
1258  }
1259 
1260  ast_assert(handler != NULL);
1261 
1262  if (!handler) {
1263  /* This should never happen. If it does, though, it is bad. The user will not have been removed
1264  * from the appropriate list, so counts will be off and stuff. The conference won't be torn down, etc.
1265  * Shouldn't happen, though. */
1266  conf_invalid_event_fn(user);
1267  return -1;
1268  }
1269 
1270  handler(user);
1271 
1272  return 0;
1273 }
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_assert(a)
Definition: utils.h:695
conference_event_fn leave_unmarked
Definition: conf_state.h:53
#define NULL
Definition: resample.c:96
conference_event_fn leave_marked
Definition: conf_state.h:55
struct confbridge_state * state
Definition: confbridge.h:246
void conf_invalid_event_fn(struct confbridge_user *user)
A handler for join/leave events that are invalid in a particular state.
Definition: conf_state.c:45
conference_event_fn leave_waitmarked
Definition: conf_state.h:54
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
void(* conference_event_fn)(struct confbridge_user *user)
Definition: conf_state.h:43
struct user_profile u_profile
Definition: confbridge.h:274

◆ handle_video_on_exit()

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

Definition at line 1075 of file app_confbridge.c.

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

Referenced by confbridge_exec(), and execute_menu_entry().

1076 {
1077  struct confbridge_user *user = NULL;
1078 
1079  /* if this isn't a video source, nothing to update */
1080  if (!ast_bridge_is_video_src(conference->bridge, chan)) {
1081  return;
1082  }
1083 
1084  ast_bridge_remove_video_src(conference->bridge, chan);
1085 
1086  /* If in follow talker mode, make sure to restore this mode on the
1087  * bridge when a source is removed. It is possible this channel was
1088  * only set temporarily as a video source by an AMI or DTMF action. */
1091  }
1092 
1093  /* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
1096  return;
1097  }
1098 
1099  /* Make the next available marked user the video src. */
1100  ao2_lock(conference);
1101  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1102  if (user->chan == chan) {
1103  continue;
1104  }
1106  ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
1107  break;
1108  }
1109  }
1110  ao2_unlock(conference);
1111 }
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_unlock(a)
Definition: astobj2.h:730
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
struct bridge_profile b_profile
Definition: confbridge.h:248
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
remove a channel as a source of video for the bridge.
Definition: bridge.c:3984
#define ao2_lock(a)
Definition: astobj2.h:718
int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
Determine if a channel is a video src for the bridge.
Definition: bridge.c:3958
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
Set the bridge to pick the strongest talker supporting video as the single source video feed...
Definition: bridge.c:3833
structure to hold users read from users.conf
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:3816
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct user_profile u_profile
Definition: confbridge.h:274
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ handle_video_on_join()

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

Definition at line 1043 of file app_confbridge.c.

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

Referenced by confbridge_exec().

1044 {
1045  /* Right now, only marked users are automatically set as the single src of video.*/
1046  if (!marked) {
1047  return;
1048  }
1049 
1051  int set = 1;
1052  struct confbridge_user *user = NULL;
1053 
1054  ao2_lock(conference);
1055  /* see if anyone is already the video src */
1056  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1057  if (user->chan == chan) {
1058  continue;
1059  }
1060  if (ast_bridge_is_video_src(conference->bridge, user->chan)) {
1061  set = 0;
1062  break;
1063  }
1064  }
1065  ao2_unlock(conference);
1066  if (set) {
1067  ast_bridge_set_single_src_video_mode(conference->bridge, chan);
1068  }
1069  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
1070  /* we joined and are video capable, we override anyone else that may have already been the video feed */
1071  ast_bridge_set_single_src_video_mode(conference->bridge, chan);
1072  }
1073 }
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_unlock(a)
Definition: astobj2.h:730
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ao2_lock(a)
Definition: astobj2.h:718
int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
Determine if a channel is a video src for the bridge.
Definition: bridge.c:3958
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
structure to hold users read from users.conf
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:3816
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ hangup_data_destroy()

static void hangup_data_destroy ( struct hangup_data hangup)
static

Definition at line 1160 of file app_confbridge.c.

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

Referenced by destroy_conference_bridge().

1161 {
1162  ast_mutex_destroy(&hangup->lock);
1163  ast_cond_destroy(&hangup->cond);
1164 }
ast_cond_t cond
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_mutex_destroy(a)
Definition: lock.h:186
ast_mutex_t lock

◆ hangup_data_init()

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

Definition at line 1151 of file app_confbridge.c.

References ast_cond_init, ast_mutex_init, hangup_data::cond, hangup_data::conference, hangup_data::hungup, hangup_data::lock, and NULL.

Referenced by destroy_conference_bridge().

1152 {
1153  ast_mutex_init(&hangup->lock);
1154  ast_cond_init(&hangup->cond, NULL);
1155 
1156  hangup->conference = conference;
1157  hangup->hungup = 0;
1158 }
struct confbridge_conference * conference
Definition: confbridge.h:272
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
ast_cond_t cond
#define ast_mutex_init(pmutex)
Definition: lock.h:184
struct confbridge_conference * conference
ast_mutex_t lock

◆ hangup_playback()

static int hangup_playback ( void *  data)
static

Hang up the announcer channel.

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

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

Parameters
dataA hangup_data structure
Returns
0

Definition at line 1134 of file app_confbridge.c.

References ast_autoservice_stop(), ast_cond_signal, ast_hangup(), ast_mutex_lock, ast_mutex_unlock, hangup_data::cond, hangup_data::conference, hangup(), hangup_data::hungup, hangup_data::lock, NULL, and confbridge_conference::playback_chan.

Referenced by destroy_conference_bridge().

1135 {
1136  struct hangup_data *hangup = data;
1137 
1139 
1141  hangup->conference->playback_chan = NULL;
1142 
1143  ast_mutex_lock(&hangup->lock);
1144  hangup->hungup = 1;
1145  ast_cond_signal(&hangup->cond);
1146  ast_mutex_unlock(&hangup->lock);
1147 
1148  return 0;
1149 }
#define ast_mutex_lock(a)
Definition: lock.h:187
static int hangup(void *data)
Definition: chan_pjsip.c:2483
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
ast_cond_t cond
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_channel * playback_chan
Definition: confbridge.h:254
struct confbridge_conference * conference
ast_mutex_t lock
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ is_new_rec_file()

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

Definition at line 771 of file app_confbridge.c.

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

Referenced by conf_start_record().

772 {
773  if (!ast_strlen_zero(rec_file)) {
774  if (!*orig_rec_file) {
776  }
777 
778  if (*orig_rec_file
779  && strcmp(ast_str_buffer(*orig_rec_file), rec_file)) {
780  ast_str_set(orig_rec_file, 0, "%s", rec_file);
781  return 1;
782  }
783  }
784  return 0;
785 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define RECORD_FILENAME_INITIAL_SPACE
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ join_callback()

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

Definition at line 2518 of file app_confbridge.c.

References async_play_sound_ready(), and ast_bridge_channel::chan.

Referenced by confbridge_exec().

2519 {
2520  async_play_sound_ready(bridge_channel->chan);
2521  return 0;
2522 }
void async_play_sound_ready(struct ast_channel *chan)
Indicate the initiator of an async sound file is ready for it to play.
struct ast_channel * chan

◆ join_conference_bridge()

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

Join a conference bridge.

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

Definition at line 1679 of file app_confbridge.c.

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

Referenced by confbridge_exec().

1680 {
1681  struct confbridge_conference *conference;
1682  struct post_join_action *action;
1683  int max_members_reached = 0;
1684 
1685  /* We explictly lock the conference bridges container ourselves so that other callers can not create duplicate conferences at the same */
1687 
1688  ast_debug(1, "Trying to find conference bridge '%s'\n", conference_name);
1689 
1690  /* Attempt to find an existing conference bridge */
1691  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
1692  if (conference && conference->b_profile.max_members) {
1693  max_members_reached = conference->b_profile.max_members > conference->activeusers ? 0 : 1;
1694  }
1695 
1696  /* When finding a conference bridge that already exists make sure that it is not locked, and if so that we are not an admin */
1697  if (conference && (max_members_reached || conference->locked) && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
1699  ast_debug(1, "Conference '%s' is locked and caller is not an admin\n", conference_name);
1700  ast_stream_and_wait(user->chan,
1702  "");
1703  ao2_ref(conference, -1);
1704  return NULL;
1705  }
1706 
1707  /* If no conference bridge was found see if we can create one */
1708  if (!conference) {
1709  /* Try to allocate memory for a new conference bridge, if we fail... this won't end well. */
1710  if (!(conference = ao2_alloc(sizeof(*conference), destroy_conference_bridge))) {
1712  ast_log(LOG_ERROR, "Conference '%s' could not be created.\n", conference_name);
1713  return NULL;
1714  }
1715 
1716  /* Setup for the record channel */
1718  if (!conference->record_filename) {
1719  ao2_ref(conference, -1);
1721  return NULL;
1722  }
1723 
1724  /* Setup conference bridge parameters */
1725  ast_copy_string(conference->name, conference_name, sizeof(conference->name));
1726  conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
1727 
1728  /* Create an actual bridge that will do the audio mixing */
1731  app, conference_name, NULL);
1732  if (!conference->bridge) {
1733  ao2_ref(conference, -1);
1735  ast_log(LOG_ERROR, "Conference '%s' mixing bridge could not be created.\n", conference_name);
1736  return NULL;
1737  }
1738 
1739  /* Set the internal sample rate on the bridge from the bridge profile */
1741  /* Set the maximum sample rate on the bridge from the bridge profile */
1743  /* Set the internal mixing interval on the bridge from the bridge profile */
1744  ast_bridge_set_mixing_interval(conference->bridge, conference->b_profile.mix_interval);
1746 
1749  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) {
1755  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST)) {
1757  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
1759  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL)) {
1761  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL)) {
1763  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL)) {
1765  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_FORCE)) {
1768  }
1769  }
1770 
1771  if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_ENABLE_EVENTS)) {
1772  ast_bridge_set_send_sdp_label(conference->bridge, 1);
1773  }
1774 
1775  /* Link it into the conference bridges container */
1776  if (!ao2_link(conference_bridges, conference)) {
1777  ao2_ref(conference, -1);
1780  "Conference '%s' could not be added to the conferences list.\n", conference_name);
1781  return NULL;
1782  }
1783 
1784  /* Set the initial state to EMPTY */
1785  conference->state = CONF_STATE_EMPTY;
1786 
1787  if (alloc_playback_chan(conference)) {
1788  ao2_unlink(conference_bridges, conference);
1789  ao2_ref(conference, -1);
1791  ast_log(LOG_ERROR, "Could not allocate announcer channel for conference '%s'\n", conference_name);
1792  return NULL;
1793  }
1794 
1795  if (push_announcer(conference)) {
1796  ao2_unlink(conference_bridges, conference);
1797  ao2_ref(conference, -1);
1799  ast_log(LOG_ERROR, "Could not add announcer channel for conference '%s' bridge\n", conference_name);
1800  return NULL;
1801  }
1802 
1804  ao2_lock(conference);
1805  conf_start_record(conference);
1806  ao2_unlock(conference);
1807  }
1808 
1809  send_conf_start_event(conference);
1810 
1811  if (!ast_strlen_zero(conference->b_profile.regcontext)) {
1812  if (!ast_exists_extension(NULL, conference->b_profile.regcontext, conference->name, 1, NULL)) {
1813  ast_add_extension(conference->b_profile.regcontext, 1, conference->name, 1, NULL, NULL, "Noop", NULL, NULL, "ConfBridge");
1814  }
1815  }
1816 
1817  ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
1818  }
1819 
1821 
1822  /* Setup conference bridge user parameters */
1823  user->conference = conference;
1824 
1825  ao2_lock(conference);
1826 
1827  /* Determine if the new user should join the conference muted. */
1829  || (!ast_test_flag(&user->u_profile, USER_OPT_ADMIN) && conference->muted)) {
1830  /* Set user level mute request. */
1831  user->muted = 1;
1832  }
1833 
1834  /*
1835  * Suspend any MOH until the user actually joins the bridge of
1836  * the conference. This way any pre-join file playback does not
1837  * need to worry about MOH.
1838  */
1839  user->suspended_moh = 1;
1840 
1841  if (handle_conf_user_join(user)) {
1842  /* Invalid event, nothing was done, so we don't want to process a leave. */
1843  ao2_unlock(conference);
1844  ao2_ref(conference, -1);
1845  user->conference = NULL;
1846  return NULL;
1847  }
1848 
1849  if (ast_check_hangup(user->chan)) {
1850  ao2_unlock(conference);
1851  leave_conference(user);
1852  return NULL;
1853  }
1854 
1855  ao2_unlock(conference);
1856 
1857  /* If an announcement is to be played play it */
1858  if (!ast_strlen_zero(user->u_profile.announcement)) {
1859  if (play_prompt_to_user(user,
1860  user->u_profile.announcement)) {
1861  leave_conference(user);
1862  return NULL;
1863  }
1864  }
1865 
1866  /* Announce number of users if need be */
1868  if (announce_user_count(conference, user, NULL)) {
1869  leave_conference(user);
1870  return NULL;
1871  }
1872  }
1873 
1875  (conference->activeusers > user->u_profile.announce_user_count_all_after)) {
1876  int user_count_res;
1877 
1878  /*
1879  * We have to autoservice the new user because he has not quite
1880  * joined the conference yet.
1881  */
1882  ast_autoservice_start(user->chan);
1883  user_count_res = announce_user_count(conference, NULL, NULL);
1884  ast_autoservice_stop(user->chan);
1885  if (user_count_res) {
1886  leave_conference(user);
1887  return NULL;
1888  }
1889  }
1890 
1891  /* Handle post-join actions */
1892  while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
1893  action->func(user);
1894  ast_free(action);
1895  }
1896 
1897  return conference;
1898 }
void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge)
Set the bridge to be a selective forwarding unit.
Definition: bridge.c:3841
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.
void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
Adjust the internal mixing interval of a bridge used during multimix mode.
Definition: bridge.c:3765
void ast_bridge_set_binaural_active(struct ast_bridge *bridge, unsigned int binaural_active)
Activates the use of binaural signals in a conference bridge.
Definition: bridge.c:3772
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
struct ast_channel * chan
Definition: confbridge.h:277
void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the maximum mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3786
struct confbridge_conference * conference
Definition: confbridge.h:272
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...
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
struct confbridge_user::@93 post_join_list
struct post_join_action::@92 list
struct bridge_profile_sounds * sounds
Definition: confbridge.h:236
unsigned int suspended_moh
Definition: confbridge.h:280
struct confbridge_state * CONF_STATE_EMPTY
Conference state with no active or waiting users.
#define ao2_unlock(a)
Definition: astobj2.h:730
static const char app[]
#define NULL
Definition: resample.c:96
unsigned int announce_user_count_all_after
Definition: confbridge.h:158
void ast_bridge_set_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate)
Force the REMB report estimated bitrate to a specific max value.
Definition: bridge.c:3874
struct bridge_profile b_profile
Definition: confbridge.h:248
unsigned int locked
Definition: confbridge.h:252
#define ast_strlen_zero(foo)
Definition: strings.h:52
static void destroy_conference_bridge(void *obj)
Destroy a conference bridge.
void conf_bridge_profile_copy(struct bridge_profile *dst, struct bridge_profile *src)
copies a bridge profile
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label)
Controls whether to send a "label" attribute in each stream in an SDP.
Definition: bridge.c:4033
void ast_brige_set_remb_behavior(struct ast_bridge *bridge, enum ast_bridge_video_sfu_remb_behavior behavior)
Set the REMB report generation behavior on a bridge.
Definition: bridge.c:3865
static void send_conf_start_event(struct confbridge_conference *conference)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:960
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
unsigned int maximum_sample_rate
Definition: confbridge.h:234
int(* func)(struct confbridge_user *user)
Definition: confbridge.h:266
unsigned int internal_sample_rate
Definition: confbridge.h:233
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard)
Set the amount of time to discard subsequent video updates after a video update has been sent...
Definition: bridge.c:3849
struct confbridge_state * state
Definition: confbridge.h:246
static int conf_start_record(struct confbridge_conference *conference)
unsigned int video_update_discard
Definition: confbridge.h:238
#define LOG_ERROR
Definition: logger.h:285
#define RECORD_FILENAME_INITIAL_SPACE
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
unsigned int muted
Definition: confbridge.h:281
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval)
Set the interval at which a combined REMB frame will be sent to video sources.
Definition: bridge.c:3856
unsigned int max_members
Definition: confbridge.h:232
#define ast_free(a)
Definition: astmm.h:182
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:1814
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
Set the bridge to pick the strongest talker supporting video as the single source video feed...
Definition: bridge.c:3833
struct bridge_profile b_profile
Definition: confbridge.h:273
static int push_announcer(struct confbridge_conference *conference)
Push the announcer channel into the bridge.
The structure that represents a conference bridge.
Definition: confbridge.h:244
unsigned int activeusers
Definition: confbridge.h:249
char regcontext[AST_MAX_CONTEXT]
Definition: confbridge.h:237
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
static int alloc_playback_chan(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:401
unsigned int remb_estimated_bitrate
Definition: confbridge.h:240
unsigned int muted
Definition: confbridge.h:253
struct ast_str * record_filename
Definition: confbridge.h:256
struct user_profile u_profile
Definition: confbridge.h:274
static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
Play back an audio file to a channel.
static int handle_conf_user_join(struct confbridge_user *user)
Call the proper join event handler for the user for the conference bridge&#39;s current state...
unsigned int remb_send_interval
Definition: confbridge.h:239
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
unsigned int mix_interval
Definition: confbridge.h:235
char announcement[PATH_MAX]
Definition: confbridge.h:156
void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the internal mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3779
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
static void leave_conference(struct confbridge_user *user)
Leave a conference.
struct ast_bridge * bridge
Definition: confbridge.h:247
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ kick_conference_participant()

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

Definition at line 3233 of file app_confbridge.c.

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

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

3235 {
3236  int res = -1;
3237  int match;
3238  struct confbridge_user *user = NULL;
3239  int all = !strcasecmp("all", channel);
3240  int participants = !strcasecmp("participants", channel);
3241 
3242  SCOPED_AO2LOCK(bridge_lock, conference);
3243 
3244  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3245  if (user->kicked) {
3246  continue;
3247  }
3248  match = !strcasecmp(channel, ast_channel_name(user->chan));
3249  if (match || all
3250  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3251  user->kicked = 1;
3252  pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3253  ast_bridge_remove(conference->bridge, user->chan);
3254  res = 0;
3255  if (match) {
3256  return res;
3257  }
3258  }
3259  }
3260  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3261  if (user->kicked) {
3262  continue;
3263  }
3264  match = !strcasecmp(channel, ast_channel_name(user->chan));
3265  if (match || all
3266  || (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
3267  user->kicked = 1;
3268  pbx_builtin_setvar_helper(user->chan, "CONFBRIDGE_RESULT", "KICKED");
3269  ast_bridge_remove(conference->bridge, user->chan);
3270  res = 0;
3271  if (match) {
3272  return res;
3273  }
3274  }
3275  }
3276 
3277  return res;
3278 }
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: muted.c:95
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:2315
struct confbridge_user::@94 list
#define NULL
Definition: resample.c:96
struct confbridge_conference::@90 active_list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
structure to hold users read from users.conf
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...
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:271
struct confbridge_conference::@91 waiting_list
struct user_profile u_profile
Definition: confbridge.h:274
unsigned int kicked
Definition: confbridge.h:282
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ leave_conference()

static void leave_conference ( struct confbridge_user user)
static

Leave a conference.

Parameters
userThe conference user

Definition at line 1905 of file app_confbridge.c.

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

Referenced by confbridge_exec(), and join_conference_bridge().

1906 {
1907  struct post_join_action *action;
1908 
1909  ao2_lock(user->conference);
1910  handle_conf_user_leave(user);
1911  ao2_unlock(user->conference);
1912 
1913  /* Discard any post-join actions */
1914  while ((action = AST_LIST_REMOVE_HEAD(&user->post_join_list, list))) {
1915  ast_free(action);
1916  }
1917 
1918  /* Done mucking with the conference, huzzah */
1919  ao2_ref(user->conference, -1);
1920  user->conference = NULL;
1921 }
struct confbridge_conference * conference
Definition: confbridge.h:272
struct confbridge_user::@93 post_join_list
struct post_join_action::@92 list
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
static int handle_conf_user_leave(struct confbridge_user *user)
Call the proper leave event handler for the user for the conference bridge&#39;s current state...
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 4439 of file app_confbridge.c.

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

Referenced by reload().

4440 {
4441  int res = 0;
4442 
4443  if (conf_load_config()) {
4444  ast_log(LOG_ERROR, "Unable to load config. Not loading module.\n");
4445  return AST_MODULE_LOAD_DECLINE;
4446  }
4447 
4450  unload_module();
4451  return AST_MODULE_LOAD_DECLINE;
4452  }
4453 
4454  /* Create a container to hold the conference bridges */
4458  if (!conference_bridges) {
4459  unload_module();
4460  return AST_MODULE_LOAD_DECLINE;
4461  }
4462 
4463  /* Setup manager stasis subscriptions */
4464  res |= manager_confbridge_init();
4465 
4468 
4471 
4473 
4483  res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
4484  if (res) {
4485  unload_module();
4486  return AST_MODULE_LOAD_DECLINE;
4487  }
4488 
4489  return AST_MODULE_LOAD_SUCCESS;
4490 }
static int action_confbridgekick(struct mansession *s, const struct message *m)
int manager_confbridge_init(void)
register stasis message routers to handle manager events for confbridge messages
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int action_confbridgesetsinglevideosrc(struct mansession *s, const struct message *m)
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_custom_function confbridge_info_function
static const char app[]
static int action_confbridgeunlock(struct mansession *s, const struct message *m)
#define NULL
Definition: resample.c:96
#define CONFERENCE_BRIDGE_BUCKETS
struct ast_channel_tech * conf_record_get_tech(void)
Get ConfBridge record channel technology struct.
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
Definition: pbx.h:1517
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
static struct ast_custom_function confbridge_function
struct ast_channel_tech * conf_announce_get_tech(void)
Get ConfBridge announce channel technology struct.
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static int action_confbridgestoprecord(struct mansession *s, const struct message *m)
static int action_confbridgelock(struct mansession *s, const struct message *m)
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int action_confbridgemute(struct mansession *s, const struct message *m)
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int action_confbridgelist(struct mansession *s, const struct message *m)
static const char app2[]
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int action_confbridgestartrecord(struct mansession *s, const struct message *m)
static struct ast_cli_entry cli_confbridge[]
static int unload_module(void)
Called when module is being unloaded.
static int conference_bridge_hash_cb(const void *obj, const int flags)
Hashing function used for conference bridges container.
static int confkick_exec(struct ast_channel *chan, const char *data)
static int conference_bridge_cmp_cb(void *obj, void *arg, int flags)
Comparison function used for conference bridges container.
static int action_confbridgeunmute(struct mansession *s, const struct message *m)
static int action_confbridgelistrooms(struct mansession *s, const struct message *m)
int conf_load_config(void)
load confbridge.conf file
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
static int register_channel_tech(struct ast_channel_tech *tech)
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
static int confbridge_exec(struct ast_channel *chan, const char *data)
The ConfBridge application.

◆ play_file()

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

Definition at line 928 of file app_confbridge.c.

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

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

930 {
931  struct ast_channel *chan;
932  const char *stop_digits;
933  int digit;
934 
935  if (bridge_channel) {
936  chan = bridge_channel->chan;
937  stop_digits = AST_DIGIT_ANY;
938  } else {
939  chan = channel;
940  stop_digits = AST_DIGIT_NONE;
941  }
942 
943  digit = ast_stream_and_wait(chan, filename, stop_digits);
944  if (digit < 0) {
945  ast_log(LOG_WARNING, "Failed to playback file '%s' to channel\n", filename);
946  return -1;
947  }
948 
949  if (digit > 0) {
950  ast_stopstream(bridge_channel->chan);
951  ast_bridge_channel_feature_digit_add(bridge_channel, digit);
952  return 1;
953  }
954 
955  return 0;
956 }
char digit
Main Channel structure associated with a channel.
#define AST_DIGIT_ANY
Definition: file.h:48
#define LOG_WARNING
Definition: logger.h:274
void ast_bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits.
#define ast_log
Definition: astobj2.c:42
#define AST_DIGIT_NONE
Definition: file.h:47
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:1814
struct ast_channel * chan
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ play_prompt_to_user()

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

Play back an audio file to a channel.

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

Definition at line 1038 of file app_confbridge.c.

References ast_stream_and_wait(), and confbridge_user::chan.

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

1039 {
1040  return ast_stream_and_wait(user->chan, filename, "");
1041 }
struct ast_channel * chan
Definition: confbridge.h:277
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:1814

◆ play_sound_file()

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

Play sound file into conference bridge.

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

Definition at line 2035 of file app_confbridge.c.

References play_sound_helper().

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

2036 {
2037  return play_sound_helper(conference, filename, -1);
2038 }
static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)

◆ play_sound_helper()

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

Definition at line 1997 of file app_confbridge.c.

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

Referenced by play_sound_file(), and play_sound_number().

1998 {
1999  struct playback_task_data ptd;
2000 
2001  /* Do not waste resources trying to play files that do not exist */
2002  if (ast_strlen_zero(filename)) {
2003  if (say_number < 0) {
2004  return 0;
2005  }
2006  } else if (!sound_file_exists(filename)) {
2007  return 0;
2008  }
2009 
2010  playback_task_data_init(&ptd, conference, filename, say_number);
2011  if (ast_taskprocessor_push(conference->playback_queue, playback_task, &ptd)) {
2012  if (!ast_strlen_zero(filename)) {
2013  ast_log(LOG_WARNING, "Unable to play file '%s' to conference %s\n",
2014  filename, conference->name);
2015  } else {
2016  ast_log(LOG_WARNING, "Unable to say number '%d' to conference %s\n",
2017  say_number, conference->name);
2018  }
2020  return -1;
2021  }
2022 
2023  /* Wait for the playback to complete */
2024  ast_mutex_lock(&ptd.lock);
2025  while (!ptd.playback_finished) {
2026  ast_cond_wait(&ptd.cond, &ptd.lock);
2027  }
2028  ast_mutex_unlock(&ptd.lock);
2029 
2031 
2032  return 0;
2033 }
static int playback_task(void *data)
Play an announcement into a confbridge.
#define LOG_WARNING
Definition: logger.h:274
const char * filename
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:260
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
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)
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.
static int sound_file_exists(const char *filename)
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ play_sound_number()

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

Play number into the conference bridge.

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

Definition at line 2317 of file app_confbridge.c.

References NULL, and play_sound_helper().

Referenced by announce_user_count().

2318 {
2319  return play_sound_helper(conference, NULL, say_number);
2320 }
#define NULL
Definition: resample.c:96
static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)

◆ playback_common()

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

Definition at line 1923 of file app_confbridge.c.

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

Referenced by async_playback_task(), and playback_task().

1924 {
1925  /* Don't try to play if the playback channel has been hung up */
1926  if (!conference->playback_chan) {
1927  return;
1928  }
1929 
1930  ast_autoservice_stop(conference->playback_chan);
1931 
1932  /* The channel is all under our control, in goes the prompt */
1933  if (!ast_strlen_zero(filename)) {
1934  ast_stream_and_wait(conference->playback_chan, filename, "");
1935  } else if (say_number >= 0) {
1936  ast_say_number(conference->playback_chan, say_number, "",
1937  ast_channel_language(conference->playback_chan), NULL);
1938  }
1939 
1940  ast_autoservice_start(conference->playback_chan);
1941 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
const char * filename
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
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:1814
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:8337
struct ast_channel * playback_chan
Definition: confbridge.h:254
const char * ast_channel_language(const struct ast_channel *chan)

◆ playback_task()

static int playback_task ( void *  data)
static

Play an announcement into a confbridge.

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

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

Parameters
dataA playback_task_data
Returns
0

Definition at line 1965 of file app_confbridge.c.

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

Referenced by play_sound_helper().

1966 {
1967  struct playback_task_data *ptd = data;
1968 
1969  playback_common(ptd->conference, ptd->filename, ptd->say_number);
1970 
1971  ast_mutex_lock(&ptd->lock);
1972  ptd->playback_finished = 1;
1973  ast_cond_signal(&ptd->cond);
1974  ast_mutex_unlock(&ptd->lock);
1975 
1976  return 0;
1977 }
const char * filename
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
struct confbridge_conference * conference
static void playback_common(struct confbridge_conference *conference, const char *filename, int say_number)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ playback_task_data_destroy()

static void playback_task_data_destroy ( struct playback_task_data ptd)
static

Definition at line 1991 of file app_confbridge.c.

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

Referenced by play_sound_helper().

1992 {
1993  ast_mutex_destroy(&ptd->lock);
1994  ast_cond_destroy(&ptd->cond);
1995 }
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ playback_task_data_init()

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

Definition at line 1979 of file app_confbridge.c.

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

Referenced by play_sound_helper().

1981 {
1982  ast_mutex_init(&ptd->lock);
1983  ast_cond_init(&ptd->cond, NULL);
1984 
1985  ptd->filename = filename;
1986  ptd->say_number = say_number;
1987  ptd->conference = conference;
1988  ptd->playback_finished = 0;
1989 }
const char * filename
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
struct confbridge_conference * conference
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ push_announcer()

static int push_announcer ( struct confbridge_conference conference)
static

Push the announcer channel into the bridge.

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

Definition at line 1539 of file app_confbridge.c.

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

Referenced by join_conference_bridge().

1540 {
1541  if (conf_announce_channel_push(conference->playback_chan)) {
1542  ast_hangup(conference->playback_chan);
1543  conference->playback_chan = NULL;
1544  return -1;
1545  }
1546 
1547  ast_autoservice_start(conference->playback_chan);
1548  return 0;
1549 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
#define NULL
Definition: resample.c:96
int conf_announce_channel_push(struct ast_channel *ast)
Push the announcer channel into the conference.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_channel * playback_chan
Definition: confbridge.h:254

◆ register_channel_tech()

static int register_channel_tech ( struct ast_channel_tech tech)
static

Definition at line 4377 of file app_confbridge.c.

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

Referenced by load_module().

4378 {
4380  if (!tech->capabilities) {
4381  return -1;
4382  }
4384  if (ast_channel_register(tech)) {
4385  ast_log(LOG_ERROR, "Unable to register channel technology %s(%s).\n",
4386  tech->type, tech->description);
4387  return -1;
4388  }
4389  return 0;
4390 }
const char *const type
Definition: channel.h:630
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define ast_log
Definition: astobj2.c:42
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define LOG_ERROR
Definition: logger.h:285
struct ast_format_cap * capabilities
Definition: channel.h:633
const char *const description
Definition: channel.h:631

◆ reload()

static int reload ( void  )
static

Definition at line 4492 of file app_confbridge.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEVSTATE_PROVIDER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, conf_reload_config(), load_module(), and unload_module().

4493 {
4494  return conf_reload_config();
4495 }
int conf_reload_config(void)
reload confbridge.conf file

◆ send_conf_end_event()

static void send_conf_end_event ( struct confbridge_conference conference)
static

Definition at line 664 of file app_confbridge.c.

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

Referenced by conf_ended().

665 {
666  send_conf_stasis(conference, NULL, confbridge_end_type(), NULL, 0);
667 }
#define NULL
Definition: resample.c:96
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_end_type(void)
get the confbridge end stasis message type

◆ send_conf_start_event()

static void send_conf_start_event ( struct confbridge_conference conference)
static

Definition at line 659 of file app_confbridge.c.

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

Referenced by join_conference_bridge().

660 {
661  send_conf_stasis(conference, NULL, confbridge_start_type(), NULL, 0);
662 }
#define NULL
Definition: resample.c:96
struct stasis_message_type * confbridge_start_type(void)
get the confbridge start stasis message type
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)

◆ send_conf_stasis()

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

Definition at line 585 of file app_confbridge.c.

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

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

587 {
588  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
589  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
590 
591  json_object = ast_json_pack("{s: s}",
592  "conference", conference->name);
593  if (!json_object) {
594  return;
595  }
596 
597  if (extras) {
598  ast_json_object_update(json_object, extras);
599  }
600 
601  ast_bridge_lock(conference->bridge);
602  msg = ast_bridge_blob_create(type,
603  conference->bridge,
604  chan,
605  json_object);
606  ast_bridge_unlock(conference->bridge);
607  if (!msg) {
608  return;
609  }
610 
611  if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_ENABLE_EVENTS)) {
612  conf_send_event_to_participants(conference, chan, msg);
613  }
614 
615  if (channel_topic) {
616  stasis_publish(ast_channel_topic(chan), msg);
617  } else {
618  stasis_publish(ast_bridge_topic(conference->bridge), msg);
619  }
620 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_object_update(struct ast_json *object, struct ast_json *other)
Update object with all of the fields of other.
Definition: json.c:416
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:248
#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:911
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
void conf_send_event_to_participants(struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message *msg)
Send events to bridge participants.
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_message * ast_bridge_blob_create(struct stasis_message_type *type, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_json *blob)
Creates a ast_bridge_blob message.
Abstract JSON element (object, array, string, int, ...).
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ send_conf_stasis_snapshots()

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

Definition at line 622 of file app_confbridge.c.

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

Referenced by confbridge_handle_atxfer().

625 {
626  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
627  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
628  RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
629 
630  json_object = ast_json_pack("{s: s}",
631  "conference", conference->name);
632  if (!json_object) {
633  return;
634  }
635 
636  if (extras) {
637  ast_json_object_update(json_object, extras);
638  }
639 
640  ast_bridge_lock(conference->bridge);
641  bridge_snapshot = ast_bridge_snapshot_create(conference->bridge);
642  ast_bridge_unlock(conference->bridge);
643  if (!bridge_snapshot) {
644  return;
645  }
646 
648  bridge_snapshot,
649  chan_snapshot,
650  json_object);
651  if (!msg) {
652  return;
653  }
654 
655  stasis_publish(ast_bridge_topic(conference->bridge), msg);
656 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_object_update(struct ast_json *object, struct ast_json *other)
Update object with all of the fields of other.
Definition: json.c:416
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
#define NULL
Definition: resample.c:96
#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:911
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate...
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
char name[MAX_CONF_NAME]
Definition: confbridge.h:245
struct stasis_message * ast_bridge_blob_create_from_snapshots(struct stasis_message_type *type, struct ast_bridge_snapshot *bridge_snapshot, struct ast_channel_snapshot *chan_snapshot, struct ast_json *blob)
Creates a ast_bridge_blob message from snapshots.
struct ast_bridge * bridge
Definition: confbridge.h:247

◆ send_event_hook_callback()

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

Definition at line 2530 of file app_confbridge.c.

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

Referenced by confbridge_exec().

2531 {
2532  struct confbridge_hook_data *hook_data = data;
2533 
2534  if (hook_data->hook_type == AST_BRIDGE_HOOK_TYPE_JOIN) {
2535  send_join_event(hook_data->user, hook_data->conference);
2536  } else {
2537  send_leave_event(hook_data->user, hook_data->conference);
2538  }
2539 
2540  return 0;
2541 }
static void send_leave_event(struct confbridge_user *user, struct confbridge_conference *conference)
static void send_join_event(struct confbridge_user *user, struct confbridge_conference *conference)
struct confbridge_conference * conference
struct confbridge_user * user
enum ast_bridge_hook_type hook_type

◆ send_join_event()

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

Definition at line 669 of file app_confbridge.c.

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_user::chan, confbridge_join_type(), confbridge_user::muted, send_conf_stasis(), confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by send_event_hook_callback().

670 {
671  struct ast_json *json_object;
672 
673  json_object = ast_json_pack("{s: b, s: b}",
674  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
675  "muted", user->muted);
676  if (!json_object) {
677  return;
678  }
679  send_conf_stasis(conference, user->chan, confbridge_join_type(), json_object, 0);
680  ast_json_unref(json_object);
681 }
struct stasis_message_type * confbridge_join_type(void)
get the confbridge join stasis message type
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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)
unsigned int muted
Definition: confbridge.h:281
Abstract JSON element (object, array, string, int, ...).
struct user_profile u_profile
Definition: confbridge.h:274

◆ send_leave_event()

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

Definition at line 683 of file app_confbridge.c.

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_user::chan, confbridge_leave_type(), send_conf_stasis(), confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by send_event_hook_callback().

684 {
685  struct ast_json *json_object;
686 
687  json_object = ast_json_pack("{s: b}",
688  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
689  );
690  if (!json_object) {
691  return;
692  }
693  send_conf_stasis(conference, user->chan, confbridge_leave_type(), json_object, 0);
694  ast_json_unref(json_object);
695 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_message_type * confbridge_leave_type(void)
get the confbridge leave stasis message type
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)
Abstract JSON element (object, array, string, int, ...).
struct user_profile u_profile
Definition: confbridge.h:274

◆ send_mute_event()

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

Definition at line 707 of file app_confbridge.c.

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_user::chan, confbridge_mute_type(), send_conf_stasis(), confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by generic_mute_unmute_user().

708 {
709  struct ast_json *json_object;
710 
711  json_object = ast_json_pack("{s: b}",
712  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
713  );
714  if (!json_object) {
715  return;
716  }
717  send_conf_stasis(conference, user->chan, confbridge_mute_type(), json_object, 1);
718  ast_json_unref(json_object);
719 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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)
Abstract JSON element (object, array, string, int, ...).
struct stasis_message_type * confbridge_mute_type(void)
get the confbridge mute stasis message type
struct user_profile u_profile
Definition: confbridge.h:274

◆ send_start_record_event()

static void send_start_record_event ( struct confbridge_conference conference)
static

Definition at line 697 of file app_confbridge.c.

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

Referenced by conf_start_record().

698 {
700 }
struct stasis_message_type * confbridge_start_record_type(void)
get the confbridge start_record stasis message type
#define NULL
Definition: resample.c:96
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)

◆ send_stop_record_event()

static void send_stop_record_event ( struct confbridge_conference conference)
static

Definition at line 702 of file app_confbridge.c.

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

Referenced by conf_stop_record().

703 {
705 }
#define NULL
Definition: resample.c:96
struct stasis_message_type * confbridge_stop_record_type(void)
get the confbridge stop_record stasis message type
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)

◆ send_unmute_event()

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

Definition at line 721 of file app_confbridge.c.

References ast_json_pack(), ast_json_unref(), ast_test_flag, confbridge_user::chan, confbridge_unmute_type(), send_conf_stasis(), confbridge_user::u_profile, and USER_OPT_ADMIN.

Referenced by generic_mute_unmute_user().

722 {
723  struct ast_json *json_object;
724 
725  json_object = ast_json_pack("{s: b}",
726  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
727  );
728  if (!json_object) {
729  return;
730  }
731  send_conf_stasis(conference, user->chan, confbridge_unmute_type(), json_object, 1);
732  ast_json_unref(json_object);
733 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_channel * chan
Definition: confbridge.h:277
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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_unmute_type(void)
get the confbridge unmute stasis message type
Abstract JSON element (object, array, string, int, ...).
struct user_profile u_profile
Definition: confbridge.h:274

◆ set_rec_filename()

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

Definition at line 735 of file app_confbridge.c.

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

Referenced by conf_start_record().

736 {
737  char *rec_file = conference->b_profile.rec_file;
738  char *ext;
739  time_t now;
740 
741  if (ast_str_strlen(*filename)
743  && !is_new) {
744  return;
745  }
746 
747  time(&now);
748 
749  ast_str_reset(*filename);
750  if (ast_strlen_zero(rec_file)) {
751  ast_str_set(filename, 0, "confbridge-%s-%u.wav", conference->name,
752  (unsigned int) now);
753  } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_TIMESTAMP)) {
754  /* insert time before file extension */
755  ext = strrchr(rec_file, '.');
756  if (ext) {
757  ast_str_set_substr(filename, 0, rec_file, ext - rec_file);
758  ast_str_append(filename, 0, "-%u%s", (unsigned int) now, ext);
759  } else {
760  ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int) now);
761  }
762  } else {
763  ast_str_set(filename, 0, "%s", rec_file);
764  }
765  ast_str_append(filename, 0, ",%s%s,%s",
766  ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND) ? "a" : "",
767  conference->b_profile.rec_options,
768  conference->b_profile.rec_command);
769 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
char rec_command[128]
Definition: confbridge.h:230
char rec_file[PATH_MAX]
Definition: confbridge.h:228
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * ext
Definition: http.c:147
struct bridge_profile b_profile
Definition: confbridge.h:248
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
char rec_options[128]
Definition: confbridge.h:229
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
char * ast_str_set_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring.
Definition: strings.h:1007
char name[MAX_CONF_NAME]
Definition: confbridge.h:245

◆ setup_async_playback_datastore()

static int setup_async_playback_datastore ( struct ast_channel initiator)
static

Prepare the async playback datastore.

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

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

Definition at line 2112 of file app_confbridge.c.

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

Referenced by async_playback_task_data_alloc().

2113 {
2114  struct ast_datastore *async_datastore;
2115 
2116  async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2117  if (async_datastore) {
2118  struct async_datastore_data *add;
2119 
2120  add = async_datastore->data;
2121  add->wait = 1;
2122 
2123  return 0;
2124  }
2125 
2126  async_datastore = ast_datastore_alloc(&async_datastore_info, NULL);
2127  if (!async_datastore) {
2128  return -1;
2129  }
2130 
2131  async_datastore->data = async_datastore_data_alloc();
2132  if (!async_datastore->data) {
2133  ast_datastore_free(async_datastore);
2134  return -1;
2135  }
2136 
2137  ast_channel_datastore_add(initiator, async_datastore);
2138  return 0;
2139 }
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static struct ast_datastore_info async_datastore_info
Datastore used for timing of async announcement playback.
static struct async_datastore_data * async_datastore_data_alloc(void)
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ sound_file_exists()

static int sound_file_exists ( const char *  filename)
static

Definition at line 966 of file app_confbridge.c.

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

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

967 {
968  if (ast_fileexists(filename, NULL, NULL)) {
969  return -1;
970  }
971  ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
972  return 0;
973 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086

◆ unload_module()

static int unload_module ( void  )
static

Called when module is being unloaded.

Definition at line 4393 of file app_confbridge.c.

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

Referenced by load_module(), and reload().

4394 {
4397 
4400 
4402 
4403  ast_manager_unregister("ConfbridgeList");
4404  ast_manager_unregister("ConfbridgeListRooms");
4405  ast_manager_unregister("ConfbridgeMute");
4406  ast_manager_unregister("ConfbridgeUnmute");
4407  ast_manager_unregister("ConfbridgeKick");
4408  ast_manager_unregister("ConfbridgeUnlock");
4409  ast_manager_unregister("ConfbridgeLock");
4410  ast_manager_unregister("ConfbridgeStartRecord");
4411  ast_manager_unregister("ConfbridgeStopRecord");
4412  ast_manager_unregister("ConfbridgeSetSingleVideoSrc");
4413 
4414  /* Unsubscribe from stasis confbridge message type and clean it up. */
4416 
4417  /* Get rid of the conference bridges container. Since we only allow dynamic ones none will be active. */
4420 
4422 
4425 
4426  return 0;
4427 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_custom_function confbridge_info_function
static const char app[]
#define NULL
Definition: resample.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
struct ast_channel_tech * conf_record_get_tech(void)
Get ConfBridge record channel technology struct.
static struct ast_custom_function confbridge_function
struct ast_channel_tech * conf_announce_get_tech(void)
Get ConfBridge announce channel technology struct.
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
void conf_destroy_config(void)
destroy the information loaded from the confbridge.conf file
void manager_confbridge_shutdown(void)
unregister stasis message routers to handle manager events for confbridge messages ...
static void unregister_channel_tech(struct ast_channel_tech *tech)
static const char app2[]
static struct ast_cli_entry cli_confbridge[]
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ unregister_channel_tech()

static void unregister_channel_tech ( struct ast_channel_tech tech)
static

Definition at line 4361 of file app_confbridge.c.

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

Referenced by unload_module().

4362 {
4363  ast_channel_unregister(tech);
4364  ao2_cleanup(tech->capabilities);
4365 }
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
struct ast_format_cap * capabilities
Definition: channel.h:633
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ user_timeout()

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

Definition at line 2392 of file app_confbridge.c.

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

Referenced by confbridge_exec().

2393 {
2395  pbx_builtin_setvar_helper(bridge_channel->chan, "CONFBRIDGE_RESULT", "TIMEOUT");
2396  return -1;
2397 }
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
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 ast_channel * chan

◆ wait_for_initiator()

static void wait_for_initiator ( struct ast_channel initiator)
static

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

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

Parameters
initiatorThe channel that queued the async announcement

Definition at line 2201 of file app_confbridge.c.

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

Referenced by async_playback_task().

2202 {
2203  struct ast_datastore *async_datastore;
2204  struct async_datastore_data *add;
2205 
2206  ast_channel_lock(initiator);
2207  async_datastore = ast_channel_datastore_find(initiator, &async_datastore_info, NULL);
2208  ast_channel_unlock(initiator);
2209 
2210  if (!async_datastore) {
2211  return;
2212  }
2213 
2214  add = async_datastore->data;
2215 
2216  ast_mutex_lock(&add->lock);
2217  while (add->wait) {
2218  ast_cond_wait(&add->cond, &add->lock);
2219  }
2220  ast_mutex_unlock(&add->lock);
2221 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
static struct ast_datastore_info async_datastore_info
Datastore used for timing of async announcement playback.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
#define ast_mutex_unlock(a)
Definition: lock.h:188

Variable Documentation

◆ __mod_info

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

Definition at line 4504 of file app_confbridge.c.

◆ app

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

Definition at line 459 of file app_confbridge.c.

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

◆ app2

const char app2[] = "ConfKick"
static

Definition at line 460 of file app_confbridge.c.

Referenced by _macro_exec(), load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 4504 of file app_confbridge.c.

◆ async_datastore_info

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

Datastore used for timing of async announcement playback.

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

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

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

Definition at line 2080 of file app_confbridge.c.

◆ cli_confbridge

struct ast_cli_entry cli_confbridge[]
static

Definition at line 3800 of file app_confbridge.c.

◆ confbridge_function

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

Definition at line 3810 of file app_confbridge.c.

◆ confbridge_info_function

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

Definition at line 3816 of file app_confbridge.c.

◆ conference_bridges

struct ao2_container* conference_bridges

Container to hold all conference bridges in progress.

Definition at line 469 of file app_confbridge.c.

Referenced by announce_request().