[svn-commits] oej: branch oej/pine-instance-uuid-1.8 r400214 - in /team/oej/pine-instance-u...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Oct 1 02:43:47 CDT 2013
Author: oej
Date: Tue Oct 1 02:43:31 2013
New Revision: 400214
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=400214
Log:
Resolving issues that this branch was suffering from. Poor little branch.
Modified:
team/oej/pine-instance-uuid-1.8/ (props changed)
team/oej/pine-instance-uuid-1.8/CHANGES
team/oej/pine-instance-uuid-1.8/UPGRADE.txt
team/oej/pine-instance-uuid-1.8/addons/chan_ooh323.c
team/oej/pine-instance-uuid-1.8/apps/app_meetme.c
team/oej/pine-instance-uuid-1.8/apps/app_mixmonitor.c
team/oej/pine-instance-uuid-1.8/apps/app_playback.c
team/oej/pine-instance-uuid-1.8/apps/app_queue.c
team/oej/pine-instance-uuid-1.8/apps/app_stack.c
team/oej/pine-instance-uuid-1.8/build_tools/prep_tarball
team/oej/pine-instance-uuid-1.8/cel/cel_custom.c
team/oej/pine-instance-uuid-1.8/channels/chan_dahdi.c
team/oej/pine-instance-uuid-1.8/channels/chan_iax2.c
team/oej/pine-instance-uuid-1.8/channels/chan_misdn.c
team/oej/pine-instance-uuid-1.8/channels/chan_sip.c
team/oej/pine-instance-uuid-1.8/channels/iax2-parser.c
team/oej/pine-instance-uuid-1.8/channels/misdn/isdn_msg_parser.c
team/oej/pine-instance-uuid-1.8/channels/sig_pri.c
team/oej/pine-instance-uuid-1.8/channels/sig_ss7.c
team/oej/pine-instance-uuid-1.8/channels/sip/dialplan_functions.c
team/oej/pine-instance-uuid-1.8/channels/sip/include/sip.h
team/oej/pine-instance-uuid-1.8/channels/sip/reqresp_parser.c
team/oej/pine-instance-uuid-1.8/configs/chan_dahdi.conf.sample
team/oej/pine-instance-uuid-1.8/configs/h323.conf.sample
team/oej/pine-instance-uuid-1.8/configs/iax.conf.sample
team/oej/pine-instance-uuid-1.8/configs/indications.conf.sample
team/oej/pine-instance-uuid-1.8/configs/queues.conf.sample
team/oej/pine-instance-uuid-1.8/configs/sip.conf.sample
team/oej/pine-instance-uuid-1.8/configs/sla.conf.sample
team/oej/pine-instance-uuid-1.8/configure.ac
team/oej/pine-instance-uuid-1.8/contrib/realtime/postgresql/realtime.sql
team/oej/pine-instance-uuid-1.8/default.exports
team/oej/pine-instance-uuid-1.8/funcs/func_channel.c
team/oej/pine-instance-uuid-1.8/funcs/func_dialgroup.c
team/oej/pine-instance-uuid-1.8/funcs/func_global.c
team/oej/pine-instance-uuid-1.8/funcs/func_strings.c
team/oej/pine-instance-uuid-1.8/include/asterisk/astmm.h
team/oej/pine-instance-uuid-1.8/include/asterisk/autoconfig.h.in
team/oej/pine-instance-uuid-1.8/include/asterisk/frame.h
team/oej/pine-instance-uuid-1.8/include/asterisk/lock.h
team/oej/pine-instance-uuid-1.8/include/asterisk/logger.h
team/oej/pine-instance-uuid-1.8/include/asterisk/utils.h
team/oej/pine-instance-uuid-1.8/main/abstract_jb.c
team/oej/pine-instance-uuid-1.8/main/asterisk.c
team/oej/pine-instance-uuid-1.8/main/asterisk.exports.in
team/oej/pine-instance-uuid-1.8/main/astfd.c
team/oej/pine-instance-uuid-1.8/main/astmm.c
team/oej/pine-instance-uuid-1.8/main/astobj2.c
team/oej/pine-instance-uuid-1.8/main/cdr.c
team/oej/pine-instance-uuid-1.8/main/cel.c
team/oej/pine-instance-uuid-1.8/main/channel.c
team/oej/pine-instance-uuid-1.8/main/cli.c
team/oej/pine-instance-uuid-1.8/main/config.c
team/oej/pine-instance-uuid-1.8/main/data.c
team/oej/pine-instance-uuid-1.8/main/event.c
team/oej/pine-instance-uuid-1.8/main/features.c
team/oej/pine-instance-uuid-1.8/main/heap.c
team/oej/pine-instance-uuid-1.8/main/http.c
team/oej/pine-instance-uuid-1.8/main/indications.c
team/oej/pine-instance-uuid-1.8/main/loader.c
team/oej/pine-instance-uuid-1.8/main/lock.c
team/oej/pine-instance-uuid-1.8/main/logger.c
team/oej/pine-instance-uuid-1.8/main/manager.c
team/oej/pine-instance-uuid-1.8/main/pbx.c
team/oej/pine-instance-uuid-1.8/main/slinfactory.c
team/oej/pine-instance-uuid-1.8/main/threadstorage.c
team/oej/pine-instance-uuid-1.8/main/utils.c
team/oej/pine-instance-uuid-1.8/main/xmldoc.c
team/oej/pine-instance-uuid-1.8/pbx/pbx_dundi.c
team/oej/pine-instance-uuid-1.8/pbx/pbx_loopback.c
team/oej/pine-instance-uuid-1.8/res/res_agi.c
team/oej/pine-instance-uuid-1.8/res/res_jabber.c
team/oej/pine-instance-uuid-1.8/res/res_musiconhold.c
team/oej/pine-instance-uuid-1.8/res/res_rtp_asterisk.c
team/oej/pine-instance-uuid-1.8/res/res_security_log.c
team/oej/pine-instance-uuid-1.8/res/res_srtp.c
team/oej/pine-instance-uuid-1.8/sounds/Makefile
team/oej/pine-instance-uuid-1.8/tests/test_hashtab_thrash.c
team/oej/pine-instance-uuid-1.8/tests/test_substitution.c
team/oej/pine-instance-uuid-1.8/utils/ (props changed)
team/oej/pine-instance-uuid-1.8/utils/Makefile
team/oej/pine-instance-uuid-1.8/utils/ael_main.c
team/oej/pine-instance-uuid-1.8/utils/check_expr.c
team/oej/pine-instance-uuid-1.8/utils/conf2ael.c
team/oej/pine-instance-uuid-1.8/utils/extconf.c
Propchange: team/oej/pine-instance-uuid-1.8/
------------------------------------------------------------------------------
automerge = Is-there-life-off-net?
Propchange: team/oej/pine-instance-uuid-1.8/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 1 02:43:31 2013
@@ -24,3 +24,4 @@
makeopts.embed_rules
aclocal.m4
update.log
+doxygen.log
Propchange: team/oej/pine-instance-uuid-1.8/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Oct 1 02:43:31 2013
@@ -1,1 +1,1 @@
-/branches/1.8:1-386606
+/branches/1.8:1-400213
Modified: team/oej/pine-instance-uuid-1.8/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-instance-uuid-1.8/CHANGES?view=diff&rev=400214&r1=400213&r2=400214
==============================================================================
--- team/oej/pine-instance-uuid-1.8/CHANGES (original)
+++ team/oej/pine-instance-uuid-1.8/CHANGES Tue Oct 1 02:43:31 2013
@@ -7,6 +7,15 @@
=== and the other UPGRADE files for older releases.
===
======================================================================
+
+------------------------------------------------------------------------------
+--- Functionality changes since Asterisk 1.8.19.1 ----------------------------
+------------------------------------------------------------------------------
+
+App_queue
+---------
+ * App_queue will now play periodic announcements for the caller that
+ holds the first position in the queue while waiting for answer.
------------------------------------------------------------------------------
--- Functionality changes since Asterisk 1.8.12.0 ----------------------------
Modified: team/oej/pine-instance-uuid-1.8/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-instance-uuid-1.8/UPGRADE.txt?view=diff&rev=400214&r1=400213&r2=400214
==============================================================================
--- team/oej/pine-instance-uuid-1.8/UPGRADE.txt (original)
+++ team/oej/pine-instance-uuid-1.8/UPGRADE.txt Tue Oct 1 02:43:31 2013
@@ -17,10 +17,25 @@
=== UPGRADE-1.6.txt -- Upgrade info for 1.4 to 1.6
===
===========================================================
+from 1.8.23.0 to 1.8.24.0:
+* res_agi will now properly indicate if there was an error in streaming an
+ audio file. The result code will be -1 and the result returned from the
+ the function will be RESULT_FAILURE instead of the prior behavior of always
+ returning RESULT_SUCCESS even if there was an error.
+
+* The option "register_retry_403" has been added to chan_sip to work around
+ servers that are known to erroneously send 403 in response to valid
+ REGISTER requests and allows Asterisk to continue attepmting to connect.
from 1.8.22.0 to 1.8.23.0:
* The default settings for chan_sip are now overriden properly by the general
settings in sip.conf. Please look over your settings upon upgrading.
+
+* It is now possible to play the Queue prompts to the first user waiting in a call queue.
+ Note that this may impact the ability for agents to talk with users, as a prompt may
+ still be playing when an agent connects to the user. This ability is disabled by
+ default but can be enabled on an individual queue using the 'announce-to-first-user'
+ option.
from 1.8.21.0 to 1.8.22.0:
* Added the 'n' option to MeetMe to prevent application of the DENOISE function
Modified: team/oej/pine-instance-uuid-1.8/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-instance-uuid-1.8/addons/chan_ooh323.c?view=diff&rev=400214&r1=400213&r2=400214
==============================================================================
--- team/oej/pine-instance-uuid-1.8/addons/chan_ooh323.c (original)
+++ team/oej/pine-instance-uuid-1.8/addons/chan_ooh323.c Tue Oct 1 02:43:31 2013
@@ -286,6 +286,8 @@
int onCallCleared(ooCallData *call);
void onModeChanged(ooCallData *call, int t38mode);
+extern OOH323EndPoint gH323ep;
+
static char gLogFile[256] = DEFAULT_LOGFILE;
static int gPort = 1720;
static char gIP[20];
@@ -629,6 +631,7 @@
ooh323_destroy(p);
ast_mutex_unlock(&iflock);
ast_log(LOG_ERROR, "Destination format is not supported\n");
+ *cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
return NULL;
}
@@ -671,6 +674,10 @@
ast_mutex_unlock(&p->lock);
ooh323_destroy(p);
ast_mutex_unlock(&iflock);
+ return NULL;
+ } else if (gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered) {
+ ast_log(LOG_ERROR, "Gatekeeper client is configured but not registered\n");
+ *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
return NULL;
}
p->g729onlyA = g729onlyA;
Modified: team/oej/pine-instance-uuid-1.8/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pine-instance-uuid-1.8/apps/app_meetme.c?view=diff&rev=400214&r1=400213&r2=400214
==============================================================================
--- team/oej/pine-instance-uuid-1.8/apps/app_meetme.c (original)
+++ team/oej/pine-instance-uuid-1.8/apps/app_meetme.c Tue Oct 1 02:43:31 2013
@@ -832,17 +832,26 @@
/*! This option uses the values in the sla_hold_access enum and sets the
* access control type for hold on this station. */
unsigned int hold_access:1;
- /*! Use count for inside sla_station_exec */
- unsigned int ref_count;
+ /*! Mark used during reload processing */
+ unsigned int mark:1;
};
+/*!
+ * \brief A reference to a station
+ *
+ * This struct looks near useless at first glance. However, its existence
+ * in the list of stations in sla_trunk means that this station references
+ * that trunk. We use the mark to keep track of whether it needs to be
+ * removed from the sla_trunk's list of stations during a reload.
+ */
struct sla_station_ref {
AST_LIST_ENTRY(sla_station_ref) entry;
struct sla_station *station;
+ /*! Mark used during reload processing */
+ unsigned int mark:1;
};
struct sla_trunk {
- AST_RWLIST_ENTRY(sla_trunk) entry;
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(name);
AST_STRING_FIELD(device);
@@ -866,10 +875,16 @@
/*! Whether this trunk is currently on hold, meaning that once a station
* connects to it, the trunk channel needs to have UNHOLD indicated to it. */
unsigned int on_hold:1;
- /*! Use count for inside sla_trunk_exec */
- unsigned int ref_count;
+ /*! Mark used during reload processing */
+ unsigned int mark:1;
};
+/*!
+ * \brief A station's reference to a trunk
+ *
+ * An sla_station keeps a list of trunk_refs. This holds metadata about the
+ * stations usage of the trunk.
+ */
struct sla_trunk_ref {
AST_LIST_ENTRY(sla_trunk_ref) entry;
struct sla_trunk *trunk;
@@ -883,10 +898,12 @@
* station. This takes higher priority than a ring delay set at
* the station level. */
unsigned int ring_delay;
+ /*! Mark used during reload processing */
+ unsigned int mark:1;
};
-static AST_RWLIST_HEAD_STATIC(sla_stations, sla_station);
-static AST_RWLIST_HEAD_STATIC(sla_trunks, sla_trunk);
+static struct ao2_container *sla_stations;
+static struct ao2_container *sla_trunks;
static const char sla_registrar[] = "SLA";
@@ -898,10 +915,6 @@
SLA_EVENT_DIAL_STATE,
/*! The state of a ringing trunk has changed */
SLA_EVENT_RINGING_TRUNK,
- /*! A reload of configuration has been requested */
- SLA_EVENT_RELOAD,
- /*! Poke the SLA thread so it can check if it can perform a reload */
- SLA_EVENT_CHECK_RELOAD,
};
struct sla_event {
@@ -957,8 +970,6 @@
/*! Attempt to handle CallerID, even though it is known not to work
* properly in some situations. */
unsigned int attempt_callerid:1;
- /*! A reload has been requested */
- unsigned int reload:1;
} sla = {
.thread = AST_PTHREADT_NULL,
};
@@ -1719,7 +1730,8 @@
static char *sla_show_trunks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- const struct sla_trunk *trunk;
+ struct ao2_iterator i;
+ struct sla_trunk *trunk;
switch (cmd) {
case CLI_INIT:
@@ -1737,12 +1749,17 @@
"=== Configured SLA Trunks ===================================\n"
"=============================================================\n"
"===\n");
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
+ i = ao2_iterator_init(sla_trunks, 0);
+ for (; (trunk = ao2_iterator_next(&i)); ao2_ref(trunk, -1)) {
struct sla_station_ref *station_ref;
char ring_timeout[16] = "(none)";
- if (trunk->ring_timeout)
+
+ ao2_lock(trunk);
+
+ if (trunk->ring_timeout) {
snprintf(ring_timeout, sizeof(ring_timeout), "%u Seconds", trunk->ring_timeout);
+ }
+
ast_cli(a->fd, "=== ---------------------------------------------------------\n"
"=== Trunk Name: %s\n"
"=== ==> Device: %s\n"
@@ -1756,13 +1773,16 @@
ring_timeout,
trunk->barge_disabled ? "No" : "Yes",
sla_hold_str(trunk->hold_access));
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry)
+
+ AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
ast_cli(a->fd, "=== ==> Station name: %s\n", station_ref->station->name);
- AST_RWLIST_UNLOCK(&sla_stations);
+ }
+
ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
+
+ ao2_unlock(trunk);
+ }
+ ao2_iterator_destroy(&i);
ast_cli(a->fd, "=============================================================\n\n");
return CLI_SUCCESS;
@@ -1784,7 +1804,8 @@
static char *sla_show_stations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- const struct sla_station *station;
+ struct ao2_iterator i;
+ struct sla_station *station;
switch (cmd) {
case CLI_INIT:
@@ -1802,11 +1823,14 @@
"=== Configured SLA Stations =================================\n"
"=============================================================\n"
"===\n");
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
+ i = ao2_iterator_init(sla_stations, 0);
+ for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
struct sla_trunk_ref *trunk_ref;
char ring_timeout[16] = "(none)";
char ring_delay[16] = "(none)";
+
+ ao2_lock(station);
+
if (station->ring_timeout) {
snprintf(ring_timeout, sizeof(ring_timeout),
"%u", station->ring_timeout);
@@ -1827,7 +1851,6 @@
S_OR(station->autocontext, "(none)"),
ring_timeout, ring_delay,
sla_hold_str(station->hold_access));
- AST_RWLIST_RDLOCK(&sla_trunks);
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
if (trunk_ref->ring_timeout) {
snprintf(ring_timeout, sizeof(ring_timeout),
@@ -1847,11 +1870,12 @@
trunkstate2str(trunk_ref->state),
ring_timeout, ring_delay);
}
- AST_RWLIST_UNLOCK(&sla_trunks);
ast_cli(a->fd, "=== ---------------------------------------------------------\n"
"===\n");
- }
- AST_RWLIST_UNLOCK(&sla_stations);
+
+ ao2_unlock(station);
+ }
+ ao2_iterator_destroy(&i);
ast_cli(a->fd, "============================================================\n"
"\n");
@@ -1991,11 +2015,16 @@
struct sla_event *event;
if (sla.thread == AST_PTHREADT_NULL) {
+ ao2_ref(station, -1);
+ ao2_ref(trunk_ref, -1);
return;
}
- if (!(event = ast_calloc(1, sizeof(*event))))
+ if (!(event = ast_calloc(1, sizeof(*event)))) {
+ ao2_ref(station, -1);
+ ao2_ref(trunk_ref, -1);
return;
+ }
event->type = type;
event->trunk_ref = trunk_ref;
@@ -2029,6 +2058,7 @@
struct sla_station *station;
struct sla_trunk_ref *trunk_ref = NULL;
char *trunk_name;
+ struct ao2_iterator i;
trunk_name = ast_strdupa(conf->confno);
strsep(&trunk_name, "_");
@@ -2037,16 +2067,23 @@
return;
}
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
+ i = ao2_iterator_init(sla_stations, 0);
+ while ((station = ao2_iterator_next(&i))) {
+ ao2_lock(station);
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name))
+ if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name)) {
+ ao2_ref(trunk_ref, 1);
break;
- }
- if (trunk_ref)
+ }
+ }
+ ao2_unlock(station);
+ if (trunk_ref) {
+ /* station reference given to sla_queue_event_full() */
break;
- }
- AST_RWLIST_UNLOCK(&sla_stations);
+ }
+ ao2_ref(station, -1);
+ }
+ ao2_iterator_destroy(&i);
if (!trunk_ref) {
ast_debug(1, "Trunk not found for event!\n");
@@ -4801,6 +4838,23 @@
res = -2;
goto usernotfound;
}
+ } else {
+ /* fail for commands that require a user */
+ switch (*args.command) {
+ case 'm': /* Unmute */
+ case 'M': /* Mute */
+ case 't': /* Lower user's talk volume */
+ case 'T': /* Raise user's talk volume */
+ case 'u': /* Lower user's listen volume */
+ case 'U': /* Raise user's listen volume */
+ case 'r': /* Reset user's volume level */
+ case 'k': /* Kick user */
+ res = -2;
+ ast_log(LOG_NOTICE, "No user specified!\n");
+ goto usernotfound;
+ default:
+ break;
+ }
}
switch (*args.command) {
@@ -4816,21 +4870,24 @@
case 101: /* e: Eject last user*/
{
int max_no = 0;
-
- /* If they passed in a user, disregard it */
- if (user) {
- ao2_ref(user, -1);
- }
+ struct ast_conf_user *eject_user;
ao2_callback(cnf->usercontainer, OBJ_NODATA, user_max_cmp, &max_no);
- user = ao2_find(cnf->usercontainer, &max_no, 0);
- if (!ast_test_flag64(&user->userflags, CONFFLAG_ADMIN))
- user->adminflags |= ADMINFLAG_KICKME;
- else {
+ eject_user = ao2_find(cnf->usercontainer, &max_no, 0);
+ if (!eject_user) {
+ res = -1;
+ ast_log(LOG_NOTICE, "No last user to kick!\n");
+ break;
+ }
+
+ if (!ast_test_flag64(&eject_user->userflags, CONFFLAG_ADMIN)) {
+ eject_user->adminflags |= ADMINFLAG_KICKME;
+ } else {
res = -1;
ast_log(LOG_NOTICE, "Not kicking last user, is an Admin!\n");
}
- ao2_ref(user, -1);
+
+ ao2_ref(eject_user, -1);
break;
}
case 77: /* M: Mute */
@@ -5292,34 +5349,41 @@
ast_config_destroy(cfg);
}
-/*! \brief Find an SLA trunk by name
- * \note This must be called with the sla_trunks container locked
+/*!
+ * \private
+ * \brief helper for RAII_VAR
+ */
+static void unref_obj(void *obj)
+{
+ if (obj) {
+ ao2_ref(obj, -1);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Find an SLA trunk by name
*/
static struct sla_trunk *sla_find_trunk(const char *name)
{
- struct sla_trunk *trunk = NULL;
-
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
- if (!strcasecmp(trunk->name, name))
- break;
- }
-
- return trunk;
-}
-
-/*! \brief Find an SLA station by name
- * \note This must be called with the sla_stations container locked
+ struct sla_trunk tmp_trunk = {
+ .name = name,
+ };
+
+ return ao2_find(sla_trunks, &tmp_trunk, OBJ_POINTER);
+}
+
+/*!
+ * \internal
+ * \brief Find an SLA station by name
*/
static struct sla_station *sla_find_station(const char *name)
{
- struct sla_station *station = NULL;
-
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
- if (!strcasecmp(station->name, name))
- break;
- }
-
- return station;
+ struct sla_station tmp_station = {
+ .name = name,
+ };
+
+ return ao2_find(sla_stations, &tmp_station, OBJ_POINTER);
}
static int sla_check_station_hold_access(const struct sla_trunk *trunk,
@@ -5343,9 +5407,11 @@
return 0;
}
-/*! \brief Find a trunk reference on a station by name
+/*!
+ * \brief Find a trunk reference on a station by name
* \param station the station
* \param name the trunk's name
+ * \pre sla_station is locked
* \return 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.
@@ -5372,16 +5438,32 @@
break;
}
+ if (trunk_ref) {
+ ao2_ref(trunk_ref, 1);
+ }
+
return trunk_ref;
}
+static void sla_station_ref_destructor(void *obj)
+{
+ struct sla_station_ref *station_ref = obj;
+
+ if (station_ref->station) {
+ ao2_ref(station_ref->station, -1);
+ station_ref->station = NULL;
+ }
+}
+
static struct sla_station_ref *sla_create_station_ref(struct sla_station *station)
{
struct sla_station_ref *station_ref;
- if (!(station_ref = ast_calloc(1, sizeof(*station_ref))))
+ if (!(station_ref = ao2_alloc(sizeof(*station_ref), sla_station_ref_destructor))) {
return NULL;
-
+ }
+
+ ao2_ref(station, 1);
station_ref->station = station;
return station_ref;
@@ -5394,10 +5476,46 @@
if (!(ringing_station = ast_calloc(1, sizeof(*ringing_station))))
return NULL;
+ ao2_ref(station, 1);
ringing_station->station = station;
ringing_station->ring_begin = ast_tvnow();
return ringing_station;
+}
+
+static void sla_ringing_station_destroy(struct sla_ringing_station *ringing_station)
+{
+ if (ringing_station->station) {
+ ao2_ref(ringing_station->station, -1);
+ ringing_station->station = NULL;
+ }
+
+ ast_free(ringing_station);
+}
+
+static struct sla_failed_station *sla_create_failed_station(struct sla_station *station)
+{
+ struct sla_failed_station *failed_station;
+
+ if (!(failed_station = ast_calloc(1, sizeof(*failed_station)))) {
+ return NULL;
+ }
+
+ ao2_ref(station, 1);
+ failed_station->station = station;
+ failed_station->last_try = ast_tvnow();
+
+ return failed_station;
+}
+
+static void sla_failed_station_destroy(struct sla_failed_station *failed_station)
+{
+ if (failed_station->station) {
+ ao2_ref(failed_station->station, -1);
+ failed_station->station = NULL;
+ }
+
+ ast_free(failed_station);
}
static enum ast_device_state sla_state_to_devstate(enum sla_trunk_state state)
@@ -5422,18 +5540,25 @@
{
struct sla_station *station;
struct sla_trunk_ref *trunk_ref;
-
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
+ struct ao2_iterator i;
+
+ i = ao2_iterator_init(sla_stations, 0);
+ while ((station = ao2_iterator_next(&i))) {
+ ao2_lock(station);
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0)
- || trunk_ref == exclude)
+ || trunk_ref == exclude) {
continue;
+ }
trunk_ref->state = state;
ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE,
"SLA:%s_%s", station->name, trunk->name);
break;
}
- }
+ ao2_unlock(station);
+ ao2_ref(station, -1);
+ }
+ ao2_iterator_destroy(&i);
}
struct run_station_args {
@@ -5451,8 +5576,8 @@
static void *run_station(void *data)
{
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref;
+ RAII_VAR(struct sla_station *, station, NULL, unref_obj);
+ RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
struct ast_str *conf_name = ast_str_create(16);
struct ast_flags64 conf_flags = { 0 };
struct ast_conference *conf;
@@ -5495,6 +5620,8 @@
return NULL;
}
+static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk);
+
static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
{
char buf[80];
@@ -5504,10 +5631,11 @@
admin_exec(NULL, buf);
sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
- while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry)))
- ast_free(station_ref);
-
- ast_free(ringing_trunk);
+ while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry))) {
+ ao2_ref(station_ref, -1);
+ }
+
+ sla_ringing_trunk_destroy(ringing_trunk);
}
static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station,
@@ -5542,7 +5670,7 @@
}
done:
- ast_free(ringing_station);
+ sla_ringing_station_destroy(ringing_station);
}
static void sla_dial_state_callback(struct ast_dial *dial)
@@ -5594,8 +5722,10 @@
if (rm)
AST_LIST_REMOVE_CURRENT(entry);
- if (trunk_ref)
+ if (trunk_ref) {
+ ao2_ref(s_trunk_ref, 1);
*trunk_ref = s_trunk_ref;
+ }
break;
}
@@ -5613,7 +5743,7 @@
struct sla_ringing_station *ringing_station;
AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
- struct sla_trunk_ref *s_trunk_ref = NULL;
+ RAII_VAR(struct sla_trunk_ref *, s_trunk_ref, NULL, unref_obj);
struct sla_ringing_trunk *ringing_trunk = NULL;
struct run_station_args args;
enum ast_dial_result dial_res;
@@ -5646,7 +5776,7 @@
ast_dial_join(ringing_station->station->dial);
ast_dial_destroy(ringing_station->station->dial);
ringing_station->station->dial = NULL;
- ast_free(ringing_station);
+ sla_ringing_station_destroy(ringing_station);
break;
}
/* Track the channel that answered this trunk */
@@ -5657,12 +5787,14 @@
/* Now, start a thread that will connect this station to the trunk. The rest of
* the code here sets up the thread and ensures that it is able to save the arguments
* before they are no longer valid since they are allocated on the stack. */
+ ao2_ref(s_trunk_ref, 1);
args.trunk_ref = s_trunk_ref;
+ ao2_ref(ringing_station->station, 1);
args.station = ringing_station->station;
args.cond = &cond;
args.cond_lock = &cond_lock;
- ast_free(ringing_trunk);
- ast_free(ringing_station);
+ sla_ringing_trunk_destroy(ringing_trunk);
+ sla_ringing_station_destroy(ringing_station);
ast_mutex_init(&cond_lock);
ast_cond_init(&cond, NULL);
ast_mutex_lock(&cond_lock);
@@ -5716,7 +5848,7 @@
continue;
if (ast_tvdiff_ms(ast_tvnow(), failed_station->last_try) > 1000) {
AST_LIST_REMOVE_CURRENT(entry);
- ast_free(failed_station);
+ sla_failed_station_destroy(failed_station);
break;
}
res = 1;
@@ -5769,11 +5901,9 @@
if (res != AST_DIAL_RESULT_TRYING) {
struct sla_failed_station *failed_station;
ast_dial_destroy(dial);
- if (!(failed_station = ast_calloc(1, sizeof(*failed_station))))
- return -1;
- failed_station->station = station;
- failed_station->last_try = ast_tvnow();
- AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
+ if ((failed_station = sla_create_failed_station(station))) {
+ AST_LIST_INSERT_HEAD(&sla.failed_stations, failed_station, entry);
+ }
return -1;
}
if (!(ringing_station = sla_create_ringing_station(station))) {
@@ -5812,6 +5942,8 @@
if (trunk_ref->trunk == trunk)
break;
}
+
+ ao2_ref(trunk_ref, 1);
return trunk_ref;
}
@@ -5824,7 +5956,7 @@
static int sla_check_station_delay(struct sla_station *station,
struct sla_ringing_trunk *ringing_trunk)
{
- struct sla_trunk_ref *trunk_ref;
+ RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
unsigned int delay = UINT_MAX;
int time_left, time_elapsed;
@@ -5917,7 +6049,7 @@
ast_dial_join(ringing_station->station->dial);
ast_dial_destroy(ringing_station->station->dial);
ringing_station->station->dial = NULL;
- ast_free(ringing_station);
+ sla_ringing_station_destroy(ringing_station);
}
}
AST_LIST_TRAVERSE_SAFE_END
@@ -6074,8 +6206,10 @@
{
struct sla_station *station;
int res = 0;
-
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
+ struct ao2_iterator i;
+
+ i = ao2_iterator_init(sla_stations, 0);
+ for (; (station = ao2_iterator_next(&i)); ao2_ref(station, -1)) {
struct sla_ringing_trunk *ringing_trunk;
int time_left;
@@ -6105,6 +6239,7 @@
if (time_left < *timeout)
*timeout = time_left;
}
+ ao2_iterator_destroy(&i);
return res;
}
@@ -6146,49 +6281,19 @@
return 1;
}
-static int sla_load_config(int reload);
-
-/*! \brief Check if we can do a reload of SLA, and do it if we can */
-static void sla_check_reload(void)
-{
- struct sla_station *station;
- struct sla_trunk *trunk;
-
- ast_mutex_lock(&sla.lock);
-
- if (!AST_LIST_EMPTY(&sla.event_q) || !AST_LIST_EMPTY(&sla.ringing_trunks)
- || !AST_LIST_EMPTY(&sla.ringing_stations)) {
- ast_mutex_unlock(&sla.lock);
- return;
- }
-
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
- if (station->ref_count)
- break;
- }
- AST_RWLIST_UNLOCK(&sla_stations);
- if (station) {
- ast_mutex_unlock(&sla.lock);
- return;
- }
-
- AST_RWLIST_RDLOCK(&sla_trunks);
- AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
- if (trunk->ref_count)
- break;
- }
- AST_RWLIST_UNLOCK(&sla_trunks);
- if (trunk) {
- ast_mutex_unlock(&sla.lock);
- return;
- }
-
- /* yay */
- sla_load_config(1);
- sla.reload = 0;
-
- ast_mutex_unlock(&sla.lock);
+static void sla_event_destroy(struct sla_event *event)
+{
+ if (event->trunk_ref) {
+ ao2_ref(event->trunk_ref, -1);
+ event->trunk_ref = NULL;
+ }
+
+ if (event->station) {
+ ao2_ref(event->station, -1);
+ event->station = NULL;
+ }
+
+ ast_free(event);
}
static void *sla_thread(void *data)
@@ -6227,27 +6332,21 @@
case SLA_EVENT_RINGING_TRUNK:
sla_handle_ringing_trunk_event();
break;
- case SLA_EVENT_RELOAD:
- sla.reload = 1;
- case SLA_EVENT_CHECK_RELOAD:
- break;
- }
- ast_free(event);
+ }
+ sla_event_destroy(event);
ast_mutex_lock(&sla.lock);
}
-
- if (sla.reload) {
- sla_check_reload();
- }
}
ast_mutex_unlock(&sla.lock);
- while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry)))
- ast_free(ringing_station);
-
- while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry)))
- ast_free(failed_station);
+ while ((ringing_station = AST_LIST_REMOVE_HEAD(&sla.ringing_stations, entry))) {
+ sla_ringing_station_destroy(ringing_station);
+ }
+
+ while ((failed_station = AST_LIST_REMOVE_HEAD(&sla.failed_stations, entry))) {
+ sla_failed_station_destroy(failed_station);
+ }
return NULL;
}
@@ -6268,7 +6367,8 @@
char conf_name[MAX_CONFNUM];
struct ast_conference *conf;
struct ast_flags64 conf_flags = { 0 };
- struct sla_trunk_ref *trunk_ref = args->trunk_ref;
+ RAII_VAR(struct sla_trunk_ref *, trunk_ref, args->trunk_ref, unref_obj);
+ RAII_VAR(struct sla_station *, station, args->station, unref_obj);
int caller_is_saved;
struct ast_party_caller caller;
int last_state = 0;
@@ -6340,8 +6440,8 @@
break;
/* check that SLA station that originated trunk call is still alive */
- if (args->station && ast_device_state(args->station->device) == AST_DEVICE_NOT_INUSE) {
- ast_debug(3, "Originating station device %s no longer active\n", args->station->device);
+ if (station && ast_device_state(station->device) == AST_DEVICE_NOT_INUSE) {
+ ast_debug(3, "Originating station device %s no longer active\n", station->device);
trunk_ref->trunk->chan = NULL;
break;
}
@@ -6394,15 +6494,19 @@
return NULL;
}
-/*! \brief For a given station, choose the highest priority idle trunk
+/*!
+ * \brief For a given station, choose the highest priority idle trunk
+ * \pre sla_station is locked
*/
static struct sla_trunk_ref *sla_choose_idle_trunk(const struct sla_station *station)
{
struct sla_trunk_ref *trunk_ref = NULL;
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (trunk_ref->state == SLA_TRUNK_STATE_IDLE)
+ if (trunk_ref->state == SLA_TRUNK_STATE_IDLE) {
+ ao2_ref(trunk_ref, 1);
break;
+ }
}
return trunk_ref;
@@ -6411,8 +6515,8 @@
static int sla_station_exec(struct ast_channel *chan, const char *data)
{
char *station_name, *trunk_name;
- struct sla_station *station;
- struct sla_trunk_ref *trunk_ref = NULL;
+ RAII_VAR(struct sla_station *, station, NULL, unref_obj);
+ RAII_VAR(struct sla_trunk_ref *, trunk_ref, NULL, unref_obj);
char conf_name[MAX_CONFNUM];
struct ast_flags64 conf_flags = { 0 };
struct ast_conference *conf;
@@ -6432,25 +6536,21 @@
return 0;
}
- AST_RWLIST_RDLOCK(&sla_stations);
station = sla_find_station(station_name);
- if (station)
- ast_atomic_fetchadd_int((int *) &station->ref_count, 1);
- AST_RWLIST_UNLOCK(&sla_stations);
if (!station) {
ast_log(LOG_WARNING, "Station '%s' not found!\n", station_name);
pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "FAILURE");
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
- AST_RWLIST_RDLOCK(&sla_trunks);
+ ao2_lock(station);
if (!ast_strlen_zero(trunk_name)) {
trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
- } else
+ } else {
trunk_ref = sla_choose_idle_trunk(station);
- AST_RWLIST_UNLOCK(&sla_trunks);
+ }
+ ao2_unlock(station);
if (!trunk_ref) {
if (ast_strlen_zero(trunk_name))
@@ -6460,8 +6560,6 @@
"'%s' due to access controls.\n", trunk_name);
}
pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
- ast_atomic_fetchadd_int((int *) &station->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
@@ -6490,7 +6588,7 @@
answer_trunk_chan(ringing_trunk->trunk->chan);
sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
- free(ringing_trunk);
+ sla_ringing_trunk_destroy(ringing_trunk);
/* Queue up reprocessing ringing trunks, and then ringing stations again */
sla_queue_event(SLA_EVENT_RINGING_TRUNK);
@@ -6510,6 +6608,8 @@
.cond_lock = &cond_lock,
.cond = &cond,
};
+ ao2_ref(trunk_ref, 1);
+ ao2_ref(station, 1);
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
/* Create a thread to dial the trunk and dump it into the conference.
* However, we want to wait until the trunk has been dialed and the
@@ -6529,8 +6629,6 @@
pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
trunk_ref->chan = NULL;
- ast_atomic_fetchadd_int((int *) &station->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
}
@@ -6563,19 +6661,28 @@
pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
- ast_atomic_fetchadd_int((int *) &station->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
-
return 0;
}
+static void sla_trunk_ref_destructor(void *obj)
+{
+ struct sla_trunk_ref *trunk_ref = obj;
+
+ if (trunk_ref->trunk) {
+ ao2_ref(trunk_ref->trunk, -1);
+ trunk_ref->trunk = NULL;
+ }
+}
+
static struct sla_trunk_ref *create_trunk_ref(struct sla_trunk *trunk)
{
struct sla_trunk_ref *trunk_ref;
- if (!(trunk_ref = ast_calloc(1, sizeof(*trunk_ref))))
+ if (!(trunk_ref = ao2_alloc(sizeof(*trunk_ref), sla_trunk_ref_destructor))) {
return NULL;
-
+ }
+
+ ao2_ref(trunk, 1);
trunk_ref->trunk = trunk;
return trunk_ref;
@@ -6585,9 +6692,11 @@
{
struct sla_ringing_trunk *ringing_trunk;
- if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk))))
+ if (!(ringing_trunk = ast_calloc(1, sizeof(*ringing_trunk)))) {
return NULL;
-
+ }
+
+ ao2_ref(trunk, 1);
ringing_trunk->trunk = trunk;
ringing_trunk->ring_begin = ast_tvnow();
@@ -6600,6 +6709,16 @@
sla_queue_event(SLA_EVENT_RINGING_TRUNK);
return ringing_trunk;
+}
+
+static void sla_ringing_trunk_destroy(struct sla_ringing_trunk *ringing_trunk)
+{
+ if (ringing_trunk->trunk) {
+ ao2_ref(ringing_trunk->trunk, -1);
+ ringing_trunk->trunk = NULL;
+ }
+
+ ast_free(ringing_trunk);
}
enum {
@@ -6620,7 +6739,7 @@
char conf_name[MAX_CONFNUM];
struct ast_conference *conf;
struct ast_flags64 conf_flags = { 0 };
- struct sla_trunk *trunk;
+ RAII_VAR(struct sla_trunk *, trunk, NULL, unref_obj);
struct sla_ringing_trunk *ringing_trunk;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(trunk_name);
@@ -6644,16 +6763,11 @@
}
}
- AST_RWLIST_RDLOCK(&sla_trunks);
trunk = sla_find_trunk(args.trunk_name);
- if (trunk)
- ast_atomic_fetchadd_int((int *) &trunk->ref_count, 1);
- AST_RWLIST_UNLOCK(&sla_trunks);
if (!trunk) {
ast_log(LOG_ERROR, "SLA Trunk '%s' not found!\n", args.trunk_name);
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
@@ -6661,8 +6775,6 @@
ast_log(LOG_ERROR, "Call came in on %s, but the trunk is already in use!\n",
args.trunk_name);
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- ast_atomic_fetchadd_int((int *) &trunk->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
@@ -6670,8 +6782,6 @@
if (!(ringing_trunk = queue_ringing_trunk(trunk))) {
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- ast_atomic_fetchadd_int((int *) &trunk->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
@@ -6679,8 +6789,6 @@
conf = build_conf(conf_name, "", "", 1, 1, 1, chan, NULL);
if (!conf) {
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "FAILURE");
- ast_atomic_fetchadd_int((int *) &trunk->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
return 0;
}
ast_set_flag64(&conf_flags,
@@ -6714,46 +6822,37 @@
AST_LIST_TRAVERSE_SAFE_END;
ast_mutex_unlock(&sla.lock);
if (ringing_trunk) {
- ast_free(ringing_trunk);
+ sla_ringing_trunk_destroy(ringing_trunk);
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "UNANSWERED");
/* Queue reprocessing of ringing trunks to make stations stop ringing
* that shouldn't be ringing after this trunk stopped. */
sla_queue_event(SLA_EVENT_RINGING_TRUNK);
}
- ast_atomic_fetchadd_int((int *) &trunk->ref_count, -1);
- sla_queue_event(SLA_EVENT_CHECK_RELOAD);
-
return 0;
}
static enum ast_device_state sla_state(const char *data)
{
char *buf, *station_name, *trunk_name;
- struct sla_station *station;
+ RAII_VAR(struct sla_station *, station, NULL, unref_obj);
struct sla_trunk_ref *trunk_ref;
enum ast_device_state res = AST_DEVICE_INVALID;
trunk_name = buf = ast_strdupa(data);
station_name = strsep(&trunk_name, "_");
- AST_RWLIST_RDLOCK(&sla_stations);
- AST_LIST_TRAVERSE(&sla_stations, station, entry) {
- if (strcasecmp(station_name, station->name))
- continue;
- AST_RWLIST_RDLOCK(&sla_trunks);
+ station = sla_find_station(station_name);
+ if (station) {
+ ao2_lock(station);
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
- if (!strcasecmp(trunk_name, trunk_ref->trunk->name))
+ if (!strcasecmp(trunk_name, trunk_ref->trunk->name)) {
+ res = sla_state_to_devstate(trunk_ref->state);
break;
- }
- if (!trunk_ref) {
- AST_RWLIST_UNLOCK(&sla_trunks);
- break;
- }
- res = sla_state_to_devstate(trunk_ref->state);
- AST_RWLIST_UNLOCK(&sla_trunks);
- }
- AST_RWLIST_UNLOCK(&sla_stations);
+ }
+ }
+ ao2_unlock(station);
+ }
if (res == AST_DEVICE_INVALID) {
ast_log(LOG_ERROR, "Could not determine state for trunk %s on station %s!\n",
@@ -6763,26 +6862,39 @@
return res;
}
-static void destroy_trunk(struct sla_trunk *trunk)
-{
+static int sla_trunk_release_refs(void *obj, void *arg, int flags)
+{
+ struct sla_trunk *trunk = obj;
[... 6103 lines stripped ...]
More information about the svn-commits
mailing list