[asterisk-commits] oej: branch oej/pinesounds-dtmf-feature-delay-1.4 r403284 - in /team/oej/pine...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Dec 2 03:58:06 CST 2013


Author: oej
Date: Mon Dec  2 03:58:00 2013
New Revision: 403284

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403284
Log:
Resetting

Modified:
    team/oej/pinesounds-dtmf-feature-delay-1.4/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/CHANGES
    team/oej/pinesounds-dtmf-feature-delay-1.4/agi/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_dial.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_directed_pickup.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_meetme.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_milliwatt.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_voicemail.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/cdr_pgsql.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_agent.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_dahdi.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_iax2.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_local.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_sip.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_skinny.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/codecs/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/codecs/gsm/src/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/codecs/lpc10/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/configs/http.conf.sample
    team/oej/pinesounds-dtmf-feature-delay-1.4/configs/indications.conf.sample
    team/oej/pinesounds-dtmf-feature-delay-1.4/configs/manager.conf.sample
    team/oej/pinesounds-dtmf-feature-delay-1.4/configs/sip.conf.sample
    team/oej/pinesounds-dtmf-feature-delay-1.4/configs/skinny.conf.sample
    team/oej/pinesounds-dtmf-feature-delay-1.4/configure
    team/oej/pinesounds-dtmf-feature-delay-1.4/configure.ac
    team/oej/pinesounds-dtmf-feature-delay-1.4/contrib/scripts/safe_asterisk
    team/oej/pinesounds-dtmf-feature-delay-1.4/formats/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/formats/format_wav.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/funcs/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/include/asterisk/autoconfig.h.in
    team/oej/pinesounds-dtmf-feature-delay-1.4/include/asterisk/select.h
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/asterisk.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/channel.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/db1-ast/btree/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/db1-ast/db/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/db1-ast/hash/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/db1-ast/mpool/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/db1-ast/recno/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/http.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/manager.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/main/stdtime/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/pbx/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/pbx/ael/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/res/   (props changed)
    team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_agi.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/res/res_features.c
    team/oej/pinesounds-dtmf-feature-delay-1.4/utils/   (props changed)

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/
------------------------------------------------------------------------------
    automerge = Is-there-life-off-net?

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/
------------------------------------------------------------------------------
--- svn:externals (original)
+++ svn:externals Mon Dec  2 03:58:00 2013
@@ -1,1 +1,1 @@
-menuselect https://origsvn.digium.com/svn/menuselect/trunk
+menuselect https://origsvn.digium.com/svn/menuselect/tags/autotag_for_asterisk/1.4.42

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Dec  2 03:58:00 2013
@@ -1,1 +1,1 @@
-/branches/1.4:1-310816
+/branches/1.4:1-403283

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/CHANGES?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/CHANGES (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/CHANGES Mon Dec  2 03:58:00 2013
@@ -1,3 +1,11 @@
+Changes since Asterisk 1.4.42
+
+    * Due to potential username discovery vulnerabilities, the 'nat' setting in sip.conf
+      now defaults to yes. It is very important that phones requiring nat=no be
+      specifically set as such instead of relying on the default setting. If at all
+      possible, all devices should have nat settings configured in the general section as
+      opposed to configuring nat per-device.
+
 Changes since Asterisk 1.2:
 
     * over 4,000 commits since 1.2

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/agi/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec  2 03:58:00 2013
@@ -1,3 +1,4 @@
+*.o
 eagi-test
 eagi-sphinx-test
 *.d

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec  2 03:58:00 2013
@@ -1,3 +1,4 @@
+*.o
 *.a
 *.d
 *.i

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_dial.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_dial.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_dial.c Mon Dec  2 03:58:00 2013
@@ -1459,8 +1459,11 @@
 	 * to which the datastore was moved hangs up, it will attempt to free this
 	 * datastore again, causing a crash
 	 */
-	if (!ast_channel_datastore_remove(chan, datastore))
+	ast_channel_lock(chan);
+	if (!ast_channel_datastore_remove(chan, datastore)) {
 		ast_channel_datastore_free(datastore);
+	}
+	ast_channel_unlock(chan);
 	if (!peer) {
 		if (result) {
 			res = result;

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_directed_pickup.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_directed_pickup.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_directed_pickup.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_directed_pickup.c Mon Dec  2 03:58:00 2013
@@ -54,39 +54,45 @@
 "10 at PICKUPMARK, this application tries to find a channel which has defined a channel variable with the same content\n"
 "as \"extension\".";
 
-/* Perform actual pickup between two channels */
+/*!
+ * \internal
+ * \brief Perform actual pickup between two channels.
+ * \note Must remain in sync with same function in res/res_features.c.
+ */
 static int pickup_do(struct ast_channel *chan, struct ast_channel *target)
 {
-	int res = 0;
-
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
 
-	if ((res = ast_answer(chan))) {
+	if (ast_answer(chan)) {
 		ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
 		return -1;
 	}
 
-	if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) {
+	if (ast_queue_control(chan, AST_CONTROL_ANSWER)) {
 		ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
 		return -1;
 	}
 
-	if ((res = ast_channel_masquerade(target, chan))) {
+	if (ast_channel_masquerade(target, chan)) {
 		ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
 		return -1;
 	}
 
-	return res;
+	return 0;
 }
 
 /* Helper function that determines whether a channel is capable of being picked up */
 static int can_pickup(struct ast_channel *chan)
 {
-	if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN))
+	if (!chan->pbx && !chan->masq &&
+		!ast_test_flag(chan, AST_FLAG_ZOMBIE) &&
+		(chan->_state == AST_STATE_RINGING ||
+		 chan->_state == AST_STATE_RING ||
+		 chan->_state == AST_STATE_DOWN)) {
 		return 1;
-	else
-		return 0;
+	}
+	return 0;
 }
 
 /* Attempt to pick up specified extension with context */

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_meetme.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_meetme.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_meetme.c Mon Dec  2 03:58:00 2013
@@ -1099,6 +1099,7 @@
 				AST_LIST_UNLOCK(&confs);
 				return usr ? strdup(usrno) : NULL;
 			}
+			AST_LIST_UNLOCK(&confs);
 		} else if ( strstr(line, "list") && ( 0 == state ) )
 			return strdup("concise");
 	}

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_milliwatt.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_milliwatt.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_milliwatt.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_milliwatt.c Mon Dec  2 03:58:00 2013
@@ -77,7 +77,7 @@
 static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
 {
 	unsigned char buf[AST_FRIENDLY_OFFSET + 640];
-	const int maxsamples = sizeof (buf) / sizeof (buf[0]);
+	const int maxsamples = (sizeof (buf) / sizeof (buf[0])) - (AST_FRIENDLY_OFFSET / sizeof(buf[0]));
 	int i, *indexp = (int *) data;
 	struct ast_frame wf = {
 		.frametype = AST_FRAME_VOICE,

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_voicemail.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_voicemail.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/apps/app_voicemail.c Mon Dec  2 03:58:00 2013
@@ -2539,7 +2539,7 @@
 		ast_odbc_release_obj(obj);
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:	
+yuck:
 	if (f)
 		fclose(f);
 	if (fd > -1)
@@ -2560,7 +2560,8 @@
 	struct odbc_obj *obj;
 	obj = ast_odbc_request_obj(odbc_database, 0);
 	if (obj) {
-		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?",odbc_table);
+		snprintf(sql, sizeof(sql), "SELECT msgnum FROM %s WHERE dir=? order by msgnum desc limit 1", odbc_table);
+
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt) {
 			ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -2569,7 +2570,12 @@
 		}
 		res = SQLFetch(stmt);
 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-			ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+			if (res == SQL_NO_DATA) {
+				ast_log(LOG_DEBUG, "Directory '%s' has no messages and therefore no index was retrieved.\n", dir);
+			} else {
+				ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+			}
+
 			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 			ast_odbc_release_obj(obj);
 			goto yuck;
@@ -2582,12 +2588,13 @@
 			goto yuck;
 		}
 		if (sscanf(rowdata, "%30d", &x) != 1)
-			ast_log(LOG_WARNING, "Failed to read message count!\n");
+			ast_log(LOG_WARNING, "Failed to read message index!\n");
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 		ast_odbc_release_obj(obj);
+		return x;
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:	
+yuck:
 	return x - 1;
 }
 
@@ -2633,13 +2640,54 @@
 		ast_odbc_release_obj(obj);
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:	
+yuck:
 	return x;
 }
 
 static int count_messages(struct ast_vm_user *vmu, char *dir)
 {
-	return last_message_index(vmu, dir) + 1;
+	int x = 0;
+	int res;
+	SQLHSTMT stmt;
+	char sql[PATH_MAX];
+	char rowdata[20];
+	char *argv[] = { dir };
+	struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
+
+	struct odbc_obj *obj;
+	obj = ast_odbc_request_obj(odbc_database, 0);
+	if (obj) {
+		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table);
+		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
+		if (!stmt) {
+			ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
+			ast_odbc_release_obj(obj);
+			goto yuck;
+		}
+		res = SQLFetch(stmt);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
+			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+			ast_odbc_release_obj(obj);
+			goto yuck;
+		}
+		res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
+		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+			ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+			ast_odbc_release_obj(obj);
+			goto yuck;
+		}
+		if (sscanf(rowdata, "%30d", &x) != 1)
+			ast_log(LOG_WARNING, "Failed to read message count!\n");
+		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+		ast_odbc_release_obj(obj);
+		return x;
+	} else
+		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
+yuck:
+	return x - 1;
+
 }
 
 static void delete_file(char *sdir, int smsg)
@@ -2834,7 +2882,7 @@
 		ast_odbc_release_obj(obj);
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
-yuck:	
+yuck:
 	if (cfg)
 		ast_config_destroy(cfg);
 	if (fdm != MAP_FAILED)
@@ -3593,7 +3641,8 @@
 		char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
 		char tmpdir[256], newtmp[256];
 		int tmpfd = -1;
-	
+		int soxstatus = 0;
+
 		if (vmu->volgain < -.001 || vmu->volgain > .001) {
 			create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
 			snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
@@ -3602,7 +3651,6 @@
 			if (option_debug > 2)
 				ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
 			if (tmpfd > -1) {
-				int soxstatus;
 				snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
 				if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
 					attach = newtmp;
@@ -3625,7 +3673,9 @@
 		base_encode(fname, p);
 		fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
 		if (tmpfd > -1) {
-			unlink(fname);
+			if (soxstatus == 0) {
+				unlink(fname);
+			}
 			close(tmpfd);
 			unlink(newtmp);
 		}
@@ -3911,7 +3961,7 @@
 	} else
 		ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
 		
-yuck:	
+yuck:
 	return x;
 }
 
@@ -4486,12 +4536,10 @@
 					ast_unlock_path(dir);
 					inprocess_count(vmu->mailbox, vmu->context, -1);
 				} else {
-					for (;;) {
-						make_file(fn, sizeof(fn), dir, msgnum);
-						if (!EXISTS(dir, msgnum, fn, NULL))
-							break;
-						msgnum++;
-					}
+#ifndef IMAP_STORAGE
+					msgnum = last_message_index(vmu, dir) + 1;
+#endif
+					make_file(fn, sizeof(fn), dir, msgnum);
 
 					/* assign a variable with the name of the voicemail file */ 
 #ifndef IMAP_STORAGE
@@ -4557,7 +4605,7 @@
 	return res;
 }
 
-#if !defined(IMAP_STORAGE) && !defined(ODBC_STORAGE)
+#if !defined(IMAP_STORAGE)
 static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount)
 {
 	/* we know the actual number of messages, so stop process when number is hit */
@@ -5997,9 +6045,6 @@
 #ifndef IMAP_STORAGE
 static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box)
 {
-#ifndef ODBC_STORAGE
-	int res = 0;
-#endif
 	int count_msg, last_msg;
 
 	ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
@@ -6035,14 +6080,10 @@
 
 	if (last_msg < -1) {
 		return last_msg;
-	}
-#ifndef ODBC_STORAGE
-	else if (vms->lastmsg != last_msg)
-	{
+	} else if (vms->lastmsg != last_msg) {
 		ast_log(LOG_NOTICE, "Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
-		res = resequence_mailbox(vmu, vms->curdir, count_msg);
-	}
-#endif
+		resequence_mailbox(vmu, vms->curdir, count_msg);
+	}
 
 	return 0;
 }
@@ -6052,6 +6093,7 @@
 {
 	int x = 0;
 #ifndef IMAP_STORAGE
+	int last_msg_index;
 	int res = 0, nummsg;
 #endif
 
@@ -6063,9 +6105,14 @@
 	/* Get the deleted messages fixed */ 
 	if (vm_lock_path(vms->curdir))
 		return ERROR_LOCK_PATH;
-	 
+
+	last_msg_index = last_message_index(vmu, vms->curdir);
+	if (last_msg_index !=  vms->lastmsg) {
+		ast_log(LOG_NOTICE, "%d messages arrived while mailbox was open\n", last_msg_index - vms->lastmsg);
+	}
+ 
 	/* must check up to last detected message, just in case it is erroneously greater than maxmsg */
-	for (x = 0; x < vms->lastmsg + 1; x++) { 
+	for (x = 0; x < last_msg_index + 1; x++) { 
 		if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
 			/* Save this message.  It's not in INBOX or hasn't been heard */ 
 			make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec  2 03:58:00 2013
@@ -1,3 +1,4 @@
+*.o
 *.a
 *.d
 *.i

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/cdr_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/cdr_pgsql.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/cdr_pgsql.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/cdr/cdr_pgsql.c Mon Dec  2 03:58:00 2013
@@ -86,7 +86,11 @@
 		if (PQstatus(conn) != CONNECTION_BAD) {
 			connected = 1;
 			if (PQsetClientEncoding(conn, encoding)) {
+#ifdef HAVE_PGSQL_pg_encoding_to_char
 				ast_log(LOG_WARNING, "Failed to set encoding to '%s'.  Encoding set to default '%s'\n", encoding, pg_encoding_to_char(PQclientEncoding(conn)));
+#else
+				ast_log(LOG_WARNING, "Failed to set encoding to '%s'.  Encoding set to default.\n", encoding);
+#endif
 			}
 		} else {
 			pgerror = PQerrorMessage(conn);
@@ -298,7 +302,11 @@
 			ast_log(LOG_DEBUG, "Successfully connected to PostgreSQL database.\n");
 		connected = 1;
 		if (PQsetClientEncoding(conn, encoding)) {
+#ifdef HAVE_PGSQL_pg_encoding_to_char
 			ast_log(LOG_WARNING, "Failed to set encoding to '%s'.  Encoding set to default '%s'\n", encoding, pg_encoding_to_char(PQclientEncoding(conn)));
+#else
+			ast_log(LOG_WARNING, "Failed to set encoding to '%s'.  Encoding set to default.\n", encoding);
+#endif
 		}
 	} else {
 		pgerror = PQerrorMessage(conn);

Propchange: team/oej/pinesounds-dtmf-feature-delay-1.4/channels/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Dec  2 03:58:00 2013
@@ -1,3 +1,4 @@
+*.o
 *.a
 *.d
 *.i

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_agent.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_agent.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_agent.c Mon Dec  2 03:58:00 2013
@@ -194,9 +194,9 @@
 	char password[AST_MAX_AGENT];  /*!< Password for Agent login */
 	char name[AST_MAX_AGENT];
 	int inherited_devicestate;     /*!< Does the underlying channel have a devicestate to pass? */
-	ast_mutex_t app_lock;          /**< Synchronization between owning applications */
 	int app_lock_flag;
 	ast_cond_t app_complete_cond;
+	ast_cond_t login_wait_cond;
 	volatile int app_sleep_cond;   /**< Sleep condition for the login app */
 	struct ast_channel *owner;     /**< Agent */
 	/**! channel they logged in from. This may also be used to tell if an agent
@@ -384,8 +384,8 @@
 			return NULL;
 		ast_copy_string(p->agent, agt, sizeof(p->agent));
 		ast_mutex_init(&p->lock);
-		ast_mutex_init(&p->app_lock);
 		ast_cond_init(&p->app_complete_cond, NULL);
+		ast_cond_init(&p->login_wait_cond, NULL);
 		p->app_lock_flag = 0;
 		p->app_sleep_cond = 1;
 		p->group = group;
@@ -429,21 +429,26 @@
  */
 static int agent_cleanup(struct agent_pvt *p)
 {
-	struct ast_channel *chan = p->owner;
+	struct ast_channel *chan = NULL;
+	ast_mutex_lock(&p->lock);
+	chan = p->owner;
 	p->owner = NULL;
 	chan->tech_pvt = NULL;
+	/* Release ownership of the agent to other threads (presumably running the login app). */
 	p->app_sleep_cond = 1;
-	/* Release ownership of the agent to other threads (presumably running the login app). */
 	p->app_lock_flag = 0;
 	ast_cond_signal(&p->app_complete_cond);
 	if (chan)
 		ast_channel_free(chan);
 	if (p->dead) {
+		ast_mutex_unlock(&p->lock);
 		ast_mutex_destroy(&p->lock);
-		ast_mutex_destroy(&p->app_lock);
 		ast_cond_destroy(&p->app_complete_cond);
+		ast_cond_destroy(&p->login_wait_cond);
 		free(p);
-        }
+        } else {
+		ast_mutex_unlock(&p->lock);
+	}
 	return 0;
 }
 
@@ -751,22 +756,25 @@
 	struct agent_pvt *p = ast->tech_pvt;
 	int res = -1;
 	int newstate=0;
+	struct ast_channel *chan;
+
 	ast_mutex_lock(&p->lock);
 	p->acknowledged = 0;
+
+	if (p->pending) {
+		ast_log(LOG_DEBUG, "Pretending to dial on pending agent\n");
+		ast_mutex_unlock(&p->lock);
+		ast_setstate(ast, AST_STATE_DIALING);
+		return 0;
+	}
+
 	if (!p->chan) {
-		if (p->pending) {
-			ast_log(LOG_DEBUG, "Pretending to dial on pending agent\n");
-			newstate = AST_STATE_DIALING;
-			res = 0;
-		} else {
-			ast_log(LOG_NOTICE, "Whoa, they hung up between alloc and call...  what are the odds of that?\n");
-			res = -1;
-		}
+		ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
 		ast_mutex_unlock(&p->lock);
-		if (newstate)
-			ast_setstate(ast, newstate);
 		return res;
-	} else if (!ast_strlen_zero(p->loginchan)) {
+	}
+
+	if (!ast_strlen_zero(p->loginchan)) {
 		time(&p->start);
 		/* Call on this agent */
 		if (option_verbose > 2)
@@ -783,14 +791,25 @@
 		ast_verbose(VERBOSE_PREFIX_3 "agent_call, call to agent '%s' call on '%s'\n", p->agent, p->chan->name);
 	if (option_debug > 2)
 		ast_log(LOG_DEBUG, "Playing beep, lang '%s'\n", p->chan->language);
-	res = ast_streamfile(p->chan, beep, p->chan->language);
+
+	chan = p->chan;
+	ast_mutex_unlock(&p->lock);
+
+	res = ast_streamfile(chan, beep, chan->language);
 	if (option_debug > 2)
 		ast_log(LOG_DEBUG, "Played beep, result '%d'\n", res);
 	if (!res) {
-		res = ast_waitstream(p->chan, "");
+		res = ast_waitstream(chan, "");
 		if (option_debug > 2)
 			ast_log(LOG_DEBUG, "Waited for stream, result '%d'\n", res);
 	}
+
+	ast_mutex_lock(&p->lock);
+	if (!p->chan) {
+		/* chan went away while we were streaming, this shouldn't be possible */
+		res = -1;
+	}
+
 	if (!res) {
 		res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats));
 		if (option_debug > 2)
@@ -887,6 +906,12 @@
 	ast->tech_pvt = NULL;
 	p->app_sleep_cond = 1;
 	p->acknowledged = 0;
+
+	/* Release ownership of the agent to other threads (presumably running the login app). */
+	if (ast_strlen_zero(p->loginchan)) {
+		p->app_lock_flag = 0;
+		ast_cond_signal(&p->app_complete_cond);
+	}
 
 	/* if they really are hung up then set start to 0 so the test
 	 * later if we're called on an already downed channel
@@ -973,8 +998,8 @@
 		p->abouttograb = 0;
 	} else if (p->dead) {
 		ast_mutex_destroy(&p->lock);
-		ast_mutex_destroy(&p->app_lock);
 		ast_cond_destroy(&p->app_complete_cond);
+		ast_cond_destroy(&p->login_wait_cond);
 		free(p);
 	} else {
 		if (p->chan) {
@@ -983,11 +1008,6 @@
 			/* Store last disconnect time */
 			p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
 			ast_mutex_unlock(&p->lock);
-		}
-		/* Release ownership of the agent to other threads (presumably running the login app). */
-		if (ast_strlen_zero(p->loginchan)) {
-			p->app_lock_flag = 0;
-			ast_cond_signal(&p->app_complete_cond);
 		}
 	}
 	return 0;
@@ -1076,7 +1096,6 @@
 static struct ast_channel *agent_new(struct agent_pvt *p, int state)
 {
 	struct ast_channel *tmp;
-	int alreadylocked;
 #if 0
 	if (!p->chan) {
 		ast_log(LOG_WARNING, "No channel? :(\n");
@@ -1119,50 +1138,6 @@
 #endif
 	ast_update_use_count();
 	tmp->priority = 1;
-	/* Wake up and wait for other applications (by definition the login app)
-	 * to release this channel). Takes ownership of the agent channel
-	 * to this thread only.
-	 * For signalling the other thread, ast_queue_frame is used until we
-	 * can safely use signals for this purpose. The pselect() needs to be
-	 * implemented in the kernel for this.
-	 */
-	p->app_sleep_cond = 0;
-
-	alreadylocked = p->app_lock_flag;
-	p->app_lock_flag = 1;
-
-	if(ast_strlen_zero(p->loginchan) && alreadylocked) {
-		if (p->chan) {
-			ast_queue_frame(p->chan, &ast_null_frame);
-			ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
-			p->app_lock_flag = 1;
-			ast_mutex_lock(&p->lock);
-		} else {
-			ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
-			p->owner = NULL;
-			tmp->tech_pvt = NULL;
-			p->app_sleep_cond = 1;
-			ast_channel_free( tmp );
-			ast_mutex_unlock(&p->lock);	/* For other thread to read the condition. */
-			p->app_lock_flag = 0;
-			ast_cond_signal(&p->app_complete_cond);
-			return NULL;
-		}
-	} else if (!ast_strlen_zero(p->loginchan)) {
-		if (p->chan)
-			ast_queue_frame(p->chan, &ast_null_frame);
-		if (!p->chan) {
-			ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
-			p->owner = NULL;
-			tmp->tech_pvt = NULL;
-			p->app_sleep_cond = 1;
-			ast_channel_free( tmp );
-			ast_mutex_unlock(&p->lock);     /* For other thread to read the condition. */
-			return NULL;
-		}	
-	} 
-	if (p->chan)
-		ast_indicate(p->chan, AST_CONTROL_UNHOLD);
 	return tmp;
 }
 
@@ -1306,8 +1281,8 @@
 			if (!p->owner) {
 				if (!p->chan) {
 					ast_mutex_destroy(&p->lock);
-					ast_mutex_destroy(&p->app_lock);
 					ast_cond_destroy(&p->app_complete_cond);
+					ast_cond_destroy(&p->login_wait_cond);
 					free(p);
 				} else {
 					/* Cause them to hang up */
@@ -1550,6 +1525,47 @@
 	}
 	*cause = hasagent ? AST_CAUSE_BUSY : AST_CAUSE_UNREGISTERED;
 	AST_LIST_UNLOCK(&agents);
+
+	if (chan) {
+		ast_mutex_lock(&p->lock);
+		if (p->pending) {
+			ast_mutex_unlock(&p->lock);
+			return chan;
+		}
+
+		if (!p->chan) {
+			ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
+			*cause = AST_CAUSE_UNREGISTERED;
+			ast_mutex_unlock(&p->lock);
+			agent_hangup(chan);
+			return NULL;
+		}
+
+		/* when not in callback mode we need to take control of the channel
+		 * from the login app thread */
+		if(ast_strlen_zero(p->loginchan)) {
+			p->app_sleep_cond = 0;
+			p->app_lock_flag = 1;
+
+			ast_queue_frame(p->chan, &ast_null_frame);
+			ast_cond_wait(&p->login_wait_cond, &p->lock);
+
+			if (!p->chan) {
+				ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
+				p->app_sleep_cond = 1;
+				p->app_lock_flag = 0;
+				ast_cond_signal(&p->app_complete_cond);
+				ast_mutex_unlock(&p->lock);
+				*cause = AST_CAUSE_UNREGISTERED;
+				agent_hangup(chan);
+				return NULL;
+			}
+
+			ast_indicate(p->chan, AST_CONTROL_UNHOLD);
+		}
+		ast_mutex_unlock(&p->lock);
+	}
+
 	return chan;
 }
 
@@ -2302,14 +2318,15 @@
 							}
 							ast_mutex_unlock(&p->lock);
 							AST_LIST_UNLOCK(&agents);
+
 							/*	Synchronize channel ownership between call to agent and itself. */
-							ast_mutex_lock(&p->app_lock);
+							ast_mutex_lock(&p->lock);
 							if (p->app_lock_flag == 1) {
-								ast_cond_wait(&p->app_complete_cond, &p->app_lock);
+								ast_cond_signal(&p->login_wait_cond);
+								ast_cond_wait(&p->app_complete_cond, &p->lock);
 							}
-							ast_mutex_unlock(&p->app_lock);
-							ast_mutex_lock(&p->lock);
 							ast_mutex_unlock(&p->lock);
+
 							if (p->ackcall > 1) 
 								res = agent_ack_sleep(p);
 							else
@@ -2325,13 +2342,21 @@
 							sched_yield();
 						}
 						ast_mutex_lock(&p->lock);
-						if (res && p->owner) 
-							ast_log(LOG_WARNING, "Huh?  We broke out when there was still an owner?\n");
 						/* Log us off if appropriate */
 						if (p->chan == chan) {
 							p->chan = NULL;
 							p->inherited_devicestate = -1;
 						}
+
+						/* Synchronize channel ownership between call to agent and itself. */
+						if (p->app_lock_flag == 1) {
+							ast_cond_signal(&p->login_wait_cond);
+							ast_cond_wait(&p->app_complete_cond, &p->lock);
+						}
+
+						if (res && p->owner)
+							ast_log(LOG_WARNING, "Huh?  We broke out when there was still an owner?\n");
+
 						p->acknowledged = 0;
 						logintime = time(NULL) - p->loginstart;
 						p->loginstart = 0;
@@ -2348,8 +2373,8 @@
 						ast_device_state_changed("Agent/%s", p->agent);
 						if (p->dead && !p->owner) {
 							ast_mutex_destroy(&p->lock);
-							ast_mutex_destroy(&p->app_lock);
 							ast_cond_destroy(&p->app_complete_cond);
+							ast_cond_destroy(&p->login_wait_cond);
 							free(p);
 						}
 					}

Modified: team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_dahdi.c?view=diff&rev=403284&r1=403283&r2=403284
==============================================================================
--- team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_dahdi.c (original)
+++ team/oej/pinesounds-dtmf-feature-delay-1.4/channels/chan_dahdi.c Mon Dec  2 03:58:00 2013
@@ -126,6 +126,21 @@
 #undef SUPPORT_USERUSER
 
 /*! 
+ * Define to make always pick a channel if allowed.  Useful for
+ * testing channel shifting.
+ */
+//#define ALWAYS_PICK_CHANNEL	1
+
+/*!
+ * Define to force a RESTART on a channel that returns a cause
+ * code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44).  If the cause
+ * is because of a stuck channel on the peer and the channel is
+ * always the next channel we pick for an outgoing call then
+ * this can help.
+ */
+#define FORCE_RESTART_UNAVAIL_CHANS		1
+
+/*!
  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
  * the user hangs up to reset the state machine so ring works properly.
  * This is used to be able to support kewlstart by putting the zhone in
@@ -145,8 +160,6 @@
 
 /*! \brief Typically, how many rings before we should send Caller*ID */
 #define DEFAULT_CIDRINGS 1
-
-#define CHANNEL_PSEUDO -12
 
 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
 
@@ -257,6 +270,9 @@
 static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
 
 static int dahdi_sendtext(struct ast_channel *c, const char *text);
+
+#define SIG_PRI_LIB_HANDLE_CASES	\
+	SIG_PRI
 
 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
 static inline int dahdi_get_event(int fd)
@@ -592,6 +608,19 @@
 	unsigned int unknown_alarm:1;
 	/*! \brief TRUE if TDD in MATE mode */
 	unsigned int mate:1;
+#if defined(HAVE_PRI)
+	/*!
+	 * \brief TRUE when this channel is allocated.
+	 *
+	 * \details
+	 * Needed to hold an outgoing channel allocation before the
+	 * owner pointer is created.
+	 *
+	 * \note This is one of several items to check to see if a
+	 * channel is available for use.
+	 */
+	unsigned int allocated:1;
+#endif	/* defined(HAVE_PRI) */
 	/*! \brief TRUE if we originated the call leg. */
 	unsigned int outgoing:1;
 	/* unsigned int overlapdial:1; 			unused and potentially confusing */
@@ -3060,7 +3089,6 @@
 	}
 
 	if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
-		p->owner = NULL;
 		p->ringt = 0;
 		p->distinctivering = 0;
 		p->confirmanswer = 0;
@@ -3101,59 +3129,58 @@
 		if (res < 0) 
 			ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
 		/* Perform low level hangup if no owner left */
-#ifdef HAVE_PRI
+#if defined(HAVE_PRI)
 		if (p->pri) {
 #ifdef SUPPORT_USERUSER
 			const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
 #endif
 
 			/* Make sure we have a call (or REALLY have a call in the case of a PRI) */
+			pri_grab(p, p->pri);
 			if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
-				if (!pri_grab(p, p->pri)) {
-					if (p->alreadyhungup) {
-						ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
+				if (p->alreadyhungup) {
+					ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
 
 #ifdef SUPPORT_USERUSER
-						pri_call_set_useruser(p->call, useruser);
+					pri_call_set_useruser(p->call, useruser);
 #endif
 
-						pri_hangup(p->pri->pri, p->call, -1);
-						p->call = NULL;
-						if (p->bearer) 
-							p->bearer->call = NULL;
-					} else {
-						const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
-						int icause = ast->hangupcause ? ast->hangupcause : -1;
-						ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
+					pri_hangup(p->pri->pri, p->call, -1);
+					p->call = NULL;
+					if (p->bearer)
+						p->bearer->call = NULL;
+				} else {
+					const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
+					int icause = ast->hangupcause ? ast->hangupcause : -1;
+					ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
 
 #ifdef SUPPORT_USERUSER
-						pri_call_set_useruser(p->call, useruser);
+					pri_call_set_useruser(p->call, useruser);
 #endif
 
-						p->alreadyhungup = 1;
-						if (p->bearer)
-							p->bearer->alreadyhungup = 1;
-						if (cause) {
-							if (atoi(cause))
-								icause = atoi(cause);
-						}
-						pri_hangup(p->pri->pri, p->call, icause);
+					p->alreadyhungup = 1;
+					if (p->bearer)
+						p->bearer->alreadyhungup = 1;
+					if (cause) {
+						if (atoi(cause))
+							icause = atoi(cause);
 					}
-					if (res < 0) 
-						ast_log(LOG_WARNING, "pri_disconnect failed\n");
-					pri_rel(p->pri);			
-				} else {
-					ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-					res = -1;
+					pri_hangup(p->pri->pri, p->call, icause);
 				}
 			} else {
 				if (p->bearer)
 					ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
 				p->call = NULL;
-				res = 0;
-			}
-		}
-#endif
+			}
+			p->allocated = 0;
+			p->owner = NULL;
+			pri_rel(p->pri);
+			res = 0;
+		} else
+#endif	/* defined(HAVE_PRI) */
+		{
+			p->owner = NULL;
+		}
 		if (p->sig && (p->sig != SIG_PRI))
 			res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
 		if (res < 0) {
@@ -3233,12 +3260,10 @@
 	p->oprmode = 0;
 	ast->tech_pvt = NULL;
 	ast_mutex_unlock(&p->lock);
-	ast_module_unref(ast_module_info->self);
 	if (option_verbose > 2) 
 		ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
 
 	ast_mutex_lock(&iflock);
-
 	if (p->restartpending) {
 		num_restart_pending--;
 	}
@@ -3257,6 +3282,8 @@
 		}
 	}
 	ast_mutex_unlock(&iflock);
+
+	ast_module_unref(ast_module_info->self);
 	return 0;
 }
 
@@ -4512,27 +4539,30 @@
 		case DAHDI_EVENT_ALARM:
 #ifdef HAVE_PRI
 			if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
-				/* T309 is not enabled : hangup calls when alarm occurs */
+				/* T309 is not enabled : destroy calls when alarm occurs */
 				if (p->call) {
 					if (p->pri && p->pri->pri) {
-						if (!pri_grab(p, p->pri)) {
-							pri_hangup(p->pri->pri, p->call, -1);
-							pri_destroycall(p->pri->pri, p->call);
-							p->call = NULL;
-							pri_rel(p->pri);
-						} else
-							ast_log(LOG_WARNING, "Failed to grab PRI!\n");
+						pri_grab(p, p->pri);
+						pri_destroycall(p->pri->pri, p->call);
+						p->call = NULL;
+						pri_rel(p->pri);
 					} else
 						ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
 				}
 				if (p->owner)
 					p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 			}
-			if (p->bearer)
+			if (p->bearer) {
 				p->bearer->inalarm = 1;
-			else
+				p->bearer->resetting = 0;
+			} else
 #endif
-			p->inalarm = 1;
+			{
+				p->inalarm = 1;
+#if defined(HAVE_PRI)
+				p->resetting = 0;
+#endif	/* defined(HAVE_PRI) */
+			}
 			res = get_alarms(p);
 			handle_alarms(p, res);
 #ifdef HAVE_PRI
@@ -4872,9 +4902,12 @@
 		case DAHDI_EVENT_NOALARM:
 			p->inalarm = 0;
 #ifdef HAVE_PRI
+			p->resetting = 0;
 			/* Extremely unlikely but just in case */
-			if (p->bearer)
+			if (p->bearer) {
 				p->bearer->inalarm = 0;
+				p->bearer->resetting = 0;
+			}
 #endif				
 			if (!p->unknown_alarm) {
 				ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
@@ -5389,14 +5422,27 @@
 
 static struct ast_frame  *dahdi_read(struct ast_channel *ast)
 {
-	struct dahdi_pvt *p = ast->tech_pvt;
+	struct dahdi_pvt *p;
 	int res;
 	int index;
 	void *readbuf;
 	struct ast_frame *f;
 
+	/*
+	 * For analog channels, we must do deadlock avoidance because
+	 * analog ports can have more than one Asterisk channel using
+	 * the same private structure.
+	 */
+	p = ast->tech_pvt;
 	while (ast_mutex_trylock(&p->lock)) {
 		DEADLOCK_AVOIDANCE(&ast->lock);
+
+		/*
+		 * For PRI channels, we must refresh the private pointer because
+		 * the call could move to another B channel while the Asterisk
+		 * channel is unlocked.
+		 */
+		p = ast->tech_pvt;
 	}
 
 	index = dahdi_get_index(ast, p, 0);
@@ -6622,7 +6668,10 @@
                         /* some switches require a minimum guard time between
                            the last FGD wink and something that answers
                            immediately. This ensures it */
-                        if (ast_safe_sleep(chan,100)) goto quit;
+			if (ast_safe_sleep(chan, 100)) {
+				ast_hangup(chan);
+				goto quit;
+			}
 		}
 		dahdi_enable_ec(p);
 		if (NEED_MFDETECT(p)) {
@@ -7614,6 +7663,9 @@
 		break;
 	case DAHDI_EVENT_NOALARM:
 		i->inalarm = 0;
+#if defined(HAVE_PRI)
+		i->resetting = 0;
+#endif	/* defined(HAVE_PRI) */
 		if (!i->unknown_alarm) {
 			ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
 			manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
@@ -7624,6 +7676,9 @@
 		break;
 	case DAHDI_EVENT_ALARM:
 		i->inalarm = 1;
+#if defined(HAVE_PRI)
+		i->resetting = 0;
+#endif	/* defined(HAVE_PRI) */
 		res = get_alarms(i);
 		handle_alarms(i, res);
 		/* fall thru intentionally */
@@ -8509,10 +8564,14 @@
 			/* the dchannel is down so put the channel in alarm */
 			if (tmp->pri && !pri_is_up(tmp->pri)) {
 				tmp->inalarm = 1;
+				tmp->resetting = 0;

[... 4486 lines stripped ...]



More information about the asterisk-commits mailing list