[svn-commits] jpeeler: branch jpeeler/chan_dahdi14 r122298 - in /team/jpeeler/chan_dahdi14:...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jun 12 13:31:19 CDT 2008


Author: jpeeler
Date: Thu Jun 12 13:31:18 2008
New Revision: 122298

URL: http://svn.digium.com/view/asterisk?view=rev&rev=122298
Log:
sync with 1.4 branch

Modified:
    team/jpeeler/chan_dahdi14/   (props changed)
    team/jpeeler/chan_dahdi14/CHANGES
    team/jpeeler/chan_dahdi14/apps/app_dial.c
    team/jpeeler/chan_dahdi14/apps/app_forkcdr.c
    team/jpeeler/chan_dahdi14/apps/app_meetme.c
    team/jpeeler/chan_dahdi14/apps/app_parkandannounce.c
    team/jpeeler/chan_dahdi14/channels/chan_agent.c
    team/jpeeler/chan_dahdi14/channels/chan_iax2.c
    team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c
    team/jpeeler/chan_dahdi14/doc/backtrace.txt
    team/jpeeler/chan_dahdi14/funcs/func_cdr.c
    team/jpeeler/chan_dahdi14/include/asterisk/app.h
    team/jpeeler/chan_dahdi14/include/asterisk/cdr.h
    team/jpeeler/chan_dahdi14/include/asterisk/global_datastores.h
    team/jpeeler/chan_dahdi14/main/abstract_jb.c
    team/jpeeler/chan_dahdi14/main/app.c
    team/jpeeler/chan_dahdi14/main/cdr.c
    team/jpeeler/chan_dahdi14/main/channel.c
    team/jpeeler/chan_dahdi14/main/global_datastores.c
    team/jpeeler/chan_dahdi14/main/sched.c
    team/jpeeler/chan_dahdi14/res/res_features.c

Propchange: team/jpeeler/chan_dahdi14/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Jun 12 13:31:18 2008
@@ -1,1 +1,1 @@
-/branches/1.4:1-121697
+/branches/1.4:1-122287

Modified: team/jpeeler/chan_dahdi14/CHANGES
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/CHANGES?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/CHANGES (original)
+++ team/jpeeler/chan_dahdi14/CHANGES Thu Jun 12 13:31:18 2008
@@ -131,12 +131,22 @@
                 o New Option: K/k parking via dtmf tones
          5. Dictate() -- optional filename argument added.
          6. Directory() -- new option: e - In addition to the name, also read the extension number...
-         7. Meetme() -- new options:
+         7. ForkCDR() -- new options: 
+                o 'a' -- update answer time on new cdr
+                o 'A' -- Lock the orig CDR answer time against changes.
+                o 'D' -- Copy the disposition from the orig to the new CDR.
+                o 'd' -- clear the dstcannel field in the new CDR.
+                o 'e' -- set the end time of the original CDR.
+                o 'R' -- do NOT reset the new CDR.
+                o 's' -- Add/change var in orig CDR.
+                o 'T' -- Force ast_cdr_end, answer to obey LOCKED flag for the orig. CDR.
+                      -- ast_cdr_setvar will be forced also (used by the CDR() func in write mode)
+         8. Meetme() -- new options:
                 o 'I' -- announce user join/leave without review
                 o 'l' -- set listen only mode (Listen only, no talking)
                 o 'o' -- set talker optimization - treats talkers who aren't speaking as...
                 o '1' -- do not play message when first person enters
-         8. MeetmeAdmin() -- new options:
+         9. MeetmeAdmin() -- new options:
                 o 'r' -- Reset one user's volume settings
                 o 'R' -- Reset all users volume settings
                 o 's' -- Lower entire conference speaking volume
@@ -147,21 +157,21 @@
                 o 'U' -- Lower all users listen volume
                 o 'v' -- Lower entire conference listening volume
                 o 'V' -- Raise entire conference listening volume
-         9. OSPFinish() : now also can return ERROR result.
-        10. OSPLookup() : Sets more variables, also now returns ERROR result.
-        11. Page() -- New option: r - record the page into a file (see 'r' for app_meetme)
-        12. Pickup() -- multiple extensions, PICKUPMARK; read the description!
-        13. Queue()
+        10. OSPFinish() : now also can return ERROR result.
+        11. OSPLookup() : Sets more variables, also now returns ERROR result.
+        12. Page() -- New option: r - record the page into a file (see 'r' for app_meetme)
+        13. Pickup() -- multiple extensions, PICKUPMARK; read the description!
+        14. Queue()
                 o New Argument: AGI
                 o New option: i
-        14. Random() -- is now deprecated in 1.4
-        15. Read() -- replace 'skip' and 'noanswer' options with 's', 'n', add 'i' option.
-        16. Record() -- New option: 'x' : ignore all terminator keys (DTMF) and keep recording until hangup
-        17. UserEvent() -- slight change in behavior. Read the description.
-        18. VoiceMailMain() -- new a(#) option, goes to folder # directly.
-        19. WaitForSilence() -- new optional 3rd arg, time delay before returning.
+        15. Random() -- is now deprecated in 1.4
+        16. Read() -- replace 'skip' and 'noanswer' options with 's', 'n', add 'i' option.
+        17. Record() -- New option: 'x' : ignore all terminator keys (DTMF) and keep recording until hangup
+        18. UserEvent() -- slight change in behavior. Read the description.
+        19. VoiceMailMain() -- new a(#) option, goes to folder # directly.
+        20. WaitForSilence() -- new optional 3rd arg, time delay before returning.
     * Functions that have changes to their interfaces:
-         1. CDR -- new option: u
+         1. CDR -- new options: u and s
          2. LANGUAGE -- Deprecated. Use CHANNEL(language) instead.
          3. MUSICCLASS -- Deprecated. Use CHANNEL(musicclass) instead.
     * Configuration File Changes:

Modified: team/jpeeler/chan_dahdi14/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_dial.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_dial.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_dial.c Thu Jun 12 13:31:18 2008
@@ -789,6 +789,19 @@
 	return 0;
 }
 
+static void set_dial_features(struct ast_flags *opts, struct ast_dial_features *features)
+{
+	struct ast_flags perm_opts = {.flags = 0};
+
+	ast_copy_flags(&perm_opts, opts,
+		OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_HANGUP |
+		OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_HANGUP);
+
+	memset(features->options, 0, sizeof(features->options));
+
+	ast_app_options2str(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
+}
+
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
 {
 	int res = -1;
@@ -831,6 +844,9 @@
 	struct ast_flags opts = { 0, };
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
 	struct ast_datastore *datastore = NULL;
+	struct ast_datastore *ds_caller_features = NULL;
+	struct ast_datastore *ds_callee_features = NULL;
+	struct ast_dial_features *caller_features;
 	int fulldial = 0, num_dialed = 0;
 
 	if (ast_strlen_zero(data)) {
@@ -1086,6 +1102,28 @@
 	}
 	    
 	ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
+
+	/* Create datastore for channel dial features for caller */
+	if (!(ds_caller_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
+		ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
+		goto out;
+	}
+
+	if (!(caller_features = ast_malloc(sizeof(*caller_features)))) {
+		ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
+		goto out;
+	}
+
+	caller_features->is_caller = 1;
+	set_dial_features(&opts, caller_features);
+
+	ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
+	ds_caller_features->data = caller_features;
+
+	ast_channel_lock(chan);
+	ast_channel_datastore_add(chan, ds_caller_features);
+	ast_channel_unlock(chan);
+
 	/* loop through the list of dial destinations */
 	rest = args.peers;
 	while ((cur = strsep(&rest, "&")) ) {
@@ -1096,6 +1134,7 @@
 		char *tech = strsep(&number, "/");
 		/* find if we already dialed this interface */
 		struct ast_dialed_interface *di;
+		struct ast_dial_features *callee_features;
 		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
 		num_dialed++;
 		if (!number) {
@@ -1244,6 +1283,30 @@
 			ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
 		else
 			ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
+
+		/* Save callee features */
+		if (!(ds_callee_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
+			ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
+			ast_free(tmp);
+			goto out;
+		}
+
+		if (!(callee_features = ast_malloc(sizeof(*callee_features)))) {
+			ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
+			ast_free(tmp);
+			goto out;
+		}
+
+		callee_features->is_caller = 0;
+		set_dial_features(&opts, callee_features);
+
+		ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
+		ds_callee_features->data = callee_features;
+
+		ast_channel_lock(tmp->chan);
+		ast_channel_datastore_add(tmp->chan, ds_callee_features);
+		ast_channel_unlock(tmp->chan);
+
 
 		/* Place the call, but don't wait on the answer */
 		res = ast_call(tmp->chan, numsubst, 0);

Modified: team/jpeeler/chan_dahdi14/apps/app_forkcdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_forkcdr.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_forkcdr.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_forkcdr.c Thu Jun 12 13:31:18 2008
@@ -48,21 +48,82 @@
 "Forks the Call Data Record";
 static char *descrip = 
 "  ForkCDR([options]):  Causes the Call Data Record to fork an additional\n"
-"cdr record starting from the time of the fork call\n"
+"cdr record starting from the time of the fork call. This new cdr record will\n"
+"be linked to end of the list of cdr records attached to the channel. The original CDR is\n"
+"has a LOCKED flag set, which forces most cdr operations to skip it, except\n"
+"for the functions that set the answer and end times, which ignore the LOCKED\n"
+"flag. This allows all the cdr records in the channel to be 'ended' together\n"
+"when the channel is closed.\n"
+"The CDR() func (when setting CDR values) normally ignores the LOCKED flag also,\n"
+"but has options to vary its behavior. The 'T' option (described below), can\n"
+"override this behavior, but beware the risks.\n"
+"\n"
+"Detailed Behavior Description:\n"
+"First, this app finds the last cdr record in the list, and makes\n"
+"a copy of it. This new copy will be the newly forked cdr record.\n"
+"Next, this new record is linked to the end of the cdr record list.\n"
+"Next, The new cdr record is RESET (unless you use an option to prevent this)\n"
+"This means that:\n"
+"   1. All flags are unset on the cdr record\n"
+"   2. the start, end, and answer times are all set to zero.\n"
+"   3. the billsec and duration fields are set to zero.\n"
+"   4. the start time is set to the current time.\n"
+"   5. the disposition is set to NULL.\n"
+"Next, unless you specified the 'v' option, all variables will be\n"
+"removed from the original cdr record. Thus, the 'v' option allows\n"
+"any CDR variables to be replicated to all new forked cdr records.\n"
+"Without the 'v' option, the variables on the original are effectively\n"
+"moved to the new forked cdr record.\n"
+"Next, if the 's' option is set, the provided variable and value\n"
+"are set on the original cdr record.\n"
+"Next, if the 'a' option is given, and the original cdr record has an\n"
+"answer time set, then the new forked cdr record will have its answer\n"
+"time set to its start time. If the old answer time were carried forward,\n"
+"the answer time would be earlier than the start time, giving strange\n"
+"duration and billsec times.\n"
+"Next, if the 'd' option was specified, the disposition is copied from\n"
+"the original cdr record to the new forked cdr.\n"
+"Next, if the 'D' option was specified, the destination channel field\n"
+"in the new forked CDR is erased.\n"
+"Next, if the 'e' option was specified, the 'end' time for the original\n"
+"cdr record is set to the current time. Future hang-up or ending events\n"
+"will not override this time stamp.\n"
+"Next, If the 'A' option is specified, the original cdr record will have\n"
+"it ANS_LOCKED flag set, which prevent future answer events\n"
+"from updating the original cdr record's disposition. Normally, an\n"
+"'ANSWERED' event would mark all cdr records in the chain as 'ANSWERED'.\n"
+"Next, if the 'T' option is specified, the original cdr record will have\n"
+"its 'DONT_TOUCH' flag set, which will force the cdr_answer, cdr_end, and\n"
+"cdr_setvar functions to leave that cdr record alone.\n"
+"And, last but not least, the original cdr record has its LOCKED flag\n"
+"set. Almost all internal CDR functions (except for the funcs that set\n"
+"the end, and answer times, and set a variable) will honor this flag\n"
+"and leave a LOCKED cdr record alone.\n"
+"This means that the newly created forked cdr record will affected\n"
+"by events transpiring within Asterisk, with the previously noted\n"
+"exceptions.\n"
 "  Options:\n"
-"    a  - update the answer time on the NEW CDR just after it's been inited..\n"
+"    a - update the answer time on the NEW CDR just after it's been inited..\n"
 "         The new CDR may have been answered already, the reset that forkcdr.\n"
-"         does will erase the answer time. This will bring it back, but.\n"
+"         does will erase the answer time. This will bring it back, but\n"
 "         the answer time will be a copy of the fork/start time. It will.\n"
 "         only do this if the initial cdr was indeed already answered..\n"
-"    D -  Copy the disposition forward from the old cdr, after the .\n"
+"    A - Lock the original CDR against the answer time being updated.\n"
+"         This will allow the disposition on the original CDR to remain the same.\n"
+"    d - Copy the disposition forward from the old cdr, after the .\n"
 "         init..\n"
-"    d -  Clear the dstchannel on the new CDR after reset..\n"
-"    e -  end the original CDR. Do this after all the necc. data.\n"
+"    D - Clear the dstchannel on the new CDR after reset..\n"
+"    e - end the original CDR. Do this after all the necc. data.\n"
 "         is copied from the original CDR to the new forked CDR..\n"
 "    R -  do NOT reset the new cdr..\n"
 "    s(name=val) - Set the CDR var 'name' in the original CDR, with value.\n"
 "                  'val'.\n"
+"    T -  Mark the original CDR with a DONT_TOUCH flag. setvar, answer, and end\n"
+"          cdr funcs will obey this flag; normally they don't honor the LOCKED\n"
+"          flag set on the original CDR record.\n"
+"          Beware-- using this flag may cause CDR's not to have their end times\n"
+"          updated! It is suggested that if you specify this flag, you might\n"
+"          wish to use the 'e' flag as well!\n"
 "    v  - When the new CDR is forked, it gets a copy of the vars attached\n"
 "         to the current CDR. The vars attached to the original CDR are removed\n"
 "         unless this option is specified.\n";
@@ -76,6 +137,8 @@
 	OPT_NORESET =           (1 << 4),
 	OPT_KEEPVARS =          (1 << 5),
 	OPT_VARSET =            (1 << 6),
+	OPT_ANSLOCK =           (1 << 7),
+	OPT_DONTOUCH =          (1 << 8),
 };
 
 enum {
@@ -86,11 +149,13 @@
 
 AST_APP_OPTIONS(forkcdr_exec_options, {
 	AST_APP_OPTION('a', OPT_SETANS),
+	AST_APP_OPTION('A', OPT_ANSLOCK),
 	AST_APP_OPTION('d', OPT_SETDISP),
 	AST_APP_OPTION('D', OPT_RESETDEST),
 	AST_APP_OPTION('e', OPT_ENDCDR),
 	AST_APP_OPTION('R', OPT_NORESET),
 	AST_APP_OPTION_ARG('s', OPT_VARSET, OPT_ARG_VARSET),
+	AST_APP_OPTION('T', OPT_DONTOUCH),
 	AST_APP_OPTION('v', OPT_KEEPVARS),
 });
 
@@ -138,6 +203,12 @@
 	if (ast_test_flag(&optflags, OPT_ENDCDR))
 		ast_cdr_end(cdr);
 
+	if (ast_test_flag(&optflags, OPT_ANSLOCK))
+		ast_set_flag(cdr, AST_CDR_FLAG_ANSLOCKED);
+	
+	if (ast_test_flag(&optflags, OPT_DONTOUCH))
+		ast_set_flag(cdr, AST_CDR_FLAG_DONT_TOUCH);
+		
 	ast_set_flag(cdr, AST_CDR_FLAG_CHILD | AST_CDR_FLAG_LOCKED);
 }
 

Modified: team/jpeeler/chan_dahdi14/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_meetme.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_meetme.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_meetme.c Thu Jun 12 13:31:18 2008
@@ -1910,6 +1910,8 @@
 				break;
 
 			if (c) {
+				char dtmfstr[2] = "";
+
 				if (c->fds[0] != origfd || (user->zapchannel && (c->audiohooks || c->monitor))) {
 					if (using_pseudo) {
 						/* Kill old pseudo */
@@ -1927,6 +1929,11 @@
 					f = ast_read(c);
 				if (!f)
 					break;
+				if (f->frametype == AST_FRAME_DTMF) {
+					dtmfstr[0] = f->subclass;
+					dtmfstr[1] = '\0';
+				}
+
 				if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
 					if (user->talk.actual)
 						ast_frame_adjust_volume(f, user->talk.actual);
@@ -1977,21 +1984,6 @@
 						if (user->talking || !(confflags & CONFFLAG_OPTIMIZETALKER))
 							careful_write(fd, f->data, f->datalen, 0);
 					}
-				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
-					char tmp[2];
-
-					if (confflags & CONFFLAG_PASS_DTMF)
-						conf_queue_dtmf(conf, user, f);
-
-					tmp[0] = f->subclass;
-					tmp[1] = '\0';
-					if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
-						ast_log(LOG_DEBUG, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
-						ret = 0;
-						ast_frfree(f);
-						break;
-					} else if (option_debug > 1)
-						ast_log(LOG_DEBUG, "Exit by single digit did not work in meetme. Extension %s does not exist in context %s\n", tmp, exitcontext);
 				} else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#') && (confflags & CONFFLAG_POUNDEXIT)) {
 					if (confflags & CONFFLAG_PASS_DTMF)
 						conf_queue_dtmf(conf, user, f);
@@ -2155,6 +2147,18 @@
 					}
 
 					conf_flush(fd, chan);
+				/* Since this option could absorb dtmf for the previous, we have to check this one last */
+				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT) && ast_exists_extension(chan, exitcontext, dtmfstr, 1, "")) {
+					if (confflags & CONFFLAG_PASS_DTMF)
+						conf_queue_dtmf(conf, user, f);
+
+					if (!ast_goto_if_exists(chan, exitcontext, dtmfstr, 1)) {
+						ast_log(LOG_DEBUG, "Got DTMF %c, goto context %s\n", dtmfstr[0], exitcontext);
+						ret = 0;
+						ast_frfree(f);
+						break;
+					} else if (option_debug > 1)
+						ast_log(LOG_DEBUG, "Exit by single digit did not work in meetme. Extension '%s' does not exist in context '%s'\n", dtmfstr, exitcontext);
 				} else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
 					&& confflags & CONFFLAG_PASS_DTMF) {
 					conf_queue_dtmf(conf, user, f);

Modified: team/jpeeler/chan_dahdi14/apps/app_parkandannounce.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/apps/app_parkandannounce.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/apps/app_parkandannounce.c (original)
+++ team/jpeeler/chan_dahdi14/apps/app_parkandannounce.c Thu Jun 12 13:31:18 2008
@@ -76,14 +76,13 @@
 
 static int parkandannounce_exec(struct ast_channel *chan, void *data)
 {
-	int res=0;
 	char *return_context;
 	int lot, timeout = 0, dres;
 	char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
 	char *template, *tpl_working, *tpl_current;
 	char *tmp[100];
 	char buf[13];
-	int looptemp=0,i=0;
+	int looptemp = 0,i = 0, res = 0;
 	char *s;
 
 	struct ast_channel *dchan;
@@ -101,7 +100,7 @@
 
 	s = ast_strdupa(data);
 
-	template=strsep(&s,"|");
+	template = strsep(&s,"|");
 	if(! template) {
 		ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
 		ast_module_user_remove(u);
@@ -112,14 +111,14 @@
 		timeout = atoi(strsep(&s, "|"));
 		timeout *= 1000;
 	}
-	dial=strsep(&s, "|");
+	dial = strsep(&s, "|");
 	if(!dial) {
 		ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
 		ast_module_user_remove(u);
 		return -1;
 	} else {
-		dialtech=strsep(&dial, "/");
-		dialstr=dial;
+		dialtech = strsep(&dial, "/");
+		dialstr = dial;
 		ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
 	}
 
@@ -170,9 +169,10 @@
 	/* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
 	before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
 
-	ast_masq_park_call(chan, NULL, timeout, &lot);
-
-	res=-1; 
+	res = ast_masq_park_call(chan, NULL, timeout, &lot);
+	if (res == -1) {
+		goto finish;
+	}
 
 	ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
 
@@ -209,15 +209,15 @@
 	ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
 
 	tpl_working = template;
-	tpl_current=strsep(&tpl_working, ":");
+	tpl_current = strsep(&tpl_working, ":");
 
 	while(tpl_current && looptemp < ARRAY_LEN(tmp)) {
 		tmp[looptemp]=tpl_current;
 		looptemp++;
-		tpl_current=strsep(&tpl_working,":");
-	}
-
-	for(i=0; i<looptemp; i++) {
+		tpl_current = strsep(&tpl_working,":");
+	}
+
+	for(i = 0; i < looptemp; i++) {
 		ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
 		if(!strcmp(tmp[i], "PARKED")) {
 			ast_say_digits(dchan, lot, "", dchan->language);
@@ -234,9 +234,9 @@
 
 	ast_stopstream(dchan);  
 	ast_hangup(dchan);
-	
+
+finish:
 	ast_module_user_remove(u);
-	
 	return res;
 }
 

Modified: team/jpeeler/chan_dahdi14/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/chan_agent.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/chan_agent.c (original)
+++ team/jpeeler/chan_dahdi14/channels/chan_agent.c Thu Jun 12 13:31:18 2008
@@ -1061,7 +1061,7 @@
 	if (p->chan) {
 		if (ast_test_flag(p->chan, AST_FLAG_BLOCKING)) {
 			ast_log( LOG_ERROR, "A blocker exists after agent channel ownership acquired\n" );
-			ast_assert(0);
+			ast_assert(ast_test_flag(p->chan, AST_FLAG_BLOCKING) == 0);
 		}
 	}
 	return tmp;

Modified: team/jpeeler/chan_dahdi14/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/chan_iax2.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/chan_iax2.c (original)
+++ team/jpeeler/chan_dahdi14/channels/chan_iax2.c Thu Jun 12 13:31:18 2008
@@ -1010,10 +1010,19 @@
 
 static int send_ping(const void *data)
 {
+	int callno = (long) data;
+
+	ast_mutex_lock(&iaxsl[callno]);
+	if (iaxs[callno]) {
+		iaxs[callno]->pingid = -1;
+	}
+	ast_mutex_unlock(&iaxsl[callno]);
+
 #ifdef SCHED_MULTITHREADED
 	if (schedule_action(__send_ping, data))
 #endif		
 		__send_ping(data);
+
 	return 0;
 }
 
@@ -1050,10 +1059,19 @@
 
 static int send_lagrq(const void *data)
 {
+	int callno = (long) data;
+
+	ast_mutex_lock(&iaxsl[callno]);
+	if (iaxs[callno]) {
+		iaxs[callno]->lagid = -1;
+	}
+	ast_mutex_unlock(&iaxsl[callno]);
+
 #ifdef SCHED_MULTITHREADED
 	if (schedule_action(__send_lagrq, data))
 #endif		
 		__send_lagrq(data);
+	
 	return 0;
 }
 

Modified: team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c (original)
+++ team/jpeeler/chan_dahdi14/channels/misdn/isdn_lib.c Thu Jun 12 13:31:18 2008
@@ -3110,12 +3110,18 @@
 	struct timeval now;
 	gettimeofday(&now, NULL);
 	if (!bc->in_use) {
-		if (bc->last_used.tv_sec < now.tv_sec) {
-			cb_log(0,bc->port, "channel with stid:%x for one second still in use!\n", bc->b_stid);
+		if ( bc->last_used.tv_sec == now.tv_sec ) {
+			cb_log(2,bc->port, "channel with stid:%x for one second still in use! (n:%d lu:%d)\n", bc->b_stid, now.tv_sec, bc->last_used.tv_sec);
 			return 1;
 		}
-	}
-	return 0;
+		
+
+		cb_log(3,bc->port, "channel with stid:%x not in use!\n", bc->b_stid);
+		return 0;
+	}
+	
+	cb_log(2,bc->port, "channel with stid:%x in use!\n", bc->b_stid);
+	return 1;
 }
 
 
@@ -3163,9 +3169,15 @@
 			if (channel > 0) {
 				if (channel <= stack->b_num) {
 					for (i = 0; i < stack->b_num; i++) {
-						if ( test_inuse(&stack->bc[i]) && stack->bc[i].channel == channel) {
-							cb_log(0,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
-							return NULL;
+						if ( stack->bc[i].channel == channel) {
+							if (test_inuse(&stack->bc[i])) { 
+								cb_log(0,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
+								return NULL;
+
+							} else {
+								prepare_bc(&stack->bc[i], channel);
+								return &stack->bc[i];
+							}
 						}
 					}
 				} else {
@@ -3178,7 +3190,7 @@
 
 			if (dec) {
 				for (i = maxnum-1; i>=0; i--) {
-					if (test_inuse(&stack->bc[i])) {
+					if (!test_inuse(&stack->bc[i])) {
 						/* 3. channel on bri means CW*/
 						if (!stack->pri && i==stack->b_num)
 							stack->bc[i].cw=1;
@@ -3190,7 +3202,7 @@
 				}
 			} else {
 				for (i = 0; i <maxnum; i++) {
-					if (test_inuse(&stack->bc[i])) {
+					if (!test_inuse(&stack->bc[i])) {
 						/* 3. channel on bri means CW*/
 						if (!stack->pri && i==stack->b_num)
 							stack->bc[i].cw=1;

Modified: team/jpeeler/chan_dahdi14/doc/backtrace.txt
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/doc/backtrace.txt?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/doc/backtrace.txt (original)
+++ team/jpeeler/chan_dahdi14/doc/backtrace.txt Thu Jun 12 13:31:18 2008
@@ -75,6 +75,11 @@
 Loaded symbols for /usr/lib/asterisk/modules/app_externalivr.so
 #0  0x29b45d7e in ?? ()
 (gdb)
+
+In order to make extracting the gdb output easier, you may wish to
+turn on logging using "set logging on". This command will save all
+output to the default file of gdb.txt, which in the end can be 
+uploaded as an attachment to the bug tracker.
 
 Now at the gdb prompt, type: bt
 You would see output similar to:
@@ -178,8 +183,9 @@
 
 That output tells us crucial information about each thread.
 
-Now, just create an output.txt file and dump your "bt full"
-(and/or "bt") ALONG WITH "thread apply all bt" into it.
+Now, if you turned on logging upload your gdb.txt file. Otherwise,
+create an output.txt file and dump your "bt full" (and/or "bt")
+ALONG WITH "thread apply all bt" into it.
 
 Note: Please ATTACH your output, DO NOT paste it as a note.
 

Modified: team/jpeeler/chan_dahdi14/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/funcs/func_cdr.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/funcs/func_cdr.c (original)
+++ team/jpeeler/chan_dahdi14/funcs/func_cdr.c Thu Jun 12 13:31:18 2008
@@ -44,11 +44,13 @@
 	OPT_RECURSIVE = (1 << 0),
 	OPT_UNPARSED = (1 << 1),
 	OPT_LAST = (1 << 2),
+	OPT_SKIPLOCKED = (1 << 3),
 } cdr_option_flags;
 
 AST_APP_OPTIONS(cdr_func_options, {
 	AST_APP_OPTION('l', OPT_LAST),
 	AST_APP_OPTION('r', OPT_RECURSIVE),
+	AST_APP_OPTION('s', OPT_SKIPLOCKED),
 	AST_APP_OPTION('u', OPT_UNPARSED),
 });
 
@@ -78,6 +80,10 @@
 		while (cdr->next)
 			cdr = cdr->next;
 
+	if (ast_test_flag(&flags, OPT_SKIPLOCKED))
+		while (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED) && cdr->next)
+			cdr = cdr->next;
+
 	ast_cdr_getvar(cdr, args.variable, &ret, buf, len,
 		       ast_test_flag(&flags, OPT_RECURSIVE),
 			   ast_test_flag(&flags, OPT_UNPARSED));
@@ -88,6 +94,7 @@
 static int cdr_write(struct ast_channel *chan, char *cmd, char *parse,
 		     const char *value)
 {
+	struct ast_cdr *cdr = chan ? chan->cdr : NULL;
 	struct ast_flags flags = { 0 };
 	AST_DECLARE_APP_ARGS(args,
 			     AST_APP_ARG(variable);
@@ -97,19 +104,26 @@
 	if (ast_strlen_zero(parse) || !value || !chan)
 		return -1;
 
+	if (!cdr)
+		return -1;
+
 	AST_STANDARD_APP_ARGS(args, parse);
 
 	if (!ast_strlen_zero(args.options))
 		ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
 
-	if (!strcasecmp(args.variable, "accountcode"))
+	if (ast_test_flag(&flags, OPT_LAST))
+		while (cdr->next)
+			cdr = cdr->next;
+
+	if (!strcasecmp(args.variable, "accountcode"))  /* the 'l' flag doesn't apply to setting the accountcode, userfield, or amaflags */
 		ast_cdr_setaccount(chan, value);
 	else if (!strcasecmp(args.variable, "userfield"))
 		ast_cdr_setuserfield(chan, value);
 	else if (!strcasecmp(args.variable, "amaflags"))
 		ast_cdr_setamaflags(chan, value);
-	else if (chan->cdr)
-		ast_cdr_setvar(chan->cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
+	else
+		ast_cdr_setvar(cdr, args.variable, value, ast_test_flag(&flags, OPT_RECURSIVE));
 		/* No need to worry about the u flag, as all fields for which setting
 		 * 'u' would do anything are marked as readonly. */
 
@@ -126,6 +140,8 @@
 "Options:\n"
 "  'l' uses the most recent CDR on a channel with multiple records\n"
 "  'r' searches the entire stack of CDRs on the channel\n"
+"  's' skips any CDR's that are marked 'LOCKED' due to forkCDR() calls.\n"
+"      (on setting/writing CDR vars only)\n"
 "  'u' retrieves the raw, unprocessed value\n"
 "  For example, 'start', 'answer', and 'end' will be retrieved as epoch\n"
 "  values, when the 'u' option is passed, but formatted as YYYY-MM-DD HH:MM:SS\n"
@@ -143,11 +159,13 @@
 "  a name not on the above list, and create your own\n"
 "  variable, whose value can be changed with this function,\n"
 "  and this variable will be stored on the cdr.\n"
+"  For setting CDR values, the 'l' flag does not apply to\n"
+"  setting the accountcode, userfield, or amaflags.\n"
 "   raw values for disposition:\n"
 "       1 = NO ANSWER\n"
-"	2 = BUSY\n"
-"	3 = FAILED\n"
-"	4 = ANSWERED\n"
+"       2 = BUSY\n"
+"       3 = FAILED\n"
+"       4 = ANSWERED\n"
 "    raw values for amaflags:\n"
 "       1 = OMIT\n"
 "       2 = BILLING\n"

Modified: team/jpeeler/chan_dahdi14/include/asterisk/app.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/include/asterisk/app.h?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/include/asterisk/app.h (original)
+++ team/jpeeler/chan_dahdi14/include/asterisk/app.h Thu Jun 12 13:31:18 2008
@@ -411,8 +411,16 @@
  */
 int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
 
-/*! \brief Present a dialtone and collect a certain length extension. 
-    \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension. 
+/*! \brief Given a list of options array, return an option string based on passed flags
+	\param options The array of possible options declared with AST_APP_OPTIONS
+	\param flags The flags of the options that you wish to populate the buffer with
+	\param buf The buffer to fill with the string of options
+	\param len The maximum length of buf
+*/
+void ast_app_options2str(const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len);
+
+/*! \brief Present a dialtone and collect a certain length extension.
+    \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
 \note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
 int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
 

Modified: team/jpeeler/chan_dahdi14/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/include/asterisk/cdr.h?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/include/asterisk/cdr.h (original)
+++ team/jpeeler/chan_dahdi14/include/asterisk/cdr.h Thu Jun 12 13:31:18 2008
@@ -24,11 +24,13 @@
 #define _ASTERISK_CDR_H
 
 #include <sys/time.h>
-#define AST_CDR_FLAG_KEEP_VARS			(1 << 0)
+#define AST_CDR_FLAG_KEEP_VARS		(1 << 0)
 #define AST_CDR_FLAG_POSTED			(1 << 1)
 #define AST_CDR_FLAG_LOCKED			(1 << 2)
 #define AST_CDR_FLAG_CHILD			(1 << 3)
-#define AST_CDR_FLAG_POST_DISABLED		(1 << 4)
+#define AST_CDR_FLAG_POST_DISABLED	(1 << 4)
+#define AST_CDR_FLAG_ANSLOCKED      (1 << 5)
+#define AST_CDR_FLAG_DONT_TOUCH     (1 << 6)
 
 #define AST_CDR_NULL                0
 #define AST_CDR_FAILED				(1 << 0)
@@ -39,10 +41,10 @@
 /*! AMA Flags */
 #define AST_CDR_OMIT				(1)
 #define AST_CDR_BILLING				(2)
-#define AST_CDR_DOCUMENTATION			(3)
+#define AST_CDR_DOCUMENTATION		(3)
 
 #define AST_MAX_USER_FIELD			256
-#define AST_MAX_ACCOUNT_CODE			20
+#define AST_MAX_ACCOUNT_CODE		20
 
 /* Include channel.h after relevant declarations it will need */
 #include "asterisk/channel.h"
@@ -179,12 +181,17 @@
 /*!
  * \param cdr the cdr you wish to associate with the call
  * Marks the channel disposition as "NO ANSWER"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
  */
 extern void ast_cdr_noanswer(struct ast_cdr *cdr);
 
 /*! Busy a call */
 /*!
  * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "BUSY"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
  * Returns nothing
  */
 void ast_cdr_busy(struct ast_cdr *cdr);
@@ -192,6 +199,9 @@
 /*! Fail a call */
 /*!
  * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "FAILED"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
  * Returns nothing
  */
 void ast_cdr_failed(struct ast_cdr *cdr);
@@ -199,8 +209,8 @@
 /*! Save the result of the call based on the AST_CAUSE_* */
 /*!
  * \param cdr the cdr you wish to associate with the call
- * Returns nothing
  * \param cause the AST_CAUSE_*
+ * Returns nothing
  */
 int ast_cdr_disposition(struct ast_cdr *cdr, int cause);
 	

Modified: team/jpeeler/chan_dahdi14/include/asterisk/global_datastores.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/include/asterisk/global_datastores.h?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/include/asterisk/global_datastores.h (original)
+++ team/jpeeler/chan_dahdi14/include/asterisk/global_datastores.h Thu Jun 12 13:31:18 2008
@@ -26,11 +26,22 @@
 
 #include "asterisk/channel.h"
 
+#define MAX_DIAL_FEATURE_OPTIONS 30
+
 extern const struct ast_datastore_info dialed_interface_info;
+
+extern const struct ast_datastore_info dial_features_info;
 
 struct ast_dialed_interface {
 	AST_LIST_ENTRY(ast_dialed_interface) list;
 	char interface[1];
 };
 
+struct ast_dial_features {
+	struct ast_flags features_caller;
+	struct ast_flags features_callee;
+	char options[MAX_DIAL_FEATURE_OPTIONS];
+	int is_caller;
+};
+
 #endif

Modified: team/jpeeler/chan_dahdi14/main/abstract_jb.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/abstract_jb.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/main/abstract_jb.c (original)
+++ team/jpeeler/chan_dahdi14/main/abstract_jb.c Thu Jun 12 13:31:18 2008
@@ -433,7 +433,7 @@
 			return;
 		default:
 			ast_log(LOG_ERROR, "This should never happen!\n");
-			ast_assert(0);
+			ast_assert("JB type unknown" == NULL);
 			break;
 		}
 		
@@ -487,10 +487,9 @@
 			*tmp = '#';
 		
 		bridged = ast_bridged_channel(chan);
-		if (!bridged) {
-			/* We should always have bridged chan if a jitterbuffer is in use */
-			ast_assert(0);
-		}
+		/* We should always have bridged chan if a jitterbuffer is in use */
+		ast_assert(bridged != NULL);
+
 		snprintf(name1, sizeof(name1), "%s", bridged->name);
 		tmp = strchr(name1, '/');
 		if (tmp)

Modified: team/jpeeler/chan_dahdi14/main/app.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/app.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/main/app.c (original)
+++ team/jpeeler/chan_dahdi14/main/app.c Thu Jun 12 13:31:18 2008
@@ -1387,6 +1387,18 @@
 	return output;
 }
 
+void ast_app_options2str(const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len)
+{
+	unsigned int i, found = 0;
+
+	for (i = 32; i < 128 && found < len;i++) {
+		if (ast_test_flag(flags, options[i].flag)) {
+			buf[found++] = i;
+		}
+	}
+	buf[found] = '\0';
+}
+
 int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
 {
 	char *s;

Modified: team/jpeeler/chan_dahdi14/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/cdr.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/main/cdr.c (original)
+++ team/jpeeler/chan_dahdi14/main/cdr.c Thu Jun 12 13:31:18 2008
@@ -312,6 +312,8 @@
 	}
 
 	for (; cdr; cdr = recur ? cdr->next : NULL) {
+		if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+			continue;
 		headp = &cdr->varshead;
 		AST_LIST_TRAVERSE_SAFE_BEGIN(headp, newvariable, entries) {
 			if (!strcasecmp(ast_var_name(newvariable), name)) {
@@ -695,6 +697,10 @@
 {
 
 	for (; cdr; cdr = cdr->next) {
+		if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED)) 
+			continue;
+		if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+			continue;
 		check_post(cdr);
 		if (cdr->disposition < AST_CDR_ANSWERED)
 			cdr->disposition = AST_CDR_ANSWERED;
@@ -852,6 +858,8 @@
 void ast_cdr_end(struct ast_cdr *cdr)
 {
 	for ( ; cdr ; cdr = cdr->next) {
+		if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+			continue;
 		check_post(cdr);
 		if (ast_tvzero(cdr->end))
 			cdr->end = ast_tvnow();

Modified: team/jpeeler/chan_dahdi14/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi14/main/channel.c?view=diff&rev=122298&r1=122297&r2=122298
==============================================================================
--- team/jpeeler/chan_dahdi14/main/channel.c (original)
+++ team/jpeeler/chan_dahdi14/main/channel.c Thu Jun 12 13:31:18 2008
@@ -764,6 +764,7 @@
 	if (needqueue) {
 		if (pipe(tmp->alertpipe)) {
 			ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
+alertpipe_failed:
 #ifdef HAVE_DAHDI
 			if (tmp->timingfd > -1)
 				close(tmp->timingfd);
@@ -774,9 +775,19 @@
 			return NULL;
 		} else {
 			flags = fcntl(tmp->alertpipe[0], F_GETFL);
-			fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
+			if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {

[... 257 lines stripped ...]



More information about the svn-commits mailing list