[asterisk-commits] oej: branch oej/no-premature-183 r190660 - in /team/oej/no-premature-183: ./ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Apr 27 13:02:26 CDT 2009
Author: oej
Date: Mon Apr 27 13:02:12 2009
New Revision: 190660
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=190660
Log:
Reset automerge in this branch
Added:
team/oej/no-premature-183/default.exports
- copied unchanged from r190356, branches/1.4/default.exports
team/oej/no-premature-183/main/asterisk.exports
- copied unchanged from r190356, branches/1.4/main/asterisk.exports
team/oej/no-premature-183/main/astfd.c
- copied unchanged from r190356, branches/1.4/main/astfd.c
team/oej/no-premature-183/res/res_adsi.exports
- copied unchanged from r190356, branches/1.4/res/res_adsi.exports
team/oej/no-premature-183/res/res_agi.exports
- copied unchanged from r190356, branches/1.4/res/res_agi.exports
team/oej/no-premature-183/res/res_features.exports
- copied unchanged from r190356, branches/1.4/res/res_features.exports
team/oej/no-premature-183/res/res_jabber.exports
- copied unchanged from r190356, branches/1.4/res/res_jabber.exports
team/oej/no-premature-183/res/res_monitor.exports
- copied unchanged from r190356, branches/1.4/res/res_monitor.exports
team/oej/no-premature-183/res/res_odbc.exports
- copied unchanged from r190356, branches/1.4/res/res_odbc.exports
team/oej/no-premature-183/res/res_smdi.exports
- copied unchanged from r190356, branches/1.4/res/res_smdi.exports
team/oej/no-premature-183/res/res_speech.exports
- copied unchanged from r190356, branches/1.4/res/res_speech.exports
Removed:
team/oej/no-premature-183/build_tools/strip_nonapi
Modified:
team/oej/no-premature-183/ (props changed)
team/oej/no-premature-183/Makefile.rules
team/oej/no-premature-183/agi/Makefile
team/oej/no-premature-183/apps/app_dahdiras.c
team/oej/no-premature-183/apps/app_dial.c
team/oej/no-premature-183/apps/app_flash.c
team/oej/no-premature-183/apps/app_followme.c
team/oej/no-premature-183/apps/app_macro.c
team/oej/no-premature-183/apps/app_meetme.c
team/oej/no-premature-183/apps/app_mp3.c
team/oej/no-premature-183/apps/app_nbscat.c
team/oej/no-premature-183/apps/app_queue.c
team/oej/no-premature-183/apps/app_senddtmf.c
team/oej/no-premature-183/apps/app_sendtext.c
team/oej/no-premature-183/apps/app_test.c
team/oej/no-premature-183/apps/app_voicemail.c
team/oej/no-premature-183/autoconf/ast_check_gnu_make.m4
team/oej/no-premature-183/autoconf/ast_check_openh323.m4
team/oej/no-premature-183/autoconf/ast_prog_sed.m4
team/oej/no-premature-183/build_tools/cflags.xml
team/oej/no-premature-183/build_tools/make_version
team/oej/no-premature-183/cdr/cdr_radius.c
team/oej/no-premature-183/channels/Makefile
team/oej/no-premature-183/channels/chan_agent.c
team/oej/no-premature-183/channels/chan_alsa.c
team/oej/no-premature-183/channels/chan_dahdi.c
team/oej/no-premature-183/channels/chan_gtalk.c
team/oej/no-premature-183/channels/chan_h323.c
team/oej/no-premature-183/channels/chan_iax2.c
team/oej/no-premature-183/channels/chan_local.c
team/oej/no-premature-183/channels/chan_misdn.c
team/oej/no-premature-183/channels/chan_sip.c
team/oej/no-premature-183/channels/chan_skinny.c
team/oej/no-premature-183/channels/h323/ast_h323.cxx
team/oej/no-premature-183/channels/h323/ast_h323.h
team/oej/no-premature-183/channels/h323/chan_h323.h
team/oej/no-premature-183/channels/h323/compat_h323.cxx
team/oej/no-premature-183/channels/h323/compat_h323.h
team/oej/no-premature-183/channels/iax2-parser.h
team/oej/no-premature-183/channels/misdn/isdn_lib.c
team/oej/no-premature-183/channels/misdn_config.c
team/oej/no-premature-183/configs/extensions.conf.sample
team/oej/no-premature-183/configs/features.conf.sample
team/oej/no-premature-183/configs/misdn.conf.sample
team/oej/no-premature-183/configs/queues.conf.sample
team/oej/no-premature-183/configs/sip.conf.sample
team/oej/no-premature-183/configs/voicemail.conf.sample
team/oej/no-premature-183/configure
team/oej/no-premature-183/configure.ac
team/oej/no-premature-183/contrib/scripts/get_ilbc_source.sh
team/oej/no-premature-183/contrib/scripts/realtime_pgsql.sql
team/oej/no-premature-183/contrib/scripts/sip-friends.sql
team/oej/no-premature-183/doc/channelvariables.txt
team/oej/no-premature-183/formats/format_wav.c
team/oej/no-premature-183/formats/format_wav_gsm.c
team/oej/no-premature-183/funcs/func_odbc.c
team/oej/no-premature-183/funcs/func_strings.c
team/oej/no-premature-183/include/asterisk.h
team/oej/no-premature-183/include/asterisk/astmm.h
team/oej/no-premature-183/include/asterisk/astobj2.h
team/oej/no-premature-183/include/asterisk/autoconfig.h.in
team/oej/no-premature-183/include/asterisk/callerid.h
team/oej/no-premature-183/include/asterisk/channel.h
team/oej/no-premature-183/include/asterisk/compat.h
team/oej/no-premature-183/include/asterisk/crypto.h
team/oej/no-premature-183/include/asterisk/features.h
team/oej/no-premature-183/include/asterisk/frame.h
team/oej/no-premature-183/include/asterisk/io.h
team/oej/no-premature-183/include/asterisk/lock.h
team/oej/no-premature-183/include/asterisk/poll-compat.h
team/oej/no-premature-183/include/asterisk/threadstorage.h
team/oej/no-premature-183/include/asterisk/utils.h
team/oej/no-premature-183/main/Makefile
team/oej/no-premature-183/main/app.c
team/oej/no-premature-183/main/ast_expr2.c
team/oej/no-premature-183/main/ast_expr2.fl
team/oej/no-premature-183/main/ast_expr2.h
team/oej/no-premature-183/main/ast_expr2.y
team/oej/no-premature-183/main/ast_expr2f.c
team/oej/no-premature-183/main/asterisk.c
team/oej/no-premature-183/main/astobj2.c
team/oej/no-premature-183/main/audiohook.c
team/oej/no-premature-183/main/callerid.c
team/oej/no-premature-183/main/channel.c
team/oej/no-premature-183/main/config.c
team/oej/no-premature-183/main/db.c
team/oej/no-premature-183/main/db1-ast/recno/rec_open.c
team/oej/no-premature-183/main/editline/configure
team/oej/no-premature-183/main/editline/configure.in
team/oej/no-premature-183/main/editline/np/unvis.c
team/oej/no-premature-183/main/editline/sys.h
team/oej/no-premature-183/main/enum.c
team/oej/no-premature-183/main/file.c
team/oej/no-premature-183/main/frame.c
team/oej/no-premature-183/main/io.c
team/oej/no-premature-183/main/loader.c
team/oej/no-premature-183/main/manager.c
team/oej/no-premature-183/main/pbx.c
team/oej/no-premature-183/main/poll.c
team/oej/no-premature-183/main/rtp.c
team/oej/no-premature-183/main/utils.c
team/oej/no-premature-183/makeopts.in
team/oej/no-premature-183/pbx/ael/ael.tab.c
team/oej/no-premature-183/pbx/ael/ael.y
team/oej/no-premature-183/pbx/pbx_ael.c
team/oej/no-premature-183/pbx/pbx_config.c
team/oej/no-premature-183/res/res_agi.c
team/oej/no-premature-183/res/res_config_odbc.c
team/oej/no-premature-183/res/res_config_pgsql.c
team/oej/no-premature-183/res/res_crypto.c
team/oej/no-premature-183/res/res_features.c
team/oej/no-premature-183/res/res_indications.c
team/oej/no-premature-183/res/res_monitor.c
team/oej/no-premature-183/res/res_musiconhold.c
team/oej/no-premature-183/res/res_odbc.c
team/oej/no-premature-183/res/res_snmp.c
team/oej/no-premature-183/sounds/Makefile
team/oej/no-premature-183/utils/Makefile
team/oej/no-premature-183/utils/expr2.testinput
team/oej/no-premature-183/utils/muted.c
Propchange: team/oej/no-premature-183/
------------------------------------------------------------------------------
automerge = http://www.codename-pineapple.org/
Propchange: team/oej/no-premature-183/
------------------------------------------------------------------------------
Binary property 'branch-1.2-blocked' - no diff available.
Propchange: team/oej/no-premature-183/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.
Propchange: team/oej/no-premature-183/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Apr 27 13:02:12 2009
@@ -1,1 +1,1 @@
-/branches/1.4:1-177657
+/branches/1.4:1-190629
Modified: team/oej/no-premature-183/Makefile.rules
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/Makefile.rules?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/Makefile.rules (original)
+++ team/oej/no-premature-183/Makefile.rules Mon Apr 27 13:02:12 2009
@@ -51,8 +51,13 @@
# per-target settings will be applied
CC_CFLAGS=$(PTHREAD_CFLAGS) $(ASTCFLAGS)
CXX_CFLAGS=$(PTHREAD_CFLAGS) $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(AST_DECLARATION_AFTER_STATEMENT),$(ASTCFLAGS))
-CC_LDFLAGS_SO=$(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK)
-CXX_LDFLAGS_SO=$(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK)
+
+ifeq ($(GNU_LD),1)
+SO_SUPPRESS_SYMBOLS=-Wl,--version-script,$(if $(wildcard $(subst .so,.exports,$@)),$(subst .so,.exports,$@),$(ASTTOPDIR)/default.exports)
+endif
+
+CC_LDFLAGS_SO=$(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) $(SO_SUPPRESS_SYMBOLS)
+CXX_LDFLAGS_SO=$(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) $(SO_SUPPRESS_SYMBOLS)
CC_LIBS=$(PTHREAD_LIBS) $(LIBS)
CXX_LIBS=$(PTHREAD_LIBS) $(LIBS)
Modified: team/oej/no-premature-183/agi/Makefile
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/agi/Makefile?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/agi/Makefile (original)
+++ team/oej/no-premature-183/agi/Makefile Mon Apr 27 13:02:12 2009
@@ -20,6 +20,8 @@
endif
include $(ASTTOPDIR)/Makefile.rules
+
+ASTCFLAGS+=-DSTANDALONE
all: $(AGIS)
Modified: team/oej/no-premature-183/apps/app_dahdiras.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_dahdiras.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_dahdiras.c (original)
+++ team/oej/no-premature-183/apps/app_dahdiras.c Mon Apr 27 13:02:12 2009
@@ -49,6 +49,9 @@
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
+
+#include "asterisk/dahdi_compat.h"
+
#ifdef HAVE_CAP
#include <sys/capability.h>
#endif /* HAVE_CAP */
@@ -60,8 +63,6 @@
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
-
-#include "asterisk/dahdi_compat.h"
static char *dahdi_app = "DAHDIRAS";
static char *zap_app = "ZapRAS";
Modified: team/oej/no-premature-183/apps/app_dial.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_dial.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_dial.c (original)
+++ team/oej/no-premature-183/apps/app_dial.c Mon Apr 27 13:02:12 2009
@@ -356,6 +356,10 @@
ast_cdr_failed(chan->cdr); \
numnochan++; \
break; \
+ case AST_CAUSE_NO_ANSWER: \
+ if (chan->cdr) \
+ ast_cdr_noanswer(chan->cdr); \
+ break; \
case AST_CAUSE_NORMAL_CLEARING: \
break; \
default: \
@@ -383,6 +387,7 @@
return 0;
}
+static int detect_disconnect(struct ast_channel *chan, char code, char *featurecode, int len);
static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
{
@@ -417,7 +422,9 @@
struct ast_channel *peer = NULL;
/* single is set if only one destination is enabled */
int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
-
+
+ char featurecode[FEATURE_MAX_LEN + 1] = { 0, };
+
if (single) {
/* Turn off hold music, etc */
ast_deactivate_generator(in);
@@ -742,10 +749,10 @@
}
}
- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
- (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
+ if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
+ detect_disconnect(in, f->subclass, featurecode, sizeof(featurecode))) {
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
+ ast_verbose(VERBOSE_PREFIX_3 "User requested call disconnect.\n");
*to=0;
ast_cdr_noanswer(in->cdr);
strcpy(status, "CANCEL");
@@ -784,6 +791,34 @@
}
return peer;
+}
+
+static int detect_disconnect(struct ast_channel *chan, char code, char *featurecode, int len)
+{
+ struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
+ struct ast_call_feature feature = { 0, };
+ char *tmp;
+ int res;
+
+ if ((strlen(featurecode)) < (len - 2)) {
+ tmp = &featurecode[strlen(featurecode)];
+ tmp[0] = code;
+ tmp[1] = '\0';
+ } else {
+ featurecode[0] = 0;
+ return -1; /* no room in featurecode buffer */
+ }
+
+ res = ast_feature_detect(chan, &features, featurecode, &feature);
+
+ if (res != FEATURE_RETURN_STOREDIGITS) {
+ featurecode[0] = '\0';
+ }
+ if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
+ return 1;
+ }
+
+ return 0;
}
static void replace_macro_delimiter(char *s)
@@ -1249,6 +1284,7 @@
/* Inherit specially named variables from parent channel */
ast_channel_inherit_variables(chan, tmp->chan);
+ ast_channel_datastore_inherit(chan, tmp->chan);
tmp->chan->appl = "AppDial";
tmp->chan->data = "(Outgoing Line)";
@@ -1840,7 +1876,7 @@
}
}
- if ((dialdata = strchr(dialdata, '|'))) {
+ if (dialdata && (dialdata = strchr(dialdata, '|'))) {
*dialdata++ = '\0';
} else {
ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
Modified: team/oej/no-premature-183/apps/app_flash.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_flash.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_flash.c (original)
+++ team/oej/no-premature-183/apps/app_flash.c Mon Apr 27 13:02:12 2009
@@ -126,7 +126,7 @@
static int load_module(void)
{
- if (dahdi_chan_mode == CHAN_ZAP_MODE) {
+ if (*dahdi_chan_mode == CHAN_ZAP_MODE) {
return ast_register_application(app, flash_exec, zap_synopsis, zap_descrip);
} else {
return ast_register_application(app, flash_exec, dahdi_synopsis, dahdi_descrip);
Modified: team/oej/no-premature-183/apps/app_followme.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_followme.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_followme.c (original)
+++ team/oej/no-premature-183/apps/app_followme.c Mon Apr 27 13:02:12 2009
@@ -942,7 +942,7 @@
static int app_exec(struct ast_channel *chan, void *data)
{
- struct fm_args targs;
+ struct fm_args targs = { 0, };
struct ast_bridge_config config;
struct call_followme *f;
struct number *nm, *newnm;
Modified: team/oej/no-premature-183/apps/app_macro.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_macro.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_macro.c (original)
+++ team/oej/no-premature-183/apps/app_macro.c Mon Apr 27 13:02:12 2009
@@ -61,17 +61,23 @@
"will be returned at the location of the Goto.\n"
"If ${MACRO_OFFSET} is set at termination, Macro will attempt to continue\n"
"at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n"
-"Extensions: While a macro is being executed, it becomes the current context.\n"
-" This means that if a hangup occurs, for instance, that the macro\n"
-" will be searched for an 'h' extension, NOT the context from which\n"
-" the macro was called. So, make sure to define all appropriate\n"
-" extensions in your macro! (you can use 'catch' in AEL) \n"
"WARNING: Because of the way Macro is implemented (it executes the priorities\n"
" contained within it via sub-engine), and a fixed per-thread\n"
" memory stack allowance, macros are limited to 7 levels\n"
" of nesting (macro calling macro calling macro, etc.); It\n"
-" may be possible that stack-intensive applications in deeply nested macros\n"
-" could cause asterisk to crash earlier than this limit.\n";
+" may be possible that stack-intensive applications in deeply nested\n"
+" macros could cause asterisk to crash earlier than this limit.\n"
+"NOTE: a bug existed in earlier versions of Asterisk that caused Macro not\n"
+"to reset its context and extension correctly upon exit. This meant that\n"
+"the 'h' extension within a Macro sometimes would execute, when the dialplan\n"
+"exited while that Macro was running. However, since this bug has been in\n"
+"Asterisk for so long, users started to depend upon this behavior. Therefore,\n"
+"when a channel hangs up when in the midst of executing a Macro, the macro\n"
+"context will first be checked for an 'h' extension, followed by the main\n"
+"context from which the Macro was originally called. This behavior in 1.4\n"
+"exists only for compatibility with earlier versions. You are strongly\n"
+"encouraged to make use of the 'h' extension only in the context from which\n"
+"Macro was originally called.\n";
static char *if_descrip =
" MacroIf(<expr>?macroname_a[|arg1][:macroname_b[|arg1]])\n"
Modified: team/oej/no-premature-183/apps/app_meetme.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_meetme.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_meetme.c (original)
+++ team/oej/no-premature-183/apps/app_meetme.c Mon Apr 27 13:02:12 2009
@@ -1909,12 +1909,9 @@
ast_waitstream(chan, "");
}
- c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
-
-
/* Update the struct with the actual confflags */
user->userflags = confflags;
-
+
if (confflags & CONFFLAG_WAITMARKED) {
if(currentmarked == 0) {
if (lastmarked != 0) {
@@ -2035,6 +2032,8 @@
/* Perform an extra hangup check just in case */
if (ast_check_hangup(chan))
break;
+
+ c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
if (c) {
char dtmfstr[2] = "";
@@ -4730,7 +4729,7 @@
return -1;
}
if (ast_add_extension2(context, 0 /* don't replace */, "s", 1,
- NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free, sla_registrar)) {
+ NULL, NULL, slatrunk_app, ast_strdup(trunk->name), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", trunk->name);
destroy_trunk(trunk);
@@ -4869,7 +4868,7 @@
/* The extension for when the handset goes off-hook.
* exten => station1,1,SLAStation(station1) */
if (ast_add_extension2(context, 0 /* don't replace */, station->name, 1,
- NULL, NULL, slastation_app, ast_strdup(station->name), ast_free, sla_registrar)) {
+ NULL, NULL, slastation_app, ast_strdup(station->name), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", station->name);
destroy_station(station);
@@ -4884,7 +4883,7 @@
/* Extension for this line button
* exten => station1_line1,1,SLAStation(station1_line1) */
if (ast_add_extension2(context, 0 /* don't replace */, exten, 1,
- NULL, NULL, slastation_app, ast_strdup(exten), ast_free, sla_registrar)) {
+ NULL, NULL, slastation_app, ast_strdup(exten), ast_free_ptr, sla_registrar)) {
ast_log(LOG_ERROR, "Failed to automatically create extension "
"for trunk '%s'!\n", station->name);
destroy_station(station);
Modified: team/oej/no-premature-183/apps/app_mp3.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_mp3.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_mp3.c (original)
+++ team/oej/no-premature-183/apps/app_mp3.c Mon Apr 27 13:02:12 2009
@@ -131,7 +131,7 @@
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
- res = poll(fds, 1, timeout);
+ res = ast_poll(fds, 1, timeout);
if (res < 1) {
ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res);
return -1;
Modified: team/oej/no-premature-183/apps/app_nbscat.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_nbscat.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_nbscat.c (original)
+++ team/oej/no-premature-183/apps/app_nbscat.c Mon Apr 27 13:02:12 2009
@@ -123,7 +123,7 @@
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
- res = poll(fds, 1, 2000);
+ res = ast_poll(fds, 1, 2000);
if (res < 1) {
ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
return -1;
Modified: team/oej/no-premature-183/apps/app_queue.c
URL: http://svn.digium.com/svn-view/asterisk/team/oej/no-premature-183/apps/app_queue.c?view=diff&rev=190660&r1=190659&r2=190660
==============================================================================
--- team/oej/no-premature-183/apps/app_queue.c (original)
+++ team/oej/no-premature-183/apps/app_queue.c Mon Apr 27 13:02:12 2009
@@ -192,7 +192,7 @@
static char *app_aqm = "AddQueueMember" ;
static char *app_aqm_synopsis = "Dynamically adds queue members" ;
static char *app_aqm_descrip =
-" AddQueueMember(queuename[|interface[|penalty[|options[|membername]]]]):\n"
+" AddQueueMember(queuename[|interface[|penalty[|options[|membername[|state_interface]]]]]):\n"
"Dynamically adds interface to an existing queue.\n"
"If the interface is already in the queue and there exists an n+101 priority\n"
"then it will then jump to this priority. Otherwise it will return an error\n"
@@ -202,6 +202,9 @@
" AQMSTATUS The status of the attempt to add a queue member as a \n"
" text string, one of\n"
" ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
+"If a device is provided in the state_interface parameter, then this will\n"
+"be the device which will be used to determine the device state of the\n"
+"added queue member.\n"
"Example: AddQueueMember(techsupport|SIP/3000)\n"
"";
@@ -354,6 +357,7 @@
struct member {
char interface[80]; /*!< Technology/Location */
+ char state_interface[80]; /*!< Technology/Location from which to read device state changes */
char membername[80]; /*!< Member name to use in queue logs */
int penalty; /*!< Are we a last resort? */
int calls; /*!< Number of calls serviced by this member */
@@ -598,7 +602,7 @@
while ((cur = ao2_iterator_next(&mem_iter))) {
char *tmp_interface;
char *slash_pos;
- tmp_interface = ast_strdupa(cur->interface);
+ tmp_interface = ast_strdupa(cur->state_interface);
if ((slash_pos = strchr(tmp_interface, '/')))
if ((slash_pos = strchr(slash_pos + 1, '/')))
*slash_pos = '\0';
@@ -751,7 +755,7 @@
return 0;
}
/*! \brief allocate space for new queue member and set fields based on parameters passed */
-static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
+static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface)
{
struct member *cur;
@@ -759,13 +763,18 @@
cur->penalty = penalty;
cur->paused = paused;
ast_copy_string(cur->interface, interface, sizeof(cur->interface));
+ if (!ast_strlen_zero(state_interface)) {
+ ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
+ } else {
+ ast_copy_string(cur->state_interface, interface, sizeof(cur->state_interface));
+ }
if (!ast_strlen_zero(membername))
ast_copy_string(cur->membername, membername, sizeof(cur->membername));
else
ast_copy_string(cur->membername, interface, sizeof(cur->membername));
if (!strchr(cur->interface, '/'))
ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
- cur->status = ast_device_state(interface);
+ cur->status = ast_device_state(cur->state_interface);
}
return cur;
@@ -899,17 +908,21 @@
static int interface_exists_global(const char *interface)
{
struct call_queue *q;
- struct member *mem, tmpmem;
+ struct member *mem;
+ struct ao2_iterator mem_iter;
int ret = 0;
-
- ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
AST_LIST_LOCK(&queues);
AST_LIST_TRAVERSE(&queues, q, list) {
ast_mutex_lock(&q->lock);
- if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((mem = ao2_iterator_next(&mem_iter))) {
+ if (!strcasecmp(mem->state_interface, interface)) {
+ ao2_ref(mem, -1);
+ ret = 1;
+ break;
+ }
ao2_ref(mem, -1);
- ret = 1;
}
ast_mutex_unlock(&q->lock);
if (ret)
@@ -1108,7 +1121,7 @@
}
}
-static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
+static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str, const char *state_interface)
{
struct member *m, tmpmem;
int penalty = 0;
@@ -1132,10 +1145,10 @@
/* Create a new one if not found, else update penalty */
if (!m) {
- if ((m = create_queue_member(interface, membername, penalty, paused))) {
+ if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
m->dead = 0;
m->realtime = 1;
- add_to_interfaces(interface);
+ add_to_interfaces(m->state_interface);
ao2_link(q->members, m);
ao2_ref(m, -1);
m = NULL;
@@ -1145,6 +1158,11 @@
m->dead = 0; /* Do not delete this one. */
if (paused_str)
m->paused = paused;
+ if (strcasecmp(state_interface, m->state_interface)) {
+ remove_from_interfaces(m->state_interface);
+ ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
+ add_to_interfaces(m->state_interface);
+ }
m->penalty = penalty;
ao2_ref(m, -1);
}
@@ -1159,7 +1177,7 @@
while ((cur = ao2_iterator_next(&mem_iter))) {
if (all || !cur->dynamic) {
ao2_unlink(q->members, cur);
- remove_from_interfaces(cur->interface);
+ remove_from_interfaces(cur->state_interface);
q->membercount--;
}
ao2_ref(cur, -1);
@@ -1278,7 +1296,8 @@
rt_handle_member_record(q, interface,
ast_variable_retrieve(member_config, interface, "membername"),
ast_variable_retrieve(member_config, interface, "penalty"),
- ast_variable_retrieve(member_config, interface, "paused"));
+ ast_variable_retrieve(member_config, interface, "paused"),
+ S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface));
}
/* Delete all realtime members that have been deleted in DB. */
@@ -1287,7 +1306,7 @@
if (m->dead) {
ao2_unlink(q->members, m);
ast_mutex_unlock(&q->lock);
- remove_from_interfaces(m->interface);
+ remove_from_interfaces(m->state_interface);
ast_mutex_lock(&q->lock);
q->membercount--;
}
@@ -1348,7 +1367,8 @@
rt_handle_member_record(q, interface,
S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
ast_variable_retrieve(member_config, interface, "penalty"),
- ast_variable_retrieve(member_config, interface, "paused"));
+ ast_variable_retrieve(member_config, interface, "paused"),
+ S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface));
}
/* Delete all realtime members that have been deleted in DB. */
@@ -1357,7 +1377,7 @@
if (m->dead) {
ao2_unlink(q->members, m);
ast_mutex_unlock(&q->lock);
- remove_from_interfaces(m->interface);
+ remove_from_interfaces(m->state_interface);
ast_mutex_lock(&q->lock);
q->membercount--;
}
@@ -1486,6 +1506,10 @@
{
int res;
+ if (ast_strlen_zero(filename)) {
+ return 0;
+ }
+
ast_stopstream(chan);
res = ast_streamfile(chan, filename, chan->language);
@@ -1713,6 +1737,53 @@
}
}
+/*!
+ * \brief Get the number of members available to accept a call.
+ *
+ * \note The queue passed in should be locked prior to this function call
+ *
+ * \param[in] q The queue for which we are couting the number of available members
+ * \return Return the number of available members in queue q
+ */
+static int num_available_members(struct call_queue *q)
+{
+ struct member *mem;
+ int avl = 0;
+ struct ao2_iterator mem_iter;
+
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((mem = ao2_iterator_next(&mem_iter))) {
+ switch (mem->status) {
+ case AST_DEVICE_INUSE:
+ if (!q->ringinuse)
+ break;
+ /* else fall through */
+ case AST_DEVICE_NOT_INUSE:
+ case AST_DEVICE_UNKNOWN:
+ if (!mem->paused) {
+ avl++;
+ }
+ break;
+ }
+ ao2_ref(mem, -1);
+
+ /* If autofill is not enabled or if the queue's strategy is ringall, then
+ * we really don't care about the number of available members so much as we
+ * do that there is at least one available.
+ *
+ * In fact, we purposely will return from this function stating that only
+ * one member is available if either of those conditions hold. That way,
+ * functions which determine what action to take based on the number of available
+ * members will operate properly. The reasoning is that even if multiple
+ * members are available, only the head caller can actually be serviced.
+ */
+ if ((!q->autofill || q->strategy == QUEUE_STRATEGY_RINGALL) && avl) {
+ break;
+ }
+ }
+
+ return avl;
+}
/* traverse all defined queues which have calls waiting and contain this member
return 0 if no other queue has precedence (higher weight) or 1 if found */
@@ -1731,7 +1802,7 @@
if (q->count && q->members) {
if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
- if (q->weight > rq->weight) {
+ if (q->weight > rq->weight && q->count >= num_available_members(q)) {
ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
found = 1;
}
@@ -1851,7 +1922,7 @@
ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0;
- update_status(tmp->member->interface, ast_device_state(tmp->member->interface));
+ update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface));
ast_mutex_lock(&qe->parent->lock);
qe->parent->rrpos++;
@@ -1903,7 +1974,7 @@
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
do_hang(tmp);
(*busies)++;
- update_status(tmp->member->interface, ast_device_state(tmp->member->interface));
+ update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface));
return 0;
} else if (qe->parent->eventwhencalled) {
char vars[2048];
@@ -1927,7 +1998,7 @@
ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
}
- update_status(tmp->member->interface, ast_device_state(tmp->member->interface));
+ update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface));
return 1;
}
@@ -2333,86 +2404,51 @@
return peer;
}
+
/*! \brief Check if we should start attempting to call queue members
*
- * The behavior of this function is dependent first on whether autofill is enabled
- * and second on whether the ring strategy is ringall. If autofill is not enabled,
- * then return true if we're the head of the queue. If autofill is enabled, then
- * we count the available members and see if the number of available members is enough
- * that given our position in the queue, we would theoretically be able to connect to
- * one of those available members
+ * A simple process, really. Count the number of members who are available
+ * to take our call and then see if we are in a position in the queue at
+ * which a member could accept our call.
+ *
+ * \param[in] qe The caller who wants to know if it is his turn
+ * \retval 0 It is not our turn
+ * \retval 1 It is our turn
*/
static int is_our_turn(struct queue_ent *qe)
{
struct queue_ent *ch;
- struct member *cur;
- int avl = 0;
+ int res;
+ int avl;
int idx = 0;
- int res;
-
- if (!qe->parent->autofill) {
- /* Atomically read the parent head -- does not need a lock */
- ch = qe->parent->head;
- /* If we are now at the top of the head, break out */
- if (ch == qe) {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
- res = 1;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
- res = 0;
- }
-
+ /* This needs a lock. How many members are available to be served? */
+ ast_mutex_lock(&qe->parent->lock);
+
+ avl = num_available_members(qe->parent);
+
+ ch = qe->parent->head;
+
+ if (option_debug) {
+ ast_log(LOG_DEBUG, "There %s %d available %s.\n", avl != 1 ? "are" : "is", avl, avl != 1 ? "members" : "member");
+ }
+
+ while ((idx < avl) && (ch) && (ch != qe)) {
+ if (!ch->pending)
+ idx++;
+ ch = ch->next;
+ }
+
+ ast_mutex_unlock(&qe->parent->lock);
+
+ /* If the queue entry is within avl [the number of available members] calls from the top ... */
+ if (ch && idx < avl) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
+ res = 1;
} else {
- /* This needs a lock. How many members are available to be served? */
- ast_mutex_lock(&qe->parent->lock);
-
- ch = qe->parent->head;
-
- if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
- avl = 1;
- } else {
- struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
- while ((cur = ao2_iterator_next(&mem_iter))) {
- switch (cur->status) {
- case AST_DEVICE_INUSE:
- if (!qe->parent->ringinuse)
- break;
- /* else fall through */
- case AST_DEVICE_NOT_INUSE:
- case AST_DEVICE_UNKNOWN:
- if (!cur->paused)
- avl++;
- break;
- }
- ao2_ref(cur, -1);
- }
- }
-
if (option_debug)
- ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
-
- while ((idx < avl) && (ch) && (ch != qe)) {
- if (!ch->pending)
- idx++;
- ch = ch->next;
- }
-
- /* If the queue entry is within avl [the number of available members] calls from the top ... */
- if (ch && idx < avl) {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's our turn (%s).\n", qe->chan->name);
- res = 1;
- } else {
- if (option_debug)
- ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
- res = 0;
- }
-
- ast_mutex_unlock(&qe->parent->lock);
+ ast_log(LOG_DEBUG, "It's not our turn (%s).\n", qe->chan->name);
+ res = 0;
}
return res;
@@ -3254,7 +3290,7 @@
/* Dump all members in a specific queue to the database
*
- * <pm_family>/<queuename> = <interface>;<penalty>;<paused>[|...]
+ * <pm_family>/<queuename> = <interface>;<penalty>;<paused>;<state_interface>[|...]
*
*/
static void dump_queue_members(struct call_queue *pm_queue)
@@ -3277,8 +3313,8 @@
continue;
}
- res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s",
- value_len ? "|" : "", cur_member->interface, cur_member->penalty, cur_member->paused, cur_member->membername);
+ res = snprintf(value + value_len, sizeof(value) - value_len, "%s%s;%d;%d;%s;%s",
+ value_len ? "|" : "", cur_member->interface, cur_member->penalty, cur_member->paused, cur_member->membername, cur_member->state_interface);
ao2_ref(cur_member, -1);
@@ -3328,6 +3364,7 @@
"MemberName: %s\r\n",
q->name, mem->interface, mem->membername);
ao2_unlink(q->members, mem);
+ remove_from_interfaces(mem->state_interface);
ao2_ref(mem, -1);
if (queue_persistent_members)
@@ -3341,16 +3378,13 @@
break;
}
- if (res == RES_OKAY)
- remove_from_interfaces(interface);
-
AST_LIST_UNLOCK(&queues);
return res;
}
-static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump)
+static int add_to_queue(const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump, const char *state_interface)
{
struct call_queue *q;
struct member *new_member, *old_member;
@@ -3365,8 +3399,8 @@
ast_mutex_lock(&q->lock);
if ((old_member = interface_exists(q, interface)) == NULL) {
- add_to_interfaces(interface);
- if ((new_member = create_queue_member(interface, membername, penalty, paused))) {
+ if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) {
+ add_to_interfaces(new_member->state_interface);
new_member->dynamic = 1;
ao2_link(q->members, new_member);
q->membercount++;
@@ -3458,6 +3492,7 @@
char *member;
char *interface;
char *membername = NULL;
+ char *state_interface;
char *penalty_tok;
int penalty = 0;
char *paused_tok;
@@ -3506,6 +3541,7 @@
penalty_tok = strsep(&member, ";");
paused_tok = strsep(&member, ";");
membername = strsep(&member, ";");
+ state_interface = strsep(&member,";");
if (!penalty_tok) {
ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
@@ -3532,7 +3568,7 @@
if (option_debug)
ast_log(LOG_DEBUG, "Reload Members: Queue: %s Member: %s Name: %s Penalty: %d Paused: %d\n", queue_name, interface, membername, penalty, paused);
- if (add_to_queue(queue_name, interface, membername, penalty, paused, 0) == RES_OUTOFMEMORY) {
+ if (add_to_queue(queue_name, interface, membername, penalty, paused, 0, state_interface) == RES_OUTOFMEMORY) {
ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
break;
}
@@ -3731,11 +3767,12 @@
AST_APP_ARG(penalty);
AST_APP_ARG(options);
AST_APP_ARG(membername);
+ AST_APP_ARG(state_interface);
);
int penalty = 0;
if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|[interface]|[penalty][|options][|membername]])\n");
+ ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|interface[|penalty[|options[|membername[|state_interface]]]]])\n");
return -1;
}
@@ -3764,7 +3801,7 @@
priority_jump = 1;
}
- switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members)) {
+ switch (add_to_queue(args.queuename, args.interface, args.membername, penalty, 0, queue_persistent_members, args.state_interface)) {
case RES_OKAY:
ast_queue_log(args.queuename, chan->uniqueid, args.interface, "ADDMEMBER", "%s", "");
ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", args.interface, args.queuename);
@@ -4289,13 +4326,14 @@
int new;
const char *general_val = NULL;
char parse[80];
- char *interface;
+ char *interface, *state_interface;
char *membername = NULL;
[... 10441 lines stripped ...]
More information about the asterisk-commits
mailing list