[asterisk-commits] schmidts: branch schmidts/unleash-the-beast r356137 - in /team/schmidts/unlea...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 21 06:14:40 CST 2012


Author: schmidts
Date: Tue Feb 21 06:14:25 2012
New Revision: 356137

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=356137
Log:
resolve conflict, enable automerge

Added:
    team/schmidts/unleash-the-beast/autoconf/ast_c_declare_check.m4
      - copied unchanged from r356107, branches/1.8/autoconf/ast_c_declare_check.m4
Modified:
    team/schmidts/unleash-the-beast/   (props changed)
    team/schmidts/unleash-the-beast/CHANGES
    team/schmidts/unleash-the-beast/UPGRADE.txt
    team/schmidts/unleash-the-beast/addons/chan_ooh323.c
    team/schmidts/unleash-the-beast/apps/app_chanspy.c
    team/schmidts/unleash-the-beast/apps/app_parkandannounce.c
    team/schmidts/unleash-the-beast/apps/app_queue.c
    team/schmidts/unleash-the-beast/apps/app_voicemail.c
    team/schmidts/unleash-the-beast/cdr/cdr_pgsql.c
    team/schmidts/unleash-the-beast/cel/cel_sqlite3_custom.c
    team/schmidts/unleash-the-beast/channels/chan_agent.c
    team/schmidts/unleash-the-beast/channels/chan_dahdi.c
    team/schmidts/unleash-the-beast/channels/chan_iax2.c
    team/schmidts/unleash-the-beast/channels/chan_sip.c
    team/schmidts/unleash-the-beast/channels/sig_analog.c
    team/schmidts/unleash-the-beast/channels/sig_analog.h
    team/schmidts/unleash-the-beast/channels/sig_pri.c
    team/schmidts/unleash-the-beast/channels/sig_pri.h
    team/schmidts/unleash-the-beast/channels/sig_ss7.c
    team/schmidts/unleash-the-beast/channels/sig_ss7.h
    team/schmidts/unleash-the-beast/channels/sip/include/dialog.h
    team/schmidts/unleash-the-beast/channels/sip/include/sip.h
    team/schmidts/unleash-the-beast/configs/cdr_sqlite3_custom.conf.sample
    team/schmidts/unleash-the-beast/configs/extconfig.conf.sample
    team/schmidts/unleash-the-beast/configs/http.conf.sample
    team/schmidts/unleash-the-beast/configs/iax.conf.sample
    team/schmidts/unleash-the-beast/configs/manager.conf.sample
    team/schmidts/unleash-the-beast/configs/sip.conf.sample
    team/schmidts/unleash-the-beast/configure
    team/schmidts/unleash-the-beast/configure.ac
    team/schmidts/unleash-the-beast/contrib/init.d/etc_default_asterisk
    team/schmidts/unleash-the-beast/contrib/realtime/postgresql/realtime.sql
    team/schmidts/unleash-the-beast/formats/format_ogg_vorbis.c
    team/schmidts/unleash-the-beast/funcs/func_cdr.c
    team/schmidts/unleash-the-beast/funcs/func_curl.c
    team/schmidts/unleash-the-beast/funcs/func_odbc.c
    team/schmidts/unleash-the-beast/include/asterisk/audiohook.h
    team/schmidts/unleash-the-beast/include/asterisk/autoconfig.h.in
    team/schmidts/unleash-the-beast/include/asterisk/channel.h
    team/schmidts/unleash-the-beast/include/asterisk/dnsmgr.h
    team/schmidts/unleash-the-beast/include/asterisk/indications.h
    team/schmidts/unleash-the-beast/include/asterisk/manager.h
    team/schmidts/unleash-the-beast/main/audiohook.c
    team/schmidts/unleash-the-beast/main/channel.c
    team/schmidts/unleash-the-beast/main/config.c
    team/schmidts/unleash-the-beast/main/dnsmgr.c
    team/schmidts/unleash-the-beast/main/features.c
    team/schmidts/unleash-the-beast/main/http.c
    team/schmidts/unleash-the-beast/main/indications.c
    team/schmidts/unleash-the-beast/main/manager.c
    team/schmidts/unleash-the-beast/main/netsock.c
    team/schmidts/unleash-the-beast/main/pbx.c
    team/schmidts/unleash-the-beast/main/rtp_engine.c
    team/schmidts/unleash-the-beast/main/taskprocessor.c
    team/schmidts/unleash-the-beast/main/test.c
    team/schmidts/unleash-the-beast/pbx/pbx_config.c
    team/schmidts/unleash-the-beast/pbx/pbx_spool.c
    team/schmidts/unleash-the-beast/res/res_calendar.c
    team/schmidts/unleash-the-beast/res/res_config_pgsql.c
    team/schmidts/unleash-the-beast/res/res_fax.c
    team/schmidts/unleash-the-beast/res/res_monitor.c
    team/schmidts/unleash-the-beast/res/res_odbc.c
    team/schmidts/unleash-the-beast/res/res_pktccops.c
    team/schmidts/unleash-the-beast/res/res_srtp.c
    team/schmidts/unleash-the-beast/res/snmp/agent.c
    team/schmidts/unleash-the-beast/sounds/Makefile

Propchange: team/schmidts/unleash-the-beast/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/schmidts/unleash-the-beast/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Feb 21 06:14:25 2012
@@ -1,1 +1,1 @@
-/branches/1.8:1-352278
+/branches/1.8:1-356136

Modified: team/schmidts/unleash-the-beast/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/CHANGES?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/CHANGES (original)
+++ team/schmidts/unleash-the-beast/CHANGES Tue Feb 21 06:14:25 2012
@@ -29,6 +29,10 @@
    Also, with strictrtp on, Asterisk will now drop all packets until learning
    mode has successfully exited. These changes are based on how pjmedia handles
    media sources and source changes.
+
+FAX changes
+------------
+ * res_fax now has module reload support.
 
 ------------------------------------------------------------------------------
 --- Functionality changes since Asterisk 1.8.7.1 -----------------------------

Modified: team/schmidts/unleash-the-beast/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/UPGRADE.txt?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/UPGRADE.txt (original)
+++ team/schmidts/unleash-the-beast/UPGRADE.txt Tue Feb 21 06:14:25 2012
@@ -20,6 +20,12 @@
 
 From 1.6.2 to 1.8:
 
+* When using TLS with Manager and the HTTP server, the desired port
+  must be specified in the tlsbindaddr setting. If no port is specified,
+  then the default port will be used. See the sample config file to know
+  the default ports. Settings like "sslbindport" and "tlsbindport" have
+  no effect.
+
 * chan_sip no longer sets HASH(SIP_CAUSE,<chan name>) on channels by default.
   This must now be enabled by setting 'sipstorecause' to 'yes' in sip.conf.
   This carries a performance penalty.

Modified: team/schmidts/unleash-the-beast/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/addons/chan_ooh323.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/addons/chan_ooh323.c (original)
+++ team/schmidts/unleash-the-beast/addons/chan_ooh323.c Tue Feb 21 06:14:25 2012
@@ -449,8 +449,11 @@
 			} 
 	 	}
 
-		manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nChanneltype: %s\r\n"
+		if (ch) {
+			manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 
+				"Channel: %s\r\nChanneltype: %s\r\n"
 				"CallRef: %d\r\n", ch->name, "OOH323", i->call_reference);
+		}
 	} else
 		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
 
@@ -854,6 +857,7 @@
 {
 	char dtmf[2];
 	struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
+	int res = 0;
 	
 	if (gH323Debug)
 		ast_verbose("---   ooh323_digit_begin\n");
@@ -882,17 +886,21 @@
 		dtmf[0] = digit;
 		dtmf[1] = '\0';
 		ooSendDTMFDigit(p->callToken, dtmf);
+	} else if (p->dtmfmode & H323_DTMF_INBAND) {
+		res = -1; // tell Asterisk to generate inband indications
 	}
 	ast_mutex_unlock(&p->lock);
-	if (gH323Debug)
-		ast_verbose("+++   ooh323_digit_begin\n");
-
-	return 0;
+	if (gH323Debug) {
+		ast_verbose("+++   ooh323_digit_begin %d\n", res);
+	}
+
+	return res;
 }
 
 static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
 {
 	struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;
+	int res = 0;
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_digit_end\n");
@@ -902,14 +910,18 @@
 		return -1;
 	}
 	ast_mutex_lock(&p->lock);
-	if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) 
+	if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) {
 		ast_rtp_instance_dtmf_end(p->rtp, digit);
+	} else if(p->dtmfmode & H323_DTMF_INBAND) {
+		res = -1; // tell Asterisk to stop inband indications
+	}
 
 	ast_mutex_unlock(&p->lock);
-	if (gH323Debug)
-		ast_verbose("+++   ooh323_digit_end\n");
-
-	return 0;
+	if (gH323Debug) {
+		ast_verbose("+++   ooh323_digit_end, res = %d\n", res);
+	}
+
+	return res;
 }
 
 

Modified: team/schmidts/unleash-the-beast/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/apps/app_chanspy.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/apps/app_chanspy.c (original)
+++ team/schmidts/unleash-the-beast/apps/app_chanspy.c Tue Feb 21 06:14:25 2012
@@ -825,11 +825,13 @@
 		}
 
 		if (!iter) {
-			return -1;
+			res = -1;
+			goto exit;
 		}
 
 		res = ast_waitfordigit(chan, waitms);
 		if (res < 0) {
+			iter = ast_channel_iterator_destroy(iter);
 			ast_clear_flag(chan, AST_FLAG_SPYING);
 			break;
 		}
@@ -837,10 +839,12 @@
 			char tmp[2];
 			tmp[0] = res;
 			tmp[1] = '\0';
-			if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
+			if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
+				iter = ast_channel_iterator_destroy(iter);
 				goto exit;
-			else
+			} else {
 				ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
+			}
 		}
 
 		/* reset for the next loop around, unless overridden later */
@@ -979,10 +983,12 @@
 
 			if (res == -1) {
 				ast_autochan_destroy(autochan);
+				iter = ast_channel_iterator_destroy(iter);
 				goto exit;
 			} else if (res == -2) {
 				res = 0;
 				ast_autochan_destroy(autochan);
+				iter = ast_channel_iterator_destroy(iter);
 				goto exit;
 			} else if (res > 1 && spec) {
 				struct ast_channel *next;
@@ -1002,6 +1008,7 @@
 					}
 				}
 			} else if (res == 0 && ast_test_flag(flags, OPTION_EXITONHANGUP)) {
+				iter = ast_channel_iterator_destroy(iter);
 				goto exit;
 			}
 		}

Modified: team/schmidts/unleash-the-beast/apps/app_parkandannounce.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/apps/app_parkandannounce.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/apps/app_parkandannounce.c (original)
+++ team/schmidts/unleash-the-beast/apps/app_parkandannounce.c Tue Feb 21 06:14:25 2012
@@ -140,6 +140,7 @@
 	}
 
 	/* Save the CallerID because the masquerade turns chan into a ZOMBIE. */
+	ast_party_id_init(&caller_id);
 	ast_channel_lock(chan);
 	ast_party_id_copy(&caller_id, &chan->caller.id);
 	ast_channel_unlock(chan);

Modified: team/schmidts/unleash-the-beast/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/apps/app_queue.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/apps/app_queue.c (original)
+++ team/schmidts/unleash-the-beast/apps/app_queue.c Tue Feb 21 06:14:25 2012
@@ -1395,9 +1395,9 @@
 				ast_debug(4, "%s is unavailable because it has only been %d seconds since his last call (wrapup time is %d)\n", member->membername, (int) (time(NULL) - member->lastcall), q->wrapuptime);
 				break;
 			} else {
-				ao2_unlock(q);
 				ao2_ref(member, -1);
 				ao2_iterator_destroy(&mem_iter);
+				ao2_unlock(q);
 				ast_debug(4, "%s is available.\n", member->membername);
 				return 0;
 			}
@@ -4435,24 +4435,24 @@
 		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
 		if (!tmp) {
 			ao2_ref(cur, -1);
+			ao2_iterator_destroy(&memi);
 			ao2_unlock(qe->parent);
-			ao2_iterator_destroy(&memi);
 			goto out;
 		}
 		if (!datastore) {
 			if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
+				callattempt_free(tmp);
 				ao2_ref(cur, -1);
+				ao2_iterator_destroy(&memi);
 				ao2_unlock(qe->parent);
-				ao2_iterator_destroy(&memi);
-				callattempt_free(tmp);
 				goto out;
 			}
 			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
 			if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
+				callattempt_free(tmp);
 				ao2_ref(cur, -1);
+				ao2_iterator_destroy(&memi);
 				ao2_unlock(&qe->parent);
-				ao2_iterator_destroy(&memi);
-				callattempt_free(tmp);
 				goto out;
 			}
 			datastore->data = dialed_interfaces;
@@ -4476,6 +4476,7 @@
 
 		if (di) {
 			callattempt_free(tmp);
+			ao2_ref(cur, -1);
 			continue;
 		}
 
@@ -4485,10 +4486,10 @@
 		 * it won't call one that has already been called. */
 		if (strncasecmp(cur->interface, "Local/", 6)) {
 			if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
+				callattempt_free(tmp);
 				ao2_ref(cur, -1);
+				ao2_iterator_destroy(&memi);
 				ao2_unlock(qe->parent);
-				ao2_iterator_destroy(&memi);
-				callattempt_free(tmp);
 				goto out;
 			}
 			strcpy(di->interface, cur->interface);
@@ -6313,9 +6314,10 @@
 
 	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Find for QUEUE_MEMBER_LIST()"))) {
 		int buflen = 0, count = 0;
-		struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
+		struct ao2_iterator mem_iter;
 
 		ao2_lock(q);
+		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((m = ao2_iterator_next(&mem_iter))) {
 			/* strcat() is always faster than printf() */
 			if (count++) {
@@ -6821,7 +6823,9 @@
 static int clear_stats(const char *queuename)
 {
 	struct call_queue *q;
-	struct ao2_iterator queue_iter = ao2_iterator_init(queues, 0);
+	struct ao2_iterator queue_iter;
+
+	queue_iter = ao2_iterator_init(queues, 0);
 	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename))
@@ -6909,8 +6913,8 @@
 		}
 	}
 
+	ao2_lock(queues);
 	queue_iter = ao2_iterator_init(queues, AO2_ITERATOR_DONTLOCK);
-	ao2_lock(queues);
 	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		float sl;
 		struct call_queue *realtime_queue = NULL;
@@ -7610,11 +7614,11 @@
 		while ((m = ao2_iterator_next(&mem_iter))) {
 			if (!strncasecmp(word, m->membername, wordlen) && ++which > state) {
 				char *tmp;
-				ao2_unlock(q);
 				tmp = ast_strdup(m->interface);
 				ao2_ref(m, -1);
+				ao2_iterator_destroy(&mem_iter);
+				ao2_unlock(q);
 				queue_t_unref(q, "Done with iterator, returning interface name");
-				ao2_iterator_destroy(&mem_iter);
 				ao2_iterator_destroy(&queue_iter);
 				return tmp;
 			}
@@ -8156,6 +8160,7 @@
 
 		ao2_ref(member, -1);
 	}
+	ao2_iterator_destroy(&im);
 
 	/* include the callers inside the result. */
 	if (queue->head) {

Modified: team/schmidts/unleash-the-beast/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/apps/app_voicemail.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/apps/app_voicemail.c (original)
+++ team/schmidts/unleash-the-beast/apps/app_voicemail.c Tue Feb 21 06:14:25 2012
@@ -1824,7 +1824,7 @@
 	struct vm_state *vms_p;
 	char *file, *filename;
 	char *attachment;
-	int ret = 0, i;
+	int i;
 	BODY *body;
 
 	/* This function is only used for retrieval of IMAP greetings
@@ -1854,12 +1854,12 @@
 			return -1;
 		}
 	}
-	
+
 	/* Greetings will never have a prepended message */
 	*vms_p->introfn = '\0';
 
 	ast_mutex_lock(&vms_p->lock);
-	ret = init_mailstream(vms_p, GREETINGS_FOLDER);
+	init_mailstream(vms_p, GREETINGS_FOLDER);
 	if (!vms_p->mailstream) {
 		ast_log(AST_LOG_ERROR, "IMAP mailstream is NULL\n");
 		ast_mutex_unlock(&vms_p->lock);
@@ -6850,9 +6850,6 @@
 static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts,
 			char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag)
 {
-#ifdef IMAP_STORAGE
-	int res;
-#endif
 	int cmd = 0;
 	int retries = 0, prepend_duration = 0, already_recorded = 0;
 	char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
@@ -6889,9 +6886,9 @@
 			/* Record new intro file */
 			make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg);
 			strncat(vms->introfn, "intro", sizeof(vms->introfn));
-			res = ast_play_and_wait(chan, INTRO);
-			res = ast_play_and_wait(chan, "beep");
-			res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag);
+			ast_play_and_wait(chan, INTRO);
+			ast_play_and_wait(chan, "beep");
+			play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag);
 			cmd = 't';
 #else
 
@@ -6907,7 +6904,7 @@
 				cmd = 0;
 				break;
 			}
-			
+
 			/* Back up the original file, so we can retry the prepend and restore it after forward. */
 #ifndef IMAP_STORAGE
 			if (already_recorded) {
@@ -8030,11 +8027,11 @@
 #endif
 
 done:
-	if (vms->deleted && vmu->maxmsg) {
-		memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int));
-	}
-	if (vms->heard && vmu->maxmsg) {
-		memset(vms->heard, 0, vms->dh_arraysize * sizeof(int));
+	if (vms->deleted) {
+		ast_free(vms->deleted);
+	}
+	if (vms->heard) {
+		ast_free(vms->heard);
 	}
 
 	return 0;
@@ -10023,17 +10020,6 @@
 	vmstate_insert(&vms);
 	init_vm_state(&vms);
 #endif
-	/* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */
-	if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) {
-		ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n");
-		cmd = ast_play_and_wait(chan, "an-error-has-occured");
-		return -1;
-	}
-	if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) {
-		ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n");
-		cmd = ast_play_and_wait(chan, "an-error-has-occured");
-		return -1;
-	}
 	
 	/* Set language from config to override channel language */
 	if (!ast_strlen_zero(vmu->language))
@@ -10616,10 +10602,6 @@
 #endif
 	if (vmu)
 		free_user(vmu);
-	if (vms.deleted)
-		ast_free(vms.deleted);
-	if (vms.heard)
-		ast_free(vms.heard);
 
 #ifdef IMAP_STORAGE
 	pthread_setspecific(ts_vmstate.key, NULL);

Modified: team/schmidts/unleash-the-beast/cdr/cdr_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/cdr/cdr_pgsql.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/cdr/cdr_pgsql.c (original)
+++ team/schmidts/unleash-the-beast/cdr/cdr_pgsql.c Tue Feb 21 06:14:25 2012
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2003 - 2006
+ * Copyright (C) 2003 - 2012
  *
  * Matthew D. Hardeman <mhardemn at papersoft.com>
  * Adapted from the MySQL CDR logger originally by James Sharp
@@ -81,6 +81,7 @@
 						ast_free(sql);                                    \
 						ast_free(sql2);                                   \
 						AST_RWLIST_UNLOCK(&psql_columns);                 \
+						ast_mutex_unlock(&pgsql_lock);                    \
 						return -1;                                        \
 					}                                                     \
 				}                                                         \
@@ -94,6 +95,7 @@
 						ast_free(sql);                    \
 						ast_free(sql2);                   \
 						AST_RWLIST_UNLOCK(&psql_columns); \
+						ast_mutex_unlock(&pgsql_lock);    \
 						return -1;                        \
 					}                                     \
 				}                                         \
@@ -132,14 +134,10 @@
 		struct ast_str *sql = ast_str_create(maxsize), *sql2 = ast_str_create(maxsize2);
 		char buf[257], escapebuf[513], *value;
 		int first = 1;
-  
+
 		if (!sql || !sql2) {
-			if (sql) {
-				ast_free(sql);
-			}
-			if (sql2) {
-				ast_free(sql2);
-			}
+			ast_free(sql);
+			ast_free(sql2);
 			return -1;
 		}
 
@@ -270,9 +268,10 @@
 				}
 			}
 			first = 0;
-  		}
+		}
+
+		LENGTHEN_BUF1(ast_str_strlen(sql2) + 2);
 		AST_RWLIST_UNLOCK(&psql_columns);
-		LENGTHEN_BUF1(ast_str_strlen(sql2) + 2);
 		ast_str_append(&sql, 0, ")%s)", ast_str_buffer(sql2));
 		ast_verb(11, "[%s]\n", ast_str_buffer(sql));
 
@@ -334,44 +333,34 @@
 	return 0;
 }
 
-static int unload_module(void)
+/* This function should be called without holding the pgsql_columns lock */
+static void empty_columns(void)
 {
 	struct columns *current;
-
-	ast_cdr_unregister(name);
-
-	PQfinish(conn);
-
-	if (pghostname) {
-		ast_free(pghostname);
-	}
-	if (pgdbname) {
-		ast_free(pgdbname);
-	}
-	if (pgdbuser) {
-		ast_free(pgdbuser);
-	}
-	if (pgpassword) {
-		ast_free(pgpassword);
-	}
-	if (pgdbport) {
-		ast_free(pgdbport);
-	}
-	if (table) {
-		ast_free(table);
-	}
-	if (encoding) {
-		ast_free(encoding);
-	}
-	if (tz) {
-		ast_free(tz);
-	}
-
 	AST_RWLIST_WRLOCK(&psql_columns);
 	while ((current = AST_RWLIST_REMOVE_HEAD(&psql_columns, list))) {
 		ast_free(current);
 	}
 	AST_RWLIST_UNLOCK(&psql_columns);
+
+}
+
+static int unload_module(void)
+{
+	ast_cdr_unregister(name);
+
+	PQfinish(conn);
+
+	ast_free(pghostname);
+	ast_free(pgdbname);
+	ast_free(pgdbuser);
+	ast_free(pgpassword);
+	ast_free(pgdbport);
+	ast_free(table);
+	ast_free(encoding);
+	ast_free(tz);
+
+	empty_columns();
 
 	return 0;
 }
@@ -389,12 +378,18 @@
 	if ((cfg = ast_config_load(config, config_flags)) == NULL || cfg == CONFIG_STATUS_FILEINVALID) {
 		ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
 		return -1;
-	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
+	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
 		return 0;
+	}
+
+	ast_mutex_lock(&pgsql_lock);
 
 	if (!(var = ast_variable_browse(cfg, "global"))) {
 		ast_config_destroy(cfg);
-		return 0;
+		ast_mutex_unlock(&pgsql_lock);
+		ast_log(LOG_NOTICE, "cdr_pgsql configuration contains no global section, skipping module %s.\n",
+			reload ? "reload" : "load");
+		return -1;
 	}
 
 	if (!(tmp = ast_variable_retrieve(cfg, "global", "hostname"))) {
@@ -402,10 +397,10 @@
 		tmp = "";	/* connect via UNIX-socket by default */
 	}
 
-	if (pghostname)
-		ast_free(pghostname);
+	ast_free(pghostname);
 	if (!(pghostname = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -414,10 +409,10 @@
 		tmp = "asteriskcdrdb";
 	}
 
-	if (pgdbname)
-		ast_free(pgdbname);
+	ast_free(pgdbname);
 	if (!(pgdbname = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -426,10 +421,10 @@
 		tmp = "asterisk";
 	}
 
-	if (pgdbuser)
-		ast_free(pgdbuser);
+	ast_free(pgdbuser);
 	if (!(pgdbuser = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -438,10 +433,10 @@
 		tmp = "";
 	}
 
-	if (pgpassword)
-		ast_free(pgpassword);
+	ast_free(pgpassword);
 	if (!(pgpassword = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -450,10 +445,10 @@
 		tmp = "5432";
 	}
 
-	if (pgdbport)
-		ast_free(pgdbport);
+	ast_free(pgdbport);
 	if (!(pgdbport = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -462,10 +457,10 @@
 		tmp = "cdr";
 	}
 
-	if (table)
-		ast_free(table);
+	ast_free(table);
 	if (!(table = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -474,11 +469,10 @@
 		tmp = "LATIN9";
 	}
 
-	if (encoding) {
-		ast_free(encoding);
-	}
+	ast_free(encoding);
 	if (!(encoding = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -486,12 +480,12 @@
 		tmp = "";
 	}
 
-	if (tz) {
-		ast_free(tz);
-		tz = NULL;
-	}
+	ast_free(tz);
+	tz = NULL;
+
 	if (!ast_strlen_zero(tmp) && !(tz = ast_strdup(tmp))) {
 		ast_config_destroy(cfg);
+		ast_mutex_unlock(&pgsql_lock);
 		return -1;
 	}
 
@@ -577,6 +571,7 @@
 			ast_log(LOG_ERROR, "Failed to query database columns: %s\n", pgerror);
 			PQclear(result);
 			unload_module();
+			ast_mutex_unlock(&pgsql_lock);
 			return AST_MODULE_LOAD_DECLINE;
 		}
 
@@ -585,8 +580,12 @@
 			ast_log(LOG_ERROR, "cdr_pgsql: Failed to query database columns. No columns found, does the table exist?\n");
 			PQclear(result);
 			unload_module();
+			ast_mutex_unlock(&pgsql_lock);
 			return AST_MODULE_LOAD_DECLINE;
 		}
+
+		/* Clear out the columns list. */
+		empty_columns();
 
 		for (i = 0; i < rows; i++) {
 			fname = PQgetvalue(result, i, 0);
@@ -616,7 +615,9 @@
 				} else {
 					cur->hasdefault = 0;
 				}
+				AST_RWLIST_WRLOCK(&psql_columns);
 				AST_RWLIST_INSERT_TAIL(&psql_columns, cur, list);
+				AST_RWLIST_UNLOCK(&psql_columns);
 			}
 		}
 		PQclear(result);
@@ -629,12 +630,17 @@
 
 	ast_config_destroy(cfg);
 
-	return ast_cdr_register(name, ast_module_info->description, pgsql_log);
+	ast_mutex_unlock(&pgsql_lock);
+	return 0;
 }
 
 static int load_module(void)
 {
-	return config_module(0) ? AST_MODULE_LOAD_DECLINE : 0;
+	if (config_module(0)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	return ast_cdr_register(name, ast_module_info->description, pgsql_log)
+		? AST_MODULE_LOAD_DECLINE : 0;
 }
 
 static int reload(void)

Modified: team/schmidts/unleash-the-beast/cel/cel_sqlite3_custom.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/cel/cel_sqlite3_custom.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/cel/cel_sqlite3_custom.c (original)
+++ team/schmidts/unleash-the-beast/cel/cel_sqlite3_custom.c Tue Feb 21 06:14:25 2012
@@ -353,7 +353,7 @@
 
 	ast_mutex_lock(&lock);
 	res = load_config(1);
-	ast_mutex_lock(&lock);
+	ast_mutex_unlock(&lock);
 
 	return res;
 }

Modified: team/schmidts/unleash-the-beast/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/channels/chan_agent.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/channels/chan_agent.c (original)
+++ team/schmidts/unleash-the-beast/channels/chan_agent.c Tue Feb 21 06:14:25 2012
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2012, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *
@@ -375,6 +375,43 @@
 };
 
 /*!
+ * \brief Locks the owning channel for a LOCKED pvt while obeying locking order. The pvt
+ * must enter this function locked and will be returned locked, but this function will
+ * unlock the pvt for a short time, so it can't be used while expecting the pvt to remain
+ * static. If function returns a non NULL channel, it will need to be unlocked and
+ * unrefed once it is no longer needed.
+ *
+ * \param pvt Pointer to the LOCKED agent_pvt for which the owner is needed
+ * \ret locked channel which owns the pvt at the time of completion. NULL if not available.
+ */
+static struct ast_channel *agent_lock_owner(struct agent_pvt *pvt)
+{
+	struct ast_channel *owner;
+
+	for (;;) {
+		if (!pvt->owner) { /* No owner. Nothing to do. */
+			return NULL;
+		}
+
+		/* If we don't ref the owner, it could be killed when we unlock the pvt. */
+		owner = ast_channel_ref(pvt->owner);
+
+		/* Locking order requires us to lock channel, then pvt. */
+		ast_mutex_unlock(&pvt->lock);
+		ast_channel_lock(owner);
+		ast_mutex_lock(&pvt->lock);
+
+		/* Check if owner changed during pvt unlock period */
+		if (owner != pvt->owner) { /* Channel changed. Unref and do another pass. */
+			ast_channel_unlock(owner);
+			owner = ast_channel_unref(owner);
+		} else { /* Channel stayed the same. Return it. */
+			return owner;
+		}
+	}
+}
+
+/*!
  * Adds an agent to the global list of agents.
  *
  * \param agent A string with the username, password and real name of an agent. As defined in agents.conf. Example: "13,169,John Smith"
@@ -554,7 +591,11 @@
 	struct ast_frame *f = NULL;
 	static struct ast_frame answer_frame = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
 	int cur_time = time(NULL);
+	struct ast_channel *owner;
+
 	ast_mutex_lock(&p->lock);
+	owner = agent_lock_owner(p);
+
 	CHECK_FORMATS(ast, p);
 	if (!p->start) {
 		p->start = cur_time;
@@ -584,13 +625,11 @@
 			int howlong = cur_time - p->start;
 			if (p->autologoff && (howlong >= p->autologoff)) {
 				ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
-				if (p->owner || p->chan) {
-					while (p->owner && ast_channel_trylock(p->owner)) {
-						DEADLOCK_AVOIDANCE(&p->lock);
-					}
-					if (p->owner) {
-						ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
-						ast_channel_unlock(p->owner);
+				if (owner || p->chan) {
+					if (owner) {
+						ast_softhangup(owner, AST_SOFTHANGUP_EXPLICIT);
+						ast_channel_unlock(owner);
+						owner = ast_channel_unref(owner);
 					}
 
 					while (p->chan && ast_channel_trylock(p->chan)) {
@@ -652,6 +691,11 @@
 		}
 	}
 
+	if (owner) {
+		ast_channel_unlock(owner);
+		owner = ast_channel_unref(owner);
+	}
+
 	CLEANUP(ast,p);
 	if (p->chan && !p->chan->_bridge) {
 		if (strcasecmp(p->chan->tech->type, "Local")) {
@@ -887,6 +931,14 @@
 static int agent_hangup(struct ast_channel *ast)
 {
 	struct agent_pvt *p = ast->tech_pvt;
+	struct ast_channel *indicate_chan = NULL;
+	char *tmp_moh; /* moh buffer for indicating after unlocking p */
+
+	if (p->pending) {
+		AST_LIST_LOCK(&agents);
+		AST_LIST_REMOVE(&agents, p, list);
+		AST_LIST_UNLOCK(&agents);
+	}
 
 	ast_mutex_lock(&p->lock);
 	p->owner = NULL;
@@ -909,7 +961,7 @@
 	if (p->start && (ast->_state != AST_STATE_UP)) {
 		p->start = 0;
 	} else
-		p->start = 0; 
+		p->start = 0;
 	if (p->chan) {
 		p->chan->_bridge = NULL;
 		/* If they're dead, go ahead and hang up on the agent now */
@@ -918,14 +970,20 @@
 			ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
 			ast_channel_unlock(p->chan);
 		} else if (p->loginstart) {
-			ast_channel_lock(p->chan);
-			ast_indicate_data(p->chan, AST_CONTROL_HOLD, 
-				S_OR(p->moh, NULL),
-				!ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
-			ast_channel_unlock(p->chan);
+			indicate_chan = ast_channel_ref(p->chan);
+			tmp_moh = ast_strdupa(p->moh);
 		}
 	}
 	ast_mutex_unlock(&p->lock);
+
+	if (indicate_chan) {
+		ast_channel_lock(indicate_chan);
+		ast_indicate_data(indicate_chan, AST_CONTROL_HOLD,
+			S_OR(tmp_moh, NULL),
+			!ast_strlen_zero(tmp_moh) ? strlen(tmp_moh) + 1 : 0);
+		ast_channel_unlock(indicate_chan);
+		indicate_chan = ast_channel_unref(indicate_chan);
+	}
 
 	/* Only register a device state change if the agent is still logged in */
 	if (!p->loginstart) {
@@ -934,11 +992,6 @@
 		ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
 	}
 
-	if (p->pending) {
-		AST_LIST_LOCK(&agents);
-		AST_LIST_REMOVE(&agents, p, list);
-		AST_LIST_UNLOCK(&agents);
-	}
 	if (p->abouttograb) {
 		/* Let the "about to grab" thread know this isn't valid anymore, and let it
 		   kill it later */
@@ -1491,6 +1544,8 @@
 /*!
  * Lists agents and their status to the Manager API.
  * It is registered on load_module() and it gets called by the manager backend.
+ * This function locks both the pvt and the channel that owns it for a while, but
+ * does not keep these locks.
  * \param s
  * \param m
  * \returns 
@@ -1513,7 +1568,9 @@
 	astman_send_ack(s, m, "Agents will follow");
 	AST_LIST_LOCK(&agents);
 	AST_LIST_TRAVERSE(&agents, p, list) {
-        	ast_mutex_lock(&p->lock);
+		struct ast_channel *owner;
+		ast_mutex_lock(&p->lock);
+		owner = agent_lock_owner(p);
 
 		/* Status Values:
 		   AGENT_LOGGEDOFF - Agent isn't logged in
@@ -1528,16 +1585,14 @@
 
 		if (p->chan) {
 			loginChan = ast_strdupa(p->chan->name);
-			if (p->owner && p->owner->_bridge) {
+			if (owner && owner->_bridge) {
 				talkingto = S_COR(p->chan->caller.id.number.valid,
 					p->chan->caller.id.number.str, "n/a");
-				ast_channel_lock(p->owner);
-				if ((bridge = ast_bridged_channel(p->owner))) {
+				if ((bridge = ast_bridged_channel(owner))) {
 					talkingtoChan = ast_strdupa(bridge->name);
 				} else {
 					talkingtoChan = "n/a";
 				}
-				ast_channel_unlock(p->owner);
 				status = "AGENT_ONCALL";
 			} else {
 				talkingto = "n/a";
@@ -1549,6 +1604,11 @@
 			talkingto = "n/a";
 			talkingtoChan = "n/a";
 			status = "AGENT_LOGGEDOFF";
+		}
+
+		if (owner) {
+			ast_channel_unlock(owner);
+			owner = ast_channel_unref(owner);
 		}
 
 		astman_append(s, "Event: Agents\r\n"
@@ -1582,14 +1642,14 @@
 			ret = 0;
 			if (p->owner || p->chan) {
 				if (!soft) {
+					struct ast_channel *owner;
 					ast_mutex_lock(&p->lock);
-
-					while (p->owner && ast_channel_trylock(p->owner)) {
-						DEADLOCK_AVOIDANCE(&p->lock);
-					}
-					if (p->owner) {
-						ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
-						ast_channel_unlock(p->owner);
+					owner = agent_lock_owner(p);
+
+					if (owner) {
+						ast_softhangup(owner, AST_SOFTHANGUP_EXPLICIT);
+						ast_channel_unlock(owner);
+						owner = ast_channel_unref(owner);
 					}
 
 					while (p->chan && ast_channel_trylock(p->chan)) {
@@ -1726,7 +1786,9 @@
 
 	AST_LIST_LOCK(&agents);
 	AST_LIST_TRAVERSE(&agents, p, list) {
+		struct ast_channel *owner;
 		ast_mutex_lock(&p->lock);
+		owner = agent_lock_owner(p);
 		if (p->pending) {
 			if (p->group)
 				ast_cli(a->fd, "-- Pending call to group %d\n", powerof(p->group));
@@ -1739,10 +1801,11 @@
 				username[0] = '\0';
 			if (p->chan) {
 				snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
-				if (p->owner && ast_bridged_channel(p->owner))
+				if (owner && ast_bridged_channel(owner)) {
 					snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
-				 else 
+				} else {
 					strcpy(talkingto, " is idle");
+				}
 				online_agents++;
 			} else {
 				strcpy(location, "not logged in");
@@ -1755,6 +1818,11 @@
 				username, location, talkingto, music);
 			count_agents++;
 		}
+
+		if (owner) {
+			ast_channel_unlock(owner);
+			owner = ast_channel_unref(owner);
+		}
 		ast_mutex_unlock(&p->lock);
 	}
 	AST_LIST_UNLOCK(&agents);
@@ -1795,21 +1863,32 @@
 
 	AST_LIST_LOCK(&agents);
 	AST_LIST_TRAVERSE(&agents, p, list) {
+		struct ast_channel *owner;
+
 		agent_status = 0;       /* reset it to offline */
 		ast_mutex_lock(&p->lock);
+		owner = agent_lock_owner(p);
+
 		if (!ast_strlen_zero(p->name))
 			snprintf(username, sizeof(username), "(%s) ", p->name);
 		else
 			username[0] = '\0';
 		if (p->chan) {
 			snprintf(location, sizeof(location), "logged in on %s", p->chan->name);
-			if (p->owner && ast_bridged_channel(p->owner)) 
-				snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(p->owner)->name);
-			else 
+			if (owner && ast_bridged_channel(owner)) {
+				snprintf(talkingto, sizeof(talkingto), " talking to %s", ast_bridged_channel(owner)->name);
+			} else {
 				strcpy(talkingto, " is idle");
+			}
 			agent_status = 1;
 			online_agents++;
 		}
+
+		if (owner) {
+			ast_channel_unlock(owner);
+			owner = ast_channel_unref(owner);
+		}
+
 		if (!ast_strlen_zero(p->moh))
 			snprintf(music, sizeof(music), " (musiconhold is '%s')", p->moh);
 		if (agent_status)
@@ -2381,12 +2460,16 @@
 
 	AST_LIST_LOCK(&agents);
 	AST_LIST_TRAVERSE(&agents, p, list) {
+		struct ast_channel *owner;
+
 		data_agent = ast_data_add_node(data_root, "agent");
 		if (!data_agent) {
 			continue;
 		}
 
 		ast_mutex_lock(&p->lock);
+		owner = agent_lock_owner(p);
+
 		if (!(p->pending)) {
 			ast_data_add_str(data_agent, "id", p->agent);
 			ast_data_add_structure(agent_pvt, data_agent, p);
@@ -2397,17 +2480,25 @@
 				if (!data_channel) {
 					ast_mutex_unlock(&p->lock);
 					ast_data_remove_node(data_root, data_agent);
+					if (owner) {
+						ast_channel_unlock(owner);
+						owner = ast_channel_unref(owner);
+					}
 					continue;
 				}
 				ast_channel_data_add_structure(data_channel, p->chan, 0);
-				if (p->owner && ast_bridged_channel(p->owner)) {
+				if (owner && ast_bridged_channel(owner)) {
 					data_talkingto = ast_data_add_node(data_agent, "talkingto");
 					if (!data_talkingto) {
 						ast_mutex_unlock(&p->lock);
 						ast_data_remove_node(data_root, data_agent);
+						if (owner) {
+							ast_channel_unlock(owner);
+							owner = ast_channel_unref(owner);
+						}
 						continue;
 					}
-					ast_channel_data_add_structure(data_talkingto, ast_bridged_channel(p->owner), 0);
+					ast_channel_data_add_structure(data_talkingto, ast_bridged_channel(owner), 0);
 				}
 			} else {
 				ast_data_add_node(data_agent, "talkingto");
@@ -2415,6 +2506,12 @@
 			}
 			ast_data_add_str(data_agent, "musiconhold", p->moh);
 		}
+
+		if (owner) {
+			ast_channel_unlock(owner);
+			owner = ast_channel_unref(owner);
+		}
+
 		ast_mutex_unlock(&p->lock);
 
 		/* if this agent doesn't match remove the added agent. */

Modified: team/schmidts/unleash-the-beast/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/channels/chan_dahdi.c?view=diff&rev=356137&r1=356136&r2=356137
==============================================================================
--- team/schmidts/unleash-the-beast/channels/chan_dahdi.c (original)
+++ team/schmidts/unleash-the-beast/channels/chan_dahdi.c Tue Feb 21 06:14:25 2012
@@ -1733,7 +1733,7 @@
 			if (num)
 				ast_copy_string(numbuf, num, ANALOG_MAX_CID);
 
-			ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
+			ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
 			return 0;
 		}
 	}
@@ -2240,6 +2240,13 @@
 	p->dialing = is_dialing;
 }
 
+static void my_set_outgoing(void *pvt, int is_outgoing)
+{
+	struct dahdi_pvt *p = pvt;
+
+	p->outgoing = is_outgoing;
+}
+
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
 static void my_set_digital(void *pvt, int is_digital)
 {
@@ -2640,6 +2647,39 @@
 	if (pvt->dsp_features && pvt->dsp) {
 		ast_dsp_set_features(pvt->dsp, pvt->dsp_features);
 		pvt->dsp_features = 0;
+	}
+}
+#endif	/* defined(HAVE_PRI) */
+
+#if defined(HAVE_PRI)
+/*!
+ * \internal
+ * \brief Ask DAHDI to dial the given dial string.
+ * \since 1.8.11
+ *
+ * \param p Channel private control structure.
+ * \param dial_string String to pass to DAHDI to dial.
+ *
+ * \note The channel private lock needs to be held when calling.
+ *
+ * \return Nothing
+ */
+static void my_pri_dial_digits(void *p, const char *dial_string)
+{
+	struct dahdi_dialoperation zo = {
+		.op = DAHDI_DIAL_OP_APPEND,
+	};
+	struct dahdi_pvt *pvt = p;
+	int res;
+
+	snprintf(zo.dialstr, sizeof(zo.dialstr), "T%s", dial_string);
+	ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", pvt->channel, zo.dialstr);
+	res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
+	if (res) {
+		ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
+			pvt->channel, dial_string, strerror(errno));
+	} else {
+		pvt->dialing = 1;
 	}
 }
 #endif	/* defined(HAVE_PRI) */
@@ -3329,6 +3369,7 @@
 	.fixup_chans = my_pri_fixup_chans,
 	.set_alarm = my_set_alarm,
 	.set_dialing = my_set_dialing,
+	.set_outgoing = my_set_outgoing,
 	.set_digital = my_set_digital,
 	.set_callerid = my_set_callerid,
 	.set_dnid = my_set_dnid,
@@ -3342,6 +3383,7 @@
 	.update_span_devstate = dahdi_pri_update_span_devstate,
 	.module_ref = my_module_ref,
 	.module_unref = my_module_unref,
+	.dial_digits = my_pri_dial_digits,

[... 5427 lines stripped ...]



More information about the asterisk-commits mailing list