Asterisk - The Open Source Telephony Project GIT-master-85241bd
Data Structures | Macros | Enumerations | Functions | Variables
app_sla.c File Reference

Shared Line Appearances. More...

#include "asterisk.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/cli.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/devicestate.h"
#include "asterisk/dial.h"
#include "asterisk/causes.h"
#include "asterisk/format_compatibility.h"
Include dependency graph for app_sla.c:

Go to the source code of this file.

Data Structures

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_framehook_data
 Framehook to support HOLD within the conference. 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...
 

Macros

#define MAX_CONFNUM   80
 
#define S(e)   case e: return # e;
 
#define SLA_CONFIG_FILE   "sla.conf"
 

Enumerations

enum  {
  CONFFLAG_QUIET = (1 << 0) , CONFFLAG_MOH = (1 << 1) , CONFFLAG_MARKEDEXIT = (1 << 2) , CONFFLAG_MARKEDUSER = (1 << 3) ,
  CONFFLAG_PASS_DTMF = (1 << 4) , CONFFLAG_SLA_STATION = (1 << 5) , CONFFLAG_SLA_TRUNK = (1 << 6)
}
 
enum  { SLA_TRUNK_OPT_MOH = (1 << 0) }
 
enum  { SLA_TRUNK_OPT_ARG_MOH_CLASS = 0 , SLA_TRUNK_OPT_ARG_ARRAY_SIZE = 1 }
 
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 }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void answer_trunk_chan (struct ast_channel *chan)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int attach_framehook (struct ast_channel *chan, const char *confname)
 
static int conf_kick_all (struct ast_channel *chan, const char *confname)
 
static int conf_run (struct ast_channel *chan, const char *confname, struct ast_flags *confflags, char *optargs[])
 
static struct sla_trunk_refcreate_trunk_ref (struct sla_trunk *trunk)
 
static void * dial_trunk (void *data)
 
static int load_config (int reload)
 
static int load_module (void)
 Load the module. More...
 
static struct sla_ringing_trunkqueue_ringing_trunk (struct sla_trunk *trunk)
 
static int reload (void)
 
static int remove_framehook (struct ast_channel *chan)
 
static void * run_station (void *data)
 
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 struct ast_framesla_framehook (struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
 
static int sla_framehook_consume (void *data, enum ast_frame_type type)
 Callback function which informs upstream if we are consuming a frame of a specific type. 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, const char *confname)
 Queue a SLA event from the conference. More...
 
static void sla_queue_event_full (enum sla_event_type type, struct sla_trunk_ref *trunk_ref, struct sla_station *station, int lock)
 
static void sla_queue_event_nolock (enum sla_event_type type)
 
static int sla_ring_station (struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
 Ring a station. More...
 
static void sla_ring_stations (void)
 Ring stations based on current set of ringing trunks. More...
 
static void sla_ringing_station_destroy (struct sla_ringing_station *ringing_station)
 
static void sla_ringing_trunk_destroy (struct sla_ringing_trunk *ringing_trunk)
 
static char * sla_show_stations (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * sla_show_trunks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static enum ast_device_state sla_state (const char *data)
 
static enum ast_device_state sla_state_to_devstate (enum sla_trunk_state state)
 
static int sla_station_cmp (void *obj, void *arg, int flags)
 
static void sla_station_destructor (void *obj)
 
static int sla_station_exec (struct ast_channel *chan, const char *data)
 
static int sla_station_is_marked (void *obj, void *arg, int flags)
 
static int sla_station_mark (void *obj, void *arg, int flags)
 
static void sla_station_ref_destructor (void *obj)
 
static int sla_station_release_refs (void *obj, void *arg, int flags)
 
static void sla_stop_ringing_station (struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
 
static void sla_stop_ringing_trunk (struct sla_ringing_trunk *ringing_trunk)
 
static void * sla_thread (void *data)
 
static int sla_trunk_cmp (void *obj, void *arg, int flags)
 
static void sla_trunk_destructor (void *obj)
 
static int sla_trunk_exec (struct ast_channel *chan, const char *data)
 
static int sla_trunk_is_marked (void *obj, void *arg, int flags)
 
static int sla_trunk_mark (void *obj, void *arg, int flags)
 
static void sla_trunk_ref_destructor (void *obj)
 
static int sla_trunk_release_refs (void *obj, void *arg, int flags)
 
static const char * trunkstate2str (enum sla_trunk_state state)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Shared Line Appearances" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_sla []
 
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 struct ast_datastore_info sla_framehook_datastore
 
static const char sla_registrar [] = "SLA"
 
static struct ao2_containersla_stations
 
static const struct ast_app_option sla_trunk_opts [128] = { [ 'M' ] = { .flag = SLA_TRUNK_OPT_MOH , .arg_index = SLA_TRUNK_OPT_ARG_MOH_CLASS + 1 }, }
 
static struct ao2_containersla_trunks
 
static const char *const slastation_app = "SLAStation"
 
static const char *const slatrunk_app = "SLATrunk"
 

Detailed Description

Shared Line Appearances.

Author
Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..org

Definition in file app_sla.c.

Macro Definition Documentation

◆ MAX_CONFNUM

#define MAX_CONFNUM   80

Definition at line 125 of file app_sla.c.

◆ S

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

◆ SLA_CONFIG_FILE

#define SLA_CONFIG_FILE   "sla.conf"

Definition at line 124 of file app_sla.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
CONFFLAG_QUIET 

If set there will be no enter or leave sounds

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_MARKEDUSER 

If set, the user will be marked

CONFFLAG_PASS_DTMF 

Pass DTMF through the conference

CONFFLAG_SLA_STATION 
CONFFLAG_SLA_TRUNK 

Definition at line 130 of file app_sla.c.

130 {
131 /*! If set there will be no enter or leave sounds */
132 CONFFLAG_QUIET = (1 << 0),
133 /*! Set to have music on hold when user is alone in conference */
134 CONFFLAG_MOH = (1 << 1),
135 /*! If set, the channel will leave the conference if all marked users leave */
136 CONFFLAG_MARKEDEXIT = (1 << 2),
137 /*! If set, the user will be marked */
138 CONFFLAG_MARKEDUSER = (1 << 3),
139 /*! Pass DTMF through the conference */
140 CONFFLAG_PASS_DTMF = (1 << 4),
141 CONFFLAG_SLA_STATION = (1 << 5),
142 CONFFLAG_SLA_TRUNK = (1 << 6),
143};
@ CONFFLAG_QUIET
Definition: app_sla.c:132
@ CONFFLAG_MARKEDUSER
Definition: app_sla.c:138
@ CONFFLAG_MARKEDEXIT
Definition: app_sla.c:136
@ CONFFLAG_PASS_DTMF
Definition: app_sla.c:140
@ CONFFLAG_MOH
Definition: app_sla.c:134
@ CONFFLAG_SLA_TRUNK
Definition: app_sla.c:142
@ CONFFLAG_SLA_STATION
Definition: app_sla.c:141

◆ anonymous enum

anonymous enum
Enumerator
SLA_TRUNK_OPT_MOH 

Definition at line 145 of file app_sla.c.

145 {
146 SLA_TRUNK_OPT_MOH = (1 << 0),
147};
@ SLA_TRUNK_OPT_MOH
Definition: app_sla.c:146

◆ anonymous enum

anonymous enum
Enumerator
SLA_TRUNK_OPT_ARG_MOH_CLASS 
SLA_TRUNK_OPT_ARG_ARRAY_SIZE 

Definition at line 149 of file app_sla.c.

149 {
152};
@ SLA_TRUNK_OPT_ARG_MOH_CLASS
Definition: app_sla.c:150
@ SLA_TRUNK_OPT_ARG_ARRAY_SIZE
Definition: app_sla.c:151

◆ sla_event_type

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

Enumerator
SLA_EVENT_HOLD 

A station has put the call on hold

SLA_EVENT_DIAL_STATE 

The state of a dial has changed

SLA_EVENT_RINGING_TRUNK 

The state of a ringing trunk has changed

Definition at line 278 of file app_sla.c.

278 {
279 /*! A station has put the call on hold */
281 /*! The state of a dial has changed */
283 /*! The state of a ringing trunk has changed */
285};
@ SLA_EVENT_RINGING_TRUNK
Definition: app_sla.c:284
@ SLA_EVENT_HOLD
Definition: app_sla.c:280
@ SLA_EVENT_DIAL_STATE
Definition: app_sla.c:282

◆ sla_hold_access

Enumerator
SLA_HOLD_OPEN 

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

SLA_HOLD_PRIVATE 

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

Definition at line 171 of file app_sla.c.

171 {
172 /*! This means that any station can put it on hold, and any station
173 * can retrieve the call from hold. */
175 /*! This means that only the station that put the call on hold may
176 * retrieve it from hold. */
178};
@ SLA_HOLD_OPEN
Definition: app_sla.c:174
@ SLA_HOLD_PRIVATE
Definition: app_sla.c:177

◆ sla_station_hangup

Enumerator
SLA_STATION_HANGUP_NORMAL 
SLA_STATION_HANGUP_TIMEOUT 

Definition at line 311 of file app_sla.c.

311 {
314};
@ SLA_STATION_HANGUP_NORMAL
Definition: app_sla.c:312
@ SLA_STATION_HANGUP_TIMEOUT
Definition: app_sla.c:313

◆ sla_trunk_state

Enumerator
SLA_TRUNK_STATE_IDLE 
SLA_TRUNK_STATE_RINGING 
SLA_TRUNK_STATE_UP 
SLA_TRUNK_STATE_ONHOLD 
SLA_TRUNK_STATE_ONHOLD_BYME 

Definition at line 163 of file app_sla.c.

163 {
169};
@ SLA_TRUNK_STATE_ONHOLD
Definition: app_sla.c:167
@ SLA_TRUNK_STATE_RINGING
Definition: app_sla.c:165
@ SLA_TRUNK_STATE_UP
Definition: app_sla.c:166
@ SLA_TRUNK_STATE_ONHOLD_BYME
Definition: app_sla.c:168
@ SLA_TRUNK_STATE_IDLE
Definition: app_sla.c:164

◆ sla_which_trunk_refs

Enumerator
ALL_TRUNK_REFS 
INACTIVE_TRUNK_REFS 

Definition at line 158 of file app_sla.c.

158 {
161};
@ INACTIVE_TRUNK_REFS
Definition: app_sla.c:160
@ ALL_TRUNK_REFS
Definition: app_sla.c:159

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2875 of file app_sla.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2875 of file app_sla.c.

◆ answer_trunk_chan()

static void answer_trunk_chan ( struct ast_channel chan)
static

Definition at line 911 of file app_sla.c.

912{
913 ast_raw_answer(chan); /* Do NOT use ast_answer since that waits for media using ast_waitfor_nandfds. */
914 ast_indicate(chan, -1);
915}
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
int ast_raw_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2690

References ast_indicate(), ast_raw_answer(), and sla_trunk_ref::chan.

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

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 2875 of file app_sla.c.

◆ attach_framehook()

static int attach_framehook ( struct ast_channel chan,
const char *  confname 
)
static

Definition at line 660 of file app_sla.c.

661{
662 struct ast_datastore *datastore;
663 struct sla_framehook_data *data;
664 static struct ast_framehook_interface sla_framehook_interface = {
666 .event_cb = sla_framehook,
667 .consume_cb = sla_framehook_consume,
668 .disable_inheritance = 1,
669 };
670 SCOPED_CHANNELLOCK(chan_lock, chan);
671
673 if (datastore) {
674 ast_log(AST_LOG_WARNING, "SLA framehook already set on '%s'\n", ast_channel_name(chan));
675 return 0;
676 }
677
679 if (!datastore) {
680 return -1;
681 }
682
683 data = ast_calloc(1, sizeof(*data));
684 if (!data) {
685 ast_datastore_free(datastore);
686 return -1;
687 }
688
689 data->framehook_id = ast_framehook_attach(chan, &sla_framehook_interface);
690 data->confname = ast_strdup(confname);
691 if (!data->confname || data->framehook_id < 0) {
692 ast_log(AST_LOG_WARNING, "Failed to attach SLA framehook to '%s'\n", ast_channel_name(chan));
693 ast_datastore_free(datastore);
694 ast_free(data);
695 return -1;
696 }
697 datastore->data = data;
698
699 ast_channel_datastore_add(chan, datastore);
700 return 0;
701}
static int sla_framehook_consume(void *data, enum ast_frame_type type)
Callback function which informs upstream if we are consuming a frame of a specific type.
Definition: app_sla.c:655
static struct ast_frame * sla_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Definition: app_sla.c:642
static const struct ast_datastore_info sla_framehook_datastore
Definition: app_sla.c:610
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
#define AST_LOG_WARNING
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
#define NULL
Definition: resample.c:96
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Framehook to support HOLD within the conference.
Definition: app_sla.c:605

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_name(), ast_datastore_alloc, ast_datastore_free(), ast_framehook_attach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_free, ast_log, AST_LOG_WARNING, ast_strdup, ast_datastore::data, ast_framehook_interface::data, NULL, SCOPED_CHANNELLOCK, sla_framehook(), sla_framehook_consume(), sla_framehook_datastore, and ast_framehook_interface::version.

Referenced by conf_run().

◆ conf_kick_all()

static int conf_kick_all ( struct ast_channel chan,
const char *  confname 
)
static

Definition at line 952 of file app_sla.c.

953{
954 char confkick_args[256];
955
956 snprintf(confkick_args, sizeof(confkick_args), "%s,all", confname);
957 ast_debug(2, "Kicking all participants from conference %s\n", confname);
958
959 if (chan) {
960 return ast_pbx_exec_application(chan, "ConfKick", confkick_args);
961 } else {
962 /* We might not have a channel available to us, use a dummy channel in that case. */
964 if (!chan) {
965 ast_log(LOG_WARNING, "Failed to allocate dummy channel\n");
966 return -1;
967 } else {
968 int res = ast_pbx_exec_application(chan, "ConfKick", confkick_args);
969 ast_channel_unref(chan);
970 return res;
971 }
972 }
973}
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1282
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
Definition: pbx_app.c:501

References ast_channel_unref, ast_debug, ast_dummy_channel_alloc, ast_log, ast_pbx_exec_application(), sla_trunk_ref::chan, and LOG_WARNING.

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

◆ conf_run()

static int conf_run ( struct ast_channel chan,
const char *  confname,
struct ast_flags confflags,
char *  optargs[] 
)
static

Definition at line 917 of file app_sla.c.

918{
919 char confbridge_args[256];
920 int res = 0;
921
922 snprintf(confbridge_args, sizeof(confbridge_args), "%s", confname);
923
924 res |= ast_func_write(chan, "CONFBRIDGE(user,quiet)", ast_test_flag(confflags, CONFFLAG_QUIET) ? "1" : "0");
925 res |= ast_func_write(chan, "CONFBRIDGE(user,dtmf_passthrough)", ast_test_flag(confflags, CONFFLAG_PASS_DTMF) ? "1" : "0");
926 res |= ast_func_write(chan, "CONFBRIDGE(user,marked)", ast_test_flag(confflags, CONFFLAG_MARKEDUSER) ? "1" : "0");
927 res |= ast_func_write(chan, "CONFBRIDGE(user,end_marked)", ast_test_flag(confflags, CONFFLAG_MARKEDEXIT) ? "1" : "0");
928 res |= ast_func_write(chan, "CONFBRIDGE(user,music_on_hold_when_empty)", ast_test_flag(confflags, CONFFLAG_MOH) ? "1" : "0");
930 res |= ast_func_write(chan, "CONFBRIDGE(user,music_on_hold_class)", optargs[SLA_TRUNK_OPT_ARG_MOH_CLASS]);
931 }
932
933 if (res) {
934 ast_log(LOG_ERROR, "Failed to set up conference, aborting\n");
935 return -1;
936 }
937
938 /* Attach a framehook that we'll use to process HOLD from stations. */
939 if (ast_test_flag(confflags, CONFFLAG_SLA_STATION) && attach_framehook(chan, confname)) {
940 return -1;
941 }
942
943 ast_debug(2, "Channel %s is running ConfBridge(%s)\n", ast_channel_name(chan), confbridge_args);
944 res = ast_pbx_exec_application(chan, "ConfBridge", confbridge_args);
945
946 if (ast_test_flag(confflags, CONFFLAG_SLA_STATION)) {
947 remove_framehook(chan);
948 }
949 return res;
950}
static int remove_framehook(struct ast_channel *chan)
Definition: app_sla.c:614
static int attach_framehook(struct ast_channel *chan, const char *confname)
Definition: app_sla.c:660
#define LOG_ERROR
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_channel_name(), ast_debug, ast_func_write(), ast_log, ast_pbx_exec_application(), ast_strlen_zero(), ast_test_flag, attach_framehook(), sla_trunk_ref::chan, CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_MOH, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_STATION, LOG_ERROR, remove_framehook(), and SLA_TRUNK_OPT_ARG_MOH_CLASS.

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

◆ create_trunk_ref()

static struct sla_trunk_ref * create_trunk_ref ( struct sla_trunk trunk)
static

Definition at line 2106 of file app_sla.c.

2107{
2108 struct sla_trunk_ref *trunk_ref;
2109
2110 if (!(trunk_ref = ao2_alloc(sizeof(*trunk_ref), sla_trunk_ref_destructor))) {
2111 return NULL;
2112 }
2113
2114 ao2_ref(trunk, 1);
2115 trunk_ref->trunk = trunk;
2116
2117 return trunk_ref;
2118}
static void sla_trunk_ref_destructor(void *obj)
Definition: app_sla.c:2096
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
A station's reference to a trunk.
Definition: app_sla.c:255
struct sla_trunk * trunk
Definition: app_sla.c:257

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

Referenced by sla_add_trunk_to_station().

◆ dial_trunk()

static void * dial_trunk ( void *  data)
static

Definition at line 1794 of file app_sla.c.

1795{
1796 struct dial_trunk_args *args = data;
1797 struct ast_dial *dial;
1798 char *tech, *tech_data;
1799 enum ast_dial_result dial_res;
1800 char conf_name[MAX_CONFNUM];
1801 struct ast_flags conf_flags = { 0 };
1802 RAII_VAR(struct sla_trunk_ref *, trunk_ref, args->trunk_ref, ao2_cleanup);
1803 RAII_VAR(struct sla_station *, station, args->station, ao2_cleanup);
1804 int caller_is_saved;
1805 struct ast_party_caller caller;
1806 int last_state = 0;
1807 int current_state = 0;
1808
1809 if (!(dial = ast_dial_create())) {
1810 ast_mutex_lock(args->cond_lock);
1811 ast_cond_signal(args->cond);
1812 ast_mutex_unlock(args->cond_lock);
1813 return NULL;
1814 }
1815
1816 tech_data = ast_strdupa(trunk_ref->trunk->device);
1817 tech = strsep(&tech_data, "/");
1818 if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
1819 ast_mutex_lock(args->cond_lock);
1820 ast_cond_signal(args->cond);
1821 ast_mutex_unlock(args->cond_lock);
1822 ast_dial_destroy(dial);
1823 return NULL;
1824 }
1825
1826 /* Do we need to save of the caller ID data? */
1827 caller_is_saved = 0;
1828 if (!sla.attempt_callerid) {
1829 caller_is_saved = 1;
1830 caller = *ast_channel_caller(trunk_ref->chan);
1831 ast_party_caller_init(ast_channel_caller(trunk_ref->chan));
1832 }
1833
1834 dial_res = ast_dial_run(dial, trunk_ref->chan, 1);
1835
1836 /* Restore saved caller ID */
1837 if (caller_is_saved) {
1838 ast_party_caller_free(ast_channel_caller(trunk_ref->chan));
1839 ast_channel_caller_set(trunk_ref->chan, &caller);
1840 }
1841
1842 if (dial_res != AST_DIAL_RESULT_TRYING) {
1843 ast_mutex_lock(args->cond_lock);
1844 ast_cond_signal(args->cond);
1845 ast_mutex_unlock(args->cond_lock);
1846 ast_dial_destroy(dial);
1847 return NULL;
1848 }
1849
1850 /* Wait for dial to end, while servicing the channel */
1851 while (ast_waitfor(trunk_ref->chan, 100)) {
1852 unsigned int done = 0;
1853 struct ast_frame *fr = ast_read(trunk_ref->chan);
1854
1855 if (!fr) {
1856 ast_debug(1, "Channel %s did not return a frame, must have hung up\n", ast_channel_name(trunk_ref->chan));
1857 done = 1;
1858 break;
1859 }
1860 ast_frfree(fr); /* Ignore while dialing */
1861
1862 switch ((dial_res = ast_dial_state(dial))) {
1864 trunk_ref->trunk->chan = ast_dial_answered(dial);
1870 done = 1;
1871 break;
1873 current_state = AST_CONTROL_PROGRESS;
1874 break;
1878 current_state = AST_CONTROL_RINGING;
1879 break;
1880 }
1881 if (done) {
1882 break;
1883 }
1884
1885 /* check that SLA station that originated trunk call is still alive */
1886 if (station && ast_device_state(station->device) == AST_DEVICE_NOT_INUSE) {
1887 ast_debug(3, "Originating station device %s no longer active\n", station->device);
1888 trunk_ref->trunk->chan = NULL;
1889 break;
1890 }
1891
1892 /* If trunk line state changed, send indication back to originating SLA Station channel */
1893 if (current_state != last_state) {
1894 ast_debug(3, "Indicating State Change %d to channel %s\n", current_state, ast_channel_name(trunk_ref->chan));
1895 ast_indicate(trunk_ref->chan, current_state);
1896 last_state = current_state;
1897 }
1898 }
1899
1900 if (!trunk_ref->trunk->chan) {
1901 ast_mutex_lock(args->cond_lock);
1902 ast_cond_signal(args->cond);
1903 ast_mutex_unlock(args->cond_lock);
1904 ast_dial_join(dial);
1905 ast_dial_destroy(dial);
1906 return NULL;
1907 }
1908
1909 snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
1911
1912 ast_mutex_lock(args->cond_lock);
1913 ast_cond_signal(args->cond);
1914 ast_mutex_unlock(args->cond_lock);
1915
1916 ast_debug(2, "Trunk dial %s joining conference %s\n", trunk_ref->trunk->name, conf_name);
1917 conf_run(trunk_ref->trunk->chan, conf_name, &conf_flags, NULL);
1918
1919 /* If the trunk is going away, it is definitely now IDLE. */
1921
1922 trunk_ref->trunk->chan = NULL;
1923 trunk_ref->trunk->on_hold = 0;
1924
1925 ast_dial_join(dial);
1926 ast_dial_destroy(dial);
1927
1928 return NULL;
1929}
static struct @66 sla
A structure for data used by the sla thread.
static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
Definition: app_sla.c:880
#define MAX_CONFNUM
Definition: app_sla.c:125
static int conf_run(struct ast_channel *chan, const char *confname, struct ast_flags *confflags, char *optargs[])
Definition: app_sla.c:917
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
void ast_channel_caller_set(struct ast_channel *chan, struct ast_party_caller *value)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4257
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:2015
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_caller_init(struct ast_party_caller *init)
Initialize the given caller structure.
Definition: channel.c:1978
ast_device_state
Device States.
Definition: devicestate.h:52
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
enum ast_dial_result ast_dial_state(struct ast_dial *dial)
Return state of dial.
Definition: dial.c:1008
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
@ AST_DIAL_RESULT_FAILED
Definition: dial.h:56
@ AST_DIAL_RESULT_HANGUP
Definition: dial.h:63
@ AST_DIAL_RESULT_INVALID
Definition: dial.h:55
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
@ AST_DIAL_RESULT_TIMEOUT
Definition: dial.h:62
@ AST_DIAL_RESULT_TRYING
Definition: dial.h:57
@ AST_DIAL_RESULT_PROGRESS
Definition: dial.h:59
@ AST_DIAL_RESULT_RINGING
Definition: dial.h:58
@ AST_DIAL_RESULT_PROCEEDING
Definition: dial.h:60
@ AST_DIAL_RESULT_UNANSWERED
Definition: dial.h:64
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:280
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:223
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:977
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:935
enum ast_dial_result ast_dial_join(struct ast_dial *dial)
Cancel async thread.
Definition: dial.c:1017
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
char * strsep(char **str, const char *delims)
#define ast_frfree(fr)
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_RINGING
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203
Main dialing structure. Contains global options, channels being dialed, and more!
Definition: dial.c:48
Structure used to handle boolean flags.
Definition: utils.h:199
Data structure associated with a single frame of data.
Caller Party information.
Definition: channel.h:418
int done
Definition: test_amihooks.c:48
const char * args
#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:941
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ALL_TRUNK_REFS, ao2_cleanup, args, ast_channel_caller(), ast_channel_caller_set(), ast_channel_name(), ast_cond_signal, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, AST_DEVICE_NOT_INUSE, ast_dial_answered(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_join(), AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_HANGUP, AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_RINGING, AST_DIAL_RESULT_TIMEOUT, AST_DIAL_RESULT_TRYING, AST_DIAL_RESULT_UNANSWERED, ast_dial_run(), ast_dial_state(), ast_frfree, ast_indicate(), ast_mutex_lock, ast_mutex_unlock, ast_party_caller_free(), ast_party_caller_init(), ast_read(), ast_set_flag, ast_strdupa, ast_waitfor(), conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_TRUNK, done, MAX_CONFNUM, NULL, RAII_VAR, sla, sla_change_trunk_state(), SLA_TRUNK_STATE_IDLE, and strsep().

Referenced by sla_station_exec().

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 2819 of file app_sla.c.

2820{
2821 return sla_load_config(reload);
2822}
static int sla_load_config(int reload)
Definition: app_sla.c:2753
static int reload(void)
Definition: app_sla.c:2864

References reload(), and sla_load_config().

Referenced by load_module(), and reload().

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 2849 of file app_sla.c.

2850{
2851 int res = 0;
2852
2853 res |= load_config(0);
2854
2858
2859 res |= ast_devstate_prov_add("SLA", sla_state);
2860
2861 return res;
2862}
static const char *const slatrunk_app
Definition: app_sla.c:128
static struct ast_cli_entry cli_sla[]
Definition: app_sla.c:514
static const char *const slastation_app
Definition: app_sla.c:127
static int sla_trunk_exec(struct ast_channel *chan, const char *data)
Definition: app_sla.c:2153
static enum ast_device_state sla_state(const char *data)
Definition: app_sla.c:2244
static int sla_station_exec(struct ast_channel *chan, const char *data)
Definition: app_sla.c:1949
static int load_config(int reload)
Definition: app_sla.c:2819
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback)
Add device state provider.
Definition: devicestate.c:391
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_cli_register_multiple, ast_devstate_prov_add(), ast_register_application_xml, cli_sla, load_config(), sla_state(), sla_station_exec(), sla_trunk_exec(), slastation_app, and slatrunk_app.

◆ queue_ringing_trunk()

static struct sla_ringing_trunk * queue_ringing_trunk ( struct sla_trunk trunk)
static

Definition at line 2120 of file app_sla.c.

2121{
2122 struct sla_ringing_trunk *ringing_trunk;
2123
2124 if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk)))) {
2125 return NULL;
2126 }
2127
2128 ao2_ref(trunk, 1);
2129 ringing_trunk->trunk = trunk;
2130 ringing_trunk->ring_begin = ast_tvnow();
2131
2133
2134 ast_mutex_lock(&sla.lock);
2135 AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
2136 ast_mutex_unlock(&sla.lock);
2137
2139
2140 return ringing_trunk;
2141}
static void sla_queue_event(enum sla_event_type type)
Definition: app_sla.c:555
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
Definition: search.h:40
A trunk that is ringing.
Definition: app_sla.c:303
struct timeval ring_begin
Definition: app_sla.c:306
struct sla_trunk * trunk
Definition: app_sla.c:304
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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

Referenced by sla_trunk_exec().

◆ reload()

static int reload ( void  )
static

Definition at line 2864 of file app_sla.c.

2865{
2866 return load_config(1);
2867}

References load_config().

Referenced by load_config(), and sla_load_config().

◆ remove_framehook()

static int remove_framehook ( struct ast_channel chan)
static

Definition at line 614 of file app_sla.c.

615{
616 struct ast_datastore *datastore = NULL;
617 struct sla_framehook_data *data;
618 SCOPED_CHANNELLOCK(chan_lock, chan);
619
621 if (!datastore) {
622 ast_log(AST_LOG_WARNING, "Cannot remove framehook from %s: HOLD_INTERCEPT not currently enabled\n", ast_channel_name(chan));
623 return -1;
624 }
625 data = datastore->data;
626
627 ast_free(data->confname);
628
629 if (ast_framehook_detach(chan, data->framehook_id)) {
630 ast_log(AST_LOG_WARNING, "Failed to remove framehook from channel %s\n", ast_channel_name(chan));
631 return -1;
632 }
633 if (ast_channel_datastore_remove(chan, datastore)) {
634 ast_log(AST_LOG_WARNING, "Failed to remove datastore from channel %s\n", ast_channel_name(chan));
635 return -1;
636 }
637 ast_datastore_free(datastore);
638
639 return 0;
640}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_name(), ast_datastore_free(), ast_framehook_detach(), ast_free, ast_log, AST_LOG_WARNING, sla_framehook_data::confname, ast_datastore::data, sla_framehook_data::framehook_id, NULL, SCOPED_CHANNELLOCK, and sla_framehook_datastore.

Referenced by conf_run().

◆ run_station()

static void * run_station ( void *  data)
static

Definition at line 975 of file app_sla.c.

976{
977 RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
978 RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
979 struct ast_str *conf_name = ast_str_create(16);
980 struct ast_flags conf_flags = { 0 };
981
982 {
983 struct run_station_args *args = data;
984 station = args->station;
985 trunk_ref = args->trunk_ref;
986 ast_mutex_lock(args->cond_lock);
987 ast_cond_signal(args->cond);
988 ast_mutex_unlock(args->cond_lock);
989 /* args is no longer valid here. */
990 }
991
993 ast_str_set(&conf_name, 0, "SLA_%s", trunk_ref->trunk->name);
996
997 ast_debug(2, "Station %s joining conference %s\n", station->name, ast_str_buffer(conf_name));
998 conf_run(trunk_ref->chan, ast_str_buffer(conf_name), &conf_flags, NULL);
999
1000 trunk_ref->chan = NULL;
1003 conf_kick_all(NULL, ast_str_buffer(conf_name));
1006 }
1007
1010 station->dial = NULL;
1011 ast_free(conf_name);
1012
1013 return NULL;
1014}
static int conf_kick_all(struct ast_channel *chan, const char *confname)
Definition: app_sla.c:952
static void answer_trunk_chan(struct ast_channel *chan)
Definition: app_sla.c:911
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
Definition: lock.h:767
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:1113
Support for dynamic strings.
Definition: strings.h:623
struct sla_station * station
Definition: app_sla.c:905
struct sla_trunk_ref * trunk_ref
Definition: app_sla.c:906
struct ast_dial * dial
Definition: app_sla.c:190
enum sla_trunk_state state
Definition: app_sla.c:258
struct ast_channel * chan
Definition: app_sla.c:259
unsigned int hold_stations
Definition: app_sla.c:233
unsigned int active_stations
Definition: app_sla.c:231
const ast_string_field name
Definition: app_sla.c:226

References sla_trunk::active_stations, ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, args, ast_atomic_dec_and_test(), ast_atomic_fetchadd_int(), ast_cond_signal, ast_debug, ast_dial_destroy(), ast_dial_join(), ast_free, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_str_buffer(), ast_str_create, ast_str_set(), sla_trunk_ref::chan, conf_kick_all(), conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_STATION, sla_station::dial, sla_trunk::hold_stations, sla_trunk::name, NULL, 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().

◆ sla_add_trunk_to_station()

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

Definition at line 2472 of file app_sla.c.

2473{
2474 RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
2475 struct sla_trunk_ref *trunk_ref = NULL;
2476 struct sla_station_ref *station_ref;
2477 char *trunk_name, *options, *cur;
2478 int existing_trunk_ref = 0;
2479 int existing_station_ref = 0;
2480
2481 options = ast_strdupa(var->value);
2482 trunk_name = strsep(&options, ",");
2483
2484 trunk = sla_find_trunk(trunk_name);
2485 if (!trunk) {
2486 ast_log(LOG_ERROR, "Trunk '%s' not found!\n", var->value);
2487 return;
2488 }
2489
2490 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2491 if (trunk_ref->trunk == trunk) {
2492 trunk_ref->mark = 0;
2493 existing_trunk_ref = 1;
2494 break;
2495 }
2496 }
2497
2498 if (!trunk_ref && !(trunk_ref = create_trunk_ref(trunk))) {
2499 return;
2500 }
2501
2502 trunk_ref->state = SLA_TRUNK_STATE_IDLE;
2503
2504 while ((cur = strsep(&options, ","))) {
2505 char *name, *value = cur;
2506 name = strsep(&value, "=");
2507 if (!strcasecmp(name, "ringtimeout")) {
2508 if (sscanf(value, "%30u", &trunk_ref->ring_timeout) != 1) {
2509 ast_log(LOG_WARNING, "Invalid ringtimeout value '%s' for trunk '%s' on station '%s'\n", value, trunk->name, station->name);
2510 trunk_ref->ring_timeout = 0;
2511 }
2512 } else if (!strcasecmp(name, "ringdelay")) {
2513 if (sscanf(value, "%30u", &trunk_ref->ring_delay) != 1) {
2514 ast_log(LOG_WARNING, "Invalid ringdelay value '%s' for trunk '%s' on station '%s'\n", value, trunk->name, station->name);
2515 trunk_ref->ring_delay = 0;
2516 }
2517 } else {
2518 ast_log(LOG_WARNING, "Invalid option '%s' for trunk '%s' on station '%s'\n", name, trunk->name, station->name);
2519 }
2520 }
2521
2522 AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
2523 if (station_ref->station == station) {
2524 station_ref->mark = 0;
2525 existing_station_ref = 1;
2526 break;
2527 }
2528 }
2529
2530 if (!station_ref && !(station_ref = sla_create_station_ref(station))) {
2531 if (!existing_trunk_ref) {
2532 ao2_ref(trunk_ref, -1);
2533 } else {
2534 trunk_ref->mark = 1;
2535 }
2536 return;
2537 }
2538
2539 if (!existing_station_ref) {
2540 ao2_lock(trunk);
2541 AST_LIST_INSERT_TAIL(&trunk->stations, station_ref, entry);
2542 ast_atomic_fetchadd_int((int *) &trunk->num_stations, 1);
2543 ao2_unlock(trunk);
2544 }
2545
2546 if (!existing_trunk_ref) {
2550 }
2551}
static struct sla_station_ref * sla_create_station_ref(struct sla_station *station)
Definition: app_sla.c:799
static struct sla_trunk_ref * create_trunk_ref(struct sla_trunk *trunk)
Definition: app_sla.c:2106
static struct sla_trunk * sla_find_trunk(const char *name)
Definition: app_sla.c:707
#define var
Definition: ast_expr2f.c:605
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
static const char name[]
Definition: format_mp3.c:68
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
A reference to a station.
Definition: app_sla.c:214
struct sla_station * station
Definition: app_sla.c:216
unsigned int mark
Definition: app_sla.c:218
unsigned int ring_timeout
Definition: app_sla.c:263
unsigned int ring_delay
Definition: app_sla.c:267
unsigned int mark
Definition: app_sla.c:269
int value
Definition: syslog.c:37
static struct test_options options

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

Referenced by sla_build_station().

◆ sla_build_station()

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

Definition at line 2553 of file app_sla.c.

2554{
2555 RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
2556 struct ast_variable *var;
2557 const char *dev;
2558 int existing_station = 0;
2559
2560 if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
2561 ast_log(LOG_ERROR, "SLA Station '%s' defined with no device!\n", cat);
2562 return -1;
2563 }
2564
2565 if ((station = sla_find_station(cat))) {
2566 station->mark = 0;
2567 existing_station = 1;
2568 } else if ((station = ao2_alloc(sizeof(*station), sla_station_destructor))) {
2569 if (ast_string_field_init(station, 32)) {
2570 return -1;
2571 }
2572 ast_string_field_set(station, name, cat);
2573 } else {
2574 return -1;
2575 }
2576
2577 ao2_lock(station);
2578
2579 ast_string_field_set(station, device, dev);
2580
2581 for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
2582 if (!strcasecmp(var->name, "trunk")) {
2583 ao2_unlock(station);
2584 sla_add_trunk_to_station(station, var);
2585 ao2_lock(station);
2586 } else if (!strcasecmp(var->name, "autocontext")) {
2587 ast_string_field_set(station, autocontext, var->value);
2588 } else if (!strcasecmp(var->name, "ringtimeout")) {
2589 if (sscanf(var->value, "%30u", &station->ring_timeout) != 1) {
2590 ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for station '%s'\n", var->value, station->name);
2591 station->ring_timeout = 0;
2592 }
2593 } else if (!strcasecmp(var->name, "ringdelay")) {
2594 if (sscanf(var->value, "%30u", &station->ring_delay) != 1) {
2595 ast_log(LOG_WARNING, "Invalid ringdelay '%s' specified for station '%s'\n", var->value, station->name);
2596 station->ring_delay = 0;
2597 }
2598 } else if (!strcasecmp(var->name, "hold")) {
2599 if (!strcasecmp(var->value, "private")) {
2600 station->hold_access = SLA_HOLD_PRIVATE;
2601 } else if (!strcasecmp(var->value, "open")) {
2602 station->hold_access = SLA_HOLD_OPEN;
2603 } else {
2604 ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n", var->value, station->name);
2605 }
2606 } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
2607 ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", var->name, var->lineno, SLA_CONFIG_FILE);
2608 }
2609 }
2610
2611 ao2_unlock(station);
2612
2613 if (!ast_strlen_zero(station->autocontext)) {
2614 struct sla_trunk_ref *trunk_ref;
2615
2616 if (!ast_context_find_or_create(NULL, NULL, station->autocontext, sla_registrar)) {
2617 ast_log(LOG_ERROR, "Failed to automatically find or create context '%s' for SLA!\n", station->autocontext);
2618 return -1;
2619 }
2620 /* The extension for when the handset goes off-hook.
2621 * exten => station1,1,SLAStation(station1) */
2622 if (ast_add_extension(station->autocontext, 0 /* don't replace */, station->name, 1,
2624 ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", station->name);
2625 return -1;
2626 }
2627 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2628 char exten[AST_MAX_EXTENSION];
2629 char hint[AST_MAX_EXTENSION + 5];
2630 snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
2631 snprintf(hint, sizeof(hint), "SLA:%s", exten);
2632 /* Extension for this line button
2633 * exten => station1_line1,1,SLAStation(station1_line1) */
2634 if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, 1,
2636 ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", station->name);
2637 return -1;
2638 }
2639 /* Hint for this line button
2640 * exten => station1_line1,hint,SLA:station1_line1 */
2641 if (ast_add_extension(station->autocontext, 0 /* don't replace */, exten, PRIORITY_HINT,
2642 NULL, NULL, hint, NULL, NULL, sla_registrar)) {
2643 ast_log(LOG_ERROR, "Failed to automatically create hint for trunk '%s'!\n", station->name);
2644 return -1;
2645 }
2646 }
2647 }
2648
2649 if (!existing_station) {
2650 ao2_link(sla_stations, station);
2651 }
2652
2653 return 0;
2654}
static struct ao2_container * sla_stations
Definition: app_sla.c:272
static void sla_add_trunk_to_station(struct sla_station *station, struct ast_variable *var)
Definition: app_sla.c:2472
#define SLA_CONFIG_FILE
Definition: app_sla.c:124
static struct sla_station * sla_find_station(const char *name)
Definition: app_sla.c:720
static void sla_station_destructor(void *obj)
Definition: app_sla.c:2297
static const char sla_registrar[]
Definition: app_sla.c:275
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define AST_MAX_EXTENSION
Definition: channel.h:134
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6928
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:6149
#define PRIORITY_HINT
Definition: pbx.h:54
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Structure for variables, used for configurations and for channel variables.

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

Referenced by sla_load_config().

◆ sla_build_trunk()

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

Definition at line 2390 of file app_sla.c.

2391{
2392 RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
2393 struct ast_variable *var;
2394 const char *dev;
2395 int existing_trunk = 0;
2396
2397 if (!(dev = ast_variable_retrieve(cfg, cat, "device"))) {
2398 ast_log(LOG_ERROR, "SLA Trunk '%s' defined with no device!\n", cat);
2399 return -1;
2400 }
2401
2402 if (sla_check_device(dev)) {
2403 ast_log(LOG_ERROR, "SLA Trunk '%s' defined with invalid device '%s'!\n", cat, dev);
2404 return -1;
2405 }
2406
2407 if ((trunk = sla_find_trunk(cat))) {
2408 trunk->mark = 0;
2409 existing_trunk = 1;
2410 } else if ((trunk = ao2_alloc(sizeof(*trunk), sla_trunk_destructor))) {
2411 if (ast_string_field_init(trunk, 32)) {
2412 return -1;
2413 }
2414 ast_string_field_set(trunk, name, cat);
2415 } else {
2416 return -1;
2417 }
2418
2419 ao2_lock(trunk);
2420
2421 ast_string_field_set(trunk, device, dev);
2422
2423 for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
2424 if (!strcasecmp(var->name, "autocontext")) {
2425 ast_string_field_set(trunk, autocontext, var->value);
2426 } else if (!strcasecmp(var->name, "ringtimeout")) {
2427 if (sscanf(var->value, "%30u", &trunk->ring_timeout) != 1) {
2428 ast_log(LOG_WARNING, "Invalid ringtimeout '%s' specified for trunk '%s'\n", var->value, trunk->name);
2429 trunk->ring_timeout = 0;
2430 }
2431 } else if (!strcasecmp(var->name, "barge")) {
2432 trunk->barge_disabled = ast_false(var->value);
2433 } else if (!strcasecmp(var->name, "hold")) {
2434 if (!strcasecmp(var->value, "private")) {
2435 trunk->hold_access = SLA_HOLD_PRIVATE;
2436 } else if (!strcasecmp(var->value, "open")) {
2437 trunk->hold_access = SLA_HOLD_OPEN;
2438 } else {
2439 ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n", var->value, trunk->name);
2440 }
2441 } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
2442 ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", var->name, var->lineno, SLA_CONFIG_FILE);
2443 }
2444 }
2445
2446 ao2_unlock(trunk);
2447
2448 if (!ast_strlen_zero(trunk->autocontext)) {
2449 if (!ast_context_find_or_create(NULL, NULL, trunk->autocontext, sla_registrar)) {
2450 ast_log(LOG_ERROR, "Failed to automatically find or create context '%s' for SLA!\n", trunk->autocontext);
2451 return -1;
2452 }
2453
2454 if (ast_add_extension(trunk->autocontext, 0 /* don't replace */, "s", 1,
2456 ast_log(LOG_ERROR, "Failed to automatically create extension for trunk '%s'!\n", trunk->name);
2457 return -1;
2458 }
2459 }
2460
2461 if (!existing_trunk) {
2462 ao2_link(sla_trunks, trunk);
2463 }
2464
2465 return 0;
2466}
static int sla_check_device(const char *device)
Definition: app_sla.c:2361
static void sla_trunk_destructor(void *obj)
Definition: app_sla.c:2375
static struct ao2_container * sla_trunks
Definition: app_sla.c:273
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

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

Referenced by sla_load_config().

◆ sla_calc_station_delays()

static int sla_calc_station_delays ( unsigned int *  timeout)
static

Calculate the ring delay for a station.

Note
Assumes sla.lock is locked

Definition at line 1625 of file app_sla.c.

1626{
1627 struct sla_station *station;
1628 int res = 0;
1629 struct ao2_iterator i;
1630
1632 for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
1633 struct sla_ringing_trunk *ringing_trunk;
1634 int time_left;
1635
1636 /* Ignore stations already ringing */
1637 if (sla_check_ringing_station(station)) {
1638 continue;
1639 }
1640
1641 /* Ignore stations already on a call */
1642 if (sla_check_inuse_station(station)) {
1643 continue;
1644 }
1645
1646 /* Ignore stations that don't have one of their trunks ringing */
1647 if (!(ringing_trunk = sla_choose_ringing_trunk(station, NULL, 0))) {
1648 continue;
1649 }
1650
1651 if ((time_left = sla_check_station_delay(station, ringing_trunk)) == INT_MAX) {
1652 continue;
1653 }
1654
1655 /* If there is no time left, then the station needs to start ringing.
1656 * Return non-zero so that an event will be queued up an event to
1657 * make that happen. */
1658 if (time_left <= 0) {
1659 res = 1;
1660 continue;
1661 }
1662
1663 if (time_left < *timeout) {
1664 *timeout = time_left;
1665 }
1666 }
1668
1669 return res;
1670}
static int sla_check_inuse_station(const struct sla_station *station)
Check to see if a station is in use.
Definition: app_sla.c:1324
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_sla.c:1099
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_sla.c:1357
static int sla_check_ringing_station(const struct sla_station *station)
Check to see if this station is already ringing.
Definition: app_sla.c:1223
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

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

Referenced by sla_process_timers().

◆ sla_calc_station_timeouts()

static int sla_calc_station_timeouts ( unsigned int *  timeout)
static

Process station ring timeouts.

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

Definition at line 1533 of file app_sla.c.

1534{
1535 struct sla_ringing_trunk *ringing_trunk;
1536 struct sla_ringing_station *ringing_station;
1537 int res = 0;
1538
1539 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
1540 unsigned int ring_timeout = 0;
1541 int time_elapsed, time_left = INT_MAX, final_trunk_time_left = INT_MIN;
1542 struct sla_trunk_ref *trunk_ref;
1543
1544 /* If there are any ring timeouts specified for a specific trunk
1545 * on the station, then use the highest per-trunk ring timeout.
1546 * Otherwise, use the ring timeout set for the entire station. */
1547 AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
1548 struct sla_station_ref *station_ref;
1549 int trunk_time_elapsed, trunk_time_left;
1550
1551 AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
1552 if (ringing_trunk->trunk == trunk_ref->trunk) {
1553 break;
1554 }
1555 }
1556 if (!ringing_trunk) {
1557 continue;
1558 }
1559
1560 /* If there is a trunk that is ringing without a timeout, then the
1561 * only timeout that could matter is a global station ring timeout. */
1562 if (!trunk_ref->ring_timeout) {
1563 break;
1564 }
1565
1566 /* This trunk on this station is ringing and has a timeout.
1567 * However, make sure this trunk isn't still ringing from a
1568 * previous timeout. If so, don't consider it. */
1569 AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, station_ref, entry) {
1570 if (station_ref->station == ringing_station->station) {
1571 break;
1572 }
1573 }
1574 if (station_ref) {
1575 continue;
1576 }
1577
1578 trunk_time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
1579 trunk_time_left = (trunk_ref->ring_timeout * 1000) - trunk_time_elapsed;
1580 if (trunk_time_left > final_trunk_time_left) {
1581 final_trunk_time_left = trunk_time_left;
1582 }
1583 }
1584
1585 /* No timeout was found for ringing trunks, and no timeout for the entire station */
1586 if (final_trunk_time_left == INT_MIN && !ringing_station->station->ring_timeout) {
1587 continue;
1588 }
1589
1590 /* Compute how much time is left for a global station timeout */
1591 if (ringing_station->station->ring_timeout) {
1592 ring_timeout = ringing_station->station->ring_timeout;
1593 time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
1594 time_left = (ring_timeout * 1000) - time_elapsed;
1595 }
1596
1597 /* If the time left based on the per-trunk timeouts is smaller than the
1598 * global station ring timeout, use that. */
1599 if (final_trunk_time_left > INT_MIN && final_trunk_time_left < time_left) {
1600 time_left = final_trunk_time_left;
1601 }
1602
1603 /* If there is no time left, the station needs to stop ringing */
1604 if (time_left <= 0) {
1607 res = 1;
1608 continue;
1609 }
1610
1611 /* There is still some time left for this station to ring, so save that
1612 * timeout if it is the first event scheduled to occur */
1613 if (time_left < *timeout) {
1614 *timeout = time_left;
1615 }
1616 }
1618
1619 return res;
1620}
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station, enum sla_station_hangup hangup)
Definition: app_sla.c:1032
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
A station that is ringing.
Definition: app_sla.c:317
struct sla_station * station
Definition: app_sla.c:318
struct timeval ring_begin
Definition: app_sla.c:320
struct sla_ringing_trunk::@72 timed_out_stations
unsigned int ring_timeout
Definition: app_sla.c:194
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

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

◆ sla_calc_trunk_timeouts()

static int sla_calc_trunk_timeouts ( unsigned int *  timeout)
static

Process trunk ring timeouts.

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

Definition at line 1501 of file app_sla.c.

1502{
1503 struct sla_ringing_trunk *ringing_trunk;
1504 int res = 0;
1505
1506 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
1507 int time_left, time_elapsed;
1508 if (!ringing_trunk->trunk->ring_timeout) {
1509 continue;
1510 }
1511 time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
1512 time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
1513 if (time_left <= 0) {
1514 pbx_builtin_setvar_helper(ringing_trunk->trunk->chan, "SLATRUNK_STATUS", "RINGTIMEOUT");
1516 sla_stop_ringing_trunk(ringing_trunk);
1517 res = 1;
1518 continue;
1519 }
1520 if (time_left < *timeout) {
1521 *timeout = time_left;
1522 }
1523 }
1525
1526 return res;
1527}
static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
Definition: app_sla.c:1018
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.
unsigned int ring_timeout
Definition: app_sla.c:235
struct ast_channel * chan
Definition: app_sla.c:234

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

◆ sla_change_trunk_state()

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

Definition at line 880 of file app_sla.c.

882{
883 struct sla_station *station;
884 struct sla_trunk_ref *trunk_ref;
885 struct ao2_iterator i;
886
888 while ((station = ao2_iterator_next(&i))) {
889 ao2_lock(station);
890 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
891 if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0) || trunk_ref == exclude) {
892 continue;
893 }
894 trunk_ref->state = state;
895 ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE, "SLA:%s_%s", station->name, trunk->name);
896 break;
897 }
898 ao2_unlock(station);
899 ao2_ref(station, -1);
900 }
902}
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
Definition: app_sla.c:863
enum cc_state state
Definition: ccss.c:393
@ AST_DEVSTATE_CACHABLE
Definition: devicestate.h:70
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510

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, sla_trunk_ref::state, 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().

◆ sla_check_device()

static int sla_check_device ( const char *  device)
static

Definition at line 2361 of file app_sla.c.

2362{
2363 char *tech, *tech_data;
2364
2365 tech_data = ast_strdupa(device);
2366 tech = strsep(&tech_data, "/");
2367
2368 if (ast_strlen_zero(tech) || ast_strlen_zero(tech_data)) {
2369 return -1;
2370 }
2371
2372 return 0;
2373}

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

Referenced by sla_build_trunk().

◆ sla_check_failed_station()

static int sla_check_failed_station ( const struct sla_station station)
static

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

Note
assumes sla.lock is locked

Definition at line 1239 of file app_sla.c.

1240{
1241 struct sla_failed_station *failed_station;
1242 int res = 0;
1243
1244 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.failed_stations, failed_station, entry) {
1245 if (station != failed_station->station) {
1246 continue;
1247 }
1248 if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
1250 sla_failed_station_destroy(failed_station);
1251 break;
1252 }
1253 res = 1;
1254 }
1256
1257 return res;
1258}
static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
Definition: app_sla.c:853
A station that failed to be dialed.
Definition: app_sla.c:296
struct sla_station * station
Definition: app_sla.c:297
struct timeval last_try
Definition: app_sla.c:298

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

◆ sla_check_inuse_station()

static int sla_check_inuse_station ( const struct sla_station station)
static

Check to see if a station is in use.

Definition at line 1324 of file app_sla.c.

1325{
1326 struct sla_trunk_ref *trunk_ref;
1327
1328 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
1329 if (trunk_ref->chan) {
1330 return 1;
1331 }
1332 }
1333
1334 return 0;
1335}

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

Referenced by sla_calc_station_delays(), and sla_ring_stations().

◆ sla_check_ringing_station()

static int sla_check_ringing_station ( const struct sla_station station)
static

Check to see if this station is already ringing.

Note
Assumes sla.lock is locked

Definition at line 1223 of file app_sla.c.

1224{
1225 struct sla_ringing_station *ringing_station;
1226
1227 AST_LIST_TRAVERSE(&sla.ringing_stations, ringing_station, entry) {
1228 if (station == ringing_station->station) {
1229 return 1;
1230 }
1231 }
1232
1233 return 0;
1234}

References AST_LIST_TRAVERSE, sla, and sla_ringing_station::station.

Referenced by sla_calc_station_delays(), and sla_ring_stations().

◆ sla_check_station_delay()

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

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

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

Definition at line 1357 of file app_sla.c.

1358{
1359 RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
1360 unsigned int delay = UINT_MAX;
1361 int time_left, time_elapsed;
1362
1363 if (!ringing_trunk) {
1364 ringing_trunk = sla_choose_ringing_trunk(station, &trunk_ref, 0);
1365 } else {
1366 trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk);
1367 }
1368
1369 if (!ringing_trunk || !trunk_ref) {
1370 return delay;
1371 }
1372
1373 /* If this station has a ring delay specific to the highest priority
1374 * ringing trunk, use that. Otherwise, use the ring delay specified
1375 * globally for the station. */
1376 delay = trunk_ref->ring_delay;
1377 if (!delay) {
1378 delay = station->ring_delay;
1379 }
1380 if (!delay) {
1381 return INT_MAX;
1382 }
1383
1384 time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
1385 time_left = (delay * 1000) - time_elapsed;
1386
1387 return time_left;
1388}
static struct sla_trunk_ref * sla_find_trunk_ref(const struct sla_station *station, const struct sla_trunk *trunk)
Definition: app_sla.c:1337
unsigned int ring_delay
Definition: app_sla.c:198

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

Referenced by sla_calc_station_delays(), and sla_ring_stations().

◆ sla_check_station_hold_access()

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

Definition at line 729 of file app_sla.c.

730{
731 struct sla_station_ref *station_ref;
732 struct sla_trunk_ref *trunk_ref;
733
734 /* For each station that has this call on hold, check for private hold. */
735 AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
736 AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
737 if (trunk_ref->trunk != trunk || station_ref->station == station) {
738 continue;
739 }
740 if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME && station_ref->station->hold_access == SLA_HOLD_PRIVATE) {
741 return 1;
742 }
743 return 0;
744 }
745 }
746
747 return 0;
748}
unsigned int hold_access
Definition: app_sla.c:201
struct sla_trunk::@68 stations

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

◆ sla_check_timed_out_station()

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

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

Note
Assumes sla.lock is locked

Definition at line 1078 of file app_sla.c.

1079{
1080 struct sla_station_ref *timed_out_station;
1081
1082 AST_LIST_TRAVERSE(&ringing_trunk->timed_out_stations, timed_out_station, entry) {
1083 if (station == timed_out_station->station) {
1084 return 1;
1085 }
1086 }
1087
1088 return 0;
1089}

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

◆ sla_choose_idle_trunk()

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

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

Precondition
sla_station is locked

Definition at line 1935 of file app_sla.c.

1936{
1937 struct sla_trunk_ref *trunk_ref = NULL;
1938
1939 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
1940 if (trunk_ref->state == SLA_TRUNK_STATE_IDLE) {
1941 ao2_ref(trunk_ref, 1);
1942 break;
1943 }
1944 }
1945
1946 return trunk_ref;
1947}

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

Referenced by sla_station_exec().

◆ sla_choose_ringing_trunk()

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

Choose the highest priority ringing trunk for a station.

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

Definition at line 1099 of file app_sla.c.

1100{
1101 struct sla_trunk_ref *s_trunk_ref;
1102 struct sla_ringing_trunk *ringing_trunk = NULL;
1103
1104 AST_LIST_TRAVERSE(&station->trunks, s_trunk_ref, entry) {
1105 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
1106 /* Make sure this is the trunk we're looking for */
1107 if (s_trunk_ref->trunk != ringing_trunk->trunk) {
1108 continue;
1109 }
1110
1111 /* This trunk on the station is ringing. But, make sure this station
1112 * didn't already time out while this trunk was ringing. */
1113 if (sla_check_timed_out_station(ringing_trunk, station)) {
1114 continue;
1115 }
1116
1117 if (rm) {
1119 }
1120
1121 if (trunk_ref) {
1122 ao2_ref(s_trunk_ref, 1);
1123 *trunk_ref = s_trunk_ref;
1124 }
1125
1126 break;
1127 }
1129
1130 if (ringing_trunk) {
1131 break;
1132 }
1133 }
1134
1135 return ringing_trunk;
1136}
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_sla.c:1078

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

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

◆ sla_create_failed_station()

static struct sla_failed_station * sla_create_failed_station ( struct sla_station station)
static

Definition at line 838 of file app_sla.c.

839{
840 struct sla_failed_station *failed_station;
841
842 if (!(failed_station = ast_calloc(1, sizeof(*failed_station)))) {
843 return NULL;
844 }
845
846 ao2_ref(station, 1);
847 failed_station->station = station;
848 failed_station->last_try = ast_tvnow();
849
850 return failed_station;
851}

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

Referenced by sla_ring_station().

◆ sla_create_ringing_station()

static struct sla_ringing_station * sla_create_ringing_station ( struct sla_station station)
static

Definition at line 813 of file app_sla.c.

814{
815 struct sla_ringing_station *ringing_station;
816
817 if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station)))) {
818 return NULL;
819 }
820
821 ao2_ref(station, 1);
822 ringing_station->station = station;
823 ringing_station->ring_begin = ast_tvnow();
824
825 return ringing_station;
826}

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

Referenced by sla_ring_station().

◆ sla_create_station_ref()

static struct sla_station_ref * sla_create_station_ref ( struct sla_station station)
static

Definition at line 799 of file app_sla.c.

800{
801 struct sla_station_ref *station_ref;
802
803 if (!(station_ref = ao2_alloc(sizeof(*station_ref), sla_station_ref_destructor))) {
804 return NULL;
805 }
806
807 ao2_ref(station, 1);
808 station_ref->station = station;
809
810 return station_ref;
811}
static void sla_station_ref_destructor(void *obj)
Definition: app_sla.c:789

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

Referenced by sla_add_trunk_to_station(), and sla_stop_ringing_station().

◆ sla_destroy()

static void sla_destroy ( void  )
static

Definition at line 2335 of file app_sla.c.

2336{
2337 if (sla.thread != AST_PTHREADT_NULL) {
2338 ast_mutex_lock(&sla.lock);
2339 sla.stop = 1;
2340 ast_cond_signal(&sla.cond);
2341 ast_mutex_unlock(&sla.lock);
2342 pthread_join(sla.thread, NULL);
2343 }
2344
2345 /* Drop any created contexts from the dialplan */
2347
2348 ast_mutex_destroy(&sla.lock);
2349 ast_cond_destroy(&sla.cond);
2350
2353
2354 ao2_ref(sla_trunks, -1);
2355 sla_trunks = NULL;
2356
2357 ao2_ref(sla_stations, -1);
2359}
static int sla_trunk_release_refs(void *obj, void *arg, int flags)
Definition: app_sla.c:2273
static int sla_station_release_refs(void *obj, void *arg, int flags)
Definition: app_sla.c:2285
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_destroy(a)
Definition: lock.h:188
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:8221

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

Referenced by unload_module().

◆ sla_dial_state_callback()

static void sla_dial_state_callback ( struct ast_dial dial)
static

Definition at line 1070 of file app_sla.c.

References SLA_EVENT_DIAL_STATE, and sla_queue_event().

Referenced by sla_ring_station().

◆ sla_event_destroy()

static void sla_event_destroy ( struct sla_event event)
static

Definition at line 1714 of file app_sla.c.

1715{
1716 if (event->trunk_ref) {
1717 ao2_ref(event->trunk_ref, -1);
1718 event->trunk_ref = NULL;
1719 }
1720
1721 if (event->station) {
1722 ao2_ref(event->station, -1);
1723 event->station = NULL;
1724 }
1725
1726 ast_free(event);
1727}
Definition: astman.c:222

References ao2_ref, ast_free, and NULL.

Referenced by sla_thread().

◆ sla_failed_station_destroy()

static void sla_failed_station_destroy ( struct sla_failed_station failed_station)
static

Definition at line 853 of file app_sla.c.

854{
855 if (failed_station->station) {
856 ao2_ref(failed_station->station, -1);
857 failed_station->station = NULL;
858 }
859
860 ast_free(failed_station);
861}

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

Referenced by sla_check_failed_station(), and sla_thread().

◆ sla_find_station()

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

Definition at line 720 of file app_sla.c.

721{
722 struct sla_station tmp_station = {
723 .name = name,
724 };
725
726 return ao2_find(sla_stations, &tmp_station, OBJ_POINTER);
727}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, name, OBJ_POINTER, and sla_stations.

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

◆ sla_find_trunk()

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

Definition at line 707 of file app_sla.c.

708{
709 struct sla_trunk tmp_trunk = {
710 .name = name,
711 };
712
713 return ao2_find(sla_trunks, &tmp_trunk, OBJ_POINTER);
714}

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

◆ sla_find_trunk_ref()

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

Definition at line 1337 of file app_sla.c.

1338{
1339 struct sla_trunk_ref *trunk_ref = NULL;
1340
1341 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
1342 if (trunk_ref->trunk == trunk) {
1343 break;
1344 }
1345 }
1346
1347 ao2_ref(trunk_ref, 1);
1348
1349 return trunk_ref;
1350}

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

Referenced by sla_check_station_delay().

◆ sla_find_trunk_ref_byname()

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

Find a trunk reference on a station by name.

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

Definition at line 759 of file app_sla.c.

760{
761 struct sla_trunk_ref *trunk_ref = NULL;
762
763 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
764 if (strcasecmp(trunk_ref->trunk->name, name)) {
765 continue;
766 }
767
768 if (trunk_ref->trunk->barge_disabled && trunk_ref->state == SLA_TRUNK_STATE_UP) {
769 ast_debug(2, "Barge disabled, trunk not available\n");
770 trunk_ref = NULL;
771 } else if (trunk_ref->trunk->hold_stations && trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE && trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
772 ast_debug(2, "Private hold by another station\n");
773 trunk_ref = NULL;
774 } else if (sla_check_station_hold_access(trunk_ref->trunk, station)) {
775 ast_debug(2, "No hold access\n");
776 trunk_ref = NULL;
777 }
778
779 break;
780 }
781
782 if (trunk_ref) {
783 ao2_ref(trunk_ref, 1);
784 }
785
786 return trunk_ref;
787}
static int sla_check_station_hold_access(const struct sla_trunk *trunk, const struct sla_station *station)
Definition: app_sla.c:729
unsigned int barge_disabled
Definition: app_sla.c:238
unsigned int hold_access
Definition: app_sla.c:241

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

Referenced by sla_station_exec().

◆ sla_framehook()

static struct ast_frame * sla_framehook ( struct ast_channel chan,
struct ast_frame f,
enum ast_framehook_event  event,
void *  data 
)
static

Definition at line 642 of file app_sla.c.

643{
644 struct sla_framehook_data *sla_data = data;
645 if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
646 return f;
647 }
650 }
651 return f;
652}
static void sla_queue_event_conf(enum sla_event_type type, struct ast_channel *chan, const char *confname)
Queue a SLA event from the conference.
Definition: app_sla.c:561
@ AST_FRAMEHOOK_EVENT_WRITE
Definition: framehook.h:153
@ AST_FRAME_CONTROL
@ AST_CONTROL_HOLD
struct ast_frame_subclass subclass
enum ast_frame_type frametype

References AST_CONTROL_HOLD, AST_FRAME_CONTROL, AST_FRAMEHOOK_EVENT_WRITE, sla_framehook_data::confname, ast_frame::frametype, ast_frame_subclass::integer, SLA_EVENT_HOLD, sla_queue_event_conf(), and ast_frame::subclass.

Referenced by attach_framehook().

◆ sla_framehook_consume()

static int sla_framehook_consume ( void *  data,
enum ast_frame_type  type 
)
static

Callback function which informs upstream if we are consuming a frame of a specific type.

Definition at line 655 of file app_sla.c.

656{
657 return (type == AST_FRAME_CONTROL ? 1 : 0);
658}
static const char type[]
Definition: chan_ooh323.c:109

References AST_FRAME_CONTROL, and type.

Referenced by attach_framehook().

◆ sla_handle_dial_state_event()

static void sla_handle_dial_state_event ( void  )
static

Definition at line 1138 of file app_sla.c.

1139{
1140 struct sla_ringing_station *ringing_station;
1141
1142 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
1143 RAII_VAR(struct sla_trunk_ref *, s_trunk_ref, NULL, ao2_cleanup);
1144 struct sla_ringing_trunk *ringing_trunk = NULL;
1145 struct run_station_args args;
1146 enum ast_dial_result dial_res;
1147 pthread_t dont_care;
1150
1151 switch ((dial_res = ast_dial_state(ringing_station->station->dial))) {
1159 break;
1162 /* Find the appropriate trunk to answer. */
1163 ast_mutex_lock(&sla.lock);
1164 ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
1165 ast_mutex_unlock(&sla.lock);
1166 if (!ringing_trunk) {
1167 /* This case happens in a bit of a race condition. If two stations answer
1168 * the outbound call at the same time, the first one will get connected to
1169 * the trunk. When the second one gets here, it will not see any trunks
1170 * ringing so we have no idea what to conect it to. So, we just hang up
1171 * on it. */
1172 ast_debug(1, "Found no ringing trunk for station '%s' to answer!\n", ringing_station->station->name);
1173 ast_dial_join(ringing_station->station->dial);
1174 ast_dial_destroy(ringing_station->station->dial);
1175 ringing_station->station->dial = NULL;
1176 sla_ringing_station_destroy(ringing_station);
1177 break;
1178 }
1179 /* Track the channel that answered this trunk */
1180 s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
1181 /* Actually answer the trunk */
1182 answer_trunk_chan(ringing_trunk->trunk->chan);
1184 /* Now, start a thread that will connect this station to the trunk. The rest of
1185 * the code here sets up the thread and ensures that it is able to save the arguments
1186 * before they are no longer valid since they are allocated on the stack. */
1187 ao2_ref(s_trunk_ref, 1);
1188 args.trunk_ref = s_trunk_ref;
1189 ao2_ref(ringing_station->station, 1);
1190 args.station = ringing_station->station;
1191 args.cond = &cond;
1192 args.cond_lock = &cond_lock;
1193 sla_ringing_trunk_destroy(ringing_trunk);
1194 sla_ringing_station_destroy(ringing_station);
1203 break;
1208 break;
1209 }
1210 if (dial_res == AST_DIAL_RESULT_ANSWERED) {
1211 /* Queue up reprocessing ringing trunks, and then ringing stations again */
1214 break;
1215 }
1216 }
1218}
ast_cond_t cond
Definition: app_sla.c:330
static void * run_station(void *data)
Definition: app_sla.c:975
static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
Definition: app_sla.c:2143
static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
Definition: app_sla.c:828
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186
pthread_cond_t ast_cond_t
Definition: lock.h:178
Structure for mutex and tracking information.
Definition: lock.h:135
ast_mutex_t * cond_lock
Definition: app_sla.c:907
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:597

References ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, ao2_ref, args, 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_lock, sla_station::dial, NULL, RAII_VAR, run_station(), sla, sla_change_trunk_state(), sla_choose_ringing_trunk(), SLA_EVENT_DIAL_STATE, SLA_EVENT_RINGING_TRUNK, sla_queue_event(), sla_ringing_station_destroy(), sla_ringing_trunk_destroy(), SLA_STATION_HANGUP_NORMAL, sla_stop_ringing_station(), SLA_TRUNK_STATE_UP, sla_ringing_station::station, and sla_ringing_trunk::trunk.

Referenced by sla_thread().

◆ sla_handle_hold_event()

static void sla_handle_hold_event ( struct sla_event event)
static

Definition at line 1479 of file app_sla.c.

1480{
1481 ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
1482 event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
1483 ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s", event->station->name, event->trunk_ref->trunk->name);
1485
1486 if (event->trunk_ref->trunk->active_stations == 1) {
1487 /* The station putting it on hold is the only one on the call, so start
1488 * Music on hold to the trunk. */
1489 event->trunk_ref->trunk->on_hold = 1;
1490 ast_indicate(event->trunk_ref->trunk->chan, AST_CONTROL_HOLD);
1491 }
1492
1493 ast_softhangup(event->trunk_ref->chan, AST_SOFTHANGUP_DEV);
1494 event->trunk_ref->chan = NULL;
1495}
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1121
@ AST_DEVICE_ONHOLD
Definition: devicestate.h:61

References ast_atomic_fetchadd_int(), AST_CONTROL_HOLD, AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_indicate(), ast_softhangup(), AST_SOFTHANGUP_DEV, INACTIVE_TRUNK_REFS, NULL, sla_change_trunk_state(), SLA_TRUNK_STATE_ONHOLD, and SLA_TRUNK_STATE_ONHOLD_BYME.

Referenced by sla_thread().

◆ sla_handle_ringing_trunk_event()

static void sla_handle_ringing_trunk_event ( void  )
static

Definition at line 1469 of file app_sla.c.

1470{
1471 ast_mutex_lock(&sla.lock);
1473 ast_mutex_unlock(&sla.lock);
1474
1475 /* Find stations that shouldn't be ringing anymore. */
1477}
static void sla_ring_stations(void)
Ring stations based on current set of ringing trunks.
Definition: app_sla.c:1393
static void sla_hangup_stations(void)
Definition: app_sla.c:1439

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

Referenced by sla_thread().

◆ sla_hangup_stations()

static void sla_hangup_stations ( void  )
static

Definition at line 1439 of file app_sla.c.

1440{
1441 struct sla_trunk_ref *trunk_ref;
1442 struct sla_ringing_station *ringing_station;
1443
1444 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
1445 AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
1446 struct sla_ringing_trunk *ringing_trunk;
1447 ast_mutex_lock(&sla.lock);
1448 AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
1449 if (trunk_ref->trunk == ringing_trunk->trunk) {
1450 break;
1451 }
1452 }
1453 ast_mutex_unlock(&sla.lock);
1454 if (ringing_trunk) {
1455 break;
1456 }
1457 }
1458 if (!trunk_ref) {
1460 ast_dial_join(ringing_station->station->dial);
1461 ast_dial_destroy(ringing_station->station->dial);
1462 ringing_station->station->dial = NULL;
1463 sla_ringing_station_destroy(ringing_station);
1464 }
1465 }
1467}

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

Referenced by sla_handle_ringing_trunk_event().

◆ sla_hold_str()

static const char * sla_hold_str ( unsigned int  hold_access)
static

Definition at line 344 of file app_sla.c.

345{
346 const char *hold = "Unknown";
347
348 switch (hold_access) {
349 case SLA_HOLD_OPEN:
350 hold = "Open";
351 break;
352 case SLA_HOLD_PRIVATE:
353 hold = "Private";
354 default:
355 break;
356 }
357
358 return hold;
359}
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.

References hold(), SLA_HOLD_OPEN, and SLA_HOLD_PRIVATE.

Referenced by sla_show_stations(), and sla_show_trunks().

◆ sla_in_use()

static int sla_in_use ( void  )
static

Definition at line 2748 of file app_sla.c.

2749{
2751}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.

References ao2_container_count(), sla_stations, and sla_trunks.

Referenced by sla_load_config().

◆ sla_load_config()

static int sla_load_config ( int  reload)
static

Definition at line 2753 of file app_sla.c.

2754{
2755 struct ast_config *cfg;
2756 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2757 const char *cat = NULL;
2758 int res = 0;
2759 const char *val;
2760
2761 if (!reload) {
2762 ast_mutex_init(&sla.lock);
2763 ast_cond_init(&sla.cond, NULL);
2766 }
2767
2768 if (!(cfg = ast_config_load(SLA_CONFIG_FILE, config_flags))) {
2769 return 0; /* Treat no config as normal */
2770 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2771 return 0;
2772 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2773 ast_log(LOG_ERROR, "Config file " SLA_CONFIG_FILE " is in an invalid format. Aborting.\n");
2774 return 0;
2775 }
2776
2777 if (reload) {
2780 }
2781
2782 if ((val = ast_variable_retrieve(cfg, "general", "attemptcallerid"))) {
2783 sla.attempt_callerid = ast_true(val);
2784 }
2785
2786 while ((cat = ast_category_browse(cfg, cat)) && !res) {
2787 const char *type;
2788 if (!strcasecmp(cat, "general")) {
2789 continue;
2790 }
2791 if (!(type = ast_variable_retrieve(cfg, cat, "type"))) {
2792 ast_log(LOG_WARNING, "Invalid entry in %s defined with no type!\n", SLA_CONFIG_FILE);
2793 continue;
2794 }
2795 if (!strcasecmp(type, "trunk")) {
2796 res = sla_build_trunk(cfg, cat);
2797 } else if (!strcasecmp(type, "station")) {
2798 res = sla_build_station(cfg, cat);
2799 } else {
2800 ast_log(LOG_WARNING, "Entry in %s defined with invalid type '%s'!\n", SLA_CONFIG_FILE, type);
2801 }
2802 }
2803
2804 ast_config_destroy(cfg);
2805
2806 if (reload) {
2809 }
2810
2811 /* Start SLA event processing thread once SLA has been configured. */
2812 if (sla.thread == AST_PTHREADT_NULL && sla_in_use()) {
2814 }
2815
2816 return res;
2817}
static int sla_build_station(struct ast_config *cfg, const char *cat)
Definition: app_sla.c:2553
static int sla_trunk_is_marked(void *obj, void *arg, int flags)
Definition: app_sla.c:2692
static int sla_build_trunk(struct ast_config *cfg, const char *cat)
Definition: app_sla.c:2390
static int sla_station_mark(void *obj, void *arg, int flags)
Definition: app_sla.c:2674
static int sla_station_is_marked(void *obj, void *arg, int flags)
Definition: app_sla.c:2720
static int sla_trunk_cmp(void *obj, void *arg, int flags)
Definition: app_sla.c:2321
static int sla_trunk_mark(void *obj, void *arg, int flags)
Definition: app_sla.c:2656
static int sla_in_use(void)
Definition: app_sla.c:2748
static int sla_station_cmp(void *obj, void *arg, int flags)
Definition: app_sla.c:2328
static void * sla_thread(void *data)
Definition: app_sla.c:1729
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
@ CONFIG_FLAG_FILEUNCHANGED
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
Definition: ast_expr2.c:325
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584

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

Referenced by load_config().

◆ sla_process_timers()

static int sla_process_timers ( struct timespec *  ts)
static

Calculate the time until the next known event.

Note
Called with sla.lock locked

Definition at line 1674 of file app_sla.c.

1675{
1676 unsigned int timeout = UINT_MAX;
1677 struct timeval wait;
1678 unsigned int change_made = 0;
1679
1680 /* Check for ring timeouts on ringing trunks */
1681 if (sla_calc_trunk_timeouts(&timeout)) {
1682 change_made = 1;
1683 }
1684
1685 /* Check for ring timeouts on ringing stations */
1686 if (sla_calc_station_timeouts(&timeout)) {
1687 change_made = 1;
1688 }
1689
1690 /* Check for station ring delays */
1691 if (sla_calc_station_delays(&timeout)) {
1692 change_made = 1;
1693 }
1694
1695 /* queue reprocessing of ringing trunks */
1696 if (change_made) {
1698 }
1699
1700 /* No timeout */
1701 if (timeout == UINT_MAX) {
1702 return 0;
1703 }
1704
1705 if (ts) {
1706 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1000));
1707 ts->tv_sec = wait.tv_sec;
1708 ts->tv_nsec = wait.tv_usec * 1000;
1709 }
1710
1711 return 1;
1712}
static int sla_calc_station_delays(unsigned int *timeout)
Calculate the ring delay for a station.
Definition: app_sla.c:1625
static void sla_queue_event_nolock(enum sla_event_type type)
Definition: app_sla.c:550
static int sla_calc_trunk_timeouts(unsigned int *timeout)
Process trunk ring timeouts.
Definition: app_sla.c:1501
static int sla_calc_station_timeouts(unsigned int *timeout)
Process station ring timeouts.
Definition: app_sla.c:1533
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:282
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282

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

◆ sla_queue_event()

static void sla_queue_event ( enum sla_event_type  type)
static

Definition at line 555 of file app_sla.c.

556{
558}
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_sla.c:519

References NULL, sla_queue_event_full(), and type.

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

◆ sla_queue_event_conf()

static void sla_queue_event_conf ( enum sla_event_type  type,
struct ast_channel chan,
const char *  confname 
)
static

Queue a SLA event from the conference.

Definition at line 561 of file app_sla.c.

562{
563 struct sla_station *station;
564 struct sla_trunk_ref *trunk_ref = NULL;
565 char *trunk_name;
566 struct ao2_iterator i;
567
568 trunk_name = ast_strdupa(confname);
569 strsep(&trunk_name, "_");
570 if (ast_strlen_zero(trunk_name)) {
571 ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", confname);
572 return;
573 }
574
576 while ((station = ao2_iterator_next(&i))) {
577 ao2_lock(station);
578 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
579 if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name)) {
580 ao2_ref(trunk_ref, 1);
581 break;
582 }
583 }
584 ao2_unlock(station);
585 if (trunk_ref) {
586 /* station reference given to sla_queue_event_full() */
587 break;
588 }
589 ao2_ref(station, -1);
590 }
592
593 if (!trunk_ref) {
594 ast_debug(1, "Trunk not found for event!\n");
595 return;
596 }
597
598 sla_queue_event_full(type, trunk_ref, station, 1);
599}

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, LOG_ERROR, sla_trunk::name, NULL, sla_queue_event_full(), sla_stations, strsep(), sla_trunk_ref::trunk, sla_station::trunks, and type.

Referenced by sla_framehook().

◆ sla_queue_event_full()

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

Definition at line 519 of file app_sla.c.

520{
521 struct sla_event *event;
522
523 if (sla.thread == AST_PTHREADT_NULL) {
524 ao2_ref(station, -1);
525 ao2_ref(trunk_ref, -1);
526 return;
527 }
528
529 if (!(event = ast_calloc(1, sizeof(*event)))) {
530 ao2_ref(station, -1);
531 ao2_ref(trunk_ref, -1);
532 return;
533 }
534
535 event->type = type;
536 event->trunk_ref = trunk_ref;
537 event->station = station;
538
539 if (!lock) {
541 return;
542 }
543
544 ast_mutex_lock(&sla.lock);
546 ast_cond_signal(&sla.cond);
547 ast_mutex_unlock(&sla.lock);
548}
ast_mutex_t lock
Definition: app_sla.c:331
struct sla_station * station
Definition: app_sla.c:289
struct sla_trunk_ref * trunk_ref
Definition: app_sla.c:290

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

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

◆ sla_queue_event_nolock()

static void sla_queue_event_nolock ( enum sla_event_type  type)
static

Definition at line 550 of file app_sla.c.

551{
553}

References NULL, sla_queue_event_full(), and type.

Referenced by sla_process_timers().

◆ sla_ring_station()

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

Ring a station.

Note
Assumes sla.lock is locked

Definition at line 1263 of file app_sla.c.

1264{
1265 char *tech, *tech_data;
1266 struct ast_dial *dial;
1267 struct sla_ringing_station *ringing_station;
1268 enum ast_dial_result res;
1269 int caller_is_saved;
1270 struct ast_party_caller caller;
1271
1272 if (!(dial = ast_dial_create())) {
1273 return -1;
1274 }
1275
1277 tech_data = ast_strdupa(station->device);
1278 tech = strsep(&tech_data, "/");
1279
1280 if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
1281 ast_dial_destroy(dial);
1282 return -1;
1283 }
1284
1285 /* Do we need to save off the caller ID data? */
1286 caller_is_saved = 0;
1287 if (!sla.attempt_callerid) {
1288 caller_is_saved = 1;
1289 caller = *ast_channel_caller(ringing_trunk->trunk->chan);
1291 }
1292
1293 res = ast_dial_run(dial, ringing_trunk->trunk->chan, 1);
1294
1295 /* Restore saved caller ID */
1296 if (caller_is_saved) {
1298 ast_channel_caller_set(ringing_trunk->trunk->chan, &caller);
1299 }
1300
1301 if (res != AST_DIAL_RESULT_TRYING) {
1302 struct sla_failed_station *failed_station;
1303 ast_dial_destroy(dial);
1304 if ((failed_station = sla_create_failed_station(station))) {
1305 AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
1306 }
1307 return -1;
1308 }
1309 if (!(ringing_station = sla_create_ringing_station(station))) {
1310 ast_dial_join(dial);
1311 ast_dial_destroy(dial);
1312 return -1;
1313 }
1314
1315 station->dial = dial;
1316
1317 AST_LIST_INSERT_HEAD(&sla.ringing_stations, ringing_station, entry);
1318
1319 return 0;
1320}
static void sla_dial_state_callback(struct ast_dial *dial)
Definition: app_sla.c:1070
static struct sla_ringing_station * sla_create_ringing_station(struct sla_station *station)
Definition: app_sla.c:813
static struct sla_failed_station * sla_create_failed_station(struct sla_station *station)
Definition: app_sla.c:838
void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback)
Set a callback for state changes.
Definition: dial.c:1269

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

Referenced by sla_ring_stations().

◆ sla_ring_stations()

static void sla_ring_stations ( void  )
static

Ring stations based on current set of ringing trunks.

Note
Assumes that sla.lock is locked

Definition at line 1393 of file app_sla.c.

1394{
1395 struct sla_station_ref *station_ref;
1396 struct sla_ringing_trunk *ringing_trunk;
1397
1398 /* Make sure that every station that uses at least one of the ringing
1399 * trunks, is ringing. */
1400 AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
1401 AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
1402 int time_left;
1403
1404 /* Is this station already ringing? */
1405 if (sla_check_ringing_station(station_ref->station)) {
1406 continue;
1407 }
1408
1409 /* Is this station already in a call? */
1410 if (sla_check_inuse_station(station_ref->station)) {
1411 continue;
1412 }
1413
1414 /* Did we fail to dial this station earlier? If so, has it been
1415 * a minute since we tried? */
1416 if (sla_check_failed_station(station_ref->station)) {
1417 continue;
1418 }
1419
1420 /* If this station already timed out while this trunk was ringing,
1421 * do not dial it again for this ringing trunk. */
1422 if (sla_check_timed_out_station(ringing_trunk, station_ref->station)) {
1423 continue;
1424 }
1425
1426 /* Check for a ring delay in progress */
1427 time_left = sla_check_station_delay(station_ref->station, ringing_trunk);
1428 if (time_left != INT_MAX && time_left > 0) {
1429 continue;
1430 }
1431
1432 /* It is time to make this station begin to ring. Do it! */
1433 sla_ring_station(ringing_trunk, station_ref->station);
1434 }
1435 }
1436 /* Now, all of the stations that should be ringing, are ringing. */
1437}
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_sla.c:1239
static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_station *station)
Ring a station.
Definition: app_sla.c:1263

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

◆ sla_ringing_station_destroy()

static void sla_ringing_station_destroy ( struct sla_ringing_station ringing_station)
static

Definition at line 828 of file app_sla.c.

829{
830 if (ringing_station->station) {
831 ao2_ref(ringing_station->station, -1);
832 ringing_station->station = NULL;
833 }
834
835 ast_free(ringing_station);
836}

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

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

◆ sla_ringing_trunk_destroy()

static void sla_ringing_trunk_destroy ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 2143 of file app_sla.c.

2144{
2145 if (ringing_trunk->trunk) {
2146 ao2_ref(ringing_trunk->trunk, -1);
2147 ringing_trunk->trunk = NULL;
2148 }
2149
2150 ast_free(ringing_trunk);
2151}

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

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

◆ sla_show_stations()

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

Definition at line 435 of file app_sla.c.

436{
437 struct ao2_iterator i;
438 struct sla_station *station;
439
440 switch (cmd) {
441 case CLI_INIT:
442 e->command = "sla show stations";
443 e->usage =
444 "Usage: sla show stations\n"
445 " This will list all stations defined in sla.conf\n";
446 return NULL;
447 case CLI_GENERATE:
448 return NULL;
449 }
450
451 ast_cli(a->fd, "\n"
452 "=============================================================\n"
453 "=== Configured SLA Stations =================================\n"
454 "=============================================================\n"
455 "===\n");
457 for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
458 struct sla_trunk_ref *trunk_ref;
459 char ring_timeout[16] = "(none)";
460 char ring_delay[16] = "(none)";
461
462 ao2_lock(station);
463
464 if (station->ring_timeout) {
465 snprintf(ring_timeout, sizeof(ring_timeout), "%u", station->ring_timeout);
466 }
467 if (station->ring_delay) {
468 snprintf(ring_delay, sizeof(ring_delay), "%u", station->ring_delay);
469 }
470 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
471 "=== Station Name: %s\n"
472 "=== ==> Device: %s\n"
473 "=== ==> AutoContext: %s\n"
474 "=== ==> RingTimeout: %s\n"
475 "=== ==> RingDelay: %s\n"
476 "=== ==> HoldAccess: %s\n"
477 "=== ==> Trunks ...\n",
478 station->name, station->device,
479 S_OR(station->autocontext, "(none)"),
481 sla_hold_str(station->hold_access));
482 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
483 if (trunk_ref->ring_timeout) {
484 snprintf(ring_timeout, sizeof(ring_timeout), "%u", trunk_ref->ring_timeout);
485 } else {
486 strcpy(ring_timeout, "(none)");
487 }
488 if (trunk_ref->ring_delay) {
489 snprintf(ring_delay, sizeof(ring_delay), "%u", trunk_ref->ring_delay);
490 } else {
491 strcpy(ring_delay, "(none)");
492 }
493
494 ast_cli(a->fd, "=== ==> Trunk Name: %s\n"
495 "=== ==> State: %s\n"
496 "=== ==> RingTimeout: %s\n"
497 "=== ==> RingDelay: %s\n",
498 trunk_ref->trunk->name,
499 trunkstate2str(trunk_ref->state),
501 }
502 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
503 "===\n");
504
505 ao2_unlock(station);
506 }
508 ast_cli(a->fd, "============================================================\n"
509 "\n");
510
511 return CLI_SUCCESS;
512}
static const char * sla_hold_str(unsigned int hold_access)
Definition: app_sla.c:344
static const char * trunkstate2str(enum sla_trunk_state state)
Definition: app_sla.c:421
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, 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, sla_station::hold_access, sla_trunk::name, NULL, sla_station::ring_delay, sla_trunk_ref::ring_delay, sla_station::ring_timeout, sla_trunk_ref::ring_timeout, S_OR, sla_hold_str(), sla_stations, sla_trunk_ref::state, sla_trunk_ref::trunk, sla_station::trunks, trunkstate2str(), and ast_cli_entry::usage.

◆ sla_show_trunks()

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

Definition at line 361 of file app_sla.c.

362{
363 struct ao2_iterator i;
364 struct sla_trunk *trunk;
365
366 switch (cmd) {
367 case CLI_INIT:
368 e->command = "sla show trunks";
369 e->usage =
370 "Usage: sla show trunks\n"
371 " This will list all trunks defined in sla.conf\n";
372 return NULL;
373 case CLI_GENERATE:
374 return NULL;
375 }
376
377 ast_cli(a->fd, "\n"
378 "=============================================================\n"
379 "=== Configured SLA Trunks ===================================\n"
380 "=============================================================\n"
381 "===\n");
383 for (; (trunk = ao2_iterator_next(&i)); ao2_ref(trunk, -1)) {
384 struct sla_station_ref *station_ref;
385 char ring_timeout[23] = "(none)";
386
387 ao2_lock(trunk);
388
389 if (trunk->ring_timeout) {
390 snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
391 }
392
393 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
394 "=== Trunk Name: %s\n"
395 "=== ==> Device: %s\n"
396 "=== ==> AutoContext: %s\n"
397 "=== ==> RingTimeout: %s\n"
398 "=== ==> BargeAllowed: %s\n"
399 "=== ==> HoldAccess: %s\n"
400 "=== ==> Stations ...\n",
401 trunk->name, trunk->device,
402 S_OR(trunk->autocontext, "(none)"),
403 ring_timeout,
404 trunk->barge_disabled ? "No" : "Yes",
405 sla_hold_str(trunk->hold_access));
406
407 AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
408 ast_cli(a->fd, "=== ==> Station name: %s\n", station_ref->station->name);
409 }
410
411 ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
412
413 ao2_unlock(trunk);
414 }
416 ast_cli(a->fd, "=============================================================\n\n");
417
418 return CLI_SUCCESS;
419}
const ast_string_field autocontext
Definition: app_sla.c:226
const ast_string_field device
Definition: app_sla.c:226

References a, 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, sla_trunk::hold_access, sla_trunk::name, NULL, sla_trunk::ring_timeout, S_OR, sla_hold_str(), sla_trunks, sla_station_ref::station, sla_trunk::stations, and ast_cli_entry::usage.

◆ sla_state()

static enum ast_device_state sla_state ( const char *  data)
static

Definition at line 2244 of file app_sla.c.

2245{
2246 char *buf, *station_name, *trunk_name;
2247 RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
2248 struct sla_trunk_ref *trunk_ref;
2250
2251 trunk_name = buf = ast_strdupa(data);
2252 station_name = strsep(&trunk_name, "_");
2253
2254 station = sla_find_station(station_name);
2255 if (station) {
2256 ao2_lock(station);
2257 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2258 if (!strcasecmp(trunk_name, trunk_ref->trunk->name)) {
2259 res = sla_state_to_devstate(trunk_ref->state);
2260 break;
2261 }
2262 }
2263 ao2_unlock(station);
2264 }
2265
2266 if (res == AST_DEVICE_INVALID) {
2267 ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n", trunk_name, station_name);
2268 }
2269
2270 return res;
2271}
@ AST_DEVICE_INVALID
Definition: devicestate.h:57
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

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

Referenced by load_module().

◆ sla_state_to_devstate()

static enum ast_device_state sla_state_to_devstate ( enum sla_trunk_state  state)
static

◆ sla_station_cmp()

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

Definition at line 2328 of file app_sla.c.

2329{
2330 struct sla_station *station = obj, *station2 = arg;
2331
2332 return !strcasecmp(station->name, station2->name) ? CMP_MATCH | CMP_STOP : 0;
2333}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028

References CMP_MATCH, and CMP_STOP.

Referenced by sla_load_config().

◆ sla_station_destructor()

static void sla_station_destructor ( void *  obj)
static

Definition at line 2297 of file app_sla.c.

2298{
2299 struct sla_station *station = obj;
2300
2301 ast_debug(1, "sla_station destructor for '%s'\n", station->name);
2302
2303 if (!ast_strlen_zero(station->autocontext)) {
2304 struct sla_trunk_ref *trunk_ref;
2305
2306 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2307 char exten[AST_MAX_EXTENSION];
2308 char hint[AST_MAX_EXTENSION + 5];
2309 snprintf(exten, sizeof(exten), "%s_%s", station->name, trunk_ref->trunk->name);
2310 snprintf(hint, sizeof(hint), "SLA:%s", exten);
2311 ast_context_remove_extension(station->autocontext, exten, 1, sla_registrar);
2312 ast_context_remove_extension(station->autocontext, hint, PRIORITY_HINT, sla_registrar);
2313 }
2314 }
2315
2316 sla_station_release_refs(station, NULL, 0);
2317
2319}
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4948
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

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

Referenced by sla_build_station().

◆ sla_station_exec()

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

Definition at line 1949 of file app_sla.c.

1950{
1951 char *station_name, *trunk_name;
1952 RAII_VAR(struct sla_station *, station, NULL, ao2_cleanup);
1953 RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, ao2_cleanup);
1954 char conf_name[MAX_CONFNUM];
1955 struct ast_flags conf_flags = { 0 };
1956
1957 if (ast_strlen_zero(data)) {
1958 ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
1959 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
1960 return 0;
1961 }
1962
1963 trunk_name = ast_strdupa(data);
1964 station_name = strsep(&trunk_name, "_");
1965
1966 if (ast_strlen_zero(station_name)) {
1967 ast_log(LOG_WARNING, "Invalid Arguments to SLAStation!\n");
1968 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
1969 return 0;
1970 }
1971
1972 station = sla_find_station(station_name);
1973
1974 if (!station) {
1975 ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
1976 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
1977 return 0;
1978 }
1979
1980 ao2_lock(station);
1981 if (!ast_strlen_zero(trunk_name)) {
1982 trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
1983 } else {
1984 trunk_ref = sla_choose_idle_trunk(station);
1985 }
1986 ao2_unlock(station);
1987
1988 if (!trunk_ref) {
1989 if (ast_strlen_zero(trunk_name)) {
1990 ast_log(LOG_NOTICE, "No trunks available for call.\n");
1991 } else {
1992 ast_log(LOG_NOTICE, "Can't join existing call on trunk '%s' due to access controls.\n", trunk_name);
1993 }
1994 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
1995 return 0;
1996 }
1997
1998 if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
1999 if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1) {
2001 } else {
2002 trunk_ref->state = SLA_TRUNK_STATE_UP;
2003 ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "SLA:%s_%s", station->name, trunk_ref->trunk->name);
2004 }
2005 } else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
2006 struct sla_ringing_trunk *ringing_trunk;
2007
2008 ast_mutex_lock(&sla.lock);
2009 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
2010 if (ringing_trunk->trunk == trunk_ref->trunk) {
2012 break;
2013 }
2014 }
2016 ast_mutex_unlock(&sla.lock);
2017
2018 if (ringing_trunk) {
2019 answer_trunk_chan(ringing_trunk->trunk->chan);
2021
2022 sla_ringing_trunk_destroy(ringing_trunk);
2023
2024 /* Queue up reprocessing ringing trunks, and then ringing stations again */
2027 }
2028 }
2029
2030 trunk_ref->chan = chan;
2031
2032 if (!trunk_ref->trunk->chan) {
2033 ast_mutex_t cond_lock;
2035 pthread_t dont_care;
2036 struct dial_trunk_args args = {
2037 .trunk_ref = trunk_ref,
2038 .station = station,
2039 .cond_lock = &cond_lock,
2040 .cond = &cond,
2041 };
2042 ao2_ref(trunk_ref, 1);
2043 ao2_ref(station, 1);
2045 /* Create a thread to dial the trunk and dump it into the conference.
2046 * However, we want to wait until the trunk has been dialed and the
2047 * conference is created before continuing on here.
2048 * Don't autoservice the channel or we'll have multiple threads
2049 * handling it. dial_trunk services the channel.
2050 */
2059
2060 if (!trunk_ref->trunk->chan) {
2061 ast_debug(1, "Trunk didn't get created. chan: %lx\n", (unsigned long) trunk_ref->trunk->chan);
2062 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
2064 trunk_ref->chan = NULL;
2065 return 0;
2066 }
2067 }
2068
2069 if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
2071 trunk_ref->trunk->on_hold = 0;
2074 }
2075
2076 snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
2078 ast_answer(chan);
2079
2080 ast_debug(2, "Station %s joining conference %s\n", station->name, conf_name);
2081 conf_run(chan, conf_name, &conf_flags, NULL);
2082
2083 trunk_ref->chan = NULL;
2086 conf_kick_all(chan, conf_name);
2089 }
2090
2091 pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
2092
2093 return 0;
2094}
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_sla.c:1935
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_sla.c:759
static void * dial_trunk(void *data)
Definition: app_sla.c:1794
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
@ AST_CONTROL_UNHOLD
#define LOG_NOTICE
struct sla_station * station
Definition: app_sla.c:1789
ast_mutex_t * cond_lock
Definition: app_sla.c:1790
struct sla_trunk_ref * trunk_ref
Definition: app_sla.c:1788
unsigned int on_hold
Definition: app_sla.c:244

References sla_trunk::active_stations, ALL_TRUNK_REFS, answer_trunk_chan(), ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, args, ast_answer(), ast_atomic_dec_and_test(), ast_atomic_fetchadd_int(), 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_flag, ast_strdupa, ast_strlen_zero(), sla_trunk::chan, sla_trunk_ref::chan, cond, dial_trunk_args::cond_lock, conf_kick_all(), conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, CONFFLAG_SLA_STATION, dial_trunk(), sla_trunk::hold_stations, LOG_NOTICE, LOG_WARNING, MAX_CONFNUM, sla_trunk::name, NULL, sla_trunk::on_hold, pbx_builtin_setvar_helper(), RAII_VAR, sla, sla_change_trunk_state(), sla_choose_idle_trunk(), SLA_EVENT_DIAL_STATE, SLA_EVENT_RINGING_TRUNK, sla_find_station(), sla_find_trunk_ref_byname(), sla_queue_event(), sla_ringing_trunk_destroy(), SLA_TRUNK_STATE_IDLE, SLA_TRUNK_STATE_ONHOLD_BYME, SLA_TRUNK_STATE_RINGING, SLA_TRUNK_STATE_UP, sla_trunk_ref::state, dial_trunk_args::station, strsep(), sla_trunk_ref::trunk, sla_ringing_trunk::trunk, and dial_trunk_args::trunk_ref.

Referenced by load_module().

◆ sla_station_is_marked()

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

Definition at line 2720 of file app_sla.c.

2721{
2722 struct sla_station *station = obj;
2723
2724 ao2_lock(station);
2725
2726 if (station->mark) {
2727 /* Only remove all of the trunk references if the station itself is going away */
2728 sla_station_release_refs(station, NULL, 0);
2729 } else {
2730 struct sla_trunk_ref *trunk_ref;
2731
2732 /* Otherwise only remove references to trunks no longer in the config */
2733 AST_LIST_TRAVERSE_SAFE_BEGIN(&station->trunks, trunk_ref, entry) {
2734 if (!trunk_ref->mark) {
2735 continue;
2736 }
2738 ao2_ref(trunk_ref, -1);
2739 }
2741 }
2742
2743 ao2_unlock(station);
2744
2745 return station->mark ? CMP_MATCH : 0;
2746}
unsigned int mark
Definition: app_sla.c:203

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

Referenced by sla_load_config().

◆ sla_station_mark()

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

Definition at line 2674 of file app_sla.c.

2675{
2676 struct sla_station *station = obj;
2677 struct sla_trunk_ref *trunk_ref;
2678
2679 ao2_lock(station);
2680
2681 station->mark = 1;
2682
2683 AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
2684 trunk_ref->mark = 1;
2685 }
2686
2687 ao2_unlock(station);
2688
2689 return 0;
2690}

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

Referenced by sla_load_config().

◆ sla_station_ref_destructor()

static void sla_station_ref_destructor ( void *  obj)
static

Definition at line 789 of file app_sla.c.

790{
791 struct sla_station_ref *station_ref = obj;
792
793 if (station_ref->station) {
794 ao2_ref(station_ref->station, -1);
795 station_ref->station = NULL;
796 }
797}

References ao2_ref, NULL, and sla_station_ref::station.

Referenced by sla_create_station_ref().

◆ sla_station_release_refs()

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

Definition at line 2285 of file app_sla.c.

2286{
2287 struct sla_station *station = obj;
2288 struct sla_trunk_ref *trunk_ref;
2289
2290 while ((trunk_ref = AST_LIST_REMOVE_HEAD(&station->trunks, entry))) {
2291 ao2_ref(trunk_ref, -1);
2292 }
2293
2294 return 0;
2295}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833

References ao2_ref, AST_LIST_REMOVE_HEAD, and sla_station::trunks.

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

◆ sla_stop_ringing_station()

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

Definition at line 1032 of file app_sla.c.

1033{
1034 struct sla_ringing_trunk *ringing_trunk;
1035 struct sla_trunk_ref *trunk_ref;
1036 struct sla_station_ref *station_ref;
1037
1038 ast_dial_join(ringing_station->station->dial);
1039 ast_dial_destroy(ringing_station->station->dial);
1040 ringing_station->station->dial = NULL;
1041
1043 goto done;
1044 }
1045
1046 /* If the station is being hung up because of a timeout, then add it to the
1047 * list of timed out stations on each of the ringing trunks. This is so
1048 * that when doing further processing to figure out which stations should be
1049 * ringing, which trunk to answer, determining timeouts, etc., we know which
1050 * ringing trunks we should ignore. */
1051 AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
1052 AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
1053 if (ringing_trunk->trunk == trunk_ref->trunk) {
1054 break;
1055 }
1056 }
1057 if (!trunk_ref) {
1058 continue;
1059 }
1060 if (!(station_ref = sla_create_station_ref(ringing_station->station))) {
1061 continue;
1062 }
1063 AST_LIST_INSERT_TAIL(&ringing_trunk->timed_out_stations, station_ref, entry);
1064 }
1065
1066done:
1067 sla_ringing_station_destroy(ringing_station);
1068}
static int hangup(void *data)
Definition: chan_pjsip.c:2516

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

Referenced by sla_calc_station_timeouts(), and sla_handle_dial_state_event().

◆ sla_stop_ringing_trunk()

static void sla_stop_ringing_trunk ( struct sla_ringing_trunk ringing_trunk)
static

Definition at line 1018 of file app_sla.c.

1019{
1020 struct sla_station_ref *station_ref;
1021
1022 conf_kick_all(ringing_trunk->trunk->chan, ringing_trunk->trunk->name);
1024
1025 while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry))) {
1026 ao2_ref(station_ref, -1);
1027 }
1028
1029 sla_ringing_trunk_destroy(ringing_trunk);
1030}

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

Referenced by sla_calc_trunk_timeouts().

◆ sla_thread()

static void * sla_thread ( void *  data)
static

Definition at line 1729 of file app_sla.c.

1730{
1731 struct sla_failed_station *failed_station;
1732 struct sla_ringing_station *ringing_station;
1733
1734 ast_mutex_lock(&sla.lock);
1735
1736 while (!sla.stop) {
1737 struct sla_event *event;
1738 struct timespec ts = { 0, };
1739 unsigned int have_timeout = 0;
1740
1741 if (AST_LIST_EMPTY(&sla.event_q)) {
1742 if ((have_timeout = sla_process_timers(&ts))) {
1743 ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
1744 } else {
1745 ast_cond_wait(&sla.cond, &sla.lock);
1746 }
1747 if (sla.stop) {
1748 break;
1749 }
1750 }
1751
1752 if (have_timeout) {
1754 }
1755
1756 while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
1757 ast_mutex_unlock(&sla.lock);
1758 switch (event->type) {
1759 case SLA_EVENT_HOLD:
1761 break;
1764 break;
1767 break;
1768 }
1770 ast_mutex_lock(&sla.lock);
1771 }
1772 }
1773
1774 ast_mutex_unlock(&sla.lock);
1775
1776 while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry))) {
1777 sla_ringing_station_destroy(ringing_station);
1778 }
1779
1780 while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry))) {
1781 sla_failed_station_destroy(failed_station);
1782 }
1783
1784 return NULL;
1785}
static void sla_handle_ringing_trunk_event(void)
Definition: app_sla.c:1469
static void sla_handle_dial_state_event(void)
Definition: app_sla.c:1138
static void sla_event_destroy(struct sla_event *event)
Definition: app_sla.c:1714
static void sla_handle_hold_event(struct sla_event *event)
Definition: app_sla.c:1479
static int sla_process_timers(struct timespec *ts)
Calculate the time until the next known event.
Definition: app_sla.c:1674
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206

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

Referenced by sla_load_config().

◆ sla_trunk_cmp()

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

Definition at line 2321 of file app_sla.c.

2322{
2323 struct sla_trunk *trunk = obj, *trunk2 = arg;
2324
2325 return !strcasecmp(trunk->name, trunk2->name) ? CMP_MATCH | CMP_STOP : 0;
2326}

References CMP_MATCH, CMP_STOP, and sla_trunk::name.

Referenced by sla_load_config().

◆ sla_trunk_destructor()

static void sla_trunk_destructor ( void *  obj)
static

Definition at line 2375 of file app_sla.c.

2376{
2377 struct sla_trunk *trunk = obj;
2378
2379 ast_debug(1, "sla_trunk destructor for '%s'\n", trunk->name);
2380
2381 if (!ast_strlen_zero(trunk->autocontext)) {
2383 }
2384
2385 sla_trunk_release_refs(trunk, NULL, 0);
2386
2388}

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

Referenced by sla_build_trunk().

◆ sla_trunk_exec()

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

Definition at line 2153 of file app_sla.c.

2154{
2155 char conf_name[MAX_CONFNUM];
2156 struct ast_flags conf_flags = { 0 };
2157 RAII_VAR(struct sla_trunk *, trunk, NULL, ao2_cleanup);
2158 struct sla_ringing_trunk *ringing_trunk;
2160 AST_APP_ARG(trunk_name);
2162 );
2163 char *opts[SLA_TRUNK_OPT_ARG_ARRAY_SIZE] = { NULL, };
2164 struct ast_flags opt_flags = { 0 };
2165 char *parse;
2166
2167 if (ast_strlen_zero(data)) {
2168 ast_log(LOG_ERROR, "The SLATrunk application requires an argument, the trunk name\n");
2169 return -1;
2170 }
2171
2172 parse = ast_strdupa(data);
2174 if (args.argc == 2) {
2175 if (ast_app_parse_options(sla_trunk_opts, &opt_flags, opts, args.options)) {
2176 ast_log(LOG_ERROR, "Error parsing options for SLATrunk\n");
2177 return -1;
2178 }
2179 }
2180
2181 trunk = sla_find_trunk(args.trunk_name);
2182
2183 if (!trunk) {
2184 ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", args.trunk_name);
2185 pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
2186 return 0;
2187 }
2188
2189 if (trunk->chan) {
2190 ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n", args.trunk_name);
2191 pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
2192 return 0;
2193 }
2194
2195 trunk->chan = chan;
2196
2197 if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
2198 pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
2199 return 0;
2200 }
2201
2202 snprintf(conf_name, sizeof(conf_name), "SLA_%s", args.trunk_name);
2204
2205 if (ast_test_flag(&opt_flags, SLA_TRUNK_OPT_MOH)) {
2206 ast_indicate(chan, -1);
2207 ast_set_flag(&conf_flags, CONFFLAG_MOH);
2208 } else {
2210 }
2211
2212 ast_debug(2, "Trunk %s joining conference %s\n", args.trunk_name, conf_name);
2213 conf_run(chan, conf_name, &conf_flags, opts);
2214 trunk->chan = NULL;
2215 trunk->on_hold = 0;
2216
2218
2219 if (!pbx_builtin_getvar_helper(chan, "SLATRUNK_STATUS")) {
2220 pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");
2221 }
2222
2223 /* Remove the entry from the list of ringing trunks if it is still there. */
2224 ast_mutex_lock(&sla.lock);
2225 AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
2226 if (ringing_trunk->trunk == trunk) {
2228 break;
2229 }
2230 }
2232 ast_mutex_unlock(&sla.lock);
2233 if (ringing_trunk) {
2234 sla_ringing_trunk_destroy(ringing_trunk);
2235 pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
2236 /* Queue reprocessing of ringing trunks to make stations stop ringing
2237 * that shouldn't be ringing after this trunk stopped. */
2239 }
2240
2241 return 0;
2242}
static struct sla_ringing_trunk * queue_ringing_trunk(struct sla_trunk *trunk)
Definition: app_sla.c:2120
static const struct ast_app_option sla_trunk_opts[128]
Definition: app_sla.c:156
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3056
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.

References ALL_TRUNK_REFS, ao2_cleanup, args, AST_APP_ARG, ast_app_parse_options(), AST_CONTROL_RINGING, ast_debug, 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_flag, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, conf_run(), CONFFLAG_MARKEDEXIT, CONFFLAG_MARKEDUSER, CONFFLAG_MOH, CONFFLAG_PASS_DTMF, CONFFLAG_QUIET, LOG_ERROR, MAX_CONFNUM, NULL, options, 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().

◆ sla_trunk_is_marked()

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

Definition at line 2692 of file app_sla.c.

2693{
2694 struct sla_trunk *trunk = obj;
2695
2696 ao2_lock(trunk);
2697
2698 if (trunk->mark) {
2699 /* Only remove all of the station references if the trunk itself is going away */
2700 sla_trunk_release_refs(trunk, NULL, 0);
2701 } else {
2702 struct sla_station_ref *station_ref;
2703
2704 /* Otherwise only remove references to stations no longer in the config */
2705 AST_LIST_TRAVERSE_SAFE_BEGIN(&trunk->stations, station_ref, entry) {
2706 if (!station_ref->mark) {
2707 continue;
2708 }
2710 ao2_ref(station_ref, -1);
2711 }
2713 }
2714
2715 ao2_unlock(trunk);
2716
2717 return trunk->mark ? CMP_MATCH : 0;
2718}
unsigned int mark
Definition: app_sla.c:246

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

Referenced by sla_load_config().

◆ sla_trunk_mark()

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

Definition at line 2656 of file app_sla.c.

2657{
2658 struct sla_trunk *trunk = obj;
2659 struct sla_station_ref *station_ref;
2660
2661 ao2_lock(trunk);
2662
2663 trunk->mark = 1;
2664
2665 AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
2666 station_ref->mark = 1;
2667 }
2668
2669 ao2_unlock(trunk);
2670
2671 return 0;
2672}

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

Referenced by sla_load_config().

◆ sla_trunk_ref_destructor()

static void sla_trunk_ref_destructor ( void *  obj)
static

Definition at line 2096 of file app_sla.c.

2097{
2098 struct sla_trunk_ref *trunk_ref = obj;
2099
2100 if (trunk_ref->trunk) {
2101 ao2_ref(trunk_ref->trunk, -1);
2102 trunk_ref->trunk = NULL;
2103 }
2104}

References ao2_ref, NULL, and sla_trunk_ref::trunk.

Referenced by create_trunk_ref().

◆ sla_trunk_release_refs()

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

Definition at line 2273 of file app_sla.c.

2274{
2275 struct sla_trunk *trunk = obj;
2276 struct sla_station_ref *station_ref;
2277
2278 while ((station_ref = AST_LIST_REMOVE_HEAD(&trunk->stations, entry))) {
2279 ao2_ref(station_ref, -1);
2280 }
2281
2282 return 0;
2283}

References ao2_ref, AST_LIST_REMOVE_HEAD, and sla_trunk::stations.

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

◆ trunkstate2str()

static const char * trunkstate2str ( enum sla_trunk_state  state)
static

Definition at line 421 of file app_sla.c.

422{
423#define S(e) case e: return # e;
424 switch (state) {
430 }
431 return "Uknown State";
432#undef S
433}
#define S(e)

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

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 2824 of file app_sla.c.

2825{
2826 int res = 0;
2827
2831
2832 ast_devstate_prov_del("SLA");
2833
2834 sla_destroy();
2835
2836 return res;
2837}
static void sla_destroy(void)
Definition: app_sla.c:2335
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_devstate_prov_del(const char *label)
Remove device state provider.
Definition: devicestate.c:418
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_devstate_prov_del(), ast_unregister_application(), cli_sla, sla_destroy(), slastation_app, and slatrunk_app.

Variable Documentation

◆ __mod_info

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

Definition at line 2875 of file app_sla.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2875 of file app_sla.c.

◆ attempt_callerid

unsigned int attempt_callerid

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

Definition at line 339 of file app_sla.c.

◆ cli_sla

struct ast_cli_entry cli_sla[]
static
Initial value:
= {
{ .handler = sla_show_trunks , .summary = "Show SLA Trunks" ,},
{ .handler = sla_show_stations , .summary = "Show SLA Stations" ,},
}
static char * sla_show_stations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_sla.c:435
static char * sla_show_trunks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_sla.c:361

Definition at line 514 of file app_sla.c.

Referenced by load_module(), and unload_module().

◆ cond

ast_cond_t cond

◆ 

struct { ... } event_q

◆ 

struct { ... } failed_stations

◆ first

struct sla_event* first

◆ last

struct sla_event* last

◆ lock

Definition at line 331 of file app_sla.c.

Referenced by __ast_bucket_scheme_register(), __ast_cli_generator(), __ast_codec_register_with_format(), __ast_format_interface_register(), __ast_named_lock_get(), action_lock_unlock_helper(), add_headers_to_message(), add_masquerade_store(), add_transferer_role(), aeap_transport_read(), aeap_transport_write(), after_bridge_cb_find(), after_bridge_cb_setup(), aor_alloc(), ast_aeap_connect(), ast_ari_add_handler(), ast_bridge_basic_set_flags(), ast_bridge_read_after_goto(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), ast_cdr_fork(), ast_channel_move(), ast_clear_mixmonitor_methods(), ast_config_engine_deregister(), ast_config_engine_register(), ast_endpoint_snapshot_create(), ast_format_cache_set(), ast_get_extension_for_mime_type(), ast_get_format_for_file_ext(), ast_localtime_wakeup_monitor(), ast_realtime_is_mapping_defined(), ast_serializer_shutdown_group_join(), ast_set_mixmonitor_methods(), ast_sip_format_endpoint_ami(), ast_sip_identify_endpoint(), ast_sip_publish_client_remove(), ast_sip_publish_client_send(), ast_sip_register_endpoint_formatter(), ast_sip_register_endpoint_identifier_with_name(), ast_sip_register_event_publisher_handler(), ast_sip_register_supplement(), ast_sip_session_add_supplements(), ast_sip_session_register_sdp_handler(), ast_sip_session_register_supplement_with_module(), ast_sip_session_unregister_supplement(), ast_sip_unregister_endpoint_formatter(), ast_sip_unregister_endpoint_identifier(), ast_sip_unregister_event_publisher_handler(), ast_sip_unregister_supplement(), ast_spinlock_destroy(), ast_spinlock_init(), ast_spinlock_lock(), ast_spinlock_trylock(), ast_spinlock_unlock(), ast_start_mixmonitor(), ast_stop_mixmonitor(), ast_taskprocessor_set_local(), AST_TEST_DEFINE(), ast_threadpool_push(), ast_threadpool_set_size(), ast_unreal_channel_push_to_bridge(), bridge_basic_change_personality(), bucket_file_wizard_retrieve(), bucket_wizard_retrieve(), builtin_feature_get_exten(), cancel_and_unpublish(), channel_get_external_vars(), clear_stimulus_queue(), cli_show_channels(), cli_show_endpoint_identifiers(), complex_task(), conf_announce_channel_push(), consumer_exec(), consumer_exec_sync(), consumer_should_stay(), consumer_wait_for(), consumer_wait_for_completion(), event_session_shutdown(), expire_contact(), find_engine(), find_route(), generic_lock_unlock_helper(), get_park_common_datastore_copy(), get_publishes_and_update_state(), get_root_handler(), get_wait_bridge_wrapper(), handle_bridge_enter(), handle_cli_core_show_config_mappings(), handle_local_optimization_begin(), handle_local_optimization_end(), has_complex_started(), has_masquerade_store(), internal_feature_read(), internal_feature_write(), internal_featuremap_read(), internal_featuremap_write(), load_module(), load_task(), lock_it(), lock_thread(), message_sink_cb(), mid_test_sync(), one_protocol(), persistent_endpoint_find_or_create(), playback_cancel(), playback_final_update(), playback_first_update(), playback_forward(), playback_pause(), playback_restart(), playback_reverse(), playback_stop(), playback_unpause(), poke_worker(), prometheus_callback_register(), prometheus_callback_unregister(), prometheus_last_scrape_time_get(), prometheus_metric_register(), prometheus_metric_registered_count(), prometheus_metric_unregister(), publisher_client_send(), recording_set_state(), reload_module(), remove_hooks_on_personality_change(), remove_masquerade_store(), remove_stasis_subscriptions(), report_fax_status(), report_receive_fax_status(), report_send_fax_status(), set_touch_variables(), shutdown_has_completed(), shutdown_poke(), shutdown_task_exec(), shutdown_waitfor_completion(), shutdown_waitfor_start(), signal_condition(), simple_task(), sip_outbound_publish_callback(), sip_publisher_service_queue(), sla_queue_event_full(), snoop_determine_format(), sorcery_observer_created(), sorcery_observer_deleted(), sorcery_observer_loaded(), sorcery_observer_updated(), stasis_app_control_record(), stasis_app_playback_get_state(), stasis_app_playback_operation(), stasis_app_recording_operation(), stasis_message_sink_dtor(), stasis_message_sink_should_stay(), stasis_message_sink_wait_for(), stasis_message_sink_wait_for_count(), task(), task_wait(), test_emptied(), test_state_changed(), test_sub(), test_task_pushed(), threadpool_active_thread_idle(), threadpool_idle_thread_dead(), threadpool_tps_emptied(), threadpool_tps_task_pushed(), threadpool_zombie_thread_dead(), unload_module(), unlock_it(), wait_for_completion(), wait_for_complex_completion(), wait_for_complex_start(), wait_for_empty_notice(), wait_for_stimulus(), wait_for_task_pushed(), wait_until_thread_state(), and worker_set_state().

◆ 

struct { ... } ringing_stations

◆ 

struct { ... } ringing_trunks

◆ 

struct { ... } sla

◆ sla_framehook_datastore

const struct ast_datastore_info sla_framehook_datastore
static
Initial value:
= {
.type = "app_sla",
}

Definition at line 610 of file app_sla.c.

Referenced by attach_framehook(), and remove_framehook().

◆ sla_registrar

const char sla_registrar[] = "SLA"
static

◆ sla_stations

struct ao2_container* sla_stations
static

◆ sla_trunk_opts

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

Definition at line 156 of file app_sla.c.

Referenced by sla_trunk_exec().

◆ sla_trunks

struct ao2_container* sla_trunks
static

◆ slastation_app

const char* const slastation_app = "SLAStation"
static

Definition at line 127 of file app_sla.c.

Referenced by load_module(), sla_build_station(), and unload_module().

◆ slatrunk_app

const char* const slatrunk_app = "SLATrunk"
static

Definition at line 128 of file app_sla.c.

Referenced by load_module(), sla_build_trunk(), and unload_module().

◆ stop

unsigned int stop

◆ thread

pthread_t thread