[asterisk-commits] jpeeler: branch jpeeler/chan_dahdi r122227 - in /team/jpeeler/chan_dahdi: ./ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 12 11:22:20 CDT 2008


Author: jpeeler
Date: Thu Jun 12 11:22:19 2008
New Revision: 122227

URL: http://svn.digium.com/view/asterisk?view=rev&rev=122227
Log:
sync with trunk

Added:
    team/jpeeler/chan_dahdi/include/asterisk/timing.h
      - copied unchanged from r122174, trunk/include/asterisk/timing.h
    team/jpeeler/chan_dahdi/main/timing.c
      - copied unchanged from r122174, trunk/main/timing.c
Modified:
    team/jpeeler/chan_dahdi/   (props changed)
    team/jpeeler/chan_dahdi/CHANGES
    team/jpeeler/chan_dahdi/UPGRADE.txt
    team/jpeeler/chan_dahdi/apps/app_forkcdr.c
    team/jpeeler/chan_dahdi/apps/app_meetme.c
    team/jpeeler/chan_dahdi/channels/chan_agent.c
    team/jpeeler/chan_dahdi/channels/misdn/isdn_lib.c
    team/jpeeler/chan_dahdi/contrib/scripts/realtime_pgsql.sql
    team/jpeeler/chan_dahdi/doc/backtrace.txt
    team/jpeeler/chan_dahdi/doc/distributed_devstate.txt
    team/jpeeler/chan_dahdi/funcs/func_cdr.c
    team/jpeeler/chan_dahdi/include/asterisk/cdr.h
    team/jpeeler/chan_dahdi/include/asterisk/res_odbc.h
    team/jpeeler/chan_dahdi/main/Makefile
    team/jpeeler/chan_dahdi/main/abstract_jb.c
    team/jpeeler/chan_dahdi/main/cdr.c
    team/jpeeler/chan_dahdi/main/channel.c
    team/jpeeler/chan_dahdi/main/features.c
    team/jpeeler/chan_dahdi/main/netsock.c
    team/jpeeler/chan_dahdi/main/sched.c
    team/jpeeler/chan_dahdi/res/res_config_odbc.c
    team/jpeeler/chan_dahdi/res/res_odbc.c

Propchange: team/jpeeler/chan_dahdi/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/jpeeler/chan_dahdi/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/jpeeler/chan_dahdi/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Jun 12 11:22:19 2008
@@ -1,1 +1,1 @@
-/trunk:1-121680
+/trunk:1-122209

Modified: team/jpeeler/chan_dahdi/CHANGES
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/CHANGES?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/CHANGES (original)
+++ team/jpeeler/chan_dahdi/CHANGES Thu Jun 12 11:22:19 2008
@@ -93,6 +93,12 @@
  * PrivacyManager now takes an option where you can specify a context where the 
    given number will be matched. This way you have more control over who is allowed
    and it stops the people who blindly enter 10 digits.
+ * ForkCDR has new options: 'a' updates the answer time on the new CDR; 'A' locks
+   answer times, disposition, on orig CDR against updates; 'D' Copies the disposition
+   from the orig CDR to the new CDR after reset; 'e' sets the 'end' time on the
+   original CDR; 'R' prevents the new CDR from being reset; 's(var=val)' adds/changes
+   the 'var' variable on the original CDR; 'T' forces ast_cdr_end(), ast_cdr_answer(),
+   obey the LOCKED flag on cdr's in the chain, and also the ast_cdr_setvar() func.
 
 SIP Changes
 -----------

Modified: team/jpeeler/chan_dahdi/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/UPGRADE.txt?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/UPGRADE.txt (original)
+++ team/jpeeler/chan_dahdi/UPGRADE.txt Thu Jun 12 11:22:19 2008
@@ -150,6 +150,11 @@
   username and password parameters in cdr_odbc.conf, therefore, are no
   longer used.  The dsn parameter now points to an entry in res_odbc.conf.
 
+* The uniqueid field in the core Asterisk structure has been changed from a
+  maximum 31 character field to a 149 character field, to account for all
+  possible values the systemname prefix could be.  In the past, if the
+  systemname was too long, the uniqueid would have been truncated.
+
 Formats:
 
 * format_wav: The GAIN preprocessor definition and source code that used it

Modified: team/jpeeler/chan_dahdi/apps/app_forkcdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/apps/app_forkcdr.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/apps/app_forkcdr.c (original)
+++ team/jpeeler/chan_dahdi/apps/app_forkcdr.c Thu Jun 12 11:22:19 2008
@@ -42,21 +42,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";
@@ -70,6 +131,8 @@
 	OPT_NORESET =           (1 << 4),
 	OPT_KEEPVARS =          (1 << 5),
 	OPT_VARSET =            (1 << 6),
+	OPT_ANSLOCK =           (1 << 7),
+	OPT_DONTOUCH =          (1 << 8),
 };
 
 enum {
@@ -80,11 +143,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),
 });
 
@@ -132,6 +197,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_dahdi/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/apps/app_meetme.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/apps/app_meetme.c (original)
+++ team/jpeeler/chan_dahdi/apps/app_meetme.c Thu Jun 12 11:22:19 2008
@@ -2281,7 +2281,9 @@
 				break;
 
 			if (c) {
-				if (c->fds[0] != origfd || (user->dahdichannel && (c->audiohooks || c->monitor))) {
+				char dtmfstr[2] = "";
+
+				if (c->fds[0] != origfd || (user->zapchannel && (c->audiohooks || c->monitor))) {
 					if (using_pseudo) {
 						/* Kill old pseudo */
 						close(fd);
@@ -2298,6 +2300,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);
@@ -2348,35 +2355,6 @@
 						if (user->talking)
 							careful_write(fd, f->data.ptr, 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_debug(1, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
-						ret = 0;
-						ast_frfree(f);
-						break;
-					} else {
-						ast_debug(2, "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) && (confflags & CONFFLAG_KEYEXIT) && (strchr(exitkeys, f->subclass))) {
-					char exitkey[2];
-
-					exitkey[0] = f->subclass;
-					exitkey[1] = '\0';
-					
-					pbx_builtin_setvar_helper(chan, "MEETME_EXIT_KEY", exitkey);
-						
-					if (confflags & CONFFLAG_PASS_DTMF)
-						conf_queue_dtmf(conf, user, f);
-					ret = 0;
-					ast_frfree(f);
-					break;
 				} else if (((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*') && (confflags & CONFFLAG_STARMENU)) || ((f->frametype == AST_FRAME_DTMF) && menu_active)) {
 					if (confflags & CONFFLAG_PASS_DTMF)
 						conf_queue_dtmf(conf, user, f);
@@ -2543,6 +2521,27 @@
 					}
 
 					conf_flush(fd, chan);
+				/* Since this option could absorb dtmf meant for the previous (menu), 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_debug(1, "Got DTMF %c, goto context %s\n", dtmfstr[0], exitcontext);
+						ret = 0;
+						ast_frfree(f);
+						break;
+					} else {
+						ast_debug(2, "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) && (confflags & CONFFLAG_KEYEXIT) && (strchr(exitkeys, f->subclass))) {
+					pbx_builtin_setvar_helper(chan, "MEETME_EXIT_KEY", dtmfstr);
+						
+					if (confflags & CONFFLAG_PASS_DTMF)
+						conf_queue_dtmf(conf, user, f);
+					ret = 0;
+					ast_frfree(f);
+					break;
 				} 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_dahdi/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/channels/chan_agent.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/channels/chan_agent.c (original)
+++ team/jpeeler/chan_dahdi/channels/chan_agent.c Thu Jun 12 11:22:19 2008
@@ -1018,7 +1018,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_dahdi/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/channels/misdn/isdn_lib.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/channels/misdn/isdn_lib.c (original)
+++ team/jpeeler/chan_dahdi/channels/misdn/isdn_lib.c Thu Jun 12 11:22:19 2008
@@ -3121,12 +3121,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;
 }
 
 
@@ -3175,9 +3181,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 {
@@ -3190,7 +3202,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;
@@ -3202,7 +3214,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_dahdi/contrib/scripts/realtime_pgsql.sql
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/contrib/scripts/realtime_pgsql.sql?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/contrib/scripts/realtime_pgsql.sql (original)
+++ team/jpeeler/chan_dahdi/contrib/scripts/realtime_pgsql.sql Thu Jun 12 11:22:19 2008
@@ -25,7 +25,7 @@
 disposition character varying(45) DEFAULT '' NOT NULL,
 amaflags bigint DEFAULT 0::bigint NOT NULL,
 accountcode character varying(20) DEFAULT '' NOT NULL,
-uniqueid character varying(32) DEFAULT '' NOT NULL,
+uniqueid character varying(150) DEFAULT '' NOT NULL,
 userfield character varying(255) DEFAULT '' NOT NULL
 );
 

Modified: team/jpeeler/chan_dahdi/doc/backtrace.txt
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/doc/backtrace.txt?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/doc/backtrace.txt (original)
+++ team/jpeeler/chan_dahdi/doc/backtrace.txt Thu Jun 12 11:22:19 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_dahdi/doc/distributed_devstate.txt
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/doc/distributed_devstate.txt?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/doc/distributed_devstate.txt (original)
+++ team/jpeeler/chan_dahdi/doc/distributed_devstate.txt Thu Jun 12 11:22:19 2008
@@ -134,7 +134,7 @@
 will let you build the res_ais module.  Check menuselect to make sure that
 res_ais is going to get compiled and installed.
 
-$ cd asterisk-events
+$ cd asterisk-source
 $ ./configure
 
 $ make menuselect
@@ -182,7 +182,7 @@
 For more information on the contents and available options in this configuration
 file, please see the sample configuration file:
 
-$ cd asterisk-events
+$ cd asterisk-source
 $ less configs/ais.conf.sample
 
 -------------------------------------------------------------------------------

Modified: team/jpeeler/chan_dahdi/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/funcs/func_cdr.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/funcs/func_cdr.c (original)
+++ team/jpeeler/chan_dahdi/funcs/func_cdr.c Thu Jun 12 11:22:19 2008
@@ -40,11 +40,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),
 });
 
@@ -74,6 +76,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));
@@ -84,6 +90,7 @@
 static int cdr_write(struct ast_channel *chan, const 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);
@@ -93,19 +100,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. */
 
@@ -122,6 +136,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"
@@ -139,6 +155,8 @@
 "  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"

Modified: team/jpeeler/chan_dahdi/include/asterisk/cdr.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/include/asterisk/cdr.h?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/include/asterisk/cdr.h (original)
+++ team/jpeeler/chan_dahdi/include/asterisk/cdr.h Thu Jun 12 11:22:19 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_FLAG_POST_ENABLE                (1 << 5)
 
 /*! \name CDR Flags */
@@ -44,11 +46,11 @@
 /*@{ */
 #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"
@@ -90,8 +92,9 @@
 	char accountcode[AST_MAX_ACCOUNT_CODE];			
 	/*! flags */
 	unsigned int flags;				
-	/*! Unique Channel Identifier */
-	char uniqueid[32];
+	/*! Unique Channel Identifier
+	 * 150 = 127 (max systemname) + "-" + 10 (epoch timestamp) + "." + 10 (monotonically incrementing integer) + NULL */
+	char uniqueid[150];
 	/*! User field */
 	char userfield[AST_MAX_USER_FIELD];
 
@@ -195,12 +198,17 @@
  * \brief A call wasn't answered 
  * \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);
 
 /*! 
  * \brief 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);
@@ -208,6 +216,9 @@
 /*! 
  * \brief 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);

Modified: team/jpeeler/chan_dahdi/include/asterisk/res_odbc.h
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/include/asterisk/res_odbc.h?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/include/asterisk/res_odbc.h (original)
+++ team/jpeeler/chan_dahdi/include/asterisk/res_odbc.h Thu Jun 12 11:22:19 2008
@@ -142,4 +142,35 @@
  */
 SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_cb)(struct odbc_obj *obj, void *data), void *data);
 
+/*!
+ * \brief Find or create an entry describing the table specified.
+ * \param database Name of an ODBC class on which to query the table
+ * \param table Tablename to describe
+ * \retval A structure describing the table layout, or NULL, if the table is not found or another error occurs.
+ * When a structure is returned, the contained columns list will be
+ * rdlock'ed, to ensure that it will be retained in memory.
+ */
+struct odbc_cache_tables *ast_odbc_find_table(const char *database, const char *tablename);
+
+/*!
+ * \brief Find a column entry within a cached table structure
+ * \param table Cached table structure, as returned from ast_odbc_find_table()
+ * \param colname The column name requested
+ * \retval A structure describing the column type, or NULL, if the column is not found.
+ */
+struct odbc_cache_columns *ast_odbc_find_column(struct odbc_cache_tables *table, const char *colname);
+
+/*!
+ * \brief Remove a cache entry from memory
+ * \param database Name of an ODBC class (used to ensure like-named tables in different databases are not confused)
+ * \param table Tablename for which a cached record should be removed
+ * \retval 0 if the cache entry was removed, or -1 if no matching entry was found.
+ */
+int ast_odbc_clear_cache(const char *database, const char *tablename);
+
+/*!
+ * \brief Release a table returned from ast_odbc_find_table
+ */
+#define ast_odbc_release_table(ptr) if (ptr) { AST_RWLIST_UNLOCK(&(ptr)->columns); }
+
 #endif /* _ASTERISK_RES_ODBC_H */

Modified: team/jpeeler/chan_dahdi/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/Makefile?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/Makefile (original)
+++ team/jpeeler/chan_dahdi/main/Makefile Thu Jun 12 11:22:19 2008
@@ -30,7 +30,7 @@
 	cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
 	strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \
 	astobj2.o hashtab.o global_datastores.o $(RESAMPLE_OBJS) version.o \
-	features.o taskprocessor.o
+	features.o taskprocessor.o timing.o
 
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static

Modified: team/jpeeler/chan_dahdi/main/abstract_jb.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/abstract_jb.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/abstract_jb.c (original)
+++ team/jpeeler/chan_dahdi/main/abstract_jb.c Thu Jun 12 11:22:19 2008
@@ -430,7 +430,7 @@
 			return;
 		default:
 			ast_log(LOG_ERROR, "This should never happen!\n");
-			ast_assert(0);
+			ast_assert("JB type unknown" == NULL);
 			break;
 		}
 		
@@ -484,10 +484,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_dahdi/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/cdr.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/cdr.c (original)
+++ team/jpeeler/chan_dahdi/main/cdr.c Thu Jun 12 11:22:19 2008
@@ -306,6 +306,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)) {
@@ -689,6 +691,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;
@@ -712,6 +718,7 @@
 void ast_cdr_failed(struct ast_cdr *cdr)
 {
 	for (; cdr; cdr = cdr->next) {
+		check_post(cdr);
 		if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
 			check_post(cdr);
 			if (cdr->disposition < AST_CDR_FAILED)
@@ -847,6 +854,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_dahdi/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/channel.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/channel.c (original)
+++ team/jpeeler/chan_dahdi/main/channel.c Thu Jun 12 11:22:19 2008
@@ -824,6 +824,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);
@@ -834,9 +835,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) {
+				ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				close(tmp->alertpipe[0]);
+				close(tmp->alertpipe[1]);
+				goto alertpipe_failed;
+			}
 			flags = fcntl(tmp->alertpipe[1], F_GETFL);
-			fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
+			if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
+				ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				close(tmp->alertpipe[0]);
+				close(tmp->alertpipe[1]);
+				goto alertpipe_failed;
+			}
 		}
 	} else	/* Make sure we've got it done right if they don't */
 		tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
@@ -983,7 +994,7 @@
 	if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
 		if (fin->frametype != AST_FRAME_VOICE) {
 			ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
-			ast_assert(0);
+			ast_assert(fin->frametype == AST_FRAME_VOICE);
 		} else {
 			ast_debug(1, "Dropping voice to exceptionally long queue on %s\n", chan->name);
 			ast_frfree(f);
@@ -1641,7 +1652,7 @@
 		ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
 					"is blocked by thread %ld in procedure %s!  Expect a failure\n",
 					(long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
-		ast_assert(0);
+		ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
 	}
 	if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
 		ast_debug(1, "Hanging up channel '%s'\n", chan->name);
@@ -2385,8 +2396,20 @@
 	
 	/* Read and ignore anything on the alertpipe, but read only
 	   one sizeof(blah) per frame that we send from it */
-	if (chan->alertpipe[0] > -1)
+	if (chan->alertpipe[0] > -1) {
+		int flags = fcntl(chan->alertpipe[0], F_GETFL);
+		/* For some odd reason, the alertpipe occasionally loses nonblocking status,
+		 * which immediately causes a deadlock scenario.  Detect and prevent this. */
+		if ((flags & O_NONBLOCK) == 0) {
+			ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
+			if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
+				ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				f = &ast_null_frame;
+				goto done;
+			}
+		}
 		read(chan->alertpipe[0], &blah, sizeof(blah));
+	}
 
 #ifdef HAVE_DAHDI
 	if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {

Modified: team/jpeeler/chan_dahdi/main/features.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/features.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/features.c (original)
+++ team/jpeeler/chan_dahdi/main/features.c Thu Jun 12 11:22:19 2008
@@ -3001,7 +3001,7 @@
 			default_parkinglot->parking_stop = 750;
 			default_parkinglot->parking_offset = 0;
 			default_parkinglot->parkfindnext = 0;
-			default_parkinglot->parkingtime = 0;
+			default_parkinglot->parkingtime = DEFAULT_PARK_TIME;
 			ao2_unlock(default_parkinglot);
 		}
 	}

Modified: team/jpeeler/chan_dahdi/main/netsock.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/netsock.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/netsock.c (original)
+++ team/jpeeler/chan_dahdi/main/netsock.c Thu Jun 12 11:22:19 2008
@@ -266,7 +266,7 @@
 	}
 #endif
 #endif
-	ast_log(LOG_NOTICE, "No ethernet interface found for seeding global EID. You will have to set it manually.\n");
+	ast_debug(1, "No ethernet interface found for seeding global EID. You will have to set it manually.\n");
 }
 
 int ast_str_to_eid(struct ast_eid *eid, const char *s)

Modified: team/jpeeler/chan_dahdi/main/sched.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/main/sched.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/main/sched.c (original)
+++ team/jpeeler/chan_dahdi/main/sched.c Thu Jun 12 11:22:19 2008
@@ -373,7 +373,7 @@
 
 	if (!s) {
 		ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id);
-		ast_assert(0);
+		ast_assert(s != NULL);
 		return -1;
 	}
 	

Modified: team/jpeeler/chan_dahdi/res/res_config_odbc.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/chan_dahdi/res/res_config_odbc.c?view=diff&rev=122227&r1=122226&r2=122227
==============================================================================
--- team/jpeeler/chan_dahdi/res/res_config_odbc.c (original)
+++ team/jpeeler/chan_dahdi/res/res_config_odbc.c Thu Jun 12 11:22:19 2008
@@ -53,153 +53,6 @@
 	va_list ap;
 	unsigned long long skip;
 };
-
-/*!\brief The structures referenced are in include/asterisk/res_odbc.h */
-static AST_RWLIST_HEAD_STATIC(odbc_tables, odbc_cache_tables);
-
-static void destroy_table_cache(struct odbc_cache_tables *table) {
-	struct odbc_cache_columns *col;
-	ast_debug(1, "Destroying table cache for %s\n", table->table);
-	AST_RWLIST_WRLOCK(&table->columns);
-	while ((col = AST_RWLIST_REMOVE_HEAD(&table->columns, list))) {
-		ast_free(col);
-	}
-	AST_RWLIST_UNLOCK(&table->columns);
-	AST_RWLIST_HEAD_DESTROY(&table->columns);
-	ast_free(table);
-}
-
-#define release_table(ptr) if (ptr) { AST_RWLIST_UNLOCK(&(ptr)->columns); }
-
-/*!
- * \brief Find or create an entry describing the table specified.
- * \param obj An active ODBC handle on which to query the table
- * \param table Tablename to describe
- * \retval A structure describing the table layout, or NULL, if the table is not found or another error occurs.
- * When a structure is returned, the contained columns list will be
- * rdlock'ed, to ensure that it will be retained in memory.
- */
-static struct odbc_cache_tables *find_table(const char *database, const char *tablename)
-{
-	struct odbc_cache_tables *tableptr;
-	struct odbc_cache_columns *entry;
-	char columnname[80];
-	SQLLEN sqlptr;
-	SQLHSTMT stmt = NULL;
-	int res = 0, error = 0, try = 0;
-	struct odbc_obj *obj = ast_odbc_request_obj(database, 0);
-
-	AST_RWLIST_RDLOCK(&odbc_tables);
-	AST_RWLIST_TRAVERSE(&odbc_tables, tableptr, list) {
-		if (strcmp(tableptr->connection, database) == 0 && strcmp(tableptr->table, tablename) == 0) {
-			break;
-		}
-	}
-	if (tableptr) {
-		AST_RWLIST_RDLOCK(&tableptr->columns);
-		AST_RWLIST_UNLOCK(&odbc_tables);
-		return tableptr;
-	}
-
-	if (!obj) {
-		ast_log(LOG_WARNING, "Unable to retrieve database handle for table description '%s@%s'\n", tablename, database);
-		return NULL;
-	}
-
-	/* Table structure not already cached; build it now. */
-	do {
-retry:
-		res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
-		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-			if (try == 0) {
-				try = 1;
-				ast_odbc_sanity_check(obj);
-				goto retry;
-			}
-			ast_log(LOG_WARNING, "SQL Alloc Handle failed on connection '%s'!\n", database);

[... 416 lines stripped ...]



More information about the asterisk-commits mailing list