Asterisk - The Open Source Telephony Project  GIT-master-1b41629
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 4422 of file app_confbridge.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4422 of file app_confbridge.c.

◆ action_confbridgekick()

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

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

4005 {
4006  const char *conference_name = astman_get_header(m, "Conference");
4007  const char *channel = astman_get_header(m, "Channel");
4008  struct confbridge_conference *conference;
4009  int found;
4010 
4011  if (ast_strlen_zero(conference_name)) {
4012  astman_send_error(s, m, "No Conference name provided.");
4013  return 0;
4014  }
4016  astman_send_error(s, m, "No active conferences.");
4017  return 0;
4018  }
4019 
4020  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4021  if (!conference) {
4022  astman_send_error(s, m, "No Conference by that name found.");
4023  return 0;
4024  }
4025 
4026  found = !kick_conference_participant(conference, channel);
4027  ao2_ref(conference, -1);
4028 
4029  if (found) {
4030  astman_send_ack(s, m, !strcmp("all", channel) ? "All participants kicked" : "User kicked");
4031  } else {
4032  astman_send_error(s, m, "No Channel by that name found in Conference.");
4033  }
4034  return 0;
4035 }
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:243
#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 3836 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().

3837 {
3838  const char *actionid = astman_get_header(m, "ActionID");
3839  const char *conference_name = astman_get_header(m, "Conference");
3840  struct confbridge_user *user;
3841  struct confbridge_conference *conference;
3842  char id_text[80];
3843  int total = 0;
3844 
3845  id_text[0] = '\0';
3846  if (!ast_strlen_zero(actionid)) {
3847  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
3848  }
3849  if (ast_strlen_zero(conference_name)) {
3850  astman_send_error(s, m, "No Conference name provided.");
3851  return 0;
3852  }
3854  astman_send_error(s, m, "No active conferences.");
3855  return 0;
3856  }
3857  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3858  if (!conference) {
3859  astman_send_error(s, m, "No Conference by that name found.");
3860  return 0;
3861  }
3862 
3863  astman_send_listack(s, m, "Confbridge user list will follow", "start");
3864 
3865  ao2_lock(conference);
3866  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
3867  total += action_confbridgelist_item(s, id_text, conference, user, 0);
3868  }
3869  AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
3870  total += action_confbridgelist_item(s, id_text, conference, user, 1);
3871  }
3872  ao2_unlock(conference);
3873  ao2_ref(conference, -1);
3874 
3875  astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
3877 
3878  return 0;
3879 }
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:243
#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:270
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 3788 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().

3789 {
3790  struct ast_channel_snapshot *snapshot;
3791  struct ast_str *snap_str;
3792 
3794  if (!snapshot) {
3795  return 0;
3796  }
3797 
3798  snap_str = ast_manager_build_channel_state_string(snapshot);
3799  if (!snap_str) {
3800  ao2_ref(snapshot, -1);
3801  return 0;
3802  }
3803 
3804  astman_append(s,
3805  "Event: ConfbridgeList\r\n"
3806  "%s"
3807  "Conference: %s\r\n"
3808  "Admin: %s\r\n"
3809  "MarkedUser: %s\r\n"
3810  "WaitMarked: %s\r\n"
3811  "EndMarked: %s\r\n"
3812  "Waiting: %s\r\n"
3813  "Muted: %s\r\n"
3814  "Talking: %s\r\n"
3815  "AnsweredTime: %d\r\n"
3816  "%s"
3817  "\r\n",
3818  id_text,
3819  conference->name,
3824  AST_YESNO(waiting),
3825  AST_YESNO(user->muted),
3826  AST_YESNO(user->talking),
3828  ast_str_buffer(snap_str));
3829 
3830  ast_free(snap_str);
3831  ao2_ref(snapshot, -1);
3832 
3833  return 1;
3834 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
struct ast_channel * chan
Definition: confbridge.h:276
#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:2840
#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:280
#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:273
unsigned int talking
Definition: confbridge.h:283
char name[MAX_CONF_NAME]
Definition: confbridge.h:244

◆ action_confbridgelistrooms()

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

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

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

References action_lock_unlock_helper().

Referenced by load_module().

4000 {
4001  return action_lock_unlock_helper(s, m, 1);
4002 }
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 3970 of file app_confbridge.c.

References action_mute_unmute_helper().

Referenced by load_module().

3971 {
3972  return action_mute_unmute_helper(s, m, 1);
3973 }
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 4116 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().

4117 {
4118  const char *conference_name = astman_get_header(m, "Conference");
4119  const char *channel = astman_get_header(m, "Channel");
4120  struct confbridge_user *user;
4121  struct confbridge_conference *conference;
4122 
4123  if (ast_strlen_zero(conference_name)) {
4124  astman_send_error(s, m, "No Conference name provided.");
4125  return 0;
4126  }
4127  if (ast_strlen_zero(channel)) {
4128  astman_send_error(s, m, "No channel name provided.");
4129  return 0;
4130  }
4132  astman_send_error(s, m, "No active conferences.");
4133  return 0;
4134  }
4135 
4136  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4137  if (!conference) {
4138  astman_send_error(s, m, "No Conference by that name found.");
4139  return 0;
4140  }
4141 
4142  /* find channel and set as video src. */
4143  ao2_lock(conference);
4144  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
4145  if (!strncmp(channel, ast_channel_name(user->chan), strlen(channel))) {
4146  ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
4147  break;
4148  }
4149  }
4150  ao2_unlock(conference);
4151  ao2_ref(conference, -1);
4152 
4153  /* do not access user after conference unlock. We are just
4154  * using this check to see if it was found or not */
4155  if (!user) {
4156  astman_send_error(s, m, "No channel by that name found in conference.");
4157  return 0;
4158  }
4159  astman_send_ack(s, m, "Conference single video source set.");
4160  return 0;
4161 }
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:276
#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:243
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
Set a bridge to feed a single video source to all participants.
Definition: bridge.c:3816
const char * ast_channel_name(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:270
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:246

◆ action_confbridgestartrecord()

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

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

4038 {
4039  const char *conference_name = astman_get_header(m, "Conference");
4040  const char *recordfile = astman_get_header(m, "RecordFile");
4041  struct confbridge_conference *conference;
4042 
4043  if (ast_strlen_zero(conference_name)) {
4044  astman_send_error(s, m, "No Conference name provided.");
4045  return 0;
4046  }
4048  astman_send_error(s, m, "No active conferences.");
4049  return 0;
4050  }
4051 
4052  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4053  if (!conference) {
4054  astman_send_error(s, m, "No Conference by that name found.");
4055  return 0;
4056  }
4057 
4058  ao2_lock(conference);
4059  if (conf_is_recording(conference)) {
4060  astman_send_error(s, m, "Conference is already being recorded.");
4061  ao2_unlock(conference);
4062  ao2_ref(conference, -1);
4063  return 0;
4064  }
4065 
4066  if (!ast_strlen_zero(recordfile)) {
4067  ast_copy_string(conference->b_profile.rec_file, recordfile, sizeof(conference->b_profile.rec_file));
4068  }
4069 
4070  if (conf_start_record(conference)) {
4071  astman_send_error(s, m, "Internal error starting conference recording.");
4072  ao2_unlock(conference);
4073  ao2_ref(conference, -1);
4074  return 0;
4075  }
4076  ao2_unlock(conference);
4077 
4078  ao2_ref(conference, -1);
4079  astman_send_ack(s, m, "Conference Recording Started.");
4080  return 0;
4081 }
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:227
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:247
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:243
#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 4082 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().

4083 {
4084  const char *conference_name = astman_get_header(m, "Conference");
4085  struct confbridge_conference *conference;
4086 
4087  if (ast_strlen_zero(conference_name)) {
4088  astman_send_error(s, m, "No Conference name provided.");
4089  return 0;
4090  }
4092  astman_send_error(s, m, "No active conferences.");
4093  return 0;
4094  }
4095 
4096  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
4097  if (!conference) {
4098  astman_send_error(s, m, "No Conference by that name found.");
4099  return 0;
4100  }
4101 
4102  ao2_lock(conference);
4103  if (conf_stop_record(conference)) {
4104  ao2_unlock(conference);
4105  astman_send_error(s, m, "Internal error while stopping recording.");
4106  ao2_ref(conference, -1);
4107  return 0;
4108  }
4109  ao2_unlock(conference);
4110 
4111  ao2_ref(conference, -1);
4112  astman_send_ack(s, m, "Conference Recording Stopped.");
4113  return 0;
4114 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
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:243
#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 3995 of file app_confbridge.c.

References action_lock_unlock_helper().

Referenced by load_module().

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

References action_mute_unmute_helper().

Referenced by load_module().

3967 {
3968  return action_mute_unmute_helper(s, m, 0);
3969 }
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 3026 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().

3027 {
3028  struct ast_pbx_args args;
3029  struct ast_pbx *pbx;
3030  char *exten;
3031  char *context;
3032  int priority;
3033  int res;
3034 
3035  memset(&args, 0, sizeof(args));
3036  args.no_hangup_chan = 1;
3037 
3038  ast_channel_lock(bridge_channel->chan);
3039 
3040  /*save off*/
3041  exten = ast_strdupa(ast_channel_exten(bridge_channel->chan));
3042  context = ast_strdupa(ast_channel_context(bridge_channel->chan));
3043  priority = ast_channel_priority(bridge_channel->chan);
3044  pbx = ast_channel_pbx(bridge_channel->chan);
3045  ast_channel_pbx_set(bridge_channel->chan, NULL);
3046 
3047  /*set new*/
3048  ast_channel_exten_set(bridge_channel->chan, menu_action->data.dialplan_args.exten);
3049  ast_channel_context_set(bridge_channel->chan, menu_action->data.dialplan_args.context);
3050  ast_channel_priority_set(bridge_channel->chan, menu_action->data.dialplan_args.priority);
3051 
3052  ast_channel_unlock(bridge_channel->chan);
3053 
3054  /*execute*/
3055  res = ast_pbx_run_args(bridge_channel->chan, &args);
3056 
3057  /*restore*/
3058  ast_channel_lock(bridge_channel->chan);
3059 
3060  ast_channel_exten_set(bridge_channel->chan, exten);
3061  ast_channel_context_set(bridge_channel->chan, context);
3062  ast_channel_priority_set(bridge_channel->chan, priority);
3063  ast_channel_pbx_set(bridge_channel->chan, pbx);
3064 
3065  ast_channel_unlock(bridge_channel->chan);
3066 
3067  return res;
3068 }
Options for ast_pbx_run()
Definition: pbx.h:391
#define ast_channel_lock(chan)
Definition: channel.h:2902
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
const char * args
#define NULL
Definition: resample.c:96
static int priority
int ast_channel_priority(const struct ast_channel *chan)
Definition: pbx.h:211
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
Definition: pbx.c:4739
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
union conf_menu_action::@81 data
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2903
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 2989 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().

2992 {
2993  struct confbridge_user *last_user = NULL;
2994  int isadmin = ast_test_flag(&user->u_profile, USER_OPT_ADMIN);
2995 
2996  if (!isadmin) {
2997  play_file(bridge_channel, NULL,
2999  ast_log(LOG_WARNING, "Only admin users can use the kick_last menu action. Channel %s of conf %s is not an admin.\n",
3000  ast_channel_name(bridge_channel->chan),
3001  conference->name);
3002  return -1;
3003  }
3004 
3005  ao2_lock(conference);
3006  last_user = AST_LIST_LAST(&conference->active_list);
3007  if (!last_user) {
3008  ao2_unlock(conference);
3009  return 0;
3010  }
3011 
3012  if (last_user == user || ast_test_flag(&last_user->u_profile, USER_OPT_ADMIN)) {
3013  ao2_unlock(conference);
3014  play_file(bridge_channel, NULL,
3016  } else if (!last_user->kicked) {
3017  last_user->kicked = 1;
3018  pbx_builtin_setvar_helper(last_user->chan, "CONFBRIDGE_RESULT", "KICKED");
3019  ast_bridge_remove(conference->bridge, last_user->chan);
3020  ao2_unlock(conference);
3021  }
3022 
3023  return 0;
3024 }
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
struct ast_channel * chan
Definition: confbridge.h:276
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:235
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:247
#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:270
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:273
char name[MAX_CONF_NAME]
Definition: confbridge.h:244
unsigned int kicked
Definition: confbridge.h:281
struct ast_bridge * bridge
Definition: confbridge.h:246

◆ action_lock_unlock_helper()

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

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

3976 {
3977  const char *conference_name = astman_get_header(m, "Conference");
3978  int res = 0;
3979 
3980  if (ast_strlen_zero(conference_name)) {
3981  astman_send_error(s, m, "No Conference name provided.");
3982  return 0;
3983  }
3985  astman_send_error(s, m, "No active conferences.");
3986  return 0;
3987  }
3988  if ((res = generic_lock_unlock_helper(lock, conference_name))) {
3989  astman_send_error(s, m, "No Conference by that name found.");
3990  return 0;
3991  }
3992  astman_send_ack(s, m, lock ? "Conference locked" : "Conference unlocked");
3993  return 0;
3994 }
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 3933 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().

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

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

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

2851 {
2852  unsigned int binaural;
2853  ast_bridge_channel_lock_bridge(bridge_channel);
2854  binaural = !bridge_channel->binaural_suspended;
2855  bridge_channel->binaural_suspended = binaural;
2856  ast_bridge_unlock(bridge_channel->bridge);
2857  return play_file(bridge_channel, NULL, (binaural ?
2860 }
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:235
unsigned int binaural_suspended
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct bridge_profile b_profile
Definition: confbridge.h:272
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 2833 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().

2836 {
2837  int mute;
2838 
2839  /* Toggle user level mute request. */
2840  mute = !user->muted;
2841  generic_mute_unmute_user(conference, user, mute);
2842 
2843  return play_file(bridge_channel, NULL,
2845  conference->b_profile.sounds)) < 0;
2846 }
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:235
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:247
unsigned int muted
Definition: confbridge.h:280
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 2862 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().

2863 {
2864  struct confbridge_user *cur_user = NULL;
2865  const char *sound_to_play;
2866  int mute;
2867 
2868  ao2_lock(conference);
2869 
2870  /* Toggle bridge level mute request. */
2871  mute = !conference->muted;
2872  conference->muted = mute;
2873 
2874  AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) {
2875  if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) {
2876  /* Set user level to bridge level mute request. */
2877  cur_user->muted = mute;
2878  conf_update_user_mute(cur_user);
2879  }
2880  }
2881 
2882  ao2_unlock(conference);
2883 
2884  sound_to_play = conf_get_sound(
2886  conference->b_profile.sounds);
2887 
2888  if (strcmp(conference->b_profile.language, ast_channel_language(user->chan))) {
2889  /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
2890  ast_stream_and_wait(user->chan, sound_to_play, "");
2891 
2892  /* Announce to the group that all participants are muted */
2893  ast_autoservice_start(user->chan);
2894  play_sound_file(conference, sound_to_play);
2895  ast_autoservice_stop(user->chan);
2896  } else {
2897  /* Playing the sound asynchronously lets the sound be heard by everyone at once */
2898  async_play_sound_file(conference, sound_to_play, user->chan);
2899  }
2900 
2901  return 0;
2902 }
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:276
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:235
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:247
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:226
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:280
#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:270
unsigned int muted
Definition: confbridge.h:252
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:273
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:2902
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:259
struct bridge_profile b_profile
Definition: confbridge.h:247
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:6343
#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:226
#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:2903
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2534
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * playback_chan
Definition: confbridge.h:253
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:244

◆ 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:276
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:235
#define NULL
Definition: resample.c:96
struct bridge_profile b_profile
Definition: confbridge.h:247
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:248
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:8236
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 4422 of file app_confbridge.c.

◆ async_datastore_data_alloc()

static struct async_datastore_data* async_datastore_data_alloc ( void  )
static

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

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

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

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

2462 {
2463  struct async_delete_name_rec_task_data *atd;
2464 
2465  if (ast_strlen_zero(filename)) {
2466  return 0;
2467  } else if (!sound_file_exists(filename)) {
2468  return 0;
2469  }
2470 
2472  if (!atd) {
2473  return -1;
2474  }
2475 
2477  ast_log(LOG_WARNING, "Conference '%s' was unable to remove user name file '%s'\n",
2478  conference->name, filename);
2480  return -1;
2481  }
2482 
2483  return 0;
2484 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_taskprocessor * playback_queue
Definition: confbridge.h:259
#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:244

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

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

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

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

References ast_free.

Referenced by async_delete_name_rec(), and async_delete_name_rec_task().

2435 {
2436  ast_free(atd);
2437 }
#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 2250 of file app_confbridge.c.

References async_play_sound_helper().

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

2252 {
2253  return async_play_sound_helper(conference, filename, -1, initiator);
2254 }
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 2216 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().

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

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

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

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

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

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

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

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

3270 {
3271  int which = 0;
3272  RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
3273  struct confbridge_user *user;
3274  char *res = NULL;
3275  int wordlen = strlen(word);
3276 
3277  conference = ao2_find(conference_bridges, conference_name, OBJ_KEY);
3278  if (!conference) {
3279  return NULL;
3280  }
3281 
3282  if (!strncasecmp("all", word, wordlen) && ++which > state) {
3283  return ast_strdup("all");
3284  }
3285 
3286  if (!strncasecmp("participants", word, wordlen) && ++which > state) {
3287  return ast_strdup("participants");
3288  }
3289 
3290  {
3291  SCOPED_AO2LOCK(bridge_lock, conference);
3293  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3294  res = ast_strdup(ast_channel_name(user->chan));
3295  return res;
3296  }
3297  }
3299  if (!strncasecmp(ast_channel_name(user->chan), word, wordlen) && ++which > state) {
3300  res = ast_strdup(ast_channel_name(user->chan));
3301  return res;
3302  }
3303  }
3304  }
3305 
3306  return NULL;
3307 }
static char user[512]
struct ast_channel * chan
Definition: confbridge.h:276
struct confbridge_conference * conference
Definition: confbridge.h:271
#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:911
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:243
#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:270
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:265
#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 4223 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().

4224 {
4225  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4226  conference->activeusers++;
4227 }
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:248

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

4230 {
4231  AST_LIST_INSERT_TAIL(&conference->active_list, user, list);
4232  conference->activeusers++;
4233  conference->markedusers++;
4234 }
unsigned int markedusers
Definition: confbridge.h:249
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:248

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

4237 {
4238  AST_LIST_INSERT_TAIL(&conference->waiting_list, user, list);
4239  conference->waitingusers++;
4240 }
unsigned int waitingusers
Definition: confbridge.h:250
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:4952
struct bridge_profile b_profile
Definition: confbridge.h:247
#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:236
char name[MAX_CONF_NAME]
Definition: confbridge.h:244
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 2318 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().

2319 {
2320  char pin_guess[MAX_PIN+1] = { 0, };
2321  const char *pin = user->u_profile.pin;
2322  char *tmp = pin_guess;
2323  int i, res;
2324  unsigned int len = MAX_PIN;
2325 
2326  /*
2327  * NOTE: We have not joined a conference yet so we have to use
2328  * the bridge profile requested by the user.
2329  */
2330 
2331  /* give them three tries to get the pin right */
2332  for (i = 0; i < 3; i++) {
2333  if (ast_app_getdata(chan,
2335  tmp, len, 0) >= 0) {
2336  if (!strcasecmp(pin, pin_guess)) {
2337  return 0;
2338  }
2339  }
2340  ast_streamfile(chan,
2342  ast_channel_language(chan));
2343  res = ast_waitstream(chan, AST_DIGIT_ANY);
2344  if (res > 0) {
2345  /* Account for digit already read during ivalid pin playback
2346  * resetting pin buf. */
2347  pin_guess[0] = res;
2348  pin_guess[1] = '\0';
2349  tmp = pin_guess + 1;
2350  len = MAX_PIN - 1;
2351  } else {
2352  /* reset pin buf as empty buffer. */
2353  tmp = pin_guess;
2354  len = MAX_PIN;
2355  }
2356  }
2357  return -1;
2358 }
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:235
char pin[MAX_PIN]
Definition: confbridge.h:153
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:272
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:273
#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:221
const ast_string_field thereare
Definition: confbridge.h:221
const ast_string_field join
Definition: confbridge.h:221
const ast_string_field otherinparty
Definition: confbridge.h:221
const ast_string_field onlyone
Definition: confbridge.h:221
const ast_string_field hasjoin
Definition: confbridge.h:221
const ast_string_field begin
Definition: confbridge.h:221
const ast_string_field errormenu
Definition: confbridge.h:221
const ast_string_field binauraloff
Definition: confbridge.h:221
const ast_string_field waitforleader
Definition: confbridge.h:221
const ast_string_field getpin
Definition: confbridge.h:221
const ast_string_field participantsmuted
Definition: confbridge.h:221
const ast_string_field leave
Definition: confbridge.h:221
const ast_string_field lockednow
Definition: confbridge.h:221
const ast_string_field binauralon
Definition: confbridge.h:221
const ast_string_field participantsunmuted
Definition: confbridge.h:221
const ast_string_field unmuted
Definition: confbridge.h:221
const ast_string_field invalidpin
Definition: confbridge.h:221
const ast_string_field onlyperson
Definition: confbridge.h:221
#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:221
const ast_string_field leaderhasleft
Definition: confbridge.h:221
const ast_string_field kicked
Definition: confbridge.h:221
const ast_string_field locked
Definition: confbridge.h:221
const ast_string_field placeintoconf
Definition: confbridge.h:221
const ast_string_field hasleft
Definition: confbridge.h:221

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

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

◆ 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:271
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:235
struct bridge_profile b_profile
Definition: confbridge.h:247
struct user_profile u_profile
Definition: confbridge.h:273
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:271
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:235
struct bridge_profile b_profile
Definition: confbridge.h:247
struct user_profile u_profile
Definition: confbridge.h:273
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:270
struct user_profile u_profile
Definition: confbridge.h:273

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

2291 {
2292  struct confbridge_user *user = hook_pvt;
2294  struct ast_json *talking_extras;
2295 
2296  conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY);
2297  if (!conference) {
2298  /* Remove the hook since the conference does not exist. */
2299  return -1;
2300  }
2301 
2302  ao2_lock(conference);
2303  user->talking = talking;
2304  ao2_unlock(conference);
2305 
2306  talking_extras = ast_json_pack("{s: s, s: b}",
2307  "talking_status", talking ? "on" : "off",
2308  "admin", ast_test_flag(&user->u_profile, USER_OPT_ADMIN));
2309  if (!talking_extras) {
2310  return 0;
2311  }
2312 
2313  send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
2314  ast_json_unref(talking_extras);
2315  return 0;
2316 }
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:271
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_lock(a)
Definition: astobj2.h:718
struct ao2_container * conference_bridges
Container to hold all conference bridges in progress.
static void send_conf_stasis(struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *extras, int channel_topic)
The structure that represents a conference bridge.
Definition: confbridge.h:243
#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:270
struct user_profile u_profile
Definition: confbridge.h:273
unsigned int talking
Definition: confbridge.h:283
char name[MAX_CONF_NAME]
Definition: confbridge.h:244

◆ 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:254

◆ 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:276
unsigned int playing_moh
Definition: confbridge.h:282
struct confbridge_conference * conference
Definition: confbridge.h:271
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3089
unsigned int suspended_moh
Definition: confbridge.h:279
#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:7765
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3068
struct user_profile u_profile
Definition: confbridge.h:273
char moh_class[128]
Definition: confbridge.h:154
struct ast_bridge * bridge
Definition: confbridge.h:246

◆ 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:276
unsigned int playing_moh
Definition: confbridge.h:282
struct confbridge_conference * conference
Definition: confbridge.h:271
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3089
unsigned int suspended_moh
Definition: confbridge.h:279
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7775
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3068
struct ast_bridge * bridge
Definition: confbridge.h:246

◆ 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:276
unsigned int playing_moh
Definition: confbridge.h:282
struct confbridge_conference * conference
Definition: confbridge.h:271
unsigned int suspended_moh
Definition: confbridge.h:279
#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:7775
#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:276
unsigned int playing_moh
Definition: confbridge.h:282
struct confbridge_conference * conference
Definition: confbridge.h:271
unsigned int suspended_moh
Definition: confbridge.h:279
#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:7765
struct user_profile u_profile
Definition: confbridge.h:273
char moh_class[128]
Definition: confbridge.h:154

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

4256 {
4257  struct confbridge_user *only_user = AST_LIST_FIRST(&conference->active_list);
4258 
4259  /* Turn on MOH if the single participant is set up for it */
4260  if (ast_test_flag(&only_user->u_profile, USER_OPT_MUSICONHOLD)) {
4261  conf_moh_start(only_user);
4262  }
4263  conf_update_user_mute(only_user);
4264 }
#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:270
struct user_profile u_profile
Definition: confbridge.h:273

◆ conf_rec_name()

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

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

2368 {
2369  char destdir[PATH_MAX];
2370  int res;
2371  int duration = 20;
2372 
2373  snprintf(destdir, sizeof(destdir), "%s/confbridge", ast_config_AST_SPOOL_DIR);
2374 
2375  if (ast_mkdir(destdir, 0777) != 0) {
2376  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
2377  return -1;
2378  }
2379  snprintf(user->name_rec_location, sizeof(user->name_rec_location),
2380  "%s/confbridge-name-%s-%s", destdir,
2381  conf_name, ast_channel_uniqueid(user->chan));
2382 
2384  res = ast_play_and_record(user->chan,
2385  "vm-rec-name",
2386  user->name_rec_location,
2387  10,
2388  "sln",
2389  &duration,
2390  NULL,
2392  0,
2393  NULL);
2394  } else {
2395  res = ast_record_review(user->chan,
2396  "vm-rec-name",
2397  user->name_rec_location,
2398  10,
2399  "sln",
2400  &duration,
2401  NULL);
2402  }
2403 
2404  if (res == -1) {
2406  user->name_rec_location[0] = '\0';
2407  return -1;
2408  }
2409  return 0;
2410 }
struct ast_channel * chan
Definition: confbridge.h:276
#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:154
char name_rec_location[PATH_MAX]
Definition: confbridge.h:275
#define PATH_MAX
Definition: asterisk.h:40
struct user_profile u_profile
Definition: confbridge.h:273
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:2231

◆ conf_remove_user_active()

void conf_remove_user_active ( struct confbridge_conference conference,
struct confbridge_user user 
)

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

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

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

4243 {
4244  AST_LIST_REMOVE(&conference->active_list, user, list);
4245  conference->activeusers--;
4246 }
#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:248
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 4248 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().

4249 {
4250  AST_LIST_REMOVE(&conference->active_list, user, list);
4251  conference->activeusers--;
4252  conference->markedusers--;
4253 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int markedusers
Definition: confbridge.h:249
struct confbridge_conference::@87 active_list
unsigned int activeusers
Definition: confbridge.h:248
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 4266 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().

4267 {
4268  AST_LIST_REMOVE(&conference->waiting_list, user, list);
4269  conference->waitingusers--;
4270 }
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
unsigned int waitingusers
Definition: confbridge.h:250
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:2938
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:225
#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:227
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:254
struct ast_str * orig_rec_file
Definition: confbridge.h:256
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
struct bridge_profile b_profile
Definition: confbridge.h:247
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:6343
struct ast_flags feature_flags
#define ast_log
Definition: astobj2.c:42
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1924
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static int conf_is_recording(struct confbridge_conference *conference)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2534
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750
static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2927
ast_app: A registered application
Definition: pbx_app.c:45
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2800
struct ast_str * record_filename
Definition: confbridge.h:255
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:244
static void send_start_record_event(struct confbridge_conference *conference)
struct ast_bridge * bridge
Definition: confbridge.h:246

◆ 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:2938
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:225
#define NULL
Definition: resample.c:96
struct ast_channel * record_chan
Definition: confbridge.h:254
struct bridge_profile b_profile
Definition: confbridge.h:247
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:276
unsigned int playing_moh
Definition: confbridge.h:282
struct confbridge_conference * conference
Definition: confbridge.h:271
#define ast_test_flag(p, flag)
Definition: utils.h:63
char name[MAX_PROFILE_NAME]
Definition: confbridge.h:225
unsigned int markedusers
Definition: confbridge.h:249
struct bridge_profile b_profile
Definition: confbridge.h:247
#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:280
struct ast_bridge_features features
Definition: confbridge.h:277
const char * ast_channel_name(const struct ast_channel *chan)
struct user_profile u_profile
Definition: confbridge.h:273

◆ confbridge_exec()

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

The ConfBridge application.

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

2513 {
2514  int res = 0, volume_adjustments[2];
2515  int quiet = 0;
2516  int async_delete_task_pushed = 0;
2517  char *parse;
2518  const char *b_profile_name = NULL;
2519  const char *u_profile_name = NULL;
2520  const char *menu_profile_name = NULL;
2521  struct confbridge_conference *conference = NULL;
2522  struct confbridge_user user = {
2523  .chan = chan,
2524  .tech_args.talking_threshold = DEFAULT_TALKING_THRESHOLD,
2525  .tech_args.silence_threshold = DEFAULT_SILENCE_THRESHOLD,
2526  .tech_args.drop_silence = 0,
2527  };
2528  struct confbridge_hook_data *join_hook_data;
2529  struct confbridge_hook_data *leave_hook_data;
2530 
2532  AST_APP_ARG(conf_name);
2533  AST_APP_ARG(b_profile_name);
2534  AST_APP_ARG(u_profile_name);
2535  AST_APP_ARG(menu_profile_name);
2536  );
2537 
2538  if (ast_channel_state(chan) != AST_STATE_UP) {
2539  ast_answer(chan);
2540  }
2541 
2542  if (ast_bridge_features_init(&user.features)) {
2543  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2544  res = -1;
2545  goto confbridge_cleanup;
2546  }
2547 
2548  /* We need to make a copy of the input string if we are going to modify it! */
2549  parse = ast_strdupa(data);
2550 
2551  AST_STANDARD_APP_ARGS(args, parse);
2552 
2553  if (ast_strlen_zero(args.conf_name)) {
2554  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2555  ast_log(LOG_WARNING, "%s requires an argument (conference name[,options])\n", app);
2556  res = -1;
2557  goto confbridge_cleanup;
2558  }
2559 
2560  if (strlen(args.conf_name) >= MAX_CONF_NAME) {
2561  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2562  ast_log(LOG_WARNING, "%s does not accept conference names longer than %d\n", app, MAX_CONF_NAME - 1);
2563  res = -1;
2564  goto confbridge_cleanup;
2565  }
2566 
2567  /* bridge profile name */
2568  if (args.argc > 1 && !ast_strlen_zero(args.b_profile_name)) {
2569  b_profile_name = args.b_profile_name;
2570  }
2571  if (!conf_find_bridge_profile(chan, b_profile_name, &user.b_profile)) {
2572  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2573  ast_log(LOG_WARNING, "Conference bridge profile %s does not exist\n", b_profile_name ?
2574  b_profile_name : DEFAULT_BRIDGE_PROFILE);
2575  res = -1;
2576  goto confbridge_cleanup;
2577  }
2578 
2579  /* user profile name */
2580  if (args.argc > 2 && !ast_strlen_zero(args.u_profile_name)) {
2581  u_profile_name = args.u_profile_name;
2582  }
2583  if (!conf_find_user_profile(chan, u_profile_name, &user.u_profile)) {
2584  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2585  ast_log(LOG_WARNING, "Conference user profile %s does not exist\n", u_profile_name ?
2586  u_profile_name : DEFAULT_USER_PROFILE);
2587  res = -1;
2588  goto confbridge_cleanup;
2589  }
2590 
2591  quiet = ast_test_flag(&user.u_profile, USER_OPT_QUIET);
2592 
2593  /* ask for a PIN immediately after finding user profile. This has to be
2594  * prompted for requardless of quiet setting. */
2595  if (!ast_strlen_zero(user.u_profile.pin)) {
2596  if (conf_get_pin(chan, &user)) {
2597  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2598  res = -1; /* invalid PIN */
2599  goto confbridge_cleanup;
2600  }
2601  }
2602 
2603  /* See if we need them to record a intro name */
2604  if (!quiet &&
2607  if (conf_rec_name(&user, args.conf_name)) {
2608  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2609  res = -1; /* Hangup during name recording */
2610  goto confbridge_cleanup;
2611  }
2612  }
2613 
2614  /* menu name */
2615  if (args.argc > 3 && !ast_strlen_zero(args.menu_profile_name)) {
2616  menu_profile_name = args.menu_profile_name;
2617  }
2618 
2619  if (conf_set_menu_to_user(chan, &user, menu_profile_name)) {
2620  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2621  ast_log(LOG_WARNING, "Conference menu profile %s does not exist\n", menu_profile_name ?
2622  menu_profile_name : DEFAULT_MENU_PROFILE);
2623  res = -1;
2624  goto confbridge_cleanup;
2625  }
2626 
2627  /* Set if DTMF should pass through for this user or not */
2629  user.features.dtmf_passthrough = 1;
2630  } else {
2631  user.features.dtmf_passthrough = 0;
2632  }
2633 
2634  /* Set if text messaging is enabled for this user or not */
2636  user.features.text_messaging = 1;
2637  } else {
2638  user.features.text_messaging = 0;
2639  }
2640 
2641  /* Set dsp threshold values if present */
2642  if (user.u_profile.talking_threshold) {
2644  }
2645  if (user.u_profile.silence_threshold) {
2647  }
2648 
2649  /* Set a talker indicate call back if talking detection is requested */
2653  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2654  res = -1;
2655  goto confbridge_cleanup;
2656  }
2657  }
2658 
2659  /* Look for a conference bridge matching the provided name */
2660  if (!(conference = join_conference_bridge(args.conf_name, &user))) {
2661  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "FAILED");
2662  res = -1;
2663  goto confbridge_cleanup;
2664  }
2665 
2666  /* Keep a copy of volume adjustments so we can restore them later if need be */
2667  volume_adjustments[0] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_READ);
2668  volume_adjustments[1] = ast_audiohook_volume_get(chan, AST_AUDIOHOOK_DIRECTION_WRITE);
2669 
2671  user.tech_args.drop_silence = 1;
2672  }
2673 
2675  ast_func_write(chan, "JITTERBUFFER(adaptive)", "default");
2676  }
2677 
2679  ast_func_write(chan, "DENOISE(rx)", "on");
2680  }
2681 
2682  /* if this user has a intro, play it before entering */
2683  if (!ast_strlen_zero(user.name_rec_location)) {
2684  ast_autoservice_start(chan);
2685  play_sound_file(conference, user.name_rec_location);
2686  play_sound_file(conference,
2688  ast_autoservice_stop(chan);
2689  }
2690 
2691  /* Play the Join sound to both the conference and the user entering. */
2692  if (!quiet) {
2693  const char *join_sound = conf_get_sound(CONF_SOUND_JOIN, conference->b_profile.sounds);
2694 
2695  if (strcmp(conference->b_profile.language, ast_channel_language(chan))) {
2696  ast_stream_and_wait(chan, join_sound, "");
2697  ast_autoservice_start(chan);
2698  play_sound_file(conference, join_sound);
2699  ast_autoservice_stop(chan);
2700  } else {
2701  async_play_sound_file(conference, join_sound, chan);
2702  }
2703  }
2704 
2705  if (user.u_profile.timeout) {
2707  0,
2708  user.u_profile.timeout * 1000,
2709  user_timeout,
2710  NULL,
2711  NULL,
2713  }
2714 
2715  /* See if we need to automatically set this user as a video source or not */
2717 
2718  conf_moh_unsuspend(&user);
2719 
2720  join_hook_data = ast_malloc(sizeof(*join_hook_data));
2721  if (!join_hook_data) {
2722  res = -1;
2723  goto confbridge_cleanup;
2724  }
2725  join_hook_data->user = &user;
2726  join_hook_data->conference = conference;
2727  join_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_JOIN;
2729  join_hook_data, ast_free_ptr, 0);
2730  if (res) {
2731  ast_free(join_hook_data);
2732  ast_log(LOG_ERROR, "Couldn't add bridge join hook for channel '%s'\n", ast_channel_name(chan));
2733  goto confbridge_cleanup;
2734  }
2735 
2736  leave_hook_data = ast_malloc(sizeof(*leave_hook_data));
2737  if (!leave_hook_data) {
2738  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2739  res = -1;
2740  goto confbridge_cleanup;
2741  }
2742  leave_hook_data->user = &user;
2743  leave_hook_data->conference = conference;
2744  leave_hook_data->hook_type = AST_BRIDGE_HOOK_TYPE_LEAVE;
2746  leave_hook_data, ast_free_ptr, 0);
2747  if (res) {
2748  /* join_hook_data is cleaned up by ast_bridge_features_cleanup via the goto */
2749  ast_free(leave_hook_data);
2750  ast_log(LOG_ERROR, "Couldn't add bridge leave hook for channel '%s'\n", ast_channel_name(chan));
2751  goto confbridge_cleanup;
2752  }
2753 
2756  }
2757 
2758  ast_bridge_join(conference->bridge,
2759  chan,
2760  NULL,
2761  &user.features,
2762  &user.tech_args,
2763  0);
2764 
2765  /* This is a catch-all in case joining the bridge failed or for some reason
2766  * an async announcement got queued up and hasn't been told to play yet
2767  */
2768  async_play_sound_ready(chan);
2769 
2770  if (!user.kicked && ast_check_hangup(chan)) {
2771  pbx_builtin_setvar_helper(chan, "CONFBRIDGE_RESULT", "HANGUP");
2772  }
2773 
2774  /* if we're shutting down, don't attempt to do further processing */
2775  if (ast_shutting_down()) {
2776  /*
2777  * Not taking any new calls at this time. We cannot create
2778  * the announcer channel if this is the first channel into
2779  * the conference and we certainly cannot create any
2780  * recording channel.
2781  */
2782  leave_conference(&user);
2783  conference = NULL;
2784  goto confbridge_cleanup;
2785  }
2786 
2787  /* If this user was a video source, we need to clean up and possibly pick a new source. */
2788  handle_video_on_exit(conference, user.chan);
2789 
2790  /* if this user has a intro, play it when leaving */
2791  if (!quiet && !ast_strlen_zero(user.name_rec_location)) {
2792  async_play_sound_file(conference, user.name_rec_location, NULL);
2793  async_play_sound_file(conference,
2795  async_delete_name_rec(conference, user.name_rec_location);
2796  async_delete_task_pushed = 1;
2797  }
2798 
2799  /* play the leave sound */
2800  if (!quiet) {
2801  const char *leave_sound = conf_get_sound(CONF_SOUND_LEAVE, conference->b_profile.sounds);
2802  async_play_sound_file(conference, leave_sound, NULL);
2803  }
2804 
2805  /* If the user was kicked from the conference play back the audio prompt for it */
2806  if (!quiet && user.kicked) {
2807  res = ast_stream_and_wait(chan,
2809  "");
2810  }
2811 
2812  /* Easy as pie, depart this channel from the conference bridge */
2813  leave_conference(&user);
2814  conference = NULL;
2815 
2816  /* Restore volume adjustments to previous values in case they were changed */
2817  if (volume_adjustments[0]) {
2818  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_READ, volume_adjustments[0]);
2819  }
2820  if (volume_adjustments[1]) {
2821  ast_audiohook_volume_set(chan, AST_AUDIOHOOK_DIRECTION_WRITE, volume_adjustments[1]);
2822  }
2823 
2824 confbridge_cleanup:
2825  if (!async_delete_task_pushed && !ast_strlen_zero(user.name_rec_location)) {
2827  }
2830  return res;
2831 }
static char user[512]
static void conf_moh_unsuspend(struct confbridge_user *user)
int ast_audiohook_volume_set(struct ast_channel *chan, enum ast_audiohook_direction direction, int volume)
Adjust the volume on frames read from or written to a channel.
Definition: audiohook.c:1346
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720
int ast_shutting_down(void)
Definition: asterisk.c:1834
static int join_callback(struct ast_bridge_channel *bridge_channel, void *ignore)
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
struct ast_channel * chan
Definition: confbridge.h:276
static int user_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
int ast_audiohook_volume_get(struct ast_channel *chan, enum ast_audiohook_direction direction)
Retrieve the volume adjustment value on frames read from or written to a channel. ...
Definition: audiohook.c:1371
int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel leave hook to a bridge features structure.
Definition: bridge.c:3348
const char * conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
Looks to see if sound file is stored in bridge profile sounds, if not default sound is provided...
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_bridge_join_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Unregisters a handler for a built in interval feature.
Definition: bridge.c:3338
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, ast_bridge_talking_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel talk detection hook to a bridge features structure.
Definition: bridge.c:3358
const struct user_profile * conf_find_user_profile(struct ast_channel *chan, const char *user_profile_name, struct user_profile *result)
find a user profile given a user profile&#39;s name and store that profile in result structure.
static int conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
static struct confbridge_conference * join_conference_bridge(const char *conference_name, struct confbridge_user *user)
Join a conference bridge.
struct bridge_profile_sounds * sounds
Definition: confbridge.h:235
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:161
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:247
static int quiet
Definition: ael_main.c:123
unsigned int text_messaging
#define ast_log
Definition: astobj2.c:42
int async_play_sound_file(struct confbridge_conference *conference, const char *filename, struct ast_channel *initiator)
Play sound file into conference bridge asynchronously.
#define DEFAULT_TALKING_THRESHOLD
Definition: confbridge.h:46
void conf_bridge_profile_destroy(struct bridge_profile *b_profile)
Destroy a bridge profile found by &#39;conf_find_bridge_profile&#39;.
static int async_delete_name_rec(struct confbridge_conference *conference, const char *filename)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3382
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
char language[MAX_LANGUAGE]
Definition: confbridge.h:226
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:153
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:159
#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:163
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:272
struct ast_bridge_features features
Definition: confbridge.h:277
The structure that represents a conference bridge.
Definition: confbridge.h:243
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:275
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:2800
const char * ast_channel_language(const struct ast_channel *chan)
The structure that represents a conference bridge user.
Definition: confbridge.h:270
#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:273
#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:281
#define DEFAULT_SILENCE_THRESHOLD
Definition: confbridge.h:49
struct ast_bridge_tech_optimizations tech_args
Definition: confbridge.h:278
#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:246
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:276
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