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