[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