Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
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"

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 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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, .optional_modules = "codec_speex,func_jitterbuffer", }
 
static const char app [] = "ConfBridge"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_datastore_info async_datastore_info
 Datastore used for timing of async announcement playback. More...
 
static struct ast_cli_entry cli_confbridge []
 
static struct ast_custom_function confbridge_function
 
static struct ast_custom_function confbridge_info_function
 
struct ao2_containerconference_bridges
 Container to hold all conference bridges in progress. More...
 

Detailed Description

Conference Bridge application.

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

This is a conference bridge application utilizing the bridging core.

Definition in file app_confbridge.c.

Macro Definition Documentation

◆ CONFERENCE_BRIDGE_BUCKETS

#define CONFERENCE_BRIDGE_BUCKETS   53

Number of buckets our conference bridges container can have

Definition at line 431 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 434 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 4419 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4419 of file app_confbridge.c.

◆ action_confbridgekick()

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

Definition at line 4001 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().

4002 {
4003  const char *conference_name = astman_get_header(m, "Conference");
4004  const char *channel = astman_get_header(m, "Channel");
4005  struct confbridge_conference *conference;
4006  int found;
4007 
4008  if (ast_strlen_zero(conference_name)) {
4009  astman_send_error(s, m, "No Conference name provided.");
4010  return 0;
4011  }
4013  astman_send_error(s, m, "No active conferences.");
4014  return 0;
4015  }
4016 
4017  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4018  if (!conference) {
4019  astman_send_error(s, m, "No Conference by that name found.");
4020  return 0;
4021  }
4022 
4023  found = !kick_conference_participant(conference, channel);
4024  ao2_ref(conference, -1);
4025 
4026  if (found) {
4027  astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4028  } else {
4029  astman_send_error(s, m, "No Channel by that name found in Conference.");
4030  }
4031  return 0;
4032 }
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 ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ast_strlen_zero(a)
Definition: muted.c:73
The structure that represents a conference bridge.
Definition: confbridge.h:241
#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 3833 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().

3834 {
3835  const char *actionid = astman_get_header(m, "ActionID");
3836  const char *conference_name = astman_get_header(m, "Conference");
3837  struct confbridge_user *user;
3838  struct confbridge_conference *conference;
3839  char id_text[80];
3840  int total = 0;
3841 
3842  id_text[0] = '\0';
3843  if (!ast_strlen_zero(actionid)) {
3844  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3845  }
3846  if (ast_strlen_zero(conference_name)) {
3847  astman_send_error(s, m, "No Conference name provided.");
3848  return 0;
3849  }
3851  astman_send_error(s, m, "No active conferences.");
3852  return 0;
3853  }
3854  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3855  if (!conference) {
3856  astman_send_error(s, m, "No Conference by that name found.");
3857  return 0;
3858  }
3859 
3860  astman_send_listack(s, m, "Confbridge user list will follow", "start");
3861 
3862  ao2_lock(conference);
3863  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3864  total += action_confbridgelist_item(s, id_text, conference, user, 0);
3865  }
3866  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3867  total += action_confbridgelist_item(s, id_text, conference, user, 1);
3868  }
3869  ao2_unlock(conference);
3870  ao2_ref(conference, -1);
3871 
3872  astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
3874 
3875  return 0;
3876 }
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
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
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.
struct confbridge_conference::@87 active_list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
The structure that represents a conference bridge.
Definition: confbridge.h:241
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct confbridge_conference::@88 waiting_list
static int total
Definition: res_adsi.c:968
The structure that represents a conference bridge user.
Definition: confbridge.h:268
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 3785 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().

3786 {
3787  struct ast_channel_snapshot *snapshot;
3788  struct ast_str *snap_str;
3789 
3791  if (!snapshot) {
3792  return 0;
3793  }
3794 
3795  snap_str = ast_manager_build_channel_state_string(snapshot);
3796  if (!snap_str) {
3797  ao2_ref(snapshot, -1);
3798  return 0;
3799  }
3800 
3801  astman_append(s,
3802  "Event: ConfbridgeList\r\n"
3803  "%s"
3804  "Conference: %s\r\n"
3805  "Admin: %s\r\n"
3806  "MarkedUser: %s\r\n"
3807  "WaitMarked: %s\r\n"
3808  "EndMarked: %s\r\n"
3809  "Waiting: %s\r\n"
3810  "Muted: %s\r\n"
3811  "Talking: %s\r\n"
3812  "AnsweredTime: %d\r\n"
3813  "%s"
3814  "\r\n",
3815  id_text,
3816  conference->name,
3821  AST_YESNO(waiting),
3822  AST_YESNO(user->muted),
3823  AST_YESNO(user->talking),
3825  ast_str_buffer(snap_str));
3826 
3827  ast_free(snap_str);
3828  ao2_ref(snapshot, -1);
3829 
3830  return 1;
3831 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
struct ast_channel * chan
Definition: confbridge.h:274
#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:2820
#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:278
#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:271
unsigned int talking
Definition: confbridge.h:281
char name[MAX_CONF_NAME]
Definition: confbridge.h:242

◆ action_confbridgelistrooms()

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

Definition at line 3878 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().

3879 {
3880  const char *actionid = astman_get_header(m, "ActionID");
3881  struct confbridge_conference *conference;
3882  struct ao2_iterator iter;
3883  char id_text[512] = "";
3884  int totalitems = 0;
3885 
3886  if (!ast_strlen_zero(actionid)) {
3887  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3888  }
3889 
3891  astman_send_error(s, m, "No active conferences.");
3892  return 0;
3893  }
3894 
3895  astman_send_listack(s, m, "Confbridge conferences will follow", "start");
3896 
3897  /* Traverse the conference list */
3899  while ((conference = ao2_iterator_next(&iter))) {
3900  totalitems++;
3901 
3902  ao2_lock(conference);
3903  astman_append(s,
3904  "Event: ConfbridgeListRooms\r\n"
3905  "%s"
3906  "Conference: %s\r\n"
3907  "Parties: %u\r\n"
3908  "Marked: %u\r\n"
3909  "Locked: %s\r\n"
3910  "Muted: %s\r\n"
3911  "\r\n",
3912  id_text,
3913  conference->name,
3914  conference->activeusers + conference->waitingusers,
3915  conference->markedusers,
3916  AST_YESNO(conference->locked),
3917  AST_YESNO(conference->muted));
3918  ao2_unlock(conference);
3919 
3920  ao2_ref(conference, -1);
3921  }
3922  ao2_iterator_destroy(&iter);
3923 
3924  /* Send final confirmation */
3925  astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
3927  return 0;
3928 }
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:247
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:249
unsigned int waitingusers
Definition: confbridge.h:248
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
#define ast_strlen_zero(a)
Definition: muted.c:73
The structure that represents a conference bridge.
Definition: confbridge.h:241
unsigned int activeusers
Definition: confbridge.h:246
#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:250
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:242
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 3996 of file app_confbridge.c.

References action_lock_unlock_helper().

Referenced by load_module().

3997 {
3998  return action_lock_unlock_helper(s, m, 1);
3999 }
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 3967 of file app_confbridge.c.

References action_mute_unmute_helper().

Referenced by load_module().

3968 {
3969  return action_mute_unmute_helper(s, m, 1);
3970 }
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 4113 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().

4114 {
4115  const char *conference_name = astman_get_header(m, "Conference");
4116  const char *channel = astman_get_header(m, "Channel");
4117  struct confbridge_user *user;
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  }
4124  if (ast_strlen_zero(channel)) {
4125  astman_send_error(s, m, "No channel name provided.");
4126  return 0;
4127  }
4129  astman_send_error(s, m, "No active conferences.");
4130  return 0;
4131  }
4132 
4133  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4134  if (!conference) {
4135  astman_send_error(s, m, "No Conference by that name found.");
4136  return 0;
4137  }
4138 
4139  /* find channel and set as video src. */
4140  ao2_lock(conference);
4141  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4142  if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4143  ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
4144  break;
4145  }
4146  }
4147  ao2_unlock(conference);
4148  ao2_ref(conference, -1);
4149 
4150  /* do not access user after conference unlock. We are just
4151  * using this check to see if it was found or not */
4152  if (!user) {
4153  astman_send_error(s, m, "No channel by that name found in conference.");
4154  return 0;
4155  }
4156  astman_send_ack(s, m, "Conference single video source set.");
4157  return 0;
4158 }
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:274
#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
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#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.
struct confbridge_conference::@87 active_list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
The structure that represents a conference bridge.
Definition: confbridge.h:241
#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:3807
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:268
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:244

◆ action_confbridgestartrecord()

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

Definition at line 4034 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().

4035 {
4036  const char *conference_name = astman_get_header(m, "Conference");
4037  const char *recordfile = astman_get_header(m, "RecordFile");
4038  struct confbridge_conference *conference;
4039 
4040  if (ast_strlen_zero(conference_name)) {
4041  astman_send_error(s, m, "No Conference name provided.");
4042  return 0;
4043  }
4045  astman_send_error(s, m, "No active conferences.");
4046  return 0;
4047  }
4048 
4049  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4050  if (!conference) {
4051  astman_send_error(s, m, "No Conference by that name found.");
4052  return 0;
4053  }
4054 
4055  ao2_lock(conference);
4056  if (conf_is_recording(conference)) {
4057  astman_send_error(s, m, "Conference is already being recorded.");
4058  ao2_unlock(conference);
4059  ao2_ref(conference, -1);
4060  return 0;
4061  }
4062 
4063  if (!ast_strlen_zero(recordfile)) {
4064  ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4065  }
4066 
4067  if (conf_start_record(conference)) {
4068  astman_send_error(s, m, "Internal error starting conference recording.");
4069  ao2_unlock(conference);
4070  ao2_ref(conference, -1);
4071  return 0;
4072  }
4073  ao2_unlock(conference);
4074 
4075  ao2_ref(conference, -1);
4076  astman_send_ack(s, m, "Conference Recording Started.");
4077  return 0;
4078 }
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:226
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:245
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#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)
#define ast_strlen_zero(a)
Definition: muted.c:73
static int conf_is_recording(struct confbridge_conference *conference)
The structure that represents a conference bridge.
Definition: confbridge.h:241
#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 4079 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().

4080 {
4081  const char *conference_name = astman_get_header(m, "Conference");
4082  struct confbridge_conference *conference;
4083 
4084  if (ast_strlen_zero(conference_name)) {
4085  astman_send_error(s, m, "No Conference name provided.");
4086  return 0;
4087  }
4089  astman_send_error(s, m, "No active conferences.");
4090  return 0;
4091  }
4092 
4093  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4094  if (!conference) {
4095  astman_send_error(s, m, "No Conference by that name found.");
4096  return 0;
4097  }
4098 
4099  ao2_lock(conference);
4100  if (conf_stop_record(conference)) {
4101  ao2_unlock(conference);
4102  astman_send_error(s, m, "Internal error while stopping recording.");
4103  ao2_ref(conference, -1);
4104  return 0;
4105  }
4106  ao2_unlock(conference);
4107 
4108  ao2_ref(conference, -1);
4109  astman_send_ack(s, m, "Conference Recording Stopped.");
4110  return 0;
4111 }
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 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_strlen_zero(a)
Definition: muted.c:73
The structure that represents a conference bridge.
Definition: confbridge.h:241
#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 3992 of file app_confbridge.c.

References action_lock_unlock_helper().

Referenced by load_module().

3993 {
3994  return action_lock_unlock_helper(s, m, 0);
3995 }
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 3963 of file app_confbridge.c.

References action_mute_unmute_helper().

Referenced by load_module().

3964 {
3965  return action_mute_unmute_helper(s, m, 0);
3966 }
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 3023 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().

3024 {
3025  struct ast_pbx_args args;
3026  struct ast_pbx *pbx;
3027  char *exten;
3028  char *context;
3029  int priority;
3030  int res;
3031 
3032  memset(&args, 0, sizeof(args));
3033  args.no_hangup_chan = 1;
3034 
3035  ast_channel_lock(bridge_channel->chan);
3036 
3037  /*save off*/
3038  exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3039  context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3040  priority = ast_channel_priority(bridge_channel->chan);
3041  pbx = ast_channel_pbx(bridge_channel->chan);
3042  ast_channel_pbx_set(bridge_channel->chan, NULL);
3043 
3044  /*set new*/
3045  ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3046  ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3047  ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3048 
3049  ast_channel_unlock(bridge_channel->chan);
3050 
3051  /*execute*/
3052  res = ast_pbx_run_args(bridge_channel->chan, &args);
3053 
3054  /*restore*/
3055  ast_channel_lock(bridge_channel->chan);
3056 
3057  ast_channel_exten_set(bridge_channel->chan, exten);
3058  ast_channel_context_set(bridge_channel->chan, context);
3059  ast_channel_priority_set(bridge_channel->chan, priority);
3060  ast_channel_pbx_set(bridge_channel->chan, pbx);
3061 
3062  ast_channel_unlock(bridge_channel->chan);
3063 
3064  return res;
3065 }
Options for ast_pbx_run()
Definition: pbx.h:391
#define ast_channel_lock(chan)
Definition: channel.h:2837
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:4730
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
union conf_menu_action::@81 data
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2838
void ast_channel_pbx_set(struct ast_channel *chan, struct ast_pbx *value)
struct conf_menu_action::@81::@83 dialplan_args
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 2986 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().

2989 {
2990  struct confbridge_user *last_user = NULL;
2991  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
2992 
2993  if (!isadmin) {
2994  play_file(bridge_channel, NULL,
2996  ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
2997  ast_channel_name(bridge_channel->chan),
2998  conference->name);
2999  return -1;
3000  }
3001 
3002  ao2_lock(conference);
3003  last_user = AST_LIST_LAST(&conference->active_list);
3004  if (!last_user) {
3005  ao2_unlock(conference);
3006  return 0;
3007  }
3008 
3009  if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3010  ao2_unlock(conference);
3011  play_file(bridge_channel, NULL,
3013  } else if (!last_user->kicked) {
3014  last_user->kicked = 1;
3015  pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3016  ast_bridge_remove(conference->bridge, last_user->chan);
3017  ao2_unlock(conference);
3018  }
3019 
3020  return 0;
3021 }
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1988
struct ast_channel * chan
Definition: confbridge.h:274
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:234
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:245
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
struct confbridge_conference::@87 active_list
#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:268
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:271
char name[MAX_CONF_NAME]
Definition: confbridge.h:242
unsigned int kicked
Definition: confbridge.h:279
struct ast_bridge * bridge
Definition: confbridge.h:244

◆ action_lock_unlock_helper()

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

Definition at line 3972 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().

3973 {
3974  const char *conference_name = astman_get_header(m, "Conference");
3975  int res = 0;
3976 
3977  if (ast_strlen_zero(conference_name)) {
3978  astman_send_error(s, m, "No Conference name provided.");
3979  return 0;
3980  }
3982  astman_send_error(s, m, "No active conferences.");
3983  return 0;
3984  }
3985  if ((res = generic_lock_unlock_helper(lock, conference_name))) {
3986  astman_send_error(s, m, "No Conference by that name found.");
3987  return 0;
3988  }
3989  astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
3990  return 0;
3991 }
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
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
#define ast_strlen_zero(a)
Definition: muted.c:73
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 3930 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().

3931 {
3932  const char *conference_name = astman_get_header(m, "Conference");
3933  const char *channel_name = astman_get_header(m, "Channel");
3934  int res = 0;
3935 
3936  if (ast_strlen_zero(conference_name)) {
3937  astman_send_error(s, m, "No Conference name provided.");
3938  return 0;
3939  }
3940  if (ast_strlen_zero(channel_name)) {
3941  astman_send_error(s, m, "No channel name provided.");
3942  return 0;
3943  }
3945  astman_send_error(s, m, "No active conferences.");
3946  return 0;
3947  }
3948 
3949  res = generic_mute_unmute_helper(mute, conference_name, channel_name);
3950 
3951  if (res == -1) {
3952  astman_send_error(s, m, "No Conference by that name found.");
3953  return 0;
3954  } else if (res == -2) {
3955  astman_send_error(s, m, "No Channel by that name found in Conference.");
3956  return 0;
3957  }
3958 
3959  astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
3960  return 0;
3961 }
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
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)
#define ast_strlen_zero(a)
Definition: muted.c:73
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 2901 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().

2902 {
2903  char *file_copy = ast_strdupa(playback_file);
2904  char *file = NULL;
2905 
2906  while ((file = strsep(&file_copy, "&"))) {
2907  if (ast_stream_and_wait(bridge_channel->chan, file, "")) {
2908  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2909  return -1;
2910  }
2911  }
2912  return 0;
2913 }
#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:1813
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 2915 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().

2922 {
2923  int i;
2924  int digit = 0;
2925  char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
2926  struct conf_menu_entry new_menu_entry = { { 0, }, };
2927  char *file_copy = ast_strdupa(playback_file);
2928  char *file = NULL;
2929 
2930  while ((file = strsep(&file_copy, "&"))) {
2931  if (ast_streamfile(bridge_channel->chan, file, ast_channel_language(bridge_channel->chan))) {
2932  ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", file);
2933  return -1;
2934  }
2935 
2936  /* now wait for more digits. */
2937  if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
2938  /* streaming finished and no DTMF was entered */
2939  continue;
2940  } else if (digit == -1) {
2941  /* error */
2942  return -1;
2943  } else {
2944  break; /* dtmf was entered */
2945  }
2946  }
2947  if (!digit) {
2948  /* streaming finished on all files and no DTMF was entered */
2949  return -1;
2950  }
2951  ast_stopstream(bridge_channel->chan);
2952 
2953  /* If we get here, then DTMF has been entered, This means no
2954  * additional prompts should be played for this menu entry */
2955  *stop_prompts = 1;
2956 
2957  /* If a digit was pressed during the payback, update
2958  * the dtmf string and look for a new menu entry in the
2959  * menu structure */
2960  ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
2961  for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
2962  dtmf[i] = cur_dtmf[i];
2963  if (!dtmf[i]) {
2964  dtmf[i] = (char) digit;
2965  dtmf[i + 1] = '\0';
2966  i = -1;
2967  break;
2968  }
2969  }
2970  /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
2971  * If this is the case, no new DTMF sequence should be looked for. */
2972  if (i != -1) {
2973  return 0;
2974  }
2975 
2976  if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
2977  execute_menu_entry(conference,
2978  user,
2979  bridge_channel,
2980  &new_menu_entry, menu);
2981  conf_menu_entry_destroy(&new_menu_entry);
2982  }
2983  return 0;
2984 }
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:134
#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:1775
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 2845 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().

2848 {
2849  unsigned int binaural;
2850  ast_bridge_channel_lock_bridge(bridge_channel);
2851  binaural = !bridge_channel->binaural_suspended;
2852  bridge_channel->binaural_suspended = binaural;
2853  ast_bridge_unlock(bridge_channel->bridge);
2854  return play_file(bridge_channel, NULL, (binaural ?
2857 }
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:234
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:489
struct bridge_profile b_profile
Definition: confbridge.h:270
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 2830 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().

2833 {
2834  int mute;
2835 
2836  /* Toggle user level mute request. */
2837  mute = !user->muted;
2838  generic_mute_unmute_user(conference, user, mute);
2839 
2840  return play_file(bridge_channel, NULL,
2842  conference->b_profile.sounds)) < 0;
2843 }
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:234
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:245
unsigned int muted
Definition: confbridge.h:278
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 2859 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().

2860 {
2861  struct confbridge_user *cur_user = NULL;
2862  const char *sound_to_play;
2863  int mute;
2864 
2865  ao2_lock(conference);
2866 
2867  /* Toggle bridge level mute request. */
2868  mute = !conference->muted;
2869  conference->muted = mute;
2870 
2871  AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) {
2872  if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
2873  /* Set user level to bridge level mute request. */
2874  cur_user->muted = mute;
2875  conf_update_user_mute(cur_user);
2876  }
2877  }
2878 
2879  ao2_unlock(conference);
2880 
2881  sound_to_play = conf_get_sound(
2883  conference->b_profile.sounds);
2884 
2885  if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
2886  /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
2887  ast_stream_and_wait(user->chan, sound_to_play, "");
2888 
2889  /* Announce to the group that all participants are muted */
2890  ast_autoservice_start(user->chan);
2891  play_sound_file(conference, sound_to_play);
2892  ast_autoservice_stop(user->chan);
2893  } else {
2894  /* Playing the sound asynchronously lets the sound be heard by everyone at once */
2895  async_play_sound_file(conference, sound_to_play, user->chan);
2896  }
2897 
2898  return 0;
2899 }
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:274
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:234
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
#define NULL
Definition: resample.c:96
static int mute
Definition: chan_alsa.c:144
struct bridge_profile b_profile
Definition: confbridge.h:245
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:225
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
struct confbridge_conference::@87 active_list
unsigned int muted
Definition: confbridge.h:278
#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:1813
const char * ast_channel_language(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:268
unsigned int muted
Definition: confbridge.h:250
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:271
struct confbridge_user::@91 list

◆ alloc_playback_chan()

static int alloc_playback_chan ( struct confbridge_conference conference)
static

Definition at line 1464 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().

1465 {
1466  struct ast_format_cap *cap;
1467  char taskprocessor_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1468 
1470  if (!cap) {
1471  return -1;
1472  }
1474  conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
1475  conference->name, NULL);
1476  ao2_ref(cap, -1);
1477  if (!conference->playback_chan) {
1478  return -1;
1479  }
1480 
1481  /* To make sure playback_chan has the same language as the bridge */
1482  ast_channel_lock(conference->playback_chan);
1483  ast_channel_language_set(conference->playback_chan, conference->b_profile.language);
1484  ast_channel_unlock(conference->playback_chan);
1485 
1486  ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
1487  ast_channel_name(conference->playback_chan), conference->name);
1488 
1489  ast_taskprocessor_build_name(taskprocessor_name, sizeof(taskprocessor_name),
1490  "Confbridge/%s", conference->name);
1491  conference->playback_queue = ast_taskprocessor_get(taskprocessor_name, TPS_REF_DEFAULT);
1492  if (!conference->playback_queue) {
1493  ast_hangup(conference->playback_chan);
1494  conference->playback_chan = NULL;
1495  return -1;
1496  }
1497  return 0;
1498 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
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:257
struct bridge_profile b_profile
Definition: confbridge.h:245
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:6312
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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:225
#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:2838
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2523
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * playback_chan
Definition: confbridge.h:251
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:242

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

955 {
956  const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
957  const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
958  const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
959 
960  if (conference->activeusers <= 1) {
961  /* Awww we are the only person in the conference bridge OR we only have waitmarked users */
962  return 0;
963  } else if (conference->activeusers == 2) {
964  if (user) {
965  /* Eep, there is one other person */
966  if (play_file(bridge_channel, user->chan, only_one) < 0) {
967  return -1;
968  }
969  } else {
970  play_sound_file(conference, only_one);
971  }
972  } else {
973  /* Alas multiple others in here */
974  if (user) {
975  if (ast_stream_and_wait(user->chan,
976  there_are,
977  "")) {
978  return -1;
979  }
980  if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
981  return -1;
982  }
983  if (play_file(bridge_channel, user->chan, other_in_party) < 0) {
984  return -1;
985  }
986  } else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
987  play_sound_file(conference, there_are);
988  play_sound_number(conference, conference->activeusers - 1);
989  play_sound_file(conference, other_in_party);
990  }
991  }
992  return 0;
993 }
struct ast_channel * chan
Definition: confbridge.h:274
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:234
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:245
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:1813
unsigned int activeusers
Definition: confbridge.h:246
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:8176
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 4419 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data* async_datastore_data_alloc ( void  )
static

Definition at line 2050 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().

2051 {
2052  struct async_datastore_data *add;
2053 
2054  add = ast_malloc(sizeof(*add));
2055  if (!add) {
2056  return NULL;
2057  }
2058 
2059  ast_mutex_init(&add->lock);
2060  ast_cond_init(&add->cond, NULL);
2061  add->wait = 1;
2062 
2063  return add;
2064 }
#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 2018 of file app_confbridge.c.

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

2019 {
2020  struct async_datastore_data *add = data;
2021 
2022  ast_mutex_destroy(&add->lock);
2023  ast_cond_destroy(&add->cond);
2024 
2025  ast_free(add);
2026 }
#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 2457 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().

2459 {
2460  struct async_delete_name_rec_task_data *atd;
2461 
2462  if (ast_strlen_zero(filename)) {
2463  return 0;
2464  } else if (!sound_file_exists(filename)) {
2465  return 0;
2466  }
2467 
2469  if (!atd) {
2470  return -1;
2471  }
2472 
2474  ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2475  conference->name, filename);
2477  return -1;
2478  }
2479 
2480  return 0;
2481 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:257
#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)
#define ast_strlen_zero(a)
Definition: muted.c:73
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:242

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

2446 {
2447  struct async_delete_name_rec_task_data *atd = data;
2448 
2449  ast_filedelete(atd->filename, NULL);
2450  ast_log(LOG_DEBUG, "Conference '%s' removed user name file '%s'\n",
2451  atd->conference->name, atd->filename);
2452 
2454  return 0;
2455 }
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:242

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

2416 {
2417  struct async_delete_name_rec_task_data *atd;
2418 
2419  atd = ast_malloc(sizeof(*atd) + strlen(filename) + 1);
2420  if (!atd) {
2421  return NULL;
2422  }
2423 
2424  /* Safe */
2425  strcpy(atd->filename, filename);
2426  atd->conference = conference;
2427 
2428  return atd;
2429 }
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 2431 of file app_confbridge.c.

References ast_free.

Referenced by async_delete_name_rec(), and async_delete_name_rec_task().

2432 {
2433  ast_free(atd);
2434 }
#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 2247 of file app_confbridge.c.

References async_play_sound_helper().

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

2249 {
2250  return async_play_sound_helper(conference, filename, -1, initiator);
2251 }
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 2213 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().

2215 {
2216  struct async_playback_task_data *aptd;
2217 
2218  /* Do not waste resources trying to play files that do not exist */
2219  if (ast_strlen_zero(filename)) {
2220  if (say_number < 0) {
2221  return 0;
2222  }
2223  } else if (!sound_file_exists(filename)) {
2224  return 0;
2225  }
2226 
2227  aptd = async_playback_task_data_alloc(conference, filename, say_number, initiator);
2228  if (!aptd) {
2229  return -1;
2230  }
2231 
2232  if (ast_taskprocessor_push(conference->playback_queue, async_playback_task, aptd)) {
2233  if (!ast_strlen_zero(filename)) {
2234  ast_log(LOG_WARNING, "Unable to play file '%s' to conference '%s'\n",
2235  filename, conference->name);
2236  } else {
2237  ast_log(LOG_WARNING, "Unable to say number '%d' to conference '%s'\n",
2238  say_number, conference->name);
2239  }
2241  return -1;
2242  }
2243 
2244  return 0;
2245 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:257
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.
#define ast_strlen_zero(a)
Definition: muted.c:73
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:242

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

2254 {
2255  struct ast_datastore *async_datastore;
2256  struct async_datastore_data *add;
2257 
2258  ast_channel_lock(chan);
2259  async_datastore = ast_channel_datastore_find(chan, &async_datastore_info, NULL);
2260  ast_channel_unlock(chan);
2261  if (!async_datastore) {
2262  return;
2263  }
2264 
2265  add = async_datastore->data;
2266 
2267  ast_mutex_lock(&add->lock);
2268  add->wait = 0;
2269  ast_cond_signal(&add->cond);
2270  ast_mutex_unlock(&add->lock);
2271 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
#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:2379
#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:2838
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 2198 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().

2199 {
2200  struct async_playback_task_data *aptd = data;
2201 
2202  /* Wait for the initiator to get back in the bridge or be hung up */
2203  if (aptd->initiator) {
2205  }
2206 
2207  playback_common(aptd->conference, aptd->filename, aptd->say_number);
2208 
2210  return 0;
2211 }
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 2106 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().

2109 {
2110  struct async_playback_task_data *aptd;
2111 
2112  aptd = ast_malloc(sizeof(*aptd) + strlen(filename) + 1);
2113  if (!aptd) {
2114  return NULL;
2115  }
2116 
2117  /* Safe */
2118  strcpy(aptd->filename, filename);
2119  aptd->say_number = say_number;
2120 
2121  /* You may think that we need to bump the conference refcount since we are pushing
2122  * this task to the taskprocessor.
2123  *
2124  * In this case, that actually causes a problem. The destructor for the conference
2125  * pushes a hangup task into the taskprocessor and waits for it to complete before
2126  * continuing. If the destructor gets called from a taskprocessor task, we're
2127  * deadlocked.
2128  *
2129  * So is there a risk of the conference being freed out from under us? No. Since
2130  * the destructor pushes a task into the taskprocessor and waits for it to complete,
2131  * the destructor cannot free the conference out from under us. No further tasks
2132  * can be queued onto the taskprocessor after the hangup since no channels are referencing
2133  * the conference at that point any more.
2134  */
2135  aptd->conference = conference;
2136 
2137  aptd->initiator = initiator;
2138  if (initiator) {
2139  ast_channel_ref(initiator);
2140  ast_channel_lock(aptd->initiator);
2141  /* We don't really care if this fails. If the datastore fails to get set up
2142  * we'll still play the announcement. It's possible that the sound will be
2143  * clipped for the initiator, but that's not the end of the world.
2144  */
2147  }
2148 
2149  return aptd;
2150 }
#define ast_channel_lock(chan)
Definition: channel.h:2837
#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:2838
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2862
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 2152 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().

2153 {
2155  ast_free(aptd);
2156 }
struct ast_channel * initiator
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2884
#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 3538 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().

3539 {
3540  int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
3541 
3542  if (res == -1) {
3543  ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
3544  return -1;
3545  } else if (res == -2) {
3546  if (!strcasecmp("all", a->argv[3]) || !strcasecmp("participants", a->argv[3])) {
3547  ast_cli(a->fd, "No participants found in conference %s\n", a->argv[2]);
3548  } else {
3549  ast_cli(a->fd, "No channel named '%s' found in conference %s\n", a->argv[3], a->argv[2]);
3550  }
3551  return -1;
3552  }
3553  ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
3554  return 0;
3555 }
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 3244 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().

3245 {
3246  int which = 0;
3247  struct confbridge_conference *conference;
3248  char *res = NULL;
3249  int wordlen = strlen(word);
3250  struct ao2_iterator iter;
3251 
3253  while ((conference = ao2_iterator_next(&iter))) {
3254  if (!strncasecmp(conference->name, word, wordlen) && ++which > state) {
3255  res = ast_strdup(conference->name);
3256  ao2_ref(conference, -1);
3257  break;
3258  }
3259  ao2_ref(conference, -1);
3260  }
3261  ao2_iterator_destroy(&iter);
3262 
3263  return res;
3264 }
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:241
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:242
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 3266 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().

3267 {
3268  int which = 0;
3269  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3270  struct confbridge_user *user;
3271  char *res = NULL;
3272  int wordlen = strlen(word);
3273 
3274  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3275  if (!conference) {
3276  return NULL;
3277  }
3278 
3279  if (!strncasecmp("all", word, wordlen) && ++which > state) {
3280  return ast_strdup("all");
3281  }
3282 
3283  if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3284  return ast_strdup("participants");
3285  }
3286 
3287  {
3288  SCOPED_AO2LOCK(bridge_lock, conference);
3290  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3291  res = ast_strdup(ast_channel_name(user->chan));
3292  return res;
3293  }
3294  }
3296  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3297  res = ast_strdup(ast_channel_name(user->chan));
3298  return res;
3299  }
3300  }
3301  }
3302 
3303  return NULL;
3304 }
static char user[512]
struct ast_channel * chan
Definition: confbridge.h:274
struct confbridge_conference * conference
Definition: confbridge.h:269
#define OBJ_KEY
Definition: astobj2.h:1155
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#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:851
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
struct confbridge_conference::@87 active_list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
The structure that represents a conference bridge.
Definition: confbridge.h:241
#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)
struct confbridge_conference::@88 waiting_list
The structure that represents a conference bridge user.
Definition: confbridge.h:268
struct confbridge_user::@91 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 1413 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().

1414 {
1415  struct post_join_action *action;
1416  if (!(action = ast_calloc(1, sizeof(*action)))) {
1417  return -1;
1418  }
1419  action->func = func;
1420  AST_LIST_INSERT_TAIL(&user->post_join_list, action, list);
1421  return 0;
1422 }
struct confbridge_user::@90 post_join_list
struct post_join_action::@89 list
int(* func)(struct confbridge_user *user)
Definition: confbridge.h:263
#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 4220 of file app_confbridge.c.

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

Referenced by join_active(), and join_unmarked().

4221 {
4222  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4223  conference->activeusers++;
4224 }
struct post_join_action::@89 list
struct confbridge_conference::@87 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:246

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

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

Referenced by join_marked().

4227 {
4228  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4229  conference->activeusers++;
4230  conference->markedusers++;
4231 }
unsigned int markedusers
Definition: confbridge.h:247
struct post_join_action::@89 list
struct confbridge_conference::@87 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:246

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

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

Referenced by conf_default_join_waitmarked().

4234 {
4235  AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4236  conference->waitingusers++;
4237 }
unsigned int waitingusers
Definition: confbridge.h:248
struct post_join_action::@89 list
#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::@88 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 1441 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().

1442 {
1443  struct pbx_find_info q = { .stacklen = 0 };
1444 
1445  /* Called with a reference to conference */
1446  ao2_unlink(conference_bridges, conference);
1447  send_conf_end_event(conference);
1448  if (!ast_strlen_zero(conference->b_profile.regcontext) &&
1449  pbx_find_extension(NULL, NULL, &q, conference->b_profile.regcontext,
1450  conference->name, 1, NULL, "", E_MATCH)) {
1452  conference->name, 1, NULL);
1453  }
1454  ao2_lock(conference);
1455  conf_stop_record(conference);
1456  ao2_unlock(conference);
1457 }
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:4943
struct bridge_profile b_profile
Definition: confbridge.h:245
#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
#define ast_strlen_zero(a)
Definition: muted.c:73
int stacklen
Definition: extconf.h:238
char regcontext[AST_MAX_CONTEXT]
Definition: confbridge.h:235
char name[MAX_CONF_NAME]
Definition: confbridge.h:242
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 755 of file app_confbridge.c.

References ao2_find, and OBJ_KEY.

Referenced by confbridge_publish_manager_event().

756 {
757  return ao2_find(conference_bridges, conference_name, OBJ_KEY);
758 }
#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 2315 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().

2316 {
2317  char pin_guess[MAX_PIN+1] = { 0, };
2318  const char *pin = user->u_profile.pin;
2319  char *tmp = pin_guess;
2320  int i, res;
2321  unsigned int len = MAX_PIN;
2322 
2323  /*
2324  * NOTE: We have not joined a conference yet so we have to use
2325  * the bridge profile requested by the user.
2326  */
2327 
2328  /* give them three tries to get the pin right */
2329  for (i = 0; i < 3; i++) {
2330  if (ast_app_getdata(chan,
2332  tmp, len, 0) >= 0) {
2333  if (!strcasecmp(pin, pin_guess)) {
2334  return 0;
2335  }
2336  }
2337  ast_streamfile(chan,
2339  ast_channel_language(chan));
2340  res = ast_waitstream(chan, AST_DIGIT_ANY);
2341  if (res > 0) {
2342  /* Account for digit already read during ivalid pin playback
2343  * resetting pin buf. */
2344  pin_guess[0] = res;
2345  pin_guess[1] = '\0';
2346  tmp = pin_guess + 1;
2347  len = MAX_PIN - 1;
2348  } else {
2349  /* reset pin buf as empty buffer. */
2350  tmp = pin_guess;
2351  len = MAX_PIN;
2352  }
2353  }
2354  return -1;
2355 }
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:234
char pin[MAX_PIN]
Definition: confbridge.h:152
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:270
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:1775
const char * ast_channel_language(const struct ast_channel *chan)
struct user_profile u_profile
Definition: confbridge.h:271
#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 494 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().

495 {
496  switch (sound) {
498  return S_OR(custom_sounds->hasjoin, "conf-hasjoin");
499  case CONF_SOUND_HAS_LEFT:
500  return S_OR(custom_sounds->hasleft, "conf-hasleft");
501  case CONF_SOUND_KICKED:
502  return S_OR(custom_sounds->kicked, "conf-kicked");
503  case CONF_SOUND_MUTED:
504  return S_OR(custom_sounds->muted, "conf-muted");
505  case CONF_SOUND_UNMUTED:
506  return S_OR(custom_sounds->unmuted, "conf-unmuted");
508  return S_OR(custom_sounds->binauralon, "confbridge-binaural-on");
510  return S_OR(custom_sounds->binauraloff, "confbridge-binaural-off");
511  case CONF_SOUND_ONLY_ONE:
512  return S_OR(custom_sounds->onlyone, "conf-onlyone");
514  return S_OR(custom_sounds->thereare, "conf-thereare");
516  return S_OR(custom_sounds->otherinparty, "conf-otherinparty");
518  return S_OR(custom_sounds->placeintoconf, "conf-placeintoconf");
520  return S_OR(custom_sounds->waitforleader, "conf-waitforleader");
522  return S_OR(custom_sounds->leaderhasleft, "conf-leaderhasleft");
523  case CONF_SOUND_GET_PIN:
524  return S_OR(custom_sounds->getpin, "conf-getpin");
526  return S_OR(custom_sounds->invalidpin, "conf-invalidpin");
528  return S_OR(custom_sounds->onlyperson, "conf-onlyperson");
529  case CONF_SOUND_LOCKED:
530  return S_OR(custom_sounds->locked, "conf-locked");
532  return S_OR(custom_sounds->lockednow, "conf-lockednow");
534  return S_OR(custom_sounds->unlockednow, "conf-unlockednow");
536  return S_OR(custom_sounds->errormenu, "conf-errormenu");
537  case CONF_SOUND_JOIN:
538  return S_OR(custom_sounds->join, "confbridge-join");
539  case CONF_SOUND_LEAVE:
540  return S_OR(custom_sounds->leave, "confbridge-leave");
542  return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
544  return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
545  case CONF_SOUND_BEGIN:
546  return S_OR(custom_sounds->begin, "confbridge-conf-begin");
547  }
548 
549  return "";
550 }
const ast_string_field unlockednow
Definition: confbridge.h:220
const ast_string_field thereare
Definition: confbridge.h:220
const ast_string_field join
Definition: confbridge.h:220
const ast_string_field otherinparty
Definition: confbridge.h:220
const ast_string_field onlyone
Definition: confbridge.h:220
const ast_string_field hasjoin
Definition: confbridge.h:220
const ast_string_field begin
Definition: confbridge.h:220
const ast_string_field errormenu
Definition: confbridge.h:220
const ast_string_field binauraloff
Definition: confbridge.h:220
const ast_string_field waitforleader
Definition: confbridge.h:220
const ast_string_field getpin
Definition: confbridge.h:220
const ast_string_field participantsmuted
Definition: confbridge.h:220
const ast_string_field leave
Definition: confbridge.h:220
const ast_string_field lockednow
Definition: confbridge.h:220
const ast_string_field binauralon
Definition: confbridge.h:220
const ast_string_field participantsunmuted
Definition: confbridge.h:220
const ast_string_field unmuted
Definition: confbridge.h:220
const ast_string_field invalidpin
Definition: confbridge.h:220
const ast_string_field onlyperson
Definition: confbridge.h:220
#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:220
const ast_string_field leaderhasleft
Definition: confbridge.h:220
const ast_string_field kicked
Definition: confbridge.h:220
const ast_string_field locked
Definition: confbridge.h:220
const ast_string_field placeintoconf
Definition: confbridge.h:220
const ast_string_field hasleft
Definition: confbridge.h:220

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

3182 {
3183  /* See if music on hold is playing */
3184  conf_moh_suspend(user);
3185 
3186  /* execute the list of actions associated with this menu entry */
3187  execute_menu_entry(user->conference, user, bridge_channel, menu_entry, menu);
3188 
3189  /* See if music on hold needs to be started back up again */
3190  conf_moh_unsuspend(user);
3191 
3192  async_play_sound_ready(bridge_channel->chan);
3193 
3194  return 0;
3195 }
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:269
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 1425 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().

1426 {
1427  ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference->name);
1428 }
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:242

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

1390 {
1391  /* If we have not been quieted play back that they are waiting for the leader */
1394  /* user hungup while the sound was playing */
1395  return -1;
1396  }
1397  return 0;
1398 }
struct confbridge_conference * conference
Definition: confbridge.h:269
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:234
struct bridge_profile b_profile
Definition: confbridge.h:245
struct user_profile u_profile
Definition: confbridge.h:271
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 1400 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().

1401 {
1402  /* If audio prompts have not been quieted or this prompt quieted play it on out */
1404  if (play_prompt_to_user(user,
1406  /* user hungup while the sound was playing */
1407  return -1;
1408  }
1409  }
1410  return 0;
1411 }
struct confbridge_conference * conference
Definition: confbridge.h:269
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:234
struct bridge_profile b_profile
Definition: confbridge.h:245
struct user_profile u_profile
Definition: confbridge.h:271
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 1430 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().

1431 {
1432  /* If we are the second participant we may need to stop music on hold on the first */
1433  struct confbridge_user *first_user = AST_LIST_FIRST(&conference->active_list);
1434 
1435  if (ast_test_flag(&first_user->u_profile, USER_OPT_MUSICONHOLD)) {
1436  conf_moh_stop(first_user);
1437  }
1438  conf_update_user_mute(first_user);
1439 }
#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::@87 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:268
struct user_profile u_profile
Definition: confbridge.h:271

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

2288 {
2289  struct confbridge_user *user = hook_pvt;
2291  struct ast_json *talking_extras;
2292 
2293  conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2294  if (!conference) {
2295  /* Remove the hook since the conference does not exist. */
2296  return -1;
2297  }
2298 
2299  ao2_lock(conference);
2300  user->talking = talking;
2301  ao2_unlock(conference);
2302 
2303  talking_extras = ast_json_pack("{s: s, s: b}",
2304  "talking_status", talking ? "on" : "off",
2305  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2306  if (!talking_extras) {
2307  return 0;
2308  }
2309 
2310  send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2311  ast_json_unref(talking_extras);
2312  return 0;
2313 }
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:269
#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:851
#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:241
#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:268
struct user_profile u_profile
Definition: confbridge.h:271
unsigned int talking
Definition: confbridge.h:281
char name[MAX_CONF_NAME]
Definition: confbridge.h:242

◆ conf_is_recording()

static int conf_is_recording ( struct confbridge_conference conference)
static

Definition at line 771 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().

772 {
773  return conference->record_chan != NULL;
774 }
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:252

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

1329 {
1330  user->playing_moh = 1;
1331  if (!user->suspended_moh) {
1332  int in_bridge;
1333 
1334  /*
1335  * Locking the ast_bridge here is the only way to hold off the
1336  * call to ast_bridge_join() in confbridge_exec() from
1337  * interfering with the bridge and MOH operations here.
1338  */
1340 
1341  /*
1342  * Temporarily suspend the user from the bridge so we have
1343  * control to start MOH if needed.
1344  */
1345  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1346  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1347  if (in_bridge) {
1348  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1349  }
1350 
1352  }
1353 }
struct ast_channel * chan
Definition: confbridge.h:274
unsigned int playing_moh
Definition: confbridge.h:280
struct confbridge_conference * conference
Definition: confbridge.h:269
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3080
unsigned int suspended_moh
Definition: confbridge.h:277
#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:7705
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:489
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:476
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3059
struct user_profile u_profile
Definition: confbridge.h:271
char moh_class[128]
Definition: confbridge.h:153
struct ast_bridge * bridge
Definition: confbridge.h:244

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

1302 {
1303  user->playing_moh = 0;
1304  if (!user->suspended_moh) {
1305  int in_bridge;
1306 
1307  /*
1308  * Locking the ast_bridge here is the only way to hold off the
1309  * call to ast_bridge_join() in confbridge_exec() from
1310  * interfering with the bridge and MOH operations here.
1311  */
1313 
1314  /*
1315  * Temporarily suspend the user from the bridge so we have
1316  * control to stop MOH if needed.
1317  */
1318  in_bridge = !ast_bridge_suspend(user->conference->bridge, user->chan);
1319  ast_moh_stop(user->chan);
1320  if (in_bridge) {
1321  ast_bridge_unsuspend(user->conference->bridge, user->chan);
1322  }
1323 
1325  }
1326 }
struct ast_channel * chan
Definition: confbridge.h:274
unsigned int playing_moh
Definition: confbridge.h:280
struct confbridge_conference * conference
Definition: confbridge.h:269
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3080
unsigned int suspended_moh
Definition: confbridge.h:277
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7715
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:489
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:476
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3059
struct ast_bridge * bridge
Definition: confbridge.h:244

◆ conf_moh_suspend()

static void conf_moh_suspend ( struct confbridge_user user)
static

Definition at line 1380 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().

1381 {
1382  ao2_lock(user->conference);
1383  if (user->suspended_moh++ == 0 && user->playing_moh) {
1384  ast_moh_stop(user->chan);
1385  }
1386  ao2_unlock(user->conference);
1387 }
struct ast_channel * chan
Definition: confbridge.h:274
unsigned int playing_moh
Definition: confbridge.h:280
struct confbridge_conference * conference
Definition: confbridge.h:269
unsigned int suspended_moh
Definition: confbridge.h:277
#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:7715
#define ao2_lock(a)
Definition: astobj2.h:718

◆ conf_moh_unsuspend()

static void conf_moh_unsuspend ( struct confbridge_user user)
static

Definition at line 1363 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().

1364 {
1365  ao2_lock(user->conference);
1366  if (--user->suspended_moh == 0 && user->playing_moh) {
1367  ast_moh_start(user->chan, user->u_profile.moh_class, NULL);
1368  }
1369  ao2_unlock(user->conference);
1370 }
struct ast_channel * chan
Definition: confbridge.h:274
unsigned int playing_moh
Definition: confbridge.h:280
struct confbridge_conference * conference
Definition: confbridge.h:269
unsigned int suspended_moh
Definition: confbridge.h:277
#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:7705
struct user_profile u_profile
Definition: confbridge.h:271
char moh_class[128]
Definition: confbridge.h:153

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

4253 {
4254  struct confbridge_user *only_user = AST_LIST_FIRST(&conference->active_list);
4255 
4256  /* Turn on MOH if the single participant is set up for it */
4257  if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4258  conf_moh_start(only_user);
4259  }
4260  conf_update_user_mute(only_user);
4261 }
#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.
void conf_moh_start(struct confbridge_user *user)
Start MOH for the conference user.
struct confbridge_conference::@87 active_list
The structure that represents a conference bridge user.
Definition: confbridge.h:268
struct user_profile u_profile
Definition: confbridge.h:271

◆ conf_rec_name()

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

Definition at line 2364 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().

2365 {
2366  char destdir[PATH_MAX];
2367  int res;
2368  int duration = 20;
2369 
2370  snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2371 
2372  if (ast_mkdir(destdir, 0777) != 0) {
2373  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2374  return -1;
2375  }
2376  snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2377  "%s/confbridge-name-%s-%s", destdir,
2378  conf_name, ast_channel_uniqueid(user->chan));
2379 
2381  res = ast_play_and_record(user->chan,
2382  "vm-rec-name",
2383  user->name_rec_location,
2384  10,
2385  "sln",
2386  &duration,
2387  NULL,
2389  0,
2390  NULL);
2391  } else {
2392  res = ast_record_review(user->chan,
2393  "vm-rec-name",
2394  user->name_rec_location,
2395  10,
2396  "sln",
2397  &duration,
2398  NULL);
2399  }
2400 
2401  if (res == -1) {
2403  user->name_rec_location[0] = '\0';
2404  return -1;
2405  }
2406  return 0;
2407 }
struct ast_channel * chan
Definition: confbridge.h:274
#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:2412
#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:1920
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:151
char name_rec_location[PATH_MAX]
Definition: confbridge.h:273
#define PATH_MAX
Definition: asterisk.h:40
struct user_profile u_profile
Definition: confbridge.h:271
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1959
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2101

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

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

Referenced by leave_active(), and leave_unmarked().

4240 {
4241  AST_LIST_REMOVE(&conference->active_list, user, list);
4242  conference->activeusers--;
4243 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
struct confbridge_conference::@87 active_list
unsigned int activeusers
Definition: confbridge.h:246
struct confbridge_user::@91 list

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

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

Referenced by leave_marked().

4246 {
4247  AST_LIST_REMOVE(&conference->active_list, user, list);
4248  conference->activeusers--;
4249  conference->markedusers--;
4250 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int markedusers
Definition: confbridge.h:247
struct confbridge_conference::@87 active_list
unsigned int activeusers
Definition: confbridge.h:246
struct confbridge_user::@91 list

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

4264 {
4265  AST_LIST_REMOVE(&conference->waiting_list, user, list);
4266  conference->waitingusers--;
4267 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int waitingusers
Definition: confbridge.h:248
struct confbridge_conference::@88 waiting_list
struct confbridge_user::@91 list

◆ conf_start_record()

static int conf_start_record ( struct confbridge_conference conference)
static

Definition at line 819 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().

820 {
821  struct ast_app *mixmonapp;
822  struct ast_channel *chan;
823  struct ast_format_cap *cap;
824  struct ast_bridge_features *features;
825 
826  if (conf_is_recording(conference)) {
827  return -1;
828  }
829 
830  mixmonapp = pbx_findapp("MixMonitor");
831  if (!mixmonapp) {
832  ast_log(LOG_WARNING, "Cannot record ConfBridge, MixMonitor app is not installed\n");
833  return -1;
834  }
835 
836  features = ast_bridge_features_new();
837  if (!features) {
838  return -1;
839  }
841 
843  if (!cap) {
844  ast_bridge_features_destroy(features);
845  return -1;
846  }
848 
849  /* Create the recording channel. */
850  chan = ast_request("CBRec", cap, NULL, NULL, conference->name, NULL);
851  ao2_ref(cap, -1);
852  if (!chan) {
853  ast_bridge_features_destroy(features);
854  return -1;
855  }
856 
857  /* Start recording. */
858  set_rec_filename(conference, &conference->record_filename,
859  is_new_rec_file(conference->b_profile.rec_file, &conference->orig_rec_file));
860  ast_answer(chan);
861  pbx_exec(chan, mixmonapp, ast_str_buffer(conference->record_filename));
862 
863  /* Put the channel into the conference bridge. */
864  ast_channel_ref(chan);
865  conference->record_chan = chan;
866  if (ast_bridge_impart(conference->bridge, chan, NULL, features,
868  ast_hangup(chan);
869  ast_channel_unref(chan);
870  conference->record_chan = NULL;
871  return -1;
872  }
873 
874  ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
875  send_start_record_event(conference);
876 
877  return 0;
878 }
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:2873
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:224
#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:226
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:252
struct ast_str * orig_rec_file
Definition: confbridge.h:254
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3732
static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
struct bridge_profile b_profile
Definition: confbridge.h:245
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:6312
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:1915
#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:2523
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3741
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:2862
ast_app: A registered application
Definition: pbx_app.c:45
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2780
struct ast_str * record_filename
Definition: confbridge.h:253
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:242
static void send_start_record_event(struct confbridge_conference *conference)
struct ast_bridge * bridge
Definition: confbridge.h:244

◆ conf_stop_record()

static int conf_stop_record ( struct confbridge_conference conference)
static

Definition at line 787 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().

788 {
789  struct ast_channel *chan;
790  struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
791 
792  if (!conf_is_recording(conference)) {
793  return -1;
794  }
795 
796  /* Remove the recording channel from the conference bridge. */
797  chan = conference->record_chan;
798  conference->record_chan = NULL;
799  ast_queue_frame(chan, &f);
800  ast_channel_unref(chan);
801 
802  ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
803  send_stop_record_event(conference);
804 
805  return 0;
806 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2873
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:224
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:252
struct bridge_profile b_profile
Definition: confbridge.h:245
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:1135
#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 1243 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().

1244 {
1245  int mute_user;
1246  int mute_system;
1247  int mute_effective;
1248 
1249  /* User level mute request. */
1250  mute_user = user->muted;
1251 
1252  /* System level mute request. */
1253  mute_system = user->playing_moh
1254  /*
1255  * Do not allow waitmarked users to talk to anyone unless there
1256  * is a marked user present.
1257  */
1258  || (!user->conference->markedusers
1260 
1261  mute_effective = mute_user || mute_system;
1262 
1263  ast_debug(1, "User %s is %s: user:%d system:%d.\n",
1264  ast_channel_name(user->chan), mute_effective ? "muted" : "unmuted",
1265  mute_user, mute_system);
1266  user->features.mute = mute_effective;
1267  ast_test_suite_event_notify("CONF_MUTE_UPDATE",
1268  "Mode: %s\r\n"
1269  "Conference: %s\r\n"
1270  "Channel: %s",
1271  mute_effective ? "muted" : "unmuted",
1272  user->conference->b_profile.name,
1273  ast_channel_name(user->chan));
1274 }
struct ast_channel * chan
Definition: confbridge.h:274
unsigned int playing_moh
Definition: confbridge.h:280
struct confbridge_conference * conference
Definition: confbridge.h:269
#define ast_test_flag(p, flag)
Definition: utils.h:63
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:224
unsigned int markedusers
Definition: confbridge.h:247
struct bridge_profile b_profile
Definition: confbridge.h:245
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
unsigned int muted
Definition: confbridge.h:278
struct ast_bridge_features features
Definition: confbridge.h:275
const char * ast_channel_name(const struct ast_channel *chan)
struct user_profile u_profile
Definition: confbridge.h:271

◆ confbridge_exec()

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

The ConfBridge application.

Definition at line 2509 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_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().

2510 {
2511  int res = 0, volume_adjustments[2];
2512  int quiet = 0;
2513  int async_delete_task_pushed = 0;
2514  char *parse;
2515  const char *b_profile_name = NULL;
2516  const char *u_profile_name = NULL;
2517  const char *menu_profile_name = NULL;
2518  struct confbridge_conference *conference = NULL;
2519  struct confbridge_user user = {
2520  .chan = chan,
2521  .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2522  .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2523  .tech_args.drop_silence = 0,
2524  };
2525  struct confbridge_hook_data *join_hook_data;
2526  struct confbridge_hook_data *leave_hook_data;
2527 
2529  AST_APP_ARG(conf_name);
2530  AST_APP_ARG(b_profile_name);
2531  AST_APP_ARG(u_profile_name);
2532  AST_APP_ARG(menu_profile_name);
2533  );
2534 
2535  if (ast_channel_state(chan) != AST_STATE_UP) {
2536  ast_answer(chan);
2537  }
2538 
2539  if (ast_bridge_features_init(&user.features)) {
2540  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2541  res = -1;
2542  goto confbridge_cleanup;
2543  }
2544 
2545  /* We need to make a copy of the input string if we are going to modify it! */
2546  parse = ast_strdupa(data);
2547 
2548  AST_STANDARD_APP_ARGS(args, parse);
2549 
2550  if (ast_strlen_zero(args.conf_name)) {
2551  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2552  ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2553  res = -1;
2554  goto confbridge_cleanup;
2555  }
2556 
2557  if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2558  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2559  ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2560  res = -1;
2561  goto confbridge_cleanup;
2562  }
2563 
2564  /* bridge profile name */
2565  if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2566  b_profile_name = args.b_profile_name;
2567  }
2568  if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2569  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2570  ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2571  b_profile_name : DEFAULT_BRIDGE_PROFILE);
2572  res = -1;
2573  goto confbridge_cleanup;
2574  }
2575 
2576  /* user profile name */
2577  if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2578  u_profile_name = args.u_profile_name;
2579  }
2580  if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2581  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2582  ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2583  u_profile_name : DEFAULT_USER_PROFILE);
2584  res = -1;
2585  goto confbridge_cleanup;
2586  }
2587 
2588  quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2589 
2590  /* ask for a PIN immediately after finding user profile. This has to be
2591  * prompted for requardless of quiet setting. */
2592  if (!ast_strlen_zero(user.u_profile.pin)) {
2593  if (conf_get_pin(chan, &user)) {
2594  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2595  res = -1; /* invalid PIN */
2596  goto confbridge_cleanup;
2597  }
2598  }
2599 
2600  /* See if we need them to record a intro name */
2601  if (!quiet &&
2604  if (conf_rec_name(&user, args.conf_name)) {
2605  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2606  res = -1; /* Hangup during name recording */
2607  goto confbridge_cleanup;
2608  }
2609  }
2610 
2611  /* menu name */
2612  if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2613  menu_profile_name = args.menu_profile_name;
2614  }
2615 
2616  if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2617  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2618  ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2619  menu_profile_name : DEFAULT_MENU_PROFILE);
2620  res = -1;
2621  goto confbridge_cleanup;
2622  }
2623 
2624  /* Set if DTMF should pass through for this user or not */
2626  user.features.dtmf_passthrough = 1;
2627  } else {
2628  user.features.dtmf_passthrough = 0;
2629  }
2630 
2631  /* Set if text messaging is enabled for this user or not */
2633  user.features.text_messaging = 1;
2634  } else {
2635  user.features.text_messaging = 0;
2636  }
2637 
2638  /* Set dsp threshold values if present */
2639  if (user.u_profile.talking_threshold) {
2641  }
2642  if (user.u_profile.silence_threshold) {
2644  }
2645 
2646  /* Set a talker indicate call back if talking detection is requested */
2650  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2651  res = -1;
2652  goto confbridge_cleanup;
2653  }
2654  }
2655 
2656  /* Look for a conference bridge matching the provided name */
2657  if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2658  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2659  res = -1;
2660  goto confbridge_cleanup;
2661  }
2662 
2663  /* Keep a copy of volume adjustments so we can restore them later if need be */
2664  volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2665  volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2666 
2668  user.tech_args.drop_silence = 1;
2669  }
2670 
2672  ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2673  }
2674 
2676  ast_func_write(chan, "DENOISE(rx)", "on");
2677  }
2678 
2679  /* if this user has a intro, play it before entering */
2680  if (!ast_strlen_zero(user.name_rec_location)) {
2681  ast_autoservice_start(chan);
2682  play_sound_file(conference, user.name_rec_location);
2683  play_sound_file(conference,
2685  ast_autoservice_stop(chan);
2686  }
2687 
2688  /* Play the Join sound to both the conference and the user entering. */
2689  if (!quiet) {
2690  const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2691 
2692  if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2693  ast_stream_and_wait(chan, join_sound, "");
2694  ast_autoservice_start(chan);
2695  play_sound_file(conference, join_sound);
2696  ast_autoservice_stop(chan);
2697  } else {
2698  async_play_sound_file(conference, join_sound, chan);
2699  }
2700  }
2701 
2702  if (user.u_profile.timeout) {
2704  0,
2705  user.u_profile.timeout * 1000,
2706  user_timeout,
2707  NULL,
2708  NULL,
2710  }
2711 
2712  /* See if we need to automatically set this user as a video source or not */
2714 
2715  conf_moh_unsuspend(&user);
2716 
2717  join_hook_data = ast_malloc(sizeof(*join_hook_data));
2718  if (!join_hook_data) {
2719  res = -1;
2720  goto confbridge_cleanup;
2721  }
2722  join_hook_data->user = &user;
2723  join_hook_data->conference = conference;
2724  join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2726  join_hook_data, ast_free_ptr, 0);
2727  if (res) {
2728  ast_free(join_hook_data);
2729  ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2730  goto confbridge_cleanup;
2731  }
2732 
2733  leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2734  if (!leave_hook_data) {
2735  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2736  res = -1;
2737  goto confbridge_cleanup;
2738  }
2739  leave_hook_data->user = &user;
2740  leave_hook_data->conference = conference;
2741  leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2743  leave_hook_data, ast_free_ptr, 0);
2744  if (res) {
2745  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2746  ast_free(leave_hook_data);
2747  ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2748  goto confbridge_cleanup;
2749  }
2750 
2753  }
2754 
2755  ast_bridge_join(conference->bridge,
2756  chan,
2757  NULL,
2758  &user.features,
2759  &user.tech_args,
2760  0);
2761 
2762  /* This is a catch-all in case joining the bridge failed or for some reason
2763  * an async announcement got queued up and hasn't been told to play yet
2764  */
2765  async_play_sound_ready(chan);
2766 
2767  if (!user.kicked && ast_check_hangup(chan)) {
2768  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2769  }
2770 
2771  /* if we're shutting down, don't attempt to do further processing */
2772  if (ast_shutting_down()) {
2773  /*
2774  * Not taking any new calls at this time. We cannot create
2775  * the announcer channel if this is the first channel into
2776  * the conference and we certainly cannot create any
2777  * recording channel.
2778  */
2779  leave_conference(&user);
2780  conference = NULL;
2781  goto confbridge_cleanup;
2782  }
2783 
2784  /* If this user was a video source, we need to clean up and possibly pick a new source. */
2785  handle_video_on_exit(conference, user.chan);
2786 
2787  /* if this user has a intro, play it when leaving */
2788  if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2789  async_play_sound_file(conference, user.name_rec_location, NULL);
2790  async_play_sound_file(conference,
2792  async_delete_name_rec(conference, user.name_rec_location);
2793  async_delete_task_pushed = 1;
2794  }
2795 
2796  /* play the leave sound */
2797  if (!quiet) {
2798  const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2799  async_play_sound_file(conference, leave_sound, NULL);
2800  }
2801 
2802  /* If the user was kicked from the conference play back the audio prompt for it */
2803  if (!quiet && user.kicked) {
2804  res = ast_stream_and_wait(chan,
2806  "");
2807  }
2808 
2809  /* Easy as pie, depart this channel from the conference bridge */
2810  leave_conference(&user);
2811  conference = NULL;
2812 
2813  /* Restore volume adjustments to previous values in case they were changed */
2814  if (volume_adjustments[0]) {
2815  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2816  }
2817  if (volume_adjustments[1]) {
2818  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2819  }
2820 
2821 confbridge_cleanup:
2822  if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2824  }
2827  return res;
2828 }
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:3711
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:274
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:3339
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:3329
#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:3678
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:3349
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:234
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:160
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:245
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:3373
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
char language[MAX_LANGUAGE]
Definition: confbridge.h:225
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:441
char pin[MAX_PIN]
Definition: confbridge.h:152
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:158
#define ast_strlen_zero(a)
Definition: muted.c:73
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:162
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:1813
struct bridge_profile b_profile
Definition: confbridge.h:270
struct ast_bridge_features features
Definition: confbridge.h:275
The structure that represents a conference bridge.
Definition: confbridge.h:241
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:273
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:2780
const char * ast_channel_language(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:268
#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:271
#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:279
#define DEFAULT_SILENCE_THRESHOLD
Definition: confbridge.h:49
struct ast_bridge_tech_optimizations tech_args
Definition: confbridge.h:276
#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:244
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 1530 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().

1531 {
1532  struct ast_channel_snapshot *old_snapshot;
1533  struct ast_channel_snapshot *new_snapshot;
1534  char *confbr_name = NULL;
1535  char *comma;
1537  struct confbridge_user *user = NULL;
1538  int found_user = 0;
1539  struct ast_json *json_object;
1540 
1542  && strcmp(msg->to_transferee.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1543  && msg->target) {
1544  /* We're transferring a bridge to an extension */
1545  old_snapshot = msg->to_transferee.channel_snapshot;
1546  new_snapshot = msg->target;
1547  } else if (msg->to_transfer_target.channel_snapshot
1548  && strcmp(msg->to_transfer_target.channel_snapshot->dialplan->appl, "ConfBridge") == 0
1549  && msg->transferee) {
1550  /* We're transferring a call to a bridge */
1551  old_snapshot = msg->to_transfer_target.channel_snapshot;
1552  new_snapshot = msg->transferee;
1553  } else {
1554  ast_log(LOG_ERROR, "Could not determine proper channels\n");
1555  return;
1556  }
1557 
1558  /*
1559  * old_snapshot->data should have the original parameters passed to
1560  * the ConfBridge app:
1561  * conference[,bridge_profile[,user_profile[,menu]]]
1562  * We'll use "conference" to look up the bridge.
1563  *
1564  * We _could_ use old_snapshot->bridgeid to get the bridge but
1565  * that would involve locking the conference_bridges container
1566  * and iterating over it looking for a matching bridge.
1567  */
1568  if (ast_strlen_zero(old_snapshot->dialplan->data)) {
1569  ast_log(LOG_ERROR, "Channel '%s' didn't have app data set\n", old_snapshot->base->name);
1570  return;
1571  }
1572  confbr_name = ast_strdupa(old_snapshot->dialplan->data);
1573  comma = strchr(confbr_name, ',');
1574  if (comma) {
1575  *comma = '\0';
1576  }
1577 
1578  ast_debug(1, "Confbr: %s Leaving: %s Joining: %s\n", confbr_name, old_snapshot->base->name, new_snapshot->base->name);
1579 
1580  conference = ao2_find(conference_bridges, confbr_name, OBJ_SEARCH_KEY);
1581  if (!conference) {
1582  ast_log(LOG_ERROR, "Conference bridge '%s' not found\n", confbr_name);
1583  return;
1584  }
1585  ao2_lock(conference);
1586 
1587  /*
1588  * We need to grab the user profile for the departing user in order to
1589  * properly format the join/leave messages.
1590  */
1591  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
1592  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1593  found_user = 1;
1594  break;
1595  }
1596  }
1597 
1598  /*
1599  * If we didn't find the user in the active list, try the waiting list.
1600  */
1601  if (!found_user && conference->waitingusers) {
1602  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
1603  if (strcasecmp(ast_channel_name(user->chan), old_snapshot->base->name) == 0) {
1604  found_user = 1;
1605  break;
1606  }
1607  }
1608  }
1609 
1610  if (!found_user) {
1611  ast_log(LOG_ERROR, "Unable to find user profile for channel '%s' in bridge '%s'\n",
1612  old_snapshot->base->name, confbr_name);
1613  return;
1614  }
1615 
1616  /*
1617  * We're going to use the existing user profile to create the messages.
1618  */
1619  json_object = ast_json_pack("{s: b}",
1620  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN)
1621  );
1622  if (!json_object) {
1623  return;
1624  }
1625 
1626  send_conf_stasis_snapshots(conference, old_snapshot, confbridge_leave_type(), json_object);
1627  ast_json_unref(json_object);
1628 
1629  json_object = ast_json_pack("{s: b, s: b}",
1630  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN),
1631  "muted", user->muted);
1632  if (!json_object) {
1633  return;
1634  }
1635  send_conf_stasis_snapshots(conference, new_snapshot, confbridge_join_type(), json_object);
1636  ast_json_unref(json_object);
1637 }
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:274
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