Wed Jan 8 2020 09:49:53

Asterisk developer's documentation


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/data.h"
#include "asterisk/test.h"
#include "enter.h"
#include "leave.h"

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 << 33)
 
#define CONFFLAG_INTROMSG   (1ULL << 32)
 
#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_DATA_EXPORT(MEMBER)
 
#define MEETME_DELAYDETECTENDTALK   1000
 
#define MEETME_DELAYDETECTTALK   300
 
#define MEETME_USER_DATA_EXPORT(MEMBER)
 
#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) }
 
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_ARRAY_SIZE = 6
}
 
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_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)
 
 AST_DATA_STRUCTURE (ast_conference, MEETME_DATA_EXPORT)
 
 AST_DATA_STRUCTURE (ast_conf_user, MEETME_USER_DATA_EXPORT)
 
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 (void)
 
static int load_module (void)
 
static char * meetme_cmd_helper (struct ast_cli_args *a)
 
static int meetme_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
 
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)
 
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)
 
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 char * meetme_show_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
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_hash (const void *obj, const int flags)
 
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_hash (const void *obj, const int flags)
 
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)
 
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_add_provider_cb (void *obj, void *arg, int flags)
 
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_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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
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 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 } , }
 
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 ast_data_handler meetme_data_provider
 
static struct ast_data_entry meetme_data_providers []
 
static struct ast_custom_function meetme_info_acf
 
static 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 }, [ 'i' ] = { .flag = CONFFLAG_INTROUSER }, [ 'I' ] = { .flag = CONFFLAG_INTROUSERNOREVIEW }, [ 'M' ] = { .flag = CONFFLAG_MOH , .arg_index = OPT_ARG_MOH_CLASS + 1 }, [ 'm' ] = { .flag = CONFFLAG_STARTMUTED }, [ 'n' ] = { .flag = (1ULL << 33) }, [ '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 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

#define AST_FRAME_BITS   32

Definition at line 545 of file app_meetme.c.

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

#define CONF_SIZE   320

Definition at line 564 of file app_meetme.c.

Referenced by conf_run().

#define CONFFLAG_DONT_DENOISE   (1ULL << 33)

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

Definition at line 630 of file app_meetme.c.

Referenced by conf_run().

#define CONFFLAG_INTROMSG   (1ULL << 32)

If set play an intro announcement at start of conference

Definition at line 628 of file app_meetme.c.

Referenced by conf_run().

#define CONFFLAG_NO_AUDIO_UNTIL_UP   (1ULL << 31)

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

Definition at line 626 of file app_meetme.c.

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

#define CONFIG_FILE_NAME   "meetme.conf"

Definition at line 524 of file app_meetme.c.

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

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

String format for scheduled conferences

Definition at line 532 of file app_meetme.c.

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

#define DEFAULT_AUDIO_BUFFERS   32

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

Definition at line 529 of file app_meetme.c.

Referenced by load_config_meetme().

#define MAX_CONFNUM   80
#define MAX_PIN   80

Definition at line 694 of file app_meetme.c.

Referenced by conf_exec().

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

Definition at line 698 of file app_meetme.c.

Referenced by conf_exec(), and find_conf().

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

Referenced by meetme_show_cmd().

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

Referenced by meetme_show_cmd().

#define MEETME_DATA_EXPORT (   MEMBER)

Definition at line 7541 of file app_meetme.c.

#define MEETME_DELAYDETECTENDTALK   1000

Definition at line 543 of file app_meetme.c.

Referenced by conf_run().

#define MEETME_DELAYDETECTTALK   300

Definition at line 542 of file app_meetme.c.

Referenced by conf_run().

#define MEETME_USER_DATA_EXPORT (   MEMBER)

Definition at line 7558 of file app_meetme.c.

#define OPTIONS_LEN   100

Definition at line 695 of file app_meetme.c.

Referenced by find_conf_realtime().

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

Referenced by sms_readfile(), and trunkstate2str().

#define SLA_CONFIG_FILE   "sla.conf"

Definition at line 525 of file app_meetme.c.

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

#define STR_CONCISE   "concise"

Definition at line 526 of file app_meetme.c.

Referenced by complete_meetmecmd_list(), and meetme_show_cmd().

Enumeration Type Documentation

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

Definition at line 534 of file app_meetme.c.

534  {
535  ADMINFLAG_MUTED = (1 << 1), /*!< User is muted */
536  ADMINFLAG_SELFMUTED = (1 << 2), /*!< User muted self */
537  ADMINFLAG_KICKME = (1 << 3), /*!< User has been kicked */
538  /*! User has requested to speak */
539  ADMINFLAG_T_REQUEST = (1 << 4),
540 };
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 566 of file app_meetme.c.

566  {
567  /*! user has admin access on the conference */
568  CONFFLAG_ADMIN = (1 << 0),
569  /*! If set the user can only receive audio from the conference */
570  CONFFLAG_MONITOR = (1 << 1),
571  /*! If set asterisk will exit conference when key defined in p() option is pressed */
572  CONFFLAG_KEYEXIT = (1 << 2),
573  /*! If set asterisk will provide a menu to the user when '*' is pressed */
574  CONFFLAG_STARMENU = (1 << 3),
575  /*! If set the use can only send audio to the conference */
576  CONFFLAG_TALKER = (1 << 4),
577  /*! If set there will be no enter or leave sounds */
578  CONFFLAG_QUIET = (1 << 5),
579  /*! If set, when user joins the conference, they will be told the number
580  * of users that are already in */
581  CONFFLAG_ANNOUNCEUSERCOUNT = (1 << 6),
582  /*! Set to run AGI Script in Background */
583  CONFFLAG_AGI = (1 << 7),
584  /*! Set to have music on hold when user is alone in conference */
585  CONFFLAG_MOH = (1 << 8),
586  /*! If set, the channel will leave the conference if all marked users leave */
587  CONFFLAG_MARKEDEXIT = (1 << 9),
588  /*! If set, the MeetMe will wait until a marked user enters */
589  CONFFLAG_WAITMARKED = (1 << 10),
590  /*! If set, the MeetMe will exit to the specified context */
591  CONFFLAG_EXIT_CONTEXT = (1 << 11),
592  /*! If set, the user will be marked */
593  CONFFLAG_MARKEDUSER = (1 << 12),
594  /*! If set, user will be ask record name on entry of conference */
595  CONFFLAG_INTROUSER = (1 << 13),
596  /*! If set, the MeetMe will be recorded */
597  CONFFLAG_RECORDCONF = (1<< 14),
598  /*! If set, the user will be monitored if the user is talking or not */
599  CONFFLAG_MONITORTALKER = (1 << 15),
600  CONFFLAG_DYNAMIC = (1 << 16),
601  CONFFLAG_DYNAMICPIN = (1 << 17),
602  CONFFLAG_EMPTY = (1 << 18),
603  CONFFLAG_EMPTYNOPIN = (1 << 19),
604  CONFFLAG_ALWAYSPROMPT = (1 << 20),
605  /*! If set, treat talking users as muted users */
606  CONFFLAG_OPTIMIZETALKER = (1 << 21),
607  /*! If set, won't speak the extra prompt when the first person
608  * enters the conference */
609  CONFFLAG_NOONLYPERSON = (1 << 22),
610  /*! If set, user will be asked to record name on entry of conference
611  * without review */
612  CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
613  /*! If set, the user will be initially self-muted */
614  CONFFLAG_STARTMUTED = (1 << 24),
615  /*! Pass DTMF through the conference */
616  CONFFLAG_PASS_DTMF = (1 << 25),
617  CONFFLAG_SLA_STATION = (1 << 26),
618  CONFFLAG_SLA_TRUNK = (1 << 27),
619  /*! If set, the user should continue in the dialplan if kicked out */
620  CONFFLAG_KICK_CONTINUE = (1 << 28),
621  CONFFLAG_DURATION_STOP = (1 << 29),
622  CONFFLAG_DURATION_LIMIT = (1 << 30),
623 };
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_ARRAY_SIZE 

Definition at line 632 of file app_meetme.c.

anonymous enum
Enumerator
SLA_TRUNK_OPT_MOH 

Definition at line 6738 of file app_meetme.c.

6738  {
6739  SLA_TRUNK_OPT_MOH = (1 << 0),
6740 };
anonymous enum
Enumerator
SLA_TRUNK_OPT_ARG_MOH_CLASS 
SLA_TRUNK_OPT_ARG_ARRAY_SIZE 

Definition at line 6742 of file app_meetme.c.

Enumerator
CONF_HASJOIN 
CONF_HASLEFT 

Definition at line 700 of file app_meetme.c.

700  {
701  CONF_HASJOIN,
703 };
Enumerator
ENTER 
LEAVE 

Definition at line 552 of file app_meetme.c.

552  {
553  ENTER,
554  LEAVE
555 };
enum menu_modes
Enumerator
MENU_DISABLED 
MENU_NORMAL 
MENU_ADMIN 
MENU_ADMIN_EXTENDED 

Definition at line 2332 of file app_meetme.c.

Enumerator
MEETME_RECORD_OFF 
MEETME_RECORD_STARTED 
MEETME_RECORD_ACTIVE 
MEETME_RECORD_TERMINATE 

Definition at line 557 of file app_meetme.c.

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 911 of file app_meetme.c.

911  {
912  /*! A station has put the call on hold */
914  /*! The state of a dial has changed */
916  /*! The state of a ringing trunk has changed */
918 };
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 804 of file app_meetme.c.

804  {
805  /*! This means that any station can put it on hold, and any station
806  * can retrieve the call from hold. */
808  /*! This means that only the station that put the call on hold may
809  * retrieve it from hold. */
811 };
Enumerator
SLA_STATION_HANGUP_NORMAL 
SLA_STATION_HANGUP_TIMEOUT 

Definition at line 944 of file app_meetme.c.

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 796 of file app_meetme.c.

Enumerator
ALL_TRUNK_REFS 
INACTIVE_TRUNK_REFS 

Definition at line 791 of file app_meetme.c.

Enumerator
VOL_UP 
VOL_DOWN 

Definition at line 547 of file app_meetme.c.

547  {
548  VOL_UP,
549  VOL_DOWN
550 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 7792 of file app_meetme.c.

static void __unreg_module ( void  )
static

Definition at line 7792 of file app_meetme.c.

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

Definition at line 7478 of file app_meetme.c.

References acf_meetme_info_eval(), args, 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, and parse().

7479 {
7480  struct ast_conference *conf;
7481  char *parse;
7482  int result = -2; /* only non-negative numbers valid, -1 is used elsewhere */
7484  AST_APP_ARG(keyword);
7486  );
7487 
7488  if (ast_strlen_zero(data)) {
7489  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires two arguments\n");
7490  return -1;
7491  }
7492 
7493  parse = ast_strdupa(data);
7494  AST_STANDARD_APP_ARGS(args, parse);
7495 
7496  if (ast_strlen_zero(args.keyword)) {
7497  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a keyword\n");
7498  return -1;
7499  }
7500 
7501  if (ast_strlen_zero(args.confno)) {
7502  ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a conference number\n");
7503  return -1;
7504  }
7505 
7506  AST_LIST_LOCK(&confs);
7507  AST_LIST_TRAVERSE(&confs, conf, list) {
7508  if (!strcmp(args.confno, conf->confno)) {
7509  result = acf_meetme_info_eval(args.keyword, conf);
7510  break;
7511  }
7512  }
7514 
7515  if (result > -1) {
7516  snprintf(buf, len, "%d", result);
7517  } else if (result == -1) {
7518  ast_log(LOG_NOTICE, "Error: invalid keyword: '%s'\n", args.keyword);
7519  snprintf(buf, len, "0");
7520  } else if (result == -2) {
7521  ast_log(LOG_NOTICE, "Error: conference (%s) not found\n", args.confno);
7522  snprintf(buf, len, "0");
7523  }
7524 
7525  return 0;
7526 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_conference::@32 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int acf_meetme_info_eval(const char *keyword, const struct ast_conference *conf)
Definition: app_meetme.c:7460
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#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:1858
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
The MeetMe Conference object.
Definition: app_meetme.c:715
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static int acf_meetme_info_eval ( const char *  keyword,
const struct ast_conference conf 
)
static

Definition at line 7460 of file app_meetme.c.

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

Referenced by acf_meetme_info().

7461 {
7462  if (!strcasecmp("lock", keyword)) {
7463  return conf->locked;
7464  } else if (!strcasecmp("parties", keyword)) {
7465  return conf->users;
7466  } else if (!strcasecmp("activity", keyword)) {
7467  time_t now;
7468  now = time(NULL);
7469  return (now - conf->start);
7470  } else if (!strcasecmp("dynamic", keyword)) {
7471  return conf->isdynamic;
7472  } else {
7473  return -1;
7474  }
7475 
7476 }
unsigned int isdynamic
Definition: app_meetme.c:729
unsigned int locked
Definition: app_meetme.c:731
static int action_meetmelist ( struct mansession s,
const struct message m 
)
static

Definition at line 5105 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_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_listack(), ast_channel::caller, ast_conf_user::chan, CONFFLAG_ADMIN, CONFFLAG_MARKEDUSER, CONFFLAG_MONITOR, CONFFLAG_TALKER, ast_conference::confno, ast_channel::connected, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_channel::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().

5106 {
5107  const char *actionid = astman_get_header(m, "ActionID");
5108  const char *conference = astman_get_header(m, "Conference");
5109  char idText[80] = "";
5110  struct ast_conference *cnf;
5111  struct ast_conf_user *user;
5112  struct ao2_iterator user_iter;
5113  int total = 0;
5114 
5115  if (!ast_strlen_zero(actionid))
5116  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
5117 
5118  if (AST_LIST_EMPTY(&confs)) {
5119  astman_send_error(s, m, "No active conferences.");
5120  return 0;
5121  }
5122 
5123  astman_send_listack(s, m, "Meetme user list will follow", "start");
5124 
5125  /* Find the right conference */
5126  AST_LIST_LOCK(&confs);
5127  AST_LIST_TRAVERSE(&confs, cnf, list) {
5128  /* If we ask for one particular, and this isn't it, skip it */
5129  if (!ast_strlen_zero(conference) && strcmp(cnf->confno, conference))
5130  continue;
5131 
5132  /* Show all the users */
5133  user_iter = ao2_iterator_init(cnf->usercontainer, 0);
5134  while ((user = ao2_iterator_next(&user_iter))) {
5135  total++;
5136  astman_append(s,
5137  "Event: MeetmeList\r\n"
5138  "%s"
5139  "Conference: %s\r\n"
5140  "UserNumber: %d\r\n"
5141  "CallerIDNum: %s\r\n"
5142  "CallerIDName: %s\r\n"
5143  "ConnectedLineNum: %s\r\n"
5144  "ConnectedLineName: %s\r\n"
5145  "Channel: %s\r\n"
5146  "Admin: %s\r\n"
5147  "Role: %s\r\n"
5148  "MarkedUser: %s\r\n"
5149  "Muted: %s\r\n"
5150  "Talking: %s\r\n"
5151  "\r\n",
5152  idText,
5153  cnf->confno,
5154  user->user_no,
5155  S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
5156  S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<no name>"),
5157  S_COR(user->chan->connected.id.number.valid, user->chan->connected.id.number.str, "<unknown>"),
5158  S_COR(user->chan->connected.id.name.valid, user->chan->connected.id.name.str, "<no name>"),
5159  user->chan->name,
5160  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "Yes" : "No",
5161  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "Listen only" : ast_test_flag64(&user->userflags, CONFFLAG_TALKER) ? "Talk only" : "Talk and listen",
5162  ast_test_flag64(&user->userflags, CONFFLAG_MARKEDUSER) ? "Yes" : "No",
5163  user->adminflags & ADMINFLAG_MUTED ? "By admin" : user->adminflags & ADMINFLAG_SELFMUTED ? "By self" : "No",
5164  user->talking > 0 ? "Yes" : user->talking == 0 ? "No" : "Not monitored");
5165  ao2_ref(user, -1);
5166  }
5167  ao2_iterator_destroy(&user_iter);
5168  }
5170  /* Send final confirmation */
5171  astman_append(s,
5172  "Event: MeetmeListComplete\r\n"
5173  "EventList: Complete\r\n"
5174  "ListItems: %d\r\n"
5175  "%s"
5176  "\r\n", total, idText);
5177  return 0;
5178 }
static char user[512]
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#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:83
struct ast_flags64 userflags
Definition: app_meetme.c:771
const ast_string_field name
Definition: channel.h:787
#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:748
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static int total
Definition: res_adsi.c:967
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
The MeetMe Conference object.
Definition: app_meetme.c:715
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_channel * chan
Definition: app_meetme.c:773
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager list transaction.
Definition: manager.c:2145
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int action_meetmemute ( struct mansession s,
const struct message m 
)
static

Definition at line 5095 of file app_meetme.c.

References meetmemute().

Referenced by load_module().

5096 {
5097  return meetmemute(s, m, 1);
5098 }
static int meetmemute(struct mansession *s, const struct message *m, int mute)
Definition: app_meetme.c:5035
static int action_meetmeunmute ( struct mansession s,
const struct message m 
)
static

Definition at line 5100 of file app_meetme.c.

References meetmemute().

Referenced by load_module().

5101 {
5102  return meetmemute(s, m, 0);
5103 }
static int meetmemute(struct mansession *s, const struct message *m, int mute)
Definition: app_meetme.c:5035
static int admin_exec ( struct ast_channel chan,
const char *  data 
)
static

The MeetMeadmin application.

MeetMeAdmin(confno, command, caller)

Definition at line 4807 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ao2_callback, ao2_find, ao2_ref, args, 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, OBJ_NODATA, pbx_builtin_setvar_helper(), 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, ast_conf_user::userflags, VOL_DOWN, and VOL_UP.

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

4807  {
4808  char *params;
4809  struct ast_conference *cnf;
4810  struct ast_conf_user *user = NULL;
4812  AST_APP_ARG(confno);
4813  AST_APP_ARG(command);
4814  AST_APP_ARG(user);
4815  );
4816  int res = 0;
4817 
4818  if (ast_strlen_zero(data)) {
4819  ast_log(LOG_WARNING, "MeetMeAdmin requires an argument!\n");
4820  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOPARSE");
4821  return -1;
4822  }
4823 
4824  params = ast_strdupa(data);
4825  AST_STANDARD_APP_ARGS(args, params);
4826 
4827  if (!args.command) {
4828  ast_log(LOG_WARNING, "MeetmeAdmin requires a command!\n");
4829  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOPARSE");
4830  return -1;
4831  }
4832 
4833  AST_LIST_LOCK(&confs);
4834  AST_LIST_TRAVERSE(&confs, cnf, list) {
4835  if (!strcmp(cnf->confno, args.confno))
4836  break;
4837  }
4838 
4839  if (!cnf) {
4840  ast_log(LOG_WARNING, "Conference number '%s' not found!\n", args.confno);
4842  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", "NOTFOUND");
4843  return 0;
4844  }
4845 
4847 
4848  if (args.user) {
4849  user = find_user(cnf, args.user);
4850  if (!user) {
4851  ast_log(LOG_NOTICE, "Specified User not found!\n");
4852  res = -2;
4853  goto usernotfound;
4854  }
4855  } else {
4856  /* fail for commands that require a user */
4857  switch (*args.command) {
4858  case 'm': /* Unmute */
4859  case 'M': /* Mute */
4860  case 't': /* Lower user's talk volume */
4861  case 'T': /* Raise user's talk volume */
4862  case 'u': /* Lower user's listen volume */
4863  case 'U': /* Raise user's listen volume */
4864  case 'r': /* Reset user's volume level */
4865  case 'k': /* Kick user */
4866  res = -2;
4867  ast_log(LOG_NOTICE, "No user specified!\n");
4868  goto usernotfound;
4869  default:
4870  break;
4871  }
4872  }
4873 
4874  switch (*args.command) {
4875  case 76: /* L: Lock */
4876  cnf->locked = 1;
4877  break;
4878  case 108: /* l: Unlock */
4879  cnf->locked = 0;
4880  break;
4881  case 75: /* K: kick all users */
4883  break;
4884  case 101: /* e: Eject last user*/
4885  {
4886  int max_no = 0;
4887  struct ast_conf_user *eject_user;
4888 
4890  eject_user = ao2_find(cnf->usercontainer, &max_no, 0);
4891  if (!eject_user) {
4892  res = -1;
4893  ast_log(LOG_NOTICE, "No last user to kick!\n");
4894  break;
4895  }
4896 
4897  if (!ast_test_flag64(&eject_user->userflags, CONFFLAG_ADMIN)) {
4898  eject_user->adminflags |= ADMINFLAG_KICKME;
4899  } else {
4900  res = -1;
4901  ast_log(LOG_NOTICE, "Not kicking last user, is an Admin!\n");
4902  }
4903 
4904  ao2_ref(eject_user, -1);
4905  break;
4906  }
4907  case 77: /* M: Mute */
4908  user->adminflags |= ADMINFLAG_MUTED;
4909  break;
4910  case 78: /* N: Mute all (non-admin) users */
4912  break;
4913  case 109: /* m: Unmute */
4915  break;
4916  case 110: /* n: Unmute all users */
4918  break;
4919  case 107: /* k: Kick user */
4920  user->adminflags |= ADMINFLAG_KICKME;
4921  break;
4922  case 118: /* v: Lower all users listen volume */
4924  break;
4925  case 86: /* V: Raise all users listen volume */
4927  break;
4928  case 115: /* s: Lower all users speaking volume */
4930  break;
4931  case 83: /* S: Raise all users speaking volume */
4933  break;
4934  case 82: /* R: Reset all volume levels */
4936  break;
4937  case 114: /* r: Reset user's volume level */
4938  reset_volumes(user);
4939  break;
4940  case 85: /* U: Raise user's listen volume */
4941  tweak_listen_volume(user, VOL_UP);
4942  break;
4943  case 117: /* u: Lower user's listen volume */
4945  break;
4946  case 84: /* T: Raise user's talk volume */
4947  tweak_talk_volume(user, VOL_UP);
4948  break;
4949  case 116: /* t: Lower user's talk volume */
4950  tweak_talk_volume(user, VOL_DOWN);
4951  break;
4952  case 'E': /* E: Extend conference */
4953  if (rt_extend_conf(args.confno)) {
4954  res = -1;
4955  }
4956  break;
4957  }
4958 
4959  if (args.user) {
4960  /* decrement reference from find_user */
4961  ao2_ref(user, -1);
4962  }
4963 usernotfound:
4965 
4966  dispose_conf(cnf);
4967  pbx_builtin_setvar_helper(chan, "MEETMEADMINSTATUS", res == -2 ? "NOTFOUND" : res ? "FAILED" : "OK");
4968 
4969  return 0;
4970 }
#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:4744
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1102
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2116
static int user_set_unmuted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2310
#define LOG_WARNING
Definition: logger.h:144
#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:4757
static int user_reset_vol_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:4785
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
unsigned int locked
Definition: app_meetme.c:731
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1187
struct ast_conf_user::@34 list
static int user_listen_voldown_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:4764
static int user_set_kickme_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2299
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1114
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1126
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_flags64 userflags
Definition: app_meetme.c:771
static struct @350 args
static int user_talk_volup_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:4771
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
struct ao2_container * usercontainer
Definition: app_meetme.c:748
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...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
The MeetMe Conference object.
Definition: app_meetme.c:715
static int user_talk_voldown_cb(void *obj, void *unused, int flags)
Definition: app_meetme.c:4778
static int user_set_muted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2321
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static void* announce_thread ( void *  data)
static

Definition at line 2208 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_filedelete(), ast_fileexists(), AST_LIST_APPEND_LIST, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_streamfile(), ast_waitstream(), CONF_HASLEFT, announce_listitem::confchan, announce_listitem::confusers, get_announce_filename(), announce_listitem::language, LOG_DEBUG, and announce_listitem::namerecloc.

Referenced by conf_run().

2209 {
2210  struct announce_listitem *current;
2211  struct ast_conference *conf = data;
2212  int res;
2213  char filename[PATH_MAX] = "";
2215  AST_LIST_HEAD_INIT_NOLOCK(&local_list);
2216 
2217  while (!conf->announcethread_stop) {
2219  if (conf->announcethread_stop) {
2221  break;
2222  }
2223  if (AST_LIST_EMPTY(&conf->announcelist))
2225 
2226  AST_LIST_APPEND_LIST(&local_list, &conf->announcelist, entry);
2228 
2230  if (conf->announcethread_stop) {
2231  break;
2232  }
2233 
2234  for (res = 1; !conf->announcethread_stop && (current = AST_LIST_REMOVE_HEAD(&local_list, entry)); ao2_ref(current, -1)) {
2235  ast_log(LOG_DEBUG, "About to play %s\n", current->namerecloc);
2236  if (!ast_fileexists(current->namerecloc, NULL, NULL))
2237  continue;
2238  if ((current->confchan) && (current->confusers > 1) && !ast_check_hangup(current->confchan)) {
2239  if (!ast_streamfile(current->confchan, current->namerecloc, current->language))
2240  res = ast_waitstream(current->confchan, "");
2241  if (!res) {
2242  ast_copy_string(filename, get_announce_filename(current->announcetype), sizeof(filename));
2243  if (!ast_streamfile(current->confchan, filename, current->language))
2244  ast_waitstream(current->confchan, "");
2245  }
2246  }
2247  if (current->announcetype == CONF_HASLEFT) {
2248  ast_filedelete(current->namerecloc, NULL);
2249  }
2250  }
2251  }
2252 
2253  /* thread marked to stop, clean up */
2254  while ((current = AST_LIST_REMOVE_HEAD(&local_list, entry))) {
2255  ast_filedelete(current->namerecloc, NULL);
2256  ao2_ref(current, -1);
2257  }
2258  return NULL;
2259 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static const char * get_announce_filename(enum announcetypes type)
Definition: app_meetme.c:2194
struct ast_channel * confchan
Definition: app_meetme.c:709
struct ast_conference::@33 announcelist
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#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:155
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define LOG_DEBUG
Definition: logger.h:122
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
ast_mutex_t announcelistlock
Definition: app_meetme.c:756
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:224
char namerecloc[PATH_MAX]
Definition: app_meetme.c:707
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
while(yyssp!=yyss)
Definition: ast_expr2.c:2538
char language[MAX_LANGUAGE]
Definition: app_meetme.c:708
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
ast_cond_t announcelist_addition
Definition: app_meetme.c:754
unsigned int announcethread_stop
Definition: app_meetme.c:753
enum announcetypes announcetype
Definition: app_meetme.c:711
The MeetMe Conference object.
Definition: app_meetme.c:715
#define ast_mutex_unlock(a)
Definition: lock.h:156
#define AST_LIST_APPEND_LIST(head, list, field)
Appends a whole list to the tail of a list.
Definition: linkedlists.h:768
static void answer_trunk_chan ( struct ast_channel chan)
static

Definition at line 5585 of file app_meetme.c.

References ast_answer(), and ast_indicate().

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

5586 {
5587  ast_answer(chan);
5588  ast_indicate(chan, -1);
5589 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
AST_DATA_STRUCTURE ( ast_conference  ,
MEETME_DATA_EXPORT   
)
AST_DATA_STRUCTURE ( ast_conf_user  ,
MEETME_USER_DATA_EXPORT   
)
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
Returns
A pointer to the conference struct, or NULL if it wasn't found and make or dynamic were not set.

Definition at line 1213 of file app_meetme.c.

References ast_conference::announcethread, ast_conference::announcethreadlock, ao2_container_alloc, ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, ast_copy_string(), AST_FORMAT_SLINEAR, 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, conf_map, ast_conference::confno, ast_conference::dahdiconf, ast_conference::fd, ast_channel::fds, ast_conference::isdynamic, ast_conference::listenlock, LOG_WARNING, ast_conference::maxusers, ast_conference::pin, ast_conference::pinadmin, ast_conference::playlock, ast_conference::recordthread, ast_conference::recordthreadlock, ast_conference::refcount, ast_conference::start, ast_conference::uniqueid, ast_channel::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().

1216 {
1217  struct ast_conference *cnf;
1218  struct dahdi_confinfo dahdic = { 0, };
1219  int confno_int = 0;
1220 
1221  AST_LIST_LOCK(&confs);
1222 
1223  AST_LIST_TRAVERSE(&confs, cnf, list) {
1224  if (!strcmp(confno, cnf->confno))
1225  break;
1226  }
1227 
1228  if (cnf || (!make && !dynamic))
1229  goto cnfout;
1230 
1231  /* Make a new one */
1232  if (!(cnf = ast_calloc(1, sizeof(*cnf))) ||
1233  !(cnf->usercontainer = ao2_container_alloc(1, NULL, user_no_cmp))) {
1234  goto cnfout;
1235  }
1236 
1237  ast_mutex_init(&cnf->playlock);
1238  ast_mutex_init(&cnf->listenlock);
1243  ast_copy_string(cnf->confno, confno, sizeof(cnf->confno));
1244  ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
1245  ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
1246  ast_copy_string(cnf->uniqueid, chan->uniqueid, sizeof(cnf->uniqueid));
1247 
1248  /* Setup a new dahdi conference */
1249  dahdic.confno = -1;
1250  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
1251  cnf->fd = open("/dev/dahdi/pseudo", O_RDWR);
1252  if (cnf->fd < 0 || ioctl(cnf->fd, DAHDI_SETCONF, &dahdic)) {
1253  if (test) {
1254  /* if we are creating a conference for a unit test, it is not neccesary
1255  * to open a pseudo channel, so, if we fail continue creating
1256  * the conference. */
1257  ast_test_status_update(test, "Unable to open DAHDI pseudo device\n");
1258  } else {
1259  ast_log(LOG_WARNING, "Unable to open DAHDI pseudo device\n");
1260  if (cnf->fd >= 0)
1261  close(cnf->fd);
1262  ao2_ref(cnf->usercontainer, -1);
1263  ast_mutex_destroy(&cnf->playlock);
1267  ast_free(cnf);
1268  cnf = NULL;
1269  goto cnfout;
1270  }
1271  }
1272 
1273  cnf->dahdiconf = dahdic.confno;
1274 
1275  /* Setup a new channel for playback of audio files */
1276  cnf->chan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL);
1277  if (cnf->chan) {
1280  dahdic.chan = 0;
1281  dahdic.confno = cnf->dahdiconf;
1282  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
1283  if (ioctl(cnf->chan->fds[0], DAHDI_SETCONF, &dahdic)) {
1284  if (test) {
1285  ast_test_status_update(test, "Error setting conference on pseudo channel\n");
1286  }
1287  ast_log(LOG_WARNING, "Error setting conference\n");
1288  if (cnf->chan)
1289  ast_hangup(cnf->chan);
1290  else
1291  close(cnf->fd);
1292  ao2_ref(cnf->usercontainer, -1);
1293  ast_mutex_destroy(&cnf->playlock);
1297  ast_free(cnf);
1298  cnf = NULL;
1299  goto cnfout;
1300  }
1301  }
1302 
1303  /* Fill the conference struct */
1304  cnf->start = time(NULL);
1305  cnf->maxusers = 0x7fffffff;
1306  cnf->isdynamic = dynamic ? 1 : 0;
1307  ast_verb(3, "Created MeetMe conference %d for conference '%s'\n", cnf->dahdiconf, cnf->confno);
1308  AST_LIST_INSERT_HEAD(&confs, cnf, list);
1309 
1310  /* Reserve conference number in map */
1311  if ((sscanf(cnf->confno, "%30d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024))
1312  conf_map[confno_int] = 1;
1313 
1314 cnfout:
1315  if (cnf)
1316  ast_atomic_fetchadd_int(&cnf->refcount, refcount);
1317 
1319 
1320  return cnf;
1321 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:719
const ast_string_field uniqueid
Definition: channel.h:787
ast_mutex_t playlock
Definition: app_meetme.c:716
pthread_t recordthread
Definition: app_meetme.c:733
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:729
ast_mutex_t listenlock
Definition: app_meetme.c:717
#define ast_verb(level,...)
Definition: logger.h:243
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of &quot;format&quot; is ...
Definition: channel.c:5307
static int user_no_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1175
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int fds[AST_MAX_FDS]
Definition: channel.h:829
char uniqueid[32]
Definition: app_meetme.c:740
char pin[MAX_PIN]
Definition: app_meetme.c:738
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pthread_t announcethread
Definition: app_meetme.c:751
#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:696
#define ast_free(a)
Definition: astmm.h:97
struct ao2_container * usercontainer
Definition: app_meetme.c:748
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
char pinadmin[MAX_PIN]
Definition: app_meetme.c:739
static unsigned int conf_map[1024]
Definition: app_meetme.c:761
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
The MeetMe Conference object.
Definition: app_meetme.c:715
struct ast_channel * ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status)
Requests a channel.
Definition: channel.c:5695
ast_mutex_t recordthreadlock
Definition: app_meetme.c:734
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
ast_mutex_t announcethreadlock
Definition: app_meetme.c:752
static int can_write ( struct ast_channel chan,
struct ast_flags64 confflags 
)
static

Definition at line 2261 of file app_meetme.c.

References ast_channel::_state, AST_STATE_UP, ast_test_flag64, and CONFFLAG_NO_AUDIO_UNTIL_UP.

Referenced by conf_run().

2262 {
2263  if (!ast_test_flag64(confflags, CONFFLAG_NO_AUDIO_UNTIL_UP)) {
2264  return 1;
2265  }
2266 
2267  return (chan->_state == AST_STATE_UP);
2268 }
enum ast_channel_state _state
Definition: channel.h:839
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:626
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int careful_write ( int  fd,
unsigned char *  data,
int  len,
int  block 
)
static

Definition at line 1016 of file app_meetme.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by conf_play(), and conf_run().

1017 {
1018  int res;
1019  int x;
1020 
1021  while (len) {
1022  if (block) {
1023  x = DAHDI_IOMUX_WRITE | DAHDI_IOMUX_SIGEVENT;
1024  res = ioctl(fd, DAHDI_IOMUX, &x);
1025  } else
1026  res = 0;
1027  if (res >= 0)
1028  res = write(fd, data, len);
1029  if (res < 1) {
1030  if (errno != EAGAIN) {
1031  ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
1032  return -1;
1033  } else
1034  return 0;
1035  }
1036  len -= res;
1037  data += res;
1038  }
1039 
1040  return 0;
1041 }
#define LOG_WARNING
Definition: logger.h:144
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static int channel_admin_exec ( struct ast_channel chan,
const char *  data 
)
static

The MeetMeChannelAdmin application MeetMeChannelAdmin(channel, command)

Definition at line 4974 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ast_conf_user::adminflags, ao2_callback, ao2_ref, args, 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, user_chan_cb(), and ast_conference::usercontainer.

Referenced by load_module().

4974  {
4975  char *params;
4976  struct ast_conference *conf = NULL;
4977  struct ast_conf_user *user = NULL;
4979  AST_APP_ARG(channel);
4980  AST_APP_ARG(command);
4981  );
4982 
4983  if (ast_strlen_zero(data)) {
4984  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires two arguments!\n");
4985  return -1;
4986  }
4987 
4988  params = ast_strdupa(data);
4989  AST_STANDARD_APP_ARGS(args, params);
4990 
4991  if (!args.channel) {
4992  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires a channel name!\n");
4993  return -1;
4994  }
4995 
4996  if (!args.command) {
4997  ast_log(LOG_WARNING, "MeetMeChannelAdmin requires a command!\n");
4998  return -1;
4999  }
5000 
5001  AST_LIST_LOCK(&confs);
5002  AST_LIST_TRAVERSE(&confs, conf, list) {
5003  if ((user = ao2_callback(conf->usercontainer, 0, user_chan_cb, args.channel))) {
5004  break;
5005  }
5006  }
5007 
5008  if (!user) {
5009  ast_log(LOG_NOTICE, "Specified user (%s) not found\n", args.channel);
5011  return 0;
5012  }
5013 
5014  /* perform the specified action */
5015  switch (*args.command) {
5016  case 77: /* M: Mute */
5017  user->adminflags |= ADMINFLAG_MUTED;
5018  break;
5019  case 109: /* m: Unmute */
5020  user->adminflags &= ~ADMINFLAG_MUTED;
5021  break;
5022  case 107: /* k: Kick user */
5023  user->adminflags |= ADMINFLAG_KICKME;
5024  break;
5025  default: /* unknown command */
5026  ast_log(LOG_WARNING, "Unknown MeetMeChannelAdmin command '%s'\n", args.command);
5027  break;
5028  }
5029  ao2_ref(user, -1);
5031 
5032  return 0;
5033 }
#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:4792
#define LOG_WARNING
Definition: logger.h:144
#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:910
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ast_conf_user::@34 list
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#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:748
structure to hold users read from users.conf
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
The MeetMe Conference object.
Definition: app_meetme.c:715
static char* complete_confno ( const char *  word,
int  state 
)
static

Definition at line 1323 of file app_meetme.c.

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

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

1324 {
1325  struct ast_conference *cnf;
1326  char *ret = NULL;
1327  int which = 0;
1328  int len = strlen(word);
1329 
1330  AST_LIST_LOCK(&confs);
1331  AST_LIST_TRAVERSE(&confs, cnf, list) {
1332  if (!strncmp(word, cnf->confno, len) && ++which > state) {
1333  /* dup before releasing the lock */
1334  ret = ast_strdup(cnf->confno);
1335  break;
1336  }
1337  }
1339  return ret;
1340 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_conference::@32 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: ael.tab.c:203
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:715
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static char* complete_meetmecmd_list ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 1412 of file app_meetme.c.

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

Referenced by meetme_show_cmd().

1413 {
1414  int len;
1415 
1416  if (pos == 2) {
1417  len = strlen(word);
1418  if (!strncasecmp(word, STR_CONCISE, len)) {
1419  if (state == 0) {
1420  return ast_strdup(STR_CONCISE);
1421  }
1422  --state;
1423  }
1424 
1425  return complete_confno(word, state);
1426  }
1427  if (pos == 3 && state == 0) {
1428  char *saved = NULL;
1429  char *myline;
1430  char *confno;
1431 
1432  /* Extract the confno from the command line. */
1433  myline = ast_strdupa(line);
1434  strtok_r(myline, " ", &saved);
1435  strtok_r(NULL, " ", &saved);
1436  confno = strtok_r(NULL, " ", &saved);
1437 
1438  if (!strcasecmp(confno, STR_CONCISE)) {
1439  /* There is nothing valid in this position now. */
1440  return NULL;
1441  }
1442 
1443  len = strlen(word);
1444  if (!strncasecmp(word, STR_CONCISE, len)) {
1445  return ast_strdup(STR_CONCISE);
1446  }
1447  }
1448  return NULL;
1449 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define STR_CONCISE
Definition: app_meetme.c:526
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ael.tab.c:203
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1323
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static char* complete_meetmecmd_lock ( const char *  word,
int  pos,
int  state 
)
static

Definition at line 1404 of file app_meetme.c.

References complete_confno().

Referenced by meetme_lock_cmd().

1405 {
1406  if (pos == 2) {
1407  return complete_confno(word, state);
1408  }
1409  return NULL;
1410 }
Definition: ael.tab.c:203
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1323
static char* complete_meetmecmd_mute_kick ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 1364 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, and state.

Referenced by meetme_kick_cmd(), and meetme_mute_cmd().

1365 {
1366  if (pos == 2) {
1367  return complete_confno(word, state);
1368  }
1369  if (pos == 3) {
1370  int len = strlen(word);
1371  char *ret = NULL;
1372  char *saved = NULL;
1373  char *myline;
1374  char *confno;
1375  struct ast_conference *cnf;
1376 
1377  if (!strncasecmp(word, "all", len)) {
1378  if (state == 0) {
1379  return ast_strdup("all");
1380  }
1381  --state;
1382  }
1383 
1384  /* Extract the confno from the command line. */
1385  myline = ast_strdupa(line);
1386  strtok_r(myline, " ", &saved);
1387  strtok_r(NULL, " ", &saved);
1388  confno = strtok_r(NULL, " ", &saved);
1389 
1390  AST_LIST_LOCK(&confs);
1391  AST_LIST_TRAVERSE(&confs, cnf, list) {
1392  if (!strcmp(confno, cnf->confno)) {
1393  ret = complete_userno(cnf, word, state);
1394  break;
1395  }
1396  }
1398 
1399  return ret;
1400  }
1401  return NULL;
1402 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_conference::@32 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: ael.tab.c:203
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
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:1342
The MeetMe Conference object.
Definition: app_meetme.c:715
static char * complete_confno(const char *word, int state)
Definition: app_meetme.c:1323
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static char* complete_userno ( struct ast_conference cnf,
const char *  word,
int  state 
)
static

Definition at line 1342 of file app_meetme.c.

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

Referenced by complete_meetmecmd_mute_kick().

1343 {
1344  char usrno[50];
1345  struct ao2_iterator iter;
1346  struct ast_conf_user *usr;
1347  char *ret = NULL;
1348  int which = 0;
1349  int len = strlen(word);
1350 
1351  iter = ao2_iterator_init(cnf->usercontainer, 0);
1352  for (; (usr = ao2_iterator_next(&iter)); ao2_ref(usr, -1)) {
1353  snprintf(usrno, sizeof(usrno), "%d", usr->user_no);
1354  if (!strncmp(word, usrno, len) && ++which > state) {
1355  ao2_ref(usr, -1);
1356  ret = ast_strdup(usrno);
1357  break;
1358  }
1359  }
1360  ao2_iterator_destroy(&iter);
1361  return ret;
1362 }
#define ast_strdup(a)
Definition: astmm.h:109
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
Definition: ael.tab.c:203
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ao2_container * usercontainer
Definition: app_meetme.c:748
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static int conf_exec ( struct ast_channel chan,
const char *  data 
)
static

The meetme() application.

Definition at line 4419 of file app_meetme.c.

References ast_channel::_state, ast_conference::adminopts, args, ARRAY_LEN, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options64(), ast_category_browse(), 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_map, 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(), ast_conference::isdynamic, ast_channel::language, LOG_ERROR, LOG_WARNING, MAX_CONFNUM, MAX_PIN, MAX_SETTINGS, meetme_opts, ast_variable::name, ast_channel::name, ast_variable::next, OPT_ARG_ARRAY_SIZE, 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().

4420 {
4421  int res = -1;
4422  char confno[MAX_CONFNUM] = "";
4423  int allowretry = 0;
4424  int retrycnt = 0;
4425  struct ast_conference *cnf = NULL;
4426  struct ast_flags64 confflags = {0};
4427  struct ast_flags config_flags = { 0 };
4428  int dynamic = 0;
4429  int empty = 0, empty_no_pin = 0;
4430  int always_prompt = 0;
4431  const char *notdata;
4432  char *info, the_pin[MAX_PIN] = "";
4434  AST_APP_ARG(confno);
4435  AST_APP_ARG(options);
4436  AST_APP_ARG(pin);
4437  );
4438  char *optargs[OPT_ARG_ARRAY_SIZE] = { NULL, };
4439 
4440  if (ast_strlen_zero(data)) {
4441  allowretry = 1;
4442  notdata = "";
4443  } else {
4444  notdata = data;
4445  }
4446 
4447  if (chan->_state != AST_STATE_UP)
4448  ast_answer(chan);
4449 
4450  info = ast_strdupa(notdata);
4451 
4452  AST_STANDARD_APP_ARGS(args, info);
4453 
4454  if (args.confno) {
4455  ast_copy_string(confno, args.confno, sizeof(confno));
4456  if (ast_strlen_zero(confno)) {
4457  allowretry = 1;
4458  }
4459  }
4460 
4461  if (args.pin)
4462  ast_copy_string(the_pin, args.pin, sizeof(the_pin));
4463 
4464  if (args.options) {
4465  ast_app_parse_options64(meetme_opts, &confflags, optargs, args.options);
4466  dynamic = ast_test_flag64(&confflags, CONFFLAG_DYNAMIC | CONFFLAG_DYNAMICPIN);
4467  if (ast_test_flag64(&confflags, CONFFLAG_DYNAMICPIN) && ast_strlen_zero(args.pin))
4468  strcpy(the_pin, "q");
4469 
4470  empty = ast_test_flag64(&confflags, CONFFLAG_EMPTY | CONFFLAG_EMPTYNOPIN);
4471  empty_no_pin = ast_test_flag64(&confflags, CONFFLAG_EMPTYNOPIN);
4472  always_prompt = ast_test_flag64(&confflags, CONFFLAG_ALWAYSPROMPT | CONFFLAG_DYNAMICPIN);
4473  }
4474 
4475  do {
4476  if (retrycnt > 3)
4477  allowretry = 0;
4478  if (empty) {
4479  int i;
4480  struct ast_config *cfg;
4481  struct ast_variable *var;
4482  int confno_int;
4483 
4484  /* We only need to load the config file for static and empty_no_pin (otherwise we don't care) */
4485  if ((empty_no_pin) || (!dynamic)) {
4486  cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
4487  if (cfg && cfg != CONFIG_STATUS_FILEINVALID) {
4488  var = ast_variable_browse(cfg, "rooms");
4489  while (var) {
4490  char parse[MAX_SETTINGS], *stringp = parse, *confno_tmp;
4491  if (!strcasecmp(var->name, "conf")) {
4492  int found = 0;
4493  ast_copy_string(parse, var->value, sizeof(parse));
4494  confno_tmp = strsep(&stringp, "|,");
4495  if (!dynamic) {
4496  /* For static: run through the list and see if this conference is empty */
4497  AST_LIST_LOCK(&confs);
4498  AST_LIST_TRAVERSE(&confs, cnf, list) {
4499  if (!strcmp(confno_tmp, cnf->confno)) {
4500  /* The conference exists, therefore it's not empty */
4501  found = 1;
4502  break;
4503  }
4504  }
4506  cnf = NULL;
4507  if (!found) {
4508  /* At this point, we have a confno_tmp (static conference) that is empty */
4509  if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) {
4510  /* Case 1: empty_no_pin and pin is nonexistent (NULL)
4511  * Case 2: empty_no_pin and pin is blank (but not NULL)
4512  * Case 3: not empty_no_pin
4513  */
4514  ast_copy_string(confno, confno_tmp, sizeof(confno));
4515  break;
4516  }
4517  }
4518  }
4519  }
4520  var = var->next;
4521  }
4522  ast_config_destroy(cfg);
4523  }
4524 
4525  if (ast_strlen_zero(confno) && (cfg = ast_load_realtime_multientry("meetme", "confno LIKE", "%", SENTINEL))) {
4526  const char *catg;
4527  for (catg = ast_category_browse(cfg, NULL); catg; catg = ast_category_browse(cfg, catg)) {
4528  const char *confno_tmp = ast_variable_retrieve(cfg, catg, "confno");
4529  const char *pin_tmp = ast_variable_retrieve(cfg, catg, "pin");
4530  if (ast_strlen_zero(confno_tmp)) {
4531  continue;
4532  }
4533  if (!dynamic) {
4534  int found = 0;
4535  /* For static: run through the list and see if this conference is empty */
4536  AST_LIST_LOCK(&confs);
4537  AST_LIST_TRAVERSE(&confs, cnf, list) {
4538  if (!strcmp(confno_tmp, cnf->confno)) {
4539  /* The conference exists, therefore it's not empty */
4540  found = 1;
4541  break;
4542  }
4543  }
4545  if (!found) {
4546  /* At this point, we have a confno_tmp (realtime conference) that is empty */
4547  if ((empty_no_pin && ast_strlen_zero(pin_tmp)) || (!empty_no_pin)) {
4548  /* Case 1: empty_no_pin and pin is nonexistent (NULL)
4549  * Case 2: empty_no_pin and pin is blank (but not NULL)
4550  * Case 3: not empty_no_pin
4551  */
4552  ast_copy_string(confno, confno_tmp, sizeof(confno));
4553  break;
4554  }
4555  }
4556  }
4557  }
4558  ast_config_destroy(cfg);
4559  }
4560  }
4561 
4562  /* Select first conference number not in use */
4563  if (ast_strlen_zero(confno) && dynamic) {
4564  AST_LIST_LOCK(&confs);
4565  for (i = 0; i < ARRAY_LEN(conf_map); i++) {
4566  if (!conf_map[i]) {
4567  snprintf(confno, sizeof(confno), "%d", i);
4568  conf_map[i] = 1;
4569  break;
4570  }
4571  }
4573  }
4574 
4575  /* Not found? */
4576  if (ast_strlen_zero(confno)) {
4577  ast_test_suite_event_notify("PLAYBACK", "Message: conf-noempty");
4578  res = ast_streamfile(chan, "conf-noempty", chan->language);
4579  if (!res)
4580  ast_waitstream(chan, "");
4581  } else {
4582  if (sscanf(confno, "%30d", &confno_int) == 1) {
4583  if (!ast_test_flag64(&confflags, CONFFLAG_QUIET)) {
4584  res = ast_streamfile(chan, "conf-enteringno", chan->language);
4585  if (!res) {
4586  ast_waitstream(chan, "");
4587  res = ast_say_digits(chan, confno_int, "", chan->language);
4588  }
4589  }
4590  } else {
4591  ast_log(LOG_ERROR, "Could not scan confno '%s'\n", confno);
4592  }
4593  }
4594  }
4595 
4596  while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) {
4597  /* Prompt user for conference number */
4598  res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
4599  if (res < 0) {
4600  /* Don't try to validate when we catch an error */
4601  confno[0] = '\0';
4602  allowretry = 0;
4603  break;
4604  }
4605  }
4606  if (!ast_strlen_zero(confno)) {
4607  /* Check the validity of the conference */
4608  cnf = find_conf(chan, confno, 1, dynamic, the_pin,
4609  sizeof(the_pin), 1, &confflags);
4610  if (!cnf) {
4611  int too_early = 0;
4612 
4613  cnf = find_conf_realtime(chan, confno, 1, dynamic,
4614  the_pin, sizeof(the_pin), 1, &confflags, &too_early, optargs);
4615  if (rt_schedule && too_early)
4616  allowretry = 0;
4617  }
4618 
4619  if (!cnf) {
4620  if (allowretry) {
4621  confno[0] = '\0';
4622  res = ast_streamfile(chan, "conf-invalid", chan->language);
4623  if (!res)
4624  ast_waitstream(chan, "");
4625  res = -1;
4626  }
4627  } else {
4628  /* Conference requires a pin for specified access level */
4629  int req_pin = !ast_strlen_zero(cnf->pin) ||
4630  (!ast_strlen_zero(cnf->pinadmin) &&
4631  ast_test_flag64(&confflags, CONFFLAG_ADMIN));
4632  /* The following logic was derived from a
4633  * 4 variable truth table and defines which
4634  * circumstances are not exempt from pin
4635  * checking.
4636  * If this needs to be modified, write the
4637  * truth table back out from the boolean
4638  * expression AB+A'D+C', change the erroneous
4639  * result, and rederive the expression.
4640  * Variables:
4641  * A: pin provided?
4642  * B: always prompt?
4643  * C: dynamic?
4644  * D: has users? */
4645  int not_exempt = !cnf->isdynamic;
4646  not_exempt = not_exempt || (!ast_strlen_zero(args.pin) && ast_test_flag64(&confflags, CONFFLAG_ALWAYSPROMPT));
4647  not_exempt = not_exempt || (ast_strlen_zero(args.pin) && cnf->users);
4648  if (req_pin && not_exempt) {
4649  char pin[MAX_PIN] = "";
4650  int j;
4651 
4652  /* Allow the pin to be retried up to 3 times */
4653  for (j = 0; j < 3; j++) {
4654  if (*the_pin && (always_prompt == 0)) {
4655  ast_copy_string(pin, the_pin, sizeof(pin));
4656  res = 0;
4657  } else {
4658  /* Prompt user for pin if pin is required */
4659  ast_test_suite_event_notify("PLAYBACK", "Message: conf-getpin\r\n"
4660  "Channel: %s",
4661  chan->name);
4662  res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0);
4663  }
4664  if (res >= 0) {
4665  if ((!strcasecmp(pin, cnf->pin) &&
4666  (ast_strlen_zero(cnf->pinadmin) ||
4667  !ast_test_flag64(&confflags, CONFFLAG_ADMIN))) ||
4668  (!ast_strlen_zero(cnf->pinadmin) &&
4669  !strcasecmp(pin, cnf->pinadmin))) {
4670  /* Pin correct */
4671  allowretry = 0;
4672  if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin)) {
4673  if (!ast_strlen_zero(cnf->adminopts)) {
4674  char *opts = ast_strdupa(cnf->adminopts);
4675  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
4676  }
4677  } else {
4678  if (!ast_strlen_zero(cnf->useropts)) {
4679  char *opts = ast_strdupa(cnf->useropts);
4680  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
4681  }
4682  }
4683  /* Run the conference */
4684  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n", cnf->confno, cnf->recordingfilename, cnf->recordingformat);
4685  res = conf_run(chan, cnf, &confflags, optargs);
4686  break;
4687  } else {
4688  /* Pin invalid */
4689  if (!ast_streamfile(chan, "conf-invalidpin", chan->language)) {
4690  res = ast_waitstream(chan, AST_DIGIT_ANY);
4691  ast_stopstream(chan);
4692  } else {
4693  ast_log(LOG_WARNING, "Couldn't play invalid pin msg!\n");
4694  break;
4695  }
4696  if (res < 0)
4697  break;
4698  pin[0] = res;
4699  pin[1] = '\0';
4700  res = -1;
4701  if (allowretry)
4702  confno[0] = '\0';
4703  }
4704  } else {
4705  /* failed when getting the pin */
4706  res = -1;
4707  allowretry = 0;
4708  /* see if we need to get rid of the conference */
4709  break;
4710  }
4711 
4712  /* Don't retry pin with a static pin */
4713  if (*the_pin && (always_prompt == 0)) {
4714  break;
4715  }
4716  }
4717  } else {
4718  /* No pin required */
4719  allowretry = 0;
4720 
4721  /* For RealTime conferences without a pin
4722  * should still support loading options
4723  */
4724  if (!ast_strlen_zero(cnf->useropts)) {
4725  char *opts = ast_strdupa(cnf->useropts);
4726  ast_app_parse_options64(meetme_opts, &confflags, optargs, opts);
4727  }
4728 
4729  /* Run the conference */
4730  res = conf_run(chan, cnf, &confflags, optargs);
4731  }
4732  dispose_conf(cnf);
4733  cnf = NULL;
4734  }
4735  }
4736  } while (allowretry);
4737 
4738  if (cnf)
4739  dispose_conf(cnf);
4740 
4741  return res;
4742 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#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:2097
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
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: app.c:178
char * strsep(char **str, const char *delims)
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:4270
#define AST_DIGIT_ANY
Definition: file.h:47
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: app.c:2106
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:729
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
char * recordingformat
Definition: app_meetme.c:737
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8409
const char * useropts
Definition: app_meetme.c:742
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int rt_schedule
Definition: app_meetme.c:684
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:2759
#define SENTINEL
Definition: compiler.h:75
const char * value
Definition: config.h:79
static struct ast_app_option meetme_opts[128]
Definition: app_meetme.c:674
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
char pin[MAX_PIN]
Definition: app_meetme.c:738
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:1858
const char * adminopts
Definition: app_meetme.c:743
Structure used to handle boolean flags.
Definition: utils.h:200
#define MAX_CONFNUM
Definition: app_meetme.c:693
#define MAX_SETTINGS
Definition: app_meetme.c:698
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
char pinadmin[MAX_PIN]
Definition: app_meetme.c:739
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
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:4082
static unsigned int conf_map[1024]
Definition: app_meetme.c:761
char * recordingfilename
Definition: app_meetme.c:736
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
struct ast_variable * next
Definition: config.h:82
#define MAX_PIN
Definition: app_meetme.c:694
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
The MeetMe Conference object.
Definition: app_meetme.c:715
#define CONFIG_FILE_NAME
Definition: app_meetme.c:524
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2650
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static void conf_flush ( int  fd,
struct ast_channel chan 
)
static

Definition at line 1894 of file app_meetme.c.

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

Referenced by conf_run().

1895 {
1896  int x;
1897 
1898  /* read any frames that may be waiting on the channel
1899  and throw them away
1900  */
1901  if (chan) {
1902  struct ast_frame *f;
1903 
1904  /* when no frames are available, this will wait
1905  for 1 millisecond maximum
1906  */
1907  while (ast_waitfor(chan, 1) > 0) {
1908  f = ast_read(chan);
1909  if (f)
1910  ast_frfree(f);
1911  else /* channel was hung up or something else happened */
1912  break;
1913  }
1914  }
1915 
1916  /* flush any data sitting in the pseudo channel */
1917  x = DAHDI_FLUSH_ALL;
1918  if (ioctl(fd, DAHDI_FLUSH, &x))
1919  ast_log(LOG_WARNING, "Error flushing channel\n");
1920 
1921 }
#define LOG_WARNING
Definition: logger.h:144
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_format f[]
Definition: format_g726.c:181
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_frfree(fr)
Definition: frame.h:583
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 1926 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::confno, EVENT_FLAG_CALL, ast_conference::fd, ast_conference::lchan, ast_conference::listenlock, manager_event, MEETME_RECORD_ACTIVE, MEETME_RECORD_OFF, MEETME_RECORD_TERMINATE, announce_listitem::namerecloc, ast_conference::origframe, ast_conference::playlock, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthreadlock, ast_conference::transframe, ast_conference::transpath, and ast_conference::usercontainer.

Referenced by dispose_conf().

1927 {
1928  int x;
1929  struct announce_listitem *item;
1930 
1931  AST_LIST_REMOVE(&confs, conf, list);
1932  manager_event(EVENT_FLAG_CALL, "MeetmeEnd", "Meetme: %s\r\n", conf->confno);
1933 
1934  if (conf->recording == MEETME_RECORD_ACTIVE) {
1935  conf->recording = MEETME_RECORD_TERMINATE;
1937  while (1) {
1938  usleep(1);
1939  AST_LIST_LOCK(&confs);
1940  if (conf->recording == MEETME_RECORD_OFF)
1941  break;
1943  }
1944  }
1945 
1946  for (x = 0; x < AST_FRAME_BITS; x++) {
1947  if (conf->transframe[x])
1948  ast_frfree(conf->transframe[x]);
1949  if (conf->transpath[x])
1951  }
1952  if (conf->announcethread != AST_PTHREADT_NULL) {
1954  conf->announcethread_stop = 1;
1958  pthread_join(conf->announcethread, NULL);
1959 
1960  while ((item = AST_LIST_REMOVE_HEAD(&conf->announcelist, entry))) {
1961  ast_filedelete(item->namerecloc, NULL);
1962  ao2_ref(item, -1);
1963  }
1965  }
1966 
1967  if (conf->origframe)
1968  ast_frfree(conf->origframe);
1969  if (conf->lchan)
1970  ast_hangup(conf->lchan);
1971  if (conf->chan)
1972  ast_hangup(conf->chan);
1973  if (conf->fd >= 0)
1974  close(conf->fd);
1975  if (conf->recordingfilename) {
1976  ast_free(conf->recordingfilename);
1977  }
1978  if (conf->usercontainer) {
1979  ao2_ref(conf->usercontainer, -1);
1980  }
1981  if (conf->recordingformat) {
1982  ast_free(conf->recordingformat);
1983  }
1984  ast_mutex_destroy(&conf->playlock);
1985  ast_mutex_destroy(&conf->listenlock);
1988  ast_free(conf);
1989 
1990  return 0;
1991 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:719
ast_mutex_t playlock
Definition: app_meetme.c:716
#define AST_FRAME_BITS
Definition: app_meetme.c:545
struct ast_frame * origframe
Definition: app_meetme.c:746
struct announce_listitem::@31 entry
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:737
struct ast_frame * transframe[32]
Definition: app_meetme.c:745
struct ast_conference::@33 announcelist
#define EVENT_FLAG_CALL
Definition: manager.h:72
ast_mutex_t listenlock
Definition: app_meetme.c:717
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:841
#define ast_cond_signal(cond)
Definition: lock.h:169
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
ast_mutex_t announcelistlock
Definition: app_meetme.c:756
char namerecloc[PATH_MAX]
Definition: app_meetme.c:707
pthread_t announcethread
Definition: app_meetme.c:751
#define ast_free(a)
Definition: astmm.h:97
struct ao2_container * usercontainer
Definition: app_meetme.c:748
struct ast_trans_pvt * transpath[32]
Definition: app_meetme.c:747
ast_cond_t announcelist_addition
Definition: app_meetme.c:754
unsigned int announcethread_stop
Definition: app_meetme.c:753
char * recordingfilename
Definition: app_meetme.c:736
struct ast_channel * lchan
Definition: app_meetme.c:720
#define ast_frfree(fr)
Definition: frame.h:583
#define ast_mutex_destroy(a)
Definition: lock.h:154
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:272
#define ast_mutex_unlock(a)
Definition: lock.h:156
ast_mutex_t recordthreadlock
Definition: app_meetme.c:734
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
ast_mutex_t announcethreadlock
Definition: app_meetme.c:752
static void conf_play ( struct ast_channel chan,
struct ast_conference conf,
enum entrance_sound  sound 
)
static

Definition at line 1134 of file app_meetme.c.

References ast_autoservice_start(), ast_autoservice_stop(), 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 ast_channel::name.

Referenced by conf_run().

1135 {
1136  unsigned char *data;
1137  int len;
1138  int res = -1;
1139 
1140  ast_test_suite_event_notify("CONFPLAY", "Channel: %s\r\n"
1141  "Conference: %s\r\n"
1142  "Marked: %d",
1143  chan->name,
1144  conf->confno,
1145  conf->markedusers);
1146 
1147  if (!ast_check_hangup(chan))
1148  res = ast_autoservice_start(chan);
1149 
1150  AST_LIST_LOCK(&confs);
1151 
1152  switch(sound) {
1153  case ENTER:
1154  data = enter;
1155  len = sizeof(enter);
1156  break;
1157  case LEAVE:
1158  data = leave;
1159  len = sizeof(leave);
1160  break;
1161  default:
1162  data = NULL;
1163  len = 0;
1164  }
1165  if (data) {
1166  careful_write(conf->fd, data, len, 1);
1167  }
1168 
1170 
1171  if (!res)
1172  ast_autoservice_stop(chan);
1173 }
#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:179
static int careful_write(int fd, unsigned char *data, int len, int block)
Definition: app_meetme.c:1016
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
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field name
Definition: channel.h:787
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static void conf_queue_dtmf ( const struct ast_conference conf,
const struct ast_conf_user sender,
struct ast_frame f 
)
static

Definition at line 1993 of file app_meetme.c.

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

Referenced by conf_run().

1995 {
1996  struct ast_conf_user *user;
1997  struct ao2_iterator user_iter;
1998 
1999  user_iter = ao2_iterator_init(conf->usercontainer, 0);
2000  while ((user = ao2_iterator_next(&user_iter))) {
2001  if (user == sender) {
2002  ao2_ref(user, -1);
2003  continue;
2004  }
2005  if (ast_write(user->chan, f) < 0)
2006  ast_log(LOG_WARNING, "Error writing frame to channel %s\n", user->chan->name);
2007  ao2_ref(user, -1);
2008  }
2009  ao2_iterator_destroy(&user_iter);
2010 }
static char user[512]
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define LOG_WARNING
Definition: logger.h:144
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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:4916
struct ao2_container * usercontainer
Definition: app_meetme.c:748
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
struct ast_channel * chan
Definition: app_meetme.c:773
static int conf_run ( struct ast_channel chan,
struct ast_conference conf,
struct ast_flags64 confflags,
char *  optargs[] 
)
static

Definition at line 2759 of file app_meetme.c.

References volume::actual, 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_link, ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, ast_check_hangup(), 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_FORMAT_SLINEAR, 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_free, ast_frfree, AST_FRIENDLY_OFFSET, ast_func_write(), ast_goto_if_exists(), ast_hangup(), ast_indicate(), 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_manager_event, AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_mkdir(), ast_mktime(), ast_module_helper(), 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_channel::audiohooks, ast_conference::bookid, ast_channel::caller, can_write(), careful_write(), ast_conference::chan, ast_conf_user::chan, ast_frame_subclass::codec, 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_INTROUSERNOREVIEW, CONFFLAG_KEYEXIT, CONFFLAG_KICK_CONTINUE, 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, ast_channel::connected, ast_channel::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, EVENT_FLAG_CALL, exitcontext, f, ast_channel::fds, ast_frame::frametype, ast_conference::gmuted, ast_party_caller::id, ast_party_connected_line::id, ast_frame_subclass::integer, ast_conference::isdynamic, ast_conf_user::jointime, ast_conf_user::kicktime, announce_listitem::language, ast_channel::language, ast_conference::lchan, LEAVE, ast_conf_user::listen, ast_conference::listenlock, ast_conference::locked, LOG_WARNING, ast_channel::macrocontext, ast_conference::markedusers, ast_conference::maxusers, MEETME_DELAYDETECTENDTALK, MEETME_DELAYDETECTTALK, meetme_menu(), MENU_ADMIN, MENU_DISABLED, MENU_NORMAL, ast_channel::monitor, ast_variable::name, ast_party_id::name, ast_channel::name, announce_listitem::namerecloc, ast_conf_user::namerecloc, ast_variable::next, ast_party_id::number, OBJ_NODATA, ast_frame::offset, OPT_ARG_DURATION_LIMIT, OPT_ARG_DURATION_STOP, OPT_ARG_EXITKEYS, OPT_ARG_INTROMSG, OPT_ARG_MOH_CLASS, OPT_ARG_WAITMARKED, ast_conference::origframe, parse(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_exec(), pbx_findapp(), ast_conf_user::play_warning, ast_conference::playlock, ast_frame::ptr, ast_channel::rawwriteformat, ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthread, ast_conference::recordthreadlock, reset_volumes(), RQ_UINTEGER1, RQ_UINTEGER2, RQ_UINTEGER3, RQ_UINTEGER4, S_COR, ast_frame::samples, set_talk_volume(), set_user_talking(), SLA_EVENT_HOLD, sla_queue_event_conf(), ast_conf_user::start_time, ast_party_name::str, ast_party_number::str, strsep(), ast_frame::subclass, ast_conf_user::talk, ast_conf_user::talking, ast_channel::tech, THRESHOLD_SILENCE, ast_conf_user::timelimit, ast_conference::transframe, ast_conference::transpath, ast_channel_tech::type, ast_conference::uniqueid, ast_channel::uniqueid, user_max_cmp(), ast_conf_user::user_no, ast_conference::usercontainer, ast_conf_user::userflags, ast_conference::users, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, 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().

2760 {
2761  struct ast_conf_user *user = NULL;
2762  int fd;
2763  struct dahdi_confinfo dahdic, dahdic_empty;
2764  struct ast_frame *f;
2765  struct ast_channel *c;
2766  struct ast_frame fr;
2767  int outfd;
2768  int ms;
2769  int nfds;
2770  int res;
2771  int retrydahdi;
2772  int origfd;
2773  int musiconhold = 0, mohtempstopped = 0;
2774  int firstpass = 0;
2775  int lastmarked = 0;
2776  int currentmarked = 0;
2777  int ret = -1;
2778  int x;
2779  enum menu_modes menu_mode = MENU_DISABLED;
2780  int talkreq_manager = 0;
2781  int using_pseudo = 0;
2782  int duration = 20;
2783  int sent_event = 0;
2784  int checked = 0;
2785  int announcement_played = 0;
2786  struct timeval now;
2787  struct ast_dsp *dsp = NULL;
2788  struct ast_app *agi_app;
2789  char *agifile, *mod_speex;
2790  const char *agifiledefault = "conf-background.agi", *tmpvar;
2791  char meetmesecs[30] = "";
2792  char exitcontext[AST_MAX_CONTEXT] = "";
2793  char recordingtmp[AST_MAX_EXTENSION] = "";
2794  char members[10] = "";
2795  int dtmf = 0, opt_waitmarked_timeout = 0;
2796  time_t timeout = 0;
2797  struct dahdi_bufferinfo bi;
2798  char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
2799  char *buf = __buf + AST_FRIENDLY_OFFSET;
2800  char *exitkeys = NULL;
2801  unsigned int calldurationlimit = 0;
2802  long timelimit = 0;
2803  long play_warning = 0;
2804  long warning_freq = 0;
2805  const char *warning_sound = NULL;
2806  const char *end_sound = NULL;
2807  char *parse;
2808  long time_left_ms = 0;
2809  struct timeval nexteventts = { 0, };
2810  int to;
2811  int setusercount = 0;
2812  int confsilence = 0, totalsilence = 0;
2813 
2814  if (!(user = ao2_alloc(sizeof(*user), NULL))) {
2815  return ret;
2816  }
2817 
2818  /* Possible timeout waiting for marked user */
2819  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) &&
2820  !ast_strlen_zero(optargs[OPT_ARG_WAITMARKED]) &&
2821  (sscanf(optargs[OPT_ARG_WAITMARKED], "%30d", &opt_waitmarked_timeout) == 1) &&
2822  (opt_waitmarked_timeout > 0)) {
2823  timeout = time(NULL) + opt_waitmarked_timeout;
2824  }
2825 
2827  calldurationlimit = atoi(optargs[OPT_ARG_DURATION_STOP]);
2828  ast_verb(3, "Setting call duration limit to %u seconds.\n", calldurationlimit);
2829  }
2830 
2832  char *limit_str, *warning_str, *warnfreq_str;
2833  const char *var;
2834 
2835  parse = optargs[OPT_ARG_DURATION_LIMIT];
2836  limit_str = strsep(&parse, ":");
2837  warning_str = strsep(&parse, ":");
2838  warnfreq_str = parse;
2839 
2840  timelimit = atol(limit_str);
2841  if (warning_str)
2842  play_warning = atol(warning_str);
2843  if (warnfreq_str)
2844  warning_freq = atol(warnfreq_str);
2845 
2846  if (!timelimit) {
2847  timelimit = play_warning = warning_freq = 0;
2848  warning_sound = NULL;
2849  } else if (play_warning > timelimit) {
2850  if (!warning_freq) {
2851  play_warning = 0;
2852  } else {
2853  while (play_warning > timelimit)
2854  play_warning -= warning_freq;
2855  if (play_warning < 1)
2856  play_warning = warning_freq = 0;
2857  }
2858  }
2859 
2860  ast_verb(3, "Setting conference duration limit to: %ldms.\n", timelimit);
2861  if (play_warning) {
2862  ast_verb(3, "Setting warning time to %ldms from the conference duration limit.\n", play_warning);
2863  }
2864  if (warning_freq) {
2865  ast_verb(3, "Setting warning frequency to %ldms.\n", warning_freq);
2866  }
2867 
2868  ast_channel_lock(chan);
2869  if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_WARNING_FILE"))) {
2870  var = ast_strdupa(var);
2871  }
2872  ast_channel_unlock(chan);
2873 
2874  warning_sound = var ? var : "timeleft";
2875 
2876  ast_channel_lock(chan);
2877  if ((var = pbx_builtin_getvar_helper(chan, "CONF_LIMIT_TIMEOUT_FILE"))) {
2878  var = ast_strdupa(var);
2879  }
2880  ast_channel_unlock(chan);
2881 
2882  end_sound = var ? var : NULL;
2883 
2884  /* undo effect of S(x) in case they are both used */
2885  calldurationlimit = 0;
2886  /* more efficient do it like S(x) does since no advanced opts */
2887  if (!play_warning && !end_sound && timelimit) {
2888  calldurationlimit = timelimit / 1000;
2889  timelimit = play_warning = warning_freq = 0;
2890  } else {
2891  ast_debug(2, "Limit Data for this call:\n");
2892  ast_debug(2, "- timelimit = %ld\n", timelimit);
2893  ast_debug(2, "- play_warning = %ld\n", play_warning);
2894  ast_debug(2, "- warning_freq = %ld\n", warning_freq);
2895  ast_debug(2, "- warning_sound = %s\n", warning_sound ? warning_sound : "UNDEF");
2896  ast_debug(2, "- end_sound = %s\n", end_sound ? end_sound : "UNDEF");
2897  }
2898  }
2899 
2900  /* Get exit keys */
2901  if (ast_test_flag64(confflags, CONFFLAG_KEYEXIT)) {
2902  if (!ast_strlen_zero(optargs[OPT_ARG_EXITKEYS]))
2903  exitkeys = ast_strdupa(optargs[OPT_ARG_EXITKEYS]);
2904  else
2905  exitkeys = ast_strdupa("#"); /* Default */
2906  }
2907 
2908  if (ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
2909  if (!conf->recordingfilename) {
2910  const char *var;
2911  ast_channel_lock(chan);
2912  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
2913  conf->recordingfilename = ast_strdup(var);
2914  }
2915  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
2916  conf->recordingformat = ast_strdup(var);
2917  }
2918  ast_channel_unlock(chan);
2919  if (!conf->recordingfilename) {
2920  snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid);
2921  conf->recordingfilename = ast_strdup(recordingtmp);
2922  }
2923  if (!conf->recordingformat) {
2924  conf->recordingformat = ast_strdup("wav");
2925  }
2926  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
2927  conf->confno, conf->recordingfilename, conf->recordingformat);
2928  }
2929  }
2930 
2932  if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) &&
2933  ((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
2936  dahdic.chan = 0;
2937  dahdic.confno = conf->dahdiconf;
2938  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
2939  if (ioctl(conf->lchan->fds[0], DAHDI_SETCONF, &dahdic)) {
2940  ast_log(LOG_WARNING, "Error starting listen channel\n");
2941  ast_hangup(conf->lchan);
2942  conf->lchan = NULL;
2943  } else {
2945  }
2946  }
2948 
2950  if ((conf->announcethread == AST_PTHREADT_NULL) && !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
2955  }
2957 
2958  time(&user->jointime);
2959 
2960  user->timelimit = timelimit;
2961  user->play_warning = play_warning;
2962  user->warning_freq = warning_freq;
2963  user->warning_sound = warning_sound;
2964  user->end_sound = end_sound;
2965 
2966  if (calldurationlimit > 0) {
2967  time(&user->kicktime);
2968  user->kicktime = user->kicktime + calldurationlimit;
2969  }
2970 
2971  if (ast_tvzero(user->start_time))
2972  user->start_time = ast_tvnow();
2973  time_left_ms = user->timelimit;
2974 
2975  if (user->timelimit) {
2976  nexteventts = ast_tvadd(user->start_time, ast_samp2tv(user->timelimit, 1000));
2977  nexteventts = ast_tvsub(nexteventts, ast_samp2tv(user->play_warning, 1000));
2978  }
2979 
2980  if (conf->locked && (!ast_test_flag64(confflags, CONFFLAG_ADMIN))) {
2981  /* Sorry, but this conference is locked! */
2982  if (!ast_streamfile(chan, "conf-locked", chan->language))
2983  ast_waitstream(chan, "");
2984  goto outrun;
2985  }
2986 
2987  ast_mutex_lock(&conf->playlock);
2988 
2989  if (rt_schedule && conf->maxusers) {
2990  if (conf->users >= conf->maxusers) {
2991  /* Sorry, but this confernce has reached the participant limit! */
2992  ast_mutex_unlock(&conf->playlock);
2993  if (!ast_streamfile(chan, "conf-full", chan->language))
2994  ast_waitstream(chan, "");
2995  goto outrun;
2996  }
2997  }
2998 
2999  ao2_lock(conf->usercontainer);
3001  user->user_no++;
3002  ao2_link(conf->usercontainer, user);
3003  ao2_unlock(conf->usercontainer);
3004 
3005  user->chan = chan;
3006  user->userflags = *confflags;
3008  user->adminflags |= (conf->gmuted) ? ADMINFLAG_MUTED : 0;
3009  user->talking = -1;
3010 
3011  ast_mutex_unlock(&conf->playlock);
3012 
3013  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && (ast_test_flag64(confflags, CONFFLAG_INTROUSER) ||
3015  char destdir[PATH_MAX];
3016 
3017  snprintf(destdir, sizeof(destdir), "%s/meetme", ast_config_AST_SPOOL_DIR);
3018 
3019  if (ast_mkdir(destdir, 0777) != 0) {
3020  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", destdir, strerror(errno));
3021  goto outrun;
3022  }
3023 
3024  snprintf(user->namerecloc, sizeof(user->namerecloc),
3025  "%s/meetme-username-%s-%d", destdir,
3026  conf->confno, user->user_no);
3028  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);
3029  else
3030  res = ast_record_review(chan, "vm-rec-name", user->namerecloc, 10, "sln", &duration, NULL);
3031  if (res == -1)
3032  goto outrun;
3033  }
3034 
3035  ast_mutex_lock(&conf->playlock);
3036 
3037  if (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER))
3038  conf->markedusers++;
3039  conf->users++;
3040  if (rt_log_members) {
3041  /* Update table */
3042  snprintf(members, sizeof(members), "%d", conf->users);
3043  ast_realtime_require_field("meetme",
3044  "confno", strlen(conf->confno) > 7 ? RQ_UINTEGER4 : strlen(conf->confno) > 4 ? RQ_UINTEGER3 : RQ_UINTEGER2, strlen(conf->confno),
3045  "members", RQ_UINTEGER1, strlen(members),
3046  NULL);
3047  ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
3048  }
3049  setusercount = 1;
3050 
3051  /* This device changed state now - if this is the first user */
3052  if (conf->users == 1)
3054 
3055  ast_mutex_unlock(&conf->playlock);
3056 
3057  /* return the unique ID of the conference */
3058  pbx_builtin_setvar_helper(chan, "MEETMEUNIQUEID", conf->uniqueid);
3059 
3060  if (ast_test_flag64(confflags, CONFFLAG_EXIT_CONTEXT)) {
3061  ast_channel_lock(chan);
3062  if ((tmpvar = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) {
3063  ast_copy_string(exitcontext, tmpvar, sizeof(exitcontext));
3064  } else if (!ast_strlen_zero(chan->macrocontext)) {
3065  ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext));
3066  } else {
3067  ast_copy_string(exitcontext, chan->context, sizeof(exitcontext));
3068  }
3069  ast_channel_unlock(chan);
3070  }
3071 
3072  /* Play an arbitrary intro message */
3073  if (ast_test_flag64(confflags, CONFFLAG_INTROMSG) &&
3074  !ast_strlen_zero(optargs[OPT_ARG_INTROMSG])) {
3075  if (!ast_streamfile(chan, optargs[OPT_ARG_INTROMSG], chan->language)) {
3076  ast_waitstream(chan, "");
3077  }
3078  }
3079 
3080  if (!ast_test_flag64(confflags, (CONFFLAG_QUIET | CONFFLAG_NOONLYPERSON))) {
3081  if (conf->users == 1 && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED))
3082  if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
3083  ast_waitstream(chan, "");
3084  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) && conf->markedusers == 0)
3085  if (!ast_streamfile(chan, "conf-waitforleader", chan->language))
3086  ast_waitstream(chan, "");
3087  }
3088 
3090  conf->users > 1) {
3091  int keepplaying = 1;
3092 
3093  if (conf->users == 2) {
3094  if (!ast_streamfile(chan, "conf-onlyone", chan->language)) {
3095  res = ast_waitstream(chan, AST_DIGIT_ANY);
3096  ast_stopstream(chan);
3097  if (res > 0)
3098  keepplaying = 0;
3099  else if (res == -1)
3100  goto outrun;
3101  }
3102  } else {
3103  if (!ast_streamfile(chan, "conf-thereare", chan->language)) {
3104  res = ast_waitstream(chan, AST_DIGIT_ANY);
3105  ast_stopstream(chan);
3106  if (res > 0)
3107  keepplaying = 0;
3108  else if (res == -1)
3109  goto outrun;
3110  }
3111  if (keepplaying) {
3112  res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
3113  if (res > 0)
3114  keepplaying = 0;
3115  else if (res == -1)
3116  goto outrun;
3117  }
3118  if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", chan->language)) {
3119  res = ast_waitstream(chan, AST_DIGIT_ANY);
3120  ast_stopstream(chan);
3121  if (res > 0)
3122  keepplaying = 0;
3123  else if (res == -1)
3124  goto outrun;
3125  }
3126  }
3127  }
3128 
3129  if (!ast_test_flag64(confflags, CONFFLAG_NO_AUDIO_UNTIL_UP)) {
3130  /* We're leaving this alone until the state gets changed to up */
3131  ast_indicate(chan, -1);
3132  }
3133 
3134  if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
3135  ast_log(LOG_WARNING, "Unable to set '%s' to write linear mode\n", chan->name);
3136  goto outrun;
3137  }
3138 
3139  if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
3140  ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", chan->name);
3141  goto outrun;
3142  }
3143 
3144  /* Reduce background noise from each participant */
3145  if (!ast_test_flag64(confflags, CONFFLAG_DONT_DENOISE) &&
3146  (mod_speex = ast_module_helper("", "func_speex", 0, 0, 0, 0))) {
3147  ast_free(mod_speex);
3148  ast_func_write(chan, "DENOISE(rx)", "on");
3149  }
3150 
3151  retrydahdi = (strcasecmp(chan->tech->type, "DAHDI") || (chan->audiohooks || chan->monitor) ? 1 : 0);
3152  user->dahdichannel = !retrydahdi;
3153 
3154  dahdiretry:
3155  origfd = chan->fds[0];
3156  if (retrydahdi) {
3157  /* open pseudo in non-blocking mode */
3158  fd = open("/dev/dahdi/pseudo", O_RDWR | O_NONBLOCK);
3159  if (fd < 0) {
3160  ast_log(LOG_WARNING, "Unable to open DAHDI pseudo channel: %s\n", strerror(errno));
3161  goto outrun;
3162  }
3163  using_pseudo = 1;
3164  /* Setup buffering information */
3165  memset(&bi, 0, sizeof(bi));
3166  bi.bufsize = CONF_SIZE / 2;
3167  bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
3168  bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
3169  bi.numbufs = audio_buffers;
3170  if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) {
3171  ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
3172  close(fd);
3173  goto outrun;
3174  }
3175  x = 1;
3176  if (ioctl(fd, DAHDI_SETLINEAR, &x)) {
3177  ast_log(LOG_WARNING, "Unable to set linear mode: %s\n", strerror(errno));
3178  close(fd);
3179  goto outrun;
3180  }
3181  nfds = 1;
3182  } else {
3183  /* XXX Make sure we're not running on a pseudo channel XXX */
3184  fd = chan->fds[0];
3185  nfds = 0;
3186  }
3187  memset(&dahdic, 0, sizeof(dahdic));
3188  memset(&dahdic_empty, 0, sizeof(dahdic_empty));
3189  /* Check to see if we're in a conference... */
3190  dahdic.chan = 0;
3191  if (ioctl(fd, DAHDI_GETCONF, &dahdic)) {
3192  ast_log(LOG_WARNING, "Error getting conference\n");
3193  close(fd);
3194  goto outrun;
3195  }
3196  if (dahdic.confmode) {
3197  /* Whoa, already in a conference... Retry... */
3198  if (!retrydahdi) {
3199  ast_debug(1, "DAHDI channel is in a conference already, retrying with pseudo\n");
3200  retrydahdi = 1;
3201  goto dahdiretry;
3202  }
3203  }
3204  memset(&dahdic, 0, sizeof(dahdic));
3205  /* Add us to the conference */
3206  dahdic.chan = 0;
3207  dahdic.confno = conf->dahdiconf;
3208 
3209  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && (ast_test_flag64(confflags, CONFFLAG_INTROUSER) ||
3210  ast_test_flag64(confflags, CONFFLAG_INTROUSERNOREVIEW)) && conf->users > 1) {
3211  struct announce_listitem *item;
3212  if (!(item = ao2_alloc(sizeof(*item), NULL)))
3213  goto outrun;
3214  ast_copy_string(item->namerecloc, user->namerecloc, sizeof(item->namerecloc));
3215  ast_copy_string(item->language, chan->language, sizeof(item->language));
3216  item->confchan = conf->chan;
3217  item->confusers = conf->users;
3218  item->announcetype = CONF_HASJOIN;
3220  ao2_ref(item, +1); /* add one more so we can determine when announce_thread is done playing it */
3221  AST_LIST_INSERT_TAIL(&conf->announcelist, item, entry);
3224 
3225  while (!ast_check_hangup(conf->chan) && ao2_ref(item, 0) == 2 && !ast_safe_sleep(chan, 1000)) {
3226  ;
3227  }
3228  ao2_ref(item, -1);
3229  }
3230 
3231  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED) && !conf->markedusers)
3232  dahdic.confmode = DAHDI_CONF_CONF;
3233  else if (ast_test_flag64(confflags, CONFFLAG_MONITOR))
3234  dahdic.confmode = DAHDI_CONF_CONFMON | DAHDI_CONF_LISTENER;
3235  else if (ast_test_flag64(confflags, CONFFLAG_TALKER))
3236  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
3237  else
3238  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
3239 
3240  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3241  ast_log(LOG_WARNING, "Error setting conference\n");
3242  close(fd);
3243  goto outrun;
3244  }
3245  ast_debug(1, "Placed channel %s in DAHDI conf %d\n", chan->name, conf->dahdiconf);
3246 
3247  if (!sent_event) {
3248  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeJoin",
3249  "Channel: %s\r\n"
3250  "Uniqueid: %s\r\n"
3251  "Meetme: %s\r\n"
3252  "Usernum: %d\r\n"
3253  "CallerIDnum: %s\r\n"
3254  "CallerIDname: %s\r\n"
3255  "ConnectedLineNum: %s\r\n"
3256  "ConnectedLineName: %s\r\n",
3257  chan->name, chan->uniqueid, conf->confno,
3258  user->user_no,
3259  S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
3260  S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<unknown>"),
3261  S_COR(user->chan->connected.id.number.valid, user->chan->connected.id.number.str, "<unknown>"),
3262  S_COR(user->chan->connected.id.name.valid, user->chan->connected.id.name.str, "<unknown>")
3263  );
3264  sent_event = 1;
3265  }
3266 
3267  if (!firstpass && !ast_test_flag64(confflags, CONFFLAG_MONITOR) &&
3268  !ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
3269  firstpass = 1;
3270  if (!ast_test_flag64(confflags, CONFFLAG_QUIET))
3271  if (!ast_test_flag64(confflags, CONFFLAG_WAITMARKED) || (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER) &&
3272  (conf->markedusers >= 1))) {
3273  conf_play(chan, conf, ENTER);
3274  }
3275  }
3276 
3277  conf_flush(fd, chan);
3278 
3279  if (dsp)
3280  ast_dsp_free(dsp);
3281 
3282  if (!(dsp = ast_dsp_new())) {
3283  ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
3284  res = -1;
3285  }
3286 
3287  if (ast_test_flag64(confflags, CONFFLAG_AGI)) {
3288  /* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND)
3289  or use default filename of conf-background.agi */
3290 
3291  ast_channel_lock(chan);
3292  if ((tmpvar = pbx_builtin_getvar_helper(chan, "MEETME_AGI_BACKGROUND"))) {
3293  agifile = ast_strdupa(tmpvar);
3294  } else {
3295  agifile = ast_strdupa(agifiledefault);
3296  }
3297  ast_channel_unlock(chan);
3298 
3299  if (user->dahdichannel) {
3300  /* Set CONFMUTE mode on DAHDI channel to mute DTMF tones */
3301  x = 1;
3302  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3303  }
3304  /* Find a pointer to the agi app and execute the script */
3305  agi_app = pbx_findapp("agi");
3306  if (agi_app) {
3307  ret = pbx_exec(chan, agi_app, agifile);
3308  } else {
3309  ast_log(LOG_WARNING, "Could not find application (agi)\n");
3310  ret = -2;
3311  }
3312  if (user->dahdichannel) {
3313  /* Remove CONFMUTE mode on DAHDI channel */
3314  x = 0;
3315  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3316  }
3317  } else {
3318  int lastusers = conf->users;
3319  if (user->dahdichannel && ast_test_flag64(confflags, CONFFLAG_STARMENU)) {
3320  /* Set CONFMUTE mode on DAHDI channel to mute DTMF tones when the menu is enabled */
3321  x = 1;
3322  ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
3323  }
3324 
3325  for (;;) {
3326  int menu_was_active = 0;
3327 
3328  outfd = -1;
3329  ms = -1;
3330  now = ast_tvnow();
3331 
3332  if (rt_schedule && conf->endtime) {
3333  char currenttime[32];
3334  long localendtime = 0;
3335  int extended = 0;
3336  struct ast_tm tm;
3337  struct ast_variable *var, *origvar;
3338  struct timeval tmp;
3339 
3340  if (now.tv_sec % 60 == 0) {
3341  if (!checked) {
3342  ast_localtime(&now, &tm, NULL);
3343  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
3344  var = origvar = ast_load_realtime("meetme", "confno",
3345  conf->confno, "starttime <=", currenttime,
3346  "endtime >=", currenttime, NULL);
3347 
3348  for ( ; var; var = var->next) {
3349  if (!strcasecmp(var->name, "endtime")) {
3350  struct ast_tm endtime_tm;
3351  ast_strptime(var->value, "%Y-%m-%d %H:%M:%S", &endtime_tm);
3352  tmp = ast_mktime(&endtime_tm, NULL);
3353  localendtime = tmp.tv_sec;
3354  }
3355  }
3356  ast_variables_destroy(origvar);
3357 
3358  /* A conference can be extended from the
3359  Admin/User menu or by an external source */
3360  if (localendtime > conf->endtime){
3361  conf->endtime = localendtime;
3362  extended = 1;
3363  }
3364 
3365  if (conf->endtime && (now.tv_sec >= conf->endtime)) {
3366  ast_verbose("Quitting time...\n");
3367  goto outrun;
3368  }
3369 
3370  if (!announcement_played && conf->endalert) {
3371  if (now.tv_sec + conf->endalert >= conf->endtime) {
3372  if (!ast_streamfile(chan, "conf-will-end-in", chan->language))
3373  ast_waitstream(chan, "");
3374  ast_say_digits(chan, (conf->endtime - now.tv_sec) / 60, "", chan->language);
3375  if (!ast_streamfile(chan, "minutes", chan->language))
3376  ast_waitstream(chan, "");
3377  if (musiconhold) {
3378  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3379  }
3380  announcement_played = 1;
3381  }
3382  }
3383 
3384  if (extended) {
3385  announcement_played = 0;
3386  }
3387 
3388  checked = 1;
3389  }
3390  } else {
3391  checked = 0;
3392  }
3393  }
3394 
3395  if (user->kicktime && (user->kicktime <= now.tv_sec)) {
3396  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3397  ret = 0;
3398  } else {
3399  ret = -1;
3400  }
3401  break;
3402  }
3403 
3404  to = -1;
3405  if (user->timelimit) {
3406  int minutes = 0, seconds = 0, remain = 0;
3407 
3408  to = ast_tvdiff_ms(nexteventts, now);
3409  if (to < 0) {
3410  to = 0;
3411  }
3412  time_left_ms = user->timelimit - ast_tvdiff_ms(now, user->start_time);
3413  if (time_left_ms < to) {
3414  to = time_left_ms;
3415  }
3416 
3417  if (time_left_ms <= 0) {
3418  if (user->end_sound) {
3419  res = ast_streamfile(chan, user->end_sound, chan->language);
3420  res = ast_waitstream(chan, "");
3421  }
3422  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3423  ret = 0;
3424  } else {
3425  ret = -1;
3426  }
3427  break;
3428  }
3429 
3430  if (!to) {
3431  if (time_left_ms >= 5000) {
3432 
3433  remain = (time_left_ms + 500) / 1000;
3434  if (remain / 60 >= 1) {
3435  minutes = remain / 60;
3436  seconds = remain % 60;
3437  } else {
3438  seconds = remain;
3439  }
3440 
3441  /* force the time left to round up if appropriate */
3442  if (user->warning_sound && user->play_warning) {
3443  if (!strcmp(user->warning_sound, "timeleft")) {
3444 
3445  res = ast_streamfile(chan, "vm-youhave", chan->language);
3446  res = ast_waitstream(chan, "");
3447  if (minutes) {
3448  res = ast_say_number(chan, minutes, AST_DIGIT_ANY, chan->language, (char *) NULL);
3449  res = ast_streamfile(chan, "queue-minutes", chan->language);
3450  res = ast_waitstream(chan, "");
3451  }
3452  if (seconds) {
3453  res = ast_say_number(chan, seconds, AST_DIGIT_ANY, chan->language, (char *) NULL);
3454  res = ast_streamfile(chan, "queue-seconds", chan->language);
3455  res = ast_waitstream(chan, "");
3456  }
3457  } else {
3458  res = ast_streamfile(chan, user->warning_sound, chan->language);
3459  res = ast_waitstream(chan, "");
3460  }
3461  if (musiconhold) {
3462  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3463  }
3464  }
3465  }
3466  if (user->warning_freq) {
3467  nexteventts = ast_tvadd(nexteventts, ast_samp2tv(user->warning_freq, 1000));
3468  } else {
3469  nexteventts = ast_tvadd(user->start_time, ast_samp2tv(user->timelimit, 1000));
3470  }
3471  }
3472  }
3473 
3474  now = ast_tvnow();
3475  if (timeout && now.tv_sec >= timeout) {
3476  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3477  ret = 0;
3478  } else {
3479  ret = -1;
3480  }
3481  break;
3482  }
3483 
3484  /* if we have just exited from the menu, and the user had a channel-driver
3485  volume adjustment, restore it
3486  */
3487  if (!menu_mode && menu_was_active && user->listen.desired && !user->listen.actual) {
3488  set_talk_volume(user, user->listen.desired);
3489  }
3490 
3491  menu_was_active = menu_mode;
3492 
3493  currentmarked = conf->markedusers;
3494  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
3495  ast_test_flag64(confflags, CONFFLAG_MARKEDUSER) &&
3496  ast_test_flag64(confflags, CONFFLAG_WAITMARKED) &&
3497  lastmarked == 0) {
3498  if (currentmarked == 1 && conf->users > 1) {
3499  ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
3500  if (conf->users - 1 == 1) {
3501  if (!ast_streamfile(chan, "conf-userwilljoin", chan->language)) {
3502  ast_waitstream(chan, "");
3503  }
3504  } else {
3505  if (!ast_streamfile(chan, "conf-userswilljoin", chan->language)) {
3506  ast_waitstream(chan, "");
3507  }
3508  }
3509  }
3510  if (conf->users == 1 && !ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
3511  if (!ast_streamfile(chan, "conf-onlyperson", chan->language)) {
3512  ast_waitstream(chan, "");
3513  }
3514  }
3515  }
3516 
3517  /* Update the struct with the actual confflags */
3518  user->userflags = *confflags;
3519 
3520  if (ast_test_flag64(confflags, CONFFLAG_WAITMARKED)) {
3521  if (currentmarked == 0) {
3522  if (lastmarked != 0) {
3523  if (!ast_test_flag64(confflags, CONFFLAG_QUIET)) {
3524  if (!ast_streamfile(chan, "conf-leaderhasleft", chan->language)) {
3525  ast_waitstream(chan, "");
3526  }
3527  }
3528  if (ast_test_flag64(confflags, CONFFLAG_MARKEDEXIT)) {
3529  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3530  ret = 0;
3531  }
3532  break;
3533  } else {
3534  dahdic.confmode = DAHDI_CONF_CONF;
3535  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3536  ast_log(LOG_WARNING, "Error setting conference\n");
3537  close(fd);
3538  goto outrun;
3539  }
3540  }
3541  }
3542  if (!musiconhold && (ast_test_flag64(confflags, CONFFLAG_MOH))) {
3543  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3544  musiconhold = 1;
3545  }
3546  } else if (currentmarked >= 1 && lastmarked == 0) {
3547  /* Marked user entered, so cancel timeout */
3548  timeout = 0;
3549  if (ast_test_flag64(confflags, CONFFLAG_MONITOR)) {
3550  dahdic.confmode = DAHDI_CONF_CONFMON | DAHDI_CONF_LISTENER;
3551  } else if (ast_test_flag64(confflags, CONFFLAG_TALKER)) {
3552  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER;
3553  } else {
3554  dahdic.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
3555  }
3556  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3557  ast_log(LOG_WARNING, "Error setting conference\n");
3558  close(fd);
3559  goto outrun;
3560  }
3561  if (musiconhold && (ast_test_flag64(confflags, CONFFLAG_MOH))) {
3562  ast_moh_stop(chan);
3563  musiconhold = 0;
3564  }
3565  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
3566  !ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
3567  if (!ast_streamfile(chan, "conf-placeintoconf", chan->language)) {
3568  ast_waitstream(chan, "");
3569  }
3570  conf_play(chan, conf, ENTER);
3571  }
3572  }
3573  }
3574 
3575  /* trying to add moh for single person conf */
3576  if (ast_test_flag64(confflags, CONFFLAG_MOH) && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)) {
3577  if (conf->users == 1) {
3578  if (!musiconhold) {
3579  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3580  musiconhold = 1;
3581  }
3582  } else {
3583  if (musiconhold) {
3584  ast_moh_stop(chan);
3585  musiconhold = 0;
3586  }
3587  }
3588  }
3589 
3590  /* Leave if the last marked user left */
3591  if (currentmarked == 0 && lastmarked != 0 && ast_test_flag64(confflags, CONFFLAG_MARKEDEXIT)) {
3592  if (ast_test_flag64(confflags, CONFFLAG_KICK_CONTINUE)) {
3593  ret = 0;
3594  } else {
3595  ret = -1;
3596  }
3597  break;
3598  }
3599 
3600  /* Throw a TestEvent if a user exit did not cause this user to leave the conference */
3601  if (conf->users != lastusers) {
3602  if (conf->users < lastusers) {
3603  ast_test_suite_event_notify("NOEXIT", "Message: CONFFLAG_MARKEDEXIT\r\nLastUsers: %d\r\nUsers: %d", lastusers, conf->users);
3604  }
3605  lastusers = conf->users;
3606  }
3607 
3608  /* Check if my modes have changed */
3609 
3610  /* If I should be muted but am still talker, mute me */
3611  if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && (dahdic.confmode & DAHDI_CONF_TALKER)) {
3612  dahdic.confmode ^= DAHDI_CONF_TALKER;
3613  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3614  ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
3615  ret = -1;
3616  break;
3617  }
3618 
3619  /* Indicate user is not talking anymore - change him to unmonitored state */
3621  set_user_talking(chan, conf, user, -1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
3622  }
3623 
3624  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
3625  "Channel: %s\r\n"
3626  "Uniqueid: %s\r\n"
3627  "Meetme: %s\r\n"
3628  "Usernum: %d\r\n"
3629  "Status: on\r\n",
3630  chan->name, chan->uniqueid, conf->confno, user->user_no);
3631  }
3632 
3633  /* If I should be un-muted but am not talker, un-mute me */
3634  if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) && !(dahdic.confmode & DAHDI_CONF_TALKER)) {
3635  dahdic.confmode |= DAHDI_CONF_TALKER;
3636  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3637  ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
3638  ret = -1;
3639  break;
3640  }
3641 
3642  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
3643  "Channel: %s\r\n"
3644  "Uniqueid: %s\r\n"
3645  "Meetme: %s\r\n"
3646  "Usernum: %d\r\n"
3647  "Status: off\r\n",
3648  chan->name, chan->uniqueid, conf->confno, user->user_no);
3649  }
3650 
3651  if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
3652  (user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) {
3653  talkreq_manager = 1;
3654 
3655  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
3656  "Channel: %s\r\n"
3657  "Uniqueid: %s\r\n"
3658  "Meetme: %s\r\n"
3659  "Usernum: %d\r\n"
3660  "Status: on\r\n",
3661  chan->name, chan->uniqueid, conf->confno, user->user_no);
3662  }
3663 
3664 
3665  if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
3666  !(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) {
3667  talkreq_manager = 0;
3668  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
3669  "Channel: %s\r\n"
3670  "Uniqueid: %s\r\n"
3671  "Meetme: %s\r\n"
3672  "Usernum: %d\r\n"
3673  "Status: off\r\n",
3674  chan->name, chan->uniqueid, conf->confno, user->user_no);
3675  }
3676 
3677  /* If I have been kicked, exit the conference */
3678  if (user->adminflags & ADMINFLAG_KICKME) {
3679  /* You have been kicked. */
3680  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) &&
3681  !ast_streamfile(chan, "conf-kicked", chan->language)) {
3682  ast_waitstream(chan, "");
3683  }
3684  ret = 0;
3685  break;
3686  }
3687 
3688  /* Perform a hangup check here since ast_waitfor_nandfds will not always be able to get a channel after a hangup has occurred */
3689  if (ast_check_hangup(chan)) {
3690  break;
3691  }
3692 
3693  c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
3694 
3695  if (c) {
3696  char dtmfstr[2] = "";
3697 
3698  if (c->fds[0] != origfd || (user->dahdichannel && (c->audiohooks || c->monitor))) {
3699  if (using_pseudo) {
3700  /* Kill old pseudo */
3701  close(fd);
3702  using_pseudo = 0;
3703  }
3704  ast_debug(1, "Ooh, something swapped out under us, starting over\n");
3705  retrydahdi = (strcasecmp(c->tech->type, "DAHDI") || (c->audiohooks || c->monitor) ? 1 : 0);
3706  user->dahdichannel = !retrydahdi;
3707  goto dahdiretry;
3708  }
3710  f = ast_read_noaudio(c);
3711  } else {
3712  f = ast_read(c);
3713  }
3714  if (!f) {
3715  break;
3716  }
3717  if (f->frametype == AST_FRAME_DTMF) {
3718  dtmfstr[0] = f->subclass.integer;
3719  dtmfstr[1] = '\0';
3720  }
3721 
3722  if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
3723  if (user->talk.actual) {
3725  }
3726 
3728  if (user->talking == -1) {
3729  user->talking = 0;
3730  }
3731 
3732  res = ast_dsp_silence(dsp, f, &totalsilence);
3733  if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) {
3734  set_user_talking(chan, conf, user, 1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
3735  }
3736 
3737  if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) {
3738  set_user_talking(chan, conf, user, 0, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
3739  }
3740  }
3741  if (using_pseudo) {
3742  /* Absolutely do _not_ use careful_write here...
3743  it is important that we read data from the channel
3744  as fast as it arrives, and feed it into the conference.
3745  The buffering in the pseudo channel will take care of any
3746  timing differences, unless they are so drastic as to lose
3747  audio frames (in which case carefully writing would only
3748  have delayed the audio even further).
3749  */
3750  /* As it turns out, we do want to use careful write. We just
3751  don't want to block, but we do want to at least *try*
3752  to write out all the samples.
3753  */
3754  if (user->talking || !ast_test_flag64(confflags, CONFFLAG_OPTIMIZETALKER)) {
3755  careful_write(fd, f->data.ptr, f->datalen, 0);
3756  }
3757  }
3758  } else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass.integer == '*') && ast_test_flag64(confflags, CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_mode)) {
3759  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
3760  conf_queue_dtmf(conf, user, f);
3761  }
3762  /* Take out of conference */
3763  if (ioctl(fd, DAHDI_SETCONF, &dahdic_empty)) {
3764  ast_log(LOG_WARNING, "Error setting conference\n");
3765  close(fd);
3766  ast_frfree(f);
3767  goto outrun;
3768  }
3769 
3770  /* if we are entering the menu, and the user has a channel-driver
3771  volume adjustment, clear it
3772  */
3773  if (!menu_mode && user->talk.desired && !user->talk.actual) {
3774  set_talk_volume(user, 0);
3775  }
3776 
3777  if (musiconhold) {
3778  ast_moh_stop(chan);
3779  } else if (!menu_mode) {
3780  char *menu_to_play;
3781  if (ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
3782  menu_mode = MENU_ADMIN;
3783  menu_to_play = "conf-adminmenu-18";
3784  } else {
3785  menu_mode = MENU_NORMAL;
3786  menu_to_play = "conf-usermenu-162";
3787  }
3788 
3789  if (!ast_streamfile(chan, menu_to_play, chan->language)) {
3790  dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
3791  ast_stopstream(chan);
3792  } else {
3793  dtmf = 0;
3794  }
3795  } else {
3796  dtmf = f->subclass.integer;
3797  }
3798 
3799  if (dtmf > 0) {
3800  meetme_menu(&menu_mode, &dtmf, conf, confflags,
3801  chan, user, recordingtmp, sizeof(recordingtmp));
3802  }
3803 
3804  if (musiconhold && !menu_mode) {
3805  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3806  }
3807 
3808  /* Put back into conference */
3809  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3810  ast_log(LOG_WARNING, "Error setting conference\n");
3811  close(fd);
3812  ast_frfree(f);
3813  goto outrun;
3814  }
3815 
3816  conf_flush(fd, chan);
3817  /*
3818  * Since options using DTMF could absorb DTMF meant for the
3819  * conference menu, we have to check them after the menu.
3820  */
3821  } else if ((f->frametype == AST_FRAME_DTMF) && ast_test_flag64(confflags, CONFFLAG_EXIT_CONTEXT) && ast_exists_extension(chan, exitcontext, dtmfstr, 1, "")) {
3822  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
3823  conf_queue_dtmf(conf, user, f);
3824  }
3825 
3826  if (!ast_goto_if_exists(chan, exitcontext, dtmfstr, 1)) {
3827  ast_debug(1, "Got DTMF %c, goto context %s\n", dtmfstr[0], exitcontext);
3828  ret = 0;
3829  ast_frfree(f);
3830  break;
3831  } else {
3832  ast_debug(2, "Exit by single digit did not work in meetme. Extension %s does not exist in context %s\n", dtmfstr, exitcontext);
3833  }
3834  } else if ((f->frametype == AST_FRAME_DTMF) && ast_test_flag64(confflags, CONFFLAG_KEYEXIT) &&
3835  (strchr(exitkeys, f->subclass.integer))) {
3836  pbx_builtin_setvar_helper(chan, "MEETME_EXIT_KEY", dtmfstr);
3837 
3838  if (ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
3839  conf_queue_dtmf(conf, user, f);
3840  }
3841  ret = 0;
3842  ast_frfree(f);
3843  break;
3844  } else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
3845  && ast_test_flag64(confflags, CONFFLAG_PASS_DTMF)) {
3846  conf_queue_dtmf(conf, user, f);
3847  } else if (ast_test_flag64(confflags, CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
3848  switch (f->subclass.integer) {
3849  case AST_CONTROL_HOLD:
3850  sla_queue_event_conf(SLA_EVENT_HOLD, chan, conf);
3851  break;
3852  default:
3853  break;
3854  }
3855  } else if (f->frametype == AST_FRAME_NULL) {
3856  /* Ignore NULL frames. It is perfectly normal to get these if the person is muted. */
3857  } else if (f->frametype == AST_FRAME_CONTROL) {
3858  switch (f->subclass.integer) {
3859  case AST_CONTROL_BUSY:
3861  ast_frfree(f);
3862  goto outrun;
3863  break;
3864  default:
3865  ast_debug(1,
3866  "Got ignored control frame on channel %s, f->frametype=%u,f->subclass=%d\n",
3867  chan->name, f->frametype, f->subclass.integer);
3868  }
3869  } else {
3870  ast_debug(1,
3871  "Got unrecognized frame on channel %s, f->frametype=%u,f->subclass=%d\n",
3872  chan->name, f->frametype, f->subclass.integer);
3873  }
3874  ast_frfree(f);
3875  } else if (outfd > -1) {
3876  res = read(outfd, buf, CONF_SIZE);
3877  if (res > 0) {
3878  memset(&fr, 0, sizeof(fr));
3879  fr.frametype = AST_FRAME_VOICE;
3880  fr.subclass.codec = AST_FORMAT_SLINEAR;
3881  fr.datalen = res;
3882  fr.samples = res / 2;
3883  fr.data.ptr = buf;
3884  fr.offset = AST_FRIENDLY_OFFSET;
3885  if (!user->listen.actual &&
3886  (ast_test_flag64(confflags, CONFFLAG_MONITOR) ||
3888  (!user->talking && ast_test_flag64(confflags, CONFFLAG_OPTIMIZETALKER))
3889  )) {
3890  int idx;
3891  for (idx = 0; idx < AST_FRAME_BITS; idx++) {
3892  if (chan->rawwriteformat & (1 << idx)) {
3893  break;
3894  }
3895  }
3896  if (idx >= AST_FRAME_BITS) {
3897  goto bailoutandtrynormal;
3898  }
3899  ast_mutex_lock(&conf->listenlock);
3900  if (!conf->transframe[idx]) {
3901  if (conf->origframe) {
3902  if (musiconhold
3903  && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)
3904  && !ast_dsp_silence(dsp, conf->origframe, &confsilence)
3905  && confsilence < MEETME_DELAYDETECTTALK) {
3906  ast_moh_stop(chan);
3907  mohtempstopped = 1;
3908  }
3909  if (!conf->transpath[idx]) {
3910  conf->transpath[idx] = ast_translator_build_path((1 << idx), AST_FORMAT_SLINEAR);
3911  }
3912  if (conf->transpath[idx]) {
3913  conf->transframe[idx] = ast_translate(conf->transpath[idx], conf->origframe, 0);
3914  if (!conf->transframe[idx]) {
3915  conf->transframe[idx] = &ast_null_frame;
3916  }
3917  }
3918  }
3919  }
3920  if (conf->transframe[idx]) {
3921  if ((conf->transframe[idx]->frametype != AST_FRAME_NULL) &&
3922  can_write(chan, confflags)) {
3923  struct ast_frame *cur;
3924  /* the translator may have returned a list of frames, so
3925  write each one onto the channel
3926  */
3927  for (cur = conf->transframe[idx]; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
3928  if (ast_write(chan, cur)) {
3929  ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
3930  break;
3931  }
3932  }
3933  if (musiconhold && mohtempstopped && confsilence > MEETME_DELAYDETECTENDTALK) {
3934  mohtempstopped = 0;
3935  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3936  }
3937  }
3938  } else {
3939  ast_mutex_unlock(&conf->listenlock);
3940  goto bailoutandtrynormal;
3941  }
3942  ast_mutex_unlock(&conf->listenlock);
3943  } else {
3944 bailoutandtrynormal:
3945  if (musiconhold
3946  && !ast_test_flag64(confflags, CONFFLAG_WAITMARKED)
3947  && !ast_dsp_silence(dsp, &fr, &confsilence)
3948  && confsilence < MEETME_DELAYDETECTTALK) {
3949  ast_moh_stop(chan);
3950  mohtempstopped = 1;
3951  }
3952  if (user->listen.actual) {
3954  }
3955  if (can_write(chan, confflags) && ast_write(chan, &fr) < 0) {
3956  ast_log(LOG_WARNING, "Unable to write frame to channel %s\n", chan->name);
3957  }
3958  if (musiconhold && mohtempstopped && confsilence > MEETME_DELAYDETECTENDTALK) {
3959  mohtempstopped = 0;
3960  conf_start_moh(chan, optargs[OPT_ARG_MOH_CLASS]);
3961  }
3962  }
3963  } else {
3964  ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
3965  }
3966  }
3967  lastmarked = currentmarked;
3968  }
3969  }
3970 
3971  if (musiconhold) {
3972  ast_moh_stop(chan);
3973  }
3974 
3975  if (using_pseudo) {
3976  close(fd);
3977  } else {
3978  /* Take out of conference */
3979  dahdic.chan = 0;
3980  dahdic.confno = 0;
3981  dahdic.confmode = 0;
3982  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
3983  ast_log(LOG_WARNING, "Error setting conference\n");
3984  }
3985  }
3986 
3987  reset_volumes(user);
3988 
3989  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) &&
3990  !ast_test_flag64(confflags, CONFFLAG_ADMIN)) {
3991  conf_play(chan, conf, LEAVE);
3992  }
3993 
3994  if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && (ast_test_flag64(confflags, CONFFLAG_INTROUSER) || ast_test_flag64(confflags, CONFFLAG_INTROUSERNOREVIEW)) && conf->users > 1) {
3995  struct announce_listitem *item;
3996  if (!(item = ao2_alloc(sizeof(*item), NULL)))
3997  goto outrun;
3998  ast_copy_string(item->namerecloc, user->namerecloc, sizeof(item->namerecloc));
3999  ast_copy_string(item->language, chan->language, sizeof(item->language));
4000  item->confchan = conf->chan;
4001  item->confusers = conf->users;
4002  item->announcetype = CONF_HASLEFT;
4004  AST_LIST_INSERT_TAIL(&conf->announcelist, item, entry);
4007  } else if (!ast_test_flag64(confflags, CONFFLAG_QUIET) && (ast_test_flag64(confflags, CONFFLAG_INTROUSER) ||
4008  ast_test_flag64(confflags, CONFFLAG_INTROUSERNOREVIEW)) && conf->users == 1) {
4009  /* Last person is leaving, so no reason to try and announce, but should delete the name recording */
4010  ast_filedelete(user->namerecloc, NULL);
4011  }
4012 
4013  outrun:
4014  AST_LIST_LOCK(&confs);
4015 
4016  if (dsp) {
4017  ast_dsp_free(dsp);
4018  }
4019 
4020  if (user->user_no) {
4021  /* Only cleanup users who really joined! */
4022  now = ast_tvnow();
4023 
4024  if (sent_event) {
4025  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeLeave",
4026  "Channel: %s\r\n"
4027  "Uniqueid: %s\r\n"
4028  "Meetme: %s\r\n"
4029  "Usernum: %d\r\n"
4030  "CallerIDNum: %s\r\n"
4031  "CallerIDName: %s\r\n"
4032  "ConnectedLineNum: %s\r\n"
4033  "ConnectedLineName: %s\r\n"
4034  "Duration: %ld\r\n",
4035  chan->name, chan->uniqueid, conf->confno,
4036  user->user_no,
4037  S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
4038  S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<unknown>"),
4039  S_COR(user->chan->connected.id.number.valid, user->chan->connected.id.number.str, "<unknown>"),
4040  S_COR(user->chan->connected.id.name.valid, user->chan->connected.id.name.str, "<unknown>"),
4041  (long)(now.tv_sec - user->jointime));
4042  }
4043 
4044  if (setusercount) {
4045  conf->users--;
4046  if (rt_log_members) {
4047  /* Update table */
4048  snprintf(members, sizeof(members), "%d", conf->users);
4049  ast_realtime_require_field("meetme",
4050  "confno", strlen(conf->confno) > 7 ? RQ_UINTEGER4 : strlen(conf->confno) > 4 ? RQ_UINTEGER3 : RQ_UINTEGER2, strlen(conf->confno),
4051  "members", RQ_UINTEGER1, strlen(members),
4052  NULL);
4053  ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
4054  }
4055  if (ast_test_flag64(confflags, CONFFLAG_MARKEDUSER)) {
4056  conf->markedusers--;
4057  }
4058  }
4059  /* Remove ourselves from the container */
4060  ao2_unlink(conf->usercontainer, user);
4061 
4062  /* Change any states */
4063  if (!conf->users) {
4065  }
4066 
4067  /* Return the number of seconds the user was in the conf */
4068  snprintf(meetmesecs, sizeof(meetmesecs), "%d", (int) (time(NULL) - user->jointime));
4069  pbx_builtin_setvar_helper(chan, "MEETMESECS", meetmesecs);
4070 
4071  /* Return the RealTime bookid for CDR linking */
4072  if (rt_schedule) {
4073  pbx_builtin_setvar_helper(chan, "MEETMEBOOKID", conf->bookid);
4074  }
4075  }
4076  ao2_ref(user, -1);
4078 
4079  return ret;
4080 }
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: app.c:1183
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
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:2281
const char * warning_sound
Definition: app_meetme.c:784
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const char *const type
Definition: channel.h:508
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
struct timeval start_time
Definition: app_meetme.c:780
struct ast_channel * chan
Definition: app_meetme.c:719
struct ast_frame ast_null_frame
Definition: frame.c:131
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
static struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:17581
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
static int careful_write(int fd, unsigned char *data, int len, int block)
Definition: app_meetme.c:1016
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_strdup(a)
Definition: astmm.h:109
ast_mutex_t playlock
Definition: app_meetme.c:716
#define AST_FRAME_BITS
Definition: app_meetme.c:545
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define AST_DIGIT_ANY
Definition: file.h:47
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_frame * origframe
Definition: app_meetme.c:746
pthread_t recordthread
Definition: app_meetme.c:733
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
struct announce_listitem::@31 entry
void * ptr
Definition: frame.h:160
static void * recordthread(void *args)
Definition: app_meetme.c:5205
struct ast_channel * confchan
Definition: app_meetme.c:709
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define MEETME_DELAYDETECTENDTALK
Definition: app_meetme.c:543
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:729
#define CONF_SIZE
Definition: app_meetme.c:564
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
char * recordingformat
Definition: app_meetme.c:737
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
#define AST_FRAME_DTMF
Definition: frame.h:128
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:1570
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define CONFFLAG_DONT_DENOISE
Definition: app_meetme.c:630
struct ast_frame * transframe[32]
Definition: app_meetme.c:745
#define var
Definition: ast_expr2f.c:606
struct ast_conference::@33 announcelist
format_t rawwriteformat
Definition: channel.h:856
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
#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:4383
#define EVENT_FLAG_CALL
Definition: manager.h:72
ast_mutex_t listenlock
Definition: app_meetme.c:717
char * str
Subscriber name (Malloced)
Definition: channel.h:214
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8409
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define AST_OPTION_TONE_VERIFY
Definition: frame.h:441
long warning_freq
Definition: app_meetme.c:783
#define ast_mutex_lock(a)
Definition: lock.h:155
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:328
#define ao2_unlock(a)
Definition: astobj2.h:497
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
format_t codec
Definition: frame.h:137
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
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:7795
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
#define ast_cond_signal(cond)
Definition: lock.h:169
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:3188
static void conf_play(struct ast_channel *chan, struct ast_conference *conf, enum entrance_sound sound)
Definition: app_meetme.c:1134
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
#define ast_verb(level,...)
Definition: logger.h:243
unsigned int locked
Definition: app_meetme.c:731
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1187
unsigned int gmuted
Definition: app_meetme.c:732
#define CONFFLAG_INTROMSG
Definition: app_meetme.c:628
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
static int rt_schedule
Definition: app_meetme.c:684
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
struct ast_trans_pvt * ast_translator_build_path(format_t dest, format_t source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:282
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of &quot;format&quot; is ...
Definition: channel.c:5307
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: config.c:2679
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
static char exitcontext[AST_MAX_CONTEXT]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
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:516
int actual
Definition: app_meetme.c:765
const char * end_sound
Definition: app_meetme.c:785
static int can_write(struct ast_channel *chan, struct ast_flags64 *confflags)
Definition: app_meetme.c:2261
const char * bookid
Definition: app_meetme.c:744
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
Definition: dsp.c:390
#define AST_PTHREADT_NULL
Definition: lock.h:65
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
Match modules names for the Asterisk cli.
Definition: loader.c:626
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
#define AST_MAX_EXTENSION
Definition: channel.h:135
int datalen
Definition: frame.h:148
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#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:83
#define ao2_lock(a)
Definition: astobj2.h:488
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:191
static void conf_start_moh(struct ast_channel *chan, const char *musicclass)
Definition: app_meetme.c:2178
const char * name
Definition: config.h:77
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:5400
ast_mutex_t announcelistlock
Definition: app_meetme.c:756
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1126
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:2377
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
static void conf_flush(int fd, struct ast_channel *chan)
Definition: app_meetme.c:1894
static void * announce_thread(void *data)
Definition: app_meetme.c:2208
static int set_talk_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1043
struct volume listen
Definition: app_meetme.c:787
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int fds[AST_MAX_FDS]
Definition: channel.h:829
char uniqueid[32]
Definition: app_meetme.c:740
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
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)
Definition: app_meetme.c:2736
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
struct ast_flags64 userflags
Definition: app_meetme.c:771
#define DATE_FORMAT
Definition: app_meetme.c:532
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
const ast_string_field name
Definition: channel.h:787
time_t kicktime
Definition: app_meetme.c:779
char namerecloc[PATH_MAX]
Definition: app_meetme.c:707
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
pthread_t announcethread
Definition: app_meetme.c:751
int desired
Definition: app_meetme.c:764
static int rt_log_members
Definition: app_meetme.c:691
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
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:2055
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define AST_MAX_CONTEXT
Definition: channel.h:136
char namerecloc[PATH_MAX]
Definition: app_meetme.c:777
#define ast_free(a)
Definition: astmm.h:97
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
char language[MAX_LANGUAGE]
Definition: app_meetme.c:708
struct volume talk
Definition: app_meetme.c:786
static void conf_queue_dtmf(const struct ast_conference *conf, const struct ast_conf_user *sender, struct ast_frame *f)
Definition: app_meetme.c:1993
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:626
static struct ast_format f[]
Definition: format_g726.c:181
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:4916
const char * ast_config_AST_SPOOL_DIR
Definition: asterisk.c:259
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:2351
struct ao2_container * usercontainer
Definition: app_meetme.c:748
time_t jointime
Definition: app_meetme.c:778
structure to hold users read from users.conf
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: config.c:2606
#define MEETME_DELAYDETECTTALK
Definition: app_meetme.c:542
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: pbx.c:10546
menu_modes
Definition: app_meetme.c:2332
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Return non-zero if this is silence. Updates &quot;totalsilence&quot; with the total number of seconds of silenc...
Definition: dsp.c:1355
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2185
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:8397
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
ast_app: A registered application
Definition: pbx.c:971
static int audio_buffers
The number of audio buffers to be allocated on pseudo channels when in a conference.
Definition: app_meetme.c:979
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
struct ast_trans_pvt * transpath[32]
Definition: app_meetme.c:747
ast_cond_t announcelist_addition
Definition: app_meetme.c:754
int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
Adjusts the volume of the audio samples contained in a frame.
Definition: frame.c:1584
long play_warning
Definition: app_meetme.c:782
Data structure associated with a single frame of data.
Definition: frame.h:142
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
char * recordingfilename
Definition: app_meetme.c:736
struct ast_channel * lchan
Definition: app_meetme.c:720
enum ast_frame_type frametype
Definition: frame.h:144
enum announcetypes announcetype
Definition: app_meetme.c:711
struct ast_variable * next
Definition: config.h:82
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_frfree(fr)
Definition: frame.h:583
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct ast_channel_monitor * monitor
Definition: channel.h:769
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: app.c:1684
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1880
struct ast_channel * ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status)
Requests a channel.
Definition: channel.c:5695
union ast_frame::@172 data
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
Definition: pbx.c:4263
struct ast_channel_tech * tech
Definition: channel.h:743
struct ast_frame * ast_read_noaudio(struct ast_channel *chan)
Reads a frame, returning AST_FRAME_NULL frame if audio.
Definition: channel.c:4388
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
struct ast_channel * chan
Definition: app_meetme.c:773
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
#define ast_mutex_unlock(a)
Definition: lock.h:156
ast_mutex_t recordthreadlock
Definition: app_meetme.c:734
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
ast_mutex_t announcethreadlock
Definition: app_meetme.c:752
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static void conf_start_moh ( struct ast_channel chan,
const char *  musicclass 
)
static

Definition at line 2178 of file app_meetme.c.

References ast_channel_lock, ast_channel_unlock, ast_moh_start(), ast_strdupa, ast_string_field_set, and ast_channel::musicclass.

Referenced by conf_run().

2179 {
2180  char *original_moh;
2181 
2182  ast_channel_lock(chan);
2183  original_moh = ast_strdupa(chan->musicclass);
2185  ast_channel_unlock(chan);
2186 
2187  ast_moh_start(chan, original_moh, NULL);
2188 
2189  ast_channel_lock(chan);
2190  ast_string_field_set(chan, musicclass, original_moh);
2191  ast_channel_unlock(chan);
2192 }
static char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:155
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
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:8040
#define ast_channel_unlock(chan)
Definition: channel.h:2467
const ast_string_field musicclass
Definition: channel.h:787
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int count_exec ( struct ast_channel chan,
const char *  data 
)
static

The MeetmeCount application.

Definition at line 4374 of file app_meetme.c.

References ast_channel::_state, args, ast_answer(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_say_number(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), dispose_conf(), find_conf(), ast_channel::language, LOG_WARNING, pbx_builtin_setvar_helper(), and ast_conference::users.

Referenced by load_module().

4375 {
4376  int res = 0;
4377  struct ast_conference *conf;
4378  int count;
4379  char *localdata;
4380  char val[80] = "0";
4383  AST_APP_ARG(varname);
4384  );
4385 
4386  if (ast_strlen_zero(data)) {
4387  ast_log(LOG_WARNING, "MeetMeCount requires an argument (conference number)\n");
4388  return -1;
4389  }
4390 
4391  localdata = ast_strdupa(data);
4392 
4393  AST_STANDARD_APP_ARGS(args, localdata);
4394 
4395  conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 1, NULL);
4396 
4397  if (conf) {
4398  count = conf->users;
4399  dispose_conf(conf);
4400  conf = NULL;
4401  } else
4402  count = 0;
4403 
4404  if (!ast_strlen_zero(args.varname)) {
4405  /* have var so load it and exit */
4406  snprintf(val, sizeof(val), "%d", count);
4407  pbx_builtin_setvar_helper(chan, args.varname, val);
4408  } else {
4409  if (chan->_state != AST_STATE_UP) {
4410  ast_answer(chan);
4411  }
4412  res = ast_say_number(chan, count, "", chan->language, (char *) NULL); /* Needs gender */
4413  }
4414 
4415  return res;
4416 }
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
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:4270
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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: pbx.c:10546
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:8397
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
The MeetMe Conference object.
Definition: app_meetme.c:715
const ast_string_field language
Definition: channel.h:787
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static struct sla_trunk_ref* create_trunk_ref ( struct sla_trunk trunk)
static

Definition at line 6691 of file app_meetme.c.

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

Referenced by sla_add_trunk_to_station().

6692 {
6693  struct sla_trunk_ref *trunk_ref;
6694 
6695  if (!(trunk_ref = ao2_alloc(sizeof(*trunk_ref), sla_trunk_ref_destructor))) {
6696  return NULL;
6697  }
6698 
6699  ao2_ref(trunk, 1);
6700  trunk_ref->trunk = trunk;
6701 
6702  return trunk_ref;
6703 }
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static void sla_trunk_ref_destructor(void *obj)
Definition: app_meetme.c:6681
static void* dial_trunk ( void *  data)
static

Definition at line 6375 of file app_meetme.c.

References ALL_TRUNK_REFS, args, 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(), MAX_CONFNUM, 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().

6376 {
6377  struct dial_trunk_args *args = data;
6378  struct ast_dial *dial;
6379  char *tech, *tech_data;
6380  enum ast_dial_result dial_res;
6381  char conf_name[MAX_CONFNUM];
6382  struct ast_conference *conf;
6383  struct ast_flags64 conf_flags = { 0 };
6384  RAII_VAR(struct sla_trunk_ref *, trunk_ref, args->trunk_ref, unref_obj);
6385  RAII_VAR(struct sla_station *, station, args->station, unref_obj);
6386  int caller_is_saved;
6387  struct ast_party_caller caller;
6388  int last_state = 0;
6389  int current_state = 0;
6390 
6391  if (!(dial = ast_dial_create())) {
6392  ast_mutex_lock(args->cond_lock);
6393  ast_cond_signal(args->cond);
6394  ast_mutex_unlock(args->cond_lock);
6395  return NULL;
6396  }
6397 
6398  tech_data = ast_strdupa(trunk_ref->trunk->device);
6399  tech = strsep(&tech_data, "/");
6400  if (ast_dial_append(dial, tech, tech_data) == -1) {
6401  ast_mutex_lock(args->cond_lock);
6402  ast_cond_signal(args->cond);
6403  ast_mutex_unlock(args->cond_lock);
6404  ast_dial_destroy(dial);
6405  return NULL;
6406  }
6407 
6408  /* Do we need to save of the caller ID data? */
6409  caller_is_saved = 0;
6410  if (!sla.attempt_callerid) {
6411  caller_is_saved = 1;
6412  caller = trunk_ref->chan->caller;
6413  ast_party_caller_init(&trunk_ref->chan->caller);
6414  }
6415 
6416  dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
6417 
6418  /* Restore saved caller ID */
6419  if (caller_is_saved) {
6420  ast_party_caller_free(&trunk_ref->chan->caller);
6421  trunk_ref->chan->caller = caller;
6422  }
6423 
6424  if (dial_res != AST_DIAL_RESULT_TRYING) {
6425  ast_mutex_lock(args->cond_lock);
6426  ast_cond_signal(args->cond);
6427  ast_mutex_unlock(args->cond_lock);
6428  ast_dial_destroy(dial);
6429  return NULL;
6430  }
6431 
6432  for (;;) {
6433  unsigned int done = 0;
6434  switch ((dial_res = ast_dial_state(dial))) {
6436  trunk_ref->trunk->chan = ast_dial_answered(dial);
6442  done = 1;
6443  break;
6445  current_state = AST_CONTROL_PROGRESS;
6446  break;
6450  current_state = AST_CONTROL_RINGING;
6451  break;
6452  }
6453  if (done)
6454  break;
6455 
6456  /* check that SLA station that originated trunk call is still alive */
6457  if (station && ast_device_state(station->device) == AST_DEVICE_NOT_INUSE) {
6458  ast_debug(3, "Originating station device %s no longer active\n", station->device);
6459  trunk_ref->trunk->chan = NULL;
6460  break;
6461  }
6462 
6463  /* If trunk line state changed, send indication back to originating SLA Station channel */
6464  if (current_state != last_state) {
6465  ast_debug(3, "Indicating State Change %d to channel %s\n", current_state, trunk_ref->chan->name);
6466  ast_indicate(trunk_ref->chan, current_state);
6467  last_state = current_state;
6468  }
6469 
6470  /* avoid tight loop... sleep for 1/10th second */
6471  ast_safe_sleep(trunk_ref->chan, 100);
6472  }
6473 
6474  if (!trunk_ref->trunk->chan) {
6475  ast_mutex_lock(args->cond_lock);
6476  ast_cond_signal(args->cond);
6477  ast_mutex_unlock(args->cond_lock);
6478  ast_dial_join(dial);
6479  ast_dial_destroy(dial);
6480  return NULL;
6481  }
6482 
6483  snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
6484  ast_set_flag64(&conf_flags,
6487  conf = build_conf(conf_name, "", "", 1, 1, 1, trunk_ref->trunk->chan, NULL);
6488 
6489  ast_mutex_lock(args->cond_lock);
6490  ast_cond_signal(args->cond);
6491  ast_mutex_unlock(args->cond_lock);
6492 
6493  if (conf) {
6494  conf_run(trunk_ref->trunk->chan, conf, &conf_flags, NULL);
6495  dispose_conf(conf);
6496  conf = NULL;
6497  }
6498 
6499  /* If the trunk is going away, it is definitely now IDLE. */
6501 
6502  trunk_ref->trunk->chan = NULL;
6503  trunk_ref->trunk->on_hold = 0;
6504 
6505  ast_dial_join(dial);
6506  ast_dial_destroy(dial);
6507 
6508  return NULL;
6509 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
ast_device_state
Device States.
Definition: devicestate.h:51
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
char * strsep(char **str, const char *delims)
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:47
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
Append a channel.
Definition: dial.c:229
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:5552
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2302
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:1213
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_cond_t * cond
Definition: app_meetme.c:6372
ast_mutex_t * cond_lock
Definition: app_meetme.c:6371
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define ast_cond_signal(cond)
Definition: lock.h:169
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:2759
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct sla_station * station
Definition: app_meetme.c:6370
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:48
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
#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:915
Caller Party information.
Definition: channel.h:368
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:785
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:714
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:6369
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:754
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:201
#define MAX_CONFNUM
Definition: app_meetme.c:693
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
The MeetMe Conference object.
Definition: app_meetme.c:715
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:2269
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int dispose_conf ( struct ast_conference conf)
static

Decrement reference counts, as incremented by find_conf()

Definition at line 2097 of file app_meetme.c.

References ast_atomic_dec_and_test(), AST_LIST_LOCK, AST_LIST_UNLOCK, conf_free(), conf_map, 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().

2098 {
2099  int res = 0;
2100  int confno_int = 0;
2101 
2102  AST_LIST_LOCK(&confs);
2103  if (ast_atomic_dec_and_test(&conf->refcount)) {
2104  /* Take the conference room number out of an inuse state */
2105  if ((sscanf(conf->confno, "%4d", &confno_int) == 1) && (confno_int >= 0 && confno_int < 1024)) {
2106  conf_map[confno_int] = 0;
2107  }
2108  conf_free(conf);
2109  res = 1;
2110  }
2112 
2113  return res;
2114 }
static int conf_free(struct ast_conference *conf)
Remove the conference from the list and free it.
Definition: app_meetme.c:1926
#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. Useful e.g. to check if a refcount h...
Definition: lock.h:649
static unsigned int conf_map[1024]
Definition: app_meetme.c:761
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static void filename_parse ( char *  filename,
char *  buffer 
)
static

Definition at line 5186 of file app_meetme.c.

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

Referenced by recordthread().

5187 {
5188  char *slash;
5189  if (ast_strlen_zero(filename)) {
5190  ast_log(LOG_WARNING, "No file name was provided for a file save option.\n");
5191  } else if (filename[0] != '/') {
5192  snprintf(buffer, PATH_MAX, "%s/meetme/%s", ast_config_AST_SPOOL_DIR, filename);
5193  } else {
5194  ast_copy_string(buffer, filename, PATH_MAX);
5195  }
5196 
5197  slash = buffer;
5198  if ((slash = strrchr(slash, '/'))) {
5199  *slash = '\0';
5200  ast_mkdir(buffer, 0777);
5201  *slash = '/';
5202  }
5203 }
#define LOG_WARNING
Definition: logger.h:144
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_config_AST_SPOOL_DIR
Definition: asterisk.c:259
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
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 4270 of file app_meetme.c.

References args, 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_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, parse(), ast_conference::refcount, S_OR, ast_variable::value, and var.

Referenced by conf_exec(), and count_exec().

4272 {
4273  struct ast_config *cfg;
4274  struct ast_variable *var;
4275  struct ast_flags config_flags = { 0 };
4276  struct ast_conference *cnf;
4277 
4280  AST_APP_ARG(pin);
4282  );
4283 
4284  /* Check first in the conference list */
4285  ast_debug(1, "The requested confno is '%s'?\n", confno);
4286  AST_LIST_LOCK(&confs);
4287  AST_LIST_TRAVERSE(&confs, cnf, list) {
4288  ast_debug(3, "Does conf %s match %s?\n", confno, cnf->confno);
4289  if (!strcmp(confno, cnf->confno))
4290  break;
4291  }
4292  if (cnf) {
4293  cnf->refcount += refcount;
4294  }
4296 
4297  if (!cnf) {
4298  if (dynamic) {
4299  /* No need to parse meetme.conf */
4300  ast_debug(1, "Building dynamic conference '%s'\n", confno);
4301  if (dynamic_pin) {
4302  if (dynamic_pin[0] == 'q') {
4303  /* Query the user to enter a PIN */
4304  if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, pin_buf_len - 1, 0) < 0)
4305  return NULL;
4306  }
4307  cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount, chan, NULL);
4308  } else {
4309  cnf = build_conf(confno, "", "", make, dynamic, refcount, chan, NULL);
4310  }
4311  } else {
4312  /* Check the config */
4313  cfg = ast_config_load(CONFIG_FILE_NAME, config_flags);
4314  if (!cfg) {
4315  ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
4316  return NULL;
4317  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4318  ast_log(LOG_ERROR, "Config file " CONFIG_FILE_NAME " is in an invalid format. Aborting.\n");
4319  return NULL;
4320  }
4321 
4322  for (var = ast_variable_browse(cfg, "rooms"); var; var = var->next) {
4323  char parse[MAX_SETTINGS];
4324 
4325  if (strcasecmp(var->name, "conf"))
4326  continue;
4327 
4328  ast_copy_string(parse, var->value, sizeof(parse));
4329 
4330  AST_STANDARD_APP_ARGS(args, parse);
4331  ast_debug(3, "Will conf %s match %s?\n", confno, args.confno);
4332  if (!strcasecmp(args.confno, confno)) {
4333  /* Bingo it's a valid conference */
4334  cnf = build_conf(args.confno,
4335  S_OR(args.pin, ""),
4336  S_OR(args.pinadmin, ""),
4337  make, dynamic, refcount, chan, NULL);
4338  break;
4339  }
4340  }
4341  if (!var) {
4342  ast_debug(1, "%s isn't a valid conference\n", confno);
4343  }
4344  ast_config_destroy(cfg);
4345  }
4346  } else if (dynamic_pin) {
4347  /* Correct for the user selecting 'D' instead of 'd' to have
4348  someone join into a conference that has already been created
4349  with a pin. */
4350  if (dynamic_pin[0] == 'q') {
4351  dynamic_pin[0] = '\0';
4352  }
4353  }
4354 
4355  if (cnf) {
4356  if (confflags && !cnf->chan &&
4357  !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4359  ast_log(LOG_WARNING, "No DAHDI channel available for conference, user introduction disabled (is chan_dahdi loaded?)\n");
4361  }
4362 
4363  if (confflags && !cnf->chan &&
4364  ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
4365  ast_log(LOG_WARNING, "No DAHDI channel available for conference, conference recording disabled (is chan_dahdi loaded?)\n");
4367  }
4368  }
4369 
4370  return cnf;
4371 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_channel * chan
Definition: app_meetme.c:719
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: app.c:178
struct ast_conference::@32 list
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
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:1213
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
const char * name
Definition: config.h:77
char pin[MAX_PIN]
Definition: app_meetme.c:738
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:1858
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag64(p, flag)
Definition: utils.h:134
#define MAX_SETTINGS
Definition: app_meetme.c:698
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
char pinadmin[MAX_PIN]
Definition: app_meetme.c:739
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
struct ast_variable * next
Definition: config.h:82
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
The MeetMe Conference object.
Definition: app_meetme.c:715
#define CONFIG_FILE_NAME
Definition: app_meetme.c:524
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
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 4082 of file app_meetme.c.

References ast_conference::adminopts, ast_app_parse_options64(), ast_channel_lock, 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_INTROUSERNOREVIEW, CONFFLAG_QUIET, CONFFLAG_RECORDCONF, ast_conference::confno, DATE_FORMAT, earlyalert, endalert, ast_conference::endalert, ast_conference::endtime, ast_flags64::flags, fuzzystart, ast_channel::language, ast_conference::list, LOG_WARNING, ast_conference::maxusers, meetme_opts, ast_variable::name, ast_variable::next, OPTIONS_LEN, pbx_builtin_getvar_helper(), ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::refcount, ast_channel::uniqueid, ast_conference::useropts, ast_variable::value, and var.

Referenced by conf_exec().

4084 {
4085  struct ast_variable *var, *origvar;
4086  struct ast_conference *cnf;
4087 
4088  *too_early = 0;
4089 
4090  /* Check first in the conference list */
4091  AST_LIST_LOCK(&confs);
4092  AST_LIST_TRAVERSE(&confs, cnf, list) {
4093  if (!strcmp(confno, cnf->confno)) {
4094  break;
4095  }
4096  }
4097  if (cnf) {
4098  cnf->refcount += refcount;
4099  }
4101 
4102  if (!cnf) {
4103  char *pin = NULL, *pinadmin = NULL; /* For temp use */
4104  int maxusers = 0;
4105  struct timeval now;
4106  char recordingfilename[256] = "";
4107  char recordingformat[11] = "";
4108  char currenttime[32] = "";
4109  char eatime[32] = "";
4110  char bookid[51] = "";
4111  char recordingtmp[AST_MAX_EXTENSION] = "";
4112  char useropts[OPTIONS_LEN + 1] = ""; /* Used for RealTime conferences */
4113  char adminopts[OPTIONS_LEN + 1] = "";
4114  struct ast_tm tm, etm;
4115  struct timeval endtime = { .tv_sec = 0 };
4116  const char *var2;
4117 
4118  if (rt_schedule) {
4119  now = ast_tvnow();
4120 
4121  ast_localtime(&now, &tm, NULL);
4122  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
4123 
4124  ast_debug(1, "Looking for conference %s that starts after %s\n", confno, currenttime);
4125 
4126  var = ast_load_realtime("meetme", "confno",
4127  confno, "starttime <= ", currenttime, "endtime >= ",
4128  currenttime, NULL);
4129 
4130  if (!var && fuzzystart) {
4131  now = ast_tvnow();
4132  now.tv_sec += fuzzystart;
4133 
4134  ast_localtime(&now, &tm, NULL);
4135  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
4136  var = ast_load_realtime("meetme", "confno",
4137  confno, "starttime <= ", currenttime, "endtime >= ",
4138  currenttime, NULL);
4139  }
4140 
4141  if (!var && earlyalert) {
4142  now = ast_tvnow();
4143  now.tv_sec += earlyalert;
4144  ast_localtime(&now, &etm, NULL);
4145  ast_strftime(eatime, sizeof(eatime), DATE_FORMAT, &etm);
4146  var = ast_load_realtime("meetme", "confno",
4147  confno, "starttime <= ", eatime, "endtime >= ",
4148  currenttime, NULL);
4149  if (var) {
4150  *too_early = 1;
4151  }
4152  }
4153 
4154  } else {
4155  var = ast_load_realtime("meetme", "confno", confno, NULL);
4156  }
4157 
4158  if (!var) {
4159  return NULL;
4160  }
4161 
4162  if (rt_schedule && *too_early) {
4163  /* Announce that the caller is early and exit */
4164  if (!ast_streamfile(chan, "conf-has-not-started", chan->language)) {
4165  ast_waitstream(chan, "");
4166  }
4167  ast_variables_destroy(var);
4168  return NULL;
4169  }
4170 
4171  for (origvar = var; var; var = var->next) {
4172  if (!strcasecmp(var->name, "pin")) {
4173  pin = ast_strdupa(var->value);
4174  } else if (!strcasecmp(var->name, "adminpin")) {
4175  pinadmin = ast_strdupa(var->value);
4176  } else if (!strcasecmp(var->name, "bookId")) {
4177  ast_copy_string(bookid, var->value, sizeof(bookid));
4178  } else if (!strcasecmp(var->name, "opts")) {
4179  ast_copy_string(useropts, var->value, sizeof(char[OPTIONS_LEN + 1]));
4180  } else if (!strcasecmp(var->name, "maxusers")) {
4181  maxusers = atoi(var->value);
4182  } else if (!strcasecmp(var->name, "adminopts")) {
4183  ast_copy_string(adminopts, var->value, sizeof(char[OPTIONS_LEN + 1]));
4184  } else if (!strcasecmp(var->name, "recordingfilename")) {
4185  ast_copy_string(recordingfilename, var->value, sizeof(recordingfilename));
4186  } else if (!strcasecmp(var->name, "recordingformat")) {
4187  ast_copy_string(recordingformat, var->value, sizeof(recordingformat));
4188  } else if (!strcasecmp(var->name, "endtime")) {
4189  struct ast_tm endtime_tm;
4190  ast_strptime(var->value, "%Y-%m-%d %H:%M:%S", &endtime_tm);
4191  endtime = ast_mktime(&endtime_tm, NULL);
4192  }
4193  }
4194 
4195  ast_variables_destroy(origvar);
4196 
4197  cnf = build_conf(confno, pin ? pin : "", pinadmin ? pinadmin : "", make, dynamic, refcount, chan, NULL);
4198 
4199  if (cnf) {
4200  struct ast_flags64 tmp_flags;
4201 
4202  cnf->maxusers = maxusers;
4203  cnf->endalert = endalert;
4204  cnf->endtime = endtime.tv_sec;
4205  cnf->useropts = ast_strdup(useropts);
4206  cnf->adminopts = ast_strdup(adminopts);
4207  cnf->bookid = ast_strdup(bookid);
4208  if (!ast_strlen_zero(recordingfilename)) {
4209  cnf->recordingfilename = ast_strdup(recordingfilename);
4210  }
4211  if (!ast_strlen_zero(recordingformat)) {
4212  cnf->recordingformat = ast_strdup(recordingformat);
4213  }
4214 
4215  /* Parse the other options into confflags -- need to do this in two
4216  * steps, because the parse_options routine zeroes the buffer. */
4217  ast_app_parse_options64(meetme_opts, &tmp_flags, optargs, useropts);
4218  ast_copy_flags64(confflags, &tmp_flags, tmp_flags.flags);
4219 
4220  if (strchr(cnf->useropts, 'r')) {
4221  if (ast_strlen_zero(recordingfilename)) { /* If the recordingfilename in the database is empty, use the channel definition or use the default. */
4222  ast_channel_lock(chan);
4223  if ((var2 = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
4225  cnf->recordingfilename = ast_strdup(var2);
4226  }
4227  ast_channel_unlock(chan);
4228  if (ast_strlen_zero(cnf->recordingfilename)) {
4229  snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", cnf->confno, chan->uniqueid);
4231  cnf->recordingfilename = ast_strdup(recordingtmp);
4232  }
4233  }
4234  if (ast_strlen_zero(cnf->recordingformat)) {/* If the recording format is empty, use the wav as default */
4235  ast_channel_lock(chan);
4236  if ((var2 = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
4237  ast_free(cnf->recordingformat);
4238  cnf->recordingformat = ast_strdup(var2);
4239  }
4240  ast_channel_unlock(chan);
4241  if (ast_strlen_zero(cnf->recordingformat)) {
4242  ast_free(cnf->recordingformat);
4243  cnf->recordingformat = ast_strdup("wav");
4244  }
4245  }
4246  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n", cnf->confno, cnf->recordingfilename, cnf->recordingformat);
4247  }
4248  }
4249  }
4250 
4251  if (cnf) {
4252  if (confflags->flags && !cnf->chan &&
4253  !ast_test_flag64(confflags, CONFFLAG_QUIET) &&
4255  ast_log(LOG_WARNING, "No DAHDI channel available for conference, user introduction disabled (is chan_dahdi loaded?)\n");
4257  }
4258 
4259  if (confflags && !cnf->chan &&
4260  ast_test_flag64(confflags, CONFFLAG_RECORDCONF)) {
4261  ast_log(LOG_WARNING, "No DAHDI channel available for conference, conference recording disabled (is chan_dahdi loaded?)\n");
4263  }
4264  }
4265 
4266  return cnf;
4267 }
static int fuzzystart
Definition: app_meetme.c:685
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int endalert
Definition: app_meetme.c:687
struct ast_channel * chan
Definition: app_meetme.c:719
#define ast_copy_flags64(dest, src, flagz)
Definition: utils.h:141
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_strdup(a)
Definition: astmm.h:109
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: app.c:2106
struct ast_conference::@32 list
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:737
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:1570
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
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:1213
static int earlyalert
Definition: app_meetme.c:686
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
const char * useropts
Definition: app_meetme.c:742
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define ast_verb(level,...)
Definition: logger.h:243
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
static int rt_schedule
Definition: app_meetme.c:684
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
const char * bookid
Definition: app_meetme.c:744
static struct ast_app_option meetme_opts[128]
Definition: app_meetme.c:674
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
const char * name
Definition: config.h:77
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:2377
uint64_t flags
Definition: utils.h:207
char pin[MAX_PIN]
Definition: app_meetme.c:738
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define DATE_FORMAT
Definition: app_meetme.c:532
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:695
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
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:2351
const char * adminopts
Definition: app_meetme.c:743
#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:2185
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
char pinadmin[MAX_PIN]
Definition: app_meetme.c:739
char * recordingfilename
Definition: app_meetme.c:736
struct ast_variable * next
Definition: config.h:82
The MeetMe Conference object.
Definition: app_meetme.c:715
const ast_string_field language
Definition: channel.h:787
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static struct ast_conf_user* find_user ( struct ast_conference conf,
const char *  callerident 
)
static

Definition at line 4744 of file app_meetme.c.

References ao2_find, user, and ast_conference::usercontainer.

Referenced by admin_exec().

4745 {
4746  struct ast_conf_user *user = NULL;
4747  int cid;
4748 
4749  if (conf && callerident && sscanf(callerident, "%30d", &cid) == 1) {
4750  user = ao2_find(conf->usercontainer, &cid, 0);
4751  /* reference decremented later in admin_exec */
4752  return user;
4753  }
4754  return NULL;
4755 }
static char user[512]
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
struct ao2_container * usercontainer
Definition: app_meetme.c:748
structure to hold users read from users.conf
static const char* get_announce_filename ( enum announcetypes  type)
static

Definition at line 2194 of file app_meetme.c.

References CONF_HASJOIN, and CONF_HASLEFT.

Referenced by announce_thread().

2195 {
2196  switch (type) {
2197  case CONF_HASLEFT:
2198  return "conf-hasleft";
2199  break;
2200  case CONF_HASJOIN:
2201  return "conf-hasjoin";
2202  break;
2203  default:
2204  return "";
2205  }
2206 }
static const char type[]
Definition: chan_nbs.c:57
static const char* istalking ( int  x)
static

Definition at line 1006 of file app_meetme.c.

Referenced by meetme_show_cmd().

1007 {
1008  if (x > 0)
1009  return "(talking)";
1010  else if (x < 0)
1011  return "(unmonitored)";
1012  else
1013  return "(not talking)";
1014 }
static int load_config ( int  reload)
static

Definition at line 7535 of file app_meetme.c.

References load_config_meetme(), and sla_load_config().

Referenced by load_module(), and reload().

7536 {
7538  return sla_load_config(reload);
7539 }
static int sla_load_config(int reload)
Definition: app_meetme.c:7394
static int reload(void)
Definition: app_meetme.c:7781
static void load_config_meetme(void)
Definition: app_meetme.c:5296
static void load_config_meetme ( void  )
static

Definition at line 5296 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, and LOG_WARNING.

Referenced by load_config().

5297 {
5298  struct ast_config *cfg;
5299  struct ast_flags config_flags = { 0 };
5300  const char *val;
5301 
5302  if (!(cfg = ast_config_load(CONFIG_FILE_NAME, config_flags))) {
5303  return;
5304  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
5305  ast_log(LOG_ERROR, "Config file " CONFIG_FILE_NAME " is in an invalid format. Aborting.\n");
5306  return;
5307  }
5308 
5310 
5311  /* Scheduling support is off by default */
5312  rt_schedule = 0;
5313  fuzzystart = 0;
5314  earlyalert = 0;
5315  endalert = 0;
5316  extendby = 0;
5317 
5318  /* Logging of participants defaults to ON for compatibility reasons */
5319  rt_log_members = 1;
5320 
5321  if ((val = ast_variable_retrieve(cfg, "general", "audiobuffers"))) {
5322  if ((sscanf(val, "%30d", &audio_buffers) != 1)) {
5323  ast_log(LOG_WARNING, "audiobuffers setting must be a number, not '%s'\n", val);
5325  } else if ((audio_buffers < DAHDI_DEFAULT_NUM_BUFS) || (audio_buffers > DAHDI_MAX_NUM_BUFS)) {
5326  ast_log(LOG_WARNING, "audiobuffers setting must be between %d and %d\n",
5327  DAHDI_DEFAULT_NUM_BUFS, DAHDI_MAX_NUM_BUFS);
5329  }
5331  ast_log(LOG_NOTICE, "Audio buffers per channel set to %d\n", audio_buffers);
5332  }
5333 
5334  if ((val = ast_variable_retrieve(cfg, "general", "schedule")))
5335  rt_schedule = ast_true(val);
5336  if ((val = ast_variable_retrieve(cfg, "general", "logmembercount")))
5337  rt_log_members = ast_true(val);
5338  if ((val = ast_variable_retrieve(cfg, "general", "fuzzystart"))) {
5339  if ((sscanf(val, "%30d", &fuzzystart) != 1)) {
5340  ast_log(LOG_WARNING, "fuzzystart must be a number, not '%s'\n", val);
5341  fuzzystart = 0;
5342  }
5343  }
5344  if ((val = ast_variable_retrieve(cfg, "general", "earlyalert"))) {
5345  if ((sscanf(val, "%30d", &earlyalert) != 1)) {
5346  ast_log(LOG_WARNING, "earlyalert must be a number, not '%s'\n", val);
5347  earlyalert = 0;
5348  }
5349  }
5350  if ((val = ast_variable_retrieve(cfg, "general", "endalert"))) {
5351  if ((sscanf(val, "%30d", &endalert) != 1)) {
5352  ast_log(LOG_WARNING, "endalert must be a number, not '%s'\n", val);
5353  endalert = 0;
5354  }
5355  }
5356  if ((val = ast_variable_retrieve(cfg, "general", "extendby"))) {
5357  if ((sscanf(val, "%30d", &extendby) != 1)) {
5358  ast_log(LOG_WARNING, "extendby must be a number, not '%s'\n", val);
5359  extendby = 0;
5360  }
5361  }
5362 
5363  ast_config_destroy(cfg);
5364 }
static int fuzzystart
Definition: app_meetme.c:685
static int endalert
Definition: app_meetme.c:687
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
static int earlyalert
Definition: app_meetme.c:686
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int rt_schedule
Definition: app_meetme.c:684
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
#define LOG_ERROR
Definition: logger.h:155
#define DEFAULT_AUDIO_BUFFERS
Definition: app_meetme.c:529
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int rt_log_members
Definition: app_meetme.c:691
static int extendby
Definition: app_meetme.c:688
Structure used to handle boolean flags.
Definition: utils.h:200
static int audio_buffers
The number of audio buffers to be allocated on pseudo channels when in a conference.
Definition: app_meetme.c:979
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define CONFIG_FILE_NAME
Definition: app_meetme.c:524
static int load_module ( void  )
static

Definition at line 7750 of file app_meetme.c.

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

7751 {
7752  int res = 0;
7753 
7754  res |= load_config(0);
7755 
7766 
7767 #ifdef TEST_FRAMEWORK
7768  AST_TEST_REGISTER(test_meetme_data_provider);
7769 #endif
7771 
7772  res |= ast_devstate_prov_add("Meetme", meetmestate);
7773  res |= ast_devstate_prov_add("SLA", sla_state);
7774 
7776  ast_realtime_require_field("meetme", "confno", RQ_UINTEGER2, 3, "members", RQ_UINTEGER1, 3, NULL);
7777 
7778  return res;
7779 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int action_meetmeunmute(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5100
static const char *const app4
Definition: app_meetme.c:679
static int conf_exec(struct ast_channel *chan, const char *data)
The meetme() application.
Definition: app_meetme.c:4419
static const char *const app2
Definition: app_meetme.c:677
static int count_exec(struct ast_channel *chan, const char *data)
The MeetmeCount application.
Definition: app_meetme.c:4374
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static const char *const slastation_app
Definition: app_meetme.c:680
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:371
static int action_meetmelist(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5105
static struct ast_data_entry meetme_data_providers[]
Definition: app_meetme.c:7655
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static enum ast_device_state sla_state(const char *data)
Definition: app_meetme.c:6849
static struct ast_custom_function meetme_info_acf
Definition: app_meetme.c:7529
static enum ast_device_state meetmestate(const char *data)
Callback for devicestate providers.
Definition: app_meetme.c:5274
static int sla_station_exec(struct ast_channel *chan, const char *data)
Definition: app_meetme.c:6529
#define ast_data_register_multiple(data_entries, entries)
Definition: data.h:377
static int action_meetmemute(struct mansession *s, const struct message *m)
Definition: app_meetme.c:5095
static int sla_trunk_exec(struct ast_channel *chan, const char *data)
Definition: app_meetme.c:6751
static struct ast_cli_entry cli_meetme[]
Definition: app_meetme.c:1885
static const char *const app3
Definition: app_meetme.c:678
static const char *const slatrunk_app
Definition: app_meetme.c:681
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: config.c:2606
static const char *const app
Definition: app_meetme.c:676
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int load_config(int reload)
Definition: app_meetme.c:7535
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:4807
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static int channel_admin_exec(struct ast_channel *chan, const char *data)
The MeetMeChannelAdmin application MeetMeChannelAdmin(channel, command)
Definition: app_meetme.c:4974
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static char* meetme_cmd_helper ( struct ast_cli_args a)
static

Definition at line 1594 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, and strcasestr().

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

1595 {
1596  /* Process the command */
1597  struct ast_str *cmdline;
1598 
1599  /* Max confno length */
1600  if (!(cmdline = ast_str_create(MAX_CONFNUM))) {
1601  return CLI_FAILURE;
1602  }
1603 
1604  ast_str_set(&cmdline, 0, "%s", a->argv[2]); /* Argv 2: conference number */
1605  if (strcasestr(a->argv[1], "lock")) {
1606  if (strcasecmp(a->argv[1], "lock") == 0) {
1607  /* Lock */
1608  ast_str_append(&cmdline, 0, ",L");
1609  } else {
1610  /* Unlock */
1611  ast_str_append(&cmdline, 0, ",l");
1612  }
1613  } else if (strcasestr(a->argv[1], "mute")) {
1614  if (strcasecmp(a->argv[1], "mute") == 0) {
1615  /* Mute */
1616  if (strcasecmp(a->argv[3], "all") == 0) {
1617  ast_str_append(&cmdline, 0, ",N");
1618  } else {
1619  ast_str_append(&cmdline, 0, ",M,%s", a->argv[3]);
1620  }
1621  } else {
1622  /* Unmute */
1623  if (strcasecmp(a->argv[3], "all") == 0) {
1624  ast_str_append(&cmdline, 0, ",n");
1625  } else {
1626  ast_str_append(&cmdline, 0, ",m,%s", a->argv[3]);
1627  }
1628  }
1629  } else if (strcasecmp(a->argv[1], "kick") == 0) {
1630  if (strcasecmp(a->argv[3], "all") == 0) {
1631  /* Kick all */
1632  ast_str_append(&cmdline, 0, ",K");
1633  } else {
1634  /* Kick a single user */
1635  ast_str_append(&cmdline, 0, ",k,%s", a->argv[3]);
1636  }
1637  } else {
1638  /*
1639  * Should never get here because it is already filtered by the
1640  * callers.
1641  */
1642  ast_free(cmdline);
1643  return CLI_SHOWUSAGE;
1644  }
1645 
1646  ast_debug(1, "Cmdline: %s\n", ast_str_buffer(cmdline));
1647 
1648  admin_exec(NULL, ast_str_buffer(cmdline));
1649  ast_free(cmdline);
1650 
1651  return CLI_SUCCESS;
1652 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
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:874
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char *const * argv
Definition: cli.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
#define ast_free(a)
Definition: astmm.h:97
#define CLI_SUCCESS
Definition: cli.h:43
#define MAX_CONFNUM
Definition: app_meetme.c:693
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:4807
char * strcasestr(const char *, const char *)
static int meetme_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
)
static

Definition at line 7616 of file app_meetme.c.

References ao2_callback, ao2_container_count(), ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, OBJ_NODATA, user_add_provider_cb(), and ast_conference::usercontainer.

7618 {
7619  struct ast_conference *cnf;
7620  struct ast_data *data_meetme, *data_meetme_users;
7621 
7622  AST_LIST_LOCK(&confs);
7623  AST_LIST_TRAVERSE(&confs, cnf, list) {
7624  data_meetme = ast_data_add_node(data_root, "meetme");
7625  if (!data_meetme) {
7626  continue;
7627  }
7628 
7629  ast_data_add_structure(ast_conference, data_meetme, cnf);
7630 
7631  if (ao2_container_count(cnf->usercontainer)) {
7632  data_meetme_users = ast_data_add_node(data_meetme, "users");
7633  if (!data_meetme_users) {
7634  ast_data_remove_node(data_root, data_meetme);
7635  continue;
7636  }
7637 
7638  ao2_callback(cnf->usercontainer, OBJ_NODATA, user_add_provider_cb, data_meetme_users);
7639  }
7640 
7641  if (!ast_data_search_match(search, data_meetme)) {
7642  ast_data_remove_node(data_root, data_meetme);
7643  }
7644  }
7646 
7647  return 0;
7648 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
The data tree to be returned by the callbacks and managed by functions local to this file...
Definition: data.c:85
#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:910
struct ast_data * ast_data_add_node(struct ast_data *root, const char *childname)
Add a container child.
Definition: data.c:2317
#define ast_data_add_structure(structure_name, root, structure)
Definition: data.h:620
void ast_data_remove_node(struct ast_data *root, struct ast_data *child)
Remove a node that was added using ast_data_add_.
Definition: data.c:2486
#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:748
static int user_add_provider_cb(void *obj, void *arg, int flags)
Definition: app_meetme.c:7570
The MeetMe Conference object.
Definition: app_meetme.c:715
int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data)
Check the current generated node to know if it matches the search condition.
Definition: data.c:1458
static char* meetme_kick_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1674 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, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

1675 {
1676  switch (cmd) {
1677  case CLI_INIT:
1678  e->command = "meetme kick";
1679  e->usage =
1680  "Usage: meetme kick <confno> all|<userno>\n"
1681  " Kick a conference or a user in a conference.\n";
1682  return NULL;
1683  case CLI_GENERATE:
1684  return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
1685  }
1686 
1687  if (a->argc != 4) {
1688  return CLI_SHOWUSAGE;
1689  }
1690 
1691  return meetme_cmd_helper(a);
1692 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static char * complete_meetmecmd_mute_kick(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1364
const char * line
Definition: cli.h:156
const int n
Definition: cli.h:159
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1594
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
const int pos
Definition: cli.h:158
static char* meetme_lock_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1654 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, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

1655 {
1656  switch (cmd) {
1657  case CLI_INIT:
1658  e->command = "meetme {lock|unlock}";
1659  e->usage =
1660  "Usage: meetme lock|unlock <confno>\n"
1661  " Lock or unlock a conference to new users.\n";
1662  return NULL;
1663  case CLI_GENERATE:
1664  return complete_meetmecmd_lock(a->word, a->pos, a->n);
1665  }
1666 
1667  if (a->argc != 3) {
1668  return CLI_SHOWUSAGE;
1669  }
1670 
1671  return meetme_cmd_helper(a);
1672 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const int n
Definition: cli.h:159
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1594
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
const int pos
Definition: cli.h:158
static char * complete_meetmecmd_lock(const char *word, int pos, int state)
Definition: app_meetme.c:1404
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 
)
static

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

2739 {
2740  switch (*menu_mode) {
2741  case MENU_DISABLED:
2742  break;
2743  case MENU_NORMAL:
2744  meetme_menu_normal(menu_mode, dtmf, conf, confflags, chan, user);
2745  break;
2746  case MENU_ADMIN:
2747  meetme_menu_admin(menu_mode, dtmf, conf, confflags, chan, user);
2748  /* Admin Menu is capable of branching into another menu, in which case it will reset dtmf and change the menu mode. */
2749  if (*menu_mode != MENU_ADMIN_EXTENDED || (*dtmf <= 0)) {
2750  break;
2751  }
2752  case MENU_ADMIN_EXTENDED:
2753  meetme_menu_admin_extended(menu_mode, dtmf, conf, confflags, chan, user,
2754  recordingtmp, recordingtmp_size);
2755  break;
2756  }
2757 }
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:2349
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:2429
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)
Definition: app_meetme.c:2549
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 2429 of file app_meetme.c.

References ADMINFLAG_KICKME, ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ast_conf_user::adminflags, ao2_callback, ao2_find, ao2_ref, AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), ast_test_flag64, ast_waitstream(), ast_conf_user::chan, CONFFLAG_ADMIN, CONFFLAG_MONITOR, ast_conference::confno, ast_channel::language, ast_conference::locked, MENU_ADMIN_EXTENDED, MENU_DISABLED, ast_channel::name, 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().

2430 {
2431  switch(*dtmf) {
2432  case '1': /* Un/Mute */
2433  *menu_mode = MENU_DISABLED;
2434  /* for admin, change both admin and use flags */
2437  } else {
2439  }
2440 
2442  if (!ast_streamfile(chan, "conf-muted", chan->language)) {
2443  ast_waitstream(chan, "");
2444  }
2445  } else {
2446  if (!ast_streamfile(chan, "conf-unmuted", chan->language)) {
2447  ast_waitstream(chan, "");
2448  }
2449  }
2450  break;
2451 
2452  case '2': /* Un/Lock the Conference */
2453  *menu_mode = MENU_DISABLED;
2454  if (conf->locked) {
2455  conf->locked = 0;
2456  if (!ast_streamfile(chan, "conf-unlockednow", chan->language)) {
2457  ast_waitstream(chan, "");
2458  }
2459  } else {
2460  conf->locked = 1;
2461  if (!ast_streamfile(chan, "conf-lockednow", chan->language)) {
2462  ast_waitstream(chan, "");
2463  }
2464  }
2465  break;
2466 
2467  case '3': /* Eject last user */
2468  {
2469  struct ast_conf_user *usr = NULL;
2470  int max_no = 0;
2472  *menu_mode = MENU_DISABLED;
2473  usr = ao2_find(conf->usercontainer, &max_no, 0);
2474  if ((usr->chan->name == chan->name) || ast_test_flag64(&usr->userflags, CONFFLAG_ADMIN)) {
2475  if (!ast_streamfile(chan, "conf-errormenu", chan->language)) {
2476  ast_waitstream(chan, "");
2477  }
2478  } else {
2479  usr->adminflags |= ADMINFLAG_KICKME;
2480  }
2481  ao2_ref(usr, -1);
2482  ast_stopstream(chan);
2483  break;
2484  }
2485 
2486  case '4':
2488  break;
2489 
2490  case '5':
2491  /* Extend RT conference */
2492  if (rt_schedule) {
2493  if (!rt_extend_conf(conf->confno)) {
2494  if (!ast_streamfile(chan, "conf-extended", chan->language)) {
2495  ast_waitstream(chan, "");
2496  }
2497  } else {
2498  if (!ast_streamfile(chan, "conf-nonextended", chan->language)) {
2499  ast_waitstream(chan, "");
2500  }
2501  }
2502  ast_stopstream(chan);
2503  }
2504  *menu_mode = MENU_DISABLED;
2505  break;
2506 
2507  case '6':
2508  tweak_listen_volume(user, VOL_UP);
2509  break;
2510 
2511  case '7':
2512  tweak_talk_volume(user, VOL_DOWN);
2513  break;
2514 
2515  case '8':
2516  if (!ast_streamfile(chan, "conf-adminmenu-menu8", chan->language)) {
2517  /* 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. */
2518  *dtmf = ast_waitstream(chan, AST_DIGIT_ANY);
2519  ast_stopstream(chan);
2520  }
2521  *menu_mode = MENU_ADMIN_EXTENDED;
2522  break;
2523 
2524  case '9':
2525  tweak_talk_volume(user, VOL_UP);
2526  break;
2527  default:
2528  menu_mode = MENU_DISABLED;
2529  /* Play an error message! */
2530  if (!ast_streamfile(chan, "conf-errormenu", chan->language)) {
2531  ast_waitstream(chan, "");
2532  }
2533  break;
2534  }
2535 
2536 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1102
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2116
#define AST_DIGIT_ANY
Definition: file.h:47
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
unsigned int locked
Definition: app_meetme.c:731
static int user_max_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:1187
static int rt_schedule
Definition: app_meetme.c:684
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1114
struct ast_flags64 userflags
Definition: app_meetme.c:771
const ast_string_field name
Definition: channel.h:787
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
struct ao2_container * usercontainer
Definition: app_meetme.c:748
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
struct ast_channel * chan
Definition: app_meetme.c:773
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
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 
)
static

Definition at line 2549 of file app_meetme.c.

References ao2_callback, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_lock, ast_channel_unlock, AST_DIGIT_ANY, ast_fileexists(), AST_FORMAT_SLINEAR, 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_channel::fds, ast_conference::gmuted, ast_channel::language, ast_conference::lchan, LOG_WARNING, MEETME_RECORD_ACTIVE, MENU_DISABLED, ast_conf_user::namerecloc, OBJ_NODATA, pbx_builtin_getvar_helper(), ast_conference::recordingfilename, ast_conference::recordingformat, ast_conference::recordthread, ast_conference::recordthreadlock, ast_channel::uniqueid, user_set_kickme_cb(), user_set_muted_cb(), user_set_unmuted_cb(), ast_conference::usercontainer, ast_conference::users, and var.

Referenced by meetme_menu().

2552 {
2553  int keepplaying;
2554  int playednamerec;
2555  int res;
2556  struct ao2_iterator user_iter;
2557  struct ast_conf_user *usr = NULL;
2558 
2559  switch(*dtmf) {
2560  case '1': /* *81 Roll call */
2561  keepplaying = 1;
2562  playednamerec = 0;
2563  if (conf->users == 1) {
2564  if (keepplaying && !ast_streamfile(chan, "conf-onlyperson", chan->language)) {
2565  res = ast_waitstream(chan, AST_DIGIT_ANY);
2566  ast_stopstream(chan);
2567  if (res > 0) {
2568  keepplaying = 0;
2569  }
2570  }
2571  } else if (conf->users == 2) {
2572  if (keepplaying && !ast_streamfile(chan, "conf-onlyone", chan->language)) {
2573  res = ast_waitstream(chan, AST_DIGIT_ANY);
2574  ast_stopstream(chan);
2575  if (res > 0) {
2576  keepplaying = 0;
2577  }
2578  }
2579  } else {
2580  if (keepplaying && !ast_streamfile(chan, "conf-thereare", chan->language)) {
2581  res = ast_waitstream(chan, AST_DIGIT_ANY);
2582  ast_stopstream(chan);
2583  if (res > 0) {
2584  keepplaying = 0;
2585  }
2586  }
2587  if (keepplaying) {
2588  res = ast_say_number(chan, conf->users - 1, AST_DIGIT_ANY, chan->language, (char *) NULL);
2589  ast_stopstream(chan);
2590  if (res > 0) {
2591  keepplaying = 0;
2592  }
2593  }
2594  if (keepplaying && !ast_streamfile(chan, "conf-otherinparty", chan->language)) {
2595  res = ast_waitstream(chan, AST_DIGIT_ANY);
2596  ast_stopstream(chan);
2597  if (res > 0) {
2598  keepplaying = 0;
2599  }
2600  }
2601  }
2602  user_iter = ao2_iterator_init(conf->usercontainer, 0);
2603  while((usr = ao2_iterator_next(&user_iter))) {
2604  if (ast_fileexists(usr->namerecloc, NULL, NULL)) {
2605  if (keepplaying && !ast_streamfile(chan, usr->namerecloc, chan->language)) {
2606  res = ast_waitstream(chan, AST_DIGIT_ANY);
2607  ast_stopstream(chan);
2608  if (res > 0) {
2609  keepplaying = 0;
2610  }
2611  }
2612  playednamerec = 1;
2613  }
2614  ao2_ref(usr, -1);
2615  }
2616  ao2_iterator_destroy(&user_iter);
2617  if (keepplaying && playednamerec && !ast_streamfile(chan, "conf-roll-callcomplete", chan->language)) {
2618  res = ast_waitstream(chan, AST_DIGIT_ANY);
2619  ast_stopstream(chan);
2620  if (res > 0) {
2621  keepplaying = 0;
2622  }
2623  }
2624 
2625  *menu_mode = MENU_DISABLED;
2626  break;
2627 
2628  case '2': /* *82 Eject all non-admins */
2629  if (conf->users == 1) {
2630  if(!ast_streamfile(chan, "conf-errormenu", chan->language)) {
2631  ast_waitstream(chan, "");
2632  }
2633  } else {
2635  }
2636  ast_stopstream(chan);
2637  *menu_mode = MENU_DISABLED;
2638  break;
2639 
2640  case '3': /* *83 (Admin) mute/unmute all non-admins */
2641  if(conf->gmuted) {
2642  conf->gmuted = 0;
2644  if (!ast_streamfile(chan, "conf-now-unmuted", chan->language)) {
2645  ast_waitstream(chan, "");
2646  }
2647  } else {
2648  conf->gmuted = 1;
2650  if (!ast_streamfile(chan, "conf-now-muted", chan->language)) {
2651  ast_waitstream(chan, "");
2652  }
2653  }
2654  ast_stopstream(chan);
2655  *menu_mode = MENU_DISABLED;
2656  break;
2657 
2658  case '4': /* *84 Record conference */
2659  if (conf->recording != MEETME_RECORD_ACTIVE) {
2660  ast_set_flag64(confflags, CONFFLAG_RECORDCONF);
2661  if (!conf->recordingfilename) {
2662  const char *var;
2663  ast_channel_lock(chan);
2664  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE"))) {
2665  conf->recordingfilename = ast_strdup(var);
2666  }
2667  if ((var = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT"))) {
2668  conf->recordingformat = ast_strdup(var);
2669  }
2670  ast_channel_unlock(chan);
2671  if (!conf->recordingfilename) {
2672  snprintf(recordingtmp, recordingtmp_size, "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid);
2673  conf->recordingfilename = ast_strdup(recordingtmp);
2674  }
2675  if (!conf->recordingformat) {
2676  conf->recordingformat = ast_strdup("wav");
2677  }
2678  ast_verb(4, "Starting recording of MeetMe Conference %s into file %s.%s.\n",
2679  conf->confno, conf->recordingfilename, conf->recordingformat);
2680  }
2681 
2683  if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
2684  struct dahdi_confinfo dahdic;
2685 
2688  dahdic.chan = 0;
2689  dahdic.confno = conf->dahdiconf;
2690  dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
2691  if (ioctl(conf->lchan->fds[0], DAHDI_SETCONF, &dahdic)) {
2692  ast_log(LOG_WARNING, "Error starting listen channel\n");
2693  ast_hangup(conf->lchan);
2694  conf->lchan = NULL;
2695  } else {
2697  }
2698  }
2700  if (!ast_streamfile(chan, "conf-now-recording", chan->language)) {
2701  ast_waitstream(chan, "");
2702  }
2703  }
2704 
2705  ast_stopstream(chan);
2706  *menu_mode = MENU_DISABLED;
2707  break;
2708 
2709  case '8': /* *88 Exit the menu and return to the conference... without an error message */
2710  ast_stopstream(chan);
2711  *menu_mode = MENU_DISABLED;
2712  break;
2713 
2714  default:
2715  if (!ast_streamfile(chan, "conf-errormenu", chan->language)) {
2716  ast_waitstream(chan, "");
2717  }
2718  ast_stopstream(chan);
2719  *menu_mode = MENU_DISABLED;
2720  break;
2721  }
2722 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_strdup(a)
Definition: astmm.h:109
static int user_set_unmuted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2310
#define AST_DIGIT_ANY
Definition: file.h:47
pthread_t recordthread
Definition: app_meetme.c:733
static void * recordthread(void *args)
Definition: app_meetme.c:5205
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define LOG_WARNING
Definition: logger.h:144
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
char * recordingformat
Definition: app_meetme.c:737
#define var
Definition: ast_expr2f.c:606
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
#define ast_verb(level,...)
Definition: logger.h:243
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
unsigned int gmuted
Definition: app_meetme.c:732
static int user_set_kickme_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2299
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of &quot;format&quot; is ...
Definition: channel.c:5307
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
#define AST_PTHREADT_NULL
Definition: lock.h:65
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int fds[AST_MAX_FDS]
Definition: channel.h:829
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
char namerecloc[PATH_MAX]
Definition: app_meetme.c:777
struct ao2_container * usercontainer
Definition: app_meetme.c:748
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
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:8397
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
char * recordingfilename
Definition: app_meetme.c:736
struct ast_channel * lchan
Definition: app_meetme.c:720
struct ast_channel * ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status)
Requests a channel.
Definition: channel.c:5695
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static int user_set_muted_cb(void *obj, void *check_admin_arg, int flags)
Definition: app_meetme.c:2321
#define ast_mutex_unlock(a)
Definition: lock.h:156
ast_mutex_t recordthreadlock
Definition: app_meetme.c:734
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
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 2349 of file app_meetme.c.

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

Referenced by meetme_menu().

2350 {
2351  switch (*dtmf) {
2352  case '1': /* Un/Mute */
2353  *menu_mode = MENU_DISABLED;
2354 
2355  /* user can only toggle the self-muted state */
2357 
2358  /* they can't override the admin mute state */
2360  if (!ast_streamfile(chan, "conf-muted", chan->language)) {
2361  ast_waitstream(chan, "");
2362  }
2363  } else {
2364  if (!ast_streamfile(chan, "conf-unmuted", chan->language)) {
2365  ast_waitstream(chan, "");
2366  }
2367  }
2368  break;
2369 
2370  case '2':
2371  *menu_mode = MENU_DISABLED;
2374  }
2375 
2376  if (user->adminflags & ADMINFLAG_T_REQUEST) {
2377  if (!ast_streamfile(chan, "beep", chan->language)) {
2378  ast_waitstream(chan, "");
2379  }
2380  }
2381  break;
2382 
2383  case '4':
2385  break;
2386  case '5':
2387  /* Extend RT conference */
2388  if (rt_schedule) {
2389  rt_extend_conf(conf->confno);
2390  }
2391  *menu_mode = MENU_DISABLED;
2392  break;
2393 
2394  case '6':
2395  tweak_listen_volume(user, VOL_UP);
2396  break;
2397 
2398  case '7':
2399  tweak_talk_volume(user, VOL_DOWN);
2400  break;
2401 
2402  case '8':
2403  *menu_mode = MENU_DISABLED;
2404  break;
2405 
2406  case '9':
2407  tweak_talk_volume(user, VOL_UP);
2408  break;
2409 
2410  default:
2411  *menu_mode = MENU_DISABLED;
2412  if (!ast_streamfile(chan, "conf-errormenu", chan->language)) {
2413  ast_waitstream(chan, "");
2414  }
2415  break;
2416  }
2417 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1102
static int rt_extend_conf(const char *confno)
Definition: app_meetme.c:2116
static int rt_schedule
Definition: app_meetme.c:684
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1114
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
const ast_string_field language
Definition: channel.h:787
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static char* meetme_mute_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1694 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, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

1695 {
1696  switch (cmd) {
1697  case CLI_INIT:
1698  e->command = "meetme {mute|unmute}";
1699  e->usage =
1700  "Usage: meetme mute|unmute <confno> all|<userno>\n"
1701  " Mute or unmute a conference or a user in a conference.\n";
1702  return NULL;
1703  case CLI_GENERATE:
1704  return complete_meetmecmd_mute_kick(a->line, a->word, a->pos, a->n);
1705  }
1706 
1707  if (a->argc != 4) {
1708  return CLI_SHOWUSAGE;
1709  }
1710 
1711  return meetme_cmd_helper(a);
1712 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static char * complete_meetmecmd_mute_kick(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1364
const char * line
Definition: cli.h:156
const int n
Definition: cli.h:159
static char * meetme_cmd_helper(struct ast_cli_args *a)
Definition: app_meetme.c:1594
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
const int pos
Definition: cli.h:158
static char* meetme_show_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1451 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_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_channel::caller, 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, ast_cli_args::n, ast_party_id::name, ast_channel::name, 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.

1452 {
1453  /* Process the command */
1454  struct ast_conf_user *user;
1455  struct ast_conference *cnf;
1456  int hr, min, sec;
1457  int total = 0;
1458  time_t now;
1459 #define MC_HEADER_FORMAT "%-14s %-14s %-10s %-8s %-8s %-6s\n"
1460 #define MC_DATA_FORMAT "%-12.12s %4.4d %4.4s %02d:%02d:%02d %-8s %-6s\n"
1461 
1462  switch (cmd) {
1463  case CLI_INIT:
1464  e->command = "meetme list";
1465  e->usage =
1466  "Usage: meetme list [<confno>] [" STR_CONCISE "]\n"
1467  " List all conferences or a specific conference.\n";
1468  return NULL;
1469  case CLI_GENERATE:
1470  return complete_meetmecmd_list(a->line, a->word, a->pos, a->n);
1471  }
1472 
1473  if (a->argc == 2 || (a->argc == 3 && !strcasecmp(a->argv[2], STR_CONCISE))) {
1474  /* List all the conferences */
1475  int concise = (a->argc == 3);
1476  struct ast_str *marked_users;
1477 
1478  if (!(marked_users = ast_str_create(30))) {
1479  return CLI_FAILURE;
1480  }
1481 
1482  now = time(NULL);
1483  AST_LIST_LOCK(&confs);
1484  if (AST_LIST_EMPTY(&confs)) {
1485  if (!concise) {
1486  ast_cli(a->fd, "No active MeetMe conferences.\n");
1487  }
1489  ast_free(marked_users);
1490  return CLI_SUCCESS;
1491  }
1492  if (!concise) {
1493  ast_cli(a->fd, MC_HEADER_FORMAT, "Conf Num", "Parties", "Marked", "Activity", "Creation", "Locked");
1494  }
1495  AST_LIST_TRAVERSE(&confs, cnf, list) {
1496  hr = (now - cnf->start) / 3600;
1497  min = ((now - cnf->start) % 3600) / 60;
1498  sec = (now - cnf->start) % 60;
1499  if (!concise) {
1500  if (cnf->markedusers == 0) {
1501  ast_str_set(&marked_users, 0, "N/A ");
1502  } else {
1503  ast_str_set(&marked_users, 0, "%4.4d", cnf->markedusers);
1504  }
1505  ast_cli(a->fd, MC_DATA_FORMAT, cnf->confno, cnf->users,
1506  ast_str_buffer(marked_users), hr, min, sec,
1507  cnf->isdynamic ? "Dynamic" : "Static", cnf->locked ? "Yes" : "No");
1508  } else {
1509  ast_cli(a->fd, "%s!%d!%d!%02d:%02d:%02d!%d!%d\n",
1510  cnf->confno,
1511  cnf->users,
1512  cnf->markedusers,
1513  hr, min, sec,
1514  cnf->isdynamic,
1515  cnf->locked);
1516  }
1517 
1518  total += cnf->users;
1519  }
1521  if (!concise) {
1522  ast_cli(a->fd, "* Total number of MeetMe users: %d\n", total);
1523  }
1524  ast_free(marked_users);
1525  return CLI_SUCCESS;
1526  }
1527  if (a->argc == 3 || (a->argc == 4 && !strcasecmp(a->argv[3], STR_CONCISE))) {
1528  struct ao2_iterator user_iter;
1529  int concise = (a->argc == 4);
1530 
1531  /* List all the users in a conference */
1532  if (AST_LIST_EMPTY(&confs)) {
1533  if (!concise) {
1534  ast_cli(a->fd, "No active MeetMe conferences.\n");
1535  }
1536  return CLI_SUCCESS;
1537  }
1538  /* Find the right conference */
1539  AST_LIST_LOCK(&confs);
1540  AST_LIST_TRAVERSE(&confs, cnf, list) {
1541  if (strcmp(cnf->confno, a->argv[2]) == 0) {
1542  break;
1543  }
1544  }
1545  if (!cnf) {
1546  if (!concise)
1547  ast_cli(a->fd, "No such conference: %s.\n", a->argv[2]);
1549  return CLI_SUCCESS;
1550  }
1551  /* Show all the users */
1552  time(&now);
1553  user_iter = ao2_iterator_init(cnf->usercontainer, 0);
1554  while((user = ao2_iterator_next(&user_iter))) {
1555  hr = (now - user->jointime) / 3600;
1556  min = ((now - user->jointime) % 3600) / 60;
1557  sec = (now - user->jointime) % 60;
1558  if (!concise) {
1559  ast_cli(a->fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %s %02d:%02d:%02d\n",
1560  user->user_no,
1561  S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, "<unknown>"),
1562  S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, "<no name>"),
1563  user->chan->name,
1564  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "(Admin)" : "",
1565  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "(Listen only)" : "",
1566  user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : user->adminflags & ADMINFLAG_SELFMUTED ? "(Muted)" : "",
1567  user->adminflags & ADMINFLAG_T_REQUEST ? "(Request to Talk)" : "",
1568  istalking(user->talking), hr, min, sec);
1569  } else {
1570  ast_cli(a->fd, "%d!%s!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
1571  user->user_no,
1572  S_COR(user->chan->caller.id.number.valid, user->chan->caller.id.number.str, ""),
1573  S_COR(user->chan->caller.id.name.valid, user->chan->caller.id.name.str, ""),
1574  user->chan->name,
1575  ast_test_flag64(&user->userflags, CONFFLAG_ADMIN) ? "1" : "",
1576  ast_test_flag64(&user->userflags, CONFFLAG_MONITOR) ? "1" : "",
1577  user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED) ? "1" : "",
1578  user->adminflags & ADMINFLAG_T_REQUEST ? "1" : "",
1579  user->talking, hr, min, sec);
1580  }
1581  ao2_ref(user, -1);
1582  }
1583  ao2_iterator_destroy(&user_iter);
1584  if (!concise) {
1585  ast_cli(a->fd, "%d users in that conference.\n", cnf->users);
1586  }
1588  return CLI_SUCCESS;
1589  }
1590  return CLI_SHOWUSAGE;
1591 }
static char user[512]
static char * complete_meetmecmd_list(const char *line, const char *word, int pos, int state)
Definition: app_meetme.c:1412
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define STR_CONCISE
Definition: app_meetme.c:526
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
static const char * istalking(int x)
Definition: app_meetme.c:1006
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
unsigned int isdynamic
Definition: app_meetme.c:729
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
Definition: cli.h:146
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
unsigned int locked
Definition: app_meetme.c:731
const char * line
Definition: cli.h:156
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:874
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#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:83
const char *const * argv
Definition: cli.h:155
struct ast_flags64 userflags
Definition: app_meetme.c:771
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define CLI_SHOWUSAGE
Definition: cli.h:44
const ast_string_field name
Definition: channel.h:787
#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:45
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
#define MC_HEADER_FORMAT
const char * word
Definition: cli.h:157
struct ao2_container * usercontainer
Definition: app_meetme.c:748
time_t jointime
Definition: app_meetme.c:778
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
const int pos
Definition: cli.h:158
static int total
Definition: res_adsi.c:967
#define MC_DATA_FORMAT
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
The MeetMe Conference object.
Definition: app_meetme.c:715
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_channel * chan
Definition: app_meetme.c:773
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int meetmemute ( struct mansession s,
const struct message m,
int  mute 
)
static

Definition at line 5035 of file app_meetme.c.

References ADMINFLAG_MUTED, ADMINFLAG_SELFMUTED, ADMINFLAG_T_REQUEST, ast_conf_user::adminflags, ao2_find, ao2_ref, 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, ast_channel::name, ast_channel::uniqueid, user, ast_conf_user::user_no, and ast_conference::usercontainer.

Referenced by action_meetmemute(), and action_meetmeunmute().

5036 {
5037  struct ast_conference *conf;
5038  struct ast_conf_user *user;
5039  const char *confid = astman_get_header(m, "Meetme");
5040  char *userid = ast_strdupa(astman_get_header(m, "Usernum"));
5041  int userno;
5042 
5043  if (ast_strlen_zero(confid)) {
5044  astman_send_error(s, m, "Meetme conference not specified");
5045  return 0;
5046  }
5047 
5048  if (ast_strlen_zero(userid)) {
5049  astman_send_error(s, m, "Meetme user number not specified");
5050  return 0;
5051  }
5052 
5053  userno = strtoul(userid, &userid, 10);
5054 
5055  if (*userid) {
5056  astman_send_error(s, m, "Invalid user number");
5057  return 0;
5058  }
5059 
5060  /* Look in the conference list */
5061  AST_LIST_LOCK(&confs);
5062  AST_LIST_TRAVERSE(&confs, conf, list) {
5063  if (!strcmp(confid, conf->confno))
5064  break;
5065  }
5066 
5067  if (!conf) {
5069  astman_send_error(s, m, "Meetme conference does not exist");
5070  return 0;
5071  }
5072 
5073  user = ao2_find(conf->usercontainer, &userno, 0);
5074 
5075  if (!user) {
5077  astman_send_error(s, m, "User number not found");
5078  return 0;
5079  }
5080 
5081  if (mute)
5082  user->adminflags |= ADMINFLAG_MUTED; /* request user muting */
5083  else
5084  user->adminflags &= ~(ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED | ADMINFLAG_T_REQUEST); /* request user unmuting */
5085 
5087 
5088  ast_log(LOG_NOTICE, "Requested to %smute conf %s user %d userchan %s uniqueid %s\n", mute ? "" : "un", conf->confno, user->user_no, user->chan->name, user->chan->uniqueid);
5089 
5090  ao2_ref(user, -1);
5091  astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
5092  return 0;
5093 }
static char user[512]
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const ast_string_field uniqueid
Definition: channel.h:787
#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:2135
static int mute
Definition: chan_alsa.c:135
struct ast_conf_user::@34 list
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The MeetMe User object.
Definition: app_meetme.c:769
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
struct ao2_container * usercontainer
Definition: app_meetme.c:748
The MeetMe Conference object.
Definition: app_meetme.c:715
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
struct ast_channel * chan
Definition: app_meetme.c:773
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static enum ast_device_state meetmestate ( const char *  data)
static

Callback for devicestate providers.

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

5275 {
5276  struct ast_conference *conf;
5277 
5278  /* Find conference */
5279  AST_LIST_LOCK(&confs);
5280  AST_LIST_TRAVERSE(&confs, conf, list) {
5281  if (!strcmp(data, conf->confno))
5282  break;
5283  }
5285  if (!conf)
5286  return AST_DEVICE_INVALID;
5287 
5288 
5289  /* SKREP to fill */
5290  if (!conf->users)
5291  return AST_DEVICE_NOT_INUSE;
5292 
5293  return AST_DEVICE_INUSE;
5294 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct ast_conference::@32 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#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:715
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static struct sla_ringing_trunk* queue_ringing_trunk ( struct sla_trunk trunk)
static

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

6706 {
6707  struct sla_ringing_trunk *ringing_trunk;
6708 
6709  if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk)))) {
6710  return NULL;
6711  }
6712 
6713  ao2_ref(trunk, 1);
6714  ringing_trunk->trunk = trunk;
6715  ringing_trunk->ring_begin = ast_tvnow();
6716 
6718 
6719  ast_mutex_lock(&sla.lock);
6720  AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
6721  ast_mutex_unlock(&sla.lock);
6722 
6724 
6725  return ringing_trunk;
6726 }
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:5552
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2049
struct timeval ring_begin
Definition: app_meetme.c:939
A trunk that is ringing.
Definition: app_meetme.c:936
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_trunk * trunk
Definition: app_meetme.c:937
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_calloc(a, b)
Definition: astmm.h:82
struct sla_ringing_trunk::@41 entry
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void * recordthread ( void *  args)
static

Definition at line 5205 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(), f, filename_parse(), ast_frame::flags, ast_frame::frametype, ast_conference::lchan, ast_conference::listenlock, MEETME_RECORD_ACTIVE, MEETME_RECORD_OFF, MEETME_RECORD_TERMINATE, ast_conference::origframe, ast_conference::recordingfilename, ast_conference::recordingformat, and ast_conference::transframe.

5206 {
5207  struct ast_conference *cnf = args;
5208  struct ast_frame *f = NULL;
5209  int flags;
5210  struct ast_filestream *s = NULL;
5211  int res = 0;
5212  int x;
5213  const char *oldrecordingfilename = NULL;
5214  char filename_buffer[PATH_MAX];
5215 
5216  if (!cnf || !cnf->lchan) {
5217  pthread_exit(0);
5218  }
5219 
5220  filename_buffer[0] = '\0';
5221  filename_parse(cnf->recordingfilename, filename_buffer);
5222 
5223  ast_stopstream(cnf->lchan);
5224  flags = O_CREAT | O_TRUNC | O_WRONLY;
5225 
5226 
5227  cnf->recording = MEETME_RECORD_ACTIVE;
5228  while (ast_waitfor(cnf->lchan, -1) > -1) {
5229  if (cnf->recording == MEETME_RECORD_TERMINATE) {
5230  AST_LIST_LOCK(&confs);
5232  break;
5233  }
5234  if (!s && !(ast_strlen_zero(filename_buffer)) && (filename_buffer != oldrecordingfilename)) {
5235  s = ast_writefile(filename_buffer, cnf->recordingformat, NULL, flags, 0, AST_FILE_MODE);
5236  oldrecordingfilename = filename_buffer;
5237  }
5238 
5239  f = ast_read(cnf->lchan);
5240  if (!f) {
5241  res = -1;
5242  break;
5243  }
5244  if (f->frametype == AST_FRAME_VOICE) {
5245  ast_mutex_lock(&cnf->listenlock);
5246  for (x = 0; x < AST_FRAME_BITS; x++) {
5247  /* Free any translations that have occured */
5248  if (cnf->transframe[x]) {
5249  ast_frfree(cnf->transframe[x]);
5250  cnf->transframe[x] = NULL;
5251  }
5252  }
5253  if (cnf->origframe)
5254  ast_frfree(cnf->origframe);
5255  cnf->origframe = ast_frdup(f);
5257  if (s)
5258  res = ast_writestream(s, f);
5259  if (res) {
5260  ast_frfree(f);
5261  break;
5262  }
5263  }
5264  ast_frfree(f);
5265  }
5266  cnf->recording = MEETME_RECORD_OFF;
5267  if (s)
5268  ast_closestream(s);
5269 
5270  pthread_exit(0);
5271 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_FRAME_BITS
Definition: app_meetme.c:545
struct ast_frame * origframe
Definition: app_meetme.c:746
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * recordingformat
Definition: app_meetme.c:737
struct ast_frame * transframe[32]
Definition: app_meetme.c:745
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
ast_mutex_t listenlock
Definition: app_meetme.c:717
#define ast_mutex_lock(a)
Definition: lock.h:155
#define AST_FILE_MODE
Definition: asterisk.h:36
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct @350 args
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:1049
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:904
unsigned int flags
Definition: frame.h:166
static struct ast_format f[]
Definition: format_g726.c:181
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:100
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:150
Data structure associated with a single frame of data.
Definition: frame.h:142
char * recordingfilename
Definition: app_meetme.c:736
struct ast_channel * lchan
Definition: app_meetme.c:720
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
The MeetMe Conference object.
Definition: app_meetme.c:715
static void filename_parse(char *filename, char *buffer)
Definition: app_meetme.c:5186
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int reload ( void  )
static

Definition at line 7781 of file app_meetme.c.

References ast_unload_realtime(), and load_config().

7782 {
7783  ast_unload_realtime("meetme");
7784  return load_config(1);
7785 }
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: config.c:2630
static int load_config(int reload)
Definition: app_meetme.c:7535
static void reset_volumes ( struct ast_conf_user user)
static

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

1127 {
1128  signed char zero_volume = 0;
1129 
1130  ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
1131  ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &zero_volume, sizeof(zero_volume), 0);
1132 }
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:7795
#define AST_OPTION_RXGAIN
Definition: frame.h:463
struct ast_channel * chan
Definition: app_meetme.c:773
#define AST_OPTION_TXGAIN
Definition: frame.h:458
static int rt_extend_conf ( const char *  confno)
static

Definition at line 2116 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, ast_variable::value, and var.

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

2117 {
2118  char currenttime[32];
2119  char endtime[32];
2120  struct timeval now;
2121  struct ast_tm tm;
2122  struct ast_variable *var, *orig_var;
2123  char bookid[51];
2124 
2125  if (!extendby) {
2126  return 0;
2127  }
2128 
2129  now = ast_tvnow();
2130 
2131  ast_localtime(&now, &tm, NULL);
2132  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
2133 
2134  var = ast_load_realtime("meetme", "confno",
2135  confno, "startTime<= ", currenttime,
2136  "endtime>= ", currenttime, NULL);
2137 
2138  orig_var = var;
2139 
2140  /* Identify the specific RealTime conference */
2141  while (var) {
2142  if (!strcasecmp(var->name, "bookid")) {
2143  ast_copy_string(bookid, var->value, sizeof(bookid));
2144  }
2145  if (!strcasecmp(var->name, "endtime")) {
2146  ast_copy_string(endtime, var->value, sizeof(endtime));
2147  }
2148 
2149  var = var->next;
2150  }
2151  ast_variables_destroy(orig_var);
2152 
2153  ast_strptime(endtime, DATE_FORMAT, &tm);
2154  now = ast_mktime(&tm, NULL);
2155 
2156  now.tv_sec += extendby;
2157 
2158  ast_localtime(&now, &tm, NULL);
2159  ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm);
2160  strcat(currenttime, "0"); /* Seconds needs to be 00 */
2161 
2162  var = ast_load_realtime("meetme", "confno",
2163  confno, "startTime<= ", currenttime,
2164  "endtime>= ", currenttime, NULL);
2165 
2166  /* If there is no conflict with extending the conference, update the DB */
2167  if (!var) {
2168  ast_debug(3, "Trying to update the endtime of Conference %s to %s\n", confno, currenttime);
2169  ast_update_realtime("meetme", "bookid", bookid, "endtime", currenttime, NULL);
2170  return 0;
2171 
2172  }
2173 
2174  ast_variables_destroy(var);
2175  return -1;
2176 }
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:1570
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: config.c:2679
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
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:2377
#define DATE_FORMAT
Definition: app_meetme.c:532
static int extendby
Definition: app_meetme.c:688
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:2351
struct timeval ast_mktime(struct ast_tm *const tmp, const char *zone)
Timezone-independent version of mktime(3).
Definition: localtime.c:2185
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
static void* run_station ( void *  data)
static

Definition at line 5591 of file app_meetme.c.

References sla_trunk::active_stations, admin_exec(), ALL_TRUNK_REFS, answer_trunk_chan(), args, 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, RAII_VAR, sla_change_trunk_state(), 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().

5592 {
5593  RAII_VAR(struct sla_station *, station, NULL, unref_obj);
5594  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
5595  struct ast_str *conf_name = ast_str_create(16);
5596  struct ast_flags64 conf_flags = { 0 };
5597  struct ast_conference *conf;
5598 
5599  {
5600  struct run_station_args *args = data;
5601  station = args->station;
5602  trunk_ref = args->trunk_ref;
5603  ast_mutex_lock(args->cond_lock);
5604  ast_cond_signal(args->cond);
5605  ast_mutex_unlock(args->cond_lock);
5606  /* args is no longer valid here. */
5607  }
5608 
5610  ast_str_set(&conf_name, 0, "SLA_%s", trunk_ref->trunk->name);
5611  ast_set_flag64(&conf_flags,
5614  conf = build_conf(ast_str_buffer(conf_name), "", "", 0, 0, 1, trunk_ref->chan, NULL);
5615  if (conf) {
5616  conf_run(trunk_ref->chan, conf, &conf_flags, NULL);
5617  dispose_conf(conf);
5618  conf = NULL;
5619  }
5620  trunk_ref->chan = NULL;
5623  ast_str_append(&conf_name, 0, ",K");
5624  admin_exec(NULL, ast_str_buffer(conf_name));
5627  }
5628 
5631  station->dial = NULL;
5632  ast_free(conf_name);
5633 
5634  return NULL;
5635 }
const ast_string_field name
Definition: app_meetme.c:859
unsigned int active_stations
Definition: app_meetme.c:864
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:5580
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
struct sla_trunk * trunk
Definition: app_meetme.c:890
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
ast_mutex_t * cond_lock
Definition: app_meetme.c:5581
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:5552
struct ast_dial * dial
Definition: app_meetme.c:823
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:900
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:1213
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:155
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:5585
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define ast_cond_signal(cond)
Definition: lock.h:169
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
enum sla_trunk_state state
Definition: app_meetme.c:891
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:2759
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:874
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
#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:915
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0. Useful e.g. to check if a refcount h...
Definition: lock.h:649
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
struct ast_channel * chan
Definition: app_meetme.c:892
static struct @350 args
#define ast_free(a)
Definition: astmm.h:97
ast_cond_t * cond
Definition: app_meetme.c:5582
unsigned int hold_stations
Definition: app_meetme.c:866
struct sla_station * station
Definition: app_meetme.c:5579
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:4807
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
The MeetMe Conference object.
Definition: app_meetme.c:715
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void send_talking_event ( struct ast_channel chan,
struct ast_conference conf,
struct ast_conf_user user,
int  talking 
)
static

Definition at line 2270 of file app_meetme.c.

References ast_manager_event, ast_conference::confno, EVENT_FLAG_CALL, ast_channel::name, ast_channel::uniqueid, and ast_conf_user::user_no.

Referenced by set_user_talking().

2271 {
2272  ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalking",
2273  "Channel: %s\r\n"
2274  "Uniqueid: %s\r\n"
2275  "Meetme: %s\r\n"
2276  "Usernum: %d\r\n"
2277  "Status: %s\r\n",
2278  chan->name, chan->uniqueid, conf->confno, user->user_no, talking ? "on" : "off");
2279 }
const ast_string_field uniqueid
Definition: channel.h:787
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
const ast_string_field name
Definition: channel.h:787
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
static int set_listen_volume ( struct ast_conf_user user,
int  volume 
)
static

Definition at line 1055 of file app_meetme.c.

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

Referenced by tweak_listen_volume().

1056 {
1057  char gain_adjust;
1058 
1059  /* attempt to make the adjustment in the channel driver;
1060  if successful, don't adjust in the frame reading routine
1061  */
1062  gain_adjust = gain_map[volume + 5];
1063 
1064  return ast_channel_setoption(user->chan, AST_OPTION_TXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
1065 }
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:7795
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:988
struct ast_channel * chan
Definition: app_meetme.c:773
#define AST_OPTION_TXGAIN
Definition: frame.h:458
static int set_talk_volume ( struct ast_conf_user user,
int  volume 
)
static

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

1044 {
1045  char gain_adjust;
1046 
1047  /* attempt to make the adjustment in the channel driver;
1048  if successful, don't adjust in the frame reading routine
1049  */
1050  gain_adjust = gain_map[volume + 5];
1051 
1052  return ast_channel_setoption(user->chan, AST_OPTION_RXGAIN, &gain_adjust, sizeof(gain_adjust), 0);
1053 }
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:7795
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:988
#define AST_OPTION_RXGAIN
Definition: frame.h:463
struct ast_channel * chan
Definition: app_meetme.c:773
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 2281 of file app_meetme.c.

References send_talking_event(), and ast_conf_user::talking.

Referenced by conf_run().

2282 {
2283  int last_talking = user->talking;
2284  if (last_talking == talking)
2285  return;
2286 
2287  user->talking = talking;
2288 
2289  if (monitor) {
2290  /* Check if talking state changed. Take care of -1 which means unmonitored */
2291  int was_talking = (last_talking > 0);
2292  int now_talking = (talking > 0);
2293  if (was_talking != now_talking) {
2294  send_talking_event(chan, conf, user, now_talking);
2295  }
2296  }
2297 }
static void send_talking_event(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking)
Definition: app_meetme.c:2270
static unsigned int monitor
Definition: chan_phone.c:108
static void sla_add_trunk_to_station ( struct sla_station station,
struct ast_variable var 
)
static

Definition at line 7100 of file app_meetme.c.

References 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, sla_trunk::name, sla_trunk::num_stations, 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, sla_trunk::stations, strsep(), sla_trunk_ref::trunk, sla_station::trunks, value, and ast_variable::value.

Referenced by sla_build_station().

7101 {
7102  RAII_VAR(struct sla_trunk *, trunk, NULL, unref_obj);
7103  struct sla_trunk_ref *trunk_ref = NULL;
7104  struct sla_station_ref *station_ref;
7105  char *trunk_name, *options, *cur;
7106  int existing_trunk_ref = 0;
7107  int existing_station_ref = 0;
7108 
7109  options = ast_strdupa(var->value);
7110  trunk_name = strsep(&options, ",");
7111 
7112  trunk = sla_find_trunk(trunk_name);
7113  if (!trunk) {
7114  ast_log(LOG_ERROR, "Trunk '%s' not found!\n", var->value);
7115  return;
7116  }
7117 
7118  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7119  if (trunk_ref->trunk == trunk) {
7120  trunk_ref->mark = 0;
7121  existing_trunk_ref = 1;
7122  break;
7123  }
7124  }
7125 
7126  if (!trunk_ref && !(trunk_ref = create_trunk_ref(trunk))) {
7127  return;
7128  }
7129 
7130  trunk_ref->state = SLA_TRUNK_STATE_IDLE;
7131 
7132  while ((cur = strsep(&options, ","))) {
7133  char *name, *value = cur;
7134  name = strsep(&value, "=");
7135  if (!strcasecmp(name, "ringtimeout")) {
7136  if (sscanf(value, "%30u", &trunk_ref->ring_timeout) != 1) {
7137  ast_log(LOG_WARNING, "Invalid ringtimeout value '%s' for "
7138  "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
7139  trunk_ref->ring_timeout = 0;
7140  }
7141  } else if (!strcasecmp(name, "ringdelay")) {
7142  if (sscanf(value, "%30u", &trunk_ref->ring_delay) != 1) {
7143  ast_log(LOG_WARNING, "Invalid ringdelay value '%s' for "
7144  "trunk '%s' on station '%s'\n", value, trunk->name, station->name);
7145  trunk_ref->ring_delay = 0;
7146  }
7147  } else {
7148  ast_log(LOG_WARNING, "Invalid option '%s' for "
7149  "trunk '%s' on station '%s'\n", name, trunk->name, station->name);
7150  }
7151  }
7152 
7153  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
7154  if (station_ref->station == station) {
7155  station_ref->mark = 0;
7156  existing_station_ref = 1;
7157  break;
7158  }
7159  }
7160 
7161  if (!station_ref && !(station_ref = sla_create_station_ref(station))) {
7162  if (!existing_trunk_ref) {
7163  ao2_ref(trunk_ref, -1);
7164  } else {
7165  trunk_ref->mark = 1;
7166  }
7167  return;
7168  }
7169 
7170  if (!existing_station_ref) {
7171  ao2_lock(trunk);
7172  AST_LIST_INSERT_TAIL(&trunk->stations, station_ref, entry);
7173  ast_atomic_fetchadd_int((int *) &trunk->num_stations, 1);
7174  ao2_unlock(trunk);
7175  }
7176 
7177  if (!existing_trunk_ref) {
7178  ao2_lock(station);
7179  AST_LIST_INSERT_TAIL(&station->trunks, trunk_ref, entry);
7180  ao2_unlock(station);
7181  }
7182 }
char * strsep(char **str, const char *delims)
unsigned int ring_timeout
Definition: app_meetme.c:896
unsigned int mark
Definition: app_meetme.c:902
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define LOG_WARNING
Definition: logger.h:144
A reference to a station.
Definition: app_meetme.c:847
#define ao2_unlock(a)
Definition: astobj2.h:497
int value
Definition: syslog.c:39
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
enum sla_trunk_state state
Definition: app_meetme.c:891
const char * value
Definition: config.h:79
#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:915
struct sla_station_ref::@35 entry
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct sla_station_ref * sla_create_station_ref(struct sla_station *station)
Definition: app_meetme.c:5472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct sla_trunk_ref * create_trunk_ref(struct sla_trunk *trunk)
Definition: app_meetme.c:6691
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
unsigned int mark
Definition: app_meetme.c:851
unsigned int ring_delay
Definition: app_meetme.c:900
struct sla_station * station
Definition: app_meetme.c:849
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5381
static int sla_build_station ( struct ast_config cfg,
const char *  cat 
)
static

Definition at line 7184 of file app_meetme.c.

References ao2_alloc, ao2_link, ao2_lock, ao2_unlock, ast_add_extension2(), 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(), context, exten, sla_station::hold_access, ast_variable::lineno, LOG_ERROR, LOG_WARNING, sla_station::mark, ast_variable::name, sla_trunk::name, ast_variable::next, PRIORITY_HINT, RAII_VAR, sla_station::ring_delay, sla_station::ring_timeout, sla_add_trunk_to_station(), SLA_CONFIG_FILE, sla_find_station(), SLA_HOLD_OPEN, SLA_HOLD_PRIVATE, sla_registrar, sla_station_destructor(), sla_stations, sla_trunk_ref::trunk, sla_station::trunks, ast_variable::value, and var.

Referenced by sla_load_config().

7185 {
7186  RAII_VAR(struct sla_station *, station, NULL, unref_obj);
7187  struct ast_variable *var;
7188  const char *dev;
7189  int existing_station = 0;
7190 
7191  if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
7192  ast_log(LOG_ERROR, "SLA Station '%s' defined with no device!\n", cat);
7193  return -1;
7194  }
7195 
7196  if ((station = sla_find_station(cat))) {
7197  station->mark = 0;
7198  existing_station = 1;
7199  } else if ((station = ao2_alloc(sizeof(*station), sla_station_destructor))) {
7200  if (ast_string_field_init(station, 32)) {
7201  return -1;
7202  }
7203  ast_string_field_set(station, name, cat);
7204  } else {
7205  return -1;
7206  }
7207 
7208  ao2_lock(station);
7209 
7210  ast_string_field_set(station, device, dev);
7211 
7212  for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
7213  if (!strcasecmp(var->name, "trunk")) {
7214  ao2_unlock(station);
7215  sla_add_trunk_to_station(station, var);
7216  ao2_lock(station);
7217  } else if (!strcasecmp(var->name, "autocontext")) {
7218  ast_string_field_set(station, autocontext, var->value);
7219  } else if (!strcasecmp(var->name, "ringtimeout")) {
7220  if (sscanf(var->value, "%30u", &station->ring_timeout) != 1) {
7221  ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for station '%s'\n",
7222  var->value, station->name);
7223  station->ring_timeout = 0;
7224  }
7225  } else if (!strcasecmp(var->name, "ringdelay")) {
7226  if (sscanf(var->value, "%30u", &station->ring_delay) != 1) {
7227  ast_log(LOG_WARNING, "Invalid ringdelay '%s' specified for station '%s'\n",
7228  var->value, station->name);
7229  station->ring_delay = 0;
7230  }
7231  } else if (!strcasecmp(var->name, "hold")) {
7232  if (!strcasecmp(var->value, "private"))
7233  station->hold_access = SLA_HOLD_PRIVATE;
7234  else if (!strcasecmp(var->value, "open"))
7235  station->hold_access = SLA_HOLD_OPEN;
7236  else {
7237  ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n",
7238  var->value, station->name);
7239  }
7240 
7241  } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
7242  ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
7243  var->name, var->lineno, SLA_CONFIG_FILE);
7244  }
7245  }
7246 
7247  ao2_unlock(station);
7248 
7249  if (!ast_strlen_zero(station->autocontext)) {
7250  struct ast_context *context;
7251  struct sla_trunk_ref *trunk_ref;
7252  context = ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar);
7253  if (!context) {
7254  ast_log(LOG_ERROR, "Failed to automatically find or create "
7255  "context '%s' for SLA!\n", station->autocontext);
7256  return -1;
7257  }
7258  /* The extension for when the handset goes off-hook.
7259  * exten => station1,1,SLAStation(station1) */
7260  if (ast_add_extension2(context, 0 /* don't replace */, station->name, 1,
7261  NULL, NULL, slastation_app, ast_strdup(station->name), ast_free_ptr, sla_registrar)) {
7262  ast_log(LOG_ERROR, "Failed to automatically create extension "
7263  "for trunk '%s'!\n", station->name);
7264  return -1;
7265  }
7266  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7267  char exten[AST_MAX_EXTENSION];
7268  char hint[AST_MAX_APP];
7269  snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
7270  snprintf(hint, sizeof(hint), "SLA:%s", exten);
7271  /* Extension for this line button
7272  * exten => station1_line1,1,SLAStation(station1_line1) */
7273  if (ast_add_extension2(context, 0 /* don't replace */, exten, 1,
7274  NULL, NULL, slastation_app, ast_strdup(exten), ast_free_ptr, sla_registrar)) {
7275  ast_log(LOG_ERROR, "Failed to automatically create extension "
7276  "for trunk '%s'!\n", station->name);
7277  return -1;
7278  }
7279  /* Hint for this line button
7280  * exten => station1_line1,hint,SLA:station1_line1 */
7281  if (ast_add_extension2(context, 0 /* don't replace */, exten, PRIORITY_HINT,
7282  NULL, NULL, hint, NULL, NULL, sla_registrar)) {
7283  ast_log(LOG_ERROR, "Failed to automatically create hint "
7284  "for trunk '%s'!\n", station->name);
7285  return -1;
7286  }
7287  }
7288  }
7289 
7290  if (!existing_station) {
7291  ao2_link(sla_stations, station);
7292  }
7293 
7294  return 0;
7295 }
const ast_string_field name
Definition: app_meetme.c:859
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static void sla_add_trunk_to_station(struct sla_station *station, struct ast_variable *var)
Definition: app_meetme.c:7100
struct sla_trunk_ref::@37 entry
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ast_strdup(a)
Definition: astmm.h:109
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int ast_add_extension2(struct ast_context *con, 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 an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
int lineno
Definition: config.h:87
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static const char *const slastation_app
Definition: app_meetme.c:680
#define ao2_unlock(a)
Definition: astobj2.h:497
void ast_free_ptr(void *ptr)
static void sla_station_destructor(void *obj)
Definition: app_meetme.c:6903
const char * value
Definition: config.h:79
#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:915
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ao2_lock(a)
Definition: astobj2.h:488
const char * name
Definition: config.h:77
char name[0]
Definition: pbx.c:967
#define PRIORITY_HINT
Definition: pbx.h:53
#define LOG_ERROR
Definition: logger.h:155
#define AST_MAX_APP
Definition: pbx.h:39
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
#define SLA_CONFIG_FILE
Definition: app_meetme.c:525
static const char sla_registrar[]
Definition: app_meetme.c:908
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5394
struct ast_variable * next
Definition: config.h:82
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
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:7726
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
struct sla_station * station
Definition: app_meetme.c:849
ast_context: An extension context
Definition: pbx.c:955
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int sla_build_trunk ( struct ast_config cfg,
const char *  cat 
)
static

Definition at line 7011 of file app_meetme.c.

References ao2_alloc, ao2_link, ao2_lock, ao2_unlock, ast_add_extension2(), 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(), sla_trunk::autocontext, sla_trunk::barge_disabled, context, sla_trunk::hold_access, ast_variable::lineno, LOG_ERROR, LOG_WARNING, sla_trunk::mark, ast_variable::name, sla_trunk::name, ast_variable::next, RAII_VAR, sla_trunk::ring_timeout, sla_check_device(), SLA_CONFIG_FILE, sla_find_trunk(), SLA_HOLD_OPEN, SLA_HOLD_PRIVATE, sla_registrar, sla_trunk_destructor(), sla_trunks, ast_variable::value, and var.

Referenced by sla_load_config().

7012 {
7013  RAII_VAR(struct sla_trunk *, trunk, NULL, unref_obj);
7014  struct ast_variable *var;
7015  const char *dev;
7016  int existing_trunk = 0;
7017 
7018  if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
7019  ast_log(LOG_ERROR, "SLA Trunk '%s' defined with no device!\n", cat);
7020  return -1;
7021  }
7022 
7023  if (sla_check_device(dev)) {
7024  ast_log(LOG_ERROR, "SLA Trunk '%s' defined with invalid device '%s'!\n",
7025  cat, dev);
7026  return -1;
7027  }
7028 
7029  if ((trunk = sla_find_trunk(cat))) {
7030  trunk->mark = 0;
7031  existing_trunk = 1;
7032  } else if ((trunk = ao2_alloc(sizeof(*trunk), sla_trunk_destructor))) {
7033  if (ast_string_field_init(trunk, 32)) {
7034  return -1;
7035  }
7036  ast_string_field_set(trunk, name, cat);
7037  } else {
7038  return -1;
7039  }
7040 
7041  ao2_lock(trunk);
7042 
7043  ast_string_field_set(trunk, device, dev);
7044 
7045  for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
7046  if (!strcasecmp(var->name, "autocontext"))
7047  ast_string_field_set(trunk, autocontext, var->value);
7048  else if (!strcasecmp(var->name, "ringtimeout")) {
7049  if (sscanf(var->value, "%30u", &trunk->ring_timeout) != 1) {
7050  ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for trunk '%s'\n",
7051  var->value, trunk->name);
7052  trunk->ring_timeout = 0;
7053  }
7054  } else if (!strcasecmp(var->name, "barge"))
7055  trunk->barge_disabled = ast_false(var->value);
7056  else if (!strcasecmp(var->name, "hold")) {
7057  if (!strcasecmp(var->value, "private"))
7058  trunk->hold_access = SLA_HOLD_PRIVATE;
7059  else if (!strcasecmp(var->value, "open"))
7060  trunk->hold_access = SLA_HOLD_OPEN;
7061  else {
7062  ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n",
7063  var->value, trunk->name);
7064  }
7065  } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
7066  ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
7067  var->name, var->lineno, SLA_CONFIG_FILE);
7068  }
7069  }
7070 
7071  ao2_unlock(trunk);
7072 
7073  if (!ast_strlen_zero(trunk->autocontext)) {
7074  struct ast_context *context;
7075  context = ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar);
7076  if (!context) {
7077  ast_log(LOG_ERROR, "Failed to automatically find or create "
7078  "context '%s' for SLA!\n", trunk->autocontext);
7079  return -1;
7080  }
7081  if (ast_add_extension2(context, 0 /* don't replace */, "s", 1,
7082  NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free_ptr, sla_registrar)) {
7083  ast_log(LOG_ERROR, "Failed to automatically create extension "
7084  "for trunk '%s'!\n", trunk->name);
7085  return -1;
7086  }
7087  }
7088 
7089  if (!existing_trunk) {
7090  ao2_link(sla_trunks, trunk);
7091  }
7092 
7093  return 0;
7094 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ast_strdup(a)
Definition: astmm.h:109
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int ast_add_extension2(struct ast_context *con, 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 an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
int lineno
Definition: config.h:87
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
#define ao2_unlock(a)
Definition: astobj2.h:497
void ast_free_ptr(void *ptr)
const char * value
Definition: config.h:79
#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:915
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_lock(a)
Definition: astobj2.h:488
const char * name
Definition: config.h:77
static void sla_trunk_destructor(void *obj)
Definition: app_meetme.c:6996
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static int sla_check_device(const char *device)
Definition: app_meetme.c:6983
static const char name[]
static const char *const slatrunk_app
Definition: app_meetme.c:681
#define SLA_CONFIG_FILE
Definition: app_meetme.c:525
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
static const char sla_registrar[]
Definition: app_meetme.c:908
struct ast_variable * next
Definition: config.h:82
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
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:7726
ast_context: An extension context
Definition: pbx.c:955
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5381
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
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 6219 of file app_meetme.c.

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

Referenced by sla_process_timers().

6220 {
6221  struct sla_station *station;
6222  int res = 0;
6223  struct ao2_iterator i;
6224 
6226  for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
6227  struct sla_ringing_trunk *ringing_trunk;
6228  int time_left;
6229 
6230  /* Ignore stations already ringing */
6231  if (sla_check_ringing_station(station))
6232  continue;
6233 
6234  /* Ignore stations already on a call */
6235  if (sla_check_inuse_station(station))
6236  continue;
6237 
6238  /* Ignore stations that don't have one of their trunks ringing */
6239  if (!(ringing_trunk = sla_choose_ringing_trunk(station, NULL, 0)))
6240  continue;
6241 
6242  if ((time_left = sla_check_station_delay(station, ringing_trunk)) == INT_MAX)
6243  continue;
6244 
6245  /* If there is no time left, then the station needs to start ringing.
6246  * Return non-zero so that an event will be queued up an event to
6247  * make that happen. */
6248  if (time_left <= 0) {
6249  res = 1;
6250  continue;
6251  }
6252 
6253  if (time_left < *timeout)
6254  *timeout = time_left;
6255  }
6257 
6258  return res;
6259 }
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
static int sla_check_ringing_station(const struct sla_station *station)
Check to see if this station is already ringing.
Definition: app_meetme.c:5840
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:5970
A trunk that is ringing.
Definition: app_meetme.c:936
#define ao2_ref(o, delta)
Definition: astobj2.h:472
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:5719
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static int sla_check_inuse_station(const struct sla_station *station)
Check to see if a station is in use.
Definition: app_meetme.c:5938
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
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 6136 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().

6137 {
6138  struct sla_ringing_trunk *ringing_trunk;
6139  struct sla_ringing_station *ringing_station;
6140  int res = 0;
6141 
6142  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
6143  unsigned int ring_timeout = 0;
6144  int time_elapsed, time_left = INT_MAX, final_trunk_time_left = INT_MIN;
6145  struct sla_trunk_ref *trunk_ref;
6146 
6147  /* If there are any ring timeouts specified for a specific trunk
6148  * on the station, then use the highest per-trunk ring timeout.
6149  * Otherwise, use the ring timeout set for the entire station. */
6150  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
6151  struct sla_station_ref *station_ref;
6152  int trunk_time_elapsed, trunk_time_left;
6153 
6154  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6155  if (ringing_trunk->trunk == trunk_ref->trunk)
6156  break;
6157  }
6158  if (!ringing_trunk)
6159  continue;
6160 
6161  /* If there is a trunk that is ringing without a timeout, then the
6162  * only timeout that could matter is a global station ring timeout. */
6163  if (!trunk_ref->ring_timeout)
6164  break;
6165 
6166  /* This trunk on this station is ringing and has a timeout.
6167  * However, make sure this trunk isn't still ringing from a
6168  * previous timeout. If so, don't consider it. */
6169  AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, station_ref, entry) {
6170  if (station_ref->station == ringing_station->station)
6171  break;
6172  }
6173  if (station_ref)
6174  continue;
6175 
6176  trunk_time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
6177  trunk_time_left = (trunk_ref->ring_timeout * 1000) - trunk_time_elapsed;
6178  if (trunk_time_left > final_trunk_time_left)
6179  final_trunk_time_left = trunk_time_left;
6180  }
6181 
6182  /* No timeout was found for ringing trunks, and no timeout for the entire station */
6183  if (final_trunk_time_left == INT_MIN && !ringing_station->station->ring_timeout)
6184  continue;
6185 
6186  /* Compute how much time is left for a global station timeout */
6187  if (ringing_station->station->ring_timeout) {
6188  ring_timeout = ringing_station->station->ring_timeout;
6189  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
6190  time_left = (ring_timeout * 1000) - time_elapsed;
6191  }
6192 
6193  /* If the time left based on the per-trunk timeouts is smaller than the
6194  * global station ring timeout, use that. */
6195  if (final_trunk_time_left > INT_MIN && final_trunk_time_left < time_left)
6196  time_left = final_trunk_time_left;
6197 
6198  /* If there is no time left, the station needs to stop ringing */
6199  if (time_left <= 0) {
6202  res = 1;
6203  continue;
6204  }
6205 
6206  /* There is still some time left for this station to ring, so save that
6207  * timeout if it is the first event scheduled to occur */
6208  if (time_left < *timeout)
6209  *timeout = time_left;
6210  }
6212 
6213  return res;
6214 }
struct sla_trunk_ref::@37 entry
unsigned int ring_timeout
Definition: app_meetme.c:896
struct sla_trunk * trunk
Definition: app_meetme.c:890
struct sla_ringing_station::@42 entry
A station that is ringing.
Definition: app_meetme.c:950
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
A reference to a station.
Definition: app_meetme.c:847
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
struct timeval ring_begin
Definition: app_meetme.c:939
A trunk that is ringing.
Definition: app_meetme.c:936
struct sla_station_ref::@35 entry
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
struct timeval ring_begin
Definition: app_meetme.c:953
struct sla_trunk * trunk
Definition: app_meetme.c:937
#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:951
#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:888
unsigned int ring_timeout
Definition: app_meetme.c:827
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
Definition: app_meetme.c:5655
struct sla_ringing_trunk::@40 timed_out_stations
struct sla_station * station
Definition: app_meetme.c:849
static struct @28 sla
A structure for data used by the sla thread.
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 6106 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().

6107 {
6108  struct sla_ringing_trunk *ringing_trunk;
6109  int res = 0;
6110 
6111  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
6112  int time_left, time_elapsed;
6113  if (!ringing_trunk->trunk->ring_timeout)
6114  continue;
6115  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
6116  time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
6117  if (time_left <= 0) {
6118  pbx_builtin_setvar_helper(ringing_trunk->trunk->chan, "SLATRUNK_STATUS", "RINGTIMEOUT");
6120  sla_stop_ringing_trunk(ringing_trunk);
6121  res = 1;
6122  continue;
6123  }
6124  if (time_left < *timeout)
6125  *timeout = time_left;
6126  }
6128 
6129  return res;
6130 }
struct ast_channel * chan
Definition: app_meetme.c:867
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:5639
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
struct timeval ring_begin
Definition: app_meetme.c:939
A trunk that is ringing.
Definition: app_meetme.c:936
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
struct sla_trunk * trunk
Definition: app_meetme.c:937
unsigned int ring_timeout
Definition: app_meetme.c:868
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: pbx.c:10546
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct sla_ringing_trunk::@41 entry
static struct @28 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 
)
static

Definition at line 5552 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(), sla_stations, 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().

5554 {
5555  struct sla_station *station;
5556  struct sla_trunk_ref *trunk_ref;
5557  struct ao2_iterator i;
5558 
5560  while ((station = ao2_iterator_next(&i))) {
5561  ao2_lock(station);
5562  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
5563  if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0)
5564  || trunk_ref == exclude) {
5565  continue;
5566  }
5567  trunk_ref->state = state;
5569  "SLA:%s_%s", station->name, trunk->name);
5570  break;
5571  }
5572  ao2_unlock(station);
5573  ao2_ref(station, -1);
5574  }
5576 }
const ast_string_field name
Definition: app_meetme.c:859
enum sip_cc_notify_state state
Definition: chan_sip.c:842
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
Definition: app_meetme.c:5535
enum sla_trunk_state state
Definition: app_meetme.c:891
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:516
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
struct ast_channel * chan
Definition: app_meetme.c:892
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
static int sla_check_device ( const char *  device)
static

Definition at line 6983 of file app_meetme.c.

References ast_strdupa, ast_strlen_zero(), and strsep().

Referenced by sla_build_trunk().

6984 {
6985  char *tech, *tech_data;
6986 
6987  tech_data = ast_strdupa(device);
6988  tech = strsep(&tech_data, "/");
6989 
6990  if (ast_strlen_zero(tech) || ast_strlen_zero(tech_data))
6991  return -1;
6992 
6993  return 0;
6994 }
char * strsep(char **str, const char *delims)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
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 5855 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().

5856 {
5857  struct sla_failed_station *failed_station;
5858  int res = 0;
5859 
5860  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
5861  if (station != failed_station->station)
5862  continue;
5863  if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
5865  sla_failed_station_destroy(failed_station);
5866  break;
5867  }
5868  res = 1;
5869  }
5871 
5872  return res;
5873 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
struct sla_station * station
Definition: app_meetme.c:930
struct sla_failed_station::@39 entry
A station that failed to be dialed.
Definition: app_meetme.c:929
static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
Definition: app_meetme.c:5525
#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:931
static struct @28 sla
A structure for data used by the sla thread.
static int sla_check_inuse_station ( const struct sla_station station)
static

Check to see if a station is in use.

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

5939 {
5940  struct sla_trunk_ref *trunk_ref;
5941 
5942  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
5943  if (trunk_ref->chan)
5944  return 1;
5945  }
5946 
5947  return 0;
5948 }
struct sla_trunk_ref::@37 entry
struct ast_channel * chan
Definition: app_meetme.c:892
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
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 5840 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().

5841 {
5842  struct sla_ringing_station *ringing_station;
5843 
5844  AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_station, entry) {
5845  if (station == ringing_station->station)
5846  return 1;
5847  }
5848 
5849  return 0;
5850 }
struct sla_ringing_station::@42 entry
A station that is ringing.
Definition: app_meetme.c:950
#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:951
static struct @28 sla
A structure for data used by the sla thread.
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 5970 of file app_meetme.c.

References ast_tvdiff_ms(), ast_tvnow(), 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().

5972 {
5973  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
5974  unsigned int delay = UINT_MAX;
5975  int time_left, time_elapsed;
5976 
5977  if (!ringing_trunk)
5978  ringing_trunk = sla_choose_ringing_trunk(station, &trunk_ref, 0);
5979  else
5980  trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk);
5981 
5982  if (!ringing_trunk || !trunk_ref)
5983  return delay;
5984 
5985  /* If this station has a ring delay specific to the highest priority
5986  * ringing trunk, use that. Otherwise, use the ring delay specified
5987  * globally for the station. */
5988  delay = trunk_ref->ring_delay;
5989  if (!delay)
5990  delay = station->ring_delay;
5991  if (!delay)
5992  return INT_MAX;
5993 
5994  time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
5995  time_left = (delay * 1000) - time_elapsed;
5996 
5997  return time_left;
5998 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
unsigned int ring_delay
Definition: app_meetme.c:831
struct timeval ring_begin
Definition: app_meetme.c:939
#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:915
struct sla_trunk * trunk
Definition: app_meetme.c:937
static struct sla_trunk_ref * sla_find_trunk_ref(const struct sla_station *station, const struct sla_trunk *trunk)
Definition: app_meetme.c:5950
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:5719
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static int sla_check_station_hold_access ( const struct sla_trunk trunk,
const struct sla_station station 
)
static

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

5405 {
5406  struct sla_station_ref *station_ref;
5407  struct sla_trunk_ref *trunk_ref;
5408 
5409  /* For each station that has this call on hold, check for private hold. */
5410  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
5411  AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
5412  if (trunk_ref->trunk != trunk || station_ref->station == station)
5413  continue;
5414  if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME &&
5415  station_ref->station->hold_access == SLA_HOLD_PRIVATE)
5416  return 1;
5417  return 0;
5418  }
5419  }
5420 
5421  return 0;
5422 }
struct sla_trunk_ref::@37 entry
struct sla_trunk * trunk
Definition: app_meetme.c:890
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
unsigned int hold_access
Definition: app_meetme.c:834
enum sla_trunk_state state
Definition: app_meetme.c:891
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
struct sla_station * station
Definition: app_meetme.c:849
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 5698 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().

5700 {
5701  struct sla_station_ref *timed_out_station;
5702 
5703  AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, timed_out_station, entry) {
5704  if (station == timed_out_station->station)
5705  return 1;
5706  }
5707 
5708  return 0;
5709 }
A reference to a station.
Definition: app_meetme.c:847
struct sla_station_ref::@35 entry
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct sla_ringing_trunk::@40 timed_out_stations
struct sla_station * station
Definition: app_meetme.c:849
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 6515 of file app_meetme.c.

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

Referenced by sla_station_exec().

6516 {
6517  struct sla_trunk_ref *trunk_ref = NULL;
6518 
6519  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6520  if (trunk_ref->state == SLA_TRUNK_STATE_IDLE) {
6521  ao2_ref(trunk_ref, 1);
6522  break;
6523  }
6524  }
6525 
6526  return trunk_ref;
6527 }
struct sla_trunk_ref::@37 entry
enum sla_trunk_state state
Definition: app_meetme.c:891
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
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 5719 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, 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().

5721 {
5722  struct sla_trunk_ref *s_trunk_ref;
5723  struct sla_ringing_trunk *ringing_trunk = NULL;
5724 
5725  AST_LIST_TRAVERSE(&station->trunks, s_trunk_ref, entry) {
5726  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
5727  /* Make sure this is the trunk we're looking for */
5728  if (s_trunk_ref->trunk != ringing_trunk->trunk)
5729  continue;
5730 
5731  /* This trunk on the station is ringing. But, make sure this station
5732  * didn't already time out while this trunk was ringing. */
5733  if (sla_check_timed_out_station(ringing_trunk, station))
5734  continue;
5735 
5736  if (rm)
5738 
5739  if (trunk_ref) {
5740  ao2_ref(s_trunk_ref, 1);
5741  *trunk_ref = s_trunk_ref;
5742  }
5743 
5744  break;
5745  }
5747 
5748  if (ringing_trunk)
5749  break;
5750  }
5751 
5752  return ringing_trunk;
5753 }
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
A trunk that is ringing.
Definition: app_meetme.c:936
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_trunk * trunk
Definition: app_meetme.c:937
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#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:888
struct sla_ringing_trunk::@41 entry
static struct @28 sla
A structure for data used by the sla thread.
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:5698
static struct sla_failed_station* sla_create_failed_station ( struct sla_station station)
static

Definition at line 5510 of file app_meetme.c.

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

Referenced by sla_ring_station().

5511 {
5512  struct sla_failed_station *failed_station;
5513 
5514  if (!(failed_station = ast_calloc(1, sizeof(*failed_station)))) {
5515  return NULL;
5516  }
5517 
5518  ao2_ref(station, 1);
5519  failed_station->station = station;
5520  failed_station->last_try = ast_tvnow();
5521 
5522  return failed_station;
5523 }
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_station * station
Definition: app_meetme.c:930
#define ast_calloc(a, b)
Definition: astmm.h:82
A station that failed to be dialed.
Definition: app_meetme.c:929
struct timeval last_try
Definition: app_meetme.c:931
static struct sla_ringing_station* sla_create_ringing_station ( struct sla_station station)
static

Definition at line 5486 of file app_meetme.c.

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

Referenced by sla_ring_station().

5487 {
5488  struct sla_ringing_station *ringing_station;
5489 
5490  if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station))))
5491  return NULL;
5492 
5493  ao2_ref(station, 1);
5494  ringing_station->station = station;
5495  ringing_station->ring_begin = ast_tvnow();
5496 
5497  return ringing_station;
5498 }
A station that is ringing.
Definition: app_meetme.c:950
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct timeval ring_begin
Definition: app_meetme.c:953
struct sla_station * station
Definition: app_meetme.c:951
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct sla_station_ref* sla_create_station_ref ( struct sla_station station)
static

Definition at line 5472 of file app_meetme.c.

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

Referenced by sla_add_trunk_to_station(), and sla_stop_ringing_station().

5473 {
5474  struct sla_station_ref *station_ref;
5475 
5476  if (!(station_ref = ao2_alloc(sizeof(*station_ref), sla_station_ref_destructor))) {
5477  return NULL;
5478  }
5479 
5480  ao2_ref(station, 1);
5481  station_ref->station = station;
5482 
5483  return station_ref;
5484 }
A reference to a station.
Definition: app_meetme.c:847
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static void sla_station_ref_destructor(void *obj)
Definition: app_meetme.c:5462
struct sla_station * station
Definition: app_meetme.c:849
static void sla_destroy ( void  )
static

Definition at line 6957 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, sla, sla_registrar, sla_station_release_refs(), sla_stations, sla_trunk_release_refs(), and sla_trunks.

Referenced by unload_module().

6958 {
6959  if (sla.thread != AST_PTHREADT_NULL) {
6960  ast_mutex_lock(&sla.lock);
6961  sla.stop = 1;
6962  ast_cond_signal(&sla.cond);
6963  ast_mutex_unlock(&sla.lock);
6964  pthread_join(sla.thread, NULL);
6965  }
6966 
6967  /* Drop any created contexts from the dialplan */
6969 
6970  ast_mutex_destroy(&sla.lock);
6971  ast_cond_destroy(&sla.cond);
6972 
6975 
6976  ao2_ref(sla_trunks, -1);
6977  sla_trunks = NULL;
6978 
6979  ao2_ref(sla_stations, -1);
6980  sla_stations = NULL;
6981 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_cond_destroy(cond)
Definition: lock.h:168
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:6891
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context (or ANY context if NULL)
Definition: pbx.c:9875
static const char sla_registrar[]
Definition: app_meetme.c:908
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
#define ast_mutex_destroy(a)
Definition: lock.h:154
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:6879
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void sla_dial_state_callback ( struct ast_dial dial)
static

Definition at line 5690 of file app_meetme.c.

References SLA_EVENT_DIAL_STATE, and sla_queue_event().

Referenced by sla_ring_station().

5691 {
5693 }
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2049
static void sla_event_destroy ( struct sla_event event)
static

Definition at line 6298 of file app_meetme.c.

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

Referenced by sla_thread().

6299 {
6300  if (event->trunk_ref) {
6301  ao2_ref(event->trunk_ref, -1);
6302  event->trunk_ref = NULL;
6303  }
6304 
6305  if (event->station) {
6306  ao2_ref(event->station, -1);
6307  event->station = NULL;
6308  }
6309 
6310  ast_free(event);
6311 }
struct sla_station * station
Definition: app_meetme.c:922
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:923
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_free(a)
Definition: astmm.h:97
static void sla_failed_station_destroy ( struct sla_failed_station failed_station)
static

Definition at line 5525 of file app_meetme.c.

References ao2_ref, ast_free, and sla_failed_station::station.

Referenced by sla_check_failed_station(), and sla_thread().

5526 {
5527  if (failed_station->station) {
5528  ao2_ref(failed_station->station, -1);
5529  failed_station->station = NULL;
5530  }
5531 
5532  ast_free(failed_station);
5533 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_station * station
Definition: app_meetme.c:930
#define ast_free(a)
Definition: astmm.h:97
static struct sla_station* sla_find_station ( const char *  name)
static

Definition at line 5394 of file app_meetme.c.

References ao2_find, name, OBJ_POINTER, and sla_stations.

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

5395 {
5396  struct sla_station tmp_station = {
5397  .name = name,
5398  };
5399 
5400  return ao2_find(sla_stations, &tmp_station, OBJ_POINTER);
5401 }
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static const char name[]
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
static struct sla_trunk* sla_find_trunk ( const char *  name)
static

Definition at line 5381 of file app_meetme.c.

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

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

5382 {
5383  struct sla_trunk tmp_trunk = {
5384  .name = name,
5385  };
5386 
5387  return ao2_find(sla_trunks, &tmp_trunk, OBJ_POINTER);
5388 }
const ast_string_field name
Definition: app_meetme.c:859
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static const char name[]
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
static struct sla_trunk_ref* sla_find_trunk_ref ( const struct sla_station station,
const struct sla_trunk trunk 
)
static

Definition at line 5950 of file app_meetme.c.

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

Referenced by sla_check_station_delay().

5952 {
5953  struct sla_trunk_ref *trunk_ref = NULL;
5954 
5955  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
5956  if (trunk_ref->trunk == trunk)
5957  break;
5958  }
5959 
5960  ao2_ref(trunk_ref, 1);
5961 
5962  return trunk_ref;
5963 }
struct sla_trunk_ref::@37 entry
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
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 5433 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, 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().

5435 {
5436  struct sla_trunk_ref *trunk_ref = NULL;
5437 
5438  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
5439  if (strcasecmp(trunk_ref->trunk->name, name))
5440  continue;
5441 
5442  if ( (trunk_ref->trunk->barge_disabled
5443  && trunk_ref->state == SLA_TRUNK_STATE_UP) ||
5444  (trunk_ref->trunk->hold_stations
5445  && trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE
5446  && trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) ||
5447  sla_check_station_hold_access(trunk_ref->trunk, station) )
5448  {
5449  trunk_ref = NULL;
5450  }
5451 
5452  break;
5453  }
5454 
5455  if (trunk_ref) {
5456  ao2_ref(trunk_ref, 1);
5457  }
5458 
5459  return trunk_ref;
5460 }
const ast_string_field name
Definition: app_meetme.c:859
struct sla_trunk_ref::@37 entry
static int sla_check_station_hold_access(const struct sla_trunk *trunk, const struct sla_station *station)
Definition: app_meetme.c:5403
struct sla_trunk * trunk
Definition: app_meetme.c:890
enum sla_trunk_state state
Definition: app_meetme.c:891
#define ao2_ref(o, delta)
Definition: astobj2.h:472
unsigned int barge_disabled
Definition: app_meetme.c:871
unsigned int hold_access
Definition: app_meetme.c:874
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
unsigned int hold_stations
Definition: app_meetme.c:866
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static void sla_handle_dial_state_event ( void  )
static

Definition at line 5755 of file app_meetme.c.

References ALL_TRUNK_REFS, answer_trunk_chan(), 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, 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().

5756 {
5757  struct sla_ringing_station *ringing_station;
5758 
5759  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
5760  RAII_VAR(struct sla_trunk_ref *, s_trunk_ref, NULL, unref_obj);
5761  struct sla_ringing_trunk *ringing_trunk = NULL;
5762  struct run_station_args args;
5763  enum ast_dial_result dial_res;
5764  pthread_t dont_care;
5766  ast_cond_t cond;
5767 
5768  switch ((dial_res = ast_dial_state(ringing_station->station->dial))) {
5774  AST_LIST_REMOVE_CURRENT(entry);
5776  break;
5778  AST_LIST_REMOVE_CURRENT(entry);
5779  /* Find the appropriate trunk to answer. */
5780  ast_mutex_lock(&sla.lock);
5781  ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
5782  ast_mutex_unlock(&sla.lock);
5783  if (!ringing_trunk) {
5784  /* This case happens in a bit of a race condition. If two stations answer
5785  * the outbound call at the same time, the first one will get connected to
5786  * the trunk. When the second one gets here, it will not see any trunks
5787  * ringing so we have no idea what to conect it to. So, we just hang up
5788  * on it. */
5789  ast_debug(1, "Found no ringing trunk for station '%s' to answer!\n", ringing_station->station->name);
5790  ast_dial_join(ringing_station->station->dial);
5791  ast_dial_destroy(ringing_station->station->dial);
5792  ringing_station->station->dial = NULL;
5793  sla_ringing_station_destroy(ringing_station);
5794  break;
5795  }
5796  /* Track the channel that answered this trunk */
5797  s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
5798  /* Actually answer the trunk */
5799  answer_trunk_chan(ringing_trunk->trunk->chan);
5801  /* Now, start a thread that will connect this station to the trunk. The rest of
5802  * the code here sets up the thread and ensures that it is able to save the arguments
5803  * before they are no longer valid since they are allocated on the stack. */
5804  ao2_ref(s_trunk_ref, 1);
5805  args.trunk_ref = s_trunk_ref;
5806  ao2_ref(ringing_station->station, 1);
5807  args.station = ringing_station->station;
5808  args.cond = &cond;
5809  args.cond_lock = &cond_lock;
5810  sla_ringing_trunk_destroy(ringing_trunk);
5811  sla_ringing_station_destroy(ringing_station);
5812  ast_mutex_init(&cond_lock);
5813  ast_cond_init(&cond, NULL);
5814  ast_mutex_lock(&cond_lock);
5816  ast_cond_wait(&cond, &cond_lock);
5817  ast_mutex_unlock(&cond_lock);
5818  ast_mutex_destroy(&cond_lock);
5819  ast_cond_destroy(&cond);
5820  break;
5825  break;
5826  }
5827  if (dial_res == AST_DIAL_RESULT_ANSWERED) {
5828  /* Queue up reprocessing ringing trunks, and then ringing stations again */
5831  break;
5832  }
5833  }
5835 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5500
struct ast_channel * chan
Definition: app_meetme.c:867
struct sla_ringing_station::@42 entry
ast_mutex_t * cond_lock
Definition: app_meetme.c:5581
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:5552
struct ast_dial * dial
Definition: app_meetme.c:823
A station that is ringing.
Definition: app_meetme.c:950
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#define ast_cond_init(cond, attr)
Definition: lock.h:167
#define ast_mutex_lock(a)
Definition: lock.h:155
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:5585
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2049
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
pthread_cond_t ast_cond_t
Definition: lock.h:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:48
static void * run_station(void *data)
Definition: app_meetme.c:5591
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
#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:915
A trunk that is ringing.
Definition: app_meetme.c:936
ast_cond_t cond
Definition: app_meetme.c:963
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ao2_ref(o, delta)
Definition: astobj2.h:472
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:785
struct sla_trunk * trunk
Definition: app_meetme.c:937
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:5719
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:6728
static struct @350 args
#define ast_cond_destroy(cond)
Definition: lock.h:168
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:754
struct sla_station * station
Definition: app_meetme.c:951
#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:152
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
#define ast_mutex_destroy(a)
Definition: lock.h:154
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
Definition: app_meetme.c:5655
static struct @28 sla
A structure for data used by the sla thread.
Structure for mutex and tracking information.
Definition: lock.h:121
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void sla_handle_hold_event ( struct sla_event event)
static

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

6083 {
6084  ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
6085  event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
6087  event->station->name, event->trunk_ref->trunk->name);
6089  INACTIVE_TRUNK_REFS, event->trunk_ref);
6090 
6091  if (event->trunk_ref->trunk->active_stations == 1) {
6092  /* The station putting it on hold is the only one on the call, so start
6093  * Music on hold to the trunk. */
6094  event->trunk_ref->trunk->on_hold = 1;
6096  }
6097 
6099  event->trunk_ref->chan = NULL;
6100 }
const ast_string_field name
Definition: app_meetme.c:859
unsigned int active_stations
Definition: app_meetme.c:864
struct sla_station * station
Definition: app_meetme.c:922
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
struct sla_trunk * trunk
Definition: app_meetme.c:890
struct ast_channel * chan
Definition: app_meetme.c:867
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:5552
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:923
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
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:516
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
struct ast_channel * chan
Definition: app_meetme.c:892
unsigned int hold_stations
Definition: app_meetme.c:866
static void sla_handle_ringing_trunk_event ( void  )
static

Definition at line 6072 of file app_meetme.c.

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

Referenced by sla_thread().

6073 {
6074  ast_mutex_lock(&sla.lock);
6076  ast_mutex_unlock(&sla.lock);
6077 
6078  /* Find stations that shouldn't be ringing anymore. */
6080 }
static void sla_ring_stations(void)
Ring stations based on current set of ringing trunks.
Definition: app_meetme.c:6003
#define ast_mutex_lock(a)
Definition: lock.h:155
static void sla_hangup_stations(void)
Definition: app_meetme.c:6044
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void sla_hangup_stations ( void  )
static

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

6045 {
6046  struct sla_trunk_ref *trunk_ref;
6047  struct sla_ringing_station *ringing_station;
6048 
6049  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
6050  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
6051  struct sla_ringing_trunk *ringing_trunk;
6052  ast_mutex_lock(&sla.lock);
6053  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6054  if (trunk_ref->trunk == ringing_trunk->trunk)
6055  break;
6056  }
6057  ast_mutex_unlock(&sla.lock);
6058  if (ringing_trunk)
6059  break;
6060  }
6061  if (!trunk_ref) {
6063  ast_dial_join(ringing_station->station->dial);
6064  ast_dial_destroy(ringing_station->station->dial);
6065  ringing_station->station->dial = NULL;
6066  sla_ringing_station_destroy(ringing_station);
6067  }
6068  }
6070 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5500
struct sla_trunk * trunk
Definition: app_meetme.c:890
struct sla_ringing_station::@42 entry
struct ast_dial * dial
Definition: app_meetme.c:823
A station that is ringing.
Definition: app_meetme.c:950
#define ast_mutex_lock(a)
Definition: lock.h:155
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
A trunk that is ringing.
Definition: app_meetme.c:936
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
struct sla_trunk * trunk
Definition: app_meetme.c:937
#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:951
#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:888
struct sla_ringing_trunk::@41 entry
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static const char* sla_hold_str ( unsigned int  hold_access)
static

Definition at line 1714 of file app_meetme.c.

References SLA_HOLD_OPEN, and SLA_HOLD_PRIVATE.

Referenced by sla_show_stations(), and sla_show_trunks().

1715 {
1716  const char *hold = "Unknown";
1717 
1718  switch (hold_access) {
1719  case SLA_HOLD_OPEN:
1720  hold = "Open";
1721  break;
1722  case SLA_HOLD_PRIVATE:
1723  hold = "Private";
1724  default:
1725  break;
1726  }
1727 
1728  return hold;
1729 }
static int sla_in_use ( void  )
static

Definition at line 7389 of file app_meetme.c.

References ao2_container_count(), sla_stations, and sla_trunks.

Referenced by sla_load_config().

7390 {
7392 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
static int sla_load_config ( int  reload)
static

Definition at line 7394 of file app_meetme.c.

References ao2_callback, ao2_container_alloc, 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, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sla, sla_build_station(), sla_build_trunk(), SLA_CONFIG_FILE, sla_in_use(), sla_station_cmp(), sla_station_hash(), sla_station_is_marked(), sla_station_mark(), sla_stations, sla_thread(), sla_trunk_cmp(), sla_trunk_hash(), sla_trunk_is_marked(), sla_trunk_mark(), sla_trunks, and type.

Referenced by load_config().

7395 {
7396  struct ast_config *cfg;
7397  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
7398  const char *cat = NULL;
7399  int res = 0;
7400  const char *val;
7401 
7402  if (!reload) {
7403  ast_mutex_init(&sla.lock);
7404  ast_cond_init(&sla.cond, NULL);
7407  }
7408 
7409  if (!(cfg = ast_config_load(SLA_CONFIG_FILE, config_flags))) {
7410  return 0; /* Treat no config as normal */
7411  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
7412  return 0;
7413  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
7414  ast_log(LOG_ERROR, "Config file " SLA_CONFIG_FILE " is in an invalid format. Aborting.\n");
7415  return 0;
7416  }
7417 
7418  if (reload) {
7421  }
7422 
7423  if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid")))
7424  sla.attempt_callerid = ast_true(val);
7425 
7426  while ((cat = ast_category_browse(cfg, cat)) && !res) {
7427  const char *type;
7428  if (!strcasecmp(cat, "general"))
7429  continue;
7430  if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
7431  ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n",
7432  SLA_CONFIG_FILE);
7433  continue;
7434  }
7435  if (!strcasecmp(type, "trunk"))
7436  res = sla_build_trunk(cfg, cat);
7437  else if (!strcasecmp(type, "station"))
7438  res = sla_build_station(cfg, cat);
7439  else {
7440  ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'!\n",
7441  SLA_CONFIG_FILE, type);
7442  }
7443  }
7444 
7445  ast_config_destroy(cfg);
7446 
7447  if (reload) {
7450  }
7451 
7452  /* Start SLA event processing thread once SLA has been configured. */
7453  if (sla.thread == AST_PTHREADT_NULL && sla_in_use()) {
7454  ast_pthread_create(&sla.thread, NULL, sla_thread, NULL);
7455  }
7456 
7457  return res;
7458 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static int sla_build_station(struct ast_config *cfg, const char *cat)
Definition: app_meetme.c:7184
Definition: ast_expr2.c:325
#define LOG_WARNING
Definition: logger.h:144
static int sla_station_mark(void *obj, void *arg, int flags)
Definition: app_meetme.c:7315
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
#define ast_cond_init(cond, attr)
Definition: lock.h:167
static void * sla_thread(void *data)
Definition: app_meetme.c:6313
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
#define AST_PTHREADT_NULL
Definition: lock.h:65
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
static int sla_trunk_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:6936
static int sla_station_hash(const void *obj, const int flags)
Definition: app_meetme.c:6943
static int sla_in_use(void)
Definition: app_meetme.c:7389
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int reload(void)
Definition: app_meetme.c:7781
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int sla_station_is_marked(void *obj, void *arg, int flags)
Definition: app_meetme.c:7361
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:418
static int sla_station_cmp(void *obj, void *arg, int flags)
Definition: app_meetme.c:6950
static int sla_trunk_is_marked(void *obj, void *arg, int flags)
Definition: app_meetme.c:7333
static const char type[]
Definition: chan_nbs.c:57
Structure used to handle boolean flags.
Definition: utils.h:200
static int sla_trunk_mark(void *obj, void *arg, int flags)
Definition: app_meetme.c:7297
#define SLA_CONFIG_FILE
Definition: app_meetme.c:525
static int sla_build_trunk(struct ast_config *cfg, const char *cat)
Definition: app_meetme.c:7011
static int sla_trunk_hash(const void *obj, const int flags)
Definition: app_meetme.c:6929
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
#define ast_mutex_init(pmutex)
Definition: lock.h:152
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
static struct @28 sla
A structure for data used by the sla thread.
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
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 6263 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, and sla_queue_event_nolock().

Referenced by sla_thread().

6264 {
6265  unsigned int timeout = UINT_MAX;
6266  struct timeval wait;
6267  unsigned int change_made = 0;
6268 
6269  /* Check for ring timeouts on ringing trunks */
6270  if (sla_calc_trunk_timeouts(&timeout))
6271  change_made = 1;
6272 
6273  /* Check for ring timeouts on ringing stations */
6274  if (sla_calc_station_timeouts(&timeout))
6275  change_made = 1;
6276 
6277  /* Check for station ring delays */
6278  if (sla_calc_station_delays(&timeout))
6279  change_made = 1;
6280 
6281  /* queue reprocessing of ringing trunks */
6282  if (change_made)
6284 
6285  /* No timeout */
6286  if (timeout == UINT_MAX)
6287  return 0;
6288 
6289  if (ts) {
6290  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1000));
6291  ts->tv_sec = wait.tv_sec;
6292  ts->tv_nsec = wait.tv_usec * 1000;
6293  }
6294 
6295  return 1;
6296 }
static void sla_queue_event_nolock(enum sla_event_type type)
Definition: app_meetme.c:2044
static int sla_calc_station_delays(unsigned int *timeout)
Calculate the ring delay for a station.
Definition: app_meetme.c:6219
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int sla_calc_station_timeouts(unsigned int *timeout)
Process station ring timeouts.
Definition: app_meetme.c:6136
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:191
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static int sla_calc_trunk_timeouts(unsigned int *timeout)
Process trunk ring timeouts.
Definition: app_meetme.c:6106
static void sla_queue_event ( enum sla_event_type  type)
static

Definition at line 2049 of file app_meetme.c.

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

2050 {
2051  sla_queue_event_full(type, NULL, NULL, 1);
2052 }
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:2012
static const char type[]
Definition: chan_nbs.c:57
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 2055 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, sla_queue_event_full(), sla_stations, strsep(), sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by conf_run().

2057 {
2058  struct sla_station *station;
2059  struct sla_trunk_ref *trunk_ref = NULL;
2060  char *trunk_name;
2061  struct ao2_iterator i;
2062 
2063  trunk_name = ast_strdupa(conf->confno);
2064  strsep(&trunk_name, "_");
2065  if (ast_strlen_zero(trunk_name)) {
2066  ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", conf->confno);
2067  return;
2068  }
2069 
2071  while ((station = ao2_iterator_next(&i))) {
2072  ao2_lock(station);
2073  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2074  if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name)) {
2075  ao2_ref(trunk_ref, 1);
2076  break;
2077  }
2078  }
2079  ao2_unlock(station);
2080  if (trunk_ref) {
2081  /* station reference given to sla_queue_event_full() */
2082  break;
2083  }
2084  ao2_ref(station, -1);
2085  }
2087 
2088  if (!trunk_ref) {
2089  ast_debug(1, "Trunk not found for event!\n");
2090  return;
2091  }
2092 
2093  sla_queue_event_full(type, trunk_ref, station, 1);
2094 }
const ast_string_field name
Definition: app_meetme.c:859
char * strsep(char **str, const char *delims)
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
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:2012
#define ao2_lock(a)
Definition: astobj2.h:488
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
struct ast_channel * chan
Definition: app_meetme.c:892
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char type[]
Definition: chan_nbs.c:57
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
char confno[MAX_CONFNUM]
Definition: app_meetme.c:718
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 2012 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().

2014 {
2015  struct sla_event *event;
2016 
2017  if (sla.thread == AST_PTHREADT_NULL) {
2018  ao2_ref(station, -1);
2019  ao2_ref(trunk_ref, -1);
2020  return;
2021  }
2022 
2023  if (!(event = ast_calloc(1, sizeof(*event)))) {
2024  ao2_ref(station, -1);
2025  ao2_ref(trunk_ref, -1);
2026  return;
2027  }
2028 
2029  event->type = type;
2030  event->trunk_ref = trunk_ref;
2031  event->station = station;
2032 
2033  if (!lock) {
2034  AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
2035  return;
2036  }
2037 
2038  ast_mutex_lock(&sla.lock);
2039  AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
2040  ast_cond_signal(&sla.cond);
2041  ast_mutex_unlock(&sla.lock);
2042 }
struct sla_station * station
Definition: app_meetme.c:922
#define ast_mutex_lock(a)
Definition: lock.h:155
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:923
#define ast_cond_signal(cond)
Definition: lock.h:169
#define AST_PTHREADT_NULL
Definition: lock.h:65
ast_mutex_t lock
Definition: app_meetme.c:964
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_event::@38 entry
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static const char type[]
Definition: chan_nbs.c:57
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void sla_queue_event_nolock ( enum sla_event_type  type)
static

Definition at line 2044 of file app_meetme.c.

References sla_queue_event_full().

Referenced by sla_process_timers().

2045 {
2046  sla_queue_event_full(type, NULL, NULL, 0);
2047 }
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:2012
static const char type[]
Definition: chan_nbs.c:57
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 5878 of file app_meetme.c.

References 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, ast_channel::caller, sla_trunk::chan, sla_station::dial, sla, sla_create_failed_station(), sla_create_ringing_station(), sla_dial_state_callback(), strsep(), and sla_ringing_trunk::trunk.

Referenced by sla_ring_stations().

5879 {
5880  char *tech, *tech_data;
5881  struct ast_dial *dial;
5882  struct sla_ringing_station *ringing_station;
5883  enum ast_dial_result res;
5884  int caller_is_saved;
5885  struct ast_party_caller caller;
5886 
5887  if (!(dial = ast_dial_create()))
5888  return -1;
5889 
5891  tech_data = ast_strdupa(station->device);
5892  tech = strsep(&tech_data, "/");
5893 
5894  if (ast_dial_append(dial, tech, tech_data) == -1) {
5895  ast_dial_destroy(dial);
5896  return -1;
5897  }
5898 
5899  /* Do we need to save off the caller ID data? */
5900  caller_is_saved = 0;
5901  if (!sla.attempt_callerid) {
5902  caller_is_saved = 1;
5903  caller = ringing_trunk->trunk->chan->caller;
5904  ast_party_caller_init(&ringing_trunk->trunk->chan->caller);
5905  }
5906 
5907  res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
5908 
5909  /* Restore saved caller ID */
5910  if (caller_is_saved) {
5911  ast_party_caller_free(&ringing_trunk->trunk->chan->caller);
5912  ringing_trunk->trunk->chan->caller = caller;
5913  }
5914 
5915  if (res != AST_DIAL_RESULT_TRYING) {
5916  struct sla_failed_station *failed_station;
5917  ast_dial_destroy(dial);
5918  if ((failed_station = sla_create_failed_station(station))) {
5919  AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
5920  }
5921  return -1;
5922  }
5923  if (!(ringing_station = sla_create_ringing_station(station))) {
5924  ast_dial_join(dial);
5925  ast_dial_destroy(dial);
5926  return -1;
5927  }
5928 
5929  station->dial = dial;
5930 
5931  AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_station, entry);
5932 
5933  return 0;
5934 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
Main dialing structure. Contains global options, channels being dialed, and more! ...
Definition: dial.c:47
struct ast_channel * chan
Definition: app_meetme.c:867
static void sla_dial_state_callback(struct ast_dial *dial)
Definition: app_meetme.c:5690
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
Append a channel.
Definition: dial.c:229
struct ast_dial * dial
Definition: app_meetme.c:823
A station that is ringing.
Definition: app_meetme.c:950
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2302
static struct sla_failed_station * sla_create_failed_station(struct sla_station *station)
Definition: app_meetme.c:5510
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
Definition: dial.c:1043
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:48
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
Caller Party information.
Definition: channel.h:368
static struct sla_ringing_station * sla_create_ringing_station(struct sla_station *station)
Definition: app_meetme.c:5486
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:714
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct sla_trunk * trunk
Definition: app_meetme.c:937
struct sla_failed_station::@39 entry
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:201
A station that failed to be dialed.
Definition: app_meetme.c:929
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:2269
static struct @28 sla
A structure for data used by the sla thread.
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 6003 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().

6004 {
6005  struct sla_station_ref *station_ref;
6006  struct sla_ringing_trunk *ringing_trunk;
6007 
6008  /* Make sure that every station that uses at least one of the ringing
6009  * trunks, is ringing. */
6010  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
6011  AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
6012  int time_left;
6013 
6014  /* Is this station already ringing? */
6015  if (sla_check_ringing_station(station_ref->station))
6016  continue;
6017 
6018  /* Is this station already in a call? */
6019  if (sla_check_inuse_station(station_ref->station))
6020  continue;
6021 
6022  /* Did we fail to dial this station earlier? If so, has it been
6023  * a minute since we tried? */
6024  if (sla_check_failed_station(station_ref->station))
6025  continue;
6026 
6027  /* If this station already timed out while this trunk was ringing,
6028  * do not dial it again for this ringing trunk. */
6029  if (sla_check_timed_out_station(ringing_trunk, station_ref->station))
6030  continue;
6031 
6032  /* Check for a ring delay in progress */
6033  time_left = sla_check_station_delay(station_ref->station, ringing_trunk);
6034  if (time_left != INT_MAX && time_left > 0)
6035  continue;
6036 
6037  /* It is time to make this station begin to ring. Do it! */
6038  sla_ring_station(ringing_trunk, station_ref->station);
6039  }
6040  }
6041  /* Now, all of the stations that should be ringing, are ringing. */
6042 }
static int sla_check_ringing_station(const struct sla_station *station)
Check to see if this station is already ringing.
Definition: app_meetme.c:5840
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
Ring a station.
Definition: app_meetme.c:5878
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:5970
A trunk that is ringing.
Definition: app_meetme.c:936
struct sla_trunk * trunk
Definition: app_meetme.c:937
#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:5855
static int sla_check_inuse_station(const struct sla_station *station)
Check to see if a station is in use.
Definition: app_meetme.c:5938
struct sla_ringing_trunk::@41 entry
struct sla_station * station
Definition: app_meetme.c:849
static struct @28 sla
A structure for data used by the sla thread.
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:5698
static void sla_ringing_station_destroy ( struct sla_ringing_station ringing_station)
static

Definition at line 5500 of file app_meetme.c.

References ao2_ref, ast_free, and sla_ringing_station::station.

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

5501 {
5502  if (ringing_station->station) {
5503  ao2_ref(ringing_station->station, -1);
5504  ringing_station->station = NULL;
5505  }
5506 
5507  ast_free(ringing_station);
5508 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ast_free(a)
Definition: astmm.h:97
struct sla_station * station
Definition: app_meetme.c:951
static void sla_ringing_trunk_destroy ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 6728 of file app_meetme.c.

References ao2_ref, ast_free, and sla_ringing_trunk::trunk.

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

6729 {
6730  if (ringing_trunk->trunk) {
6731  ao2_ref(ringing_trunk->trunk, -1);
6732  ringing_trunk->trunk = NULL;
6733  }
6734 
6735  ast_free(ringing_trunk);
6736 }
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_trunk * trunk
Definition: app_meetme.c:937
#define ast_free(a)
Definition: astmm.h:97
static char* sla_show_stations ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1805 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, sla_station::ring_delay, sla_trunk_ref::ring_delay, sla_station::ring_timeout, sla_trunk_ref::ring_timeout, S_OR, sla_hold_str(), sla_stations, sla_trunk_ref::state, sla_trunk_ref::trunk, sla_station::trunks, trunkstate2str(), and ast_cli_entry::usage.

1806 {
1807  struct ao2_iterator i;
1808  struct sla_station *station;
1809 
1810  switch (cmd) {
1811  case CLI_INIT:
1812  e->command = "sla show stations";
1813  e->usage =
1814  "Usage: sla show stations\n"
1815  " This will list all stations defined in sla.conf\n";
1816  return NULL;
1817  case CLI_GENERATE:
1818  return NULL;
1819  }
1820 
1821  ast_cli(a->fd, "\n"
1822  "=============================================================\n"
1823  "=== Configured SLA Stations =================================\n"
1824  "=============================================================\n"
1825  "===\n");
1827  for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
1828  struct sla_trunk_ref *trunk_ref;
1829  char ring_timeout[16] = "(none)";
1830  char ring_delay[16] = "(none)";
1831 
1832  ao2_lock(station);
1833 
1834  if (station->ring_timeout) {
1835  snprintf(ring_timeout, sizeof(ring_timeout),
1836  "%u", station->ring_timeout);
1837  }
1838  if (station->ring_delay) {
1839  snprintf(ring_delay, sizeof(ring_delay),
1840  "%u", station->ring_delay);
1841  }
1842  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
1843  "=== Station Name: %s\n"
1844  "=== ==> Device: %s\n"
1845  "=== ==> AutoContext: %s\n"
1846  "=== ==> RingTimeout: %s\n"
1847  "=== ==> RingDelay: %s\n"
1848  "=== ==> HoldAccess: %s\n"
1849  "=== ==> Trunks ...\n",
1850  station->name, station->device,
1851  S_OR(station->autocontext, "(none)"),
1852  ring_timeout, ring_delay,
1853  sla_hold_str(station->hold_access));
1854  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
1855  if (trunk_ref->ring_timeout) {
1856  snprintf(ring_timeout, sizeof(ring_timeout),
1857  "%u", trunk_ref->ring_timeout);
1858  } else
1859  strcpy(ring_timeout, "(none)");
1860  if (trunk_ref->ring_delay) {
1861  snprintf(ring_delay, sizeof(ring_delay),
1862  "%u", trunk_ref->ring_delay);
1863  } else
1864  strcpy(ring_delay, "(none)");
1865  ast_cli(a->fd, "=== ==> Trunk Name: %s\n"
1866  "=== ==> State: %s\n"
1867  "=== ==> RingTimeout: %s\n"
1868  "=== ==> RingDelay: %s\n",
1869  trunk_ref->trunk->name,
1870  trunkstate2str(trunk_ref->state),
1871  ring_timeout, ring_delay);
1872  }
1873  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
1874  "===\n");
1875 
1876  ao2_unlock(station);
1877  }
1879  ast_cli(a->fd, "============================================================\n"
1880  "\n");
1881 
1882  return CLI_SUCCESS;
1883 }
const ast_string_field name
Definition: app_meetme.c:859
struct sla_trunk_ref::@37 entry
unsigned int ring_timeout
Definition: app_meetme.c:896
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
Definition: cli.h:146
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
unsigned int ring_delay
Definition: app_meetme.c:831
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
unsigned int hold_access
Definition: app_meetme.c:834
enum sla_trunk_state state
Definition: app_meetme.c:891
const int fd
Definition: cli.h:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#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:1791
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static const char * sla_hold_str(unsigned int hold_access)
Definition: app_meetme.c:1714
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
unsigned int ring_timeout
Definition: app_meetme.c:827
static struct ao2_container * sla_stations
Definition: app_meetme.c:905
unsigned int ring_delay
Definition: app_meetme.c:900
static char* sla_show_trunks ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1731 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, sla_trunk::ring_timeout, S_OR, sla_hold_str(), sla_trunks, sla_station_ref::station, sla_trunk::stations, and ast_cli_entry::usage.

1732 {
1733  struct ao2_iterator i;
1734  struct sla_trunk *trunk;
1735 
1736  switch (cmd) {
1737  case CLI_INIT:
1738  e->command = "sla show trunks";
1739  e->usage =
1740  "Usage: sla show trunks\n"
1741  " This will list all trunks defined in sla.conf\n";
1742  return NULL;
1743  case CLI_GENERATE:
1744  return NULL;
1745  }
1746 
1747  ast_cli(a->fd, "\n"
1748  "=============================================================\n"
1749  "=== Configured SLA Trunks ===================================\n"
1750  "=============================================================\n"
1751  "===\n");
1752  i = ao2_iterator_init(sla_trunks, 0);
1753  for (; (trunk = ao2_iterator_next(&i)); ao2_ref(trunk, -1)) {
1754  struct sla_station_ref *station_ref;
1755  char ring_timeout[16] = "(none)";
1756 
1757  ao2_lock(trunk);
1758 
1759  if (trunk->ring_timeout) {
1760  snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
1761  }
1762 
1763  ast_cli(a->fd, "=== ---------------------------------------------------------\n"
1764  "=== Trunk Name: %s\n"
1765  "=== ==> Device: %s\n"
1766  "=== ==> AutoContext: %s\n"
1767  "=== ==> RingTimeout: %s\n"
1768  "=== ==> BargeAllowed: %s\n"
1769  "=== ==> HoldAccess: %s\n"
1770  "=== ==> Stations ...\n",
1771  trunk->name, trunk->device,
1772  S_OR(trunk->autocontext, "(none)"),
1773  ring_timeout,
1774  trunk->barge_disabled ? "No" : "Yes",
1775  sla_hold_str(trunk->hold_access));
1776 
1777  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
1778  ast_cli(a->fd, "=== ==> Station name: %s\n", station_ref->station->name);
1779  }
1780 
1781  ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
1782 
1783  ao2_unlock(trunk);
1784  }
1786  ast_cli(a->fd, "=============================================================\n\n");
1787 
1788  return CLI_SUCCESS;
1789 }
const ast_string_field name
Definition: app_meetme.c:859
const ast_string_field autocontext
Definition: app_meetme.c:859
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
Definition: cli.h:146
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
const ast_string_field device
Definition: app_meetme.c:859
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
struct sla_station_ref::@35 entry
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
unsigned int barge_disabled
Definition: app_meetme.c:871
unsigned int hold_access
Definition: app_meetme.c:874
#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:868
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static const char * sla_hold_str(unsigned int hold_access)
Definition: app_meetme.c:1714
static struct ao2_container * sla_trunks
Definition: app_meetme.c:906
struct sla_station * station
Definition: app_meetme.c:849
static enum ast_device_state sla_state ( const char *  data)
static

Definition at line 6849 of file app_meetme.c.

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

Referenced by load_module().

6850 {
6851  char *buf, *station_name, *trunk_name;
6852  RAII_VAR(struct sla_station *, station, NULL, unref_obj);
6853  struct sla_trunk_ref *trunk_ref;
6855 
6856  trunk_name = buf = ast_strdupa(data);
6857  station_name = strsep(&trunk_name, "_");
6858 
6859  station = sla_find_station(station_name);
6860  if (station) {
6861  ao2_lock(station);
6862  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6863  if (!strcasecmp(trunk_name, trunk_ref->trunk->name)) {
6864  res = sla_state_to_devstate(trunk_ref->state);
6865  break;
6866  }
6867  }
6868  ao2_unlock(station);
6869  }
6870 
6871  if (res == AST_DEVICE_INVALID) {
6872  ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n",
6873  trunk_name, station_name);
6874  }
6875 
6876  return res;
6877 }
const ast_string_field name
Definition: app_meetme.c:859
ast_device_state
Device States.
Definition: devicestate.h:51
struct sla_trunk_ref::@37 entry
char * strsep(char **str, const char *delims)
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_unlock(a)
Definition: astobj2.h:497
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
Definition: app_meetme.c:5535
enum sla_trunk_state state
Definition: app_meetme.c:891
#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:915
#define ao2_lock(a)
Definition: astobj2.h:488
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5394
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
struct sla_station * station
Definition: app_meetme.c:849
static int sla_station_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 6950 of file app_meetme.c.

References CMP_MATCH, and CMP_STOP.

Referenced by sla_load_config().

6951 {
6952  struct sla_station *station = obj, *station2 = arg;
6953 
6954  return !strcasecmp(station->name, station2->name) ? CMP_MATCH | CMP_STOP : 0;
6955 }
static void sla_station_destructor ( void *  obj)
static

Definition at line 6903 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, PRIORITY_HINT, sla_registrar, sla_station_release_refs(), sla_trunk_ref::trunk, and sla_station::trunks.

Referenced by sla_build_station().

6904 {
6905  struct sla_station *station = obj;
6906 
6907  ast_debug(1, "sla_station destructor for '%s'\n", station->name);
6908 
6909  if (!ast_strlen_zero(station->autocontext)) {
6910  struct sla_trunk_ref *trunk_ref;
6911 
6912  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
6913  char exten[AST_MAX_EXTENSION];
6914  char hint[AST_MAX_APP];
6915  snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
6916  snprintf(hint, sizeof(hint), "SLA:%s", exten);
6917  ast_context_remove_extension(station->autocontext, exten,
6918  1, sla_registrar);
6919  ast_context_remove_extension(station->autocontext, hint,
6921  }
6922  }
6923 
6924  sla_station_release_refs(station, NULL, 0);
6925 
6927 }
const ast_string_field name
Definition: app_meetme.c:859
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct sla_trunk_ref::@37 entry
struct sla_trunk * trunk
Definition: app_meetme.c:890
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:6114
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define PRIORITY_HINT
Definition: pbx.h:53
#define AST_MAX_APP
Definition: pbx.h:39
#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:6891
static const char sla_registrar[]
Definition: app_meetme.c:908
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int sla_station_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 6529 of file app_meetme.c.

References sla_trunk::active_stations, admin_exec(), ALL_TRUNK_REFS, answer_trunk_chan(), 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, 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().

6530 {
6531  char *station_name, *trunk_name;
6532  RAII_VAR(struct sla_station *, station, NULL, unref_obj);
6533  RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
6534  char conf_name[MAX_CONFNUM];
6535  struct ast_flags64 conf_flags = { 0 };
6536  struct ast_conference *conf;
6537 
6538  if (ast_strlen_zero(data)) {
6539  ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
6540  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
6541  return 0;
6542  }
6543 
6544  trunk_name = ast_strdupa(data);
6545  station_name = strsep(&trunk_name, "_");
6546 
6547  if (ast_strlen_zero(station_name)) {
6548  ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
6549  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
6550  return 0;
6551  }
6552 
6553  station = sla_find_station(station_name);
6554 
6555  if (!station) {
6556  ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
6557  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
6558  return 0;
6559  }
6560 
6561  ao2_lock(station);
6562  if (!ast_strlen_zero(trunk_name)) {
6563  trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
6564  } else {
6565  trunk_ref = sla_choose_idle_trunk(station);
6566  }
6567  ao2_unlock(station);
6568 
6569  if (!trunk_ref) {
6570  if (ast_strlen_zero(trunk_name))
6571  ast_log(LOG_NOTICE, "No trunks available for call.\n");
6572  else {
6573  ast_log(LOG_NOTICE, "Can't join existing call on trunk "
6574  "'%s' due to access controls.\n", trunk_name);
6575  }
6576  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
6577  return 0;
6578  }
6579 
6580  if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
6581  if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1)
6582  sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
6583  else {
6584  trunk_ref->state = SLA_TRUNK_STATE_UP;
6586  "SLA:%s_%s", station->name, trunk_ref->trunk->name);
6587  }
6588  } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
6589  struct sla_ringing_trunk *ringing_trunk;
6590 
6591  ast_mutex_lock(&sla.lock);
6592  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
6593  if (ringing_trunk->trunk == trunk_ref->trunk) {
6595  break;
6596  }
6597  }
6599  ast_mutex_unlock(&sla.lock);
6600 
6601  if (ringing_trunk) {
6602  answer_trunk_chan(ringing_trunk->trunk->chan);
6604 
6605  sla_ringing_trunk_destroy(ringing_trunk);
6606 
6607  /* Queue up reprocessing ringing trunks, and then ringing stations again */
6610  }
6611  }
6612 
6613  trunk_ref->chan = chan;
6614 
6615  if (!trunk_ref->trunk->chan) {
6616  ast_mutex_t cond_lock;
6617  ast_cond_t cond;
6618  pthread_t dont_care;
6619  struct dial_trunk_args args = {
6620  .trunk_ref = trunk_ref,
6621  .station = station,
6622  .cond_lock = &cond_lock,
6623  .cond = &cond,
6624  };
6625  ao2_ref(trunk_ref, 1);
6626  ao2_ref(station, 1);
6628  /* Create a thread to dial the trunk and dump it into the conference.
6629  * However, we want to wait until the trunk has been dialed and the
6630  * conference is created before continuing on here. */
6631  ast_autoservice_start(chan);
6632  ast_mutex_init(&cond_lock);
6633  ast_cond_init(&cond, NULL);
6634  ast_mutex_lock(&cond_lock);
6635  ast_pthread_create_detached_background(&dont_care, NULL, dial_trunk, &args);
6636  ast_cond_wait(&cond, &cond_lock);
6637  ast_mutex_unlock(&cond_lock);
6638  ast_mutex_destroy(&cond_lock);
6639  ast_cond_destroy(&cond);
6640  ast_autoservice_stop(chan);
6641  if (!trunk_ref->trunk->chan) {
6642  ast_debug(1, "Trunk didn't get created. chan: %lx\n", (unsigned long) trunk_ref->trunk->chan);
6643  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
6645  trunk_ref->chan = NULL;
6646  return 0;
6647  }
6648  }
6649 
6650  if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
6651  trunk_ref->trunk->on_hold) {
6652  trunk_ref->trunk->on_hold = 0;
6655  }
6656 
6657  snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
6658  ast_set_flag64(&conf_flags,
6660  ast_answer(chan);
6661  conf = build_conf(conf_name, "", "", 0, 0, 1, chan, NULL);
6662  if (conf) {
6663  conf_run(chan, conf, &conf_flags, NULL);
6664  dispose_conf(conf);
6665  conf = NULL;
6666  }
6667  trunk_ref->chan = NULL;
6670  strncat(conf_name, ",K", sizeof(conf_name) - strlen(conf_name) - 1);
6671  admin_exec(NULL, conf_name);
6674  }
6675 
6676  pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
6677 
6678  return 0;
6679 }
const ast_string_field name
Definition: app_meetme.c:859
unsigned int active_stations
Definition: app_meetme.c:864
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:6515
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
char * strsep(char **str, const char *delims)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define LOG_WARNING
Definition: logger.h:144
struct ast_channel * chan
Definition: app_meetme.c:867
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:5552
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
#define ast_cond_init(cond, attr)
Definition: lock.h:167
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:1213
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ao2_unlock(a)
Definition: astobj2.h:497
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_meetme.c:5585
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2049
ast_mutex_t * cond_lock
Definition: app_meetme.c:6371
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
pthread_cond_t ast_cond_t
Definition: lock.h:144
enum sla_trunk_state state
Definition: app_meetme.c:891
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:2759
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct sla_station * station
Definition: app_meetme.c:6370
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:516
#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:915
unsigned int on_hold
Definition: app_meetme.c:877
A trunk that is ringing.
Definition: app_meetme.c:936
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
ast_cond_t cond
Definition: app_meetme.c:963
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0. Useful e.g. to check if a refcount h...
Definition: lock.h:649
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
struct sla_trunk_ref * trunk_ref
Definition: app_meetme.c:6369
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct sla_trunk * trunk
Definition: app_meetme.c:937
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:6728
struct ast_channel * chan
Definition: app_meetme.c:892
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_cond_destroy(cond)
Definition: lock.h:168
#define LOG_NOTICE
Definition: logger.h:133
unsigned int hold_stations
Definition: app_meetme.c:866
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: pbx.c:10546
static void * dial_trunk(void *data)
Definition: app_meetme.c:6375
#define MAX_CONFNUM
Definition: app_meetme.c:693
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:4807
static struct sla_station * sla_find_station(const char *name)
Definition: app_meetme.c:5394
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:5433
#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:152
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct sla_ringing_trunk::@41 entry
The MeetMe Conference object.
Definition: app_meetme.c:715
static struct @28 sla
A structure for data used by the sla thread.
Structure for mutex and tracking information.
Definition: lock.h:121
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sla_station_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 6943 of file app_meetme.c.

References ast_str_case_hash().

Referenced by sla_load_config().

6944 {
6945  const struct sla_station *station = obj;
6946 
6947  return ast_str_case_hash(station->name);
6948 }
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:989
static int sla_station_is_marked ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7361 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, sla_station_release_refs(), and sla_station::trunks.

Referenced by sla_load_config().

7362 {
7363  struct sla_station *station = obj;
7364 
7365  ao2_lock(station);
7366 
7367  if (station->mark) {
7368  /* Only remove all of the trunk references if the station itself is going away */
7369  sla_station_release_refs(station, NULL, 0);
7370  } else {
7371  struct sla_trunk_ref *trunk_ref;
7372 
7373  /* Otherwise only remove references to trunks no longer in the config */
7374  AST_LIST_TRAVERSE_SAFE_BEGIN(&station->trunks, trunk_ref, entry) {
7375  if (!trunk_ref->mark) {
7376  continue;
7377  }
7379  ao2_ref(trunk_ref, -1);
7380  }
7382  }
7383 
7384  ao2_unlock(station);
7385 
7386  return station->mark ? CMP_MATCH : 0;
7387 }
struct sla_trunk_ref::@37 entry
unsigned int mark
Definition: app_meetme.c:902
unsigned int mark
Definition: app_meetme.c:836
#define ao2_unlock(a)
Definition: astobj2.h:497
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:6891
#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:888
static int sla_station_mark ( void *  obj,
void *  arg,
int  flags 
)
static

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

7316 {
7317  struct sla_station *station = obj;
7318  struct sla_trunk_ref *trunk_ref;
7319 
7320  ao2_lock(station);
7321 
7322  station->mark = 1;
7323 
7324  AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
7325  trunk_ref->mark = 1;
7326  }
7327 
7328  ao2_unlock(station);
7329 
7330  return 0;
7331 }
struct sla_trunk_ref::@37 entry
unsigned int mark
Definition: app_meetme.c:902
unsigned int mark
Definition: app_meetme.c:836
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_lock(a)
Definition: astobj2.h:488
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static void sla_station_ref_destructor ( void *  obj)
static

Definition at line 5462 of file app_meetme.c.

References ao2_ref, and sla_station_ref::station.

Referenced by sla_create_station_ref().

5463 {
5464  struct sla_station_ref *station_ref = obj;
5465 
5466  if (station_ref->station) {
5467  ao2_ref(station_ref->station, -1);
5468  station_ref->station = NULL;
5469  }
5470 }
A reference to a station.
Definition: app_meetme.c:847
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct sla_station * station
Definition: app_meetme.c:849
static int sla_station_release_refs ( void *  obj,
void *  arg,
int  flags 
)
static

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

6892 {
6893  struct sla_station *station = obj;
6894  struct sla_trunk_ref *trunk_ref;
6895 
6896  while ((trunk_ref = AST_LIST_REMOVE_HEAD(&station->trunks, entry))) {
6897  ao2_ref(trunk_ref, -1);
6898  }
6899 
6900  return 0;
6901 }
struct sla_trunk_ref::@37 entry
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static void sla_stop_ringing_station ( struct sla_ringing_station ringing_station,
enum sla_station_hangup  hangup 
)
static

Definition at line 5655 of file app_meetme.c.

References ast_dial_destroy(), ast_dial_join(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, sla_station::dial, 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().

5657 {
5658  struct sla_ringing_trunk *ringing_trunk;
5659  struct sla_trunk_ref *trunk_ref;
5660  struct sla_station_ref *station_ref;
5661 
5662  ast_dial_join(ringing_station->station->dial);
5663  ast_dial_destroy(ringing_station->station->dial);
5664  ringing_station->station->dial = NULL;
5665 
5666  if (hangup == SLA_STATION_HANGUP_NORMAL)
5667  goto done;
5668 
5669  /* If the station is being hung up because of a timeout, then add it to the
5670  * list of timed out stations on each of the ringing trunks. This is so
5671  * that when doing further processing to figure out which stations should be
5672  * ringing, which trunk to answer, determining timeouts, etc., we know which
5673  * ringing trunks we should ignore. */
5674  AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
5675  AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
5676  if (ringing_trunk->trunk == trunk_ref->trunk)
5677  break;
5678  }
5679  if (!trunk_ref)
5680  continue;
5681  if (!(station_ref = sla_create_station_ref(ringing_station->station)))
5682  continue;
5683  AST_LIST_INSERT_TAIL(&ringing_trunk->timed_out_stations, station_ref, entry);
5684  }
5685 
5686 done:
5687  sla_ringing_station_destroy(ringing_station);
5688 }
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:866
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5500
struct sla_trunk * trunk
Definition: app_meetme.c:890
struct ast_dial * dial
Definition: app_meetme.c:823
A reference to a station.
Definition: app_meetme.c:847
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:794
A trunk that is ringing.
Definition: app_meetme.c:936
struct sla_station_ref::@35 entry
static struct sla_station_ref * sla_create_station_ref(struct sla_station *station)
Definition: app_meetme.c:5472
struct sla_trunk * trunk
Definition: app_meetme.c:937
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#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:951
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
struct sla_ringing_trunk::@40 timed_out_stations
static struct @28 sla
A structure for data used by the sla thread.
static void sla_stop_ringing_trunk ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 5639 of file app_meetme.c.

References admin_exec(), ALL_TRUNK_REFS, ao2_ref, AST_LIST_REMOVE_HEAD, sla_trunk::name, 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().

5640 {
5641  char buf[80];
5642  struct sla_station_ref *station_ref;
5643 
5644  snprintf(buf, sizeof(buf), "SLA_%s,K", ringing_trunk->trunk->name);
5645  admin_exec(NULL, buf);
5647 
5648  while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry))) {
5649  ao2_ref(station_ref, -1);
5650  }
5651 
5652  sla_ringing_trunk_destroy(ringing_trunk);
5653 }
const ast_string_field name
Definition: app_meetme.c:859
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:5552
A reference to a station.
Definition: app_meetme.c:847
struct sla_station_ref::@35 entry
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct sla_trunk * trunk
Definition: app_meetme.c:937
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:6728
static int admin_exec(struct ast_channel *chan, const char *data)
The MeetMeadmin application.
Definition: app_meetme.c:4807
struct sla_ringing_trunk::@40 timed_out_stations
static void* sla_thread ( void *  data)
static

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

6314 {
6315  struct sla_failed_station *failed_station;
6316  struct sla_ringing_station *ringing_station;
6317 
6318  ast_mutex_lock(&sla.lock);
6319 
6320  while (!sla.stop) {
6321  struct sla_event *event;
6322  struct timespec ts = { 0, };
6323  unsigned int have_timeout = 0;
6324 
6325  if (AST_LIST_EMPTY(&sla.event_q)) {
6326  if ((have_timeout = sla_process_timers(&ts)))
6327  ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
6328  else
6329  ast_cond_wait(&sla.cond, &sla.lock);
6330  if (sla.stop)
6331  break;
6332  }
6333 
6334  if (have_timeout)
6335  sla_process_timers(NULL);
6336 
6337  while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
6338  ast_mutex_unlock(&sla.lock);
6339  switch (event->type) {
6340  case SLA_EVENT_HOLD:
6341  sla_handle_hold_event(event);
6342  break;
6343  case SLA_EVENT_DIAL_STATE:
6345  break;
6348  break;
6349  }
6350  sla_event_destroy(event);
6351  ast_mutex_lock(&sla.lock);
6352  }
6353  }
6354 
6355  ast_mutex_unlock(&sla.lock);
6356 
6357  while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry))) {
6358  sla_ringing_station_destroy(ringing_station);
6359  }
6360 
6361  while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry))) {
6362  sla_failed_station_destroy(failed_station);
6363  }
6364 
6365  return NULL;
6366 }
static void sla_handle_ringing_trunk_event(void)
Definition: app_meetme.c:6072
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_meetme.c:5500
A station that is ringing.
Definition: app_meetme.c:950
static void sla_event_destroy(struct sla_event *event)
Definition: app_meetme.c:6298
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
enum sla_event_type type
Definition: app_meetme.c:921
#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:155
static int sla_process_timers(struct timespec *ts)
Calculate the time until the next known event.
Definition: app_meetme.c:6263
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
A station that failed to be dialed.
Definition: app_meetme.c:929
static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
Definition: app_meetme.c:5525
static void sla_handle_dial_state_event(void)
Definition: app_meetme.c:5755
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
static void sla_handle_hold_event(struct sla_event *event)
Definition: app_meetme.c:6082
static struct @28 sla
A structure for data used by the sla thread.
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sla_trunk_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 6936 of file app_meetme.c.

References CMP_MATCH, CMP_STOP, and sla_trunk::name.

Referenced by sla_load_config().

6937 {
6938  struct sla_trunk *trunk = obj, *trunk2 = arg;
6939 
6940  return !strcasecmp(trunk->name, trunk2->name) ? CMP_MATCH | CMP_STOP : 0;
6941 }
const ast_string_field name
Definition: app_meetme.c:859
static void sla_trunk_destructor ( void *  obj)
static

Definition at line 6996 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, sla_registrar, and sla_trunk_release_refs().

Referenced by sla_build_trunk().

6997 {
6998  struct sla_trunk *trunk = obj;
6999 
7000  ast_debug(1, "sla_trunk destructor for '%s'\n", trunk->name);
7001 
7002  if (!ast_strlen_zero(trunk->autocontext)) {
7004  }
7005 
7006  sla_trunk_release_refs(trunk, NULL, 0);
7007 
7009 }
const ast_string_field name
Definition: app_meetme.c:859
const ast_string_field autocontext
Definition: app_meetme.c:859
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:6114
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char sla_registrar[]
Definition: app_meetme.c:908
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_meetme.c:6879
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int sla_trunk_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 6751 of file app_meetme.c.

References ALL_TRUNK_REFS, args, 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(), sla_trunk::chan, conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_MOH, CONFFLAG_NO_AUDIO_UNTIL_UP, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, dispose_conf(), LOG_ERROR, MAX_CONFNUM, sla_trunk::on_hold, 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().

6752 {
6753  char conf_name[MAX_CONFNUM];
6754  struct ast_conference *conf;
6755  struct ast_flags64 conf_flags = { 0 };
6756  RAII_VAR(struct sla_trunk *, trunk, NULL, unref_obj);
6757  struct sla_ringing_trunk *ringing_trunk;
6759  AST_APP_ARG(trunk_name);
6760  AST_APP_ARG(options);
6761  );
6762  char *opts[SLA_TRUNK_OPT_ARG_ARRAY_SIZE] = { NULL, };
6763  struct ast_flags opt_flags = { 0 };
6764  char *parse;
6765 
6766  if (ast_strlen_zero(data)) {
6767  ast_log(LOG_ERROR, "The SLATrunk application requires an argument, the trunk name\n");
6768  return -1;
6769  }
6770 
6771  parse = ast_strdupa(data);
6772  AST_STANDARD_APP_ARGS(args, parse);
6773  if (args.argc == 2) {
6774  if (ast_app_parse_options(sla_trunk_opts, &opt_flags, opts, args.options)) {
6775  ast_log(LOG_ERROR, "Error parsing options for SLATrunk\n");
6776  return -1;
6777  }
6778  }
6779 
6780  trunk = sla_find_trunk(args.trunk_name);
6781 
6782  if (!trunk) {
6783  ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", args.trunk_name);
6784  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
6785  return 0;
6786  }
6787 
6788  if (trunk->chan) {
6789  ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n",
6790  args.trunk_name);
6791  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
6792  return 0;
6793  }
6794 
6795  trunk->chan = chan;
6796 
6797  if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
6798  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
6799  return 0;
6800  }
6801 
6802  snprintf(conf_name, sizeof(conf_name), "SLA_%s", args.trunk_name);
6803  conf = build_conf(conf_name, "", "", 1, 1, 1, chan, NULL);
6804  if (!conf) {
6805  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
6806  return 0;
6807  }
6808  ast_set_flag64(&conf_flags,
6810 
6811  if (ast_test_flag(&opt_flags, SLA_TRUNK_OPT_MOH)) {
6812  ast_indicate(chan, -1);
6813  ast_set_flag64(&conf_flags, CONFFLAG_MOH);
6814  } else
6816 
6817  conf_run(chan, conf, &conf_flags, opts);
6818  dispose_conf(conf);
6819  conf = NULL;
6820  trunk->chan = NULL;
6821  trunk->on_hold = 0;
6822 
6824 
6825  if (!pbx_builtin_getvar_helper(chan, "SLATRUNK_STATUS"))
6826  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
6827 
6828  /* Remove the entry from the list of ringing trunks if it is still there. */
6829  ast_mutex_lock(&sla.lock);
6830  AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
6831  if (ringing_trunk->trunk == trunk) {
6832  AST_LIST_REMOVE_CURRENT(entry);
6833  break;
6834  }
6835  }
6837  ast_mutex_unlock(&sla.lock);
6838  if (ringing_trunk) {
6839  sla_ringing_trunk_destroy(ringing_trunk);
6840  pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
6841  /* Queue reprocessing of ringing trunks to make stations stop ringing
6842  * that shouldn't be ringing after this trunk stopped. */
6844  }
6845 
6846  return 0;
6847 }
static int dispose_conf(struct ast_conference *conf)
Decrement reference counts, as incremented by find_conf()
Definition: app_meetme.c:2097
struct ast_channel * chan
Definition: app_meetme.c:719
#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:4393
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: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
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:5552
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:1213
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define ast_mutex_lock(a)
Definition: lock.h:155
static void sla_queue_event(enum sla_event_type type)
Definition: app_meetme.c:2049
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:206
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struct ast_flags64 *confflags, char *optargs[])
Definition: app_meetme.c:2759
static struct ast_app_option sla_trunk_opts[128]
Definition: app_meetme.c:6749
#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:915
A trunk that is ringing.
Definition: app_meetme.c:936
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct sla_trunk * trunk
Definition: app_meetme.c:937
#define LOG_ERROR
Definition: logger.h:155
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_meetme.c:6728
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define CONFFLAG_NO_AUDIO_UNTIL_UP
Definition: app_meetme.c:626
Structure used to handle boolean flags.
Definition: utils.h:200
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: pbx.c:10546
#define MAX_CONFNUM
Definition: app_meetme.c:693
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
The MeetMe Conference object.
Definition: app_meetme.c:715
static struct sla_ringing_trunk * queue_ringing_trunk(struct sla_trunk *trunk)
Definition: app_meetme.c:6705
static struct @28 sla
A structure for data used by the sla thread.
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_meetme.c:5381
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int sla_trunk_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 6929 of file app_meetme.c.

References ast_str_case_hash(), and sla_trunk::name.

Referenced by sla_load_config().

6930 {
6931  const struct sla_trunk *trunk = obj;
6932 
6933  return ast_str_case_hash(trunk->name);
6934 }
const ast_string_field name
Definition: app_meetme.c:859
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:989
static int sla_trunk_is_marked ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7333 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, sla_trunk_release_refs(), and sla_trunk::stations.

Referenced by sla_load_config().

7334 {
7335  struct sla_trunk *trunk = obj;
7336 
7337  ao2_lock(trunk);
7338 
7339  if (trunk->mark) {
7340  /* Only remove all of the station references if the trunk itself is going away */
7341  sla_trunk_release_refs(trunk, NULL, 0);
7342  } else {
7343  struct sla_station_ref *station_ref;
7344 
7345  /* Otherwise only remove references to stations no longer in the config */
7346  AST_LIST_TRAVERSE_SAFE_BEGIN(&trunk->stations, station_ref, entry) {
7347  if (!station_ref->mark) {
7348  continue;
7349  }
7351  ao2_ref(station_ref, -1);
7352  }
7354  }
7355 
7356  ao2_unlock(trunk);
7357 
7358  return trunk->mark ? CMP_MATCH : 0;
7359 }
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
#define ao2_unlock(a)
Definition: astobj2.h:497
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
unsigned int mark
Definition: app_meetme.c:879
struct sla_station_ref::@35 entry
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#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:6879
unsigned int mark
Definition: app_meetme.c:851
static int sla_trunk_mark ( void *  obj,
void *  arg,
int  flags 
)
static

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

7298 {
7299  struct sla_trunk *trunk = obj;
7300  struct sla_station_ref *station_ref;
7301 
7302  ao2_lock(trunk);
7303 
7304  trunk->mark = 1;
7305 
7306  AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
7307  station_ref->mark = 1;
7308  }
7309 
7310  ao2_unlock(trunk);
7311 
7312  return 0;
7313 }
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
#define ao2_unlock(a)
Definition: astobj2.h:497
unsigned int mark
Definition: app_meetme.c:879
struct sla_station_ref::@35 entry
#define ao2_lock(a)
Definition: astobj2.h:488
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
unsigned int mark
Definition: app_meetme.c:851
static void sla_trunk_ref_destructor ( void *  obj)
static

Definition at line 6681 of file app_meetme.c.

References ao2_ref, and sla_trunk_ref::trunk.

Referenced by create_trunk_ref().

6682 {
6683  struct sla_trunk_ref *trunk_ref = obj;
6684 
6685  if (trunk_ref->trunk) {
6686  ao2_ref(trunk_ref->trunk, -1);
6687  trunk_ref->trunk = NULL;
6688  }
6689 }
struct sla_trunk * trunk
Definition: app_meetme.c:890
#define ao2_ref(o, delta)
Definition: astobj2.h:472
A station&#39;s reference to a trunk.
Definition: app_meetme.c:888
static int sla_trunk_release_refs ( void *  obj,
void *  arg,
int  flags 
)
static

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

6880 {
6881  struct sla_trunk *trunk = obj;
6882  struct sla_station_ref *station_ref;
6883 
6884  while ((station_ref = AST_LIST_REMOVE_HEAD(&trunk->stations, entry))) {
6885  ao2_ref(station_ref, -1);
6886  }
6887 
6888  return 0;
6889 }
A reference to a station.
Definition: app_meetme.c:847
struct sla_trunk::@36 stations
struct sla_station_ref::@35 entry
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static const char* trunkstate2str ( enum sla_trunk_state  state)
static

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

1792 {
1793 #define S(e) case e: return # e;
1794  switch (state) {
1800  }
1801  return "Uknown State";
1802 #undef S
1803 }
#define S(e)
static void tweak_listen_volume ( struct ast_conf_user user,
enum volume_action  action 
)
static

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

1115 {
1116  tweak_volume(&user->listen, action);
1117  /* attempt to make the adjustment in the channel driver;
1118  if successful, don't adjust in the frame reading routine
1119  */
1120  if (!set_listen_volume(user, user->listen.desired))
1121  user->listen.actual = 0;
1122  else
1123  user->listen.actual = user->listen.desired;
1124 }
int actual
Definition: app_meetme.c:765
static void tweak_volume(struct volume *vol, enum volume_action action)
Definition: app_meetme.c:1067
struct volume listen
Definition: app_meetme.c:787
static int set_listen_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1055
int desired
Definition: app_meetme.c:764
static void tweak_talk_volume ( struct ast_conf_user user,
enum volume_action  action 
)
static

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

1103 {
1104  tweak_volume(&user->talk, action);
1105  /* attempt to make the adjustment in the channel driver;
1106  if successful, don't adjust in the frame reading routine
1107  */
1108  if (!set_talk_volume(user, user->talk.desired))
1109  user->talk.actual = 0;
1110  else
1111  user->talk.actual = user->talk.desired;
1112 }
int actual
Definition: app_meetme.c:765
static void tweak_volume(struct volume *vol, enum volume_action action)
Definition: app_meetme.c:1067
static int set_talk_volume(struct ast_conf_user *user, int volume)
Definition: app_meetme.c:1043
int desired
Definition: app_meetme.c:764
struct volume talk
Definition: app_meetme.c:786
static void tweak_volume ( struct volume vol,
enum volume_action  action 
)
static

Definition at line 1067 of file app_meetme.c.

References volume::desired, VOL_DOWN, and VOL_UP.

Referenced by tweak_listen_volume(), and tweak_talk_volume().

1068 {
1069  switch (action) {
1070  case VOL_UP:
1071  switch (vol->desired) {
1072  case 5:
1073  break;
1074  case 0:
1075  vol->desired = 2;
1076  break;
1077  case -2:
1078  vol->desired = 0;
1079  break;
1080  default:
1081  vol->desired++;
1082  break;
1083  }
1084  break;
1085  case VOL_DOWN:
1086  switch (vol->desired) {
1087  case -5:
1088  break;
1089  case 2:
1090  vol->desired = 0;
1091  break;
1092  case 0:
1093  vol->desired = -2;
1094  break;
1095  default:
1096  vol->desired--;
1097  break;
1098  }
1099  }
1100 }
int desired
Definition: app_meetme.c:764
static int unload_module ( void  )
static

Definition at line 7719 of file app_meetme.c.

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

7720 {
7721  int res = 0;
7722 
7724  res = ast_manager_unregister("MeetmeMute");
7725  res |= ast_manager_unregister("MeetmeUnmute");
7726  res |= ast_manager_unregister("MeetmeList");
7733 
7734 #ifdef TEST_FRAMEWORK
7735  AST_TEST_UNREGISTER(test_meetme_data_provider);
7736 #endif
7737  ast_data_unregister(NULL);
7738 
7739  ast_devstate_prov_del("Meetme");
7740  ast_devstate_prov_del("SLA");
7741 
7742  sla_destroy();
7743 
7745  ast_unload_realtime("meetme");
7746 
7747  return res;
7748 }
#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: cli.c:2177
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: config.c:2630
static const char *const app4
Definition: app_meetme.c:679
static const char *const app2
Definition: app_meetme.c:677
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:389
static const char *const slastation_app
Definition: app_meetme.c:680
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
#define ast_data_unregister(path)
Definition: data.h:394
static struct ast_custom_function meetme_info_acf
Definition: app_meetme.c:7529
static void sla_destroy(void)
Definition: app_meetme.c:6957
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static struct ast_cli_entry cli_meetme[]
Definition: app_meetme.c:1885
static const char *const app3
Definition: app_meetme.c:678
static const char *const slatrunk_app
Definition: app_meetme.c:681
static const char *const app
Definition: app_meetme.c:676
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
static int user_add_provider_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 7570 of file app_meetme.c.

References volume::actual, ast_channel_data_add_structure(), ast_data_add_int(), ast_data_add_node(), ast_data_add_structure, ast_conf_user::chan, volume::desired, ast_conf_user::listen, and ast_conf_user::talk.

Referenced by meetme_data_provider_get().

7571 {
7572  struct ast_data *data_meetme_user;
7573  struct ast_data *data_meetme_user_channel;
7574  struct ast_data *data_meetme_user_volume;
7575 
7576  struct ast_conf_user *user = obj;
7577  struct ast_data *data_meetme_users = arg;
7578 
7579  data_meetme_user = ast_data_add_node(data_meetme_users, "user");
7580  if (!data_meetme_user) {
7581  return 0;
7582  }
7583  /* user structure */
7584  ast_data_add_structure(ast_conf_user, data_meetme_user, user);
7585 
7586  /* user's channel */
7587  data_meetme_user_channel = ast_data_add_node(data_meetme_user, "channel");
7588  if (!data_meetme_user_channel) {
7589  return 0;
7590  }
7591 
7592  ast_channel_data_add_structure(data_meetme_user_channel, user->chan, 1);
7593 
7594  /* volume structure */
7595  data_meetme_user_volume = ast_data_add_node(data_meetme_user, "listen-volume");
7596  if (!data_meetme_user_volume) {
7597  return 0;
7598  }
7599  ast_data_add_int(data_meetme_user_volume, "desired", user->listen.desired);
7600  ast_data_add_int(data_meetme_user_volume, "actual", user->listen.actual);
7601 
7602  data_meetme_user_volume = ast_data_add_node(data_meetme_user, "talk-volume");
7603  if (!data_meetme_user_volume) {
7604  return 0;
7605  }
7606  ast_data_add_int(data_meetme_user_volume, "desired", user->talk.desired);
7607  ast_data_add_int(data_meetme_user_volume, "actual", user->talk.actual);
7608 
7609  return 0;
7610 }
The data tree to be returned by the callbacks and managed by functions local to this file...
Definition: data.c:85
int ast_channel_data_add_structure(struct ast_data *tree, struct ast_channel *chan, int add_bridged)
Insert into an astdata tree, the channel structure.
Definition: channel.c:357
int actual
Definition: app_meetme.c:765
struct ast_data * ast_data_add_node(struct ast_data *root, const char *childname)
Add a container child.
Definition: data.c:2317
The MeetMe User object.
Definition: app_meetme.c:769
#define ast_data_add_structure(structure_name, root, structure)
Definition: data.h:620
struct volume listen
Definition: app_meetme.c:787
int desired
Definition: app_meetme.c:764
struct volume talk
Definition: app_meetme.c:786
structure to hold users read from users.conf
struct ast_data * ast_data_add_int(struct ast_data *root, const char *childname, int value)
Add an integer node type.
Definition: data.c:2322
struct ast_channel * chan
Definition: app_meetme.c:773
static int user_chan_cb ( void *  obj,
void *  args,
int  flags 
)
static

Definition at line 4792 of file app_meetme.c.

References args, ast_conf_user::chan, CMP_MATCH, CMP_STOP, and ast_channel::name.

Referenced by channel_admin_exec().

4793 {
4794  struct ast_conf_user *user = obj;
4795  const char *channel = args;
4796 
4797  if (!strcmp(user->chan->name, channel)) {
4798  return (CMP_MATCH | CMP_STOP);
4799  }
4800 
4801  return 0;
4802 }
The MeetMe User object.
Definition: app_meetme.c:769
static struct @350 args
const ast_string_field name
Definition: channel.h:787
structure to hold users read from users.conf
struct ast_channel * chan
Definition: app_meetme.c:773
static int user_listen_voldown_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 4764 of file app_meetme.c.

References tweak_listen_volume(), and VOL_DOWN.

Referenced by admin_exec().

4765 {
4766  struct ast_conf_user *user = obj;
4768  return 0;
4769 }
The MeetMe User object.
Definition: app_meetme.c:769
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1114
structure to hold users read from users.conf
static int user_listen_volup_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 4757 of file app_meetme.c.

References tweak_listen_volume(), and VOL_UP.

Referenced by admin_exec().

4758 {
4759  struct ast_conf_user *user = obj;
4760  tweak_listen_volume(user, VOL_UP);
4761  return 0;
4762 }
The MeetMe User object.
Definition: app_meetme.c:769
static void tweak_listen_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1114
structure to hold users read from users.conf
static int user_max_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1187 of file app_meetme.c.

References ast_conf_user::user_no.

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

1188 {
1189  struct ast_conf_user *user = obj;
1190  int *max_no = arg;
1191 
1192  if (user->user_no > *max_no) {
1193  *max_no = user->user_no;
1194  }
1195 
1196  return 0;
1197 }
The MeetMe User object.
Definition: app_meetme.c:769
structure to hold users read from users.conf
static int user_no_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1175 of file app_meetme.c.

References CMP_MATCH, CMP_STOP, and ast_conf_user::user_no.

Referenced by build_conf().

1176 {
1177  struct ast_conf_user *user = obj;
1178  int *user_no = arg;
1179 
1180  if (user->user_no == *user_no) {
1181  return (CMP_MATCH | CMP_STOP);
1182  }
1183 
1184  return 0;
1185 }
The MeetMe User object.
Definition: app_meetme.c:769
structure to hold users read from users.conf
static int user_reset_vol_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 4785 of file app_meetme.c.

References reset_volumes().

Referenced by admin_exec().

4786 {
4787  struct ast_conf_user *user = obj;
4788  reset_volumes(user);
4789  return 0;
4790 }
The MeetMe User object.
Definition: app_meetme.c:769
static void reset_volumes(struct ast_conf_user *user)
Definition: app_meetme.c:1126
structure to hold users read from users.conf
static int user_set_kickme_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

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

2300 {
2301  struct ast_conf_user *user = obj;
2302  /* actual pointer contents of check_admin_arg is irrelevant */
2303 
2304  if (!check_admin_arg || (check_admin_arg && !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN))) {
2305  user->adminflags |= ADMINFLAG_KICKME;
2306  }
2307  return 0;
2308 }
The MeetMe User object.
Definition: app_meetme.c:769
struct ast_flags64 userflags
Definition: app_meetme.c:771
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int user_set_muted_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

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

2322 {
2323  struct ast_conf_user *user = obj;
2324  /* actual pointer contents of check_admin_arg is irrelevant */
2325 
2326  if (!check_admin_arg || !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN)) {
2327  user->adminflags |= ADMINFLAG_MUTED;
2328  }
2329  return 0;
2330 }
The MeetMe User object.
Definition: app_meetme.c:769
struct ast_flags64 userflags
Definition: app_meetme.c:771
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int user_set_unmuted_cb ( void *  obj,
void *  check_admin_arg,
int  flags 
)
static

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

2311 {
2312  struct ast_conf_user *user = obj;
2313  /* actual pointer contents of check_admin_arg is irrelevant */
2314 
2315  if (!check_admin_arg || !ast_test_flag64(&user->userflags, CONFFLAG_ADMIN)) {
2317  }
2318  return 0;
2319 }
The MeetMe User object.
Definition: app_meetme.c:769
struct ast_flags64 userflags
Definition: app_meetme.c:771
structure to hold users read from users.conf
#define ast_test_flag64(p, flag)
Definition: utils.h:120
static int user_talk_voldown_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 4778 of file app_meetme.c.

References tweak_talk_volume(), and VOL_DOWN.

Referenced by admin_exec().

4779 {
4780  struct ast_conf_user *user = obj;
4781  tweak_talk_volume(user, VOL_DOWN);
4782  return 0;
4783 }
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1102
The MeetMe User object.
Definition: app_meetme.c:769
structure to hold users read from users.conf
static int user_talk_volup_cb ( void *  obj,
void *  unused,
int  flags 
)
static

Definition at line 4771 of file app_meetme.c.

References tweak_talk_volume(), and VOL_UP.

Referenced by admin_exec().

4772 {
4773  struct ast_conf_user *user = obj;
4774  tweak_talk_volume(user, VOL_UP);
4775  return 0;
4776 }
static void tweak_talk_volume(struct ast_conf_user *user, enum volume_action action)
Definition: app_meetme.c:1102
The MeetMe User object.
Definition: app_meetme.c:769
structure to hold users read from users.conf

Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
static

Definition at line 7792 of file app_meetme.c.

const char* const app = "MeetMe"
static

Definition at line 676 of file app_meetme.c.

const char* const app2 = "MeetMeCount"
static

Definition at line 677 of file app_meetme.c.

const char* const app3 = "MeetMeAdmin"
static

Definition at line 678 of file app_meetme.c.

const char* const app4 = "MeetMeChannelAdmin"
static

Definition at line 679 of file app_meetme.c.

Definition at line 7792 of file app_meetme.c.

unsigned int attempt_callerid

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

Definition at line 972 of file app_meetme.c.

int audio_buffers
static

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

Definition at line 979 of file app_meetme.c.

Referenced by conf_run().

struct ast_cli_entry cli_meetme[]
static

Definition at line 1885 of file app_meetme.c.

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

Definition at line 761 of file app_meetme.c.

Referenced by build_conf(), conf_exec(), and dispose_conf().

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

Definition at line 686 of file app_meetme.c.

Referenced by find_conf_realtime().

int endalert
static

Definition at line 687 of file app_meetme.c.

Referenced by find_conf_realtime().

struct { ... } event_q
int extendby
static

Definition at line 688 of file app_meetme.c.

Referenced by rt_extend_conf().

struct { ... } failed_stations
int fuzzystart
static

Definition at line 685 of file app_meetme.c.

Referenced by find_conf_realtime().

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 988 of file app_meetme.c.

Definition at line 964 of file app_meetme.c.

Referenced by ast_localtime_wakeup_monitor(), and smdi_message_wait().

struct ast_data_handler meetme_data_provider
static
Initial value:
= {
}
static int meetme_data_provider_get(const struct ast_data_search *search, struct ast_data *data_root)
Definition: app_meetme.c:7616
#define AST_DATA_HANDLER_VERSION
The Data API structures version.
Definition: data.h:204

Definition at line 7650 of file app_meetme.c.

struct ast_data_entry meetme_data_providers[]
static
Initial value:
= {
AST_DATA_ENTRY("asterisk/application/meetme/list", &meetme_data_provider),
}
#define AST_DATA_ENTRY(__path, __handler)
Definition: data.h:260
static struct ast_data_handler meetme_data_provider
Definition: app_meetme.c:7650

Definition at line 7655 of file app_meetme.c.

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:7478

Definition at line 7529 of file app_meetme.c.

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 }, [ 'i' ] = { .flag = CONFFLAG_INTROUSER }, [ 'I' ] = { .flag = CONFFLAG_INTROUSERNOREVIEW }, [ 'M' ] = { .flag = CONFFLAG_MOH , .arg_index = OPT_ARG_MOH_CLASS + 1 }, [ 'm' ] = { .flag = CONFFLAG_STARTMUTED }, [ 'n' ] = { .flag = (1ULL << 33) }, [ '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 674 of file app_meetme.c.

Referenced by conf_exec(), and find_conf_realtime().

struct { ... } ringing_stations
struct { ... } ringing_trunks
int rt_log_members
static

Log participant count to the RealTime backend

Definition at line 691 of file app_meetme.c.

int rt_schedule
static

Definition at line 684 of file app_meetme.c.

const char sla_registrar[] = "SLA"
static
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 6749 of file app_meetme.c.

Referenced by sla_trunk_exec().

struct ao2_container* sla_trunks
static
const char* const slastation_app = "SLAStation"
static

Definition at line 680 of file app_meetme.c.

const char* const slatrunk_app = "SLATrunk"
static

Definition at line 681 of file app_meetme.c.