Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions | Variables
app_meetme.c File Reference

Meet me conference bridge and Shared Line Appearances. More...

#include "asterisk.h"
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/translate.h"
#include "asterisk/ulaw.h"
#include "asterisk/astobj2.h"
#include "asterisk/devicestate.h"
#include "asterisk/dial.h"
#include "asterisk/causes.h"
#include "asterisk/paths.h"
#include "asterisk/test.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/json.h"
#include "asterisk/format_compatibility.h"
#include "enter.h"
#include "leave.h"
Include dependency graph for app_meetme.c:

Go to the source code of this file.

Data Structures

struct  announce_listitem
 
struct  ast_conf_user
 The MeetMe User object. More...
 
struct  ast_conference
 The MeetMe Conference object. More...
 
struct  confs
 
struct  dial_trunk_args
 
struct  run_station_args
 
struct  sla_event
 
struct  sla_failed_station
 A station that failed to be dialed. More...
 
struct  sla_ringing_station
 A station that is ringing. More...
 
struct  sla_ringing_trunk
 A trunk that is ringing. More...
 
struct  sla_station
 
struct  sla_station_ref
 A reference to a station. More...
 
struct  sla_trunk
 
struct  sla_trunk_ref
 A station's reference to a trunk. More...
 
struct  volume
 

Macros

#define AST_FRAME_BITS   32
 
#define CONF_SIZE   320
 
#define CONFFLAG_DONT_DENOISE   (1ULL << 35)
 
#define CONFFLAG_INTROMSG   (1ULL << 32)
 
#define CONFFLAG_INTROUSER_VMREC   (1ULL << 33)
 
#define CONFFLAG_KILL_LAST_MAN_STANDING   (1ULL << 34)
 
#define CONFFLAG_NO_AUDIO_UNTIL_UP   (1ULL << 31)
 
#define CONFIG_FILE_NAME   "meetme.conf"
 
#define DATE_FORMAT   "%Y-%m-%d %H:%M:%S"
 
#define DEFAULT_AUDIO_BUFFERS   32
 
#define MAX_CONFNUM   80
 
#define MAX_PIN   80
 
#define MAX_SETTINGS   (MAX_CONFNUM + MAX_PIN + MAX_PIN + 3)
 
#define MC_DATA_FORMAT   "%-12.12s %4.4d %4.4s %02d:%02d:%02d %-8s %-6s\n"
 
#define MC_HEADER_FORMAT   "%-14s %-14s %-10s %-8s %-8s %-6s\n"
 
#define MEETME_DELAYDETECTENDTALK   1000
 
#define MEETME_DELAYDETECTTALK   300
 
#define OPTIONS_LEN   100
 
#define S(e)   case e: return # e;
 
#define SLA_CONFIG_FILE   "sla.conf"
 
#define STR_CONCISE   "concise"
 

Enumerations

enum  {
  ADMINFLAG_MUTED = (1 << 1), ADMINFLAG_SELFMUTED = (1 << 2), ADMINFLAG_KICKME = (1 << 3), ADMINFLAG_T_REQUEST = (1 << 4),
  ADMINFLAG_HANGUP = (1 << 5)
}
 
enum  {
  CONFFLAG_ADMIN = (1 << 0), CONFFLAG_MONITOR = (1 << 1), CONFFLAG_KEYEXIT = (1 << 2), CONFFLAG_STARMENU = (1 << 3),
  CONFFLAG_TALKER = (1 << 4), CONFFLAG_QUIET = (1 << 5), CONFFLAG_ANNOUNCEUSERCOUNT = (1 << 6), CONFFLAG_AGI = (1 << 7),
  CONFFLAG_MOH = (1 << 8), CONFFLAG_MARKEDEXIT = (1 << 9), CONFFLAG_WAITMARKED = (1 << 10), CONFFLAG_EXIT_CONTEXT = (1 << 11),
  CONFFLAG_MARKEDUSER = (1 << 12), CONFFLAG_INTROUSER = (1 << 13), CONFFLAG_RECORDCONF = (1<< 14), CONFFLAG_MONITORTALKER = (1 << 15),
  CONFFLAG_DYNAMIC = (1 << 16), CONFFLAG_DYNAMICPIN = (1 << 17), CONFFLAG_EMPTY = (1 << 18), CONFFLAG_EMPTYNOPIN = (1 << 19),
  CONFFLAG_ALWAYSPROMPT = (1 << 20), CONFFLAG_OPTIMIZETALKER = (1 << 21), CONFFLAG_NOONLYPERSON = (1 << 22), CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
  CONFFLAG_STARTMUTED = (1 << 24), CONFFLAG_PASS_DTMF = (1 << 25), CONFFLAG_SLA_STATION = (1 << 26), CONFFLAG_SLA_TRUNK = (1 << 27),
  CONFFLAG_KICK_CONTINUE = (1 << 28), CONFFLAG_DURATION_STOP = (1 << 29), CONFFLAG_DURATION_LIMIT = (1 << 30)
}
 
enum  {
  OPT_ARG_WAITMARKED = 0, OPT_ARG_EXITKEYS = 1, OPT_ARG_DURATION_STOP = 2, OPT_ARG_DURATION_LIMIT = 3,
  OPT_ARG_MOH_CLASS = 4, OPT_ARG_INTROMSG = 5, OPT_ARG_INTROUSER_VMREC = 6, OPT_ARG_ARRAY_SIZE = 7
}
 
enum  { SLA_TRUNK_OPT_MOH = (1 << 0) }
 
enum  { SLA_TRUNK_OPT_ARG_MOH_CLASS = 0, SLA_TRUNK_OPT_ARG_ARRAY_SIZE = 1 }
 
enum  announcetypes { CONF_HASJOIN, CONF_HASLEFT }
 
enum  entrance_sound { ENTER, LEAVE }
 
enum  menu_modes { MENU_DISABLED = 0, MENU_NORMAL, MENU_ADMIN, MENU_ADMIN_EXTENDED }
 
enum  recording_state { MEETME_RECORD_OFF, MEETME_RECORD_STARTED, MEETME_RECORD_ACTIVE, MEETME_RECORD_TERMINATE }
 
enum  sla_event_type { SLA_EVENT_HOLD, SLA_EVENT_DIAL_STATE, SLA_EVENT_RINGING_TRUNK }
 Event types that can be queued up for the SLA thread. More...
 
enum  sla_hold_access { SLA_HOLD_OPEN, SLA_HOLD_PRIVATE }
 
enum  sla_station_hangup { SLA_STATION_HANGUP_NORMAL, SLA_STATION_HANGUP_TIMEOUT }
 
enum  sla_trunk_state {
  SLA_TRUNK_STATE_IDLE, SLA_TRUNK_STATE_RINGING, SLA_TRUNK_STATE_UP, SLA_TRUNK_STATE_ONHOLD,
  SLA_TRUNK_STATE_ONHOLD_BYME
}
 
enum  sla_which_trunk_refs { ALL_TRUNK_REFS, INACTIVE_TRUNK_REFS }
 
enum  volume_action { VOL_UP, VOL_DOWN }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int acf_meetme_info (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int acf_meetme_info_eval (const char *keyword, const struct ast_conference *conf)
 
static int action_meetmelist (struct mansession *s, const struct message *m)
 
static int action_meetmelistrooms (struct mansession *s, const struct message *m)
 
static int action_meetmemute (struct mansession *s, const struct message *m)
 
static int action_meetmeunmute (struct mansession *s, const struct message *m)
 
static int admin_exec (struct ast_channel *chan, const char *data)
 The MeetMeadmin application. More...
 
static void * announce_thread (void *data)
 
static void answer_trunk_chan (struct ast_channel *chan)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_conferencebuild_conf (const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
 Find or create a conference. More...
 
static int can_write (struct ast_channel *chan, struct ast_flags64 *confflags)
 
static int careful_write (int fd, unsigned char *data, int len, int block)
 
static int channel_admin_exec (struct ast_channel *chan, const char *data)
 The MeetMeChannelAdmin application MeetMeChannelAdmin(channel, command) More...
 
static char * complete_confno (const char *word, int state)
 
static char * complete_meetmecmd_list (const char *line, const char *word, int pos, int state)
 
static char * complete_meetmecmd_lock (const char *word, int pos, int state)
 
static char * complete_meetmecmd_mute_kick (const char *line, const char *word, int pos, int state)
 
static char * complete_userno (struct ast_conference *cnf, const char *word, int state)
 
static int conf_exec (struct ast_channel *chan, const char *data)
 The meetme() application. More...
 
static void conf_flush (int fd, struct ast_channel *chan)
 
static int conf_free (struct ast_conference *conf)
 Remove the conference from the list and free it. More...
 
static void conf_play (struct ast_channel *chan, struct ast_conference *conf, enum entrance_sound sound)
 
static void conf_queue_dtmf (const struct ast_conference *conf, const struct ast_conf_user *sender, struct ast_frame *f)
 
static int conf_run (struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
 
static void conf_start_moh (struct ast_channel *chan, const char *musicclass)
 
static int count_exec (struct ast_channel *chan, const char *data)
 The MeetmeCount application. More...
 
static struct sla_trunk_refcreate_trunk_ref (struct sla_trunk *trunk)
 
static void * dial_trunk (void *data)
 
static int dispose_conf (struct ast_conference *conf)
 Decrement reference counts, as incremented by find_conf() More...
 
static void filename_parse (char *filename, char *buffer)
 
static struct ast_conferencefind_conf (struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags64 *confflags)
 
static struct ast_conferencefind_conf_realtime (struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags64 *confflags, int *too_early, char **optargs)
 
static struct ast_conf_userfind_user (struct ast_conference *conf, const char *callerident)
 
static const char * get_announce_filename (enum announcetypes type)
 
static const char * istalking (int x)
 
static int load_config (int reload)
 
static void load_config_meetme (int reload)
 
static int load_module (void)
 Load the module. More...
 
static char * meetme_cmd_helper (struct ast_cli_args *a)
 
static char * meetme_kick_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * meetme_lock_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void meetme_menu (enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, int recordingtmp_size, struct ast_format_cap *cap_slin)
 
static void meetme_menu_admin (enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
 
static void meetme_menu_admin_extended (enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, int recordingtmp_size, struct ast_format_cap *cap_slin)
 
static void meetme_menu_normal (enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
 
static char * meetme_mute_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void meetme_set_defaults (void)
 
static char * meetme_show_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void meetme_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void meetme_stasis_cleanup (void)
 
static void meetme_stasis_generate_msg (struct ast_conference *meetme_conference, struct ast_channel *chan, struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
 
static int meetme_stasis_init (void)
 
static int meetmemute (struct mansession *s, const struct message *m, int mute)
 
static enum ast_device_state meetmestate (const char *data)
 Callback for devicestate providers. More...
 
static struct sla_ringing_trunkqueue_ringing_trunk (struct sla_trunk *trunk)
 
static void * recordthread (void *args)
 
static int reload (void)
 
static void reset_volumes (struct ast_conf_user *user)
 
static int rt_extend_conf (const char *confno)
 
static void * run_station (void *data)
 
static void send_talking_event (struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking)
 
static int set_listen_volume (struct ast_conf_user *user, int volume)
 
static int set_talk_volume (struct ast_conf_user *user, int volume)
 
static void set_user_talking (struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking, int monitor)
 
static void sla_add_trunk_to_station (struct sla_station *station, struct ast_variable *var)
 
static int sla_build_station (struct ast_config *cfg, const char *cat)
 
static int sla_build_trunk (struct ast_config *cfg, const char *cat)
 
static int sla_calc_station_delays (unsigned int *timeout)
 Calculate the ring delay for a station. More...
 
static int sla_calc_station_timeouts (unsigned int *timeout)
 Process station ring timeouts. More...
 
static int sla_calc_trunk_timeouts (unsigned int *timeout)
 Process trunk ring timeouts. More...
 
static void sla_change_trunk_state (const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
 
static int sla_check_device (const char *device)
 
static int sla_check_failed_station (const struct sla_station *station)
 Check to see if this station has failed to be dialed in the past minute. More...
 
static int sla_check_inuse_station (const struct sla_station *station)
 Check to see if a station is in use. More...
 
static int sla_check_ringing_station (const struct sla_station *station)
 Check to see if this station is already ringing. More...
 
static int sla_check_station_delay (struct sla_station *station, struct sla_ringing_trunk *ringing_trunk)
 Calculate the ring delay for a given ringing trunk on a station. More...
 
static int sla_check_station_hold_access (const struct sla_trunk *trunk, const struct sla_station *station)
 
static int sla_check_timed_out_station (const struct sla_ringing_trunk *ringing_trunk, const struct sla_station *station)
 Check to see if dialing this station already timed out for this ringing trunk. More...
 
static struct sla_trunk_refsla_choose_idle_trunk (const struct sla_station *station)
 For a given station, choose the highest priority idle trunk. More...
 
static struct sla_ringing_trunksla_choose_ringing_trunk (struct sla_station *station, struct sla_trunk_ref **trunk_ref, int rm)
 Choose the highest priority ringing trunk for a station. More...
 
static struct sla_failed_stationsla_create_failed_station (struct sla_station *station)
 
static struct sla_ringing_stationsla_create_ringing_station (struct sla_station *station)
 
static struct sla_station_refsla_create_station_ref (struct sla_station *station)
 
static void sla_destroy (void)
 
static void sla_dial_state_callback (struct ast_dial *dial)
 
static void sla_event_destroy (struct sla_event *event)
 
static void sla_failed_station_destroy (struct sla_failed_station *failed_station)
 
static struct sla_stationsla_find_station (const char *name)
 
static struct sla_trunksla_find_trunk (const char *name)
 
static struct sla_trunk_refsla_find_trunk_ref (const struct sla_station *station, const struct sla_trunk *trunk)
 
static struct sla_trunk_refsla_find_trunk_ref_byname (const struct sla_station *station, const char *name)
 Find a trunk reference on a station by name. More...
 
static void sla_handle_dial_state_event (void)
 
static void sla_handle_hold_event (struct sla_event *event)
 
static void sla_handle_ringing_trunk_event (void)
 
static void sla_hangup_stations (void)
 
static const char * sla_hold_str (unsigned int hold_access)
 
static int sla_in_use (void)
 
static int sla_load_config (int reload)
 
static int sla_process_timers (struct timespec *ts)
 Calculate the time until the next known event. More...
 
static void sla_queue_event (enum sla_event_type type)
 
static void sla_queue_event_conf (enum sla_event_type type, struct ast_channel *chan, struct ast_conference *conf)
 Queue a SLA event from the conference. More...
 
static void sla_queue_event_full (enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
 
static void sla_queue_event_nolock (enum sla_event_type type)
 
static int sla_ring_station (struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
 Ring a station. More...
 
static void sla_ring_stations (void)
 Ring stations based on current set of ringing trunks. More...
 
static void sla_ringing_station_destroy (struct sla_ringing_station *ringing_station)
 
static void sla_ringing_trunk_destroy (struct sla_ringing_trunk *ringing_trunk)
 
static char * sla_show_stations (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * sla_show_trunks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static enum ast_device_state sla_state (const char *data)
 
static enum ast_device_state sla_state_to_devstate (enum sla_trunk_state state)
 
static int sla_station_cmp (void *obj, void *arg, int flags)
 
static void sla_station_destructor (void *obj)
 
static int sla_station_exec (struct ast_channel *chan, const char *data)
 
static int sla_station_is_marked (void *obj, void *arg, int flags)
 
static int sla_station_mark (void *obj, void *arg, int flags)
 
static void sla_station_ref_destructor (void *obj)
 
static int sla_station_release_refs (void *obj, void *arg, int flags)
 
static void sla_stop_ringing_station (struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
 
static void sla_stop_ringing_trunk (struct sla_ringing_trunk *ringing_trunk)
 
static void * sla_thread (void *data)
 
static int sla_trunk_cmp (void *obj, void *arg, int flags)
 
static void sla_trunk_destructor (void *obj)
 
static int sla_trunk_exec (struct ast_channel *chan, const char *data)
 
static int sla_trunk_is_marked (void *obj, void *arg, int flags)
 
static int sla_trunk_mark (void *obj, void *arg, int flags)
 
static void sla_trunk_ref_destructor (void *obj)
 
static int sla_trunk_release_refs (void *obj, void *arg, int flags)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_join_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_leave_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_end_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_mute_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_talking_type)
 
 STASIS_MESSAGE_TYPE_DEFN_LOCAL (meetme_talk_request_type)
 
static struct ast_jsonstatus_to_json (int on)
 
static const char * trunkstate2str (enum sla_trunk_state state)
 
static void tweak_listen_volume (struct ast_conf_user *user, enum volume_action action)
 
static void tweak_talk_volume (struct ast_conf_user *user, enum volume_action action)
 
static void tweak_volume (struct volume *vol, enum volume_action action)
 
static int unload_module (void)
 
static int user_chan_cb (void *obj, void *args, int flags)
 
static int user_listen_voldown_cb (void *obj, void *unused, int flags)
 
static int user_listen_volup_cb (void *obj, void *unused, int flags)
 
static int user_max_cmp (void *obj, void *arg, int flags)
 
static int user_no_cmp (void *obj, void *arg, int flags)
 
static int user_reset_vol_cb (void *obj, void *unused, int flags)
 
static int user_set_hangup_cb (void *obj, void *check_admin_arg, int flags)
 
static int user_set_kickme_cb (void *obj, void *check_admin_arg, int flags)
 
static int user_set_muted_cb (void *obj, void *check_admin_arg, int flags)
 
static int user_set_unmuted_cb (void *obj, void *check_admin_arg, int flags)
 
static int user_talk_voldown_cb (void *obj, void *unused, int flags)
 
static int user_talk_volup_cb (void *obj, void *unused, int flags)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "MeetMe conference bridge" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, .optional_modules = "func_speex", }
 
static const char *const app = "MeetMe"
 
static const char *const app2 = "MeetMeCount"
 
static const char *const app3 = "MeetMeAdmin"
 
static const char *const app4 = "MeetMeChannelAdmin"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int audio_buffers
 The number of audio buffers to be allocated on pseudo channels when in a conference. More...
 
static struct ast_cli_entry cli_meetme []
 
static unsigned int conf_map [1024] = {0, }
 
static struct confs confs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static int earlyalert
 
static int endalert
 
static int extendby
 
static int fuzzystart
 
static const char gain_map []
 Map 'volume' levels from -5 through +5 into decibel (dB) settings for channel drivers. More...
 
static struct stasis_message_routermeetme_event_message_router
 
static struct ast_custom_function meetme_info_acf
 
static const struct ast_app_option meetme_opts [128] = { [ 'A' ] = { .flag = CONFFLAG_MARKEDUSER }, [ 'a' ] = { .flag = CONFFLAG_ADMIN }, [ 'b' ] = { .flag = CONFFLAG_AGI }, [ 'c' ] = { .flag = CONFFLAG_ANNOUNCEUSERCOUNT }, [ 'C' ] = { .flag = CONFFLAG_KICK_CONTINUE }, [ 'D' ] = { .flag = CONFFLAG_DYNAMICPIN }, [ 'd' ] = { .flag = CONFFLAG_DYNAMIC }, [ 'E' ] = { .flag = CONFFLAG_EMPTYNOPIN }, [ 'e' ] = { .flag = CONFFLAG_EMPTY }, [ 'F' ] = { .flag = CONFFLAG_PASS_DTMF }, [ 'G' ] = { .flag = (1ULL << 32) , .arg_index = OPT_ARG_INTROMSG + 1 }, [ 'v' ] = { .flag = (1ULL << 33) , .arg_index = OPT_ARG_INTROUSER_VMREC + 1 }, [ 'i' ] = { .flag = CONFFLAG_INTROUSER }, [ 'I' ] = { .flag = CONFFLAG_INTROUSERNOREVIEW }, [ 'k' ] = { .flag = (1ULL << 34) }, [ 'M' ] = { .flag = CONFFLAG_MOH , .arg_index = OPT_ARG_MOH_CLASS + 1 }, [ 'm' ] = { .flag = CONFFLAG_STARTMUTED }, [ 'n' ] = { .flag = (1ULL << 35) }, [ 'o' ] = { .flag = CONFFLAG_OPTIMIZETALKER }, [ 'P' ] = { .flag = CONFFLAG_ALWAYSPROMPT }, [ 'p' ] = { .flag = CONFFLAG_KEYEXIT , .arg_index = OPT_ARG_EXITKEYS + 1 }, [ 'q' ] = { .flag = CONFFLAG_QUIET }, [ 'r' ] = { .flag = CONFFLAG_RECORDCONF }, [ 's' ] = { .flag = CONFFLAG_STARMENU }, [ 'T' ] = { .flag = CONFFLAG_MONITORTALKER }, [ 'l' ] = { .flag = CONFFLAG_MONITOR }, [ 't' ] = { .flag = CONFFLAG_TALKER }, [ 'w' ] = { .flag = CONFFLAG_WAITMARKED , .arg_index = OPT_ARG_WAITMARKED + 1 }, [ 'X' ] = { .flag = CONFFLAG_EXIT_CONTEXT }, [ 'x' ] = { .flag = CONFFLAG_MARKEDEXIT }, [ '1' ] = { .flag = CONFFLAG_NOONLYPERSON }, [ 'S' ] = { .flag = CONFFLAG_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 'L' ] = { .flag = CONFFLAG_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, }
 
static int rt_log_members
 
static int rt_schedule
 
struct {
   unsigned int   attempt_callerid:1
 
   ast_cond_t   cond
 
   struct {
      struct sla_event *   first
 
      struct sla_event *   last
 
   }   event_q
 
   struct {
      struct sla_failed_station *   first
 
      struct sla_failed_station *   last
 
   }   failed_stations
 
   ast_mutex_t   lock
 
   struct {
      struct sla_ringing_station *   first
 
      struct sla_ringing_station *   last
 
   }   ringing_stations
 
   struct {
      struct sla_ringing_trunk *   first
 
      struct sla_ringing_trunk *   last
 
   }   ringing_trunks
 
   unsigned int   stop:1
 
   pthread_t   thread
 
sla
 A structure for data used by the sla thread. More...
 
static const char sla_registrar [] = "SLA"
 
static struct ao2_containersla_stations
 
static const struct ast_app_option sla_trunk_opts [128] = { [ 'M' ] = { .flag = SLA_TRUNK_OPT_MOH , .arg_index = SLA_TRUNK_OPT_ARG_MOH_CLASS + 1 }, }
 
static struct ao2_containersla_trunks
 
static const char *const slastation_app = "SLAStation"
 
static const char *const slatrunk_app = "SLATrunk"
 

Detailed Description

Meet me conference bridge and Shared Line Appearances.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
(SLA) Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file app_meetme.c.

Macro Definition Documentation

◆ AST_FRAME_BITS

#define AST_FRAME_BITS   32

Definition at line 664 of file app_meetme.c.

Referenced by conf_free(), conf_run(), and recordthread().

◆ CONF_SIZE

#define CONF_SIZE   320

Definition at line 683 of file app_meetme.c.

Referenced by conf_run().

◆ CONFFLAG_DONT_DENOISE

#define CONFFLAG_DONT_DENOISE   (1ULL << 35)

If set, don't enable a denoiser for the channel

Definition at line 753 of file app_meetme.c.

Referenced by conf_run().

◆ CONFFLAG_INTROMSG

#define CONFFLAG_INTROMSG   (1ULL << 32)

If set play an intro announcement at start of conference

Definition at line 748 of file app_meetme.c.

Referenced by conf_run().

◆ CONFFLAG_INTROUSER_VMREC

#define CONFFLAG_INTROUSER_VMREC   (1ULL << 33)

Definition at line 749 of file app_meetme.c.

Referenced by conf_run(), find_conf(), and find_conf_realtime().

◆ CONFFLAG_KILL_LAST_MAN_STANDING

#define CONFFLAG_KILL_LAST_MAN_STANDING   (1ULL << 34)

If there's only one person left in a conference when someone leaves, kill the conference

Definition at line 751 of file app_meetme.c.

Referenced by conf_run().

◆ CONFFLAG_NO_AUDIO_UNTIL_UP

#define CONFFLAG_NO_AUDIO_UNTIL_UP   (1ULL << 31)

Do not write any audio to this channel until the state is up.

Definition at line 747 of file app_meetme.c.

Referenced by can_write(), conf_run(), and sla_trunk_exec().

◆ CONFIG_FILE_NAME

#define CONFIG_FILE_NAME   "meetme.conf"

Definition at line 642 of file app_meetme.c.

Referenced by conf_exec(), find_conf(), and load_config_meetme().

◆ DATE_FORMAT

#define DATE_FORMAT   "%Y-%m-%d %H:%M:%S"

String format for scheduled conferences

Definition at line 650 of file app_meetme.c.

Referenced by conf_run(), find_conf_realtime(), and rt_extend_conf().

◆ DEFAULT_AUDIO_BUFFERS

#define DEFAULT_AUDIO_BUFFERS   32

each buffer is 20ms, so this is 640ms total

Definition at line 647 of file app_meetme.c.

Referenced by load_config_meetme(), and meetme_set_defaults().

◆ MAX_CONFNUM

#define MAX_CONFNUM   80

◆ MAX_PIN

#define MAX_PIN   80

Definition at line 820 of file app_meetme.c.

Referenced by conf_exec(), and conf_get_pin().

◆ MAX_SETTINGS

#define MAX_SETTINGS   (MAX_CONFNUM + MAX_PIN + MAX_PIN + 3)

Definition at line 824 of file app_meetme.c.

Referenced by conf_exec(), and find_conf().

◆ MC_DATA_FORMAT

#define MC_DATA_FORMAT   "%-12.12s %4.4d %4.4s %02d:%02d:%02d %-8s %-6s\n"

Referenced by meetme_show_cmd().

◆ MC_HEADER_FORMAT

#define MC_HEADER_FORMAT   "%-14s %-14s %-10s %-8s %-8s %-6s\n"

Referenced by meetme_show_cmd().

◆ MEETME_DELAYDETECTENDTALK

#define MEETME_DELAYDETECTENDTALK   1000

Definition at line 662 of file app_meetme.c.

Referenced by conf_run().

◆ MEETME_DELAYDETECTTALK

#define MEETME_DELAYDETECTTALK   300

Definition at line 661 of file app_meetme.c.

Referenced by conf_run().

◆ OPTIONS_LEN

#define OPTIONS_LEN   100

Definition at line 821 of file app_meetme.c.

Referenced by find_conf_realtime().

◆ S

#define S (   e)    case e: return # e;

Referenced by P4(), P5(), sms_readfile(), and trunkstate2str().

◆ SLA_CONFIG_FILE

#define SLA_CONFIG_FILE   "sla.conf"

Definition at line 643 of file app_meetme.c.

Referenced by sla_build_station(), sla_build_trunk(), and sla_load_config().

◆ STR_CONCISE

#define STR_CONCISE   "concise"

Definition at line 644 of file app_meetme.c.

Referenced by complete_meetmecmd_list(), and meetme_show_cmd().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
ADMINFLAG_MUTED 

User is muted

ADMINFLAG_SELFMUTED 

User muted self

ADMINFLAG_KICKME 

User has been kicked

ADMINFLAG_T_REQUEST 

User has requested to speak

ADMINFLAG_HANGUP 

User will be leaving the conference

Definition at line 652 of file app_meetme.c.

652  {
653  ADMINFLAG_MUTED = (1 << 1), /*!< User is muted */
654  ADMINFLAG_SELFMUTED = (1 << 2), /*!< User muted self */
655  ADMINFLAG_KICKME = (1 << 3), /*!< User has been kicked */
656  /*! User has requested to speak */
657  ADMINFLAG_T_REQUEST = (1 << 4),
658  ADMINFLAG_HANGUP = (1 << 5), /*!< User will be leaving the conference */
659 };

◆ anonymous enum

anonymous enum
Enumerator
CONFFLAG_ADMIN 

user has admin access on the conference

CONFFLAG_MONITOR 

If set the user can only receive audio from the conference

CONFFLAG_KEYEXIT 

If set asterisk will exit conference when key defined in p() option is pressed

CONFFLAG_STARMENU 

If set asterisk will provide a menu to the user when '*' is pressed

CONFFLAG_TALKER 

If set the use can only send audio to the conference

CONFFLAG_QUIET 

If set there will be no enter or leave sounds

CONFFLAG_ANNOUNCEUSERCOUNT 

If set, when user joins the conference, they will be told the number of users that are already in

CONFFLAG_AGI 

Set to run AGI Script in Background

CONFFLAG_MOH 

Set to have music on hold when user is alone in conference

CONFFLAG_MARKEDEXIT 

If set, the channel will leave the conference if all marked users leave

CONFFLAG_WAITMARKED 

If set, the MeetMe will wait until a marked user enters

CONFFLAG_EXIT_CONTEXT 

If set, the MeetMe will exit to the specified context

CONFFLAG_MARKEDUSER 

If set, the user will be marked

CONFFLAG_INTROUSER 

If set, user will be ask record name on entry of conference

CONFFLAG_RECORDCONF 

If set, the MeetMe will be recorded

CONFFLAG_MONITORTALKER 

If set, the user will be monitored if the user is talking or not

CONFFLAG_DYNAMIC 
CONFFLAG_DYNAMICPIN 
CONFFLAG_EMPTY 
CONFFLAG_EMPTYNOPIN 
CONFFLAG_ALWAYSPROMPT 
CONFFLAG_OPTIMIZETALKER 

If set, treat talking users as muted users

CONFFLAG_NOONLYPERSON 

If set, won't speak the extra prompt when the first person enters the conference

CONFFLAG_INTROUSERNOREVIEW 

If set, user will be asked to record name on entry of conference without review

CONFFLAG_STARTMUTED 

If set, the user will be initially self-muted

CONFFLAG_PASS_DTMF 

Pass DTMF through the conference

CONFFLAG_SLA_STATION 
CONFFLAG_SLA_TRUNK 
CONFFLAG_KICK_CONTINUE 

If set, the user should continue in the dialplan if kicked out

CONFFLAG_DURATION_STOP 
CONFFLAG_DURATION_LIMIT 

Definition at line 685 of file app_meetme.c.

685  {
686  /*! user has admin access on the conference */
687  CONFFLAG_ADMIN = (1 << 0),
688  /*! If set the user can only receive audio from the conference */
689  CONFFLAG_MONITOR = (1 << 1),
690  /*! If set asterisk will exit conference when key defined in p() option is pressed */
691  CONFFLAG_KEYEXIT = (1 << 2),
692  /*! If set asterisk will provide a menu to the user when '*' is pressed */
693  CONFFLAG_STARMENU = (1 << 3),
694  /*! If set the use can only send audio to the conference */
695  CONFFLAG_TALKER = (1 << 4),
696  /*! If set there will be no enter or leave sounds */
697  CONFFLAG_QUIET = (1 << 5),
698  /*! If set, when user joins the conference, they will be told the number
699  * of users that are already in */
700  CONFFLAG_ANNOUNCEUSERCOUNT = (1 << 6),
701  /*! Set to run AGI Script in Background */
702  CONFFLAG_AGI = (1 << 7),
703  /*! Set to have music on hold when user is alone in conference */
704  CONFFLAG_MOH = (1 << 8),
705  /*! If set, the channel will leave the conference if all marked users leave */
706  CONFFLAG_MARKEDEXIT = (1 << 9),
707  /*! If set, the MeetMe will wait until a marked user enters */
708  CONFFLAG_WAITMARKED = (1 << 10),
709  /*! If set, the MeetMe will exit to the specified context */
710  CONFFLAG_EXIT_CONTEXT = (1 << 11),
711  /*! If set, the user will be marked */
712  CONFFLAG_MARKEDUSER = (1 << 12),
713  /*! If set, user will be ask record name on entry of conference */
714  CONFFLAG_INTROUSER = (1 << 13),
715  /*! If set, the MeetMe will be recorded */
716  CONFFLAG_RECORDCONF = (1<< 14),
717  /*! If set, the user will be monitored if the user is talking or not */
718  CONFFLAG_MONITORTALKER = (1 << 15),
719  CONFFLAG_DYNAMIC = (1 << 16),
720  CONFFLAG_DYNAMICPIN = (1 << 17),
721  CONFFLAG_EMPTY = (1 << 18),
722  CONFFLAG_EMPTYNOPIN = (1 << 19),
723  CONFFLAG_ALWAYSPROMPT = (1 << 20),
724  /*! If set, treat talking users as muted users */
725  CONFFLAG_OPTIMIZETALKER = (1 << 21),
726  /*! If set, won't speak the extra prompt when the first person
727  * enters the conference */
728  CONFFLAG_NOONLYPERSON = (1 << 22),
729  /*! If set, user will be asked to record name on entry of conference
730  * without review */
731  CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
732  /*! If set, the user will be initially self-muted */
733  CONFFLAG_STARTMUTED = (1 << 24),
734  /*! Pass DTMF through the conference */
735  CONFFLAG_PASS_DTMF = (1 << 25),
736  CONFFLAG_SLA_STATION = (1 << 26),
737  CONFFLAG_SLA_TRUNK = (1 << 27),
738  /*! If set, the user should continue in the dialplan if kicked out */
739  CONFFLAG_KICK_CONTINUE = (1 << 28),
740  CONFFLAG_DURATION_STOP = (1 << 29),
741  CONFFLAG_DURATION_LIMIT = (1 << 30),
742 };

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_WAITMARKED 
OPT_ARG_EXITKEYS 
OPT_ARG_DURATION_STOP 
OPT_ARG_DURATION_LIMIT 
OPT_ARG_MOH_CLASS 
OPT_ARG_INTROMSG 
OPT_ARG_INTROUSER_VMREC 
OPT_ARG_ARRAY_SIZE 

Definition at line 755 of file app_meetme.c.

◆ anonymous enum

anonymous enum
Enumerator
SLA_TRUNK_OPT_MOH 

Definition at line 7215 of file app_meetme.c.

7215  {
7216  SLA_TRUNK_OPT_MOH = (1 << 0),
7217 };

◆ anonymous enum

anonymous enum
Enumerator
SLA_TRUNK_OPT_ARG_MOH_CLASS 
SLA_TRUNK_OPT_ARG_ARRAY_SIZE 

Definition at line 7219 of file app_meetme.c.

◆ announcetypes

Enumerator
CONF_HASJOIN 
CONF_HASLEFT 

Definition at line 826 of file app_meetme.c.

826  {
827  CONF_HASJOIN,
829 };

◆ entrance_sound

Enumerator
ENTER 
LEAVE 

Definition at line 671 of file app_meetme.c.

671  {
672  ENTER,
673  LEAVE
674 };

◆ menu_modes

enum menu_modes
Enumerator
MENU_DISABLED 
MENU_NORMAL 
MENU_ADMIN 
MENU_ADMIN_EXTENDED 

Definition at line 2749 of file app_meetme.c.

◆ recording_state

Enumerator
MEETME_RECORD_OFF 
MEETME_RECORD_STARTED 
MEETME_RECORD_ACTIVE 
MEETME_RECORD_TERMINATE 

Definition at line 676 of file app_meetme.c.

◆ sla_event_type

Event types that can be queued up for the SLA thread.

Enumerator
SLA_EVENT_HOLD 

A station has put the call on hold

SLA_EVENT_DIAL_STATE 

The state of a dial has changed

SLA_EVENT_RINGING_TRUNK 

The state of a ringing trunk has changed

Definition at line 1038 of file app_meetme.c.

1038  {
1039  /*! A station has put the call on hold */
1041  /*! The state of a dial has changed */
1043  /*! The state of a ringing trunk has changed */
1045 };

◆ sla_hold_access

Enumerator
SLA_HOLD_OPEN 

This means that any station can put it on hold, and any station can retrieve the call from hold.

SLA_HOLD_PRIVATE 

This means that only the station that put the call on hold may retrieve it from hold.

Definition at line 931 of file app_meetme.c.

931  {
932  /*! This means that any station can put it on hold, and any station
933  * can retrieve the call from hold. */
935  /*! This means that only the station that put the call on hold may
936  * retrieve it from hold. */
938 };

◆ sla_station_hangup

Enumerator
SLA_STATION_HANGUP_NORMAL 
SLA_STATION_HANGUP_TIMEOUT 

Definition at line 1071 of file app_meetme.c.

◆ sla_trunk_state

Enumerator
SLA_TRUNK_STATE_IDLE 
SLA_TRUNK_STATE_RINGING 
SLA_TRUNK_STATE_UP 
SLA_TRUNK_STATE_ONHOLD 
SLA_TRUNK_STATE_ONHOLD_BYME 

Definition at line 923 of file app_meetme.c.

◆ sla_which_trunk_refs

Enumerator
ALL_TRUNK_REFS 
INACTIVE_TRUNK_REFS 

Definition at line 918 of file app_meetme.c.

◆ volume_action

Enumerator
VOL_UP 
VOL_DOWN 

Definition at line 666 of file app_meetme.c.

666  {
667  VOL_UP,
668  VOL_DOWN
669 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 8085 of file app_meetme.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 8085 of file app_meetme.c.

◆ acf_meetme_info()

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

Definition at line 7941 of file app_meetme.c.

References acf_meetme_info_eval(), AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_conference::confno, ast_conference::list, LOG_ERROR, LOG_NOTICE, parse(), and result.

7942 {
7943  struct ast_conference *conf;
7944  char *parse;
7945  int result = -2; /* only non-negative numbers valid, -1 is used elsewhere */
7947  AST_APP_ARG(keyword);
7949  );
7950 
7951  if (ast_strlen_zero(data)) {
7952  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires two arguments\n");
7953  return -1;
7954  }
7955 
7956  parse = ast_strdupa(data);
7957  AST_STANDARD_APP_ARGS(args, parse);
7958 
7959  if (ast_strlen_zero(args.keyword)) {
7960  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a keyword\n");
7961  return -1;
7962  }
7963 
7964  if (ast_strlen_zero(args.confno)) {
7965  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a conference number\n");
7966  return -1;
7967  }
7968 
7969  AST_LIST_LOCK(&confs);
7970  AST_LIST_TRAVERSE(&confs, conf, list) {
7971  if (!strcmp(args.confno, conf->confno)) {
7972  result = acf_meetme_info_eval(args.keyword, conf);
7973  break;
7974  }
7975  }
7977 
7978  if (result > -1) {
7979  snprintf(buf, len, "%d", result);
7980  } else if (result == -1) {
7981  ast_log(LOG_NOTICE, "Error: invalid keyword: '%s'\n", args.keyword);
7982  snprintf(buf, len, "0");
7983  } else if (result == -2) {
7984  ast_log(LOG_NOTICE, "Error: conference (%s) not found\n", args.confno);
7985  snprintf(buf, len, "0");
7986  }
7987 
7988  return 0;
7989 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int acf_meetme_info_eval(const char *keyword, const struct ast_conference *conf)
Definition: app_meetme.c:7923
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static PGresult * result
Definition: cel_pgsql.c:88
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ acf_meetme_info_eval()

static int acf_meetme_info_eval ( const char *  keyword,
const struct ast_conference conf 
)
static

Definition at line 7923 of file app_meetme.c.

References ast_conference::isdynamic, ast_conference::locked, NULL, ast_conference::start, and ast_conference::users.

Referenced by acf_meetme_info().

7924 {
7925  if (!strcasecmp("lock", keyword)) {
7926  return conf->locked;
7927  } else if (!strcasecmp("parties", keyword)) {
7928  return conf->users;
7929  } else if (!strcasecmp("activity", keyword)) {
7930  time_t now;
7931  now = time(NULL);
7932  return (now - conf->start);
7933  } else if (!strcasecmp("dynamic", keyword)) {
7934  return conf->isdynamic;
7935  } else {
7936  return -1;
7937  }
7938 
7939 }
unsigned int isdynamic
Definition: app_meetme.c:857
#define NULL
Definition: resample.c:96
unsigned int locked
Definition: app_meetme.c:858

◆ action_meetmelist()

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

Definition at line 5521 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ast_conf_user::adminflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_caller(), ast_channel_connected(), ast_channel_name(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero, ast_test_flag64, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), ast_conf_user::chan, CONFFLAG_ADMIN, CONFFLAG_MARKEDUSER, CONFFLAG_MONITOR, CONFFLAG_TALKER, ast_conference::confno, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_party_id::number, S_COR, ast_party_name::str, ast_party_number::str, ast_conf_user::talking, total, user, ast_conf_user::user_no, ast_conference::usercontainer, ast_conf_user::userflags, ast_party_name::valid, and ast_party_number::valid.

Referenced by load_module().

5522 {
5523  const char *actionid = astman_get_header(m, "ActionID");
5524  const char *conference = astman_get_header(m, "Conference");
5525  char idText[80] = "";
5526  struct ast_conference *cnf;
5527  struct ast_conf_user *user;
5528  struct ao2_iterator user_iter;
5529  int total = 0;
5530 
5531  if (!ast_strlen_zero(actionid))
5532  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
5533 
5534  if (AST_LIST_EMPTY(&confs)) {
5535  astman_send_error(s, m, "No active conferences.");
5536  return 0;
5537  }
5538 
5539  astman_send_listack(s, m, "Meetme user list will follow", "start");
5540 
5541  /* Find the right conference */
5542  AST_LIST_LOCK(&confs);
5543  AST_LIST_TRAVERSE(&confs, cnf, list) {
5544  /* If we ask for one particular, and this isn't it, skip it */
5545  if (!ast_strlen_zero(conference) && strcmp(cnf->confno, conference))
5546  continue;
5547 
5548  /* Show all the users */
5549  user_iter = ao2_iterator_init(cnf->usercontainer, 0);
5550  while ((user = ao2_iterator_next(&user_iter))) {
5551  total++;
5552  astman_append(s,
5553  "Event: MeetmeList\r\n"
5554  "%s"
5555  "Conference: %s\r\n"
5556  "UserNumber: %d\r\n"
5557  "CallerIDNum: %s\r\n"
5558  "CallerIDName: %s\r\n"
5559  "ConnectedLineNum: %s\r\n"
5560  "ConnectedLineName: %s\r\n"
5561  "Channel: %s\r\n"
5562  "Admin: %s\r\n"
5563  "Role: %s\r\n"
5564  "MarkedUser: %s\r\n"
5565  "Muted: %s\r\n"
5566  "Talking: %s\r\n"
5567  "\r\n",
5568  idText,
5569  cnf->confno,
5570  user->user_no,
5571  S_COR(ast_channel_caller(user->chan)->id.number.valid, ast_channel_caller(user->chan)->id.number.str, "<unknown>"),
5572  S_COR(ast_channel_caller(user->chan)->id.name.valid, ast_channel_caller(user->chan)->id.name.str, "<no name>"),
5574  S_COR(ast_channel_connected(user->chan)->id.name.valid, ast_channel_connected(user->chan)->id.name.str, "<no name>"),
5575  ast_channel_name(user->chan),
5576  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "Yes" : "No",
5577  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "Listen only" : ast_test_flag64(&user->userflags, CONFFLAG_TALKER) ? "Talk only" : "Talk and listen",
5578  ast_test_flag64(&user->userflags, CONFFLAG_MARKEDUSER) ? "Yes" : "No",
5579  user->adminflags & ADMINFLAG_MUTED ? "By admin" : user->adminflags & ADMINFLAG_SELFMUTED ? "By self" : "No",
5580  user->talking > 0 ? "Yes" : user->talking == 0 ? "No" : "Not monitored");
5581  ao2_ref(user, -1);
5582  }
5583  ao2_iterator_destroy(&user_iter);
5584  }
5586 
5587  /* Send final confirmation */
5588  astman_send_list_complete_start(s, m, "MeetmeListComplete", total);
5590  return 0;
5591 }
static char user[512]
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
struct ast_party_id id
Connected party ID.
Definition: channel.h:459
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
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 AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * str
Subscriber name (Malloced)
Definition: channel.h:265
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
struct ast_flags64 userflags
Definition: app_meetme.c:898
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ao2_container * usercontainer
Definition: app_meetme.c:875
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const char * ast_channel_name(const struct ast_channel *chan)
static int total
Definition: res_adsi.c:968
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
The MeetMe Conference object.
Definition: app_meetme.c:842
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_channel * chan
Definition: app_meetme.c:900
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
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
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ action_meetmelistrooms()

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

Definition at line 5593 of file app_meetme.c.

References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), ast_conference::confno, ast_conference::isdynamic, ast_conference::list, ast_conference::locked, ast_conference::markedusers, min, NULL, ast_conference::start, and ast_conference::users.

Referenced by load_module().

5594 {
5595  const char *actionid = astman_get_header(m, "ActionID");
5596  char idText[80] = "";
5597  struct ast_conference *cnf;
5598  int totalitems = 0;
5599  int hr, min, sec;
5600  time_t now;
5601  char markedusers[5];
5602 
5603  if (!ast_strlen_zero(actionid)) {
5604  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
5605  }
5606 
5607  if (AST_LIST_EMPTY(&confs)) {
5608  astman_send_error(s, m, "No active conferences.");
5609  return 0;
5610  }
5611 
5612  astman_send_listack(s, m, "Meetme conferences will follow", "start");
5613 
5614  now = time(NULL);
5615 
5616  /* Traverse the conference list */
5617  AST_LIST_LOCK(&confs);
5618  AST_LIST_TRAVERSE(&confs, cnf, list) {
5619  totalitems++;
5620 
5621  if (cnf->markedusers == 0) {
5622  strcpy(markedusers, "N/A");
5623  } else {
5624  sprintf(markedusers, "%.4d", cnf->markedusers);
5625  }
5626  hr = (now - cnf->start) / 3600;
5627  min = ((now - cnf->start) % 3600) / 60;
5628  sec = (now - cnf->start) % 60;
5629 
5630  astman_append(s,
5631  "Event: MeetmeListRooms\r\n"
5632  "%s"
5633  "Conference: %s\r\n"
5634  "Parties: %d\r\n"
5635  "Marked: %s\r\n"
5636  "Activity: %2.2d:%2.2d:%2.2d\r\n"
5637  "Creation: %s\r\n"
5638  "Locked: %s\r\n"
5639  "\r\n",
5640  idText,
5641  cnf->confno,
5642  cnf->users,
5643  markedusers,
5644  hr, min, sec,
5645  cnf->isdynamic ? "Dynamic" : "Static",
5646  cnf->locked ? "Yes" : "No");
5647  }
5649 
5650  /* Send final confirmation */
5651  astman_send_list_complete_start(s, m, "MeetmeListRoomsComplete", totalitems);
5653  return 0;
5654 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
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 AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:857
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
unsigned int locked
Definition: app_meetme.c:858
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
#define min(a, b)
Definition: f2c.h:197
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
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_meetmemute()

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

Definition at line 5511 of file app_meetme.c.

References meetmemute().

Referenced by load_module().

5512 {
5513  return meetmemute(s, m, 1);
5514 }
static int meetmemute(struct mansession *s, const struct message *m, int mute)
Definition: app_meetme.c:5451

◆ action_meetmeunmute()

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

Definition at line 5516 of file app_meetme.c.

References meetmemute().

Referenced by load_module().

5517 {
5518  return meetmemute(s, m, 0);
5519 }
static int meetmemute(struct mansession *s, const struct message *m, int mute)
Definition: app_meetme.c:5451

◆ admin_exec()

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

The MeetMeadmin application.

MeetMeAdmin(confno, command, caller)

Definition at line 5225 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ao2_callback, ao2_cleanup, ao2_find, ao2_ref, AST_APP_ARG, ast_atomic_fetchadd_int(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag64, CONFFLAG_ADMIN, ast_conference::confno, dispose_conf(), find_user(), ast_conf_user::list, ast_conference::locked, LOG_NOTICE, LOG_WARNING, NULL, OBJ_NODATA, pbx_builtin_setvar_helper(), RAII_VAR, ast_conference::refcount, reset_volumes(), rt_extend_conf(), tweak_listen_volume(), tweak_talk_volume(), user_listen_voldown_cb(), user_listen_volup_cb(), user_max_cmp(), user_reset_vol_cb(), user_set_kickme_cb(), user_set_muted_cb(), user_set_unmuted_cb(), user_talk_voldown_cb(), user_talk_volup_cb(), ast_conference::usercontainer, VOL_DOWN, and VOL_UP.

Referenced by meetme_cmd_helper(), meetme_stasis_generate_msg(), run_station(), sla_station_exec(), and sla_stop_ringing_trunk().

5225  {
5226  char *params;
5227  struct ast_conference *cnf;
5228  struct ast_conf_user *user = NULL;
5230  AST_APP_ARG(confno);
5231  AST_APP_ARG(command);
5232  AST_APP_ARG(user);
5233  );
5234  int res = 0;
5235 
5236  if (ast_strlen_zero(data)) {
5237  ast_log(LOG_WARNING, "MeetMeAdmin requires an argument!\n");
5238  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOPARSE");
5239  return -1;
5240  }
5241 
5242  params = ast_strdupa(data);
5243  AST_STANDARD_APP_ARGS(args, params);
5244 
5245  if (!args.command) {
5246  ast_log(LOG_WARNING, "MeetmeAdmin requires a command!\n");
5247  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOPARSE");
5248  return -1;
5249  }
5250 
5251  AST_LIST_LOCK(&confs);
5252  AST_LIST_TRAVERSE(&confs, cnf, list) {
5253  if (!strcmp(cnf->confno, args.confno))
5254  break;
5255  }
5256 
5257  if (!cnf) {
5258  ast_log(LOG_WARNING, "Conference number '%s' not found!\n", args.confno);
5260  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOTFOUND");
5261  return 0;
5262  }
5263 
5265 
5266  if (args.user) {
5267  user = find_user(cnf, args.user);
5268  if (!user) {
5269  ast_log(LOG_NOTICE, "Specified User not found!\n");
5270  res = -2;
5271  goto usernotfound;
5272  }
5273  } else {
5274  /* fail for commands that require a user */
5275  switch (*args.command) {
5276  case 'm': /* Unmute */
5277  case 'M': /* Mute */
5278  case 't': /* Lower user's talk volume */
5279  case 'T': /* Raise user's talk volume */
5280  case 'u': /* Lower user's listen volume */
5281  case 'U': /* Raise user's listen volume */
5282  case 'r': /* Reset user's volume level */
5283  case 'k': /* Kick user */
5284  res = -2;
5285  ast_log(LOG_NOTICE, "No user specified!\n");
5286  goto usernotfound;
5287  default:
5288  break;
5289  }
5290  }
5291 
5292  switch (*args.command) {
5293  case 76: /* L: Lock */
5294  cnf->locked = 1;
5295  break;
5296  case 108: /* l: Unlock */
5297  cnf->locked = 0;
5298  break;
5299  case 75: /* K: kick all users */
5301  break;
5302  case 101: /* e: Eject last user*/
5303  {
5304  int max_no = 0;
5305  RAII_VAR(struct ast_conf_user *, eject_user, NULL, ao2_cleanup);
5306 
5308  eject_user = ao2_find(cnf->usercontainer, &max_no, 0);
5309  if (!eject_user) {
5310  res = -1;
5311  ast_log(LOG_NOTICE, "No last user to kick!\n");
5312  break;
5313  }
5314 
5315  if (!ast_test_flag64(&eject_user->userflags, CONFFLAG_ADMIN)) {
5316  eject_user->adminflags |= ADMINFLAG_KICKME;
5317  } else {
5318  res = -1;
5319  ast_log(LOG_NOTICE, "Not kicking last user, is an Admin!\n");
5320  }
5321  break;
5322  }
5323  case 77: /* M: Mute */
5324  user->adminflags |= ADMINFLAG_MUTED;
5325  break;
5326  case 78: /* N: Mute all (non-admin) users */
5328  break;
5329  case 109: /* m: Unmute */
5331  break;
5332  case 110: /* n: Unmute all users */
5334  break;
5335  case 107: /* k: Kick user */
5336  user->adminflags |= ADMINFLAG_KICKME;
5337  break;
5338  case 118: /* v: Lower all users listen volume */
5340  break;
5341  case 86: /* V: Raise all users listen volume */
5343  break;
5344  case 115: /* s: Lower all users speaking volume */
5346  break;
5347  case 83: /* S: Raise all users speaking volume */
5349  break;
5350  case 82: /* R: Reset all volume levels */
5352  break;
5353  case 114: /* r: Reset user's volume level */
5354  reset_volumes(user);
5355  break;
5356  case 85: /* U: Raise user's listen volume */
5357  tweak_listen_volume(user, VOL_UP);
5358  break;
5359  case 117: /* u: Lower user's listen volume */
5361  break;
5362  case 84: /* T: Raise user's talk volume */
5363  tweak_talk_volume(user, VOL_UP);
5364  break;
5365  case 116: /* t: Lower user's talk volume */
5366  tweak_talk_volume(user, VOL_DOWN);
5367  break;
5368  case 'E': /* E: Extend conference */
5369  if (rt_extend_conf(args.confno)) {
5370  res = -1;
5371  }
5372  break;
5373  }
5374 
5375  if (args.user) {
5376  /* decrement reference from find_user */
5377  ao2_ref(user, -1);
5378  }
5379 usernotfound:
5381 
5382  dispose_conf(cnf);
5383  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", res == -2 ? "NOTFOUND" : res ? "FAILED" : "OK");
5384 
5385  return 0;
5386 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ast_conf_user * find_user(struct ast_conference *conf, const char *callerident)
Definition: app_meetme.c:5162
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1494
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2523
static int user_set_unmuted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2727
#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
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int user_listen_volup_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:5175
static int user_reset_vol_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:5203
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
const char * args
#define NULL
Definition: resample.c:96
struct ast_conf_user::@41 list
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
unsigned int locked
Definition: app_meetme.c:858
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1579
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int user_listen_voldown_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:5182
static int user_set_kickme_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2716
#define ast_log
Definition: astobj2.c:42
#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
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1506
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1518
static int user_talk_volup_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:5189
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * usercontainer
Definition: app_meetme.c:875
structure to hold users read from users.conf
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
The MeetMe Conference object.
Definition: app_meetme.c:842
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
static int user_talk_voldown_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:5196
static int user_set_muted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2738
#define AST_APP_ARG(name)
Define an application argument.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ announce_thread()

static void* announce_thread ( void *  data)
static

Definition at line 2615 of file app_meetme.c.

References ast_conference::announcelist, ast_conference::announcelist_addition, ast_conference::announcelistlock, ast_conference::announcethread_stop, announce_listitem::announcetype, ao2_ref, ast_check_hangup(), ast_cond_wait, ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK(), AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, ast_streamfile(), ast_waitstream(), CONF_HASLEFT, announce_listitem::confchan, announce_listitem::confusers, get_announce_filename(), announce_listitem::language, announce_listitem::namerecloc, NULL, PATH_MAX, and announce_listitem::vmrec.

Referenced by conf_run().

2616 {
2617  struct announce_listitem *current;
2618  struct ast_conference *conf = data;
2619  int res;
2620  char filename[PATH_MAX] = "";
2622  AST_LIST_HEAD_INIT_NOLOCK(&local_list);
2623 
2624  while (!conf->announcethread_stop) {
2626  if (conf->announcethread_stop) {
2628  break;
2629  }
2630  if (AST_LIST_EMPTY(&conf->announcelist))
2632 
2633  AST_LIST_APPEND_LIST(&local_list, &conf->announcelist, entry);
2635 
2637  if (conf->announcethread_stop) {
2638  break;
2639  }
2640 
2641  for (res = 1; !conf->announcethread_stop && (current = AST_LIST_REMOVE_HEAD(&local_list, entry)); ao2_ref(current, -1)) {
2642  ast_debug(1, "About to play %s\n", current->namerecloc);
2643  if (!ast_fileexists(current->namerecloc, NULL, NULL))
2644  continue;
2645  if ((current->confchan) && (current->confusers > 1) && !ast_check_hangup(current->confchan)) {
2646  if (!ast_streamfile(current->confchan, current->namerecloc, current->language))
2647  res = ast_waitstream(current->confchan, "");
2648  if (!res) {
2649  ast_copy_string(filename, get_announce_filename(current->announcetype), sizeof(filename));
2650  if (!ast_streamfile(current->confchan, filename, current->language))
2651  ast_waitstream(current->confchan, "");
2652  }
2653  }
2654  if (current->announcetype == CONF_HASLEFT && current->announcetype && !current->vmrec) {
2655  /* only remove it if it isn't a VM recording file */
2656  ast_filedelete(current->namerecloc, NULL);
2657  }
2658  }
2659  }
2660 
2661  /* thread marked to stop, clean up */
2662  while ((current = AST_LIST_REMOVE_HEAD(&local_list, entry))) {
2663  /* only delete if it's a vm rec */
2664  if (!current->vmrec) {
2665  ast_filedelete(current->namerecloc, NULL);
2666  }
2667  ao2_ref(current, -1);
2668  }
2669  return NULL;
2670 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static const char * get_announce_filename(enum announcetypes type)
Definition: app_meetme.c:2601
struct ast_channel * confchan
Definition: app_meetme.c:835
struct ast_conference::@40 announcelist
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
ast_mutex_t announcelistlock
Definition: app_meetme.c:883
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
char namerecloc[PATH_MAX]
Definition: app_meetme.c:833
char language[MAX_LANGUAGE]
Definition: app_meetme.c:834
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
ast_cond_t announcelist_addition
Definition: app_meetme.c:881
unsigned int announcethread_stop
Definition: app_meetme.c:880
Definition: search.h:40
enum announcetypes announcetype
Definition: app_meetme.c:838
#define PATH_MAX
Definition: asterisk.h:40
The MeetMe Conference object.
Definition: app_meetme.c:842
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define AST_LIST_APPEND_LIST(head, list, field)
Appends a whole list to the tail of a list.
Definition: linkedlists.h:782

◆ answer_trunk_chan()

static void answer_trunk_chan ( struct ast_channel chan)
static

Definition at line 6062 of file app_meetme.c.

References ast_answer(), and ast_indicate().

Referenced by run_station(), sla_handle_dial_state_event(), and sla_station_exec().

6063 {
6064  ast_answer(chan);
6065  ast_indicate(chan, -1);
6066 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 8085 of file app_meetme.c.

◆ build_conf()

static struct ast_conference* build_conf ( const char *  confno,
const char *  pin,
const char *  pinadmin,
int  make,
int  dynamic,
int  refcount,
const struct ast_channel chan,
struct ast_test test 
)
static

Find or create a conference.

Parameters
confnoThe conference name/number
pinThe regular user pin
pinadminThe admin pin
makeMake the conf if it doesn't exist
dynamicMark the newly created conference as dynamic
refcountHow many references to mark on the conference
chanThe asterisk channel
test
Returns
A pointer to the conference struct, or NULL if it wasn't found and make or dynamic were not set.

Definition at line 1606 of file app_meetme.c.

References ast_conference::announcethread, ast_conference::announcethreadlock, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_container_alloc_list, ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, ast_channel_fd(), ast_channel_uniqueid(), ast_copy_string(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin, ast_free, ast_hangup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_destroy, ast_mutex_init, AST_PTHREADT_NULL, ast_request(), ast_set_read_format(), ast_set_write_format(), ast_test_status_update, ast_verb, ast_conference::chan, ast_conference::confno, ast_conference::dahdiconf, ast_conference::fd, ast_conference::isdynamic, ast_conference::listenlock, LOG_WARNING, ast_conference::maxusers, NULL, ast_conference::pin, ast_conference::pinadmin, ast_conference::playlock, ast_conference::recordthread, ast_conference::recordthreadlock, ast_conference::refcount, ast_conference::start, ast_conference::uniqueid, user_no_cmp(), and ast_conference::usercontainer.

Referenced by dial_trunk(), find_conf(), find_conf_realtime(), run_station(), sla_station_exec(), and sla_trunk_exec().

1609 {
1610  struct ast_conference *cnf;
1611  struct dahdi_confinfo dahdic = { 0, };
1612  int confno_int = 0;
1614 
1615  AST_LIST_LOCK(&confs);
1616 
1617  AST_LIST_TRAVERSE(&confs, cnf, list) {
1618  if (!strcmp(confno, cnf->confno))
1619  break;
1620  }
1621 
1622  if (cnf || (!make && !dynamic) || !cap_slin)
1623  goto cnfout;
1624 
1625  ast_format_cap_append(cap_slin, ast_format_slin, 0);
1626  /* Make a new one */
1627  cnf = ast_calloc(1, sizeof(*cnf));
1628  if (!cnf) {
1629  goto cnfout;
1630  }
1631 
1633  NULL, user_no_cmp);
1634  if (!cnf->usercontainer) {
1635  goto cnfout;
1636  }
1637 
1638  ast_mutex_init(&cnf->playlock);
1639  ast_mutex_init(&cnf->listenlock);
1644  ast_copy_string(cnf->confno, confno, sizeof(cnf->confno));
1645  ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
1646  ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
1647  ast_copy_string(cnf->uniqueid, ast_channel_uniqueid(chan), sizeof(cnf->uniqueid));
1648 
1649  /* Setup a new dahdi conference */
1650  dahdic.confno = -1;
1651  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
1652  cnf->fd = open("/dev/dahdi/pseudo", O_RDWR);
1653  if (cnf->fd < 0 || ioctl(cnf->fd, DAHDI_SETCONF, &dahdic)) {
1654  if (test) {
1655  /* if we are creating a conference for a unit test, it is not neccesary
1656  * to open a pseudo channel, so, if we fail continue creating
1657  * the conference. */
1658  ast_test_status_update(test, "Unable to open DAHDI pseudo device\n");
1659  } else {
1660  ast_log(LOG_WARNING, "Unable to open DAHDI pseudo device\n");
1661  if (cnf->fd >= 0)
1662  close(cnf->fd);
1663  ao2_ref(cnf->usercontainer, -1);
1664  ast_mutex_destroy(&cnf->playlock);
1668  ast_free(cnf);
1669  cnf = NULL;
1670  goto cnfout;
1671  }
1672  }
1673 
1674  cnf->dahdiconf = dahdic.confno;
1675 
1676  /* Setup a new channel for playback of audio files */
1677  cnf->chan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL);
1678  if (cnf->chan) {
1681  dahdic.chan = 0;
1682  dahdic.confno = cnf->dahdiconf;
1683  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
1684  if (ioctl(ast_channel_fd(cnf->chan, 0), DAHDI_SETCONF, &dahdic)) {
1685  if (test) {
1686  ast_test_status_update(test, "Error setting conference on pseudo channel\n");
1687  }
1688  ast_log(LOG_WARNING, "Error setting conference\n");
1689  if (cnf->chan)
1690  ast_hangup(cnf->chan);
1691  else
1692  close(cnf->fd);
1693  ao2_ref(cnf->usercontainer, -1);
1694  ast_mutex_destroy(&cnf->playlock);
1698  ast_free(cnf);
1699  cnf = NULL;
1700  goto cnfout;
1701  }
1702  }
1703 
1704  /* Fill the conference struct */
1705  cnf->start = time(NULL);
1706  cnf->maxusers = 0x7fffffff;
1707  cnf->isdynamic = dynamic ? 1 : 0;
1708  ast_verb(3, "Created MeetMe conference %d for conference '%s'\n", cnf->dahdiconf, cnf->confno);
1709  AST_LIST_INSERT_HEAD(&confs, cnf, list);
1710 
1711  /* Reserve conference number in map */
1712  if ((sscanf(cnf->confno, "%30d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024))
1713  conf_map[confno_int] = 1;
1714 
1715 cnfout:
1716  ao2_cleanup(cap_slin);
1717  if (cnf)
1718  ast_atomic_fetchadd_int(&cnf->refcount, refcount);
1719 
1721 
1722  return cnf;
1723 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:846
ast_mutex_t playlock
Definition: app_meetme.c:843
pthread_t recordthread
Definition: app_meetme.c:860
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:857
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
ast_mutex_t listenlock
Definition: app_meetme.c:844
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6444
static int user_no_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1567
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
const char * ast_channel_uniqueid(const struct ast_channel *chan)
char uniqueid[32]
Definition: app_meetme.c:867
char pin[MAX_PIN]
Definition: app_meetme.c:865
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
pthread_t announcethread
Definition: app_meetme.c:878
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ao2_container * usercontainer
Definition: app_meetme.c:875
int ast_channel_fd(const struct ast_channel *chan, int which)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char pinadmin[MAX_PIN]
Definition: app_meetme.c:866
static unsigned int conf_map[1024]
Definition: app_meetme.c:888
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
ast_mutex_t recordthreadlock
Definition: app_meetme.c:861
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
ast_mutex_t announcethreadlock
Definition: app_meetme.c:879

◆ can_write()

static int can_write ( struct ast_channel chan,
struct ast_flags64 confflags 
)
static

Definition at line 2672 of file app_meetme.c.

References AST_STATE_UP, ast_test_flag64, and CONFFLAG_NO_AUDIO_UNTIL_UP.

Referenced by conf_run().

2673 {
2674  if (!ast_test_flag64(confflags, CONFFLAG_NO_AUDIO_UNTIL_UP)) {
2675  return 1;
2676  }
2677 
2678  return (ast_channel_state(chan) == AST_STATE_UP);
2679 }
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:747
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ careful_write()

static int careful_write ( int  fd,
unsigned char *  data,
int  len,
int  block 
)
static

Definition at line 1408 of file app_meetme.c.

References ast_log, errno, and LOG_WARNING.

Referenced by conf_play(), and conf_run().

1409 {
1410  int res;
1411  int x;
1412 
1413  while (len) {
1414  if (block) {
1415  x = DAHDI_IOMUX_WRITE | DAHDI_IOMUX_SIGEVENT;
1416  res = ioctl(fd, DAHDI_IOMUX, &x);
1417  } else
1418  res = 0;
1419  if (res >= 0)
1420  res = write(fd, data, len);
1421  if (res < 1) {
1422  if (errno != EAGAIN) {
1423  ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
1424  return -1;
1425  } else
1426  return 0;
1427  }
1428  len -= res;
1429  data += res;
1430  }
1431 
1432  return 0;
1433 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno

◆ channel_admin_exec()

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

The MeetMeChannelAdmin application MeetMeChannelAdmin(channel, command)

Definition at line 5390 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ast_conf_user::adminflags, ao2_callback, ao2_ref, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_conf_user::list, LOG_NOTICE, LOG_WARNING, NULL, user_chan_cb(), and ast_conference::usercontainer.

Referenced by load_module().

5390  {
5391  char *params;
5392  struct ast_conference *conf = NULL;
5393  struct ast_conf_user *user = NULL;
5396  AST_APP_ARG(command);
5397  );
5398 
5399  if (ast_strlen_zero(data)) {
5400  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires two arguments!\n");
5401  return -1;
5402  }
5403 
5404  params = ast_strdupa(data);
5405  AST_STANDARD_APP_ARGS(args, params);
5406 
5407  if (!args.channel) {
5408  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires a channel name!\n");
5409  return -1;
5410  }
5411 
5412  if (!args.command) {
5413  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires a command!\n");
5414  return -1;
5415  }
5416 
5417  AST_LIST_LOCK(&confs);
5418  AST_LIST_TRAVERSE(&confs, conf, list) {
5419  if ((user = ao2_callback(conf->usercontainer, 0, user_chan_cb, args.channel))) {
5420  break;
5421  }
5422  }
5423 
5424  if (!user) {
5425  ast_log(LOG_NOTICE, "Specified user (%s) not found\n", args.channel);
5427  return 0;
5428  }
5429 
5430  /* perform the specified action */
5431  switch (*args.command) {
5432  case 77: /* M: Mute */
5433  user->adminflags |= ADMINFLAG_MUTED;
5434  break;
5435  case 109: /* m: Unmute */
5436  user->adminflags &= ~ADMINFLAG_MUTED;
5437  break;
5438  case 107: /* k: Kick user */
5439  user->adminflags |= ADMINFLAG_KICKME;
5440  break;
5441  default: /* unknown command */
5442  ast_log(LOG_WARNING, "Unknown MeetMeChannelAdmin command '%s'\n", args.command);
5443  break;
5444  }
5445  ao2_ref(user, -1);
5447 
5448  return 0;
5449 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int user_chan_cb(void *obj, void *args, int flags)
Definition: app_meetme.c:5210
#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
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
Definition: muted.c:95
const char * args
#define NULL
Definition: resample.c:96
struct ast_conf_user::@41 list
#define ast_strlen_zero(foo)
Definition: strings.h:52
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_log
Definition: astobj2.c:42
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ao2_container * usercontainer
Definition: app_meetme.c:875
structure to hold users read from users.conf
The MeetMe Conference object.
Definition: app_meetme.c:842
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ complete_confno()

static char* complete_confno ( const char *  word,
int  state 
)
static

Definition at line 1725 of file app_meetme.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_conference::confno, len(), ast_conference::list, and NULL.

Referenced by complete_meetmecmd_list(), complete_meetmecmd_lock(), and complete_meetmecmd_mute_kick().

1726 {
1727  struct ast_conference *cnf;
1728  char *ret = NULL;
1729  int which = 0;
1730  int len = strlen(word);
1731 
1732  AST_LIST_LOCK(&confs);
1733  AST_LIST_TRAVERSE(&confs, cnf, list) {
1734  if (!strncmp(word, cnf->confno, len) && ++which > state) {
1735  /* dup before releasing the lock */
1736  ret = ast_strdup(cnf->confno);
1737  break;
1738  }
1739  }
1741  return ret;
1742 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
short word
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ complete_meetmecmd_list()

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

Definition at line 1814 of file app_meetme.c.

References ast_strdup, ast_strdupa, complete_confno(), ast_conference::confno, len(), NULL, state, and STR_CONCISE.

Referenced by meetme_show_cmd().

1815 {
1816  int len;
1817 
1818  if (pos == 2) {
1819  len = strlen(word);
1820  if (!strncasecmp(word, STR_CONCISE, len)) {
1821  if (state == 0) {
1822  return ast_strdup(STR_CONCISE);
1823  }
1824  --state;
1825  }
1826 
1827  return complete_confno(word, state);
1828  }
1829  if (pos == 3 && state == 0) {
1830  char *saved = NULL;
1831  char *myline;
1832  char *confno;
1833 
1834  /* Extract the confno from the command line. */
1835  myline = ast_strdupa(line);
1836  strtok_r(myline, " ", &saved);
1837  strtok_r(NULL, " ", &saved);
1838  confno = strtok_r(NULL, " ", &saved);
1839 
1840  if (!strcasecmp(confno, STR_CONCISE)) {
1841  /* There is nothing valid in this position now. */
1842  return NULL;
1843  }
1844 
1845  len = strlen(word);
1846  if (!strncasecmp(word, STR_CONCISE, len)) {
1847  return ast_strdup(STR_CONCISE);
1848  }
1849  }
1850  return NULL;
1851 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define STR_CONCISE
Definition: app_meetme.c:644
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
short word
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1725
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ complete_meetmecmd_lock()

static char* complete_meetmecmd_lock ( const char *  word,
int  pos,
int  state 
)
static

Definition at line 1806 of file app_meetme.c.

References complete_confno(), and NULL.

Referenced by meetme_lock_cmd().

1807 {
1808  if (pos == 2) {
1809  return complete_confno(word, state);
1810  }
1811  return NULL;
1812 }
#define NULL
Definition: resample.c:96
short word
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1725

◆ complete_meetmecmd_mute_kick()

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

Definition at line 1766 of file app_meetme.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_strdupa, complete_confno(), complete_userno(), ast_conference::confno, len(), ast_conference::list, NULL, and state.

Referenced by meetme_kick_cmd(), and meetme_mute_cmd().

1767 {
1768  if (pos == 2) {
1769  return complete_confno(word, state);
1770  }
1771  if (pos == 3) {
1772  int len = strlen(word);
1773  char *ret = NULL;
1774  char *saved = NULL;
1775  char *myline;
1776  char *confno;
1777  struct ast_conference *cnf;
1778 
1779  if (!strncasecmp(word, "all", len)) {
1780  if (state == 0) {
1781  return ast_strdup("all");
1782  }
1783  --state;
1784  }
1785 
1786  /* Extract the confno from the command line. */
1787  myline = ast_strdupa(line);
1788  strtok_r(myline, " ", &saved);
1789  strtok_r(NULL, " ", &saved);
1790  confno = strtok_r(NULL, " ", &saved);
1791 
1792  AST_LIST_LOCK(&confs);
1793  AST_LIST_TRAVERSE(&confs, cnf, list) {
1794  if (!strcmp(confno, cnf->confno)) {
1795  ret = complete_userno(cnf, word, state);
1796  break;
1797  }
1798  }
1800 
1801  return ret;
1802  }
1803  return NULL;
1804 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static char * complete_userno(struct ast_conference *cnf, const char *word, int state)
Definition: app_meetme.c:1744
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
short word
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1725
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ complete_userno()

static char* complete_userno ( struct ast_conference cnf,
const char *  word,
int  state 
)
static

Definition at line 1744 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_strdup, len(), NULL, ast_conf_user::user_no, and ast_conference::usercontainer.

Referenced by complete_meetmecmd_mute_kick().

1745 {
1746  char usrno[50];
1747  struct ao2_iterator iter;
1748  struct ast_conf_user *usr;
1749  char *ret = NULL;
1750  int which = 0;
1751  int len = strlen(word);
1752 
1753  iter = ao2_iterator_init(cnf->usercontainer, 0);
1754  for (; (usr = ao2_iterator_next(&iter)); ao2_ref(usr, -1)) {
1755  snprintf(usrno, sizeof(usrno), "%d", usr->user_no);
1756  if (!strncmp(word, usrno, len) && ++which > state) {
1757  ao2_ref(usr, -1);
1758  ret = ast_strdup(usrno);
1759  break;
1760  }
1761  }
1762  ao2_iterator_destroy(&iter);
1763  return ret;
1764 }
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
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ao2_container * usercontainer
Definition: app_meetme.c:875
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
short word

◆ conf_exec()

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

The meetme() application.

Definition at line 4837 of file app_meetme.c.

References ast_conference::adminopts, ARRAY_LEN, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options64(), ast_category_browse(), ast_channel_language(), ast_channel_name(), ast_config_destroy(), ast_config_load, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DIGIT_ANY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_load_realtime_multientry(), ast_log, ast_say_digits(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero, ast_test_flag64, ast_test_suite_event_notify, ast_variable_browse(), ast_variable_retrieve(), ast_verb, ast_waitstream(), conf_run(), CONFFLAG_ADMIN, CONFFLAG_ALWAYSPROMPT, CONFFLAG_DYNAMIC, CONFFLAG_DYNAMICPIN, CONFFLAG_EMPTY, CONFFLAG_EMPTYNOPIN, CONFFLAG_QUIET, CONFIG_FILE_NAME, CONFIG_STATUS_FILEINVALID, ast_conference::confno, dispose_conf(), find_conf(), find_conf_realtime(), sip_to_pjsip::info(), ast_conference::isdynamic, LOG_ERROR, LOG_WARNING, MAX_CONFNUM, MAX_PIN, MAX_SETTINGS, meetme_opts, ast_variable::name, ast_variable::next, NULL, OPT_ARG_ARRAY_SIZE, options, parse(), ast_conference::pin, ast_conference::pinadmin, ast_conference::recordingfilename, ast_conference::recordingformat, SENTINEL, strsep(), ast_conference::useropts, ast_conference::users, ast_variable::value, and var.

Referenced by load_module().

4838 {
4839  int res = -1;
4840  char confno[MAX_CONFNUM] = "";
4841  int allowretry = 0;
4842  int retrycnt = 0;
4843  struct ast_conference *cnf = NULL;
4844  struct ast_flags64 confflags = {0};
4845  struct ast_flags config_flags = { 0 };
4846  int dynamic = 0;
4847  int empty = 0, empty_no_pin = 0;
4848  int always_prompt = 0;
4849  const char *notdata;
4850  char *info, the_pin[MAX_PIN] = "";
4852  AST_APP_ARG(confno);
4854  AST_APP_ARG(pin);
4855  );
4856  char *optargs[OPT_ARG_ARRAY_SIZE] = { NULL, };
4857 
4858  if (ast_strlen_zero(data)) {
4859  allowretry = 1;
4860  notdata = "";
4861  } else {
4862  notdata = data;
4863  }
4864 
4865  if (ast_channel_state(chan) != AST_STATE_UP)
4866  ast_answer(chan);
4867 
4868  info = ast_strdupa(notdata);
4869 
4870  AST_STANDARD_APP_ARGS(args, info);
4871 
4872  if (args.confno) {
4873  ast_copy_string(confno, args.confno, sizeof(confno));
4874  if (ast_strlen_zero(confno)) {
4875  allowretry = 1;
4876  }
4877  }
4878 
4879  if (args.pin)
4880  ast_copy_string(the_pin, args.pin, sizeof(the_pin));
4881 
4882  if (args.options) {
4883  ast_app_parse_options64(meetme_opts, &confflags, optargs, args.options);
4884  dynamic = ast_test_flag64(&confflags, CONFFLAG_DYNAMIC | CONFFLAG_DYNAMICPIN);
4885  if (ast_test_flag64(&confflags, CONFFLAG_DYNAMICPIN) && ast_strlen_zero(args.pin))
4886  strcpy(the_pin, "q");
4887 
4888  empty = ast_test_flag64(&confflags, CONFFLAG_EMPTY | CONFFLAG_EMPTYNOPIN);
4889  empty_no_pin = ast_test_flag64(&confflags, CONFFLAG_EMPTYNOPIN);
4890  always_prompt = ast_test_flag64(&confflags, CONFFLAG_ALWAYSPROMPT | CONFFLAG_DYNAMICPIN);
4891  }
4892 
4893  do {
4894  if (retrycnt > 3)
4895  allowretry = 0;
4896  if (empty) {
4897  int i;
4898  struct ast_config *cfg;
4899  struct ast_variable *var;
4900  int confno_int;
4901 
4902  /* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
4903  if ((empty_no_pin) || (!dynamic)) {
4904  cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
4905  if (cfg && cfg != CONFIG_STATUS_FILEINVALID) {
4906  var = ast_variable_browse(cfg, "rooms");
4907  while (var) {
4908  char parse[MAX_SETTINGS], *stringp = parse, *confno_tmp;
4909  if (!strcasecmp(var->name, "conf")) {
4910  int found = 0;
4911  ast_copy_string(parse, var->value, sizeof(parse));
4912  confno_tmp = strsep(&stringp, "|,");
4913  if (!dynamic) {
4914  /* For static: run through the list and see if this conference is empty */
4915  AST_LIST_LOCK(&confs);
4916  AST_LIST_TRAVERSE(&confs, cnf, list) {
4917  if (!strcmp(confno_tmp, cnf->confno)) {
4918  /* The conference exists, therefore it's not empty */
4919  found = 1;
4920  break;
4921  }
4922  }
4924  cnf = NULL;
4925  if (!found) {
4926  /* At this point, we have a confno_tmp (static conference) that is empty */
4927  if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) {
4928  /* Case 1: empty_no_pin and pin is nonexistent (NULL)
4929  * Case 2: empty_no_pin and pin is blank (but not NULL)
4930  * Case 3: not empty_no_pin
4931  */
4932  ast_copy_string(confno, confno_tmp, sizeof(confno));
4933  break;
4934  }
4935  }
4936  }
4937  }
4938  var = var->next;
4939  }
4940  ast_config_destroy(cfg);
4941  }
4942 
4943  if (ast_strlen_zero(confno) && (cfg = ast_load_realtime_multientry("meetme", "confno LIKE", "%", SENTINEL))) {
4944  const char *catg;
4945  for (catg = ast_category_browse(cfg, NULL); catg; catg = ast_category_browse(cfg, catg)) {
4946  const char *confno_tmp = ast_variable_retrieve(cfg, catg, "confno");
4947  const char *pin_tmp = ast_variable_retrieve(cfg, catg, "pin");
4948  if (ast_strlen_zero(confno_tmp)) {
4949  continue;
4950  }
4951  if (!dynamic) {
4952  int found = 0;
4953  /* For static: run through the list and see if this conference is empty */
4954  AST_LIST_LOCK(&confs);
4955  AST_LIST_TRAVERSE(&confs, cnf, list) {
4956  if (!strcmp(confno_tmp, cnf->confno)) {
4957  /* The conference exists, therefore it's not empty */
4958  found = 1;
4959  break;
4960  }
4961  }
4963  if (!found) {
4964  /* At this point, we have a confno_tmp (realtime conference) that is empty */
4965  if ((empty_no_pin && ast_strlen_zero(pin_tmp)) || (!empty_no_pin)) {
4966  /* Case 1: empty_no_pin and pin is nonexistent (NULL)
4967  * Case 2: empty_no_pin and pin is blank (but not NULL)
4968  * Case 3: not empty_no_pin
4969  */
4970  ast_copy_string(confno, confno_tmp, sizeof(confno));
4971  break;
4972  }
4973  }
4974  }
4975  }
4976  ast_config_destroy(cfg);
4977  }
4978  }
4979 
4980  /* Select first conference number not in use */
4981  if (ast_strlen_zero(confno) && dynamic) {
4982  AST_LIST_LOCK(&confs);
4983  for (i = 0; i < ARRAY_LEN(conf_map); i++) {
4984  if (!conf_map[i]) {
4985  snprintf(confno, sizeof(confno), "%d", i);
4986  conf_map[i] = 1;
4987  break;
4988  }
4989  }
4991  }
4992 
4993  /* Not found? */
4994  if (ast_strlen_zero(confno)) {
4995  res = ast_streamfile(chan, "conf-noempty", ast_channel_language(chan));
4996  ast_test_suite_event_notify("PLAYBACK", "Message: conf-noempty");
4997  if (!res)
4998  ast_waitstream(chan, "");
4999  } else {
5000  if (sscanf(confno, "%30d", &confno_int) == 1) {
5001  if (!ast_test_flag64(&confflags, CONFFLAG_QUIET)) {
5002  res = ast_streamfile(chan, "conf-enteringno", ast_channel_language(chan));
5003  if (!res) {
5004  ast_waitstream(chan, "");
5005  res = ast_say_digits(chan, confno_int, "", ast_channel_language(chan));
5006  }
5007  }
5008  } else {
5009  ast_log(LOG_ERROR, "Could not scan confno '%s'\n", confno);
5010  }
5011  }
5012  }
5013 
5014  while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) {
5015  /* Prompt user for conference number */
5016  res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
5017  if (res < 0) {
5018  /* Don't try to validate when we catch an error */
5019  confno[0] = '\0';
5020  allowretry = 0;
5021  break;
5022  }
5023  }
5024  if (!ast_strlen_zero(confno)) {
5025  /* Check the validity of the conference */
5026  cnf = find_conf(chan, confno, 1, dynamic, the_pin,
5027  sizeof(the_pin), 1, &confflags);
5028  if (!cnf) {
5029  int too_early = 0;
5030 
5031  cnf = find_conf_realtime(chan, confno, 1, dynamic,
5032  the_pin, sizeof(the_pin), 1, &confflags, &too_early, optargs);
5033  if (rt_schedule && too_early)
5034  allowretry = 0;
5035  }
5036 
5037  if (!cnf) {
5038  if (allowretry) {
5039  confno[0] = '\0';
5040  res = ast_streamfile(chan, "conf-invalid", ast_channel_language(chan));
5041  if (!res)
5042  ast_waitstream(chan, "");
5043  res = -1;
5044  }
5045  } else {
5046  /* Conference requires a pin for specified access level */
5047  int req_pin = !ast_strlen_zero(cnf->pin) ||
5048  (!ast_strlen_zero(cnf->pinadmin) &&
5049  ast_test_flag64(&confflags, CONFFLAG_ADMIN));
5050  /* The following logic was derived from a
5051  * 4 variable truth table and defines which
5052  * circumstances are not exempt from pin
5053  * checking.
5054  * If this needs to be modified, write the
5055  * truth table back out from the boolean
5056  * expression AB+A'D+C', change the erroneous
5057  * result, and rederive the expression.
5058  * Variables:
5059  * A: pin provided?
5060  * B: always prompt?
5061  * C: dynamic?
5062  * D: has users? */
5063  int not_exempt = !cnf->isdynamic;
5064  not_exempt = not_exempt || (!ast_strlen_zero(args.pin) && ast_test_flag64(&confflags, CONFFLAG_ALWAYSPROMPT));
5065  not_exempt = not_exempt || (ast_strlen_zero(args.pin) && cnf->users);
5066  if (req_pin && not_exempt) {
5067  char pin[MAX_PIN] = "";
5068  int j;
5069 
5070  /* Allow the pin to be retried up to 3 times */
5071  for (j = 0; j < 3; j++) {
5072  if (*the_pin && (always_prompt == 0)) {
5073  ast_copy_string(pin, the_pin, sizeof(pin));
5074  res = 0;
5075  } else {
5076  /* Prompt user for pin if pin is required */
5077  ast_test_suite_event_notify("PLAYBACK", "Message: conf-getpin\r\n"
5078  "Channel: %s",
5079  ast_channel_name(chan));
5080  res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0);
5081  }
5082  if (res >= 0) {
5083  if ((!strcasecmp(pin, cnf->pin) &&
5084  (ast_strlen_zero(cnf->pinadmin) ||
5085  !ast_test_flag64(&confflags, CONFFLAG_ADMIN))) ||
5086  (!ast_strlen_zero(cnf->pinadmin) &&
5087  !strcasecmp(pin, cnf->pinadmin))) {
5088  /* Pin correct */
5089  allowretry = 0;
5090  if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin)) {
5091  if (!ast_strlen_zero(cnf->adminopts)) {
5092  char *opts = ast_strdupa(cnf->adminopts);
5093  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
5094  }
5095  } else {
5096  if (!ast_strlen_zero(cnf->useropts)) {
5097  char *opts = ast_strdupa(cnf->useropts);
5098  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
5099  }
5100  }
5101  /* Run the conference */
5102  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n", cnf->confno, cnf->recordingfilename, cnf->recordingformat);
5103  res = conf_run(chan, cnf, &confflags, optargs);
5104  break;
5105  } else {
5106  /* Pin invalid */
5107  if (!ast_streamfile(chan, "conf-invalidpin", ast_channel_language(chan))) {
5108  res = ast_waitstream(chan, AST_DIGIT_ANY);
5109  ast_stopstream(chan);
5110  } else {
5111  ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
5112  break;
5113  }
5114  if (res < 0)
5115  break;
5116  pin[0] = res;
5117  pin[1] = '\0';
5118  res = -1;
5119  if (allowretry)
5120  confno[0] = '\0';
5121  }
5122  } else {
5123  /* failed when getting the pin */
5124  res = -1;
5125  allowretry = 0;
5126  /* see if we need to get rid of the conference */
5127  break;
5128  }
5129 
5130  /* Don't retry pin with a static pin */
5131  if (*the_pin && (always_prompt == 0)) {
5132  break;
5133  }
5134  }
5135  } else {
5136  /* No pin required */
5137  allowretry = 0;
5138 
5139  /* For RealTime conferences without a pin
5140  * should still support loading options
5141  */
5142  if (!ast_strlen_zero(cnf->useropts)) {
5143  char *opts = ast_strdupa(cnf->useropts);
5144  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
5145  }
5146 
5147  /* Run the conference */
5148  res = conf_run(chan, cnf, &confflags, optargs);
5149  }
5150  dispose_conf(cnf);
5151  cnf = NULL;
5152  }
5153  }
5154  } while (allowretry);
5155 
5156  if (cnf)
5157  dispose_conf(cnf);
5158 
5159  return res;
5160 }
struct ast_variable * next
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_conference * find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags64 *confflags)
Definition: app_meetme.c:4688
#define AST_DIGIT_ANY
Definition: file.h:48
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#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
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:857
char * recordingformat
Definition: app_meetme.c:864
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static const struct ast_app_option meetme_opts[128]
Definition: app_meetme.c:800
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8349
const char * useropts
Definition: app_meetme.c:869
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
const char * args
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int rt_schedule
Definition: app_meetme.c:810
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:3177
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2911
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
char pin[MAX_PIN]
Definition: app_meetme.c:865
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: main/config.c:3452
#define LOG_ERROR
Definition: logger.h:285
def info(msg)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
const char * adminopts
Definition: app_meetme.c:870
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
Structure used to handle boolean flags.
Definition: utils.h:199
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
char * strsep(char **str, const char *delims)
#define MAX_CONFNUM
Definition: app_meetme.c:819
#define MAX_SETTINGS
Definition: app_meetme.c:824
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
char pinadmin[MAX_PIN]
Definition: app_meetme.c:866
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
static struct ast_conference * find_conf_realtime(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags64 *confflags, int *too_early, char **optargs)
Definition: app_meetme.c:4500
const char * ast_channel_language(const struct ast_channel *chan)
static unsigned int conf_map[1024]
Definition: app_meetme.c:888
char * recordingfilename
Definition: app_meetme.c:863
#define MAX_PIN
Definition: app_meetme.c:820
static struct test_options options
The MeetMe Conference object.
Definition: app_meetme.c:842
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define CONFIG_FILE_NAME
Definition: app_meetme.c:642
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
#define AST_APP_ARG(name)
Define an application argument.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ conf_flush()

static void conf_flush ( int  fd,
struct ast_channel chan 
)
static

Definition at line 2299 of file app_meetme.c.

References ast_frfree, ast_log, ast_read(), ast_waitfor(), and LOG_WARNING.

Referenced by conf_run().

2300 {
2301  int x;
2302 
2303  /* read any frames that may be waiting on the channel
2304  and throw them away
2305  */
2306  if (chan) {
2307  struct ast_frame *f;
2308 
2309  /* when no frames are available, this will wait
2310  for 1 millisecond maximum
2311  */
2312  while (ast_waitfor(chan, 1) > 0) {
2313  f = ast_read(chan);
2314  if (f)
2315  ast_frfree(f);
2316  else /* channel was hung up or something else happened */
2317  break;
2318  }
2319  }
2320 
2321  /* flush any data sitting in the pseudo channel */
2322  x = DAHDI_FLUSH_ALL;
2323  if (ioctl(fd, DAHDI_FLUSH, &x))
2324  ast_log(LOG_WARNING, "Error flushing channel\n");
2325 
2326 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
#define ast_log
Definition: astobj2.c:42
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
#define ast_frfree(fr)
Data structure associated with a single frame of data.

◆ conf_free()

static int conf_free ( struct ast_conference conf)
static

Remove the conference from the list and free it.

We assume that this was called while holding conflock.

Definition at line 2331 of file app_meetme.c.

References ast_conference::announcelist, ast_conference::announcelist_addition, ast_conference::announcelistlock, ast_conference::announcethread, ast_conference::announcethread_stop, ast_conference::announcethreadlock, ao2_ref, ast_cond_signal, ast_filedelete(), AST_FRAME_BITS, ast_free, ast_frfree, ast_hangup(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_translator_free_path(), ast_conference::chan, ast_conference::fd, item, ast_conference::lchan, ast_conference::listenlock, MEETME_RECORD_ACTIVE, MEETME_RECORD_OFF, MEETME_RECORD_TERMINATE, meetme_stasis_generate_msg(), announce_listitem::namerecloc, NULL, ast_conference::origframe, ast_conference::playlock, ast_conference::recording, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthreadlock, ast_conference::transframe, ast_conference::transpath, ast_conference::usercontainer, and announce_listitem::vmrec.

Referenced by dispose_conf().

2332 {
2333  int x;
2334  struct announce_listitem *item;
2335 
2336  AST_LIST_REMOVE(&confs, conf, list);
2337 
2338  meetme_stasis_generate_msg(conf, NULL, NULL, meetme_end_type(), NULL);
2339 
2340  if (conf->recording == MEETME_RECORD_ACTIVE) {
2343  while (1) {
2344  usleep(1);
2345  AST_LIST_LOCK(&confs);
2346  if (conf->recording == MEETME_RECORD_OFF)
2347  break;
2349  }
2350  }
2351 
2352  for (x = 0; x < AST_FRAME_BITS; x++) {
2353  if (conf->transframe[x])
2354  ast_frfree(conf->transframe[x]);
2355  if (conf->transpath[x])
2357  }
2358  if (conf->announcethread != AST_PTHREADT_NULL) {
2360  conf->announcethread_stop = 1;
2364  pthread_join(conf->announcethread, NULL);
2365 
2366  while ((item = AST_LIST_REMOVE_HEAD(&conf->announcelist, entry))) {
2367  /* If it's a voicemail greeting file we don't want to remove it */
2368  if (!item->vmrec){
2369  ast_filedelete(item->namerecloc, NULL);
2370  }
2371  ao2_ref(item, -1);
2372  }
2374  }
2375 
2376  if (conf->origframe)
2377  ast_frfree(conf->origframe);
2378  ast_hangup(conf->lchan);
2379  ast_hangup(conf->chan);
2380  if (conf->fd >= 0)
2381  close(conf->fd);
2382  if (conf->recordingfilename) {
2383  ast_free(conf->recordingfilename);
2384  }
2385  if (conf->usercontainer) {
2386  ao2_ref(conf->usercontainer, -1);
2387  }
2388  if (conf->recordingformat) {
2389  ast_free(conf->recordingformat);
2390  }
2391  ast_mutex_destroy(&conf->playlock);
2392  ast_mutex_destroy(&conf->listenlock);
2395  ast_free(conf);
2396 
2397  return 0;
2398 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:846
ast_mutex_t playlock
Definition: app_meetme.c:843
#define AST_FRAME_BITS
Definition: app_meetme.c:664
struct ast_frame * origframe
Definition: app_meetme.c:873
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:864
struct ast_conference::@40 announcelist
struct ast_frame * transframe[32]
Definition: app_meetme.c:872
ast_mutex_t listenlock
Definition: app_meetme.c:844
static struct aco_type item
Definition: test_config.c:1463
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
#define ast_cond_signal(cond)
Definition: lock.h:201
static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference, struct ast_channel *chan, struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
Definition: app_meetme.c:1343
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
ast_mutex_t announcelistlock
Definition: app_meetme.c:883
enum recording_state recording
Definition: app_meetme.c:856
char namerecloc[PATH_MAX]
Definition: app_meetme.c:833
pthread_t announcethread
Definition: app_meetme.c:878
#define ast_free(a)
Definition: astmm.h:182
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ao2_container * usercontainer
Definition: app_meetme.c:875
struct ast_trans_pvt * transpath[32]
Definition: app_meetme.c:874
#define ast_frfree(fr)
ast_cond_t announcelist_addition
Definition: app_meetme.c:881
unsigned int announcethread_stop
Definition: app_meetme.c:880
Definition: search.h:40
char * recordingfilename
Definition: app_meetme.c:863
struct ast_channel * lchan
Definition: app_meetme.c:847
#define ast_mutex_destroy(a)
Definition: lock.h:186
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475
#define ast_mutex_unlock(a)
Definition: lock.h:188
ast_mutex_t recordthreadlock
Definition: app_meetme.c:861
ast_mutex_t announcethreadlock
Definition: app_meetme.c:879

◆ conf_play()

static void conf_play ( struct ast_channel chan,
struct ast_conference conf,
enum entrance_sound  sound 
)
static

Definition at line 1526 of file app_meetme.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_name(), ast_check_hangup(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_test_suite_event_notify, careful_write(), ast_conference::confno, enter, ENTER, ast_conference::fd, leave, LEAVE, len(), ast_conference::markedusers, and NULL.

Referenced by conf_run().

1527 {
1528  unsigned char *data;
1529  int len;
1530  int res = -1;
1531 
1532  ast_test_suite_event_notify("CONFPLAY", "Channel: %s\r\n"
1533  "Conference: %s\r\n"
1534  "Marked: %d",
1535  ast_channel_name(chan),
1536  conf->confno,
1537  conf->markedusers);
1538 
1539  if (!ast_check_hangup(chan))
1540  res = ast_autoservice_start(chan);
1541 
1542  AST_LIST_LOCK(&confs);
1543 
1544  switch(sound) {
1545  case ENTER:
1546  data = enter;
1547  len = sizeof(enter);
1548  break;
1549  case LEAVE:
1550  data = leave;
1551  len = sizeof(leave);
1552  break;
1553  default:
1554  data = NULL;
1555  len = 0;
1556  }
1557  if (data) {
1558  careful_write(conf->fd, data, len, 1);
1559  }
1560 
1562 
1563  if (!res)
1564  ast_autoservice_stop(chan);
1565 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
static int careful_write(int fd, unsigned char *data, int len, int block)
Definition: app_meetme.c:1408
static unsigned char leave[]
Definition: leave.h:12
static unsigned char enter[]
Definition: enter.h:12
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const char * ast_channel_name(const struct ast_channel *chan)
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ conf_queue_dtmf()

static void conf_queue_dtmf ( const struct ast_conference conf,
const struct ast_conf_user sender,
struct ast_frame f 
)
static

Definition at line 2400 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_name(), ast_log, ast_write(), ast_conf_user::chan, LOG_WARNING, user, and ast_conference::usercontainer.

Referenced by conf_run().

2402 {
2403  struct ast_conf_user *user;
2404  struct ao2_iterator user_iter;
2405 
2406  user_iter = ao2_iterator_init(conf->usercontainer, 0);
2407  while ((user = ao2_iterator_next(&user_iter))) {
2408  if (user == sender) {
2409  ao2_ref(user, -1);
2410  continue;
2411  }
2412  if (ast_write(user->chan, f) < 0)
2413  ast_log(LOG_WARNING, "Error writing frame to channel %s\n", ast_channel_name(user->chan));
2414  ao2_ref(user, -1);
2415  }
2416  ao2_iterator_destroy(&user_iter);
2417 }
static char user[512]
#define LOG_WARNING
Definition: logger.h:274
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_log
Definition: astobj2.c:42
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
struct ao2_container * usercontainer
Definition: app_meetme.c:875
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * chan
Definition: app_meetme.c:900
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ conf_run()

static int conf_run ( struct ast_channel chan,
struct ast_conference conf,
struct ast_flags64 confflags,
char *  optargs[] 
)
static

Definition at line 3177 of file app_meetme.c.

References volume::actual, ADMINFLAG_HANGUP, ADMINFLAG_KICKME, ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, announce_thread(), ast_conference::announcelist, ast_conference::announcelist_addition, ast_conference::announcelistlock, ast_conference::announcethread, ast_conference::announcethreadlock, announce_listitem::announcetype, ao2_alloc, ao2_callback, ao2_cleanup, ao2_link, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, ast_channel_audiohooks(), ast_channel_context(), ast_channel_fd(), ast_channel_language(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_monitor(), ast_channel_name(), ast_channel_rawwriteformat(), ast_channel_setoption(), ast_channel_tech(), ast_channel_uniqueid(), ast_channel_unlock, ast_check_hangup(), ast_clear_flag64, ast_cond_signal, ast_config_AST_SPOOL_DIR, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, ast_copy_string(), ast_debug, AST_DEVICE_INUSE, AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_DEVSTATE_NOT_CACHABLE, AST_DIGIT_ANY, ast_dsp_free(), ast_dsp_get_threshold_from_settings(), ast_dsp_new(), ast_dsp_silence(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_compatibility_format2bitfield(), ast_format_slin, ast_frame_adjust_volume(), AST_FRAME_BITS, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_func_write(), ast_goto_if_exists(), ast_hangup(), ast_indicate(), ast_json_unref(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_load_realtime(), ast_localtime(), ast_log, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_mkdir(), ast_mktime(), ast_moh_stop(), ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_null_frame, AST_OPTION_TONE_VERIFY, ast_play_and_record(), ast_pthread_create_background, ast_pthread_create_detached_background, AST_PTHREADT_NULL, ast_read(), ast_read_noaudio(), ast_realtime_require_field(), ast_record_review(), ast_request(), ast_safe_sleep(), ast_samp2tv(), ast_say_digits(), ast_say_number(), ast_set_read_format(), ast_set_write_format(), ast_stopstream(), ast_strdup, ast_strdupa, ast_streamfile(), ast_strftime(), ast_strlen_zero, ast_strptime(), ast_test_flag64, ast_test_suite_event_notify, ast_translate(), ast_translator_build_path(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_update_realtime(), ast_variables_destroy(), ast_verb, ast_verbose(), ast_waitfor_nandfds(), ast_waitstream(), ast_write(), audio_buffers, ast_conference::bookid, buf, c, can_write(), careful_write(), ast_conference::chan, ast_conf_user::chan, conf_flush(), CONF_HASJOIN, CONF_HASLEFT, conf_play(), conf_queue_dtmf(), CONF_SIZE, conf_start_moh(), announce_listitem::confchan, CONFFLAG_ADMIN, CONFFLAG_AGI, CONFFLAG_ANNOUNCEUSERCOUNT, CONFFLAG_DONT_DENOISE, CONFFLAG_DURATION_LIMIT, CONFFLAG_DURATION_STOP, CONFFLAG_EXIT_CONTEXT, CONFFLAG_INTROMSG, CONFFLAG_INTROUSER, CONFFLAG_INTROUSER_VMREC, CONFFLAG_INTROUSERNOREVIEW, CONFFLAG_KEYEXIT, CONFFLAG_KICK_CONTINUE, CONFFLAG_KILL_LAST_MAN_STANDING, CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_MOH, CONFFLAG_MONITOR, CONFFLAG_MONITORTALKER, CONFFLAG_NO_AUDIO_UNTIL_UP, CONFFLAG_NOONLYPERSON, CONFFLAG_OPTIMIZETALKER, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_RECORDCONF, CONFFLAG_SLA_STATION, CONFFLAG_STARMENU, CONFFLAG_STARTMUTED, CONFFLAG_TALKER, CONFFLAG_WAITMARKED, ast_conference::confno, announce_listitem::confusers, context, ast_conf_user::dahdichannel, ast_conference::dahdiconf, ast_frame::data, ast_frame::datalen, DATE_FORMAT, volume::desired, dtmfstr, ast_conf_user::end_sound, ast_conference::endalert, ast_conference::endtime, ENTER, errno, exitcontext, ast_frame_subclass::format, ast_frame::frametype, ast_conference::gmuted, ast_frame_subclass::integer, ast_conference::isdynamic, item, ast_conf_user::jointime, ast_conf_user::kicktime, announce_listitem::language, ast_conference::lchan, LEAVE, ast_conf_user::listen, ast_conference::listenlock, ast_conference::locked, LOG_WARNING, mailbox, ast_conference::markedusers, ast_conference::maxusers, MEETME_DELAYDETECTENDTALK, MEETME_DELAYDETECTTALK, meetme_menu(), meetme_stasis_generate_msg(), MENU_ADMIN, MENU_DISABLED, MENU_NORMAL, ast_variable::name, announce_listitem::namerecloc, ast_conf_user::namerecloc, ast_variable::next, NULL, OBJ_NODATA, ast_frame::offset, OPT_ARG_DURATION_LIMIT, OPT_ARG_DURATION_STOP, OPT_ARG_EXITKEYS, OPT_ARG_INTROMSG, OPT_ARG_INTROUSER_VMREC, OPT_ARG_MOH_CLASS, OPT_ARG_WAITMARKED, ast_conference::origframe, parse(), PATH_MAX, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_exec(), pbx_findapp(), ast_conf_user::play_warning, ast_conference::playlock, ast_frame::ptr, RAII_VAR, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthread, ast_conference::recordthreadlock, reset_volumes(), RQ_UINTEGER1, RQ_UINTEGER2, RQ_UINTEGER3, RQ_UINTEGER4, ast_frame::samples, set_talk_volume(), set_user_talking(), SLA_EVENT_HOLD, sla_queue_event_conf(), ast_conf_user::start_time, status_to_json(), strsep(), ast_frame::subclass, ast_conf_user::talk, ast_conf_user::talking, THRESHOLD_SILENCE, ast_conf_user::timelimit, timeout, ast_conference::transframe, ast_conference::transpath, type, ast_conference::uniqueid, user_max_cmp(), ast_conf_user::user_no, user_set_hangup_cb(), ast_conference::usercontainer, ast_conf_user::userflags, ast_conference::users, ast_variable::value, var, announce_listitem::vmrec, ast_conf_user::warning_freq, and ast_conf_user::warning_sound.

Referenced by conf_exec(), dial_trunk(), run_station(), sla_station_exec(), and sla_trunk_exec().

3178 {
3179  struct ast_conf_user *user = NULL;
3180  int fd;
3181  struct dahdi_confinfo dahdic, dahdic_empty;
3182  struct ast_frame *f;
3183  struct ast_channel *c;
3184  struct ast_frame fr;
3185  int outfd;
3186  int ms;
3187  int nfds;
3188  int res;
3189  int retrydahdi;
3190  int origfd;
3191  int musiconhold = 0, mohtempstopped = 0;
3192  int firstpass = 0;
3193  int lastmarked = 0;
3194  int currentmarked = 0;
3195  int ret = -1;
3196  int x;
3197  enum menu_modes menu_mode = MENU_DISABLED;
3198  int talkreq_manager = 0;
3199  int using_pseudo = 0;
3200  int duration = 20;
3201  int sent_event = 0;
3202  int checked = 0;
3203  int announcement_played = 0;
3204  struct timeval now;
3205  struct ast_dsp *dsp = NULL;
3206  struct ast_app *agi_app;
3207  char *agifile;
3208  const char *agifiledefault = "conf-background.agi", *tmpvar;
3209  char meetmesecs[30] = "";
3210  char exitcontext[AST_MAX_CONTEXT] = "";
3211  char recordingtmp[AST_MAX_EXTENSION * 2] = "";
3212  char members[10] = "";
3213  int dtmf = 0, opt_waitmarked_timeout = 0;
3214  time_t timeout = 0;
3215  struct dahdi_bufferinfo bi;
3216  char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
3217  char *buf = __buf + AST_FRIENDLY_OFFSET;
3218  char *exitkeys = NULL;
3219  unsigned int calldurationlimit = 0;
3220  long timelimit = 0;
3221  long play_warning = 0;
3222  long warning_freq = 0;
3223  const char *warning_sound = NULL;
3224  const char *end_sound = NULL;
3225  char *parse;
3226  long time_left_ms = 0;
3227  struct timeval nexteventts = { 0, };
3228  int to;
3229  int setusercount = 0;
3230  int confsilence = 0, totalsilence = 0;
3231  char *mailbox, *context;
3233 
3234  if (!cap_slin) {
3235  goto conf_run_cleanup;
3236  }
3237  ast_format_cap_append(cap_slin, ast_format_slin, 0);
3238 
3239  if (!(user = ao2_alloc(sizeof(*user), NULL))) {
3240  goto conf_run_cleanup;
3241  }
3242 
3243  /* Possible timeout waiting for marked user */
3244  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) &&
3245  !ast_strlen_zero(optargs[OPT_ARG_WAITMARKED]) &&
3246  (sscanf(optargs[OPT_ARG_WAITMARKED], "%30d", &opt_waitmarked_timeout) == 1) &&
3247  (opt_waitmarked_timeout > 0)) {
3248  timeout = time(NULL) + opt_waitmarked_timeout;
3249  }
3250 
3252  calldurationlimit = atoi(optargs[OPT_ARG_DURATION_STOP]);
3253  ast_verb(3, "Setting call duration limit to %u seconds.\n", calldurationlimit);
3254  }
3255 
3257  char *limit_str, *warning_str, *warnfreq_str;
3258  const char *var;
3259 
3260  parse = optargs[OPT_ARG_DURATION_LIMIT];
3261  limit_str = strsep(&parse, ":");
3262  warning_str = strsep(&parse, ":");
3263  warnfreq_str = parse;
3264 
3265  timelimit = atol(limit_str);
3266  if (warning_str)
3267  play_warning = atol(warning_str);
3268  if (warnfreq_str)
3269  warning_freq = atol(warnfreq_str);
3270 
3271  if (!timelimit) {
3272  timelimit = play_warning = warning_freq = 0;
3273  warning_sound = NULL;
3274  } else if (play_warning > timelimit) {
3275  if (!warning_freq) {
3276  play_warning = 0;
3277  } else {
3278  while (play_warning > timelimit)
3279  play_warning -= warning_freq;
3280  if (play_warning < 1)
3281  play_warning = warning_freq = 0;
3282  }
3283  }
3284 
3285  ast_verb(3, "Setting conference duration limit to: %ldms.\n", timelimit);
3286  if (play_warning) {
3287  ast_verb(3, "Setting warning time to %ldms from the conference duration limit.\n", play_warning);
3288  }
3289  if (warning_freq) {
3290  ast_verb(3, "Setting warning frequency to %ldms.\n", warning_freq);
3291  }
3292 
3293  ast_channel_lock(chan);
3294  if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_WARNING_FILE"))) {
3295  var = ast_strdupa(var);
3296  }
3297  ast_channel_unlock(chan);
3298 
3299  warning_sound = var ? var : "timeleft";
3300 
3301  ast_channel_lock(chan);
3302  if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_TIMEOUT_FILE"))) {
3303  var = ast_strdupa(var);
3304  }
3305  ast_channel_unlock(chan);
3306 
3307  end_sound = var ? var : NULL;
3308 
3309  /* undo effect of S(x) in case they are both used */
3310  calldurationlimit = 0;
3311  /* more efficient do it like S(x) does since no advanced opts */
3312  if (!play_warning && !end_sound && timelimit) {
3313  calldurationlimit = timelimit / 1000;
3314  timelimit = play_warning = warning_freq = 0;
3315  } else {
3316  ast_debug(2, "Limit Data for this call:\n");
3317  ast_debug(2, "- timelimit = %ld\n", timelimit);
3318  ast_debug(2, "- play_warning = %ld\n", play_warning);
3319  ast_debug(2, "- warning_freq = %ld\n", warning_freq);
3320  ast_debug(2, "- warning_sound = %s\n", warning_sound ? warning_sound : "UNDEF");
3321  ast_debug(2, "- end_sound = %s\n", end_sound ? end_sound : "UNDEF");
3322  }
3323  }
3324 
3325  /* Get exit keys */
3326  if (ast_test_flag64(confflags, CONFFLAG_KEYEXIT)) {
3327  if (!ast_strlen_zero(optargs[OPT_ARG_EXITKEYS]))
3328  exitkeys = ast_strdupa(optargs[OPT_ARG_EXITKEYS]);
3329  else
3330  exitkeys = ast_strdupa("#"); /* Default */
3331  }
3332 
3333  if (ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
3334  if (!conf->recordingfilename) {
3335  const char *var;
3336  ast_channel_lock(chan);
3337  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
3338  conf->recordingfilename = ast_strdup(var);
3339  }
3340  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
3341  conf->recordingformat = ast_strdup(var);
3342  }
3343  ast_channel_unlock(chan);
3344  if (!conf->recordingfilename) {
3345  snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, ast_channel_uniqueid(chan));
3346  conf->recordingfilename = ast_strdup(recordingtmp);
3347  }
3348  if (!conf->recordingformat) {
3349  conf->recordingformat = ast_strdup("wav");
3350  }
3351  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
3352  conf->confno, conf->recordingfilename, conf->recordingformat);
3353  }
3354  }
3355 
3357  if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) &&
3358  ((conf->lchan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL)))) {
3361  dahdic.chan = 0;
3362  dahdic.confno = conf->dahdiconf;
3363  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
3364  if (ioctl(ast_channel_fd(conf->lchan, 0), DAHDI_SETCONF, &dahdic)) {
3365  ast_log(LOG_WARNING, "Error starting listen channel\n");
3366  ast_hangup(conf->lchan);
3367  conf->lchan = NULL;
3368  } else {
3370  }
3371  }
3373 
3375  if ((conf->announcethread == AST_PTHREADT_NULL) && !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
3380  }
3382 
3383  time(&user->jointime);
3384 
3385  user->timelimit = timelimit;
3386  user->play_warning = play_warning;
3387  user->warning_freq = warning_freq;
3388  user->warning_sound = warning_sound;
3389  user->end_sound = end_sound;
3390 
3391  if (calldurationlimit > 0) {
3392  time(&user->kicktime);
3393  user->kicktime = user->kicktime + calldurationlimit;
3394  }
3395 
3396  if (ast_tvzero(user->start_time))
3397  user->start_time = ast_tvnow();
3398  time_left_ms = user->timelimit;
3399 
3400  if (user->timelimit) {
3401  nexteventts = ast_tvadd(user->start_time, ast_samp2tv(user->timelimit, 1000));
3402  nexteventts = ast_tvsub(nexteventts, ast_samp2tv(user->play_warning, 1000));
3403  }
3404 
3405  if (conf->locked && (!ast_test_flag64(confflags, CONFFLAG_ADMIN))) {
3406  /* Sorry, but this conference is locked! */
3407  if (!ast_streamfile(chan, "conf-locked", ast_channel_language(chan)))
3408  ast_waitstream(chan, "");
3409  goto outrun;
3410  }
3411 
3412  ast_mutex_lock(&conf->playlock);
3413 
3414  if (rt_schedule && conf->maxusers) {
3415  if (conf->users >= conf->maxusers) {
3416  /* Sorry, but this confernce has reached the participant limit! */
3417  ast_mutex_unlock(&conf->playlock);
3418  if (!ast_streamfile(chan, "conf-full", ast_channel_language(chan)))
3419  ast_waitstream(chan, "");
3420  goto outrun;
3421  }
3422  }
3423 
3424  ao2_lock(conf->usercontainer);
3426  user->user_no++;
3427  ao2_link(conf->usercontainer, user);
3428  ao2_unlock(conf->usercontainer);
3429 
3430  user->chan = chan;
3431  user->userflags = *confflags;
3433  if (!ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
3434  user->adminflags |= (conf->gmuted) ? ADMINFLAG_MUTED : 0;
3435  }
3436  user->talking = -1;
3437 
3438  ast_mutex_unlock(&conf->playlock);
3439 
3441  char destdir[PATH_MAX];
3442 
3443  snprintf(destdir, sizeof(destdir), "%s/meetme", ast_config_AST_SPOOL_DIR);
3444 
3445  if (ast_mkdir(destdir, 0777) != 0) {
3446  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
3447  goto outrun;
3448  }
3449 
3450  if (ast_test_flag64(confflags, CONFFLAG_INTROUSER_VMREC)){
3451  context = ast_strdupa(optargs[OPT_ARG_INTROUSER_VMREC]);
3452  mailbox = strsep(&context, "@");
3453 
3454  if (ast_strlen_zero(mailbox)) {
3455  /* invalid input, clear the v flag*/
3457  ast_log(LOG_WARNING,"You must specify a mailbox in the v() option\n");
3458  } else {
3459  if (ast_strlen_zero(context)) {
3460  context = "default";
3461  }
3462  /* if there is no mailbox we don't need to do this logic */
3463  snprintf(user->namerecloc, sizeof(user->namerecloc),
3464  "%s/voicemail/%s/%s/greet",ast_config_AST_SPOOL_DIR,context,mailbox);
3465 
3466  /* if the greeting doesn't exist then use the temp file method instead, clear flag v */
3467  if (!ast_fileexists(user->namerecloc, NULL, NULL)){
3468  snprintf(user->namerecloc, sizeof(user->namerecloc),
3469  "%s/meetme-username-%s-%d", destdir,
3470  conf->confno, user->user_no);
3472  }
3473  }
3474  } else {
3475  snprintf(user->namerecloc, sizeof(user->namerecloc),
3476  "%s/meetme-username-%s-%d", destdir,
3477  conf->confno, user->user_no);
3478  }
3479 
3480  res = 0;
3482  res = ast_play_and_record(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE), 0, NULL);
3483  else if (ast_test_flag64(confflags, CONFFLAG_INTROUSER) && !ast_fileexists(user->namerecloc, NULL, NULL))
3484  res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL);
3485  if (res == -1)
3486  goto outrun;
3487 
3488  }
3489 
3490  ast_mutex_lock(&conf->playlock);
3491 
3492  if (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER))
3493  conf->markedusers++;
3494  conf->users++;
3495  if (rt_log_members) {
3496  /* Update table */
3497  snprintf(members, sizeof(members), "%d", conf->users);
3498  ast_realtime_require_field("meetme",
3499  "confno", strlen(conf->confno) > 7 ? RQ_UINTEGER4 : strlen(conf->confno) > 4 ? RQ_UINTEGER3 : RQ_UINTEGER2, strlen(conf->confno),
3500  "members", RQ_UINTEGER1, strlen(members),
3501  NULL);
3502  ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
3503  }
3504  setusercount = 1;
3505 
3506  /* This device changed state now - if this is the first user */
3507  if (conf->users == 1)
3509 
3510  ast_mutex_unlock(&conf->playlock);
3511 
3512  /* return the unique ID of the conference */
3513  pbx_builtin_setvar_helper(chan, "MEETMEUNIQUEID", conf->uniqueid);
3514 
3515  if (ast_test_flag64(confflags, CONFFLAG_EXIT_CONTEXT)) {
3516  ast_channel_lock(chan);
3517  if ((tmpvar = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) {
3518  ast_copy_string(exitcontext, tmpvar, sizeof(exitcontext));
3519  } else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
3520  ast_copy_string(exitcontext, ast_channel_macrocontext(chan), sizeof(exitcontext));
3521  } else {
3522  ast_copy_string(exitcontext, ast_channel_context(chan), sizeof(exitcontext));
3523  }
3524  ast_channel_unlock(chan);
3525  }
3526 
3527  /* Play an arbitrary intro message */
3528  if (ast_test_flag64(confflags, CONFFLAG_INTROMSG) &&
3529  !ast_strlen_zero(optargs[OPT_ARG_INTROMSG])) {
3530  if (!ast_streamfile(chan, optargs[OPT_ARG_INTROMSG], ast_channel_language(chan))) {
3531  ast_waitstream(chan, "");
3532  }
3533  }
3534 
3535  if (!ast_test_flag64(confflags, (CONFFLAG_QUIET | CONFFLAG_NOONLYPERSON))) {
3536  if (conf->users == 1 && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED))
3537  if (!ast_streamfile(chan, "conf-onlyperson", ast_channel_language(chan)))
3538  ast_waitstream(chan, "");
3539  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) && conf->markedusers == 0)
3540  if (!ast_streamfile(chan, "conf-waitforleader", ast_channel_language(chan)))
3541  ast_waitstream(chan, "");
3542  }
3543 
3544  if (ast_test_flag64(confflags, CONFFLAG_ANNOUNCEUSERCOUNT) && conf->users > 1) {
3545  int keepplaying = 1;
3546 
3547  if (conf->users == 2) {
3548  if (!ast_streamfile(chan, "conf-onlyone", ast_channel_language(chan))) {
3549  res = ast_waitstream(chan, AST_DIGIT_ANY);
3550  ast_stopstream(chan);
3551  if (res > 0)
3552  keepplaying = 0;
3553  else if (res == -1)
3554  goto outrun;
3555  }
3556  } else {
3557  if (!ast_streamfile(chan, "conf-thereare", ast_channel_language(chan))) {
3558  res = ast_waitstream(chan, AST_DIGIT_ANY);
3559  ast_stopstream(chan);
3560  if (res > 0)
3561  keepplaying = 0;
3562  else if (res == -1)
3563  goto outrun;
3564  }
3565  if (keepplaying) {
3566  res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
3567  if (res > 0)
3568  keepplaying = 0;
3569  else if (res == -1)
3570  goto outrun;
3571  }
3572  if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", ast_channel_language(chan))) {
3573  res = ast_waitstream(chan, AST_DIGIT_ANY);
3574  ast_stopstream(chan);
3575  if (res > 0)
3576  keepplaying = 0;
3577  else if (res == -1)
3578  goto outrun;
3579  }
3580  }
3581  }
3582 
3583  if (!ast_test_flag64(confflags, CONFFLAG_NO_AUDIO_UNTIL_UP)) {
3584  /* We're leaving this alone until the state gets changed to up */
3585  ast_indicate(chan, -1);
3586  }
3587 
3588  if (ast_set_write_format(chan, ast_format_slin) < 0) {
3589  ast_log(LOG_WARNING, "Unable to set '%s' to write linear mode\n", ast_channel_name(chan));
3590  goto outrun;
3591  }
3592 
3593  if (ast_set_read_format(chan, ast_format_slin) < 0) {
3594  ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", ast_channel_name(chan));
3595  goto outrun;
3596  }
3597 
3598  /* Reduce background noise from each participant */
3599  if (!ast_test_flag64(confflags, CONFFLAG_DONT_DENOISE)) {
3600  ast_func_write(chan, "DENOISE(rx)", "on");
3601  }
3602 
3603  retrydahdi = (strcasecmp(ast_channel_tech(chan)->type, "DAHDI") || (ast_channel_audiohooks(chan) || ast_channel_monitor(chan)) ? 1 : 0);
3604  user->dahdichannel = !retrydahdi;
3605 
3606  dahdiretry:
3607  origfd = ast_channel_fd(chan, 0);
3608  if (retrydahdi) {
3609  /* open pseudo in non-blocking mode */
3610  fd = open("/dev/dahdi/pseudo", O_RDWR | O_NONBLOCK);
3611  if (fd < 0) {
3612  ast_log(LOG_WARNING, "Unable to open DAHDI pseudo channel: %s\n", strerror(errno));
3613  goto outrun;
3614  }
3615  using_pseudo = 1;
3616  /* Setup buffering information */
3617  memset(&bi, 0, sizeof(bi));
3618  bi.bufsize = CONF_SIZE / 2;
3619  bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
3620  bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
3621  bi.numbufs = audio_buffers;
3622  if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) {
3623  ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
3624  close(fd);
3625  goto outrun;
3626  }
3627  x = 1;
3628  if (ioctl(fd, DAHDI_SETLINEAR, &x)) {
3629  ast_log(LOG_WARNING, "Unable to set linear mode: %s\n", strerror(errno));
3630  close(fd);
3631  goto outrun;
3632  }
3633  nfds = 1;
3634  } else {
3635  /* XXX Make sure we're not running on a pseudo channel XXX */
3636  fd = ast_channel_fd(chan, 0);
3637  nfds = 0;
3638  }
3639  memset(&dahdic, 0, sizeof(dahdic));
3640  memset(&dahdic_empty, 0, sizeof(dahdic_empty));
3641  /* Check to see if we're in a conference... */
3642  dahdic.chan = 0;
3643  if (ioctl(fd, DAHDI_GETCONF, &dahdic)) {
3644  ast_log(LOG_WARNING, "Error getting conference\n");
3645  close(fd);
3646  goto outrun;
3647  }
3648  if (dahdic.confmode) {
3649  /* Whoa, already in a conference... Retry... */
3650  if (!retrydahdi) {
3651  ast_debug(1, "DAHDI channel is in a conference already, retrying with pseudo\n");
3652  retrydahdi = 1;
3653  goto dahdiretry;
3654  }
3655  }
3656  memset(&dahdic, 0, sizeof(dahdic));
3657  /* Add us to the conference */
3658  dahdic.chan = 0;
3659  dahdic.confno = conf->dahdiconf;
3660 
3661  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && (ast_test_flag64(confflags, CONFFLAG_INTROUSER) ||
3663  struct announce_listitem *item;
3664  if (!(item = ao2_alloc(sizeof(*item), NULL)))
3665  goto outrun;
3666  ast_copy_string(item->namerecloc, user->namerecloc, sizeof(item->namerecloc));
3667  ast_copy_string(item->language, ast_channel_language(chan), sizeof(item->language));
3668  item->confchan = conf->chan;
3669  item->confusers = conf->users;
3670  if (ast_test_flag64(confflags, CONFFLAG_INTROUSER_VMREC)){
3671  item->vmrec = 1;
3672  }
3673  item->announcetype = CONF_HASJOIN;
3675  ao2_ref(item, +1); /* add one more so we can determine when announce_thread is done playing it */
3676  AST_LIST_INSERT_TAIL(&conf->announcelist, item, entry);
3679 
3680  while (!ast_check_hangup(conf->chan) && ao2_ref(item, 0) == 2 && !ast_safe_sleep(chan, 1000)) {
3681  ;
3682  }
3683  ao2_ref(item, -1);
3684  }
3685 
3686  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) && !conf->markedusers)
3687  dahdic.confmode = DAHDI_CONF_CONF;
3688  else if (ast_test_flag64(confflags, CONFFLAG_MONITOR))
3689  dahdic.confmode = DAHDI_CONF_CONFMON | DAHDI_CONF_LISTENER;
3690  else if (ast_test_flag64(confflags, CONFFLAG_TALKER))
3691  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
3692  else
3693  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
3694 
3695  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3696  ast_log(LOG_WARNING, "Error setting conference\n");
3697  close(fd);
3698  goto outrun;
3699  }
3700  ast_debug(1, "Placed channel %s in DAHDI conf %d\n", ast_channel_name(chan), conf->dahdiconf);
3701 
3702  if (!sent_event) {
3703  meetme_stasis_generate_msg(conf, chan, user, meetme_join_type(), NULL);
3704  sent_event = 1;
3705  }
3706 
3707  if (!firstpass && !ast_test_flag64(confflags, CONFFLAG_MONITOR) &&
3708  !ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
3709  firstpass = 1;
3710  if (!ast_test_flag64(confflags, CONFFLAG_QUIET))
3711  if (!ast_test_flag64(confflags, CONFFLAG_WAITMARKED) || (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER) &&
3712  (conf->markedusers >= 1))) {
3713  conf_play(chan, conf, ENTER);
3714  }
3715  }
3716 
3717  conf_flush(fd, chan);
3718 
3719  if (dsp)
3720  ast_dsp_free(dsp);
3721 
3722  if (!(dsp = ast_dsp_new())) {
3723  ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
3724  res = -1;
3725  }
3726 
3727  if (ast_test_flag64(confflags, CONFFLAG_AGI)) {
3728  /* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND)
3729  or use default filename of conf-background.agi */
3730 
3731  ast_channel_lock(chan);
3732  if ((tmpvar = pbx_builtin_getvar_helper(chan, "MEETME_AGI_BACKGROUND"))) {
3733  agifile = ast_strdupa(tmpvar);
3734  } else {
3735  agifile = ast_strdupa(agifiledefault);
3736  }
3737  ast_channel_unlock(chan);
3738 
3739  if (user->dahdichannel) {
3740  /* Set CONFMUTE mode on DAHDI channel to mute DTMF tones */
3741  x = 1;
3742  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3743  }
3744  /* Find a pointer to the agi app and execute the script */
3745  agi_app = pbx_findapp("agi");
3746  if (agi_app) {
3747  ret = pbx_exec(chan, agi_app, agifile);
3748  } else {
3749  ast_log(LOG_WARNING, "Could not find application (agi)\n");
3750  ret = -2;
3751  }
3752  if (user->dahdichannel) {
3753  /* Remove CONFMUTE mode on DAHDI channel */
3754  x = 0;
3755  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3756  }
3757  } else {
3758  int lastusers = conf->users;
3759  if (user->dahdichannel && ast_test_flag64(confflags, CONFFLAG_STARMENU)) {
3760  /* Set CONFMUTE mode on DAHDI channel to mute DTMF tones when the menu is enabled */
3761  x = 1;
3762  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3763  }
3764 
3765  for (;;) {
3766  int menu_was_active = 0;
3767 
3768  outfd = -1;
3769  ms = -1;
3770  now = ast_tvnow();
3771 
3772  if (rt_schedule && conf->endtime) {
3773  char currenttime[32];
3774  long localendtime = 0;
3775  int extended = 0;
3776  struct ast_tm tm;
3777  struct ast_variable *var, *origvar;
3778  struct timeval tmp;
3779 
3780  if (now.tv_sec % 60 == 0) {
3781  if (!checked) {
3782  ast_localtime(&now, &tm, NULL);
3783  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
3784  var = origvar = ast_load_realtime("meetme", "confno",
3785  conf->confno, "starttime <=", currenttime,
3786  "endtime >=", currenttime, NULL);
3787 
3788  for ( ; var; var = var->next) {
3789  if (!strcasecmp(var->name, "endtime")) {
3790  struct ast_tm endtime_tm;
3791  ast_strptime(var->value, "%Y-%m-%d %H:%M:%S", &endtime_tm);
3792  tmp = ast_mktime(&endtime_tm, NULL);
3793  localendtime = tmp.tv_sec;
3794  }
3795  }
3796  ast_variables_destroy(origvar);
3797 
3798  /* A conference can be extended from the
3799  Admin/User menu or by an external source */
3800  if (localendtime > conf->endtime){
3801  conf->endtime = localendtime;
3802  extended = 1;
3803  }
3804 
3805  if (conf->endtime && (now.tv_sec >= conf->endtime)) {
3806  ast_verbose("Quitting time...\n");
3807  goto outrun;
3808  }
3809 
3810  if (!announcement_played && conf->endalert) {
3811  if (now.tv_sec + conf->endalert >= conf->endtime) {
3812  if (!ast_streamfile(chan, "conf-will-end-in", ast_channel_language(chan)))
3813  ast_waitstream(chan, "");
3814  ast_say_digits(chan, (conf->endtime - now.tv_sec) / 60, "", ast_channel_language(chan));
3815  if (!ast_streamfile(chan, "minutes", ast_channel_language(chan)))
3816  ast_waitstream(chan, "");
3817  if (musiconhold) {
3818  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3819  }
3820  announcement_played = 1;
3821  }
3822  }
3823 
3824  if (extended) {
3825  announcement_played = 0;
3826  }
3827 
3828  checked = 1;
3829  }
3830  } else {
3831  checked = 0;
3832  }
3833  }
3834 
3835  if (user->kicktime && (user->kicktime <= now.tv_sec)) {
3836  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3837  ret = 0;
3838  } else {
3839  ret = -1;
3840  }
3841  break;
3842  }
3843 
3844  to = -1;
3845  if (user->timelimit) {
3846  int minutes = 0, seconds = 0, remain = 0;
3847 
3848  to = ast_tvdiff_ms(nexteventts, now);
3849  if (to < 0) {
3850  to = 0;
3851  }
3852  time_left_ms = user->timelimit - ast_tvdiff_ms(now, user->start_time);
3853  if (time_left_ms < to) {
3854  to = time_left_ms;
3855  }
3856 
3857  if (time_left_ms <= 0) {
3858  if (user->end_sound) {
3859  res = ast_streamfile(chan, user->end_sound, ast_channel_language(chan));
3860  res = ast_waitstream(chan, "");
3861  }
3862  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3863  ret = 0;
3864  } else {
3865  ret = -1;
3866  }
3867  break;
3868  }
3869 
3870  if (!to) {
3871  if (time_left_ms >= 5000) {
3872 
3873  remain = (time_left_ms + 500) / 1000;
3874  if (remain / 60 >= 1) {
3875  minutes = remain / 60;
3876  seconds = remain % 60;
3877  } else {
3878  seconds = remain;
3879  }
3880 
3881  /* force the time left to round up if appropriate */
3882  if (user->warning_sound && user->play_warning) {
3883  if (!strcmp(user->warning_sound, "timeleft")) {
3884 
3885  res = ast_streamfile(chan, "vm-youhave", ast_channel_language(chan));
3886  res = ast_waitstream(chan, "");
3887  if (minutes) {
3888  res = ast_say_number(chan, minutes, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
3889  res = ast_streamfile(chan, "queue-minutes", ast_channel_language(chan));
3890  res = ast_waitstream(chan, "");
3891  }
3892  if (seconds) {
3893  res = ast_say_number(chan, seconds, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
3894  res = ast_streamfile(chan, "queue-seconds", ast_channel_language(chan));
3895  res = ast_waitstream(chan, "");
3896  }
3897  } else {
3898  res = ast_streamfile(chan, user->warning_sound, ast_channel_language(chan));
3899  res = ast_waitstream(chan, "");
3900  }
3901  if (musiconhold) {
3902  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3903  }
3904  }
3905  }
3906  if (user->warning_freq) {
3907  nexteventts = ast_tvadd(nexteventts, ast_samp2tv(user->warning_freq, 1000));
3908  } else {
3909  nexteventts = ast_tvadd(user->start_time, ast_samp2tv(user->timelimit, 1000));
3910  }
3911  }
3912  }
3913 
3914  now = ast_tvnow();
3915  if (timeout && now.tv_sec >= timeout) {
3916  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3917  ret = 0;
3918  } else {
3919  ret = -1;
3920  }
3921  break;
3922  }
3923 
3924  /* if we have just exited from the menu, and the user had a channel-driver
3925  volume adjustment, restore it
3926  */
3927  if (!menu_mode && menu_was_active && user->listen.desired && !user->listen.actual) {
3928  set_talk_volume(user, user->listen.desired);
3929  }
3930 
3931  menu_was_active = menu_mode;
3932 
3933  currentmarked = conf->markedusers;
3934  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
3935  ast_test_flag64(confflags, CONFFLAG_MARKEDUSER) &&
3936  ast_test_flag64(confflags, CONFFLAG_WAITMARKED) &&
3937  lastmarked == 0) {
3938  if (currentmarked == 1 && conf->users > 1) {
3939  ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
3940  if (conf->users - 1 == 1) {
3941  if (!ast_streamfile(chan, "conf-userwilljoin", ast_channel_language(chan))) {
3942  ast_waitstream(chan, "");
3943  }
3944  } else {
3945  if (!ast_streamfile(chan, "conf-userswilljoin", ast_channel_language(chan))) {
3946  ast_waitstream(chan, "");
3947  }
3948  }
3949  }
3950  if (conf->users == 1 && !ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
3951  if (!ast_streamfile(chan, "conf-onlyperson", ast_channel_language(chan))) {
3952  ast_waitstream(chan, "");
3953  }
3954  }
3955  }
3956 
3957  /* Update the struct with the actual confflags */
3958  user->userflags = *confflags;
3959 
3960  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED)) {
3961  if (currentmarked == 0) {
3962  if (lastmarked != 0) {
3963  if (!ast_test_flag64(confflags, CONFFLAG_QUIET)) {
3964  if (!ast_streamfile(chan, "conf-leaderhasleft", ast_channel_language(chan))) {
3965  ast_waitstream(chan, "");
3966  }
3967  }
3968  if (ast_test_flag64(confflags, CONFFLAG_MARKEDEXIT)) {
3969  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3970  ret = 0;
3971  }
3972  break;
3973  } else {
3974  dahdic.confmode = DAHDI_CONF_CONF;
3975  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3976  ast_log(LOG_WARNING, "Error setting conference\n");
3977  close(fd);
3978  goto outrun;
3979  }
3980  }
3981  }
3982  if (!musiconhold && (ast_test_flag64(confflags, CONFFLAG_MOH))) {
3983  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3984  musiconhold = 1;
3985  }
3986  } else if (currentmarked >= 1 && lastmarked == 0) {
3987  /* Marked user entered, so cancel timeout */
3988  timeout = 0;
3989  if (ast_test_flag64(confflags, CONFFLAG_MONITOR)) {
3990  dahdic.confmode = DAHDI_CONF_CONFMON | DAHDI_CONF_LISTENER;
3991  } else if (ast_test_flag64(confflags, CONFFLAG_TALKER)) {
3992  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
3993  } else {
3994  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
3995  }
3996  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3997  ast_log(LOG_WARNING, "Error setting conference\n");
3998  close(fd);
3999  goto outrun;
4000  }
4001  if (musiconhold && (ast_test_flag64(confflags, CONFFLAG_MOH))) {
4002  ast_moh_stop(chan);
4003  musiconhold = 0;
4004  }
4005  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4006  !ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
4007  if (!ast_streamfile(chan, "conf-placeintoconf", ast_channel_language(chan))) {
4008  ast_waitstream(chan, "");
4009  }
4010  conf_play(chan, conf, ENTER);
4011  }
4012  }
4013  }
4014 
4015  /* trying to add moh for single person conf */
4016  if (ast_test_flag64(confflags, CONFFLAG_MOH) && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)) {
4017  if (conf->users == 1) {
4018  if (!musiconhold) {
4019  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
4020  musiconhold = 1;
4021  }
4022  } else {
4023  if (musiconhold) {
4024  ast_moh_stop(chan);
4025  musiconhold = 0;
4026  }
4027  }
4028  }
4029 
4030  /* Leave if the last marked user left */
4031  if (currentmarked == 0 && lastmarked != 0 && ast_test_flag64(confflags, CONFFLAG_MARKEDEXIT)) {
4032  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
4033  ret = 0;
4034  } else {
4035  ret = -1;
4036  }
4037  break;
4038  }
4039 
4040  /* Throw a TestEvent if a user exit did not cause this user to leave the conference */
4041  if (conf->users != lastusers) {
4042  if (conf->users < lastusers) {
4043  ast_test_suite_event_notify("NOEXIT", "Message: CONFFLAG_MARKEDEXIT\r\nLastUsers: %d\r\nUsers: %d", lastusers, conf->users);
4044  }
4045  lastusers = conf->users;
4046  }
4047 
4048  /* Check if my modes have changed */
4049 
4050  /* If I should be muted but am still talker, mute me */
4051  if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && (dahdic.confmode & DAHDI_CONF_TALKER)) {
4052  RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
4053  dahdic.confmode ^= DAHDI_CONF_TALKER;
4054  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
4055  ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
4056  ret = -1;
4057  break;
4058  }
4059 
4060  /* Indicate user is not talking anymore - change him to unmonitored state */
4062  set_user_talking(chan, conf, user, -1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
4063  }
4064  meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
4065  }
4066 
4067  /* If I should be un-muted but am not talker, un-mute me */
4068  if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) && !(dahdic.confmode & DAHDI_CONF_TALKER)) {
4069  RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
4070  dahdic.confmode |= DAHDI_CONF_TALKER;
4071  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
4072  ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
4073  ret = -1;
4074  break;
4075  }
4076  meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
4077  }
4078 
4079  if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
4080  (user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) {
4081 
4082  RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
4083  talkreq_manager = 1;
4084  meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
4085  }
4086 
4087  if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
4088  !(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) {
4089  RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
4090  talkreq_manager = 0;
4091  meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
4092  }
4093 
4094  /* If user have been hung up, exit the conference */
4095  if (user->adminflags & ADMINFLAG_HANGUP) {
4096  ret = 0;
4097  break;
4098  }
4099 
4100  /* If I have been kicked, exit the conference */
4101  if (user->adminflags & ADMINFLAG_KICKME) {
4102  /* You have been kicked. */
4103  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4104  !ast_streamfile(chan, "conf-kicked", ast_channel_language(chan))) {
4105  ast_waitstream(chan, "");
4106  }
4107  ret = 0;
4108  break;
4109  }
4110 
4111  /* Perform a hangup check here since ast_waitfor_nandfds will not always be able to get a channel after a hangup has occurred */
4112  if (ast_check_hangup(chan)) {
4113  break;
4114  }
4115 
4116  c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
4117 
4118  if (c) {
4119  char dtmfstr[2] = "";
4120 
4121  if (ast_channel_fd(c, 0) != origfd || (user->dahdichannel && (ast_channel_audiohooks(c) || ast_channel_monitor(c)))) {
4122  if (using_pseudo) {
4123  /* Kill old pseudo */
4124  close(fd);
4125  using_pseudo = 0;
4126  }
4127  ast_debug(1, "Ooh, something swapped out under us, starting over\n");
4128  retrydahdi = (strcasecmp(ast_channel_tech(c)->type, "DAHDI") || (ast_channel_audiohooks(c) || ast_channel_monitor(c)) ? 1 : 0);
4129  user->dahdichannel = !retrydahdi;
4130  goto dahdiretry;
4131  }
4133  f = ast_read_noaudio(c);
4134  } else {
4135  f = ast_read(c);
4136  }
4137  if (!f) {
4138  break;
4139  }
4140  if (f->frametype == AST_FRAME_DTMF) {
4141  dtmfstr[0] = f->subclass.integer;
4142  dtmfstr[1] = '\0';
4143  }
4144 
4146  if (user->talk.actual) {
4148  }
4149 
4151  if (user->talking == -1) {
4152  user->talking = 0;
4153  }
4154 
4155  res = ast_dsp_silence(dsp, f, &totalsilence);
4156  if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) {
4157  set_user_talking(chan, conf, user, 1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
4158  }
4159 
4160  if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) {
4161  set_user_talking(chan, conf, user, 0, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
4162  }
4163  }
4164  if (using_pseudo) {
4165  /* Absolutely do _not_ use careful_write here...
4166  it is important that we read data from the channel
4167  as fast as it arrives, and feed it into the conference.
4168  The buffering in the pseudo channel will take care of any
4169  timing differences, unless they are so drastic as to lose
4170  audio frames (in which case carefully writing would only
4171  have delayed the audio even further).
4172  */
4173  /* As it turns out, we do want to use careful write. We just
4174  don't want to block, but we do want to at least *try*
4175  to write out all the samples.
4176  */
4177  if (user->talking || !ast_test_flag64(confflags, CONFFLAG_OPTIMIZETALKER)) {
4178  careful_write(fd, f->data.ptr, f->datalen, 0);
4179  }
4180  }
4181  } else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass.integer == '*') && ast_test_flag64(confflags, CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_mode)) {
4182  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
4183  conf_queue_dtmf(conf, user, f);
4184  }
4185  /* Take out of conference */
4186  if (ioctl(fd, DAHDI_SETCONF, &dahdic_empty)) {
4187  ast_log(LOG_WARNING, "Error setting conference\n");
4188  close(fd);
4189  ast_frfree(f);
4190  goto outrun;
4191  }
4192 
4193  /* if we are entering the menu, and the user has a channel-driver
4194  volume adjustment, clear it
4195  */
4196  if (!menu_mode && user->talk.desired && !user->talk.actual) {
4197  set_talk_volume(user, 0);
4198  }
4199 
4200  if (musiconhold) {
4201  ast_moh_stop(chan);
4202  } else if (!menu_mode) {
4203  char *menu_to_play;
4204  if (ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
4205  menu_mode = MENU_ADMIN;
4206  menu_to_play = "conf-adminmenu-18";
4207  } else {
4208  menu_mode = MENU_NORMAL;
4209  menu_to_play = "conf-usermenu-162";
4210  }
4211 
4212  if (!ast_streamfile(chan, menu_to_play, ast_channel_language(chan))) {
4213  dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
4214  ast_stopstream(chan);
4215  } else {
4216  dtmf = 0;
4217  }
4218  } else {
4219  dtmf = f->subclass.integer;
4220  }
4221 
4222  if (dtmf > 0) {
4223  meetme_menu(&menu_mode, &dtmf, conf, confflags,
4224  chan, user, recordingtmp, sizeof(recordingtmp), cap_slin);
4225  }
4226 
4227  if (musiconhold && !menu_mode) {
4228  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
4229  }
4230 
4231  /* Put back into conference */
4232  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
4233  ast_log(LOG_WARNING, "Error setting conference\n");
4234  close(fd);
4235  ast_frfree(f);
4236  goto outrun;
4237  }
4238 
4239  conf_flush(fd, chan);
4240  /*
4241  * Since options using DTMF could absorb DTMF meant for the
4242  * conference menu, we have to check them after the menu.
4243  */
4244  } else if ((f->frametype == AST_FRAME_DTMF) && ast_test_flag64(confflags, CONFFLAG_EXIT_CONTEXT) && ast_exists_extension(chan, exitcontext, dtmfstr, 1, "")) {
4245  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
4246  conf_queue_dtmf(conf, user, f);
4247  }
4248 
4249  if (!ast_goto_if_exists(chan, exitcontext, dtmfstr, 1)) {
4250  ast_debug(1, "Got DTMF %c, goto context %s\n", dtmfstr[0], exitcontext);
4251  ret = 0;
4252  ast_frfree(f);
4253  break;
4254  } else {
4255  ast_debug(2, "Exit by single digit did not work in meetme. Extension %s does not exist in context %s\n", dtmfstr, exitcontext);
4256  }
4257  } else if ((f->frametype == AST_FRAME_DTMF) && ast_test_flag64(confflags, CONFFLAG_KEYEXIT) &&
4258  (strchr(exitkeys, f->subclass.integer))) {
4259  pbx_builtin_setvar_helper(chan, "MEETME_EXIT_KEY", dtmfstr);
4260 
4261  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
4262  conf_queue_dtmf(conf, user, f);
4263  }
4264  ret = 0;
4265  ast_frfree(f);
4266  break;
4267  } else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
4268  && ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
4269  conf_queue_dtmf(conf, user, f);
4270  } else if (ast_test_flag64(confflags, CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
4271  switch (f->subclass.integer) {
4272  case AST_CONTROL_HOLD:
4273  sla_queue_event_conf(SLA_EVENT_HOLD, chan, conf);
4274  break;
4275  default:
4276  break;
4277  }
4278  } else if (f->frametype == AST_FRAME_NULL) {
4279  /* Ignore NULL frames. It is perfectly normal to get these if the person is muted. */
4280  } else if (f->frametype == AST_FRAME_CONTROL) {
4281  switch (f->subclass.integer) {
4282  case AST_CONTROL_BUSY:
4284  ast_frfree(f);
4285  goto outrun;
4286  break;
4287  default:
4288  ast_debug(1,
4289  "Got ignored control frame on channel %s, f->frametype=%u,f->subclass=%d\n",
4290  ast_channel_name(chan), f->frametype, f->subclass.integer);
4291  }
4292  } else {
4293  ast_debug(1,
4294  "Got unrecognized frame on channel %s, f->frametype=%u,f->subclass=%d\n",
4295  ast_channel_name(chan), f->frametype, f->subclass.integer);
4296  }
4297  ast_frfree(f);
4298  } else if (outfd > -1) {
4299  res = read(outfd, buf, CONF_SIZE);
4300  if (res > 0) {
4301  memset(&fr, 0, sizeof(fr));
4302  fr.frametype = AST_FRAME_VOICE;
4303  fr.subclass.format = ast_format_slin;
4304  fr.datalen = res;
4305  fr.samples = res / 2;
4306  fr.data.ptr = buf;
4307  fr.offset = AST_FRIENDLY_OFFSET;
4308  if (!user->listen.actual &&
4309  (ast_test_flag64(confflags, CONFFLAG_MONITOR) ||
4311  (!user->talking && ast_test_flag64(confflags, CONFFLAG_OPTIMIZETALKER))
4312  )) {
4313  int idx;
4314  for (idx = 0; idx < AST_FRAME_BITS; idx++) {
4316  break;
4317  }
4318  }
4319  if (idx >= AST_FRAME_BITS) {
4320  goto bailoutandtrynormal;
4321  }
4322  ast_mutex_lock(&conf->listenlock);
4323  if (!conf->transframe[idx]) {
4324  if (conf->origframe) {
4325  if (musiconhold
4326  && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)
4327  && !ast_dsp_silence(dsp, conf->origframe, &confsilence)
4328  && confsilence < MEETME_DELAYDETECTTALK) {
4329  ast_moh_stop(chan);
4330  mohtempstopped = 1;
4331  }
4332  if (!conf->transpath[idx]) {
4334  }
4335  if (conf->transpath[idx]) {
4336  conf->transframe[idx] = ast_translate(conf->transpath[idx], conf->origframe, 0);
4337  if (!conf->transframe[idx]) {
4338  conf->transframe[idx] = &ast_null_frame;
4339  }
4340  }
4341  }
4342  }
4343  if (conf->transframe[idx]) {
4344  if ((conf->transframe[idx]->frametype != AST_FRAME_NULL) &&
4345  can_write(chan, confflags)) {
4346  struct ast_frame *cur;
4347  /* the translator may have returned a list of frames, so
4348  write each one onto the channel
4349  */
4350  for (cur = conf->transframe[idx]; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
4351  if (ast_write(chan, cur)) {
4352  ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", ast_channel_name(chan));
4353  break;
4354  }
4355  }
4356  if (musiconhold && mohtempstopped && confsilence > MEETME_DELAYDETECTENDTALK) {
4357  mohtempstopped = 0;
4358  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
4359  }
4360  }
4361  } else {
4362  ast_mutex_unlock(&conf->listenlock);
4363  goto bailoutandtrynormal;
4364  }
4365  ast_mutex_unlock(&conf->listenlock);
4366  } else {
4367 bailoutandtrynormal:
4368  if (musiconhold
4369  && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)
4370  && !ast_dsp_silence(dsp, &fr, &confsilence)
4371  && confsilence < MEETME_DELAYDETECTTALK) {
4372  ast_moh_stop(chan);
4373  mohtempstopped = 1;
4374  }
4375  if (user->listen.actual) {
4377  }
4378  if (can_write(chan, confflags) && ast_write(chan, &fr) < 0) {
4379  ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", ast_channel_name(chan));
4380  }
4381  if (musiconhold && mohtempstopped && confsilence > MEETME_DELAYDETECTENDTALK) {
4382  mohtempstopped = 0;
4383  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
4384  }
4385  }
4386  } else {
4387  ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
4388  }
4389  }
4390  lastmarked = currentmarked;
4391  }
4392  }
4393 
4394  if (musiconhold) {
4395  ast_moh_stop(chan);
4396  }
4397 
4398  if (using_pseudo) {
4399  close(fd);
4400  } else {
4401  /* Take out of conference */
4402  dahdic.chan = 0;
4403  dahdic.confno = 0;
4404  dahdic.confmode = 0;
4405  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
4406  ast_log(LOG_WARNING, "Error setting conference\n");
4407  }
4408  }
4409 
4410  reset_volumes(user);
4411 
4412  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) &&
4413  !ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
4414  conf_play(chan, conf, LEAVE);
4415  }
4416 
4418  struct announce_listitem *item;
4419  if (!(item = ao2_alloc(sizeof(*item), NULL)))
4420  goto outrun;
4421  ast_copy_string(item->namerecloc, user->namerecloc, sizeof(item->namerecloc));
4422  ast_copy_string(item->language, ast_channel_language(chan), sizeof(item->language));
4423  item->confchan = conf->chan;
4424  item->confusers = conf->users;
4425  item->announcetype = CONF_HASLEFT;
4426  if (ast_test_flag64(confflags, CONFFLAG_INTROUSER_VMREC)){
4427  item->vmrec = 1;
4428  }
4430  AST_LIST_INSERT_TAIL(&conf->announcelist, item, entry);
4433  } else if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && ast_test_flag64(confflags, CONFFLAG_INTROUSER | CONFFLAG_INTROUSERNOREVIEW) && !ast_test_flag64(confflags, CONFFLAG_INTROUSER_VMREC) && conf->users == 1) {
4434  /* Last person is leaving, so no reason to try and announce, but should delete the name recording */
4435  ast_filedelete(user->namerecloc, NULL);
4436  }
4437 
4438  outrun:
4439  AST_LIST_LOCK(&confs);
4440 
4441  if (dsp) {
4442  ast_dsp_free(dsp);
4443  }
4444 
4445  if (user->user_no) {
4446  /* Only cleanup users who really joined! */
4447  now = ast_tvnow();
4448 
4449  if (sent_event) {
4450  meetme_stasis_generate_msg(conf, chan, user, meetme_leave_type(), NULL);
4451  }
4452 
4453  if (setusercount) {
4454  conf->users--;
4455  if (rt_log_members) {
4456  /* Update table */
4457  snprintf(members, sizeof(members), "%d", conf->users);
4458  ast_realtime_require_field("meetme",
4459  "confno", strlen(conf->confno) > 7 ? RQ_UINTEGER4 : strlen(conf->confno) > 4 ? RQ_UINTEGER3 : RQ_UINTEGER2, strlen(conf->confno),
4460  "members", RQ_UINTEGER1, strlen(members),
4461  NULL);
4462  ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
4463  }
4464  if (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
4465  conf->markedusers--;
4466  }
4467  }
4468  /* Remove ourselves from the container */
4469  ao2_unlink(conf->usercontainer, user);
4470 
4471  /* Change any states */
4472  if (!conf->users) {
4474  }
4475 
4476  /* This flag is meant to kill a conference with only one participant remaining. */
4477  if (conf->users == 1 && ast_test_flag64(confflags, CONFFLAG_KILL_LAST_MAN_STANDING)) {
4479  }
4480 
4481  /* Return the number of seconds the user was in the conf */
4482  snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
4483  pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
4484 
4485  /* Return the RealTime bookid for CDR linking */
4486  if (rt_schedule) {
4487  pbx_builtin_setvar_helper(chan, "MEETMEBOOKID", conf->bookid);
4488  }
4489  }
4490  ao2_ref(user, -1);
4492 
4493 
4494 conf_run_cleanup:
4495  ao2_cleanup(cap_slin);
4496 
4497  return ret;
4498 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
struct ast_variable * next
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
static const char type[]
Definition: chan_ooh323.c:109
static void set_user_talking(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking, int monitor)
Definition: app_meetme.c:2687
const char * warning_sound
Definition: app_meetme.c:911
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct timeval start_time
Definition: app_meetme.c:907
struct ast_channel * chan
Definition: app_meetme.c:846
uint64_t ast_format_compatibility_format2bitfield(const struct ast_format *format)
Convert a format structure to its respective bitfield.
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
static int careful_write(int fd, unsigned char *data, int len, int block)
Definition: app_meetme.c:1408
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
ast_mutex_t playlock
Definition: app_meetme.c:843
#define AST_FRAME_BITS
Definition: app_meetme.c:664
#define AST_DIGIT_ANY
Definition: file.h:48
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_frame * origframe
Definition: app_meetme.c:873
pthread_t recordthread
Definition: app_meetme.c:860
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
static void * recordthread(void *args)
Definition: app_meetme.c:5681
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_channel * confchan
Definition: app_meetme.c:835
#define CONFFLAG_INTROUSER_VMREC
Definition: app_meetme.c:749
#define MEETME_DELAYDETECTENDTALK
Definition: app_meetme.c:662
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:857
#define CONF_SIZE
Definition: app_meetme.c:683
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
char * recordingformat
Definition: app_meetme.c:864
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
static int timeout
Definition: cdr_mysql.c:86
static int tmp()
Definition: bt_open.c:389
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct ast_conference::@40 announcelist
Structure for variables, used for configurations and for channel variables.
#define CONFFLAG_DONT_DENOISE
Definition: app_meetme.c:753
struct ast_frame * transframe[32]
Definition: app_meetme.c:872
#define var
Definition: ast_expr2f.c:614
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
ast_mutex_t listenlock
Definition: app_meetme.c:844
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8349
static struct aco_type item
Definition: test_config.c:1463
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
long warning_freq
Definition: app_meetme.c:910
#define ast_mutex_lock(a)
Definition: lock.h:187
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:565
#define ao2_unlock(a)
Definition: astobj2.h:730
static struct test_val c
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define AST_FRAME_DTMF
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
static void meetme_menu(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, int recordingtmp_size, struct ast_format_cap *cap_slin)
Definition: app_meetme.c:3153
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ast_cond_signal(cond)
Definition: lock.h:201
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:2997
static void conf_play(struct ast_channel *chan, struct ast_conference *conf, enum entrance_sound sound)
Definition: app_meetme.c:1526
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
#define ast_verb(level,...)
Definition: logger.h:463
unsigned int locked
Definition: app_meetme.c:858
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1579
struct ast_frame_subclass subclass
unsigned int gmuted
Definition: app_meetme.c:859
static struct ast_json * status_to_json(int on)
Definition: app_meetme.c:1324
#define CONFFLAG_INTROMSG
Definition: app_meetme.c:748
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6444
static int rt_schedule
Definition: app_meetme.c:810
int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
Allow to record message and have a review option.
Definition: main/app.c:2489
static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference, struct ast_channel *chan, struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
Definition: app_meetme.c:1343
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define CONFFLAG_KILL_LAST_MAN_STANDING
Definition: app_meetme.c:751
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
static char exitcontext[AST_MAX_CONTEXT]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:485
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
int actual
Definition: app_meetme.c:892
const char * end_sound
Definition: app_meetme.c:912
static int can_write(struct ast_channel *chan, struct ast_flags64 *confflags)
Definition: app_meetme.c:2672
const char * bookid
Definition: app_meetme.c:871
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: main/config.c:3382
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#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
Definition: dsp.c:405
static const struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:20588
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define AST_MAX_EXTENSION
Definition: channel.h:135
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void conf_start_moh(struct ast_channel *chan, const char *musicclass)
Definition: app_meetme.c:2585
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
ast_mutex_t announcelistlock
Definition: app_meetme.c:883
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1518
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use.
Definition: localtime.c:2550
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
static void conf_flush(int fd, struct ast_channel *chan)
Definition: app_meetme.c:2299
static void * announce_thread(void *data)
Definition: app_meetme.c:2615
static int set_talk_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1435
struct volume listen
Definition: app_meetme.c:914
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
const char * ast_channel_uniqueid(const struct ast_channel *chan)
char uniqueid[32]
Definition: app_meetme.c:867
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct ast_flags64 userflags
Definition: app_meetme.c:898
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
#define DATE_FORMAT
Definition: app_meetme.c:650
int errno
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
Definition: main/app.c:1997
time_t kicktime
Definition: app_meetme.c:906
char namerecloc[PATH_MAX]
Definition: app_meetme.c:833
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
pthread_t announcethread
Definition: app_meetme.c:878
int desired
Definition: app_meetme.c:891
static int rt_log_members
Definition: app_meetme.c:817
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:8793
static void sla_queue_event_conf(enum sla_event_type type, struct ast_channel *chan, struct ast_conference *conf)
Queue a SLA event from the conference.
Definition: app_meetme.c:2462
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define AST_MAX_CONTEXT
Definition: channel.h:136
char namerecloc[PATH_MAX]
Definition: app_meetme.c:904
char language[MAX_LANGUAGE]
Definition: app_meetme.c:834
struct volume talk
Definition: app_meetme.c:913
static void conf_queue_dtmf(const struct ast_conference *conf, const struct ast_conf_user *sender, struct ast_frame *f)
Definition: app_meetme.c:2400
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:747
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct ao2_container * usercontainer
Definition: app_meetme.c:875
time_t jointime
Definition: app_meetme.c:905
structure to hold users read from users.conf
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
#define MEETME_DELAYDETECTTALK
Definition: app_meetme.c:661
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_frame ast_null_frame
Definition: main/frame.c:79
menu_modes
Definition: app_meetme.c:2749
int ast_channel_fd(const struct ast_channel *chan, int which)
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1483
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
ast_app: A registered application
Definition: pbx_app.c:45
const char * ast_channel_name(const struct ast_channel *chan)
static int audio_buffers
The number of audio buffers to be allocated on pseudo channels when in a conference.
Definition: app_meetme.c:1106
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
struct ast_trans_pvt * transpath[32]
Definition: app_meetme.c:874
#define ast_frfree(fr)
ast_cond_t announcelist_addition
Definition: app_meetme.c:881
long play_warning
Definition: app_meetme.c:909
Data structure associated with a single frame of data.
const char * ast_channel_language(const struct ast_channel *chan)
Abstract JSON element (object, array, string, int, ...).
#define AST_OPTION_TONE_VERIFY
Definition: search.h:40
const char * ast_channel_context(const struct ast_channel *chan)
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298
char * recordingfilename
Definition: app_meetme.c:863
struct ast_channel * lchan
Definition: app_meetme.c:847
union ast_frame::@263 data
enum ast_frame_type frametype
enum announcetypes announcetype
Definition: app_meetme.c:838
#define PATH_MAX
Definition: asterisk.h:40
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: main/frame.c:787
static int user_set_hangup_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2705
#define ast_mutex_init(pmutex)
Definition: lock.h:184
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_format * format
struct ast_audiohook_list * ast_channel_audiohooks(const struct ast_channel *chan)
const char * ast_channel_macrocontext(const struct ast_channel *chan)
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
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996
struct ast_channel_monitor * ast_channel_monitor(const struct ast_channel *chan)
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
struct ast_frame * ast_read_noaudio(struct ast_channel *chan)
Reads a frame, returning AST_FRAME_NULL frame if audio.
Definition: channel.c:4312
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_channel * chan
Definition: app_meetme.c:900
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
#define ast_mutex_unlock(a)
Definition: lock.h:188
ast_mutex_t recordthreadlock
Definition: app_meetme.c:861
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231
ast_mutex_t announcethreadlock
Definition: app_meetme.c:879
#define ast_test_flag64(p, flag)
Definition: utils.h:120
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ conf_start_moh()

static void conf_start_moh ( struct ast_channel chan,
const char *  musicclass 
)
static

Definition at line 2585 of file app_meetme.c.

References ast_channel_lock, ast_channel_musicclass(), ast_channel_unlock, ast_moh_start(), ast_strdupa, and NULL.

Referenced by conf_run().

2586 {
2587  char *original_moh;
2588 
2589  ast_channel_lock(chan);
2590  original_moh = ast_strdupa(ast_channel_musicclass(chan));
2591  ast_channel_musicclass_set(chan, musicclass);
2592  ast_channel_unlock(chan);
2593 
2594  ast_moh_start(chan, original_moh, NULL);
2595 
2596  ast_channel_lock(chan);
2597  ast_channel_musicclass_set(chan, original_moh);
2598  ast_channel_unlock(chan);
2599 }
static char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:162
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define NULL
Definition: resample.c:96
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_channel_musicclass(const struct ast_channel *chan)

◆ count_exec()

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

The MeetmeCount application.

Definition at line 4792 of file app_meetme.c.

References ast_answer(), AST_APP_ARG, ast_channel_language(), AST_DECLARE_APP_ARGS, ast_log, ast_say_number(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero, ast_conference::confno, dispose_conf(), find_conf(), LOG_WARNING, NULL, pbx_builtin_setvar_helper(), and ast_conference::users.

Referenced by load_module().

4793 {
4794  int res = 0;
4795  struct ast_conference *conf;
4796  int count;
4797  char *localdata;
4798  char val[80] = "0";
4801  AST_APP_ARG(varname);
4802  );
4803 
4804  if (ast_strlen_zero(data)) {
4805  ast_log(LOG_WARNING, "MeetMeCount requires an argument (conference number)\n");
4806  return -1;
4807  }
4808 
4809  localdata = ast_strdupa(data);
4810 
4811  AST_STANDARD_APP_ARGS(args, localdata);
4812 
4813  conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 1, NULL);
4814 
4815  if (conf) {
4816  count = conf->users;
4817  dispose_conf(conf);
4818  conf = NULL;
4819  } else
4820  count = 0;
4821 
4822  if (!ast_strlen_zero(args.varname)) {
4823  /* have var so load it and exit */
4824  snprintf(val, sizeof(val), "%d", count);
4825  pbx_builtin_setvar_helper(chan, args.varname, val);
4826  } else {
4827  if (ast_channel_state(chan) != AST_STATE_UP) {
4828  ast_answer(chan);
4829  }
4830  res = ast_say_number(chan, count, "", ast_channel_language(chan), (char *) NULL); /* Needs gender */
4831  }
4832 
4833  return res;
4834 }
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
static struct ast_conference * find_conf(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags64 *confflags)
Definition: app_meetme.c:4688
Definition: ast_expr2.c:325
#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
ast_channel_state
ast_channel states
Definition: channelstate.h:35
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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...
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
const char * ast_channel_language(const struct ast_channel *chan)
The MeetMe Conference object.
Definition: app_meetme.c:842
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ create_trunk_ref()

static struct sla_trunk_ref* create_trunk_ref ( struct sla_trunk trunk)
static

Definition at line 7168 of file app_meetme.c.

References ao2_alloc, ao2_ref, NULL, sla_trunk_ref_destructor(), and sla_trunk_ref::trunk.

Referenced by sla_add_trunk_to_station().

7169 {
7170  struct sla_trunk_ref *trunk_ref;
7171 
7172  if (!(trunk_ref = ao2_alloc(sizeof(*trunk_ref), sla_trunk_ref_destructor))) {
7173  return NULL;
7174  }
7175 
7176  ao2_ref(trunk, 1);
7177  trunk_ref->trunk = trunk;
7178 
7179  return trunk_ref;
7180 }
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
static void sla_trunk_ref_destructor(void *obj)
Definition: app_meetme.c:7158

◆ dial_trunk()

static void* dial_trunk ( void *  data)
static

Definition at line 6852 of file app_meetme.c.

References ALL_TRUNK_REFS, ao2_cleanup, ast_channel_caller(), ast_channel_caller_set(), ast_channel_name(), ast_cond_signal, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, AST_DEVICE_NOT_INUSE, ast_dial_answered(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_join(), AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_HANGUP, AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_RINGING, AST_DIAL_RESULT_TIMEOUT, AST_DIAL_RESULT_TRYING, AST_DIAL_RESULT_UNANSWERED, ast_dial_run(), ast_dial_state(), ast_indicate(), ast_mutex_lock, ast_mutex_unlock, ast_party_caller_free(), ast_party_caller_init(), ast_safe_sleep(), ast_set_flag64, ast_strdupa, build_conf(), dial_trunk_args::cond, dial_trunk_args::cond_lock, conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_TRUNK, dispose_conf(), done, MAX_CONFNUM, NULL, RAII_VAR, sla, sla_change_trunk_state(), SLA_TRUNK_STATE_IDLE, dial_trunk_args::station, strsep(), and dial_trunk_args::trunk_ref.

Referenced by sla_station_exec().

6853 {
6854  struct dial_trunk_args *args = data;
6855  struct ast_dial *dial;
6856  char *tech, *tech_data;
6857  enum ast_dial_result dial_res;
6858  char conf_name[MAX_CONFNUM];
6859  struct ast_conference *conf;
6860  struct ast_flags64 conf_flags = { 0 };
6861  RAII_VAR(struct sla_trunk_ref *, trunk_ref, args->trunk_ref, ao2_cleanup);
6862  RAII_VAR(struct sla_station *, station, args->station, ao2_cleanup);
6863  int caller_is_saved;
6864  struct ast_party_caller caller;
6865  int last_state = 0;
6866  int current_state = 0;
6867 
6868  if (!(dial = ast_dial_create())) {
6869  ast_mutex_lock(args->cond_lock);
6870  ast_cond_signal(args->cond);
6871  ast_mutex_unlock(args->cond_lock);
6872  return NULL;
6873  }
6874 
6875  tech_data = ast_strdupa(trunk_ref->trunk->device);
6876  tech = strsep(&tech_data, "/");
6877  if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
6878  ast_mutex_lock(args->cond_lock);
6879  ast_cond_signal(args->cond);
6880  ast_mutex_unlock(args->cond_lock);
6881  ast_dial_destroy(dial);
6882  return NULL;
6883  }
6884 
6885  /* Do we need to save of the caller ID data? */
6886  caller_is_saved = 0;
6887  if (!sla.attempt_callerid) {
6888  caller_is_saved = 1;
6889  caller = *ast_channel_caller(trunk_ref->chan);
6890  ast_party_caller_init(ast_channel_caller(trunk_ref->chan));
6891  }
6892 
6893  dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
6894 
6895  /* Restore saved caller ID */
6896  if (caller_is_saved) {
6897  ast_party_caller_free(ast_channel_caller(trunk_ref->chan));
6898  ast_channel_caller_set(trunk_ref->chan, &caller);
6899  }
6900 
6901  if (dial_res != AST_DIAL_RESULT_TRYING) {
6902  ast_mutex_lock(args->cond_lock);
6903  ast_cond_signal(args->cond);
6904  ast_mutex_unlock(args->cond_lock);
6905  ast_dial_destroy(dial);
6906  return NULL;
6907  }
6908 
6909  for (;;) {
6910  unsigned int done = 0;
6911  switch ((dial_res = ast_dial_state(dial))) {
6913  trunk_ref->trunk->chan = ast_dial_answered(dial);
6919  done = 1;
6920  break;
6922  current_state = AST_CONTROL_PROGRESS;
6923  break;
6927  current_state = AST_CONTROL_RINGING;
6928  break;
6929  }
6930  if (done)
6931  break;
6932 
6933  /* check that SLA station that originated trunk call is still alive */
6934  if (station && ast_device_state(station->device) == AST_DEVICE_NOT_INUSE) {
6935  ast_debug(3, "Originating station device %s no longer active\n", station->device);
6936  trunk_ref->trunk->chan = NULL;
6937  break;
6938  }
6939 
6940  /* If trunk line state changed, send indication back to originating SLA Station channel */
6941  if (current_state != last_state) {
6942  ast_debug(3, "Indicating State Change %d to channel %s\n", current_state, ast_channel_name(trunk_ref->chan));
6943  ast_indicate(trunk_ref->chan, current_state);
6944  last_state = current_state;
6945  }
6946 
6947  /* avoid tight loop... sleep for 1/10th second */
6948  ast_safe_sleep(trunk_ref->chan, 100);
6949  }
6950 
6951  if (!trunk_ref->trunk->chan) {
6952  ast_mutex_lock(args->cond_lock);
6953  ast_cond_signal(args->cond);
6954  ast_mutex_unlock(args->cond_lock);
6955  ast_dial_join(dial);
6956  ast_dial_destroy(dial);
6957  return NULL;
6958  }
6959 
6960  snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
6961  ast_set_flag64(&conf_flags,
6964  conf = build_conf(conf_name, "", "", 1, 1, 1, trunk_ref->trunk->chan, NULL);
6965 
6966  ast_mutex_lock(args->cond_lock);
6967  ast_cond_signal(args->cond);
6968  ast_mutex_unlock(args->cond_lock);
6969 
6970  if (conf) {
6971  conf_run(trunk_ref->trunk->chan, conf, &conf_flags, NULL);
6972  dispose_conf(conf);
6973  conf = NULL;
6974  }
6975 
6976  /* If the trunk is going away, it is definitely now IDLE. */
6978 
6979  trunk_ref->trunk->chan = NULL;
6980  trunk_ref->trunk->on_hold = 0;
6981 
6982  ast_dial_join(dial);
6983  ast_dial_destroy(dial);
6984 
6985  return NULL;
6986 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
ast_device_state
Device States.
Definition: devicestate.h:52
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
static struct @35 sla
A structure for data used by the sla thread.
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:48
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2015
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
const char * args
ast_cond_t * cond
Definition: app_meetme.c:6849
#define NULL
Definition: resample.c:96
ast_mutex_t * cond_lock
Definition: app_meetme.c:6848
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define ast_cond_signal(cond)
Definition: lock.h:201
All configuration options for statsd client.
Definition: res_statsd.c:95
int done
Definition: test_amihooks.c:48
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:3177
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct sla_station * station
Definition: app_meetme.c:6847
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
#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
Caller Party information.
Definition: channel.h:419
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
void ast_channel_caller_set(struct ast_channel *chan, struct ast_party_caller *value)
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1012
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:939
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:6846
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:282
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:981
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:225
char * strsep(char **str, const char *delims)
#define MAX_CONFNUM
Definition: app_meetme.c:819
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
The MeetMe Conference object.
Definition: app_meetme.c:842
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:1978
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ dispose_conf()

static int dispose_conf ( struct ast_conference conf)
static

Decrement reference counts, as incremented by find_conf()

Definition at line 2504 of file app_meetme.c.

References ast_atomic_dec_and_test(), AST_LIST_LOCK, AST_LIST_UNLOCK, conf_free(), ast_conference::confno, and ast_conference::refcount.

Referenced by admin_exec(), conf_exec(), count_exec(), dial_trunk(), run_station(), sla_station_exec(), and sla_trunk_exec().

2505 {
2506  int res = 0;
2507  int confno_int = 0;
2508 
2509  AST_LIST_LOCK(&confs);
2510  if (ast_atomic_dec_and_test(&conf->refcount)) {
2511  /* Take the conference room number out of an inuse state */
2512  if ((sscanf(conf->confno, "%4d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024)) {
2513  conf_map[confno_int] = 0;
2514  }
2515  conf_free(conf);
2516  res = 1;
2517  }
2519 
2520  return res;
2521 }
static int conf_free(struct ast_conference *conf)
Remove the conference from the list and free it.
Definition: app_meetme.c:2331
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
Definition: lock.h:765
static unsigned int conf_map[1024]
Definition: app_meetme.c:888
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ filename_parse()

static void filename_parse ( char *  filename,
char *  buffer 
)
static

Definition at line 5662 of file app_meetme.c.

References ast_config_AST_SPOOL_DIR, ast_copy_string(), ast_log, ast_mkdir(), ast_strlen_zero, LOG_WARNING, and PATH_MAX.

Referenced by recordthread().

5663 {
5664  char *slash;
5665  if (ast_strlen_zero(filename)) {
5666  ast_log(LOG_WARNING, "No file name was provided for a file save option.\n");
5667  } else if (filename[0] != '/') {
5668  snprintf(buffer, PATH_MAX, "%s/meetme/%s", ast_config_AST_SPOOL_DIR, filename);
5669  } else {
5670  ast_copy_string(buffer, filename, PATH_MAX);
5671  }
5672 
5673  slash = buffer;
5674  if ((slash = strrchr(slash, '/'))) {
5675  *slash = '\0';
5676  ast_mkdir(buffer, 0777);
5677  *slash = '/';
5678  }
5679 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define PATH_MAX
Definition: asterisk.h:40
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231

◆ find_conf()

static struct ast_conference* find_conf ( struct ast_channel chan,
char *  confno,
int  make,
int  dynamic,
char *  dynamic_pin,
size_t  pin_buf_len,
int  refcount,
struct ast_flags64 confflags 
)
static

Definition at line 4688 of file app_meetme.c.

References AST_APP_ARG, ast_app_getdata(), ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, AST_STANDARD_APP_ARGS, ast_test_flag64, ast_variable_browse(), build_conf(), ast_conference::chan, CONFFLAG_INTROUSER, CONFFLAG_INTROUSER_VMREC, CONFFLAG_INTROUSERNOREVIEW, CONFFLAG_QUIET, CONFFLAG_RECORDCONF, CONFIG_FILE_NAME, CONFIG_STATUS_FILEINVALID, ast_conference::confno, ast_conference::list, LOG_ERROR, LOG_WARNING, MAX_SETTINGS, ast_variable::name, ast_variable::next, NULL, parse(), ast_conference::pin, ast_conference::pinadmin, ast_conference::refcount, S_OR, ast_variable::value, and var.

Referenced by conf_exec(), and count_exec().

4690 {
4691  struct ast_config *cfg;
4692  struct ast_variable *var;
4693  struct ast_flags config_flags = { 0 };
4694  struct ast_conference *cnf;
4695 
4698  AST_APP_ARG(pin);
4700  );
4701 
4702  /* Check first in the conference list */
4703  ast_debug(1, "The requested confno is '%s'?\n", confno);
4704  AST_LIST_LOCK(&confs);
4705  AST_LIST_TRAVERSE(&confs, cnf, list) {
4706  ast_debug(3, "Does conf %s match %s?\n", confno, cnf->confno);
4707  if (!strcmp(confno, cnf->confno))
4708  break;
4709  }
4710  if (cnf) {
4711  cnf->refcount += refcount;
4712  }
4714 
4715  if (!cnf) {
4716  if (dynamic) {
4717  /* No need to parse meetme.conf */
4718  ast_debug(1, "Building dynamic conference '%s'\n", confno);
4719  if (dynamic_pin) {
4720  if (dynamic_pin[0] == 'q') {
4721  /* Query the user to enter a PIN */
4722  if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, pin_buf_len - 1, 0) < 0)
4723  return NULL;
4724  }
4725  cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount, chan, NULL);
4726  } else {
4727  cnf = build_conf(confno, "", "", make, dynamic, refcount, chan, NULL);
4728  }
4729  } else {
4730  /* Check the config */
4731  cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
4732  if (!cfg) {
4733  ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
4734  return NULL;
4735  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4736  ast_log(LOG_ERROR, "Config file " CONFIG_FILE_NAME " is in an invalid format. Aborting.\n");
4737  return NULL;
4738  }
4739 
4740  for (var = ast_variable_browse(cfg, "rooms"); var; var = var->next) {
4741  char parse[MAX_SETTINGS];
4742 
4743  if (strcasecmp(var->name, "conf"))
4744  continue;
4745 
4746  ast_copy_string(parse, var->value, sizeof(parse));
4747 
4748  AST_STANDARD_APP_ARGS(args, parse);
4749  ast_debug(3, "Will conf %s match %s?\n", confno, args.confno);
4750  if (!strcasecmp(args.confno, confno)) {
4751  /* Bingo it's a valid conference */
4752  cnf = build_conf(args.confno,
4753  S_OR(args.pin, ""),
4754  S_OR(args.pinadmin, ""),
4755  make, dynamic, refcount, chan, NULL);
4756  break;
4757  }
4758  }
4759  if (!var) {
4760  ast_debug(1, "%s isn't a valid conference\n", confno);
4761  }
4762  ast_config_destroy(cfg);
4763  }
4764  } else if (dynamic_pin) {
4765  /* Correct for the user selecting 'D' instead of 'd' to have
4766  someone join into a conference that has already been created
4767  with a pin. */
4768  if (dynamic_pin[0] == 'q') {
4769  dynamic_pin[0] = '\0';
4770  }
4771  }
4772 
4773  if (cnf) {
4774  if (confflags && !cnf->chan &&
4775  !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4777  ast_log(LOG_WARNING, "No DAHDI channel available for conference, user introduction disabled (is chan_dahdi loaded?)\n");
4779  }
4780 
4781  if (confflags && !cnf->chan &&
4782  ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
4783  ast_log(LOG_WARNING, "No DAHDI channel available for conference, conference recording disabled (is chan_dahdi loaded?)\n");
4785  }
4786  }
4787 
4788  return cnf;
4789 }
struct ast_variable * next
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:846
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define CONFFLAG_INTROUSER_VMREC
Definition: app_meetme.c:749
#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
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
const char * args
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
char pin[MAX_PIN]
Definition: app_meetme.c:865
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
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
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
#define MAX_SETTINGS
Definition: app_meetme.c:824
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#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
char pinadmin[MAX_PIN]
Definition: app_meetme.c:866
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define CONFIG_FILE_NAME
Definition: app_meetme.c:642
#define AST_APP_ARG(name)
Define an application argument.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ find_conf_realtime()

static struct ast_conference* find_conf_realtime ( struct ast_channel chan,
char *  confno,
int  make,
int  dynamic,
char *  dynamic_pin,
size_t  pin_buf_len,
int  refcount,
struct ast_flags64 confflags,
int *  too_early,
char **  optargs 
)
static

Definition at line 4500 of file app_meetme.c.

References ast_conference::adminopts, ast_app_parse_options64(), ast_channel_language(), ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_clear_flag64, ast_copy_flags64, ast_copy_string(), ast_debug, ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_load_realtime(), ast_localtime(), ast_log, AST_MAX_EXTENSION, ast_mktime(), ast_strdup, ast_strdupa, ast_streamfile(), ast_strftime(), ast_strlen_zero, ast_strptime(), ast_test_flag64, ast_tvnow(), ast_variables_destroy(), ast_verb, ast_waitstream(), ast_conference::bookid, build_conf(), ast_conference::chan, CONFFLAG_INTROUSER, CONFFLAG_INTROUSER_VMREC, CONFFLAG_INTROUSERNOREVIEW, CONFFLAG_QUIET, CONFFLAG_RECORDCONF, ast_conference::confno, DATE_FORMAT, earlyalert, endalert, ast_conference::endalert, ast_conference::endtime, ast_flags64::flags, fuzzystart, ast_conference::list, LOG_WARNING, ast_conference::maxusers, meetme_opts, ast_variable::name, ast_variable::next, NULL, OPTIONS_LEN, pbx_builtin_getvar_helper(), ast_conference::pin, ast_conference::pinadmin, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::refcount, ast_conference::useropts, ast_variable::value, and var.

Referenced by conf_exec().

4502 {
4503  struct ast_variable *var, *origvar;
4504  struct ast_conference *cnf;
4505 
4506  *too_early = 0;
4507 
4508  /* Check first in the conference list */
4509  AST_LIST_LOCK(&confs);
4510  AST_LIST_TRAVERSE(&confs, cnf, list) {
4511  if (!strcmp(confno, cnf->confno)) {
4512  break;
4513  }
4514  }
4515  if (cnf) {
4516  cnf->refcount += refcount;
4517  }
4519 
4520  if (!cnf) {
4521  char *pin = NULL, *pinadmin = NULL; /* For temp use */
4522  int maxusers = 0;
4523  struct timeval now;
4524  char recordingfilename[256] = "";
4525  char recordingformat[11] = "";
4526  char currenttime[32] = "";
4527  char eatime[32] = "";
4528  char bookid[51] = "";
4529  char recordingtmp[AST_MAX_EXTENSION * 2] = "";
4530  char useropts[OPTIONS_LEN + 1] = ""; /* Used for RealTime conferences */
4531  char adminopts[OPTIONS_LEN + 1] = "";
4532  struct ast_tm tm, etm;
4533  struct timeval endtime = { .tv_sec = 0 };
4534  const char *var2;
4535 
4536  if (rt_schedule) {
4537  now = ast_tvnow();
4538 
4539  ast_localtime(&now, &tm, NULL);
4540  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
4541 
4542  ast_debug(1, "Looking for conference %s that starts after %s\n", confno, currenttime);
4543 
4544  var = ast_load_realtime("meetme", "confno",
4545  confno, "starttime <= ", currenttime, "endtime >= ",
4546  currenttime, NULL);
4547 
4548  if (!var && fuzzystart) {
4549  now = ast_tvnow();
4550  now.tv_sec += fuzzystart;
4551 
4552  ast_localtime(&now, &tm, NULL);
4553  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
4554  var = ast_load_realtime("meetme", "confno",
4555  confno, "starttime <= ", currenttime, "endtime >= ",
4556  currenttime, NULL);
4557  }
4558 
4559  if (!var && earlyalert) {
4560  now = ast_tvnow();
4561  now.tv_sec += earlyalert;
4562  ast_localtime(&now, &etm, NULL);
4563  ast_strftime(eatime, sizeof(eatime), DATE_FORMAT, &etm);
4564  var = ast_load_realtime("meetme", "confno",
4565  confno, "starttime <= ", eatime, "endtime >= ",
4566  currenttime, NULL);
4567  if (var) {
4568  *too_early = 1;
4569  }
4570  }
4571 
4572  } else {
4573  var = ast_load_realtime("meetme", "confno", confno, NULL);
4574  }
4575 
4576  if (!var) {
4577  return NULL;
4578  }
4579 
4580  if (rt_schedule && *too_early) {
4581  /* Announce that the caller is early and exit */
4582  if (!ast_streamfile(chan, "conf-has-not-started", ast_channel_language(chan))) {
4583  ast_waitstream(chan, "");
4584  }
4585  ast_variables_destroy(var);
4586  return NULL;
4587  }
4588 
4589  for (origvar = var; var; var = var->next) {
4590  if (!strcasecmp(var->name, "pin")) {
4591  pin = ast_strdupa(var->value);
4592  } else if (!strcasecmp(var->name, "adminpin")) {
4593  pinadmin = ast_strdupa(var->value);
4594  } else if (!strcasecmp(var->name, "bookId")) {
4595  ast_copy_string(bookid, var->value, sizeof(bookid));
4596  } else if (!strcasecmp(var->name, "opts")) {
4597  ast_copy_string(useropts, var->value, sizeof(char[OPTIONS_LEN + 1]));
4598  } else if (!strcasecmp(var->name, "maxusers")) {
4599  maxusers = atoi(var->value);
4600  } else if (!strcasecmp(var->name, "adminopts")) {
4601  ast_copy_string(adminopts, var->value, sizeof(char[OPTIONS_LEN + 1]));
4602  } else if (!strcasecmp(var->name, "recordingfilename")) {
4603  ast_copy_string(recordingfilename, var->value, sizeof(recordingfilename));
4604  } else if (!strcasecmp(var->name, "recordingformat")) {
4605  ast_copy_string(recordingformat, var->value, sizeof(recordingformat));
4606  } else if (!strcasecmp(var->name, "endtime")) {
4607  struct ast_tm endtime_tm;
4608  ast_strptime(var->value, "%Y-%m-%d %H:%M:%S", &endtime_tm);
4609  endtime = ast_mktime(&endtime_tm, NULL);
4610  }
4611  }
4612 
4613  ast_variables_destroy(origvar);
4614 
4615  cnf = build_conf(confno, pin ? pin : "", pinadmin ? pinadmin : "", make, dynamic, refcount, chan, NULL);
4616 
4617  if (cnf) {
4618  struct ast_flags64 tmp_flags;
4619 
4620  cnf->maxusers = maxusers;
4621  cnf->endalert = endalert;
4622  cnf->endtime = endtime.tv_sec;
4623  cnf->useropts = ast_strdup(useropts);
4624  cnf->adminopts = ast_strdup(adminopts);
4625  cnf->bookid = ast_strdup(bookid);
4626  if (!ast_strlen_zero(recordingfilename)) {
4627  cnf->recordingfilename = ast_strdup(recordingfilename);
4628  }
4629  if (!ast_strlen_zero(recordingformat)) {
4630  cnf->recordingformat = ast_strdup(recordingformat);
4631  }
4632 
4633  /* Parse the other options into confflags -- need to do this in two
4634  * steps, because the parse_options routine zeroes the buffer. */
4635  ast_app_parse_options64(meetme_opts, &tmp_flags, optargs, useropts);
4636  ast_copy_flags64(confflags, &tmp_flags, tmp_flags.flags);
4637 
4638  if (strchr(cnf->useropts, 'r')) {
4639  if (ast_strlen_zero(recordingfilename)) { /* If the recordingfilename in the database is empty, use the channel definition or use the default. */
4640  ast_channel_lock(chan);
4641  if ((var2 = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
4643  cnf->recordingfilename = ast_strdup(var2);
4644  }
4645  ast_channel_unlock(chan);
4646  if (ast_strlen_zero(cnf->recordingfilename)) {
4647  snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", cnf->confno, ast_channel_uniqueid(chan));
4649  cnf->recordingfilename = ast_strdup(recordingtmp);
4650  }
4651  }
4652  if (ast_strlen_zero(cnf->recordingformat)) {/* If the recording format is empty, use the wav as default */
4653  ast_channel_lock(chan);
4654  if ((var2 = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
4655  ast_free(cnf->recordingformat);
4656  cnf->recordingformat = ast_strdup(var2);
4657  }
4658  ast_channel_unlock(chan);
4659  if (ast_strlen_zero(cnf->recordingformat)) {
4660  ast_free(cnf->recordingformat);
4661  cnf->recordingformat = ast_strdup("wav");
4662  }
4663  }
4664  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n", cnf->confno, cnf->recordingfilename, cnf->recordingformat);
4665  }
4666  }
4667  }
4668 
4669  if (cnf) {
4670  if (confflags->flags && !cnf->chan &&
4671  !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4673  ast_log(LOG_WARNING, "No DAHDI channel available for conference, user introduction disabled (is chan_dahdi loaded?)\n");
4675  }
4676 
4677  if (confflags && !cnf->chan &&
4678  ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
4679  ast_log(LOG_WARNING, "No DAHDI channel available for conference, conference recording disabled (is chan_dahdi loaded?)\n");
4681  }
4682  }
4683 
4684  return cnf;
4685 }
static int fuzzystart
Definition: app_meetme.c:811
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
struct ast_variable * next
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int endalert
Definition: app_meetme.c:813
struct ast_channel * chan
Definition: app_meetme.c:846
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define CONFFLAG_INTROUSER_VMREC
Definition: app_meetme.c:749
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:864
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static const struct ast_app_option meetme_opts[128]
Definition: app_meetme.c:800
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
static int earlyalert
Definition: app_meetme.c:812
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * useropts
Definition: app_meetme.c:869
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define ast_verb(level,...)
Definition: logger.h:463
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int rt_schedule
Definition: app_meetme.c:810
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const char * bookid
Definition: app_meetme.c:871
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use.
Definition: localtime.c:2550
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2911
uint64_t flags
Definition: utils.h:205
const char * ast_channel_uniqueid(const struct ast_channel *chan)
char pin[MAX_PIN]
Definition: app_meetme.c:865
#define DATE_FORMAT
Definition: app_meetme.c:650
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define OPTIONS_LEN
Definition: app_meetme.c:821
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_free(a)
Definition: astmm.h:182
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
const char * adminopts
Definition: app_meetme.c:870
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
char pinadmin[MAX_PIN]
Definition: app_meetme.c:866
const char * ast_channel_language(const struct ast_channel *chan)
char * recordingfilename
Definition: app_meetme.c:863
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ find_user()

static struct ast_conf_user* find_user ( struct ast_conference conf,
const char *  callerident 
)
static

Definition at line 5162 of file app_meetme.c.

References ao2_find, NULL, user, and ast_conference::usercontainer.

Referenced by admin_exec().

5163 {
5164  struct ast_conf_user *user = NULL;
5165  int cid;
5166 
5167  if (conf && callerident && sscanf(callerident, "%30d", &cid) == 1) {
5168  user = ao2_find(conf->usercontainer, &cid, 0);
5169  /* reference decremented later in admin_exec */
5170  return user;
5171  }
5172  return NULL;
5173 }
static char user[512]
#define NULL
Definition: resample.c:96
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * usercontainer
Definition: app_meetme.c:875
structure to hold users read from users.conf

◆ get_announce_filename()

static const char* get_announce_filename ( enum announcetypes  type)
static

Definition at line 2601 of file app_meetme.c.

References CONF_HASJOIN, and CONF_HASLEFT.

Referenced by announce_thread().

2602 {
2603  switch (type) {
2604  case CONF_HASLEFT:
2605  return "conf-hasleft";
2606  break;
2607  case CONF_HASJOIN:
2608  return "conf-hasjoin";
2609  break;
2610  default:
2611  return "";
2612  }
2613 }
static const char type[]
Definition: chan_ooh323.c:109

◆ istalking()

static const char* istalking ( int  x)
static

Definition at line 1398 of file app_meetme.c.

Referenced by meetme_show_cmd().

1399 {
1400  if (x > 0)
1401  return "(talking)";
1402  else if (x < 0)
1403  return "(unmonitored)";
1404  else
1405  return "(not talking)";
1406 }

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 7998 of file app_meetme.c.

References load_config_meetme(), and sla_load_config().

Referenced by load_module(), and reload().

7999 {
8001  return sla_load_config(reload);
8002 }
static int sla_load_config(int reload)
Definition: app_meetme.c:7855
static int reload(void)
Definition: app_meetme.c:8072
static void load_config_meetme(int reload)
Definition: app_meetme.c:5788

◆ load_config_meetme()

static void load_config_meetme ( int  reload)
static

Definition at line 5788 of file app_meetme.c.

References ast_config_destroy(), ast_config_load, ast_log, ast_true(), ast_variable_retrieve(), CONFIG_FILE_NAME, CONFIG_STATUS_FILEINVALID, DEFAULT_AUDIO_BUFFERS, LOG_ERROR, LOG_NOTICE, LOG_WARNING, and meetme_set_defaults().

Referenced by load_config().

5789 {
5790  struct ast_config *cfg;
5791  struct ast_flags config_flags = { 0 };
5792  const char *val;
5793 
5794  if (!reload) {
5796  }
5797 
5798  if (!(cfg = ast_config_load(CONFIG_FILE_NAME, config_flags))) {
5799  return;
5800  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
5801  ast_log(LOG_ERROR, "Config file " CONFIG_FILE_NAME " is in an invalid format. Aborting.\n");
5802  return;
5803  }
5804 
5805  if (reload) {
5807  }
5808 
5809  if ((val = ast_variable_retrieve(cfg, "general", "audiobuffers"))) {
5810  if ((sscanf(val, "%30d", &audio_buffers) != 1)) {
5811  ast_log(LOG_WARNING, "audiobuffers setting must be a number, not '%s'\n", val);
5813  } else if ((audio_buffers < DAHDI_DEFAULT_NUM_BUFS) || (audio_buffers > DAHDI_MAX_NUM_BUFS)) {
5814  ast_log(LOG_WARNING, "audiobuffers setting must be between %d and %d\n",
5815  DAHDI_DEFAULT_NUM_BUFS, DAHDI_MAX_NUM_BUFS);
5817  }
5819  ast_log(LOG_NOTICE, "Audio buffers per channel set to %d\n", audio_buffers);
5820  }
5821 
5822  if ((val = ast_variable_retrieve(cfg, "general", "schedule")))
5823  rt_schedule = ast_true(val);
5824  if ((val = ast_variable_retrieve(cfg, "general", "logmembercount")))
5825  rt_log_members = ast_true(val);
5826  if ((val = ast_variable_retrieve(cfg, "general", "fuzzystart"))) {
5827  if ((sscanf(val, "%30d", &fuzzystart) != 1)) {
5828  ast_log(LOG_WARNING, "fuzzystart must be a number, not '%s'\n", val);
5829  fuzzystart = 0;
5830  }
5831  }
5832  if ((val = ast_variable_retrieve(cfg, "general", "earlyalert"))) {
5833  if ((sscanf(val, "%30d", &earlyalert) != 1)) {
5834  ast_log(LOG_WARNING, "earlyalert must be a number, not '%s'\n", val);
5835  earlyalert = 0;
5836  }
5837  }
5838  if ((val = ast_variable_retrieve(cfg, "general", "endalert"))) {
5839  if ((sscanf(val, "%30d", &endalert) != 1)) {
5840  ast_log(LOG_WARNING, "endalert must be a number, not '%s'\n", val);
5841  endalert = 0;
5842  }
5843  }
5844  if ((val = ast_variable_retrieve(cfg, "general", "extendby"))) {
5845  if ((sscanf(val, "%30d", &extendby) != 1)) {
5846  ast_log(LOG_WARNING, "extendby must be a number, not '%s'\n", val);
5847  extendby = 0;
5848  }
5849  }
5850 
5851  ast_config_destroy(cfg);
5852 }
static int fuzzystart
Definition: app_meetme.c:811
static int endalert
Definition: app_meetme.c:813
Definition: ast_expr2.c:325
static void meetme_set_defaults(void)
Definition: app_meetme.c:5772
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
static int earlyalert
Definition: app_meetme.c:812
static int rt_schedule
Definition: app_meetme.c:810
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define LOG_ERROR
Definition: logger.h:285
#define DEFAULT_AUDIO_BUFFERS
Definition: app_meetme.c:647
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static int reload(void)
Definition: app_meetme.c:8072
#define LOG_NOTICE
Definition: logger.h:263
static int rt_log_members
Definition: app_meetme.c:817
static int extendby
Definition: app_meetme.c:814
Structure used to handle boolean flags.
Definition: utils.h:199
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
static int audio_buffers
The number of audio buffers to be allocated on pseudo channels when in a conference.
Definition: app_meetme.c:1106
#define CONFIG_FILE_NAME
Definition: app_meetme.c:642

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 8043 of file app_meetme.c.

References action_meetmelist(), action_meetmelistrooms(), action_meetmemute(), action_meetmeunmute(), ARRAY_LEN, ast_cli_register_multiple, ast_custom_function_register, ast_devstate_prov_add(), ast_manager_register_xml, ast_realtime_require_field(), ast_register_application_xml, channel_admin_exec(), conf_exec(), count_exec(), EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, load_config(), meetme_stasis_init(), meetmestate(), NULL, RQ_UINTEGER1, RQ_UINTEGER2, sla_state(), sla_station_exec(), and sla_trunk_exec().

Referenced by reload().

8044 {
8045  int res = 0;
8046 
8047  res |= load_config(0);
8048 
8049  res |= meetme_stasis_init();
8050 
8062 
8063  res |= ast_devstate_prov_add("Meetme", meetmestate);
8064  res |= ast_devstate_prov_add("SLA", sla_state);
8065 
8067  ast_realtime_require_field("meetme", "confno", RQ_UINTEGER2, 3, "members", RQ_UINTEGER1, 3, NULL);
8068 
8069  return res;
8070 }
static int action_meetmelistrooms(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5593
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int action_meetmeunmute(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5516
static const char *const app4
Definition: app_meetme.c:805
static int meetme_stasis_init(void)
Definition: app_meetme.c:1157
static int conf_exec(struct ast_channel *chan, const char *data)
The meetme() application.
Definition: app_meetme.c:4837
static const char *const app2
Definition: app_meetme.c:803
static int count_exec(struct ast_channel *chan, const char *data)
The MeetmeCount application.
Definition: app_meetme.c:4792
#define EVENT_FLAG_CALL
Definition: manager.h:72
static const char *const slastation_app
Definition: app_meetme.c:806
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391
static int action_meetmelist(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5521
#define NULL
Definition: resample.c:96
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: main/config.c:3382
static enum ast_device_state sla_state(const char *data)
Definition: app_meetme.c:7326
static struct ast_custom_function meetme_info_acf
Definition: app_meetme.c:7992
static enum ast_device_state meetmestate(const char *data)
Callback for devicestate providers.
Definition: app_meetme.c:5750
static int sla_station_exec(struct ast_channel *chan, const char *data)
Definition: app_meetme.c:7006
static int action_meetmemute(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5511
static int sla_trunk_exec(struct ast_channel *chan, const char *data)
Definition: app_meetme.c:7228
static struct ast_cli_entry cli_meetme[]
Definition: app_meetme.c:2290
static const char *const app3
Definition: app_meetme.c:804
static const char *const slatrunk_app
Definition: app_meetme.c:807
static const char *const app
Definition: app_meetme.c:802
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int load_config(int reload)
Definition: app_meetme.c:7998
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:5225
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
static int channel_admin_exec(struct ast_channel *chan, const char *data)
The MeetMeChannelAdmin application MeetMeChannelAdmin(channel, command)
Definition: app_meetme.c:5390
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ meetme_cmd_helper()

static char* meetme_cmd_helper ( struct ast_cli_args a)
static

Definition at line 1996 of file app_meetme.c.

References admin_exec(), ast_cli_args::argv, ast_debug, ast_free, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, MAX_CONFNUM, NULL, and strcasestr().

Referenced by meetme_kick_cmd(), meetme_lock_cmd(), and meetme_mute_cmd().

1997 {
1998  /* Process the command */
1999  struct ast_str *cmdline;
2000 
2001  /* Max confno length */
2002  if (!(cmdline = ast_str_create(MAX_CONFNUM))) {
2003  return CLI_FAILURE;
2004  }
2005 
2006  ast_str_set(&cmdline, 0, "%s", a->argv[2]); /* Argv 2: conference number */
2007  if (strcasestr(a->argv[1], "lock")) {
2008  if (strcasecmp(a->argv[1], "lock") == 0) {
2009  /* Lock */
2010  ast_str_append(&cmdline, 0, ",L");
2011  } else {
2012  /* Unlock */
2013  ast_str_append(&cmdline, 0, ",l");
2014  }
2015  } else if (strcasestr(a->argv[1], "mute")) {
2016  if (strcasecmp(a->argv[1], "mute") == 0) {
2017  /* Mute */
2018  if (strcasecmp(a->argv[3], "all") == 0) {
2019  ast_str_append(&cmdline, 0, ",N");
2020  } else {
2021  ast_str_append(&cmdline, 0, ",M,%s", a->argv[3]);
2022  }
2023  } else {
2024  /* Unmute */
2025  if (strcasecmp(a->argv[3], "all") == 0) {
2026  ast_str_append(&cmdline, 0, ",n");
2027  } else {
2028  ast_str_append(&cmdline, 0, ",m,%s", a->argv[3]);
2029  }
2030  }
2031  } else if (strcasecmp(a->argv[1], "kick") == 0) {
2032  if (strcasecmp(a->argv[3], "all") == 0) {
2033  /* Kick all */
2034  ast_str_append(&cmdline, 0, ",K");
2035  } else {
2036  /* Kick a single user */
2037  ast_str_append(&cmdline, 0, ",k,%s", a->argv[3]);
2038  }
2039  } else {
2040  /*
2041  * Should never get here because it is already filtered by the
2042  * callers.
2043  */
2044  ast_free(cmdline);
2045  return CLI_SHOWUSAGE;
2046  }
2047 
2048  ast_debug(1, "Cmdline: %s\n", ast_str_buffer(cmdline));
2049 
2050  admin_exec(NULL, ast_str_buffer(cmdline));
2051  ast_free(cmdline);
2052 
2053  return CLI_SUCCESS;
2054 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char *const * argv
Definition: cli.h:161
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * strcasestr(const char *, const char *)
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
#define CLI_SUCCESS
Definition: cli.h:44
#define MAX_CONFNUM
Definition: app_meetme.c:819
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:5225
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ meetme_kick_cmd()

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

Definition at line 2076 of file app_meetme.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_meetmecmd_mute_kick(), ast_cli_args::line, meetme_cmd_helper(), ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

2077 {
2078  switch (cmd) {
2079  case CLI_INIT:
2080  e->command = "meetme kick";
2081  e->usage =
2082  "Usage: meetme kick <confno> all|<userno>\n"
2083  " Kick a conference or a user in a conference.\n";
2084  return NULL;
2085  case CLI_GENERATE:
2086  return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
2087  }
2088 
2089  if (a->argc != 4) {
2090  return CLI_SHOWUSAGE;
2091  }
2092 
2093  return meetme_cmd_helper(a);
2094 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
static char * complete_meetmecmd_mute_kick(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1766
const char * line
Definition: cli.h:162
const int n
Definition: cli.h:165
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1996
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
const int pos
Definition: cli.h:164

◆ meetme_lock_cmd()

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

Definition at line 2056 of file app_meetme.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_meetmecmd_lock(), meetme_cmd_helper(), ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

2057 {
2058  switch (cmd) {
2059  case CLI_INIT:
2060  e->command = "meetme {lock|unlock}";
2061  e->usage =
2062  "Usage: meetme lock|unlock <confno>\n"
2063  " Lock or unlock a conference to new users.\n";
2064  return NULL;
2065  case CLI_GENERATE:
2066  return complete_meetmecmd_lock(a->word, a->pos, a->n);
2067  }
2068 
2069  if (a->argc != 3) {
2070  return CLI_SHOWUSAGE;
2071  }
2072 
2073  return meetme_cmd_helper(a);
2074 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const int n
Definition: cli.h:165
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1996
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
const int pos
Definition: cli.h:164
static char * complete_meetmecmd_lock(const char *word, int pos, int state)
Definition: app_meetme.c:1806

◆ meetme_menu()

static void meetme_menu ( enum menu_modes menu_mode,
int *  dtmf,
struct ast_conference conf,
struct ast_flags64 confflags,
struct ast_channel chan,
struct ast_conf_user user,
char *  recordingtmp,
int  recordingtmp_size,
struct ast_format_cap cap_slin 
)
static

Definition at line 3153 of file app_meetme.c.

References meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), MENU_ADMIN, MENU_ADMIN_EXTENDED, MENU_DISABLED, and MENU_NORMAL.

Referenced by conf_run().

3157 {
3158  switch (*menu_mode) {
3159  case MENU_DISABLED:
3160  break;
3161  case MENU_NORMAL:
3162  meetme_menu_normal(menu_mode, dtmf, conf, confflags, chan, user);
3163  break;
3164  case MENU_ADMIN:
3165  meetme_menu_admin(menu_mode, dtmf, conf, confflags, chan, user);
3166  /* Admin Menu is capable of branching into another menu, in which case it will reset dtmf and change the menu mode. */
3167  if (*menu_mode != MENU_ADMIN_EXTENDED || (*dtmf <= 0)) {
3168  break;
3169  }
3170  case MENU_ADMIN_EXTENDED:
3171  meetme_menu_admin_extended(menu_mode, dtmf, conf, confflags, chan, user,
3172  recordingtmp, recordingtmp_size, cap_slin);
3173  break;
3174  }
3175 }
static void meetme_menu_normal(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
Definition: app_meetme.c:2766
static void meetme_menu_admin(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user)
Definition: app_meetme.c:2846
static void meetme_menu_admin_extended(enum menu_modes *menu_mode, int *dtmf, struct ast_conference *conf, struct ast_flags64 *confflags, struct ast_channel *chan, struct ast_conf_user *user, char *recordingtmp, int recordingtmp_size, struct ast_format_cap *cap_slin)
Definition: app_meetme.c:2966

◆ meetme_menu_admin()

static void meetme_menu_admin ( enum menu_modes menu_mode,
int *  dtmf,
struct ast_conference conf,
struct ast_flags64 confflags,
struct ast_channel chan,
struct ast_conf_user user 
)
static

Definition at line 2846 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ast_conf_user::adminflags, ao2_callback, ao2_find, ao2_ref, ast_channel_language(), ast_channel_name(), AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), ast_test_flag64, ast_waitstream(), ast_conf_user::chan, CONFFLAG_ADMIN, CONFFLAG_MONITOR, ast_conference::confno, ast_conference::locked, MENU_ADMIN_EXTENDED, MENU_DISABLED, NULL, OBJ_NODATA, rt_extend_conf(), tweak_listen_volume(), tweak_talk_volume(), user_max_cmp(), ast_conference::usercontainer, ast_conf_user::userflags, VOL_DOWN, and VOL_UP.

Referenced by meetme_menu().

2847 {
2848  switch(*dtmf) {
2849  case '1': /* Un/Mute */
2850  *menu_mode = MENU_DISABLED;
2851  /* for admin, change both admin and use flags */
2854  } else {
2856  }
2857 
2859  if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
2860  ast_waitstream(chan, "");
2861  }
2862  } else {
2863  if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
2864  ast_waitstream(chan, "");
2865  }
2866  }
2867  break;
2868 
2869  case '2': /* Un/Lock the Conference */
2870  *menu_mode = MENU_DISABLED;
2871  if (conf->locked) {
2872  conf->locked = 0;
2873  if (!ast_streamfile(chan, "conf-unlockednow", ast_channel_language(chan))) {
2874  ast_waitstream(chan, "");
2875  }
2876  } else {
2877  conf->locked = 1;
2878  if (!ast_streamfile(chan, "conf-lockednow", ast_channel_language(chan))) {
2879  ast_waitstream(chan, "");
2880  }
2881  }
2882  break;
2883 
2884  case '3': /* Eject last user */
2885  {
2886  struct ast_conf_user *usr = NULL;
2887  int max_no = 0;
2889  *menu_mode = MENU_DISABLED;
2890  usr = ao2_find(conf->usercontainer, &max_no, 0);
2892  if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
2893  ast_waitstream(chan, "");
2894  }
2895  } else {
2896  usr->adminflags |= ADMINFLAG_KICKME;
2897  }
2898  ao2_ref(usr, -1);
2899  ast_stopstream(chan);
2900  break;
2901  }
2902 
2903  case '4':
2905  break;
2906 
2907  case '5':
2908  /* Extend RT conference */
2909  if (rt_schedule) {
2910  if (!rt_extend_conf(conf->confno)) {
2911  if (!ast_streamfile(chan, "conf-extended", ast_channel_language(chan))) {
2912  ast_waitstream(chan, "");
2913  }
2914  } else {
2915  if (!ast_streamfile(chan, "conf-nonextended", ast_channel_language(chan))) {
2916  ast_waitstream(chan, "");
2917  }
2918  }
2919  ast_stopstream(chan);
2920  }
2921  *menu_mode = MENU_DISABLED;
2922  break;
2923 
2924  case '6':
2925  tweak_listen_volume(user, VOL_UP);
2926  break;
2927 
2928  case '7':
2929  tweak_talk_volume(user, VOL_DOWN);
2930  break;
2931 
2932  case '8':
2933  if (!ast_streamfile(chan, "conf-adminmenu-menu8", ast_channel_language(chan))) {
2934  /* If the user provides DTMF while playing the sound, we want to drop right into the extended menu function with new DTMF once we get out of here. */
2935  *dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
2936  ast_stopstream(chan);
2937  }
2938  *menu_mode = MENU_ADMIN_EXTENDED;
2939  break;
2940 
2941  case '9':
2942  tweak_talk_volume(user, VOL_UP);
2943  break;
2944  default:
2945  *menu_mode = MENU_DISABLED;
2946  /* Play an error message! */
2947  if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
2948  ast_waitstream(chan, "");
2949  }
2950  break;
2951  }
2952 
2953 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1494
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2523
#define AST_DIGIT_ANY
Definition: file.h:48
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
unsigned int locked
Definition: app_meetme.c:858
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1579
static int rt_schedule
Definition: app_meetme.c:810
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1506
struct ast_flags64 userflags
Definition: app_meetme.c:898
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * usercontainer
Definition: app_meetme.c:875
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
struct ast_channel * chan
Definition: app_meetme.c:900
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ meetme_menu_admin_extended()

static void meetme_menu_admin_extended ( enum menu_modes menu_mode,
int *  dtmf,
struct ast_conference conf,
struct ast_flags64 confflags,
struct ast_channel chan,
struct ast_conf_user user,
char *  recordingtmp,
int  recordingtmp_size,
struct ast_format_cap cap_slin 
)
static

Definition at line 2966 of file app_meetme.c.

References ao2_callback, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_fd(), ast_channel_language(), ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, AST_DIGIT_ANY, ast_fileexists(), ast_format_slin, ast_hangup(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_detached_background, AST_PTHREADT_NULL, ast_request(), ast_say_number(), ast_set_flag64, ast_set_read_format(), ast_set_write_format(), ast_stopstream(), ast_strdup, ast_streamfile(), ast_test_flag64, ast_verb, ast_waitstream(), CONFFLAG_RECORDCONF, ast_conference::confno, ast_conference::dahdiconf, ast_conference::gmuted, ast_conference::lchan, LOG_WARNING, MEETME_RECORD_ACTIVE, MENU_DISABLED, ast_conf_user::namerecloc, NULL, OBJ_NODATA, pbx_builtin_getvar_helper(), ast_conference::recording, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthread, ast_conference::recordthreadlock, user_set_kickme_cb(), user_set_muted_cb(), user_set_unmuted_cb(), ast_conference::usercontainer, ast_conference::users, and var.

Referenced by meetme_menu().

2970 {
2971  int keepplaying;
2972  int playednamerec;
2973  int res;
2974  struct ao2_iterator user_iter;
2975  struct ast_conf_user *usr = NULL;
2976 
2977  switch(*dtmf) {
2978  case '1': /* *81 Roll call */
2979  keepplaying = 1;
2980  playednamerec = 0;
2981  if (conf->users == 1) {
2982  if (keepplaying && !ast_streamfile(chan, "conf-onlyperson", ast_channel_language(chan))) {
2983  res = ast_waitstream(chan, AST_DIGIT_ANY);
2984  ast_stopstream(chan);
2985  if (res > 0) {
2986  keepplaying = 0;
2987  }
2988  }
2989  } else if (conf->users == 2) {
2990  if (keepplaying && !ast_streamfile(chan, "conf-onlyone", ast_channel_language(chan))) {
2991  res = ast_waitstream(chan, AST_DIGIT_ANY);
2992  ast_stopstream(chan);
2993  if (res > 0) {
2994  keepplaying = 0;
2995  }
2996  }
2997  } else {
2998  if (keepplaying && !ast_streamfile(chan, "conf-thereare", ast_channel_language(chan))) {
2999  res = ast_waitstream(chan, AST_DIGIT_ANY);
3000  ast_stopstream(chan);
3001  if (res > 0) {
3002  keepplaying = 0;
3003  }
3004  }
3005  if (keepplaying) {
3006  res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL);
3007  ast_stopstream(chan);
3008  if (res > 0) {
3009  keepplaying = 0;
3010  }
3011  }
3012  if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", ast_channel_language(chan))) {
3013  res = ast_waitstream(chan, AST_DIGIT_ANY);
3014  ast_stopstream(chan);
3015  if (res > 0) {
3016  keepplaying = 0;
3017  }
3018  }
3019  }
3020  user_iter = ao2_iterator_init(conf->usercontainer, 0);
3021  while((usr = ao2_iterator_next(&user_iter))) {
3022  if (ast_fileexists(usr->namerecloc, NULL, NULL)) {
3023  if (keepplaying && !ast_streamfile(chan, usr->namerecloc, ast_channel_language(chan))) {
3024  res = ast_waitstream(chan, AST_DIGIT_ANY);
3025  ast_stopstream(chan);
3026  if (res > 0) {
3027  keepplaying = 0;
3028  }
3029  }
3030  playednamerec = 1;
3031  }
3032  ao2_ref(usr, -1);
3033  }
3034  ao2_iterator_destroy(&user_iter);
3035  if (keepplaying && playednamerec && !ast_streamfile(chan, "conf-roll-callcomplete", ast_channel_language(chan))) {
3036  res = ast_waitstream(chan, AST_DIGIT_ANY);
3037  ast_stopstream(chan);
3038  if (res > 0) {
3039  keepplaying = 0;
3040  }
3041  }
3042 
3043  *menu_mode = MENU_DISABLED;
3044  break;
3045 
3046  case '2': /* *82 Eject all non-admins */
3047  if (conf->users == 1) {
3048  if(!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
3049  ast_waitstream(chan, "");
3050  }
3051  } else {
3053  }
3054  ast_stopstream(chan);
3055  *menu_mode = MENU_DISABLED;
3056  break;
3057 
3058  case '3': /* *83 (Admin) mute/unmute all non-admins */
3059  if(conf->gmuted) {
3060  conf->gmuted = 0;
3062  if (!ast_streamfile(chan, "conf-now-unmuted", ast_channel_language(chan))) {
3063  ast_waitstream(chan, "");
3064  }
3065  } else {
3066  conf->gmuted = 1;
3068  if (!ast_streamfile(chan, "conf-now-muted", ast_channel_language(chan))) {
3069  ast_waitstream(chan, "");
3070  }
3071  }
3072  ast_stopstream(chan);
3073  *menu_mode = MENU_DISABLED;
3074  break;
3075 
3076  case '4': /* *84 Record conference */
3077  if (conf->recording != MEETME_RECORD_ACTIVE) {
3078  ast_set_flag64(confflags, CONFFLAG_RECORDCONF);
3079  if (!conf->recordingfilename) {
3080  const char *var;
3081  ast_channel_lock(chan);
3082  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
3083  conf->recordingfilename = ast_strdup(var);
3084  }
3085  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
3086  conf->recordingformat = ast_strdup(var);
3087  }
3088  ast_channel_unlock(chan);
3089  if (!conf->recordingfilename) {
3090  snprintf(recordingtmp, recordingtmp_size, "meetme-conf-rec-%s-%s", conf->confno, ast_channel_uniqueid(chan));
3091  conf->recordingfilename = ast_strdup(recordingtmp);
3092  }
3093  if (!conf->recordingformat) {
3094  conf->recordingformat = ast_strdup("wav");
3095  }
3096  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
3097  conf->confno, conf->recordingfilename, conf->recordingformat);
3098  }
3099 
3101  if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL)))) {
3102  struct dahdi_confinfo dahdic;
3103 
3106  dahdic.chan = 0;
3107  dahdic.confno = conf->dahdiconf;
3108  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
3109  if (ioctl(ast_channel_fd(conf->lchan, 0), DAHDI_SETCONF, &dahdic)) {
3110  ast_log(LOG_WARNING, "Error starting listen channel\n");
3111  ast_hangup(conf->lchan);
3112  conf->lchan = NULL;
3113  } else {
3115  }
3116  }
3118  if (!ast_streamfile(chan, "conf-now-recording", ast_channel_language(chan))) {
3119  ast_waitstream(chan, "");
3120  }
3121  }
3122 
3123  ast_stopstream(chan);
3124  *menu_mode = MENU_DISABLED;
3125  break;
3126 
3127  case '8': /* *88 Exit the menu and return to the conference... without an error message */
3128  ast_stopstream(chan);
3129  *menu_mode = MENU_DISABLED;
3130  break;
3131 
3132  default:
3133  if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
3134  ast_waitstream(chan, "");
3135  }
3136  ast_stopstream(chan);
3137  *menu_mode = MENU_DISABLED;
3138  break;
3139  }
3140 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int user_set_unmuted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2727
#define AST_DIGIT_ANY
Definition: file.h:48
pthread_t recordthread
Definition: app_meetme.c:860
static void * recordthread(void *args)
Definition: app_meetme.c:5681
#define LOG_WARNING
Definition: logger.h:274
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
char * recordingformat
Definition: app_meetme.c:864
#define var
Definition: ast_expr2f.c:614
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
#define ast_verb(level,...)
Definition: logger.h:463
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
unsigned int gmuted
Definition: app_meetme.c:859
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6444
static int user_set_kickme_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2716
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#define AST_PTHREADT_NULL
Definition: lock.h:66
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
const char * ast_channel_uniqueid(const struct ast_channel *chan)
enum recording_state recording
Definition: app_meetme.c:856
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_channel_unlock(chan)
Definition: channel.h:2946
char namerecloc[PATH_MAX]
Definition: app_meetme.c:904
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ao2_container * usercontainer
Definition: app_meetme.c:875
int ast_channel_fd(const struct ast_channel *chan, int which)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8337
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
const char * ast_channel_language(const struct ast_channel *chan)
char * recordingfilename
Definition: app_meetme.c:863
struct ast_channel * lchan
Definition: app_meetme.c:847
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
static int user_set_muted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2738
#define ast_mutex_unlock(a)
Definition: lock.h:188
ast_mutex_t recordthreadlock
Definition: app_meetme.c:861
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ meetme_menu_normal()

static void meetme_menu_normal ( enum menu_modes menu_mode,
int *  dtmf,
struct ast_conference conf,
struct ast_flags64 confflags,
struct ast_channel chan,
struct ast_conf_user user 
)
static

Definition at line 2766 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ast_channel_language(), ast_streamfile(), ast_test_flag64, ast_waitstream(), CONFFLAG_MONITOR, ast_conference::confno, MENU_DISABLED, rt_extend_conf(), tweak_listen_volume(), tweak_talk_volume(), VOL_DOWN, and VOL_UP.

Referenced by meetme_menu().

2767 {
2768  switch (*dtmf) {
2769  case '1': /* Un/Mute */
2770  *menu_mode = MENU_DISABLED;
2771 
2772  /* user can only toggle the self-muted state */
2774 
2775  /* they can't override the admin mute state */
2777  if (!ast_streamfile(chan, "conf-muted", ast_channel_language(chan))) {
2778  ast_waitstream(chan, "");
2779  }
2780  } else {
2781  if (!ast_streamfile(chan, "conf-unmuted", ast_channel_language(chan))) {
2782  ast_waitstream(chan, "");
2783  }
2784  }
2785  break;
2786 
2787  case '2':
2788  *menu_mode = MENU_DISABLED;
2791  }
2792 
2793  if (user->adminflags & ADMINFLAG_T_REQUEST) {
2794  if (!ast_streamfile(chan, "beep", ast_channel_language(chan))) {
2795  ast_waitstream(chan, "");
2796  }
2797  }
2798  break;
2799 
2800  case '4':
2802  break;
2803  case '5':
2804  /* Extend RT conference */
2805  if (rt_schedule) {
2806  rt_extend_conf(conf->confno);
2807  }
2808  *menu_mode = MENU_DISABLED;
2809  break;
2810 
2811  case '6':
2812  tweak_listen_volume(user, VOL_UP);
2813  break;
2814 
2815  case '7':
2816  tweak_talk_volume(user, VOL_DOWN);
2817  break;
2818 
2819  case '8':
2820  *menu_mode = MENU_DISABLED;
2821  break;
2822 
2823  case '9':
2824  tweak_talk_volume(user, VOL_UP);
2825  break;
2826 
2827  default:
2828  *menu_mode = MENU_DISABLED;
2829  if (!ast_streamfile(chan, "conf-errormenu", ast_channel_language(chan))) {
2830  ast_waitstream(chan, "");
2831  }
2832  break;
2833  }
2834 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1494
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2523
static int rt_schedule
Definition: app_meetme.c:810
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1506
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ meetme_mute_cmd()

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

Definition at line 2096 of file app_meetme.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_meetmecmd_mute_kick(), ast_cli_args::line, meetme_cmd_helper(), ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

2097 {
2098  switch (cmd) {
2099  case CLI_INIT:
2100  e->command = "meetme {mute|unmute}";
2101  e->usage =
2102  "Usage: meetme mute|unmute <confno> all|<userno>\n"
2103  " Mute or unmute a conference or a user in a conference.\n";
2104  return NULL;
2105  case CLI_GENERATE:
2106  return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
2107  }
2108 
2109  if (a->argc != 4) {
2110  return CLI_SHOWUSAGE;
2111  }
2112 
2113  return meetme_cmd_helper(a);
2114 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
static char * complete_meetmecmd_mute_kick(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1766
const char * line
Definition: cli.h:162
const int n
Definition: cli.h:165
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1996
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
const int pos
Definition: cli.h:164

◆ meetme_set_defaults()

static void meetme_set_defaults ( void  )
static

Definition at line 5772 of file app_meetme.c.

References DEFAULT_AUDIO_BUFFERS.

Referenced by load_config_meetme().

5773 {
5774  /* Scheduling support is off by default */
5775  rt_schedule = 0;
5776  fuzzystart = 0;
5777  earlyalert = 0;
5778  endalert = 0;
5779  extendby = 0;
5780 
5781  /* Logging of participants defaults to ON for compatibility reasons */
5782  rt_log_members = 1;
5783 
5784  /* Set default number of buffers to be allocated. */
5786 }
static int fuzzystart
Definition: app_meetme.c:811
static int endalert
Definition: app_meetme.c:813
static int earlyalert
Definition: app_meetme.c:812
static int rt_schedule
Definition: app_meetme.c:810
#define DEFAULT_AUDIO_BUFFERS
Definition: app_meetme.c:647
static int rt_log_members
Definition: app_meetme.c:817
static int extendby
Definition: app_meetme.c:814
static int audio_buffers
The number of audio buffers to be allocated on pseudo channels when in a conference.
Definition: app_meetme.c:1106

◆ meetme_show_cmd()

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

Definition at line 1853 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_channel_caller(), ast_channel_name(), ast_cli(), ast_free, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_str_buffer(), ast_str_create, ast_str_set(), ast_test_flag64, ast_conf_user::chan, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_meetmecmd_list(), CONFFLAG_ADMIN, CONFFLAG_MONITOR, ast_conference::confno, ast_cli_args::fd, ast_party_caller::id, ast_conference::isdynamic, istalking(), ast_conf_user::jointime, ast_cli_args::line, ast_conference::locked, ast_conference::markedusers, MC_DATA_FORMAT, MC_HEADER_FORMAT, min, ast_cli_args::n, ast_party_id::name, NULL, ast_party_id::number, ast_cli_args::pos, S_COR, ast_conference::start, ast_party_name::str, ast_party_number::str, STR_CONCISE, ast_conf_user::talking, total, ast_cli_entry::usage, user, ast_conf_user::user_no, ast_conference::usercontainer, ast_conf_user::userflags, ast_conference::users, ast_party_name::valid, ast_party_number::valid, and ast_cli_args::word.

1854 {
1855  /* Process the command */
1856  struct ast_conf_user *user;
1857  struct ast_conference *cnf;
1858  int hr, min, sec;
1859  int total = 0;
1860  time_t now;
1861 #define MC_HEADER_FORMAT "%-14s %-14s %-10s %-8s %-8s %-6s\n"
1862 #define MC_DATA_FORMAT "%-12.12s %4.4d %4.4s %02d:%02d:%02d %-8s %-6s\n"
1863 
1864  switch (cmd) {
1865  case CLI_INIT:
1866  e->command = "meetme list";
1867  e->usage =
1868  "Usage: meetme list [<confno>] [" STR_CONCISE "]\n"
1869  " List all conferences or a specific conference.\n";
1870  return NULL;
1871  case CLI_GENERATE:
1872  return complete_meetmecmd_list(a->line, a->word, a->pos, a->n);
1873  }
1874 
1875  if (a->argc == 2 || (a->argc == 3 && !strcasecmp(a->argv[2], STR_CONCISE))) {
1876  /* List all the conferences */
1877  int concise = (a->argc == 3);
1878  struct ast_str *marked_users;
1879 
1880  if (!(marked_users = ast_str_create(30))) {
1881  return CLI_FAILURE;
1882  }
1883 
1884  now = time(NULL);
1885  AST_LIST_LOCK(&confs);
1886  if (AST_LIST_EMPTY(&confs)) {
1887  if (!concise) {
1888  ast_cli(a->fd, "No active MeetMe conferences.\n");
1889  }
1891  ast_free(marked_users);
1892  return CLI_SUCCESS;
1893  }
1894  if (!concise) {
1895  ast_cli(a->fd, MC_HEADER_FORMAT, "Conf Num", "Parties", "Marked", "Activity", "Creation", "Locked");
1896  }
1897  AST_LIST_TRAVERSE(&confs, cnf, list) {
1898  hr = (now - cnf->start) / 3600;
1899  min = ((now - cnf->start) % 3600) / 60;
1900  sec = (now - cnf->start) % 60;
1901  if (!concise) {
1902  if (cnf->markedusers == 0) {
1903  ast_str_set(&marked_users, 0, "N/A ");
1904  } else {
1905  ast_str_set(&marked_users, 0, "%4.4d", cnf->markedusers);
1906  }
1907  ast_cli(a->fd, MC_DATA_FORMAT, cnf->confno, cnf->users,
1908  ast_str_buffer(marked_users), hr, min, sec,
1909  cnf->isdynamic ? "Dynamic" : "Static", cnf->locked ? "Yes" : "No");
1910  } else {
1911  ast_cli(a->fd, "%s!%d!%d!%02d:%02d:%02d!%d!%d\n",
1912  cnf->confno,
1913  cnf->users,
1914  cnf->markedusers,
1915  hr, min, sec,
1916  cnf->isdynamic,
1917  cnf->locked);
1918  }
1919 
1920  total += cnf->users;
1921  }
1923  if (!concise) {
1924  ast_cli(a->fd, "* Total number of MeetMe users: %d\n", total);
1925  }
1926  ast_free(marked_users);
1927  return CLI_SUCCESS;
1928  }
1929  if (a->argc == 3 || (a->argc == 4 && !strcasecmp(a->argv[3], STR_CONCISE))) {
1930  struct ao2_iterator user_iter;
1931  int concise = (a->argc == 4);
1932 
1933  /* List all the users in a conference */
1934  if (AST_LIST_EMPTY(&confs)) {
1935  if (!concise) {
1936  ast_cli(a->fd, "No active MeetMe conferences.\n");
1937  }
1938  return CLI_SUCCESS;
1939  }
1940  /* Find the right conference */
1941  AST_LIST_LOCK(&confs);
1942  AST_LIST_TRAVERSE(&confs, cnf, list) {
1943  if (strcmp(cnf->confno, a->argv[2]) == 0) {
1944  break;
1945  }
1946  }
1947  if (!cnf) {
1948  if (!concise)
1949  ast_cli(a->fd, "No such conference: %s.\n", a->argv[2]);
1951  return CLI_SUCCESS;
1952  }
1953  /* Show all the users */
1954  time(&now);
1955  user_iter = ao2_iterator_init(cnf->usercontainer, 0);
1956  while((user = ao2_iterator_next(&user_iter))) {
1957  hr = (now - user->jointime) / 3600;
1958  min = ((now - user->jointime) % 3600) / 60;
1959  sec = (now - user->jointime) % 60;
1960  if (!concise) {
1961  ast_cli(a->fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %s %02d:%02d:%02d\n",
1962  user->user_no,
1963  S_COR(ast_channel_caller(user->chan)->id.number.valid, ast_channel_caller(user->chan)->id.number.str, "<unknown>"),
1964  S_COR(ast_channel_caller(user->chan)->id.name.valid, ast_channel_caller(user->chan)->id.name.str, "<no name>"),
1965  ast_channel_name(user->chan),
1966  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "(Admin)" : "",
1967  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "(Listen only)" : "",
1968  user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : user->adminflags & ADMINFLAG_SELFMUTED ? "(Muted)" : "",
1969  user->adminflags & ADMINFLAG_T_REQUEST ? "(Request to Talk)" : "",
1970  istalking(user->talking), hr, min, sec);
1971  } else {
1972  ast_cli(a->fd, "%d!%s!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
1973  user->user_no,
1976  ast_channel_name(user->chan),
1977  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "1" : "",
1978  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "1" : "",
1979  user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED) ? "1" : "",
1980  user->adminflags & ADMINFLAG_T_REQUEST ? "1" : "",
1981  user->talking, hr, min, sec);
1982  }
1983  ao2_ref(user, -1);
1984  }
1985  ao2_iterator_destroy(&user_iter);
1986  if (!concise) {
1987  ast_cli(a->fd, "%d users in that conference.\n", cnf->users);
1988  }
1990  return CLI_SUCCESS;
1991  }
1992  return CLI_SHOWUSAGE;
1993 }
static char user[512]
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static char * complete_meetmecmd_list(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1814
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define STR_CONCISE
Definition: app_meetme.c:644
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
static const char * istalking(int x)
Definition: app_meetme.c:1398
const int argc
Definition: cli.h:160
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:857
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: cli.h:152
char * str
Subscriber name (Malloced)
Definition: channel.h:265
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int locked
Definition: app_meetme.c:858
const char * line
Definition: cli.h:162
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const char *const * argv
Definition: cli.h:161
struct ast_flags64 userflags
Definition: app_meetme.c:898
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
#define MC_HEADER_FORMAT
const char * word
Definition: cli.h:163
struct ao2_container * usercontainer
Definition: app_meetme.c:875
time_t jointime
Definition: app_meetme.c:905
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const char * ast_channel_name(const struct ast_channel *chan)
const int pos
Definition: cli.h:164
static int total
Definition: res_adsi.c:968
#define MC_DATA_FORMAT
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
The MeetMe Conference object.
Definition: app_meetme.c:842
#define min(a, b)
Definition: f2c.h:197
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_channel * chan
Definition: app_meetme.c:900
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ meetme_stasis_cb()

static void meetme_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 1226 of file app_meetme.c.

References ast_assert, ast_free, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_str_append_event_header(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_channel_blob::blob, EVENT_FLAG_CALL, manager_event, NULL, RAII_VAR, ast_channel_blob::snapshot, stasis_message_data(), stasis_message_type(), and status.

Referenced by meetme_stasis_init().

1228 {
1229  struct ast_channel_blob *channel_blob = stasis_message_data(message);
1230  struct stasis_message_type *message_type;
1231  const char *event;
1232  const char *conference_num;
1233  const char *status;
1234  struct ast_json *json_cur;
1235  RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
1236  RAII_VAR(struct ast_str *, extra_text, NULL, ast_free);
1237 
1238  if (!channel_blob) {
1239  ast_assert(0);
1240  return;
1241  }
1242 
1243  message_type = stasis_message_type(message);
1244 
1245  if (!message_type) {
1246  ast_assert(0);
1247  return;
1248  }
1249 
1250  if (message_type == meetme_join_type()) {
1251  event = "MeetmeJoin";
1252  } else if (message_type == meetme_leave_type()) {
1253  event = "MeetmeLeave";
1254  } else if (message_type == meetme_end_type()) {
1255  event = "MeetmeEnd";
1256  } else if (message_type == meetme_mute_type()) {
1257  event = "MeetmeMute";
1258  } else if (message_type == meetme_talking_type()) {
1259  event = "MeetmeTalking";
1260  } else if (message_type == meetme_talk_request_type()) {
1261  event = "MeetmeTalkRequest";
1262  } else {
1263  ast_assert(0);
1264  return;
1265  }
1266 
1267  if (!event) {
1268  ast_assert(0);
1269  return;
1270  }
1271 
1272  conference_num = ast_json_string_get(ast_json_object_get(channel_blob->blob, "Meetme"));
1273  if (!conference_num) {
1274  ast_assert(0);
1275  return;
1276  }
1277 
1278  status = ast_json_string_get(ast_json_object_get(channel_blob->blob, "status"));
1279  if (status) {
1280  ast_str_append_event_header(&extra_text, "Status", status);
1281  }
1282 
1283  if (channel_blob->snapshot) {
1284  channel_text = ast_manager_build_channel_state_string(channel_blob->snapshot);
1285  }
1286 
1287  if ((json_cur = ast_json_object_get(channel_blob->blob, "user"))) {
1288  int user_number = ast_json_integer_get(json_cur);
1289  RAII_VAR(struct ast_str *, user_prop_str, ast_str_create(32), ast_free);
1290  if (!user_prop_str) {
1291  return;
1292  }
1293 
1294  ast_str_set(&user_prop_str, 0, "%d", user_number);
1295  ast_str_append_event_header(&extra_text, "User", ast_str_buffer(user_prop_str));
1296 
1297  if ((json_cur = ast_json_object_get(channel_blob->blob, "duration"))) {
1298  int duration = ast_json_integer_get(json_cur);
1299  ast_str_set(&user_prop_str, 0, "%d", duration);
1300  ast_str_append_event_header(&extra_text, "Duration", ast_str_buffer(user_prop_str));
1301  }
1302 
1303  json_cur = NULL;
1304  }
1305 
1307  "Meetme: %s\r\n"
1308  "%s"
1309  "%s",
1310  conference_num,
1311  channel_text ? ast_str_buffer(channel_text) : "",
1312  extra_text ? ast_str_buffer(extra_text) : "");
1313 }
struct ast_json * blob
struct ast_channel_snapshot * snapshot
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define EVENT_FLAG_CALL
Definition: manager.h:72
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Definition: astman.c:222
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
Blob of data associated with a channel.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define 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
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define ast_free(a)
Definition: astmm.h:182
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322
int ast_str_append_event_header(struct ast_str **fields_string, const char *header, const char *value)
append an event header to an ast string
Definition: manager.c:9705
jack_status_t status
Definition: app_jack.c:146
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ meetme_stasis_cleanup()

static void meetme_stasis_cleanup ( void  )
static

Definition at line 1142 of file app_meetme.c.

References NULL, stasis_message_router_unsubscribe(), and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by meetme_stasis_init(), and unload_module().

1143 {
1147  }
1148 
1149  STASIS_MESSAGE_TYPE_CLEANUP(meetme_join_type);
1150  STASIS_MESSAGE_TYPE_CLEANUP(meetme_leave_type);
1151  STASIS_MESSAGE_TYPE_CLEANUP(meetme_end_type);
1152  STASIS_MESSAGE_TYPE_CLEANUP(meetme_mute_type);
1153  STASIS_MESSAGE_TYPE_CLEANUP(meetme_talking_type);
1154  STASIS_MESSAGE_TYPE_CLEANUP(meetme_talk_request_type);
1155 }
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
static struct stasis_message_router * meetme_event_message_router
Definition: app_meetme.c:1130
#define NULL
Definition: resample.c:96
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.

◆ meetme_stasis_generate_msg()

static void meetme_stasis_generate_msg ( struct ast_conference meetme_conference,
struct ast_channel chan,
struct ast_conf_user user,
struct stasis_message_type message_type,
struct ast_json extras 
)
static

Definition at line 1343 of file app_meetme.c.

References admin_exec(), ao2_cleanup, args, ast_channel_blob_create(), ast_channel_lock, ast_channel_topic(), ast_channel_unlock, ast_json_integer_create(), ast_json_object_set(), ast_json_object_update(), ast_json_pack(), ast_json_unref(), ast_tvnow(), ast_conference::confno, ast_conf_user::jointime, NULL, RAII_VAR, recordthread(), stasis_publish(), and ast_conf_user::user_no.

Referenced by conf_free(), conf_run(), and send_talking_event().

1345 {
1346  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
1347  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1348 
1349  json_object = ast_json_pack("{s: s}",
1350  "Meetme", meetme_conference->confno);
1351 
1352  if (!json_object) {
1353  return;
1354  }
1355 
1356  if (extras) {
1357  ast_json_object_update(json_object, extras);
1358  }
1359 
1360  if (user) {
1361  struct timeval now = ast_tvnow();
1362  long duration = (long)(now.tv_sec - user->jointime);
1363  struct ast_json *json_user;
1364  struct ast_json *json_user_duration;
1365 
1366  json_user = ast_json_integer_create(user->user_no);
1367  if (!json_user || ast_json_object_set(json_object, "user", json_user)) {
1368  return;
1369  }
1370 
1371  if (duration > 0) {
1372  json_user_duration = ast_json_integer_create(duration);
1373  if (!json_user_duration
1374  || ast_json_object_set(json_object, "duration", json_user_duration)) {
1375  return;
1376  }
1377  }
1378  }
1379 
1380  if (chan) {
1381  ast_channel_lock(chan);
1382  }
1383  msg = ast_channel_blob_create(chan, message_type, json_object);
1384  if (chan) {
1385  ast_channel_unlock(chan);
1386  }
1387 
1388  if (!msg) {
1389  return;
1390  }
1391 
1392  stasis_publish(ast_channel_topic(chan), msg);
1393 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_object_update(struct ast_json *object, struct ast_json *other)
Update object with all of the fields of other.
Definition: json.c:416
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:404
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message * ast_channel_blob_create(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Creates a ast_channel_blob message.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
time_t jointime
Definition: app_meetme.c:905
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845
struct ast_json * ast_json_integer_create(intmax_t value)
Create a JSON integer.
Definition: json.c:317

◆ meetme_stasis_init()

static int meetme_stasis_init ( void  )
static

Definition at line 1157 of file app_meetme.c.

References ast_channel_topic_all(), meetme_stasis_cb(), meetme_stasis_cleanup(), NULL, stasis_message_router_add(), stasis_message_router_create, and STASIS_MESSAGE_TYPE_INIT.

Referenced by load_module().

1158 {
1159 
1160  STASIS_MESSAGE_TYPE_INIT(meetme_join_type);
1161  STASIS_MESSAGE_TYPE_INIT(meetme_leave_type);
1162  STASIS_MESSAGE_TYPE_INIT(meetme_end_type);
1163  STASIS_MESSAGE_TYPE_INIT(meetme_mute_type);
1164  STASIS_MESSAGE_TYPE_INIT(meetme_talking_type);
1165  STASIS_MESSAGE_TYPE_INIT(meetme_talk_request_type);
1166 
1169 
1172  return -1;
1173  }
1174 
1176  meetme_join_type(),
1178  NULL)) {
1180  return -1;
1181  }
1182 
1184  meetme_leave_type(),
1186  NULL)) {
1188  return -1;
1189  }
1190 
1192  meetme_end_type(),
1194  NULL)) {
1196  return -1;
1197  }
1198 
1200  meetme_mute_type(),
1202  NULL)) {
1204  return -1;
1205  }
1206 
1208  meetme_talking_type(),
1210  NULL)) {
1212  return -1;
1213  }
1214 
1216  meetme_talk_request_type(),
1218  NULL)) {
1220  return -1;
1221  }
1222 
1223  return 0;
1224 }
static void meetme_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: app_meetme.c:1226
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
static struct stasis_message_router * meetme_event_message_router
Definition: app_meetme.c:1130
#define NULL
Definition: resample.c:96
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
#define stasis_message_router_create(topic)
static void meetme_stasis_cleanup(void)
Definition: app_meetme.c:1142

◆ meetmemute()

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

Definition at line 5451 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ao2_find, ao2_ref, ast_channel_name(), ast_channel_uniqueid(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_strdupa, ast_strlen_zero, astman_get_header(), astman_send_ack(), astman_send_error(), ast_conf_user::chan, ast_conference::confno, ast_conf_user::list, LOG_NOTICE, user, ast_conf_user::user_no, and ast_conference::usercontainer.

Referenced by action_meetmemute(), and action_meetmeunmute().

5452 {
5453  struct ast_conference *conf;
5454  struct ast_conf_user *user;
5455  const char *confid = astman_get_header(m, "Meetme");
5456  char *userid = ast_strdupa(astman_get_header(m, "Usernum"));
5457  int userno;
5458 
5459  if (ast_strlen_zero(confid)) {
5460  astman_send_error(s, m, "Meetme conference not specified");
5461  return 0;
5462  }
5463 
5464  if (ast_strlen_zero(userid)) {
5465  astman_send_error(s, m, "Meetme user number not specified");
5466  return 0;
5467  }
5468 
5469  userno = strtoul(userid, &userid, 10);
5470 
5471  if (*userid) {
5472  astman_send_error(s, m, "Invalid user number");
5473  return 0;
5474  }
5475 
5476  /* Look in the conference list */
5477  AST_LIST_LOCK(&confs);
5478  AST_LIST_TRAVERSE(&confs, conf, list) {
5479  if (!strcmp(confid, conf->confno))
5480  break;
5481  }
5482 
5483  if (!conf) {
5485  astman_send_error(s, m, "Meetme conference does not exist");
5486  return 0;
5487  }
5488 
5489  user = ao2_find(conf->usercontainer, &userno, 0);
5490 
5491  if (!user) {
5493  astman_send_error(s, m, "User number not found");
5494  return 0;
5495  }
5496 
5497  if (mute)
5498  user->adminflags |= ADMINFLAG_MUTED; /* request user muting */
5499  else
5500  user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED | ADMINFLAG_T_REQUEST); /* request user unmuting */
5501 
5503 
5504  ast_log(LOG_NOTICE, "Requested to %smute conf %s user %d userchan %s uniqueid %s\n", mute ? "" : "un", conf->confno, user->user_no, ast_channel_name(user->chan), ast_channel_uniqueid(user->chan));
5505 
5506  ao2_ref(user, -1);
5507  astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
5508  return 0;
5509 }
static char user[512]
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
struct ast_conf_user::@41 list
static int mute
Definition: chan_alsa.c:144
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
All configuration options for statsd client.
Definition: res_statsd.c:95
#define ast_log
Definition: astobj2.c:42
The MeetMe User object.
Definition: app_meetme.c:896
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * usercontainer
Definition: app_meetme.c:875
const char * ast_channel_name(const struct ast_channel *chan)
The MeetMe Conference object.
Definition: app_meetme.c:842
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
struct ast_channel * chan
Definition: app_meetme.c:900
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ meetmestate()

static enum ast_device_state meetmestate ( const char *  data)
static

Callback for devicestate providers.

Definition at line 5750 of file app_meetme.c.

References AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_conference::confno, ast_conference::list, and ast_conference::users.

Referenced by load_module().

5751 {
5752  struct ast_conference *conf;
5753 
5754  /* Find conference */
5755  AST_LIST_LOCK(&confs);
5756  AST_LIST_TRAVERSE(&confs, conf, list) {
5757  if (!strcmp(data, conf->confno))
5758  break;
5759  }
5761  if (!conf)
5762  return AST_DEVICE_INVALID;
5763 
5764 
5765  /* SKREP to fill */
5766  if (!conf->users)
5767  return AST_DEVICE_NOT_INUSE;
5768 
5769  return AST_DEVICE_INUSE;
5770 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
All configuration options for statsd client.
Definition: res_statsd.c:95
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
The MeetMe Conference object.
Definition: app_meetme.c:842
struct ast_conference::@39 list
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ queue_ringing_trunk()

static struct sla_ringing_trunk* queue_ringing_trunk ( struct sla_trunk trunk)
static

Definition at line 7182 of file app_meetme.c.

References ALL_TRUNK_REFS, ao2_ref, ast_calloc, AST_LIST_INSERT_HEAD, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), NULL, sla_ringing_trunk::ring_begin, sla, sla_change_trunk_state(), SLA_EVENT_RINGING_TRUNK, sla_queue_event(), SLA_TRUNK_STATE_RINGING, and sla_ringing_trunk::trunk.

Referenced by sla_trunk_exec().

7183 {
7184  struct sla_ringing_trunk *ringing_trunk;
7185 
7186  if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk)))) {
7187  return NULL;
7188  }
7189 
7190  ao2_ref(trunk, 1);
7191  ringing_trunk->trunk = trunk;
7192  ringing_trunk->ring_begin = ast_tvnow();
7193 
7195 
7196  ast_mutex_lock(&sla.lock);
7197  AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
7198  ast_mutex_unlock(&sla.lock);
7199 
7201 
7202  return ringing_trunk;
7203 }
static struct @35 sla
A structure for data used by the sla thread.
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2456
struct timeval ring_begin
Definition: app_meetme.c:1066
A trunk that is ringing.
Definition: app_meetme.c:1063
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Definition: search.h:40
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ recordthread()

static void * recordthread ( void *  args)
static

Definition at line 5681 of file app_meetme.c.

References args, ast_closestream(), AST_FILE_MODE, AST_FRAME_BITS, AST_FRAME_VOICE, ast_frdup, ast_frfree, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_read(), ast_stopstream(), ast_strlen_zero, ast_waitfor(), ast_writefile(), ast_writestream(), filename_parse(), ast_frame::flags, ast_frame::frametype, ast_conference::lchan, ast_conference::listenlock, MEETME_RECORD_ACTIVE, MEETME_RECORD_OFF, MEETME_RECORD_TERMINATE, NULL, ast_conference::origframe, PATH_MAX, ast_conference::recording, ast_conference::recordingfilename, ast_conference::recordingformat, and ast_conference::transframe.

Referenced by meetme_stasis_generate_msg().

5682 {
5683  struct ast_conference *cnf = args;
5684  struct ast_frame *f = NULL;
5685  int flags;
5686  struct ast_filestream *s = NULL;
5687  int res = 0;
5688  int x;
5689  const char *oldrecordingfilename = NULL;
5690  char filename_buffer[PATH_MAX];
5691 
5692  if (!cnf || !cnf->lchan) {
5693  pthread_exit(0);
5694  }
5695 
5696  filename_buffer[0] = '\0';
5697  filename_parse(cnf->recordingfilename, filename_buffer);
5698 
5699  ast_stopstream(cnf->lchan);
5700  flags = O_CREAT | O_TRUNC | O_WRONLY;
5701 
5702 
5704  while (ast_waitfor(cnf->lchan, -1) > -1) {
5705  if (cnf->recording == MEETME_RECORD_TERMINATE) {
5706  AST_LIST_LOCK(&confs);
5708  break;
5709  }
5710  if (!s && !(ast_strlen_zero(filename_buffer)) && (filename_buffer != oldrecordingfilename)) {
5711  s = ast_writefile(filename_buffer, cnf->recordingformat, NULL, flags, 0, AST_FILE_MODE);
5712  oldrecordingfilename = filename_buffer;
5713  }
5714 
5715  f = ast_read(cnf->lchan);
5716  if (!f) {
5717  res = -1;
5718  break;
5719  }
5720  if (f->frametype == AST_FRAME_VOICE) {
5721  ast_mutex_lock(&cnf->listenlock);
5722  for (x = 0; x < AST_FRAME_BITS; x++) {
5723  /* Free any translations that have occured */
5724  if (cnf->transframe[x]) {
5725  ast_frfree(cnf->transframe[x]);
5726  cnf->transframe[x] = NULL;
5727  }
5728  }
5729  if (cnf->origframe)
5730  ast_frfree(cnf->origframe);
5731  cnf->origframe = ast_frdup(f);
5733  if (s)
5734  res = ast_writestream(s, f);
5735  if (res) {
5736  ast_frfree(f);
5737  break;
5738  }
5739  }
5740  ast_frfree(f);
5741  }
5743  if (s)
5744  ast_closestream(s);
5745 
5746  pthread_exit(0);
5747 }
#define ast_frdup(fr)
Copies a frame.
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_FRAME_BITS
Definition: app_meetme.c:664
struct ast_frame * origframe
Definition: app_meetme.c:873
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:864
struct ast_frame * transframe[32]
Definition: app_meetme.c:872
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
ast_mutex_t listenlock
Definition: app_meetme.c:844
#define ast_mutex_lock(a)
Definition: lock.h:187
const char * args
#define NULL
Definition: resample.c:96
#define AST_FILE_MODE
Definition: asterisk.h:32
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum recording_state recording
Definition: app_meetme.c:856
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition: file.c:1361
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1068
unsigned int flags
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:209
#define ast_frfree(fr)
Data structure associated with a single frame of data.
char * recordingfilename
Definition: app_meetme.c:863
struct ast_channel * lchan
Definition: app_meetme.c:847
enum ast_frame_type frametype
#define PATH_MAX
Definition: asterisk.h:40
The MeetMe Conference object.
Definition: app_meetme.c:842
static void filename_parse(char *filename, char *buffer)
Definition: app_meetme.c:5662
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ reload()

static int reload ( void  )
static

Definition at line 8072 of file app_meetme.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEVSTATE_PROVIDER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ast_unload_realtime(), ASTERISK_GPL_KEY, load_config(), load_module(), and unload_module().

8073 {
8074  ast_unload_realtime("meetme");
8075  return load_config(1);
8076 }
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3406
static int load_config(int reload)
Definition: app_meetme.c:7998

◆ reset_volumes()

static void reset_volumes ( struct ast_conf_user user)
static

Definition at line 1518 of file app_meetme.c.

References ast_channel_setoption(), AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, and ast_conf_user::chan.

Referenced by admin_exec(), conf_run(), and user_reset_vol_cb().

1519 {
1520  signed char zero_volume = 0;
1521 
1522  ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
1523  ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &zero_volume, sizeof(zero_volume), 0);
1524 }
#define AST_OPTION_TXGAIN
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
#define AST_OPTION_RXGAIN
struct ast_channel * chan
Definition: app_meetme.c:900

◆ rt_extend_conf()

static int rt_extend_conf ( const char *  confno)
static

Definition at line 2523 of file app_meetme.c.

References ast_copy_string(), ast_debug, ast_load_realtime(), ast_localtime(), ast_mktime(), ast_strftime(), ast_strptime(), ast_tvnow(), ast_update_realtime(), ast_variables_destroy(), DATE_FORMAT, extendby, ast_variable::name, ast_variable::next, NULL, ast_variable::value, and var.

Referenced by admin_exec(), meetme_menu_admin(), and meetme_menu_normal().

2524 {
2525  char currenttime[32];
2526  char endtime[32];
2527  struct timeval now;
2528  struct ast_tm tm;
2529  struct ast_variable *var, *orig_var;
2530  char bookid[51];
2531 
2532  if (!extendby) {
2533  return 0;
2534  }
2535 
2536  now = ast_tvnow();
2537 
2538  ast_localtime(&now, &tm, NULL);
2539  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
2540 
2541  var = ast_load_realtime("meetme", "confno",
2542  confno, "startTime<= ", currenttime,
2543  "endtime>= ", currenttime, NULL);
2544 
2545  orig_var = var;
2546 
2547  /* Identify the specific RealTime conference */
2548  while (var) {
2549  if (!strcasecmp(var->name, "bookid")) {
2550  ast_copy_string(bookid, var->value, sizeof(bookid));
2551  }
2552  if (!strcasecmp(var->name, "endtime")) {
2553  ast_copy_string(endtime, var->value, sizeof(endtime));
2554  }
2555 
2556  var = var->next;
2557  }
2558  ast_variables_destroy(orig_var);
2559 
2560  ast_strptime(endtime, DATE_FORMAT, &tm);
2561  now = ast_mktime(&tm, NULL);
2562 
2563  now.tv_sec += extendby;
2564 
2565  ast_localtime(&now, &tm, NULL);
2566  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
2567  strcat(currenttime, "0"); /* Seconds needs to be 00 */
2568 
2569  var = ast_load_realtime("meetme", "confno",
2570  confno, "startTime<= ", currenttime,
2571  "endtime>= ", currenttime, NULL);
2572 
2573  /* If there is no conflict with extending the conference, update the DB */
2574  if (!var) {
2575  ast_debug(3, "Trying to update the endtime of Conference %s to %s\n", confno, currenttime);
2576  ast_update_realtime("meetme", "bookid", bookid, "endtime", currenttime, NULL);
2577  return 0;
2578 
2579  }
2580 
2581  ast_variables_destroy(var);
2582  return -1;
2583 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: main/config.c:3489
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
char * ast_strptime(const char *s, const char *format, struct ast_tm *tm)
Special version of strptime(3) which places the answer in the common structure ast_tm. Also, unlike strptime(3), ast_strptime() initializes its memory prior to use.
Definition: localtime.c:2550
#define DATE_FORMAT
Definition: app_meetme.c:650
static int extendby
Definition: app_meetme.c:814
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2357
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ run_station()

static void* run_station ( void *  data)
static

Definition at line 6068 of file app_meetme.c.

References sla_trunk::active_stations, admin_exec(), ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, ast_atomic_dec_and_test(), ast_atomic_fetchadd_int(), ast_cond_signal, ast_dial_destroy(), ast_dial_join(), ast_free, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), build_conf(), sla_trunk_ref::chan, run_station_args::cond, run_station_args::cond_lock, conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_STATION, sla_station::dial, dispose_conf(), sla_trunk::hold_stations, sla_trunk::name, NULL, RAII_VAR, sla_change_trunk_state(), sla_ringing_trunk_destroy(), SLA_TRUNK_STATE_IDLE, SLA_TRUNK_STATE_ONHOLD_BYME, sla_trunk_ref::state, run_station_args::station, sla_trunk_ref::trunk, and run_station_args::trunk_ref.

Referenced by sla_handle_dial_state_event().

6069 {
6070  RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
6071  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
6072  struct ast_str *conf_name = ast_str_create(16);
6073  struct ast_flags64 conf_flags = { 0 };
6074  struct ast_conference *conf;
6075 
6076  {
6077  struct run_station_args *args = data;
6078  station = args->station;
6079  trunk_ref = args->trunk_ref;
6080  ast_mutex_lock(args->cond_lock);
6081  ast_cond_signal(args->cond);
6082  ast_mutex_unlock(args->cond_lock);
6083  /* args is no longer valid here. */
6084  }
6085 
6087  ast_str_set(&conf_name, 0, "SLA_%s", trunk_ref->trunk->name);
6088  ast_set_flag64(&conf_flags,
6091  conf = build_conf(ast_str_buffer(conf_name), "", "", 0, 0, 1, trunk_ref->chan, NULL);
6092  if (conf) {
6093  conf_run(trunk_ref->chan, conf, &conf_flags, NULL);
6094  dispose_conf(conf);
6095  conf = NULL;
6096  }
6097  trunk_ref->chan = NULL;
6100  ast_str_append(&conf_name, 0, ",K");
6101  admin_exec(NULL, ast_str_buffer(conf_name));
6104  }
6105 
6108  station->dial = NULL;
6109  ast_free(conf_name);
6110 
6111  return NULL;
6112 }
const ast_string_field name
Definition: app_meetme.c:986
unsigned int active_stations
Definition: app_meetme.c:991
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:6057
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
struct sla_trunk * trunk
Definition: app_meetme.c:1017
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
ast_mutex_t * cond_lock
Definition: app_meetme.c:6058
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
struct ast_dial * dial
Definition: app_meetme.c:950
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:6062
const char * args
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define ast_cond_signal(cond)
Definition: lock.h:201
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
enum sla_trunk_state state
Definition: app_meetme.c:1018
All configuration options for statsd client.
Definition: res_statsd.c:95
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:3177
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
#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
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
Definition: lock.h:765
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_channel * chan
Definition: app_meetme.c:1019
#define ast_free(a)
Definition: astmm.h:182
ast_cond_t * cond
Definition: app_meetme.c:6059
unsigned int hold_stations
Definition: app_meetme.c:993
struct sla_station * station
Definition: app_meetme.c:6056
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:5225
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
The MeetMe Conference object.
Definition: app_meetme.c:842
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ send_talking_event()

static void send_talking_event ( struct ast_channel chan,
struct ast_conference conf,
struct ast_conf_user user,
int  talking 
)
static

Definition at line 2681 of file app_meetme.c.

References ast_json_unref(), meetme_stasis_generate_msg(), RAII_VAR, and status_to_json().

Referenced by set_user_talking().

2682 {
2683  RAII_VAR(struct ast_json *, status_blob, status_to_json(talking), ast_json_unref);
2684  meetme_stasis_generate_msg(conf, chan, user, meetme_talking_type(), status_blob);
2685 }
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
static struct ast_json * status_to_json(int on)
Definition: app_meetme.c:1324
static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference, struct ast_channel *chan, struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
Definition: app_meetme.c:1343
#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
Abstract JSON element (object, array, string, int, ...).

◆ set_listen_volume()

static int set_listen_volume ( struct ast_conf_user user,
int  volume 
)
static

Definition at line 1447 of file app_meetme.c.

References ast_channel_setoption(), AST_OPTION_TXGAIN, and ast_conf_user::chan.

Referenced by tweak_listen_volume().

1448 {
1449  char gain_adjust;
1450 
1451  /* attempt to make the adjustment in the channel driver;
1452  if successful, don't adjust in the frame reading routine
1453  */
1454  gain_adjust = gain_map[volume + 5];
1455 
1456  return ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
1457 }
#define AST_OPTION_TXGAIN
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
static const char gain_map[]
Map &#39;volume&#39; levels from -5 through +5 into decibel (dB) settings for channel drivers.
Definition: app_meetme.c:1115
struct ast_channel * chan
Definition: app_meetme.c:900

◆ set_talk_volume()

static int set_talk_volume ( struct ast_conf_user user,
int  volume 
)
static

Definition at line 1435 of file app_meetme.c.

References ast_channel_setoption(), AST_OPTION_RXGAIN, and ast_conf_user::chan.

Referenced by conf_run(), and tweak_talk_volume().

1436 {
1437  char gain_adjust;
1438 
1439  /* attempt to make the adjustment in the channel driver;
1440  if successful, don't adjust in the frame reading routine
1441  */
1442  gain_adjust = gain_map[volume + 5];
1443 
1444  return ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
1445 }
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7522
#define AST_OPTION_RXGAIN
static const char gain_map[]
Map &#39;volume&#39; levels from -5 through +5 into decibel (dB) settings for channel drivers.
Definition: app_meetme.c:1115
struct ast_channel * chan
Definition: app_meetme.c:900

◆ set_user_talking()

static void set_user_talking ( struct ast_channel chan,
struct ast_conference conf,
struct ast_conf_user user,
int  talking,
int  monitor 
)
static

Definition at line 2687 of file app_meetme.c.

References send_talking_event(), and ast_conf_user::talking.

Referenced by conf_run().

2688 {
2689  int last_talking = user->talking;
2690  if (last_talking == talking)
2691  return;
2692 
2693  user->talking = talking;
2694 
2695  if (monitor) {
2696  /* Check if talking state changed. Take care of -1 which means unmonitored */
2697  int was_talking = (last_talking > 0);
2698  int now_talking = (talking > 0);
2699  if (was_talking != now_talking) {
2700  send_talking_event(chan, conf, user, now_talking);
2701  }
2702  }
2703 }
static void send_talking_event(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking)
Definition: app_meetme.c:2681
static unsigned int monitor
Definition: chan_phone.c:116

◆ sla_add_trunk_to_station()

static void sla_add_trunk_to_station ( struct sla_station station,
struct ast_variable var 
)
static

Definition at line 7562 of file app_meetme.c.

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log, ast_strdupa, create_trunk_ref(), LOG_ERROR, LOG_WARNING, sla_station_ref::mark, sla_trunk_ref::mark, name, NULL, options, RAII_VAR, sla_trunk_ref::ring_delay, sla_trunk_ref::ring_timeout, sla_create_station_ref(), sla_find_trunk(), SLA_TRUNK_STATE_IDLE, sla_trunk_ref::state, sla_station_ref::station, strsep(), sla_trunk_ref::trunk, sla_station::trunks, value, and ast_variable::value.

Referenced by sla_build_station().

7563 {
7564  RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
7565  struct sla_trunk_ref *trunk_ref = NULL;
7566  struct sla_station_ref *station_ref;
7567  char *trunk_name, *options, *cur;
7568  int existing_trunk_ref = 0;
7569  int existing_station_ref = 0;
7570 
7571  options = ast_strdupa(var->value);
7572  trunk_name = strsep(&options, ",");
7573 
7574  trunk = sla_find_trunk(trunk_name);
7575  if (!trunk) {
7576  ast_log(LOG_ERROR, "Trunk '%s' not found!\n", var->value);
7577  return;
7578  }
7579 
7580  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7581  if (trunk_ref->trunk == trunk) {
7582  trunk_ref->mark = 0;
7583  existing_trunk_ref = 1;
7584  break;
7585  }
7586  }
7587 
7588  if (!trunk_ref && !(trunk_ref = create_trunk_ref(trunk))) {
7589  return;
7590  }
7591 
7592  trunk_ref->state = SLA_TRUNK_STATE_IDLE;
7593 
7594  while ((cur = strsep(&options, ","))) {
7595  char *name, *value = cur;
7596  name = strsep(&value, "=");
7597  if (!strcasecmp(name, "ringtimeout")) {
7598  if (sscanf(value, "%30u", &trunk_ref->ring_timeout) != 1) {
7599  ast_log(LOG_WARNING, "Invalid ringtimeout value '%s' for "
7600  "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
7601  trunk_ref->ring_timeout = 0;
7602  }
7603  } else if (!strcasecmp(name, "ringdelay")) {
7604  if (sscanf(value, "%30u", &trunk_ref->ring_delay) != 1) {
7605  ast_log(LOG_WARNING, "Invalid ringdelay value '%s' for "
7606  "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
7607  trunk_ref->ring_delay = 0;
7608  }
7609  } else {
7610  ast_log(LOG_WARNING, "Invalid option '%s' for "
7611  "trunk '%s' on station '%s'\n", name, trunk->name, station->name);
7612  }
7613  }
7614 
7615  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
7616  if (station_ref->station == station) {
7617  station_ref->mark = 0;
7618  existing_station_ref = 1;
7619  break;
7620  }
7621  }
7622 
7623  if (!station_ref && !(station_ref = sla_create_station_ref(station))) {
7624  if (!existing_trunk_ref) {
7625  ao2_ref(trunk_ref, -1);
7626  } else {
7627  trunk_ref->mark = 1;
7628  }
7629  return;
7630  }
7631 
7632  if (!existing_station_ref) {
7633  ao2_lock(trunk);
7634  AST_LIST_INSERT_TAIL(&trunk->stations, station_ref, entry);
7635  ast_atomic_fetchadd_int((int *) &trunk->num_stations, 1);
7636  ao2_unlock(trunk);
7637  }
7638 
7639  if (!existing_trunk_ref) {
7640  ao2_lock(station);
7641  AST_LIST_INSERT_TAIL(&station->trunks, trunk_ref, entry);
7642  ao2_unlock(station);
7643  }
7644 }
unsigned int ring_timeout
Definition: app_meetme.c:1023
unsigned int mark
Definition: app_meetme.c:1029
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define LOG_WARNING
Definition: logger.h:274
A reference to a station.
Definition: app_meetme.c:974
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
enum sla_trunk_state state
Definition: app_meetme.c:1018
#define ast_log
Definition: astobj2.c:42
#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_ref(o, delta)
Definition: astobj2.h:464
static struct sla_station_ref * sla_create_station_ref(struct sla_station *station)
Definition: app_meetme.c:5949
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct sla_trunk_ref * create_trunk_ref(struct sla_trunk *trunk)
Definition: app_meetme.c:7168
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
static struct test_options options
unsigned int mark
Definition: app_meetme.c:978
unsigned int ring_delay
Definition: app_meetme.c:1027
struct sla_station * station
Definition: app_meetme.c:976
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5858

◆ sla_build_station()

static int sla_build_station ( struct ast_config cfg,
const char *  cat 
)
static

Definition at line 7646 of file app_meetme.c.

References ao2_alloc, ao2_cleanup, ao2_link, ao2_lock, ao2_unlock, ast_add_extension(), ast_context_find_or_create(), ast_free_ptr(), AST_LIST_TRAVERSE, ast_log, AST_MAX_APP, AST_MAX_EXTENSION, ast_strdup, ast_string_field_init, ast_string_field_set, ast_strlen_zero, ast_variable_browse(), ast_variable_retrieve(), exten, ast_variable::lineno, LOG_ERROR, LOG_WARNING, name, ast_variable::name, sla_trunk::name, ast_variable::next, NULL, PRIORITY_HINT, RAII_VAR, sla_add_trunk_to_station(), SLA_CONFIG_FILE, sla_find_station(), SLA_HOLD_OPEN, SLA_HOLD_PRIVATE, sla_station_destructor(), sla_station_ref::station, sla_trunk_ref::trunk, ast_variable::value, and var.

Referenced by sla_load_config().

7647 {
7649  struct ast_variable *var;
7650  const char *dev;
7651  int existing_station = 0;
7652 
7653  if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
7654  ast_log(LOG_ERROR, "SLA Station '%s' defined with no device!\n", cat);
7655  return -1;
7656  }
7657 
7658  if ((station = sla_find_station(cat))) {
7659  station->mark = 0;
7660  existing_station = 1;
7661  } else if ((station = ao2_alloc(sizeof(*station), sla_station_destructor))) {
7662  if (ast_string_field_init(station, 32)) {
7663  return -1;
7664  }
7665  ast_string_field_set(station, name, cat);
7666  } else {
7667  return -1;
7668  }
7669 
7670  ao2_lock(station);
7671 
7672  ast_string_field_set(station, device, dev);
7673 
7674  for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
7675  if (!strcasecmp(var->name, "trunk")) {
7676  ao2_unlock(station);
7677  sla_add_trunk_to_station(station, var);
7678  ao2_lock(station);
7679  } else if (!strcasecmp(var->name, "autocontext")) {
7680  ast_string_field_set(station, autocontext, var->value);
7681  } else if (!strcasecmp(var->name, "ringtimeout")) {
7682  if (sscanf(var->value, "%30u", &station->ring_timeout) != 1) {
7683  ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for station '%s'\n",
7684  var->value, station->name);
7685  station->ring_timeout = 0;
7686  }
7687  } else if (!strcasecmp(var->name, "ringdelay")) {
7688  if (sscanf(var->value, "%30u", &station->ring_delay) != 1) {
7689  ast_log(LOG_WARNING, "Invalid ringdelay '%s' specified for station '%s'\n",
7690  var->value, station->name);
7691  station->ring_delay = 0;
7692  }
7693  } else if (!strcasecmp(var->name, "hold")) {
7694  if (!strcasecmp(var->value, "private"))
7695  station->hold_access = SLA_HOLD_PRIVATE;
7696  else if (!strcasecmp(var->value, "open"))
7697  station->hold_access = SLA_HOLD_OPEN;
7698  else {
7699  ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n",
7700  var->value, station->name);
7701  }
7702 
7703  } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
7704  ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
7705  var->name, var->lineno, SLA_CONFIG_FILE);
7706  }
7707  }
7708 
7709  ao2_unlock(station);
7710 
7711  if (!ast_strlen_zero(station->autocontext)) {
7712  struct sla_trunk_ref *trunk_ref;
7713 
7714  if (!ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar)) {
7715  ast_log(LOG_ERROR, "Failed to automatically find or create "
7716  "context '%s' for SLA!\n", station->autocontext);
7717  return -1;
7718  }
7719  /* The extension for when the handset goes off-hook.
7720  * exten => station1,1,SLAStation(station1) */
7721  if (ast_add_extension(station->autocontext, 0 /* don't replace */, station->name, 1,
7723  ast_log(LOG_ERROR, "Failed to automatically create extension "
7724  "for trunk '%s'!\n", station->name);
7725  return -1;
7726  }
7727  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7728  char exten[AST_MAX_EXTENSION];
7729  char hint[AST_MAX_APP];
7730  snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
7731  snprintf(hint, sizeof(hint), "SLA:%s", exten);
7732  /* Extension for this line button
7733  * exten => station1_line1,1,SLAStation(station1_line1) */
7734  if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, 1,
7736  ast_log(LOG_ERROR, "Failed to automatically create extension "
7737  "for trunk '%s'!\n", station->name);
7738  return -1;
7739  }
7740  /* Hint for this line button
7741  * exten => station1_line1,hint,SLA:station1_line1 */
7742  if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, PRIORITY_HINT,
7743  NULL, NULL, hint, NULL, NULL, sla_registrar)) {
7744  ast_log(LOG_ERROR, "Failed to automatically create hint "
7745  "for trunk '%s'!\n", station->name);
7746  return -1;
7747  }
7748  }
7749  }
7750 
7751  if (!existing_station) {
7752  ao2_link(sla_stations, station);
7753  }
7754 
7755  return 0;
7756 }
const ast_string_field name
Definition: app_meetme.c:986
struct ast_variable * next
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
static void sla_add_trunk_to_station(struct sla_station *station, struct ast_variable *var)
Definition: app_meetme.c:7562
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static const char *const slastation_app
Definition: app_meetme.c:806
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static void sla_station_destructor(void *obj)
Definition: app_meetme.c:7380
#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 ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ao2_lock(a)
Definition: astobj2.h:718
#define PRIORITY_HINT
Definition: pbx.h:54
#define LOG_ERROR
Definition: logger.h:285
#define AST_MAX_APP
Definition: pbx.h:40
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
#define SLA_CONFIG_FILE
Definition: app_meetme.c:643
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static const char sla_registrar[]
Definition: app_meetme.c:1035
Definition: search.h:40
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5871
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
struct sla_station * station
Definition: app_meetme.c:976
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ sla_build_trunk()

static int sla_build_trunk ( struct ast_config cfg,
const char *  cat 
)
static

Definition at line 7474 of file app_meetme.c.

References ao2_alloc, ao2_cleanup, ao2_link, ao2_lock, ao2_unlock, ast_add_extension(), ast_context_find_or_create(), ast_false(), ast_free_ptr(), ast_log, ast_strdup, ast_string_field_init, ast_string_field_set, ast_strlen_zero, ast_variable_browse(), ast_variable_retrieve(), ast_variable::lineno, LOG_ERROR, LOG_WARNING, name, ast_variable::name, ast_variable::next, NULL, RAII_VAR, sla_check_device(), SLA_CONFIG_FILE, sla_find_trunk(), SLA_HOLD_OPEN, SLA_HOLD_PRIVATE, sla_trunk_destructor(), ast_variable::value, and var.

Referenced by sla_load_config().

7475 {
7476  RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
7477  struct ast_variable *var;
7478  const char *dev;
7479  int existing_trunk = 0;
7480 
7481  if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
7482  ast_log(LOG_ERROR, "SLA Trunk '%s' defined with no device!\n", cat);
7483  return -1;
7484  }
7485 
7486  if (sla_check_device(dev)) {
7487  ast_log(LOG_ERROR, "SLA Trunk '%s' defined with invalid device '%s'!\n",
7488  cat, dev);
7489  return -1;
7490  }
7491 
7492  if ((trunk = sla_find_trunk(cat))) {
7493  trunk->mark = 0;
7494  existing_trunk = 1;
7495  } else if ((trunk = ao2_alloc(sizeof(*trunk), sla_trunk_destructor))) {
7496  if (ast_string_field_init(trunk, 32)) {
7497  return -1;
7498  }
7499  ast_string_field_set(trunk, name, cat);
7500  } else {
7501  return -1;
7502  }
7503 
7504  ao2_lock(trunk);
7505 
7506  ast_string_field_set(trunk, device, dev);
7507 
7508  for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
7509  if (!strcasecmp(var->name, "autocontext"))
7510  ast_string_field_set(trunk, autocontext, var->value);
7511  else if (!strcasecmp(var->name, "ringtimeout")) {
7512  if (sscanf(var->value, "%30u", &trunk->ring_timeout) != 1) {
7513  ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for trunk '%s'\n",
7514  var->value, trunk->name);
7515  trunk->ring_timeout = 0;
7516  }
7517  } else if (!strcasecmp(var->name, "barge"))
7518  trunk->barge_disabled = ast_false(var->value);
7519  else if (!strcasecmp(var->name, "hold")) {
7520  if (!strcasecmp(var->value, "private"))
7521  trunk->hold_access = SLA_HOLD_PRIVATE;
7522  else if (!strcasecmp(var->value, "open"))
7523  trunk->hold_access = SLA_HOLD_OPEN;
7524  else {
7525  ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n",
7526  var->value, trunk->name);
7527  }
7528  } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
7529  ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
7530  var->name, var->lineno, SLA_CONFIG_FILE);
7531  }
7532  }
7533 
7534  ao2_unlock(trunk);
7535 
7536  if (!ast_strlen_zero(trunk->autocontext)) {
7537  if (!ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar)) {
7538  ast_log(LOG_ERROR, "Failed to automatically find or create "
7539  "context '%s' for SLA!\n", trunk->autocontext);
7540  return -1;
7541  }
7542 
7543  if (ast_add_extension(trunk->autocontext, 0 /* don't replace */, "s", 1,
7545  ast_log(LOG_ERROR, "Failed to automatically create extension "
7546  "for trunk '%s'!\n", trunk->name);
7547  return -1;
7548  }
7549  }
7550 
7551  if (!existing_trunk) {
7552  ao2_link(sla_trunks, trunk);
7553  }
7554 
7555  return 0;
7556 }
struct ast_variable * next
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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 ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_lock(a)
Definition: astobj2.h:718
static void sla_trunk_destructor(void *obj)
Definition: app_meetme.c:7459
#define LOG_ERROR
Definition: logger.h:285
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static int sla_check_device(const char *device)
Definition: app_meetme.c:7446
static const char name[]
Definition: cdr_mysql.c:74
static const char *const slatrunk_app
Definition: app_meetme.c:807
#define SLA_CONFIG_FILE
Definition: app_meetme.c:643
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: main/utils.c:1968
static const char sla_registrar[]
Definition: app_meetme.c:1035
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5858
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ sla_calc_station_delays()

static int sla_calc_station_delays ( unsigned int *  timeout)
static

Calculate the ring delay for a station.

Note
Assumes sla.lock is locked

Definition at line 6696 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, NULL, sla_check_inuse_station(), sla_check_ringing_station(), sla_check_station_delay(), and sla_choose_ringing_trunk().

Referenced by sla_process_timers().

6697 {
6698  struct sla_station *station;
6699  int res = 0;
6700  struct ao2_iterator i;
6701 
6703  for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
6704  struct sla_ringing_trunk *ringing_trunk;
6705  int time_left;
6706 
6707  /* Ignore stations already ringing */
6708  if (sla_check_ringing_station(station))
6709  continue;
6710 
6711  /* Ignore stations already on a call */
6712  if (sla_check_inuse_station(station))
6713  continue;
6714 
6715  /* Ignore stations that don't have one of their trunks ringing */
6716  if (!(ringing_trunk = sla_choose_ringing_trunk(station, NULL, 0)))
6717  continue;
6718 
6719  if ((time_left = sla_check_station_delay(station, ringing_trunk)) == INT_MAX)
6720  continue;
6721 
6722  /* If there is no time left, then the station needs to start ringing.
6723  * Return non-zero so that an event will be queued up an event to
6724  * make that happen. */
6725  if (time_left <= 0) {
6726  res = 1;
6727  continue;
6728  }
6729 
6730  if (time_left < *timeout)
6731  *timeout = time_left;
6732  }
6734 
6735  return res;
6736 }
static int timeout
Definition: cdr_mysql.c:86
static int sla_check_ringing_station(const struct sla_station *station)
Check to see if this station is already ringing.
Definition: app_meetme.c:6317
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
static int sla_check_station_delay(struct sla_station *station, struct sla_ringing_trunk *ringing_trunk)
Calculate the ring delay for a given ringing trunk on a station.
Definition: app_meetme.c:6447
A trunk that is ringing.
Definition: app_meetme.c:1063
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct sla_ringing_trunk * sla_choose_ringing_trunk(struct sla_station *station, struct sla_trunk_ref **trunk_ref, int rm)
Choose the highest priority ringing trunk for a station.
Definition: app_meetme.c:6196
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
static int sla_check_inuse_station(const struct sla_station *station)
Check to see if a station is in use.
Definition: app_meetme.c:6415
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sla_calc_station_timeouts()

static int sla_calc_station_timeouts ( unsigned int *  timeout)
static

Process station ring timeouts.

Note
Called with sla.lock locked
Returns
non-zero if a change to the ringing stations was made

Definition at line 6613 of file app_meetme.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_tvdiff_ms(), ast_tvnow(), sla_ringing_trunk::ring_begin, sla_ringing_station::ring_begin, sla_station::ring_timeout, sla_trunk_ref::ring_timeout, sla, SLA_STATION_HANGUP_TIMEOUT, sla_stop_ringing_station(), sla_station_ref::station, sla_ringing_station::station, sla_ringing_trunk::timed_out_stations, sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and sla_station::trunks.

Referenced by sla_process_timers().

6614 {
6615  struct sla_ringing_trunk *ringing_trunk;
6616  struct sla_ringing_station *ringing_station;
6617  int res = 0;
6618 
6619  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
6620  unsigned int ring_timeout = 0;
6621  int time_elapsed, time_left = INT_MAX, final_trunk_time_left = INT_MIN;
6622  struct sla_trunk_ref *trunk_ref;
6623 
6624  /* If there are any ring timeouts specified for a specific trunk
6625  * on the station, then use the highest per-trunk ring timeout.
6626  * Otherwise, use the ring timeout set for the entire station. */
6627  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
6628  struct sla_station_ref *station_ref;
6629  int trunk_time_elapsed, trunk_time_left;
6630 
6631  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6632  if (ringing_trunk->trunk == trunk_ref->trunk)
6633  break;
6634  }
6635  if (!ringing_trunk)
6636  continue;
6637 
6638  /* If there is a trunk that is ringing without a timeout, then the
6639  * only timeout that could matter is a global station ring timeout. */
6640  if (!trunk_ref->ring_timeout)
6641  break;
6642 
6643  /* This trunk on this station is ringing and has a timeout.
6644  * However, make sure this trunk isn't still ringing from a
6645  * previous timeout. If so, don't consider it. */
6646  AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, station_ref, entry) {
6647  if (station_ref->station == ringing_station->station)
6648  break;
6649  }
6650  if (station_ref)
6651  continue;
6652 
6653  trunk_time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
6654  trunk_time_left = (trunk_ref->ring_timeout * 1000) - trunk_time_elapsed;
6655  if (trunk_time_left > final_trunk_time_left)
6656  final_trunk_time_left = trunk_time_left;
6657  }
6658 
6659  /* No timeout was found for ringing trunks, and no timeout for the entire station */
6660  if (final_trunk_time_left == INT_MIN && !ringing_station->station->ring_timeout)
6661  continue;
6662 
6663  /* Compute how much time is left for a global station timeout */
6664  if (ringing_station->station->ring_timeout) {
6665  ring_timeout = ringing_station->station->ring_timeout;
6666  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
6667  time_left = (ring_timeout * 1000) - time_elapsed;
6668  }
6669 
6670  /* If the time left based on the per-trunk timeouts is smaller than the
6671  * global station ring timeout, use that. */
6672  if (final_trunk_time_left > INT_MIN && final_trunk_time_left < time_left)
6673  time_left = final_trunk_time_left;
6674 
6675  /* If there is no time left, the station needs to stop ringing */
6676  if (time_left <= 0) {
6679  res = 1;
6680  continue;
6681  }
6682 
6683  /* There is still some time left for this station to ring, so save that
6684  * timeout if it is the first event scheduled to occur */
6685  if (time_left < *timeout)
6686  *timeout = time_left;
6687  }
6689 
6690  return res;
6691 }
static struct @35 sla
A structure for data used by the sla thread.
unsigned int ring_timeout
Definition: app_meetme.c:1023
struct sla_trunk * trunk
Definition: app_meetme.c:1017
static int timeout
Definition: cdr_mysql.c:86
A station that is ringing.
Definition: app_meetme.c:1077
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
A reference to a station.
Definition: app_meetme.c:974
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct timeval ring_begin
Definition: app_meetme.c:1066
A trunk that is ringing.
Definition: app_meetme.c:1063
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct timeval ring_begin
Definition: app_meetme.c:1080
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_station * station
Definition: app_meetme.c:1078
struct sla_ringing_trunk::@47 timed_out_stations
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
unsigned int ring_timeout
Definition: app_meetme.c:954
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
Definition: app_meetme.c:6132
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_calc_trunk_timeouts()

static int sla_calc_trunk_timeouts ( unsigned int *  timeout)
static

Process trunk ring timeouts.

Note
Called with sla.lock locked
Returns
non-zero if a change to the ringing trunks was made

Definition at line 6583 of file app_meetme.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_tvdiff_ms(), ast_tvnow(), sla_trunk::chan, pbx_builtin_setvar_helper(), sla_ringing_trunk::ring_begin, sla_trunk::ring_timeout, sla, sla_stop_ringing_trunk(), and sla_ringing_trunk::trunk.

Referenced by sla_process_timers().

6584 {
6585  struct sla_ringing_trunk *ringing_trunk;
6586  int res = 0;
6587 
6588  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
6589  int time_left, time_elapsed;
6590  if (!ringing_trunk->trunk->ring_timeout)
6591  continue;
6592  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
6593  time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
6594  if (time_left <= 0) {
6595  pbx_builtin_setvar_helper(ringing_trunk->trunk->chan, "SLATRUNK_STATUS", "RINGTIMEOUT");
6597  sla_stop_ringing_trunk(ringing_trunk);
6598  res = 1;
6599  continue;
6600  }
6601  if (time_left < *timeout)
6602  *timeout = time_left;
6603  }
6605 
6606  return res;
6607 }
static struct @35 sla
A structure for data used by the sla thread.
struct ast_channel * chan
Definition: app_meetme.c:994
static int timeout
Definition: cdr_mysql.c:86
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:6116
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct timeval ring_begin
Definition: app_meetme.c:1066
A trunk that is ringing.
Definition: app_meetme.c:1063
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct sla_trunk * trunk
Definition: app_meetme.c:1064
unsigned int ring_timeout
Definition: app_meetme.c:995
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...
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ sla_change_trunk_state()

static void sla_change_trunk_state ( const struct sla_trunk trunk,
enum sla_trunk_state  state,
enum sla_which_trunk_refs  inactive_only,
const struct sla_trunk_ref exclude 
)
static

Definition at line 6029 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), AST_LIST_TRAVERSE, sla_trunk_ref::chan, sla_trunk::name, sla_state_to_devstate(), state, sla_trunk_ref::state, sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by dial_trunk(), queue_ringing_trunk(), run_station(), sla_handle_dial_state_event(), sla_handle_hold_event(), sla_station_exec(), sla_stop_ringing_trunk(), and sla_trunk_exec().

6031 {
6032  struct sla_station *station;
6033  struct sla_trunk_ref *trunk_ref;
6034  struct ao2_iterator i;
6035 
6037  while ((station = ao2_iterator_next(&i))) {
6038  ao2_lock(station);
6039  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6040  if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0)
6041  || trunk_ref == exclude) {
6042  continue;
6043  }
6044  trunk_ref->state = state;
6046  "SLA:%s_%s", station->name, trunk->name);
6047  break;
6048  }
6049  ao2_unlock(station);
6050  ao2_ref(station, -1);
6051  }
6053 }
const ast_string_field name
Definition: app_meetme.c:986
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct sla_trunk * trunk
Definition: app_meetme.c:1017
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
Definition: app_meetme.c:6012
enum sla_trunk_state state
Definition: app_meetme.c:1018
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
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_channel * chan
Definition: app_meetme.c:1019
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sla_check_device()

static int sla_check_device ( const char *  device)
static

Definition at line 7446 of file app_meetme.c.

References ast_strdupa, ast_strlen_zero, and strsep().

Referenced by sla_build_trunk().

7447 {
7448  char *tech, *tech_data;
7449 
7450  tech_data = ast_strdupa(device);
7451  tech = strsep(&tech_data, "/");
7452 
7453  if (ast_strlen_zero(tech) || ast_strlen_zero(tech_data))
7454  return -1;
7455 
7456  return 0;
7457 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strsep(char **str, const char *delims)

◆ sla_check_failed_station()

static int sla_check_failed_station ( const struct sla_station station)
static

Check to see if this station has failed to be dialed in the past minute.

Note
assumes sla.lock is locked

Definition at line 6332 of file app_meetme.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_tvdiff_ms(), ast_tvnow(), sla_failed_station::last_try, sla, sla_failed_station_destroy(), and sla_failed_station::station.

Referenced by sla_ring_stations().

6333 {
6334  struct sla_failed_station *failed_station;
6335  int res = 0;
6336 
6337  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
6338  if (station != failed_station->station)
6339  continue;
6340  if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
6342  sla_failed_station_destroy(failed_station);
6343  break;
6344  }
6345  res = 1;
6346  }
6348 
6349  return res;
6350 }
static struct @35 sla
A structure for data used by the sla thread.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct sla_station * station
Definition: app_meetme.c:1057
A station that failed to be dialed.
Definition: app_meetme.c:1056
static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
Definition: app_meetme.c:6002
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct timeval last_try
Definition: app_meetme.c:1058

◆ sla_check_inuse_station()

static int sla_check_inuse_station ( const struct sla_station station)
static

Check to see if a station is in use.

Definition at line 6415 of file app_meetme.c.

References AST_LIST_TRAVERSE, sla_trunk_ref::chan, and sla_station::trunks.

Referenced by sla_calc_station_delays(), and sla_ring_stations().

6416 {
6417  struct sla_trunk_ref *trunk_ref;
6418 
6419  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6420  if (trunk_ref->chan)
6421  return 1;
6422  }
6423 
6424  return 0;
6425 }
struct ast_channel * chan
Definition: app_meetme.c:1019
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_check_ringing_station()

static int sla_check_ringing_station ( const struct sla_station station)
static

Check to see if this station is already ringing.

Note
Assumes sla.lock is locked

Definition at line 6317 of file app_meetme.c.

References AST_LIST_TRAVERSE, sla, and sla_ringing_station::station.

Referenced by sla_calc_station_delays(), and sla_ring_stations().

6318 {
6319  struct sla_ringing_station *ringing_station;
6320 
6321  AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_station, entry) {
6322  if (station == ringing_station->station)
6323  return 1;
6324  }
6325 
6326  return 0;
6327 }
static struct @35 sla
A structure for data used by the sla thread.
A station that is ringing.
Definition: app_meetme.c:1077
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_station * station
Definition: app_meetme.c:1078
Definition: search.h:40

◆ sla_check_station_delay()

static int sla_check_station_delay ( struct sla_station station,
struct sla_ringing_trunk ringing_trunk 
)
static

Calculate the ring delay for a given ringing trunk on a station.

Parameters
stationthe station
ringing_trunkthe trunk. If NULL, the highest priority ringing trunk will be used
Returns
the number of ms left before the delay is complete, or INT_MAX if there is no delay

Definition at line 6447 of file app_meetme.c.

References ao2_cleanup, ast_tvdiff_ms(), ast_tvnow(), NULL, RAII_VAR, sla_ringing_trunk::ring_begin, sla_station::ring_delay, sla_choose_ringing_trunk(), sla_find_trunk_ref(), and sla_ringing_trunk::trunk.

Referenced by sla_calc_station_delays(), and sla_ring_stations().

6449 {
6450  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
6451  unsigned int delay = UINT_MAX;
6452  int time_left, time_elapsed;
6453 
6454  if (!ringing_trunk)
6455  ringing_trunk = sla_choose_ringing_trunk(station, &trunk_ref, 0);
6456  else
6457  trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk);
6458 
6459  if (!ringing_trunk || !trunk_ref)
6460  return delay;
6461 
6462  /* If this station has a ring delay specific to the highest priority
6463  * ringing trunk, use that. Otherwise, use the ring delay specified
6464  * globally for the station. */
6465  delay = trunk_ref->ring_delay;
6466  if (!delay)
6467  delay = station->ring_delay;
6468  if (!delay)
6469  return INT_MAX;
6470 
6471  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
6472  time_left = (delay * 1000) - time_elapsed;
6473 
6474  return time_left;
6475 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
unsigned int ring_delay
Definition: app_meetme.c:958
struct timeval ring_begin
Definition: app_meetme.c:1066
#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 sla_trunk * trunk
Definition: app_meetme.c:1064
static struct sla_trunk_ref * sla_find_trunk_ref(const struct sla_station *station, const struct sla_trunk *trunk)
Definition: app_meetme.c:6427
static struct sla_ringing_trunk * sla_choose_ringing_trunk(struct sla_station *station, struct sla_trunk_ref **trunk_ref, int rm)
Choose the highest priority ringing trunk for a station.
Definition: app_meetme.c:6196
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_check_station_hold_access()

static int sla_check_station_hold_access ( const struct sla_trunk trunk,
const struct sla_station station 
)
static

Definition at line 5880 of file app_meetme.c.

References AST_LIST_TRAVERSE, sla_station::hold_access, SLA_HOLD_PRIVATE, SLA_TRUNK_STATE_ONHOLD_BYME, sla_trunk_ref::state, sla_station_ref::station, sla_trunk::stations, sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by sla_find_trunk_ref_byname().

5882 {
5883  struct sla_station_ref *station_ref;
5884  struct sla_trunk_ref *trunk_ref;
5885 
5886  /* For each station that has this call on hold, check for private hold. */
5887  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
5888  AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
5889  if (trunk_ref->trunk != trunk || station_ref->station == station)
5890  continue;
5891  if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME &&
5892  station_ref->station->hold_access == SLA_HOLD_PRIVATE)
5893  return 1;
5894  return 0;
5895  }
5896  }
5897 
5898  return 0;
5899 }
struct sla_trunk * trunk
Definition: app_meetme.c:1017
A reference to a station.
Definition: app_meetme.c:974
unsigned int hold_access
Definition: app_meetme.c:961
enum sla_trunk_state state
Definition: app_meetme.c:1018
struct sla_trunk::@43 stations
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_check_timed_out_station()

static int sla_check_timed_out_station ( const struct sla_ringing_trunk ringing_trunk,
const struct sla_station station 
)
static

Check to see if dialing this station already timed out for this ringing trunk.

Note
Assumes sla.lock is locked

Definition at line 6175 of file app_meetme.c.

References AST_LIST_TRAVERSE, sla_station_ref::station, and sla_ringing_trunk::timed_out_stations.

Referenced by sla_choose_ringing_trunk(), and sla_ring_stations().

6177 {
6178  struct sla_station_ref *timed_out_station;
6179 
6180  AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, timed_out_station, entry) {
6181  if (station == timed_out_station->station)
6182  return 1;
6183  }
6184 
6185  return 0;
6186 }
A reference to a station.
Definition: app_meetme.c:974
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_ringing_trunk::@47 timed_out_stations
Definition: search.h:40
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_choose_idle_trunk()

static struct sla_trunk_ref* sla_choose_idle_trunk ( const struct sla_station station)
static

For a given station, choose the highest priority idle trunk.

Precondition
sla_station is locked

Definition at line 6992 of file app_meetme.c.

References ao2_ref, AST_LIST_TRAVERSE, NULL, SLA_TRUNK_STATE_IDLE, sla_trunk_ref::state, and sla_station::trunks.

Referenced by sla_station_exec().

6993 {
6994  struct sla_trunk_ref *trunk_ref = NULL;
6995 
6996  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6997  if (trunk_ref->state == SLA_TRUNK_STATE_IDLE) {
6998  ao2_ref(trunk_ref, 1);
6999  break;
7000  }
7001  }
7002 
7003  return trunk_ref;
7004 }
#define NULL
Definition: resample.c:96
enum sla_trunk_state state
Definition: app_meetme.c:1018
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_choose_ringing_trunk()

static struct sla_ringing_trunk* sla_choose_ringing_trunk ( struct sla_station station,
struct sla_trunk_ref **  trunk_ref,
int  rm 
)
static

Choose the highest priority ringing trunk for a station.

Parameters
stationthe station
rmremove the ringing trunk once selected
trunk_refa place to store the pointer to this stations reference to the selected trunk
Returns
a pointer to the selected ringing trunk, or NULL if none found
Note
Assumes that sla.lock is locked

Definition at line 6196 of file app_meetme.c.

References ao2_ref, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, NULL, sla, sla_check_timed_out_station(), sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and sla_station::trunks.

Referenced by sla_calc_station_delays(), sla_check_station_delay(), and sla_handle_dial_state_event().

6198 {
6199  struct sla_trunk_ref *s_trunk_ref;
6200  struct sla_ringing_trunk *ringing_trunk = NULL;
6201 
6202  AST_LIST_TRAVERSE(&station->trunks, s_trunk_ref, entry) {
6203  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
6204  /* Make sure this is the trunk we're looking for */
6205  if (s_trunk_ref->trunk != ringing_trunk->trunk)
6206  continue;
6207 
6208  /* This trunk on the station is ringing. But, make sure this station
6209  * didn't already time out while this trunk was ringing. */
6210  if (sla_check_timed_out_station(ringing_trunk, station))
6211  continue;
6212 
6213  if (rm)
6215 
6216  if (trunk_ref) {
6217  ao2_ref(s_trunk_ref, 1);
6218  *trunk_ref = s_trunk_ref;
6219  }
6220 
6221  break;
6222  }
6224 
6225  if (ringing_trunk)
6226  break;
6227  }
6228 
6229  return ringing_trunk;
6230 }
static struct @35 sla
A structure for data used by the sla thread.
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
A trunk that is ringing.
Definition: app_meetme.c:1063
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
static int sla_check_timed_out_station(const struct sla_ringing_trunk *ringing_trunk, const struct sla_station *station)
Check to see if dialing this station already timed out for this ringing trunk.
Definition: app_meetme.c:6175

◆ sla_create_failed_station()

static struct sla_failed_station* sla_create_failed_station ( struct sla_station station)
static

Definition at line 5987 of file app_meetme.c.

References ao2_ref, ast_calloc, ast_tvnow(), sla_failed_station::last_try, NULL, and sla_failed_station::station.

Referenced by sla_ring_station().

5988 {
5989  struct sla_failed_station *failed_station;
5990 
5991  if (!(failed_station = ast_calloc(1, sizeof(*failed_station)))) {
5992  return NULL;
5993  }
5994 
5995  ao2_ref(station, 1);
5996  failed_station->station = station;
5997  failed_station->last_try = ast_tvnow();
5998 
5999  return failed_station;
6000 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_station * station
Definition: app_meetme.c:1057
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
A station that failed to be dialed.
Definition: app_meetme.c:1056
struct timeval last_try
Definition: app_meetme.c:1058

◆ sla_create_ringing_station()

static struct sla_ringing_station* sla_create_ringing_station ( struct sla_station station)
static

Definition at line 5963 of file app_meetme.c.

References ao2_ref, ast_calloc, ast_tvnow(), NULL, sla_ringing_station::ring_begin, and sla_ringing_station::station.

Referenced by sla_ring_station().

5964 {
5965  struct sla_ringing_station *ringing_station;
5966 
5967  if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station))))
5968  return NULL;
5969 
5970  ao2_ref(station, 1);
5971  ringing_station->station = station;
5972  ringing_station->ring_begin = ast_tvnow();
5973 
5974  return ringing_station;
5975 }
A station that is ringing.
Definition: app_meetme.c:1077
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct timeval ring_begin
Definition: app_meetme.c:1080
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct sla_station * station
Definition: app_meetme.c:1078

◆ sla_create_station_ref()

static struct sla_station_ref* sla_create_station_ref ( struct sla_station station)
static

Definition at line 5949 of file app_meetme.c.

References ao2_alloc, ao2_ref, NULL, sla_station_ref_destructor(), and sla_station_ref::station.

Referenced by sla_add_trunk_to_station(), and sla_stop_ringing_station().

5950 {
5951  struct sla_station_ref *station_ref;
5952 
5953  if (!(station_ref = ao2_alloc(sizeof(*station_ref), sla_station_ref_destructor))) {
5954  return NULL;
5955  }
5956 
5957  ao2_ref(station, 1);
5958  station_ref->station = station;
5959 
5960  return station_ref;
5961 }
A reference to a station.
Definition: app_meetme.c:974
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void sla_station_ref_destructor(void *obj)
Definition: app_meetme.c:5939
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_destroy()

static void sla_destroy ( void  )
static

Definition at line 7420 of file app_meetme.c.

References ao2_callback, ao2_ref, ast_cond_destroy, ast_cond_signal, ast_context_destroy(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, NULL, sla, sla_station_release_refs(), and sla_trunk_release_refs().

Referenced by unload_module().

7421 {
7422  if (sla.thread != AST_PTHREADT_NULL) {
7423  ast_mutex_lock(&sla.lock);
7424  sla.stop = 1;
7425  ast_cond_signal(&sla.cond);
7426  ast_mutex_unlock(&sla.lock);
7427  pthread_join(sla.thread, NULL);
7428  }
7429 
7430  /* Drop any created contexts from the dialplan */
7432 
7433  ast_mutex_destroy(&sla.lock);
7434  ast_cond_destroy(&sla.cond);
7435 
7438 
7439  ao2_ref(sla_trunks, -1);
7440  sla_trunks = NULL;
7441 
7442  ao2_ref(sla_stations, -1);
7443  sla_stations = NULL;
7444 }
static struct @35 sla
A structure for data used by the sla thread.
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_cond_destroy(cond)
Definition: lock.h:200
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7368
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625
static const char sla_registrar[]
Definition: app_meetme.c:1035
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033
#define ast_mutex_destroy(a)
Definition: lock.h:186
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7356
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_dial_state_callback()

static void sla_dial_state_callback ( struct ast_dial dial)
static

Definition at line 6167 of file app_meetme.c.

References SLA_EVENT_DIAL_STATE, and sla_queue_event().

Referenced by sla_ring_station().

6168 {
6170 }
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2456

◆ sla_event_destroy()

static void sla_event_destroy ( struct sla_event event)
static

Definition at line 6775 of file app_meetme.c.

References ao2_ref, ast_free, NULL, sla_event::station, and sla_event::trunk_ref.

Referenced by sla_thread().

6776 {
6777  if (event->trunk_ref) {
6778  ao2_ref(event->trunk_ref, -1);
6779  event->trunk_ref = NULL;
6780  }
6781 
6782  if (event->station) {
6783  ao2_ref(event->station, -1);
6784  event->station = NULL;
6785  }
6786 
6787  ast_free(event);
6788 }
struct sla_station * station
Definition: app_meetme.c:1049
#define NULL
Definition: resample.c:96
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:1050
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_free(a)
Definition: astmm.h:182

◆ sla_failed_station_destroy()

static void sla_failed_station_destroy ( struct sla_failed_station failed_station)
static

Definition at line 6002 of file app_meetme.c.

References ao2_ref, ast_free, NULL, and sla_failed_station::station.

Referenced by sla_check_failed_station(), and sla_thread().

6003 {
6004  if (failed_station->station) {
6005  ao2_ref(failed_station->station, -1);
6006  failed_station->station = NULL;
6007  }
6008 
6009  ast_free(failed_station);
6010 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_station * station
Definition: app_meetme.c:1057
#define ast_free(a)
Definition: astmm.h:182

◆ sla_find_station()

static struct sla_station* sla_find_station ( const char *  name)
static

Definition at line 5871 of file app_meetme.c.

References ao2_find, name, and OBJ_POINTER.

Referenced by sla_build_station(), sla_state(), and sla_station_exec().

5872 {
5873  struct sla_station tmp_station = {
5874  .name = name,
5875  };
5876 
5877  return ao2_find(sla_stations, &tmp_station, OBJ_POINTER);
5878 }
#define OBJ_POINTER
Definition: astobj2.h:1154
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032

◆ sla_find_trunk()

static struct sla_trunk* sla_find_trunk ( const char *  name)
static

Definition at line 5858 of file app_meetme.c.

References ao2_find, name, sla_trunk::name, and OBJ_POINTER.

Referenced by sla_add_trunk_to_station(), sla_build_trunk(), and sla_trunk_exec().

5859 {
5860  struct sla_trunk tmp_trunk = {
5861  .name = name,
5862  };
5863 
5864  return ao2_find(sla_trunks, &tmp_trunk, OBJ_POINTER);
5865 }
const ast_string_field name
Definition: app_meetme.c:986
#define OBJ_POINTER
Definition: astobj2.h:1154
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033

◆ sla_find_trunk_ref()

static struct sla_trunk_ref* sla_find_trunk_ref ( const struct sla_station station,
const struct sla_trunk trunk 
)
static

Definition at line 6427 of file app_meetme.c.

References ao2_ref, AST_LIST_TRAVERSE, NULL, sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by sla_check_station_delay().

6429 {
6430  struct sla_trunk_ref *trunk_ref = NULL;
6431 
6432  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6433  if (trunk_ref->trunk == trunk)
6434  break;
6435  }
6436 
6437  ao2_ref(trunk_ref, 1);
6438 
6439  return trunk_ref;
6440 }
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_find_trunk_ref_byname()

static struct sla_trunk_ref* sla_find_trunk_ref_byname ( const struct sla_station station,
const char *  name 
)
static

Find a trunk reference on a station by name.

Parameters
stationthe station
namethe trunk's name
Precondition
sla_station is locked
Returns
a pointer to the station's trunk reference. If the trunk is not found, it is not idle and barge is disabled, or if it is on hold and private hold is set, then NULL will be returned.

Definition at line 5910 of file app_meetme.c.

References ao2_ref, AST_LIST_TRAVERSE, sla_trunk::barge_disabled, sla_trunk::hold_access, sla_trunk::hold_stations, sla_trunk::name, NULL, sla_check_station_hold_access(), SLA_HOLD_PRIVATE, SLA_TRUNK_STATE_ONHOLD_BYME, SLA_TRUNK_STATE_UP, sla_trunk_ref::state, sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by sla_station_exec().

5912 {
5913  struct sla_trunk_ref *trunk_ref = NULL;
5914 
5915  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
5916  if (strcasecmp(trunk_ref->trunk->name, name))
5917  continue;
5918 
5919  if ( (trunk_ref->trunk->barge_disabled
5920  && trunk_ref->state == SLA_TRUNK_STATE_UP) ||
5921  (trunk_ref->trunk->hold_stations
5922  && trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE
5923  && trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) ||
5924  sla_check_station_hold_access(trunk_ref->trunk, station) )
5925  {
5926  trunk_ref = NULL;
5927  }
5928 
5929  break;
5930  }
5931 
5932  if (trunk_ref) {
5933  ao2_ref(trunk_ref, 1);
5934  }
5935 
5936  return trunk_ref;
5937 }
const ast_string_field name
Definition: app_meetme.c:986
static int sla_check_station_hold_access(const struct sla_trunk *trunk, const struct sla_station *station)
Definition: app_meetme.c:5880
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define NULL
Definition: resample.c:96
enum sla_trunk_state state
Definition: app_meetme.c:1018
#define ao2_ref(o, delta)
Definition: astobj2.h:464
unsigned int barge_disabled
Definition: app_meetme.c:998
unsigned int hold_access
Definition: app_meetme.c:1001
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
unsigned int hold_stations
Definition: app_meetme.c:993
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_handle_dial_state_event()

static void sla_handle_dial_state_event ( void  )
static

Definition at line 6232 of file app_meetme.c.

References ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, ao2_ref, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_debug, ast_dial_answered(), ast_dial_destroy(), ast_dial_join(), AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_HANGUP, AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_RINGING, AST_DIAL_RESULT_TIMEOUT, AST_DIAL_RESULT_TRYING, AST_DIAL_RESULT_UNANSWERED, ast_dial_state(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_detached_background, sla_trunk::chan, cond, run_station_args::cond, run_station_args::cond_lock, sla_station::dial, NULL, RAII_VAR, run_station(), sla, sla_change_trunk_state(), sla_choose_ringing_trunk(), SLA_EVENT_DIAL_STATE, SLA_EVENT_RINGING_TRUNK, sla_queue_event(), sla_ringing_station_destroy(), sla_ringing_trunk_destroy(), SLA_STATION_HANGUP_NORMAL, sla_stop_ringing_station(), SLA_TRUNK_STATE_UP, sla_ringing_station::station, run_station_args::station, sla_ringing_trunk::trunk, and run_station_args::trunk_ref.

Referenced by sla_thread().

6233 {
6234  struct sla_ringing_station *ringing_station;
6235 
6236  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
6237  RAII_VAR(struct sla_trunk_ref *, s_trunk_ref, NULL, ao2_cleanup);
6238  struct sla_ringing_trunk *ringing_trunk = NULL;
6239  struct run_station_args args;
6240  enum ast_dial_result dial_res;
6241  pthread_t dont_care;
6243  ast_cond_t cond;
6244 
6245  switch ((dial_res = ast_dial_state(ringing_station->station->dial))) {
6253  break;
6256  /* Find the appropriate trunk to answer. */
6257  ast_mutex_lock(&sla.lock);
6258  ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
6259  ast_mutex_unlock(&sla.lock);
6260  if (!ringing_trunk) {
6261  /* This case happens in a bit of a race condition. If two stations answer
6262  * the outbound call at the same time, the first one will get connected to
6263  * the trunk. When the second one gets here, it will not see any trunks
6264  * ringing so we have no idea what to conect it to. So, we just hang up
6265  * on it. */
6266  ast_debug(1, "Found no ringing trunk for station '%s' to answer!\n", ringing_station->station->name);
6267  ast_dial_join(ringing_station->station->dial);
6268  ast_dial_destroy(ringing_station->station->dial);
6269  ringing_station->station->dial = NULL;
6270  sla_ringing_station_destroy(ringing_station);
6271  break;
6272  }
6273  /* Track the channel that answered this trunk */
6274  s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
6275  /* Actually answer the trunk */
6276  answer_trunk_chan(ringing_trunk->trunk->chan);
6278  /* Now, start a thread that will connect this station to the trunk. The rest of
6279  * the code here sets up the thread and ensures that it is able to save the arguments
6280  * before they are no longer valid since they are allocated on the stack. */
6281  ao2_ref(s_trunk_ref, 1);
6282  args.trunk_ref = s_trunk_ref;
6283  ao2_ref(ringing_station->station, 1);
6284  args.station = ringing_station->station;
6285  args.cond = &cond;
6286  args.cond_lock = &cond_lock;
6287  sla_ringing_trunk_destroy(ringing_trunk);
6288  sla_ringing_station_destroy(ringing_station);
6289  ast_mutex_init(&cond_lock);
6290  ast_cond_init(&cond, NULL);
6291  ast_mutex_lock(&cond_lock);
6293  ast_cond_wait(&cond, &cond_lock);
6294  ast_mutex_unlock(&cond_lock);
6295  ast_mutex_destroy(&cond_lock);
6296  ast_cond_destroy(&cond);
6297  break;
6302  break;
6303  }
6304  if (dial_res == AST_DIAL_RESULT_ANSWERED) {
6305  /* Queue up reprocessing ringing trunks, and then ringing stations again */
6308  break;
6309  }
6310  }
6312 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
static struct @35 sla
A structure for data used by the sla thread.
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5977
struct ast_channel * chan
Definition: app_meetme.c:994
ast_mutex_t * cond_lock
Definition: app_meetme.c:6058
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
struct ast_dial * dial
Definition: app_meetme.c:950
A station that is ringing.
Definition: app_meetme.c:1077
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_mutex_lock(a)
Definition: lock.h:187
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:6062
const char * args
#define NULL
Definition: resample.c:96
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2456
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
static void * run_station(void *data)
Definition: app_meetme.c:6068
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
#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
A trunk that is ringing.
Definition: app_meetme.c:1063
ast_cond_t cond
Definition: app_meetme.c:1090
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1012
struct sla_trunk * trunk
Definition: app_meetme.c:1064
static struct sla_ringing_trunk * sla_choose_ringing_trunk(struct sla_station *station, struct sla_trunk_ref **trunk_ref, int rm)
Choose the highest priority ringing trunk for a station.
Definition: app_meetme.c:6196
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:7205
#define ast_cond_destroy(cond)
Definition: lock.h:200
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:981
struct sla_station * station
Definition: app_meetme.c:1078
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define ast_mutex_init(pmutex)
Definition: lock.h:184
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
#define ast_mutex_destroy(a)
Definition: lock.h:186
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
Definition: app_meetme.c:6132
Structure for mutex and tracking information.
Definition: lock.h:135
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_handle_hold_event()

static void sla_handle_hold_event ( struct sla_event event)
static

Definition at line 6559 of file app_meetme.c.

References sla_trunk::active_stations, ast_atomic_fetchadd_int(), AST_CONTROL_HOLD, AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_indicate(), ast_softhangup(), AST_SOFTHANGUP_DEV, sla_trunk::chan, sla_trunk_ref::chan, sla_trunk::hold_stations, INACTIVE_TRUNK_REFS, sla_trunk::name, NULL, sla_change_trunk_state(), SLA_TRUNK_STATE_ONHOLD, SLA_TRUNK_STATE_ONHOLD_BYME, sla_event::station, sla_trunk_ref::trunk, and sla_event::trunk_ref.

Referenced by sla_thread().

6560 {
6561  ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
6562  event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
6564  event->station->name, event->trunk_ref->trunk->name);
6566  INACTIVE_TRUNK_REFS, event->trunk_ref);
6567 
6568  if (event->trunk_ref->trunk->active_stations == 1) {
6569  /* The station putting it on hold is the only one on the call, so start
6570  * Music on hold to the trunk. */
6571  event->trunk_ref->trunk->on_hold = 1;
6573  }
6574 
6576  event->trunk_ref->chan = NULL;
6577 }
const ast_string_field name
Definition: app_meetme.c:986
unsigned int active_stations
Definition: app_meetme.c:991
struct sla_station * station
Definition: app_meetme.c:1049
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct sla_trunk * trunk
Definition: app_meetme.c:1017
struct ast_channel * chan
Definition: app_meetme.c:994
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
#define NULL
Definition: resample.c:96
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:1050
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
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
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
struct ast_channel * chan
Definition: app_meetme.c:1019
unsigned int hold_stations
Definition: app_meetme.c:993

◆ sla_handle_ringing_trunk_event()

static void sla_handle_ringing_trunk_event ( void  )
static

Definition at line 6549 of file app_meetme.c.

References ast_mutex_lock, ast_mutex_unlock, sla, sla_hangup_stations(), and sla_ring_stations().

Referenced by sla_thread().

6550 {
6551  ast_mutex_lock(&sla.lock);
6553  ast_mutex_unlock(&sla.lock);
6554 
6555  /* Find stations that shouldn't be ringing anymore. */
6557 }
static struct @35 sla
A structure for data used by the sla thread.
static void sla_ring_stations(void)
Ring stations based on current set of ringing trunks.
Definition: app_meetme.c:6480
#define ast_mutex_lock(a)
Definition: lock.h:187
static void sla_hangup_stations(void)
Definition: app_meetme.c:6521
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_hangup_stations()

static void sla_hangup_stations ( void  )
static

Definition at line 6521 of file app_meetme.c.

References ast_dial_destroy(), ast_dial_join(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, sla_station::dial, NULL, sla, sla_ringing_station_destroy(), sla_ringing_station::station, sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and sla_station::trunks.

Referenced by sla_handle_ringing_trunk_event().

6522 {
6523  struct sla_trunk_ref *trunk_ref;
6524  struct sla_ringing_station *ringing_station;
6525 
6526  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
6527  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
6528  struct sla_ringing_trunk *ringing_trunk;
6529  ast_mutex_lock(&sla.lock);
6530  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6531  if (trunk_ref->trunk == ringing_trunk->trunk)
6532  break;
6533  }
6534  ast_mutex_unlock(&sla.lock);
6535  if (ringing_trunk)
6536  break;
6537  }
6538  if (!trunk_ref) {
6540  ast_dial_join(ringing_station->station->dial);
6541  ast_dial_destroy(ringing_station->station->dial);
6542  ringing_station->station->dial = NULL;
6543  sla_ringing_station_destroy(ringing_station);
6544  }
6545  }
6547 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
static struct @35 sla
A structure for data used by the sla thread.
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5977
struct sla_trunk * trunk
Definition: app_meetme.c:1017
struct ast_dial * dial
Definition: app_meetme.c:950
A station that is ringing.
Definition: app_meetme.c:1077
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
A trunk that is ringing.
Definition: app_meetme.c:1063
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_station * station
Definition: app_meetme.c:1078
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_hold_str()

static const char* sla_hold_str ( unsigned int  hold_access)
static

Definition at line 2116 of file app_meetme.c.

References hold(), SLA_HOLD_OPEN, and SLA_HOLD_PRIVATE.

Referenced by sla_show_stations(), and sla_show_trunks().

2117 {
2118  const char *hold = "Unknown";
2119 
2120  switch (hold_access) {
2121  case SLA_HOLD_OPEN:
2122  hold = "Open";
2123  break;
2124  case SLA_HOLD_PRIVATE:
2125  hold = "Private";
2126  default:
2127  break;
2128  }
2129 
2130  return hold;
2131 }
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.

◆ sla_in_use()

static int sla_in_use ( void  )
static

Definition at line 7850 of file app_meetme.c.

References ao2_container_count().

Referenced by sla_load_config().

7851 {
7853 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032

◆ sla_load_config()

static int sla_load_config ( int  reload)
static

Definition at line 7855 of file app_meetme.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_callback, ao2_container_alloc_list, ast_category_browse(), ast_cond_init, ast_config_destroy(), ast_config_load, ast_log, ast_mutex_init, ast_pthread_create, AST_PTHREADT_NULL, ast_true(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, LOG_WARNING, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sla, sla_build_station(), sla_build_trunk(), SLA_CONFIG_FILE, sla_in_use(), sla_station_cmp(), sla_station_is_marked(), sla_station_mark(), sla_thread(), sla_trunk_cmp(), sla_trunk_is_marked(), sla_trunk_mark(), and type.

Referenced by load_config().

7856 {
7857  struct ast_config *cfg;
7858  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
7859  const char *cat = NULL;
7860  int res = 0;
7861  const char *val;
7862 
7863  if (!reload) {
7864  ast_mutex_init(&sla.lock);
7865  ast_cond_init(&sla.cond, NULL);
7867  NULL, sla_trunk_cmp);
7870  }
7871 
7872  if (!(cfg = ast_config_load(SLA_CONFIG_FILE, config_flags))) {
7873  return 0; /* Treat no config as normal */
7874  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
7875  return 0;
7876  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
7877  ast_log(LOG_ERROR, "Config file " SLA_CONFIG_FILE " is in an invalid format. Aborting.\n");
7878  return 0;
7879  }
7880 
7881  if (reload) {
7884  }
7885 
7886  if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid")))
7887  sla.attempt_callerid = ast_true(val);
7888 
7889  while ((cat = ast_category_browse(cfg, cat)) && !res) {
7890  const char *type;
7891  if (!strcasecmp(cat, "general"))
7892  continue;
7893  if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
7894  ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n",
7895  SLA_CONFIG_FILE);
7896  continue;
7897  }
7898  if (!strcasecmp(type, "trunk"))
7899  res = sla_build_trunk(cfg, cat);
7900  else if (!strcasecmp(type, "station"))
7901  res = sla_build_station(cfg, cat);
7902  else {
7903  ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'!\n",
7904  SLA_CONFIG_FILE, type);
7905  }
7906  }
7907 
7908  ast_config_destroy(cfg);
7909 
7910  if (reload) {
7913  }
7914 
7915  /* Start SLA event processing thread once SLA has been configured. */
7916  if (sla.thread == AST_PTHREADT_NULL && sla_in_use()) {
7918  }
7919 
7920  return res;
7921 }
static const char type[]
Definition: chan_ooh323.c:109
static struct @35 sla
A structure for data used by the sla thread.
static int sla_build_station(struct ast_config *cfg, const char *cat)
Definition: app_meetme.c:7646
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:274
static int sla_station_mark(void *obj, void *arg, int flags)
Definition: app_meetme.c:7776
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define CONFIG_STATUS_FILEINVALID
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define ast_cond_init(cond, attr)
Definition: lock.h:199
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
static void * sla_thread(void *data)
Definition: app_meetme.c:6790
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
#define AST_PTHREADT_NULL
Definition: lock.h:66
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static int sla_trunk_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:7406
#define CONFIG_STATUS_FILEUNCHANGED
static int sla_in_use(void)
Definition: app_meetme.c:7850
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static int reload(void)
Definition: app_meetme.c:8072
static int sla_station_is_marked(void *obj, void *arg, int flags)
Definition: app_meetme.c:7822
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
static int sla_station_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:7413
static int sla_trunk_is_marked(void *obj, void *arg, int flags)
Definition: app_meetme.c:7794
Structure used to handle boolean flags.
Definition: utils.h:199
static int sla_trunk_mark(void *obj, void *arg, int flags)
Definition: app_meetme.c:7758
#define SLA_CONFIG_FILE
Definition: app_meetme.c:643
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
static int sla_build_trunk(struct ast_config *cfg, const char *cat)
Definition: app_meetme.c:7474
#define ast_mutex_init(pmutex)
Definition: lock.h:184
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032

◆ sla_process_timers()

static int sla_process_timers ( struct timespec *  ts)
static

Calculate the time until the next known event.

Note
Called with sla.lock locked

Definition at line 6740 of file app_meetme.c.

References ast_samp2tv(), ast_tvadd(), ast_tvnow(), sla_calc_station_delays(), sla_calc_station_timeouts(), sla_calc_trunk_timeouts(), SLA_EVENT_RINGING_TRUNK, sla_queue_event_nolock(), and timeout.

Referenced by sla_thread().

6741 {
6742  unsigned int timeout = UINT_MAX;
6743  struct timeval wait;
6744  unsigned int change_made = 0;
6745 
6746  /* Check for ring timeouts on ringing trunks */
6747  if (sla_calc_trunk_timeouts(&timeout))
6748  change_made = 1;
6749 
6750  /* Check for ring timeouts on ringing stations */
6751  if (sla_calc_station_timeouts(&timeout))
6752  change_made = 1;
6753 
6754  /* Check for station ring delays */
6755  if (sla_calc_station_delays(&timeout))
6756  change_made = 1;
6757 
6758  /* queue reprocessing of ringing trunks */
6759  if (change_made)
6761 
6762  /* No timeout */
6763  if (timeout == UINT_MAX)
6764  return 0;
6765 
6766  if (ts) {
6767  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1000));
6768  ts->tv_sec = wait.tv_sec;
6769  ts->tv_nsec = wait.tv_usec * 1000;
6770  }
6771 
6772  return 1;
6773 }
static void sla_queue_event_nolock(enum sla_event_type type)
Definition: app_meetme.c:2451
static int timeout
Definition: cdr_mysql.c:86
static int sla_calc_station_delays(unsigned int *timeout)
Calculate the ring delay for a station.
Definition: app_meetme.c:6696
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static int sla_calc_station_timeouts(unsigned int *timeout)
Process station ring timeouts.
Definition: app_meetme.c:6613
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
static int sla_calc_trunk_timeouts(unsigned int *timeout)
Process trunk ring timeouts.
Definition: app_meetme.c:6583

◆ sla_queue_event()

static void sla_queue_event ( enum sla_event_type  type)
static

Definition at line 2456 of file app_meetme.c.

References NULL, and sla_queue_event_full().

Referenced by queue_ringing_trunk(), sla_dial_state_callback(), sla_handle_dial_state_event(), sla_station_exec(), and sla_trunk_exec().

2457 {
2459 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
static void sla_queue_event_full(enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
Definition: app_meetme.c:2419

◆ sla_queue_event_conf()

static void sla_queue_event_conf ( enum sla_event_type  type,
struct ast_channel chan,
struct ast_conference conf 
)
static

Queue a SLA event from the conference.

Definition at line 2462 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_debug, AST_LIST_TRAVERSE, ast_log, ast_strdupa, ast_strlen_zero, sla_trunk_ref::chan, ast_conference::confno, LOG_ERROR, sla_trunk::name, NULL, sla_queue_event_full(), strsep(), sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by conf_run().

2464 {
2465  struct sla_station *station;
2466  struct sla_trunk_ref *trunk_ref = NULL;
2467  char *trunk_name;
2468  struct ao2_iterator i;
2469 
2470  trunk_name = ast_strdupa(conf->confno);
2471  strsep(&trunk_name, "_");
2472  if (ast_strlen_zero(trunk_name)) {
2473  ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", conf->confno);
2474  return;
2475  }
2476 
2478  while ((station = ao2_iterator_next(&i))) {
2479  ao2_lock(station);
2480  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2481  if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name)) {
2482  ao2_ref(trunk_ref, 1);
2483  break;
2484  }
2485  }
2486  ao2_unlock(station);
2487  if (trunk_ref) {
2488  /* station reference given to sla_queue_event_full() */
2489  break;
2490  }
2491  ao2_ref(station, -1);
2492  }
2494 
2495  if (!trunk_ref) {
2496  ast_debug(1, "Trunk not found for event!\n");
2497  return;
2498  }
2499 
2500  sla_queue_event_full(type, trunk_ref, station, 1);
2501 }
const ast_string_field name
Definition: app_meetme.c:986
static const char type[]
Definition: chan_ooh323.c:109
struct sla_trunk * trunk
Definition: app_meetme.c:1017
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void sla_queue_event_full(enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
Definition: app_meetme.c:2419
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
struct ast_channel * chan
Definition: app_meetme.c:1019
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * strsep(char **str, const char *delims)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char confno[MAX_CONFNUM]
Definition: app_meetme.c:845

◆ sla_queue_event_full()

static void sla_queue_event_full ( enum sla_event_type  type,
struct sla_trunk_ref trunk_ref,
struct sla_station station,
int  lock 
)
static

Definition at line 2419 of file app_meetme.c.

References ao2_ref, ast_calloc, ast_cond_signal, AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, sla, sla_event::station, sla_event::trunk_ref, and type.

Referenced by sla_queue_event(), sla_queue_event_conf(), and sla_queue_event_nolock().

2421 {
2422  struct sla_event *event;
2423 
2424  if (sla.thread == AST_PTHREADT_NULL) {
2425  ao2_ref(station, -1);
2426  ao2_ref(trunk_ref, -1);
2427  return;
2428  }
2429 
2430  if (!(event = ast_calloc(1, sizeof(*event)))) {
2431  ao2_ref(station, -1);
2432  ao2_ref(trunk_ref, -1);
2433  return;
2434  }
2435 
2436  event->type = type;
2437  event->trunk_ref = trunk_ref;
2438  event->station = station;
2439 
2440  if (!lock) {
2441  AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
2442  return;
2443  }
2444 
2445  ast_mutex_lock(&sla.lock);
2446  AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
2447  ast_cond_signal(&sla.cond);
2448  ast_mutex_unlock(&sla.lock);
2449 }
static const char type[]
Definition: chan_ooh323.c:109
static struct @35 sla
A structure for data used by the sla thread.
struct sla_station * station
Definition: app_meetme.c:1049
Definition: astman.c:222
#define ast_mutex_lock(a)
Definition: lock.h:187
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:1050
#define ast_cond_signal(cond)
Definition: lock.h:201
#define AST_PTHREADT_NULL
Definition: lock.h:66
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#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
Definition: search.h:40
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_queue_event_nolock()

static void sla_queue_event_nolock ( enum sla_event_type  type)
static

Definition at line 2451 of file app_meetme.c.

References NULL, and sla_queue_event_full().

Referenced by sla_process_timers().

2452 {
2454 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
static void sla_queue_event_full(enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
Definition: app_meetme.c:2419

◆ sla_ring_station()

static int sla_ring_station ( struct sla_ringing_trunk ringing_trunk,
struct sla_station station 
)
static

Ring a station.

Note
Assumes sla.lock is locked

Definition at line 6355 of file app_meetme.c.

References ast_channel_caller(), ast_channel_caller_set(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_join(), AST_DIAL_RESULT_TRYING, ast_dial_run(), ast_dial_set_state_callback(), AST_LIST_INSERT_HEAD, ast_party_caller_free(), ast_party_caller_init(), ast_strdupa, sla_trunk::chan, sla_station::dial, NULL, sla, sla_create_failed_station(), sla_create_ringing_station(), sla_dial_state_callback(), strsep(), and sla_ringing_trunk::trunk.

Referenced by sla_ring_stations().

6356 {
6357  char *tech, *tech_data;
6358  struct ast_dial *dial;
6359  struct sla_ringing_station *ringing_station;
6360  enum ast_dial_result res;
6361  int caller_is_saved;
6362  struct ast_party_caller caller;
6363 
6364  if (!(dial = ast_dial_create()))
6365  return -1;
6366 
6368  tech_data = ast_strdupa(station->device);
6369  tech = strsep(&tech_data, "/");
6370 
6371  if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
6372  ast_dial_destroy(dial);
6373  return -1;
6374  }
6375 
6376  /* Do we need to save off the caller ID data? */
6377  caller_is_saved = 0;
6378  if (!sla.attempt_callerid) {
6379  caller_is_saved = 1;
6380  caller = *ast_channel_caller(ringing_trunk->trunk->chan);
6382  }
6383 
6384  res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
6385 
6386  /* Restore saved caller ID */
6387  if (caller_is_saved) {
6389  ast_channel_caller_set(ringing_trunk->trunk->chan, &caller);
6390  }
6391 
6392  if (res != AST_DIAL_RESULT_TRYING) {
6393  struct sla_failed_station *failed_station;
6394  ast_dial_destroy(dial);
6395  if ((failed_station = sla_create_failed_station(station))) {
6396  AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
6397  }
6398  return -1;
6399  }
6400  if (!(ringing_station = sla_create_ringing_station(station))) {
6401  ast_dial_join(dial);
6402  ast_dial_destroy(dial);
6403  return -1;
6404  }
6405 
6406  station->dial = dial;
6407 
6408  AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_station, entry);
6409 
6410  return 0;
6411 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
static struct @35 sla
A structure for data used by the sla thread.
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:48
struct ast_channel * chan
Definition: app_meetme.c:994
static void sla_dial_state_callback(struct ast_dial *dial)
Definition: app_meetme.c:6167
struct ast_dial * dial
Definition: app_meetme.c:950
A station that is ringing.
Definition: app_meetme.c:1077
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2015
#define NULL
Definition: resample.c:96
static struct sla_failed_station * sla_create_failed_station(struct sla_station *station)
Definition: app_meetme.c:5987
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
Definition: dial.c:1293
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
Caller Party information.
Definition: channel.h:419
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct sla_ringing_station * sla_create_ringing_station(struct sla_station *station)
Definition: app_meetme.c:5963
void ast_channel_caller_set(struct ast_channel *chan, struct ast_party_caller *value)
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:939
struct sla_trunk * trunk
Definition: app_meetme.c:1064
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:282
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:225
char * strsep(char **str, const char *delims)
A station that failed to be dialed.
Definition: app_meetme.c:1056
Definition: search.h:40
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:1978

◆ sla_ring_stations()

static void sla_ring_stations ( void  )
static

Ring stations based on current set of ringing trunks.

Note
Assumes that sla.lock is locked

Definition at line 6480 of file app_meetme.c.

References AST_LIST_TRAVERSE, sla, sla_check_failed_station(), sla_check_inuse_station(), sla_check_ringing_station(), sla_check_station_delay(), sla_check_timed_out_station(), sla_ring_station(), sla_station_ref::station, sla_trunk::stations, and sla_ringing_trunk::trunk.

Referenced by sla_handle_ringing_trunk_event().

6481 {
6482  struct sla_station_ref *station_ref;
6483  struct sla_ringing_trunk *ringing_trunk;
6484 
6485  /* Make sure that every station that uses at least one of the ringing
6486  * trunks, is ringing. */
6487  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6488  AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
6489  int time_left;
6490 
6491  /* Is this station already ringing? */
6492  if (sla_check_ringing_station(station_ref->station))
6493  continue;
6494 
6495  /* Is this station already in a call? */
6496  if (sla_check_inuse_station(station_ref->station))
6497  continue;
6498 
6499  /* Did we fail to dial this station earlier? If so, has it been
6500  * a minute since we tried? */
6501  if (sla_check_failed_station(station_ref->station))
6502  continue;
6503 
6504  /* If this station already timed out while this trunk was ringing,
6505  * do not dial it again for this ringing trunk. */
6506  if (sla_check_timed_out_station(ringing_trunk, station_ref->station))
6507  continue;
6508 
6509  /* Check for a ring delay in progress */
6510  time_left = sla_check_station_delay(station_ref->station, ringing_trunk);
6511  if (time_left != INT_MAX && time_left > 0)
6512  continue;
6513 
6514  /* It is time to make this station begin to ring. Do it! */
6515  sla_ring_station(ringing_trunk, station_ref->station);
6516  }
6517  }
6518  /* Now, all of the stations that should be ringing, are ringing. */
6519 }
static struct @35 sla
A structure for data used by the sla thread.
static int sla_check_ringing_station(const struct sla_station *station)
Check to see if this station is already ringing.
Definition: app_meetme.c:6317
A reference to a station.
Definition: app_meetme.c:974
static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
Ring a station.
Definition: app_meetme.c:6355
static int sla_check_station_delay(struct sla_station *station, struct sla_ringing_trunk *ringing_trunk)
Calculate the ring delay for a given ringing trunk on a station.
Definition: app_meetme.c:6447
A trunk that is ringing.
Definition: app_meetme.c:1063
struct sla_trunk * trunk
Definition: app_meetme.c:1064
struct sla_trunk::@43 stations
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int sla_check_failed_station(const struct sla_station *station)
Check to see if this station has failed to be dialed in the past minute.
Definition: app_meetme.c:6332
Definition: search.h:40
static int sla_check_inuse_station(const struct sla_station *station)
Check to see if a station is in use.
Definition: app_meetme.c:6415
struct sla_station * station
Definition: app_meetme.c:976
static int sla_check_timed_out_station(const struct sla_ringing_trunk *ringing_trunk, const struct sla_station *station)
Check to see if dialing this station already timed out for this ringing trunk.
Definition: app_meetme.c:6175

◆ sla_ringing_station_destroy()

static void sla_ringing_station_destroy ( struct sla_ringing_station ringing_station)
static

Definition at line 5977 of file app_meetme.c.

References ao2_ref, ast_free, NULL, and sla_ringing_station::station.

Referenced by sla_handle_dial_state_event(), sla_hangup_stations(), sla_stop_ringing_station(), and sla_thread().

5978 {
5979  if (ringing_station->station) {
5980  ao2_ref(ringing_station->station, -1);
5981  ringing_station->station = NULL;
5982  }
5983 
5984  ast_free(ringing_station);
5985 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_free(a)
Definition: astmm.h:182
struct sla_station * station
Definition: app_meetme.c:1078

◆ sla_ringing_trunk_destroy()

static void sla_ringing_trunk_destroy ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 7205 of file app_meetme.c.

References ao2_ref, ast_free, NULL, and sla_ringing_trunk::trunk.

Referenced by run_station(), sla_handle_dial_state_event(), sla_station_exec(), sla_stop_ringing_trunk(), and sla_trunk_exec().

7206 {
7207  if (ringing_trunk->trunk) {
7208  ao2_ref(ringing_trunk->trunk, -1);
7209  ringing_trunk->trunk = NULL;
7210  }
7211 
7212  ast_free(ringing_trunk);
7213 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define ast_free(a)
Definition: astmm.h:182

◆ sla_show_stations()

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

Definition at line 2207 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), AST_LIST_TRAVERSE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, sla_station::hold_access, sla_trunk::name, NULL, sla_station::ring_delay, sla_trunk_ref::ring_delay, sla_station::ring_timeout, sla_trunk_ref::ring_timeout, S_OR, sla_hold_str(), sla_trunk_ref::state, sla_trunk_ref::trunk, sla_station::trunks, trunkstate2str(), and ast_cli_entry::usage.

2208 {
2209  struct ao2_iterator i;
2210  struct sla_station *station;
2211 
2212  switch (cmd) {
2213  case CLI_INIT:
2214  e->command = "sla show stations";
2215  e->usage =
2216  "Usage: sla show stations\n"
2217  " This will list all stations defined in sla.conf\n";
2218  return NULL;
2219  case CLI_GENERATE:
2220  return NULL;
2221  }
2222 
2223  ast_cli(a->fd, "\n"
2224  "=============================================================\n"
2225  "=== Configured SLA Stations =================================\n"
2226  "=============================================================\n"
2227  "===\n");
2229  for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
2230  struct sla_trunk_ref *trunk_ref;
2231  char ring_timeout[16] = "(none)";
2232  char ring_delay[16] = "(none)";
2233 
2234  ao2_lock(station);
2235 
2236  if (station->ring_timeout) {
2237  snprintf(ring_timeout, sizeof(ring_timeout),
2238  "%u", station->ring_timeout);
2239  }
2240  if (station->ring_delay) {
2241  snprintf(ring_delay, sizeof(ring_delay),
2242  "%u", station->ring_delay);
2243  }
2244  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
2245  "=== Station Name: %s\n"
2246  "=== ==> Device: %s\n"
2247  "=== ==> AutoContext: %s\n"
2248  "=== ==> RingTimeout: %s\n"
2249  "=== ==> RingDelay: %s\n"
2250  "=== ==> HoldAccess: %s\n"
2251  "=== ==> Trunks ...\n",
2252  station->name, station->device,
2253  S_OR(station->autocontext, "(none)"),
2254  ring_timeout, ring_delay,
2255  sla_hold_str(station->hold_access));
2256  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2257  if (trunk_ref->ring_timeout) {
2258  snprintf(ring_timeout, sizeof(ring_timeout),
2259  "%u", trunk_ref->ring_timeout);
2260  } else {
2261  strcpy(ring_timeout, "(none)");
2262  }
2263  if (trunk_ref->ring_delay) {
2264  snprintf(ring_delay, sizeof(ring_delay),
2265  "%u", trunk_ref->ring_delay);
2266  } else {
2267  strcpy(ring_delay, "(none)");
2268  }
2269 
2270  ast_cli(a->fd, "=== ==> Trunk Name: %s\n"
2271  "=== ==> State: %s\n"
2272  "=== ==> RingTimeout: %s\n"
2273  "=== ==> RingDelay: %s\n",
2274  trunk_ref->trunk->name,
2275  trunkstate2str(trunk_ref->state),
2276  ring_timeout, ring_delay);
2277  }
2278  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
2279  "===\n");
2280 
2281  ao2_unlock(station);
2282  }
2284  ast_cli(a->fd, "============================================================\n"
2285  "\n");
2286 
2287  return CLI_SUCCESS;
2288 }
const ast_string_field name
Definition: app_meetme.c:986
unsigned int ring_timeout
Definition: app_meetme.c:1023
struct sla_trunk * trunk
Definition: app_meetme.c:1017
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
unsigned int ring_delay
Definition: app_meetme.c:958
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int hold_access
Definition: app_meetme.c:961
enum sla_trunk_state state
Definition: app_meetme.c:1018
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char * trunkstate2str(enum sla_trunk_state state)
Definition: app_meetme.c:2193
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#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
static const char * sla_hold_str(unsigned int hold_access)
Definition: app_meetme.c:2116
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
unsigned int ring_timeout
Definition: app_meetme.c:954
static struct ao2_container * sla_stations
Definition: app_meetme.c:1032
unsigned int ring_delay
Definition: app_meetme.c:1027
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sla_show_trunks()

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

Definition at line 2133 of file app_meetme.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli(), AST_LIST_TRAVERSE, sla_trunk::autocontext, sla_trunk::barge_disabled, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, sla_trunk::device, ast_cli_args::fd, sla_trunk::hold_access, sla_trunk::name, NULL, sla_trunk::ring_timeout, S_OR, sla_hold_str(), sla_station_ref::station, sla_trunk::stations, and ast_cli_entry::usage.

2134 {
2135  struct ao2_iterator i;
2136  struct sla_trunk *trunk;
2137 
2138  switch (cmd) {
2139  case CLI_INIT:
2140  e->command = "sla show trunks";
2141  e->usage =
2142  "Usage: sla show trunks\n"
2143  " This will list all trunks defined in sla.conf\n";
2144  return NULL;
2145  case CLI_GENERATE:
2146  return NULL;
2147  }
2148 
2149  ast_cli(a->fd, "\n"
2150  "=============================================================\n"
2151  "=== Configured SLA Trunks ===================================\n"
2152  "=============================================================\n"
2153  "===\n");
2154  i = ao2_iterator_init(sla_trunks, 0);
2155  for (; (trunk = ao2_iterator_next(&i)); ao2_ref(trunk, -1)) {
2156  struct sla_station_ref *station_ref;
2157  char ring_timeout[16] = "(none)";
2158 
2159  ao2_lock(trunk);
2160 
2161  if (trunk->ring_timeout) {
2162  snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
2163  }
2164 
2165  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
2166  "=== Trunk Name: %s\n"
2167  "=== ==> Device: %s\n"
2168  "=== ==> AutoContext: %s\n"
2169  "=== ==> RingTimeout: %s\n"
2170  "=== ==> BargeAllowed: %s\n"
2171  "=== ==> HoldAccess: %s\n"
2172  "=== ==> Stations ...\n",
2173  trunk->name, trunk->device,
2174  S_OR(trunk->autocontext, "(none)"),
2175  ring_timeout,
2176  trunk->barge_disabled ? "No" : "Yes",
2177  sla_hold_str(trunk->hold_access));
2178 
2179  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
2180  ast_cli(a->fd, "=== ==> Station name: %s\n", station_ref->station->name);
2181  }
2182 
2183  ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
2184 
2185  ao2_unlock(trunk);
2186  }
2188  ast_cli(a->fd, "=============================================================\n\n");
2189 
2190  return CLI_SUCCESS;
2191 }
const ast_string_field name
Definition: app_meetme.c:986
const ast_string_field autocontext
Definition: app_meetme.c:986
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
A reference to a station.
Definition: app_meetme.c:974
#define ao2_unlock(a)
Definition: astobj2.h:730
const ast_string_field device
Definition: app_meetme.c:986
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int barge_disabled
Definition: app_meetme.c:998
struct sla_trunk::@43 stations
unsigned int hold_access
Definition: app_meetme.c:1001
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
unsigned int ring_timeout
Definition: app_meetme.c:995
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#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
static const char * sla_hold_str(unsigned int hold_access)
Definition: app_meetme.c:2116
Definition: search.h:40
static struct ao2_container * sla_trunks
Definition: app_meetme.c:1033
struct sla_station * station
Definition: app_meetme.c:976
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ sla_state()

static enum ast_device_state sla_state ( const char *  data)
static

Definition at line 7326 of file app_meetme.c.

References ao2_cleanup, ao2_lock, ao2_unlock, AST_DEVICE_INVALID, AST_LIST_TRAVERSE, ast_log, ast_strdupa, buf, LOG_ERROR, sla_trunk::name, NULL, RAII_VAR, sla_find_station(), sla_state_to_devstate(), sla_trunk_ref::state, strsep(), and sla_trunk_ref::trunk.

Referenced by load_module().

7327 {
7328  char *buf, *station_name, *trunk_name;
7330  struct sla_trunk_ref *trunk_ref;
7332 
7333  trunk_name = buf = ast_strdupa(data);
7334  station_name = strsep(&trunk_name, "_");
7335 
7336  station = sla_find_station(station_name);
7337  if (station) {
7338  ao2_lock(station);
7339  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7340  if (!strcasecmp(trunk_name, trunk_ref->trunk->name)) {
7341  res = sla_state_to_devstate(trunk_ref->state);
7342  break;
7343  }
7344  }
7345  ao2_unlock(station);
7346  }
7347 
7348  if (res == AST_DEVICE_INVALID) {
7349  ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n",
7350  trunk_name, station_name);
7351  }
7352 
7353  return res;
7354 }
const ast_string_field name
Definition: app_meetme.c:986
ast_device_state
Device States.
Definition: devicestate.h:52
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
Definition: app_meetme.c:6012
enum sla_trunk_state state
Definition: app_meetme.c:1018
#define ast_log
Definition: astobj2.c:42
#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
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Definition: search.h:40
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5871
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_state_to_devstate()

static enum ast_device_state sla_state_to_devstate ( enum sla_trunk_state  state)
static

◆ sla_station_cmp()

static int sla_station_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7413 of file app_meetme.c.

References CMP_MATCH, and CMP_STOP.

Referenced by sla_load_config().

7414 {
7415  struct sla_station *station = obj, *station2 = arg;
7416 
7417  return !strcasecmp(station->name, station2->name) ? CMP_MATCH | CMP_STOP : 0;
7418 }

◆ sla_station_destructor()

static void sla_station_destructor ( void *  obj)
static

Definition at line 7380 of file app_meetme.c.

References ast_context_remove_extension(), ast_debug, AST_LIST_TRAVERSE, AST_MAX_APP, AST_MAX_EXTENSION, ast_string_field_free_memory, ast_strlen_zero, exten, sla_trunk::name, NULL, PRIORITY_HINT, sla_station_release_refs(), sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by sla_build_station().

7381 {
7382  struct sla_station *station = obj;
7383 
7384  ast_debug(1, "sla_station destructor for '%s'\n", station->name);
7385 
7386  if (!ast_strlen_zero(station->autocontext)) {
7387  struct sla_trunk_ref *trunk_ref;
7388 
7389  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7390  char exten[AST_MAX_EXTENSION];
7391  char hint[AST_MAX_APP];
7392  snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
7393  snprintf(hint, sizeof(hint), "SLA:%s", exten);
7394  ast_context_remove_extension(station->autocontext, exten,
7395  1, sla_registrar);
7396  ast_context_remove_extension(station->autocontext, hint,
7398  }
7399  }
7400 
7401  sla_station_release_refs(station, NULL, 0);
7402 
7404 }
const ast_string_field name
Definition: app_meetme.c:986
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#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
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define PRIORITY_HINT
Definition: pbx.h:54
#define AST_MAX_APP
Definition: pbx.h:40
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7368
static const char sla_registrar[]
Definition: app_meetme.c:1035
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sla_station_exec()

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

Definition at line 7006 of file app_meetme.c.

References sla_trunk::active_stations, admin_exec(), ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_answer(), ast_atomic_dec_and_test(), ast_atomic_fetchadd_int(), ast_autoservice_start(), ast_autoservice_stop(), ast_cond_destroy, ast_cond_init, ast_cond_wait, AST_CONTROL_UNHOLD, ast_debug, AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_indicate(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_detached_background, ast_set_flag64, ast_strdupa, ast_strlen_zero, build_conf(), sla_trunk::chan, sla_trunk_ref::chan, cond, dial_trunk_args::cond_lock, conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_STATION, dial_trunk(), dispose_conf(), sla_trunk::hold_stations, LOG_NOTICE, LOG_WARNING, MAX_CONFNUM, sla_trunk::name, NULL, sla_trunk::on_hold, pbx_builtin_setvar_helper(), RAII_VAR, sla, sla_change_trunk_state(), sla_choose_idle_trunk(), SLA_EVENT_DIAL_STATE, SLA_EVENT_RINGING_TRUNK, sla_find_station(), sla_find_trunk_ref_byname(), sla_queue_event(), sla_ringing_trunk_destroy(), SLA_TRUNK_STATE_IDLE, SLA_TRUNK_STATE_ONHOLD_BYME, SLA_TRUNK_STATE_RINGING, SLA_TRUNK_STATE_UP, sla_trunk_ref::state, dial_trunk_args::station, strsep(), sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and dial_trunk_args::trunk_ref.

Referenced by load_module().

7007 {
7008  char *station_name, *trunk_name;
7009  RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
7010  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
7011  char conf_name[MAX_CONFNUM];
7012  struct ast_flags64 conf_flags = { 0 };
7013  struct ast_conference *conf;
7014 
7015  if (ast_strlen_zero(data)) {
7016  ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
7017  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
7018  return 0;
7019  }
7020 
7021  trunk_name = ast_strdupa(data);
7022  station_name = strsep(&trunk_name, "_");
7023 
7024  if (ast_strlen_zero(station_name)) {
7025  ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
7026  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
7027  return 0;
7028  }
7029 
7030  station = sla_find_station(station_name);
7031 
7032  if (!station) {
7033  ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
7034  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
7035  return 0;
7036  }
7037 
7038  ao2_lock(station);
7039  if (!ast_strlen_zero(trunk_name)) {
7040  trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
7041  } else {
7042  trunk_ref = sla_choose_idle_trunk(station);
7043  }
7044  ao2_unlock(station);
7045 
7046  if (!trunk_ref) {
7047  if (ast_strlen_zero(trunk_name))
7048  ast_log(LOG_NOTICE, "No trunks available for call.\n");
7049  else {
7050  ast_log(LOG_NOTICE, "Can't join existing call on trunk "
7051  "'%s' due to access controls.\n", trunk_name);
7052  }
7053  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
7054  return 0;
7055  }
7056 
7057  if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
7058  if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1)
7060  else {
7061  trunk_ref->state = SLA_TRUNK_STATE_UP;
7063  "SLA:%s_%s", station->name, trunk_ref->trunk->name);
7064  }
7065  } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
7066  struct sla_ringing_trunk *ringing_trunk;
7067 
7068  ast_mutex_lock(&sla.lock);
7069  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
7070  if (ringing_trunk->trunk == trunk_ref->trunk) {
7072  break;
7073  }
7074  }
7076  ast_mutex_unlock(&sla.lock);
7077 
7078  if (ringing_trunk) {
7079  answer_trunk_chan(ringing_trunk->trunk->chan);
7081 
7082  sla_ringing_trunk_destroy(ringing_trunk);
7083 
7084  /* Queue up reprocessing ringing trunks, and then ringing stations again */
7087  }
7088  }
7089 
7090  trunk_ref->chan = chan;
7091 
7092  if (!trunk_ref->trunk->chan) {
7093  ast_mutex_t cond_lock;
7094  ast_cond_t cond;
7095  pthread_t dont_care;
7096  struct dial_trunk_args args = {
7097  .trunk_ref = trunk_ref,
7098  .station = station,
7099  .cond_lock = &cond_lock,
7100  .cond = &cond,
7101  };
7102  ao2_ref(trunk_ref, 1);
7103  ao2_ref(station, 1);
7105  /* Create a thread to dial the trunk and dump it into the conference.
7106  * However, we want to wait until the trunk has been dialed and the
7107  * conference is created before continuing on here. */
7108  ast_autoservice_start(chan);
7109  ast_mutex_init(&cond_lock);
7110  ast_cond_init(&cond, NULL);
7111  ast_mutex_lock(&cond_lock);
7113  ast_cond_wait(&cond, &cond_lock);
7114  ast_mutex_unlock(&cond_lock);
7115  ast_mutex_destroy(&cond_lock);
7116  ast_cond_destroy(&cond);
7117  ast_autoservice_stop(chan);
7118  if (!trunk_ref->trunk->chan) {
7119  ast_debug(1, "Trunk didn't get created. chan: %lx\n", (unsigned long) trunk_ref->trunk->chan);
7120  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
7122  trunk_ref->chan = NULL;
7123  return 0;
7124  }
7125  }
7126 
7127  if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
7128  trunk_ref->trunk->on_hold) {
7129  trunk_ref->trunk->on_hold = 0;
7132  }
7133 
7134  snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
7135  ast_set_flag64(&conf_flags,
7137  ast_answer(chan);
7138  conf = build_conf(conf_name, "", "", 0, 0, 1, chan, NULL);
7139  if (conf) {
7140  conf_run(chan, conf, &conf_flags, NULL);
7141  dispose_conf(conf);
7142  conf = NULL;
7143  }
7144  trunk_ref->chan = NULL;
7147  strncat(conf_name, ",K", sizeof(conf_name) - strlen(conf_name) - 1);
7148  admin_exec(NULL, conf_name);
7151  }
7152 
7153  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
7154 
7155  return 0;
7156 }
const ast_string_field name
Definition: app_meetme.c:986
unsigned int active_stations
Definition: app_meetme.c:991
static struct sla_trunk_ref * sla_choose_idle_trunk(const struct sla_station *station)
For a given station, choose the highest priority idle trunk.
Definition: app_meetme.c:6992
static struct @35 sla
A structure for data used by the sla thread.
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * chan
Definition: app_meetme.c:994
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_cond_init(cond, attr)
Definition: lock.h:199
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ao2_unlock(a)
Definition: astobj2.h:730
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:6062
const char * args
#define NULL
Definition: resample.c:96
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2456
ast_mutex_t * cond_lock
Definition: app_meetme.c:6848
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_strlen_zero(foo)
Definition: strings.h:52
enum sla_trunk_state state
Definition: app_meetme.c:1018
All configuration options for statsd client.
Definition: res_statsd.c:95
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:3177
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct sla_station * station
Definition: app_meetme.c:6847
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
#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
unsigned int on_hold
Definition: app_meetme.c:1004
A trunk that is ringing.
Definition: app_meetme.c:1063
ast_cond_t cond
Definition: app_meetme.c:1090
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
Definition: lock.h:765
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:6846
struct sla_trunk * trunk
Definition: app_meetme.c:1064
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:7205
struct ast_channel * chan
Definition: app_meetme.c:1019
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define LOG_NOTICE
Definition: logger.h:263
unsigned int hold_stations
Definition: app_meetme.c:993
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...
static void * dial_trunk(void *data)
Definition: app_meetme.c:6852
char * strsep(char **str, const char *delims)
#define MAX_CONFNUM
Definition: app_meetme.c:819
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:5225
Definition: search.h:40
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5871
static struct sla_trunk_ref * sla_find_trunk_ref_byname(const struct sla_station *station, const char *name)
Find a trunk reference on a station by name.
Definition: app_meetme.c:5910
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define ast_mutex_init(pmutex)
Definition: lock.h:184
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015
#define ast_mutex_destroy(a)
Definition: lock.h:186
The MeetMe Conference object.
Definition: app_meetme.c:842
Structure for mutex and tracking information.
Definition: lock.h:135
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_station_is_marked()

static int sla_station_is_marked ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7822 of file app_meetme.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, CMP_MATCH, sla_station::mark, sla_trunk_ref::mark, NULL, sla_station_release_refs(), and sla_station::trunks.

Referenced by sla_load_config().

7823 {
7824  struct sla_station *station = obj;
7825 
7826  ao2_lock(station);
7827 
7828  if (station->mark) {
7829  /* Only remove all of the trunk references if the station itself is going away */
7830  sla_station_release_refs(station, NULL, 0);
7831  } else {
7832  struct sla_trunk_ref *trunk_ref;
7833 
7834  /* Otherwise only remove references to trunks no longer in the config */
7835  AST_LIST_TRAVERSE_SAFE_BEGIN(&station->trunks, trunk_ref, entry) {
7836  if (!trunk_ref->mark) {
7837  continue;
7838  }
7840  ao2_ref(trunk_ref, -1);
7841  }
7843  }
7844 
7845  ao2_unlock(station);
7846 
7847  return station->mark ? CMP_MATCH : 0;
7848 }
unsigned int mark
Definition: app_meetme.c:1029
unsigned int mark
Definition: app_meetme.c:963
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7368
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_station_mark()

static int sla_station_mark ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7776 of file app_meetme.c.

References ao2_lock, ao2_unlock, AST_LIST_TRAVERSE, sla_station::mark, sla_trunk_ref::mark, and sla_station::trunks.

Referenced by sla_load_config().

7777 {
7778  struct sla_station *station = obj;
7779  struct sla_trunk_ref *trunk_ref;
7780 
7781  ao2_lock(station);
7782 
7783  station->mark = 1;
7784 
7785  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7786  trunk_ref->mark = 1;
7787  }
7788 
7789  ao2_unlock(station);
7790 
7791  return 0;
7792 }
unsigned int mark
Definition: app_meetme.c:1029
unsigned int mark
Definition: app_meetme.c:963
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_station_ref_destructor()

static void sla_station_ref_destructor ( void *  obj)
static

Definition at line 5939 of file app_meetme.c.

References ao2_ref, NULL, and sla_station_ref::station.

Referenced by sla_create_station_ref().

5940 {
5941  struct sla_station_ref *station_ref = obj;
5942 
5943  if (station_ref->station) {
5944  ao2_ref(station_ref->station, -1);
5945  station_ref->station = NULL;
5946  }
5947 }
A reference to a station.
Definition: app_meetme.c:974
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct sla_station * station
Definition: app_meetme.c:976

◆ sla_station_release_refs()

static int sla_station_release_refs ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7368 of file app_meetme.c.

References ao2_ref, AST_LIST_REMOVE_HEAD, and sla_station::trunks.

Referenced by sla_destroy(), sla_station_destructor(), and sla_station_is_marked().

7369 {
7370  struct sla_station *station = obj;
7371  struct sla_trunk_ref *trunk_ref;
7372 
7373  while ((trunk_ref = AST_LIST_REMOVE_HEAD(&station->trunks, entry))) {
7374  ao2_ref(trunk_ref, -1);
7375  }
7376 
7377  return 0;
7378 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_stop_ringing_station()

static void sla_stop_ringing_station ( struct sla_ringing_station ringing_station,
enum sla_station_hangup  hangup 
)
static

Definition at line 6132 of file app_meetme.c.

References ast_dial_destroy(), ast_dial_join(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, sla_station::dial, done, NULL, sla, sla_create_station_ref(), sla_ringing_station_destroy(), SLA_STATION_HANGUP_NORMAL, sla_ringing_station::station, sla_ringing_trunk::timed_out_stations, sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and sla_station::trunks.

Referenced by sla_calc_station_timeouts(), and sla_handle_dial_state_event().

6134 {
6135  struct sla_ringing_trunk *ringing_trunk;
6136  struct sla_trunk_ref *trunk_ref;
6137  struct sla_station_ref *station_ref;
6138 
6139  ast_dial_join(ringing_station->station->dial);
6140  ast_dial_destroy(ringing_station->station->dial);
6141  ringing_station->station->dial = NULL;
6142 
6144  goto done;
6145 
6146  /* If the station is being hung up because of a timeout, then add it to the
6147  * list of timed out stations on each of the ringing trunks. This is so
6148  * that when doing further processing to figure out which stations should be
6149  * ringing, which trunk to answer, determining timeouts, etc., we know which
6150  * ringing trunks we should ignore. */
6151  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6152  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
6153  if (ringing_trunk->trunk == trunk_ref->trunk)
6154  break;
6155  }
6156  if (!trunk_ref)
6157  continue;
6158  if (!(station_ref = sla_create_station_ref(ringing_station->station)))
6159  continue;
6160  AST_LIST_INSERT_TAIL(&ringing_trunk->timed_out_stations, station_ref, entry);
6161  }
6162 
6163 done:
6164  sla_ringing_station_destroy(ringing_station);
6165 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
static struct @35 sla
A structure for data used by the sla thread.
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5977
struct sla_trunk * trunk
Definition: app_meetme.c:1017
struct ast_dial * dial
Definition: app_meetme.c:950
A reference to a station.
Definition: app_meetme.c:974
static int hangup(void *data)
Definition: chan_pjsip.c:2483
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1021
A trunk that is ringing.
Definition: app_meetme.c:1063
static struct sla_station_ref * sla_create_station_ref(struct sla_station *station)
Definition: app_meetme.c:5949
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_station * station
Definition: app_meetme.c:1078
struct sla_ringing_trunk::@47 timed_out_stations
Definition: search.h:40
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_stop_ringing_trunk()

static void sla_stop_ringing_trunk ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 6116 of file app_meetme.c.

References admin_exec(), ALL_TRUNK_REFS, ao2_ref, AST_LIST_REMOVE_HEAD, buf, sla_trunk::name, NULL, sla_change_trunk_state(), sla_ringing_trunk_destroy(), SLA_TRUNK_STATE_IDLE, sla_ringing_trunk::timed_out_stations, and sla_ringing_trunk::trunk.

Referenced by sla_calc_trunk_timeouts().

6117 {
6118  char buf[80];
6119  struct sla_station_ref *station_ref;
6120 
6121  snprintf(buf, sizeof(buf), "SLA_%s,K", ringing_trunk->trunk->name);
6122  admin_exec(NULL, buf);
6124 
6125  while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry))) {
6126  ao2_ref(station_ref, -1);
6127  }
6128 
6129  sla_ringing_trunk_destroy(ringing_trunk);
6130 }
const ast_string_field name
Definition: app_meetme.c:986
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
A reference to a station.
Definition: app_meetme.c:974
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct sla_trunk * trunk
Definition: app_meetme.c:1064
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:7205
struct sla_ringing_trunk::@47 timed_out_stations
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:5225
Definition: search.h:40

◆ sla_thread()

static void* sla_thread ( void *  data)
static

Definition at line 6790 of file app_meetme.c.

References ast_cond_timedwait, ast_cond_wait, AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, NULL, sla, sla_event_destroy(), SLA_EVENT_DIAL_STATE, SLA_EVENT_HOLD, SLA_EVENT_RINGING_TRUNK, sla_failed_station_destroy(), sla_handle_dial_state_event(), sla_handle_hold_event(), sla_handle_ringing_trunk_event(), sla_process_timers(), sla_ringing_station_destroy(), and sla_event::type.

Referenced by sla_load_config().

6791 {
6792  struct sla_failed_station *failed_station;
6793  struct sla_ringing_station *ringing_station;
6794 
6795  ast_mutex_lock(&sla.lock);
6796 
6797  while (!sla.stop) {
6798  struct sla_event *event;
6799  struct timespec ts = { 0, };
6800  unsigned int have_timeout = 0;
6801 
6802  if (AST_LIST_EMPTY(&sla.event_q)) {
6803  if ((have_timeout = sla_process_timers(&ts)))
6804  ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
6805  else
6806  ast_cond_wait(&sla.cond, &sla.lock);
6807  if (sla.stop)
6808  break;
6809  }
6810 
6811  if (have_timeout)
6813 
6814  while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
6815  ast_mutex_unlock(&sla.lock);
6816  switch (event->type) {
6817  case SLA_EVENT_HOLD:
6818  sla_handle_hold_event(event);
6819  break;
6820  case SLA_EVENT_DIAL_STATE:
6822  break;
6825  break;
6826  }
6827  sla_event_destroy(event);
6828  ast_mutex_lock(&sla.lock);
6829  }
6830  }
6831 
6832  ast_mutex_unlock(&sla.lock);
6833 
6834  while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry))) {
6835  sla_ringing_station_destroy(ringing_station);
6836  }
6837 
6838  while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry))) {
6839  sla_failed_station_destroy(failed_station);
6840  }
6841 
6842  return NULL;
6843 }
static struct @35 sla
A structure for data used by the sla thread.
static void sla_handle_ringing_trunk_event(void)
Definition: app_meetme.c:6549
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5977
A station that is ringing.
Definition: app_meetme.c:1077
static void sla_event_destroy(struct sla_event *event)
Definition: app_meetme.c:6775
Definition: astman.c:222
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
enum sla_event_type type
Definition: app_meetme.c:1048
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static int sla_process_timers(struct timespec *ts)
Calculate the time until the next known event.
Definition: app_meetme.c:6740
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
A station that failed to be dialed.
Definition: app_meetme.c:1056
static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
Definition: app_meetme.c:6002
Definition: search.h:40
static void sla_handle_dial_state_event(void)
Definition: app_meetme.c:6232
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
static void sla_handle_hold_event(struct sla_event *event)
Definition: app_meetme.c:6559
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sla_trunk_cmp()

static int sla_trunk_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7406 of file app_meetme.c.

References CMP_MATCH, CMP_STOP, and sla_trunk::name.

Referenced by sla_load_config().

7407 {
7408  struct sla_trunk *trunk = obj, *trunk2 = arg;
7409 
7410  return !strcasecmp(trunk->name, trunk2->name) ? CMP_MATCH | CMP_STOP : 0;
7411 }
const ast_string_field name
Definition: app_meetme.c:986

◆ sla_trunk_destructor()

static void sla_trunk_destructor ( void *  obj)
static

Definition at line 7459 of file app_meetme.c.

References ast_context_remove_extension(), ast_debug, ast_string_field_free_memory, ast_strlen_zero, sla_trunk::autocontext, sla_trunk::name, NULL, and sla_trunk_release_refs().

Referenced by sla_build_trunk().

7460 {
7461  struct sla_trunk *trunk = obj;
7462 
7463  ast_debug(1, "sla_trunk destructor for '%s'\n", trunk->name);
7464 
7465  if (!ast_strlen_zero(trunk->autocontext)) {
7467  }
7468 
7469  sla_trunk_release_refs(trunk, NULL, 0);
7470 
7472 }
const ast_string_field name
Definition: app_meetme.c:986
const ast_string_field autocontext
Definition: app_meetme.c:986
#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
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static const char sla_registrar[]
Definition: app_meetme.c:1035
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7356
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ sla_trunk_exec()

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

Definition at line 7228 of file app_meetme.c.

References ALL_TRUNK_REFS, ao2_cleanup, AST_APP_ARG, ast_app_parse_options(), AST_CONTROL_RINGING, AST_DECLARE_APP_ARGS, ast_indicate(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag, build_conf(), conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_MOH, CONFFLAG_NO_AUDIO_UNTIL_UP, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, dispose_conf(), LOG_ERROR, MAX_CONFNUM, NULL, options, parse(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), queue_ringing_trunk(), RAII_VAR, sla, sla_change_trunk_state(), SLA_EVENT_RINGING_TRUNK, sla_find_trunk(), sla_queue_event(), sla_ringing_trunk_destroy(), SLA_TRUNK_OPT_ARG_ARRAY_SIZE, SLA_TRUNK_OPT_MOH, sla_trunk_opts, SLA_TRUNK_STATE_IDLE, and sla_ringing_trunk::trunk.

Referenced by load_module().

7229 {
7230  char conf_name[MAX_CONFNUM];
7231  struct ast_conference *conf;
7232  struct ast_flags64 conf_flags = { 0 };
7233  RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
7234  struct sla_ringing_trunk *ringing_trunk;
7236  AST_APP_ARG(trunk_name);
7238  );
7239  char *opts[SLA_TRUNK_OPT_ARG_ARRAY_SIZE] = { NULL, };
7240  struct ast_flags opt_flags = { 0 };
7241  char *parse;
7242 
7243  if (ast_strlen_zero(data)) {
7244  ast_log(LOG_ERROR, "The SLATrunk application requires an argument, the trunk name\n");
7245  return -1;
7246  }
7247 
7248  parse = ast_strdupa(data);
7249  AST_STANDARD_APP_ARGS(args, parse);
7250  if (args.argc == 2) {
7251  if (ast_app_parse_options(sla_trunk_opts, &opt_flags, opts, args.options)) {
7252  ast_log(LOG_ERROR, "Error parsing options for SLATrunk\n");
7253  return -1;
7254  }
7255  }
7256 
7257  trunk = sla_find_trunk(args.trunk_name);
7258 
7259  if (!trunk) {
7260  ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", args.trunk_name);
7261  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
7262  return 0;
7263  }
7264 
7265  if (trunk->chan) {
7266  ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n",
7267  args.trunk_name);
7268  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
7269  return 0;
7270  }
7271 
7272  trunk->chan = chan;
7273 
7274  if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
7275  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
7276  return 0;
7277  }
7278 
7279  snprintf(conf_name, sizeof(conf_name), "SLA_%s", args.trunk_name);
7280  conf = build_conf(conf_name, "", "", 1, 1, 1, chan, NULL);
7281  if (!conf) {
7282  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
7283  return 0;
7284  }
7285  ast_set_flag64(&conf_flags,
7287 
7288  if (ast_test_flag(&opt_flags, SLA_TRUNK_OPT_MOH)) {
7289  ast_indicate(chan, -1);
7290  ast_set_flag64(&conf_flags, CONFFLAG_MOH);
7291  } else
7293 
7294  conf_run(chan, conf, &conf_flags, opts);
7295  dispose_conf(conf);
7296  conf = NULL;
7297  trunk->chan = NULL;
7298  trunk->on_hold = 0;
7299 
7301 
7302  if (!pbx_builtin_getvar_helper(chan, "SLATRUNK_STATUS"))
7303  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
7304 
7305  /* Remove the entry from the list of ringing trunks if it is still there. */
7306  ast_mutex_lock(&sla.lock);
7307  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
7308  if (ringing_trunk->trunk == trunk) {
7310  break;
7311  }
7312  }
7314  ast_mutex_unlock(&sla.lock);
7315  if (ringing_trunk) {
7316  sla_ringing_trunk_destroy(ringing_trunk);
7317  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
7318  /* Queue reprocessing of ringing trunks to make stations stop ringing
7319  * that shouldn't be ringing after this trunk stopped. */
7321  }
7322 
7323  return 0;
7324 }
static struct @35 sla
A structure for data used by the sla thread.
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2504
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_meetme.c:6029
static struct ast_conference * build_conf(const char *confno, const char *pin, const char *pinadmin, int make, int dynamic, int refcount, const struct ast_channel *chan, struct ast_test *test)
Find or create a conference.
Definition: app_meetme.c:1606
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:187
const char * args
#define NULL
Definition: resample.c:96
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2456
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
static const struct ast_app_option sla_trunk_opts[128]
Definition: app_meetme.c:7226
#define ast_strlen_zero(foo)
Definition: strings.h:52
All configuration options for statsd client.
Definition: res_statsd.c:95
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:3177
#define ast_log
Definition: astobj2.c:42
#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
A trunk that is ringing.
Definition: app_meetme.c:1063
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2906
struct sla_trunk * trunk
Definition: app_meetme.c:1064
#define LOG_ERROR
Definition: logger.h:285
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:7205
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:747
Structure used to handle boolean flags.
Definition: utils.h:199
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define MAX_CONFNUM
Definition: app_meetme.c:819
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static struct test_options options
The MeetMe Conference object.
Definition: app_meetme.c:842
static struct sla_ringing_trunk * queue_ringing_trunk(struct sla_trunk *trunk)
Definition: app_meetme.c:7182
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5858
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define AST_APP_ARG(name)
Define an application argument.

◆ sla_trunk_is_marked()

static int sla_trunk_is_marked ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7794 of file app_meetme.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, CMP_MATCH, sla_station_ref::mark, sla_trunk::mark, NULL, sla_trunk_release_refs(), and sla_trunk::stations.

Referenced by sla_load_config().

7795 {
7796  struct sla_trunk *trunk = obj;
7797 
7798  ao2_lock(trunk);
7799 
7800  if (trunk->mark) {
7801  /* Only remove all of the station references if the trunk itself is going away */
7802  sla_trunk_release_refs(trunk, NULL, 0);
7803  } else {
7804  struct sla_station_ref *station_ref;
7805 
7806  /* Otherwise only remove references to stations no longer in the config */
7807  AST_LIST_TRAVERSE_SAFE_BEGIN(&trunk->stations, station_ref, entry) {
7808  if (!station_ref->mark) {
7809  continue;
7810  }
7812  ao2_ref(station_ref, -1);
7813  }
7815  }
7816 
7817  ao2_unlock(trunk);
7818 
7819  return trunk->mark ? CMP_MATCH : 0;
7820 }
A reference to a station.
Definition: app_meetme.c:974
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
unsigned int mark
Definition: app_meetme.c:1006
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct sla_trunk::@43 stations
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:7356
unsigned int mark
Definition: app_meetme.c:978

◆ sla_trunk_mark()

static int sla_trunk_mark ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7758 of file app_meetme.c.

References ao2_lock, ao2_unlock, AST_LIST_TRAVERSE, sla_station_ref::mark, sla_trunk::mark, and sla_trunk::stations.

Referenced by sla_load_config().

7759 {
7760  struct sla_trunk *trunk = obj;
7761  struct sla_station_ref *station_ref;
7762 
7763  ao2_lock(trunk);
7764 
7765  trunk->mark = 1;
7766 
7767  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
7768  station_ref->mark = 1;
7769  }
7770 
7771  ao2_unlock(trunk);
7772 
7773  return 0;
7774 }
A reference to a station.
Definition: app_meetme.c:974
#define ao2_unlock(a)
Definition: astobj2.h:730
unsigned int mark
Definition: app_meetme.c:1006
#define ao2_lock(a)
Definition: astobj2.h:718
struct sla_trunk::@43 stations
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
unsigned int mark
Definition: app_meetme.c:978

◆ sla_trunk_ref_destructor()

static void sla_trunk_ref_destructor ( void *  obj)
static

Definition at line 7158 of file app_meetme.c.

References ao2_ref, NULL, and sla_trunk_ref::trunk.

Referenced by create_trunk_ref().

7159 {
7160  struct sla_trunk_ref *trunk_ref = obj;
7161 
7162  if (trunk_ref->trunk) {
7163  ao2_ref(trunk_ref->trunk, -1);
7164  trunk_ref->trunk = NULL;
7165  }
7166 }
struct sla_trunk * trunk
Definition: app_meetme.c:1017
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
A station&#39;s reference to a trunk.
Definition: app_meetme.c:1015

◆ sla_trunk_release_refs()

static int sla_trunk_release_refs ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7356 of file app_meetme.c.

References ao2_ref, AST_LIST_REMOVE_HEAD, and sla_trunk::stations.

Referenced by sla_destroy(), sla_trunk_destructor(), and sla_trunk_is_marked().

7357 {
7358  struct sla_trunk *trunk = obj;
7359  struct sla_station_ref *station_ref;
7360 
7361  while ((station_ref = AST_LIST_REMOVE_HEAD(&trunk->stations, entry))) {
7362  ao2_ref(station_ref, -1);
7363  }
7364 
7365  return 0;
7366 }
A reference to a station.
Definition: app_meetme.c:974
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct sla_trunk::@43 stations
Definition: search.h:40

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [1/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_join_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [2/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_leave_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [3/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_end_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [4/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_mute_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [5/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_talking_type  )

◆ STASIS_MESSAGE_TYPE_DEFN_LOCAL() [6/6]

STASIS_MESSAGE_TYPE_DEFN_LOCAL ( meetme_talk_request_type  )

◆ status_to_json()

static struct ast_json* status_to_json ( int  on)
static

Definition at line 1324 of file app_meetme.c.

References ast_json_pack().

Referenced by conf_run(), and send_talking_event().

1325 {
1326  struct ast_json *json_object = ast_json_pack("{s: s}",
1327  "status", on ? "on" : "off");
1328 
1329  return json_object;
1330 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
Abstract JSON element (object, array, string, int, ...).

◆ trunkstate2str()

static const char* trunkstate2str ( enum sla_trunk_state  state)
static

Definition at line 2193 of file app_meetme.c.

References S, SLA_TRUNK_STATE_IDLE, SLA_TRUNK_STATE_ONHOLD, SLA_TRUNK_STATE_ONHOLD_BYME, SLA_TRUNK_STATE_RINGING, and SLA_TRUNK_STATE_UP.

Referenced by sla_show_stations().

2194 {
2195 #define S(e) case e: return # e;
2196  switch (state) {
2202  }
2203  return "Uknown State";
2204 #undef S
2205 }
#define S(e)

◆ tweak_listen_volume()

static void tweak_listen_volume ( struct ast_conf_user user,
enum volume_action  action 
)
static

Definition at line 1506 of file app_meetme.c.

References volume::actual, volume::desired, ast_conf_user::listen, set_listen_volume(), and tweak_volume().

Referenced by admin_exec(), meetme_menu_admin(), meetme_menu_normal(), user_listen_voldown_cb(), and user_listen_volup_cb().

1507 {
1508  tweak_volume(&user->listen, action);
1509  /* attempt to make the adjustment in the channel driver;
1510  if successful, don't adjust in the frame reading routine
1511  */
1512  if (!set_listen_volume(user, user->listen.desired))
1513  user->listen.actual = 0;
1514  else
1515  user->listen.actual = user->listen.desired;
1516 }
int actual
Definition: app_meetme.c:892
static void tweak_volume(struct volume *vol, enum volume_action action)
Definition: app_meetme.c:1459
struct volume listen
Definition: app_meetme.c:914
static int set_listen_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1447
int desired
Definition: app_meetme.c:891

◆ tweak_talk_volume()

static void tweak_talk_volume ( struct ast_conf_user user,
enum volume_action  action 
)
static

Definition at line 1494 of file app_meetme.c.

References volume::actual, volume::desired, set_talk_volume(), ast_conf_user::talk, and tweak_volume().

Referenced by admin_exec(), meetme_menu_admin(), meetme_menu_normal(), user_talk_voldown_cb(), and user_talk_volup_cb().

1495 {
1496  tweak_volume(&user->talk, action);
1497  /* attempt to make the adjustment in the channel driver;
1498  if successful, don't adjust in the frame reading routine
1499  */
1500  if (!set_talk_volume(user, user->talk.desired))
1501  user->talk.actual = 0;
1502  else
1503  user->talk.actual = user->talk.desired;
1504 }
int actual
Definition: app_meetme.c:892
static void tweak_volume(struct volume *vol, enum volume_action action)
Definition: app_meetme.c:1459
static int set_talk_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1435
int desired
Definition: app_meetme.c:891
struct volume talk
Definition: app_meetme.c:913

◆ tweak_volume()

static void tweak_volume ( struct volume vol,
enum volume_action  action 
)
static

Definition at line 1459 of file app_meetme.c.

References volume::desired, VOL_DOWN, and VOL_UP.

Referenced by tweak_listen_volume(), and tweak_talk_volume().

1460 {
1461  switch (action) {
1462  case VOL_UP:
1463  switch (vol->desired) {
1464  case 5:
1465  break;
1466  case 0:
1467  vol->desired = 2;
1468  break;
1469  case -2:
1470  vol->desired = 0;
1471  break;
1472  default:
1473  vol->desired++;
1474  break;
1475  }
1476  break;
1477  case VOL_DOWN:
1478  switch (vol->desired) {
1479  case -5:
1480  break;
1481  case 2:
1482  vol->desired = 0;
1483  break;
1484  case 0:
1485  vol->desired = -2;
1486  break;
1487  default:
1488  vol->desired--;
1489  break;
1490  }
1491  }
1492 }
int desired
Definition: app_meetme.c:891

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 8004 of file app_meetme.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_devstate_prov_del(), ast_manager_unregister(), ast_unload_realtime(), ast_unregister_application(), meetme_stasis_cleanup(), and sla_destroy().

Referenced by reload().

8005 {
8006  int res = 0;
8007 
8009  res = ast_manager_unregister("MeetmeMute");
8010  res |= ast_manager_unregister("MeetmeUnmute");
8011  res |= ast_manager_unregister("MeetmeList");
8012  res |= ast_manager_unregister("MeetmeListRooms");
8019 
8020  ast_devstate_prov_del("Meetme");
8021  ast_devstate_prov_del("SLA");
8022 
8023  sla_destroy();
8024 
8026  ast_unload_realtime("meetme");
8027 
8029 
8030  return res;
8031 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static const char *const app4
Definition: app_meetme.c:805
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: main/config.c:3406
static const char *const app2
Definition: app_meetme.c:803
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
static const char *const slastation_app
Definition: app_meetme.c:806
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ast_custom_function meetme_info_acf
Definition: app_meetme.c:7992
static void sla_destroy(void)
Definition: app_meetme.c:7420
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static struct ast_cli_entry cli_meetme[]
Definition: app_meetme.c:2290
static const char *const app3
Definition: app_meetme.c:804
static const char *const slatrunk_app
Definition: app_meetme.c:807
static const char *const app
Definition: app_meetme.c:802
static void meetme_stasis_cleanup(void)
Definition: app_meetme.c:1142

◆ user_chan_cb()

static int user_chan_cb ( void *  obj,
void *  args,
int  flags 
)
static

Definition at line 5210 of file app_meetme.c.

References args, ast_channel_name(), ast_conf_user::chan, CMP_MATCH, and CMP_STOP.

Referenced by channel_admin_exec().

5211 {
5212  struct ast_conf_user *user = obj;
5213  const char *channel = args;
5214 
5215  if (!strcmp(ast_channel_name(user->chan), channel)) {
5216  return (CMP_MATCH | CMP_STOP);
5217  }
5218 
5219  return 0;
5220 }
Definition: muted.c:95
const char * args
The MeetMe User object.
Definition: app_meetme.c:896
structure to hold users read from users.conf
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * chan
Definition: app_meetme.c:900

◆ user_listen_voldown_cb()

static int user_listen_voldown_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 5182 of file app_meetme.c.

References tweak_listen_volume(), and VOL_DOWN.

Referenced by admin_exec().

5183 {
5184  struct ast_conf_user *user = obj;
5186  return 0;
5187 }
The MeetMe User object.
Definition: app_meetme.c:896
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1506
structure to hold users read from users.conf

◆ user_listen_volup_cb()

static int user_listen_volup_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 5175 of file app_meetme.c.

References tweak_listen_volume(), and VOL_UP.

Referenced by admin_exec().

5176 {
5177  struct ast_conf_user *user = obj;
5178  tweak_listen_volume(user, VOL_UP);
5179  return 0;
5180 }
The MeetMe User object.
Definition: app_meetme.c:896
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1506
structure to hold users read from users.conf

◆ user_max_cmp()

static int user_max_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1579 of file app_meetme.c.

References ast_conf_user::user_no.

Referenced by admin_exec(), conf_run(), and meetme_menu_admin().

1580 {
1581  struct ast_conf_user *user = obj;
1582  int *max_no = arg;
1583 
1584  if (user->user_no > *max_no) {
1585  *max_no = user->user_no;
1586  }
1587 
1588  return 0;
1589 }
The MeetMe User object.
Definition: app_meetme.c:896
structure to hold users read from users.conf

◆ user_no_cmp()

static int user_no_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1567 of file app_meetme.c.

References CMP_MATCH, CMP_STOP, and ast_conf_user::user_no.

Referenced by build_conf().

1568 {
1569  struct ast_conf_user *user = obj;
1570  int *user_no = arg;
1571 
1572  if (user->user_no == *user_no) {
1573  return (CMP_MATCH | CMP_STOP);
1574  }
1575 
1576  return 0;
1577 }
The MeetMe User object.
Definition: app_meetme.c:896
structure to hold users read from users.conf

◆ user_reset_vol_cb()

static int user_reset_vol_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 5203 of file app_meetme.c.

References reset_volumes().

Referenced by admin_exec().

5204 {
5205  struct ast_conf_user *user = obj;
5206  reset_volumes(user);
5207  return 0;
5208 }
The MeetMe User object.
Definition: app_meetme.c:896
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1518
structure to hold users read from users.conf

◆ user_set_hangup_cb()

static int user_set_hangup_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

Definition at line 2705 of file app_meetme.c.

References ADMINFLAG_HANGUP, ast_conf_user::adminflags, ast_test_flag64, CONFFLAG_ADMIN, and ast_conf_user::userflags.

Referenced by conf_run().

2706 {
2707  struct ast_conf_user *user = obj;
2708  /* actual pointer contents of check_admin_arg is irrelevant */
2709 
2710  if (!check_admin_arg || (check_admin_arg && !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN))) {
2711  user->adminflags |= ADMINFLAG_HANGUP;
2712  }
2713  return 0;
2714 }
The MeetMe User object.
Definition: app_meetme.c:896
struct ast_flags64 userflags
Definition: app_meetme.c:898
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ user_set_kickme_cb()

static int user_set_kickme_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

Definition at line 2716 of file app_meetme.c.

References ADMINFLAG_KICKME, ast_conf_user::adminflags, ast_test_flag64, CONFFLAG_ADMIN, and ast_conf_user::userflags.

Referenced by admin_exec(), and meetme_menu_admin_extended().

2717 {
2718  struct ast_conf_user *user = obj;
2719  /* actual pointer contents of check_admin_arg is irrelevant */
2720 
2721  if (!check_admin_arg || (check_admin_arg && !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN))) {
2722  user->adminflags |= ADMINFLAG_KICKME;
2723  }
2724  return 0;
2725 }
The MeetMe User object.
Definition: app_meetme.c:896
struct ast_flags64 userflags
Definition: app_meetme.c:898
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ user_set_muted_cb()

static int user_set_muted_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

Definition at line 2738 of file app_meetme.c.

References ADMINFLAG_MUTED, ast_conf_user::adminflags, ast_test_flag64, CONFFLAG_ADMIN, and ast_conf_user::userflags.

Referenced by admin_exec(), and meetme_menu_admin_extended().

2739 {
2740  struct ast_conf_user *user = obj;
2741  /* actual pointer contents of check_admin_arg is irrelevant */
2742 
2743  if (!check_admin_arg || !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN)) {
2744  user->adminflags |= ADMINFLAG_MUTED;
2745  }
2746  return 0;
2747 }
The MeetMe User object.
Definition: app_meetme.c:896
struct ast_flags64 userflags
Definition: app_meetme.c:898
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ user_set_unmuted_cb()

static int user_set_unmuted_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

Definition at line 2727 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ast_test_flag64, CONFFLAG_ADMIN, and ast_conf_user::userflags.

Referenced by admin_exec(), and meetme_menu_admin_extended().

2728 {
2729  struct ast_conf_user *user = obj;
2730  /* actual pointer contents of check_admin_arg is irrelevant */
2731 
2732  if (!check_admin_arg || !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN)) {
2734  }
2735  return 0;
2736 }
The MeetMe User object.
Definition: app_meetme.c:896
struct ast_flags64 userflags
Definition: app_meetme.c:898
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ user_talk_voldown_cb()

static int user_talk_voldown_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 5196 of file app_meetme.c.

References tweak_talk_volume(), and VOL_DOWN.

Referenced by admin_exec().

5197 {
5198  struct ast_conf_user *user = obj;
5199  tweak_talk_volume(user, VOL_DOWN);
5200  return 0;
5201 }
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1494
The MeetMe User object.
Definition: app_meetme.c:896
structure to hold users read from users.conf

◆ user_talk_volup_cb()

static int user_talk_volup_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 5189 of file app_meetme.c.

References tweak_talk_volume(), and VOL_UP.

Referenced by admin_exec().

5190 {
5191  struct ast_conf_user *user = obj;
5192  tweak_talk_volume(user, VOL_UP);
5193  return 0;
5194 }
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1494
The MeetMe User object.
Definition: app_meetme.c:896
structure to hold users read from users.conf

Variable Documentation

◆ __mod_info

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

Definition at line 8085 of file app_meetme.c.

◆ app

const char* const app = "MeetMe"
static

Definition at line 802 of file app_meetme.c.

◆ app2

const char* const app2 = "MeetMeCount"
static

Definition at line 803 of file app_meetme.c.

◆ app3

const char* const app3 = "MeetMeAdmin"
static

Definition at line 804 of file app_meetme.c.

◆ app4

const char* const app4 = "MeetMeChannelAdmin"
static

Definition at line 805 of file app_meetme.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 8085 of file app_meetme.c.

◆ attempt_callerid

unsigned int attempt_callerid

Attempt to handle CallerID, even though it is known not to work properly in some situations.

Definition at line 1099 of file app_meetme.c.

◆ audio_buffers

int audio_buffers
static

The number of audio buffers to be allocated on pseudo channels when in a conference.

Definition at line 1106 of file app_meetme.c.

Referenced by conf_run().

◆ cli_meetme

struct ast_cli_entry cli_meetme[]
static

Definition at line 2290 of file app_meetme.c.

◆ cond

ast_cond_t cond

◆ conf_map

unsigned int conf_map[1024] = {0, }
static

Definition at line 888 of file app_meetme.c.

◆ confs

struct confs confs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ earlyalert

int earlyalert
static

Definition at line 812 of file app_meetme.c.

Referenced by find_conf_realtime().

◆ endalert

int endalert
static

Definition at line 813 of file app_meetme.c.

Referenced by find_conf_realtime().

◆ event_q

struct { ... } event_q

◆ extendby

int extendby
static

Definition at line 814 of file app_meetme.c.

Referenced by rt_extend_conf().

◆ failed_stations

struct { ... } failed_stations

◆ first

struct sla_event* first

◆ fuzzystart

int fuzzystart
static

Definition at line 811 of file app_meetme.c.

Referenced by find_conf_realtime().

◆ gain_map

const char gain_map[]
static

Map 'volume' levels from -5 through +5 into decibel (dB) settings for channel drivers.

Note
these are not a straight linear-to-dB conversion... the numbers have been modified to give the user a better level of adjustability.

Definition at line 1115 of file app_meetme.c.

◆ last

struct sla_event* last

◆ lock

Definition at line 1091 of file app_meetme.c.

Referenced by __ast_bucket_scheme_register(), __ast_codec_register_with_format(), __ast_format_interface_register(), __ast_named_lock_get(), add_headers_to_message(), add_masquerade_store(), add_transferer_role(), after_bridge_cb_find(), after_bridge_cb_setup(), aor_alloc(), ast_ari_add_handler(), ast_bridge_basic_set_flags(), ast_bridge_read_after_goto(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), ast_cdr_fork(), ast_channel_move(), ast_clear_mixmonitor_methods(), ast_config_engine_deregister(), ast_config_engine_register(), ast_crypt_validate(), ast_endpoint_snapshot_create(), ast_format_cache_set(), ast_get_extension_for_mime_type(), ast_get_format_for_file_ext(), ast_localtime_wakeup_monitor(), ast_realtime_is_mapping_defined(), ast_serializer_shutdown_group_join(), ast_set_mixmonitor_methods(), ast_sip_format_endpoint_ami(), ast_sip_identify_endpoint(), ast_sip_publish_client_remove(), ast_sip_publish_client_send(), ast_sip_push_task(), ast_sip_register_endpoint_formatter(), ast_sip_register_endpoint_identifier_with_name(), ast_sip_register_event_publisher_handler(), ast_sip_register_supplement(), ast_sip_session_add_supplements(), ast_sip_session_register_sdp_handler(), ast_sip_session_register_supplement_with_module(), ast_sip_session_unregister_supplement(), ast_sip_unregister_endpoint_formatter(), ast_sip_unregister_endpoint_identifier(), ast_sip_unregister_event_publisher_handler(), ast_sip_unregister_supplement(), ast_spinlock_destroy(), ast_start_mixmonitor(), ast_stop_mixmonitor(), ast_taskprocessor_set_local(), AST_TEST_DEFINE(), ast_threadpool_push(), ast_threadpool_set_size(), ast_unreal_channel_push_to_bridge(), bridge_basic_change_personality(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), builtin_feature_get_exten(), cancel_and_unpublish(), channel_get_external_vars(), clear_stimulus_queue(), cli_show_channels(), cli_show_endpoint_identifiers(), conf_announce_channel_push(), consumer_exec(), consumer_exec_sync(), consumer_should_stay(), consumer_wait_for(), consumer_wait_for_completion(), event_session_shutdown(), expire_contact(), find_engine(), find_route(), get_park_common_datastore_copy(), get_publishes_and_update_state(), get_root_handler(), get_sip_pvt_from_replaces(), get_wait_bridge_wrapper(), get_wrapper(), handle_bridge_enter(), handle_cli_check_permissions(), handle_cli_core_show_config_mappings(), handle_local_optimization_begin(), handle_local_optimization_end(), handle_request_invite(), has_masquerade_store(), internal_feature_read(), internal_feature_write(), internal_featuremap_read(), internal_featuremap_write(), load_module(), lock_thread(), message_sink_cb(), mid_test_sync(), one_protocol(), persistent_endpoint_find_or_create(), playback_cancel(), playback_final_update(), playback_first_update(), playback_forward(), playback_pause(), playback_restart(), playback_reverse(), playback_stop(), playback_unpause(), prometheus_callback_register(), prometheus_callback_unregister(), prometheus_last_scrape_time_get(), prometheus_metric_register(), prometheus_metric_registered_count(), prometheus_metric_unregister(), publisher_client_send(), recording_set_state(), registration_deleted_observer(), registration_loaded_observer(), reload_module(), remove_hooks_on_personality_change(), remove_masquerade_store(), remove_stasis_subscriptions(), report_fax_status(), report_receive_fax_status(), report_send_fax_status(), rtp_ioqueue_thread_get_or_create(), set_touch_variables(), sip_outbound_publish_callback(), sip_publisher_service_queue(), snoop_determine_format(), sorcery_observer_created(), sorcery_observer_deleted(), sorcery_observer_loaded(), sorcery_observer_updated(), stasis_app_control_record(), stasis_app_playback_get_state(), stasis_app_playback_operation(), stasis_app_recording_operation(), stasis_message_sink_dtor(), stasis_message_sink_should_stay(), stasis_message_sink_wait_for(), stasis_message_sink_wait_for_count(), test_sub(), threadpool_active_thread_idle(), threadpool_idle_thread_dead(), threadpool_tps_emptied(), threadpool_tps_task_pushed(), threadpool_zombie_thread_dead(), unload_module(), wait_for_stimulus(), and worker_set_state().

◆ meetme_event_message_router

struct stasis_message_router* meetme_event_message_router
static

Definition at line 1130 of file app_meetme.c.

◆ meetme_info_acf

struct ast_custom_function meetme_info_acf
static
Initial value:
= {
.name = "MEETME_INFO",
.read = acf_meetme_info,
}
static int acf_meetme_info(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: app_meetme.c:7941

Definition at line 7992 of file app_meetme.c.

◆ meetme_opts

const struct ast_app_option meetme_opts[128] = { [ 'A' ] = { .flag = CONFFLAG_MARKEDUSER }, [ 'a' ] = { .flag = CONFFLAG_ADMIN }, [ 'b' ] = { .flag = CONFFLAG_AGI }, [ 'c' ] = { .flag = CONFFLAG_ANNOUNCEUSERCOUNT }, [ 'C' ] = { .flag = CONFFLAG_KICK_CONTINUE }, [ 'D' ] = { .flag = CONFFLAG_DYNAMICPIN }, [ 'd' ] = { .flag = CONFFLAG_DYNAMIC }, [ 'E' ] = { .flag = CONFFLAG_EMPTYNOPIN }, [ 'e' ] = { .flag = CONFFLAG_EMPTY }, [ 'F' ] = { .flag = CONFFLAG_PASS_DTMF }, [ 'G' ] = { .flag = (1ULL << 32) , .arg_index = OPT_ARG_INTROMSG + 1 }, [ 'v' ] = { .flag = (1ULL << 33) , .arg_index = OPT_ARG_INTROUSER_VMREC + 1 }, [ 'i' ] = { .flag = CONFFLAG_INTROUSER }, [ 'I' ] = { .flag = CONFFLAG_INTROUSERNOREVIEW }, [ 'k' ] = { .flag = (1ULL << 34) }, [ 'M' ] = { .flag = CONFFLAG_MOH , .arg_index = OPT_ARG_MOH_CLASS + 1 }, [ 'm' ] = { .flag = CONFFLAG_STARTMUTED }, [ 'n' ] = { .flag = (1ULL << 35) }, [ 'o' ] = { .flag = CONFFLAG_OPTIMIZETALKER }, [ 'P' ] = { .flag = CONFFLAG_ALWAYSPROMPT }, [ 'p' ] = { .flag = CONFFLAG_KEYEXIT , .arg_index = OPT_ARG_EXITKEYS + 1 }, [ 'q' ] = { .flag = CONFFLAG_QUIET }, [ 'r' ] = { .flag = CONFFLAG_RECORDCONF }, [ 's' ] = { .flag = CONFFLAG_STARMENU }, [ 'T' ] = { .flag = CONFFLAG_MONITORTALKER }, [ 'l' ] = { .flag = CONFFLAG_MONITOR }, [ 't' ] = { .flag = CONFFLAG_TALKER }, [ 'w' ] = { .flag = CONFFLAG_WAITMARKED , .arg_index = OPT_ARG_WAITMARKED + 1 }, [ 'X' ] = { .flag = CONFFLAG_EXIT_CONTEXT }, [ 'x' ] = { .flag = CONFFLAG_MARKEDEXIT }, [ '1' ] = { .flag = CONFFLAG_NOONLYPERSON }, [ 'S' ] = { .flag = CONFFLAG_DURATION_STOP , .arg_index = OPT_ARG_DURATION_STOP + 1 }, [ 'L' ] = { .flag = CONFFLAG_DURATION_LIMIT , .arg_index = OPT_ARG_DURATION_LIMIT + 1 }, }
static

Definition at line 800 of file app_meetme.c.

Referenced by conf_exec(), and find_conf_realtime().

◆ ringing_stations

struct { ... } ringing_stations

◆ ringing_trunks

struct { ... } ringing_trunks

◆ rt_log_members

int rt_log_members
static

Log participant count to the RealTime backend

Definition at line 817 of file app_meetme.c.

◆ rt_schedule

int rt_schedule
static

Definition at line 810 of file app_meetme.c.

◆ sla

struct { ... } sla

◆ sla_registrar

const char sla_registrar[] = "SLA"
static

Definition at line 1035 of file app_meetme.c.

◆ sla_stations

struct ao2_container* sla_stations
static

Definition at line 1032 of file app_meetme.c.

◆ sla_trunk_opts

const struct ast_app_option sla_trunk_opts[128] = { [ 'M' ] = { .flag = SLA_TRUNK_OPT_MOH , .arg_index = SLA_TRUNK_OPT_ARG_MOH_CLASS + 1 }, }
static

Definition at line 7226 of file app_meetme.c.

Referenced by sla_trunk_exec().

◆ sla_trunks

struct ao2_container* sla_trunks
static

Definition at line 1033 of file app_meetme.c.

◆ slastation_app

const char* const slastation_app = "SLAStation"
static

Definition at line 806 of file app_meetme.c.

◆ slatrunk_app

const char* const slatrunk_app = "SLATrunk"
static

Definition at line 807 of file app_meetme.c.

◆ stop

unsigned int stop

◆ thread

pthread_t thread