Index: channels/chan_dahdi.c
===================================================================
--- channels/chan_dahdi.c	(revision 234818)
+++ channels/chan_dahdi.c	(working copy)
@@ -10366,6 +10366,21 @@
 }
 
 
+static int pri_find_principle_by_call(struct dahdi_pri *pri, q931_call *call)
+{
+	int x;
+	int principle = -1;
+
+	for (x = 0; x < pri->numchans; x++) {
+		if (pri->pvts[x] && (pri->pvts[x]->call == call)) {
+			principle = x;
+			break;
+		}
+	}
+	
+	return principle;
+}
+
 static int pri_find_principle(struct dahdi_pri *pri, int channel)
 {
 	int x;
@@ -10443,8 +10458,13 @@
 				/* Copy any DSP that may be present */
 				new->dsp = old->dsp;
 				new->dsp_features = old->dsp_features;
+				new->alreadyhungup = old->alreadyhungup;
+				new->dialing = old->dialing;
+
 				old->dsp = NULL;
 				old->dsp_features = 0;
+				old->alreadyhungup = 0;
+				old->dialing = 0;
 			}
 			return principle;
 		}
@@ -11552,173 +11572,161 @@
 				}
 				break;				
 			case PRI_EVENT_HANGUP:
-				chanpos = pri_find_principle(pri, e->hangup.channel);
+				chanpos = pri_find_principle_by_call(pri, e->hangup.call);
 				if (chanpos < 0) {
-					ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
+					ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d.  Hanging up anyway\n", 
 						PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+					pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
 				} else {
-					chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
-					if (chanpos > -1) {
-						ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						if (!pri->pvts[chanpos]->alreadyhungup) {
-							/* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
-							pri->pvts[chanpos]->alreadyhungup = 1;
-							if (pri->pvts[chanpos]->realcall) 
-								pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
-							else if (pri->pvts[chanpos]->owner) {
-								/* Queue a BUSY instead of a hangup if our cause is appropriate */
-								pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-								switch (pri->pvts[chanpos]->owner->_state) {
-								case AST_STATE_BUSY:
-								case AST_STATE_UP:
-									pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+					ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					if (!pri->pvts[chanpos]->alreadyhungup) {
+						/* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
+						pri->pvts[chanpos]->alreadyhungup = 1;
+						if (pri->pvts[chanpos]->realcall) 
+							pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
+						else if (pri->pvts[chanpos]->owner) {
+							/* Queue a BUSY instead of a hangup if our cause is appropriate */
+							pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
+							switch (pri->pvts[chanpos]->owner->_state) {
+							case AST_STATE_BUSY:
+							case AST_STATE_UP:
+								pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+								break;
+							default:
+								switch (e->hangup.cause) {
+								case PRI_CAUSE_USER_BUSY:
+									pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
 									break;
+								case PRI_CAUSE_CALL_REJECTED:
+								case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
+								case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+								case PRI_CAUSE_SWITCH_CONGESTION:
+								case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
+								case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
+									pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
+									break;
 								default:
-									switch (e->hangup.cause) {
-									case PRI_CAUSE_USER_BUSY:
-										pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
-										break;
-									case PRI_CAUSE_CALL_REJECTED:
-									case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
-									case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
-									case PRI_CAUSE_SWITCH_CONGESTION:
-									case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
-									case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
-										pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
-										break;
-									default:
-										pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-									}
-									break;
+									pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 								}
+								break;
 							}
-							ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n",
-									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
-						} else {
-							pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
-							pri->pvts[chanpos]->call = NULL;
 						}
-						if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-							ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n",
-									PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-							pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-							pri->pvts[chanpos]->resetting = 1;
-						}
-						if (e->hangup.aoc_units > -1)
-							ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
-									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
+						ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n",
+								pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
+					} else {
+						pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
+						pri->pvts[chanpos]->call = NULL;
+					}
+					if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
+						ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n",
+								PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+						pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
+						pri->pvts[chanpos]->resetting = 1;
+					}
+					if (e->hangup.aoc_units > -1)
+						ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
+								pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
 
 #ifdef SUPPORT_USERUSER
-						if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
-							struct ast_channel *owner = pri->pvts[chanpos]->owner;
-							ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-							pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
-							ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						}
+					if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
+						struct ast_channel *owner = pri->pvts[chanpos]->owner;
+						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+						pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
+						ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					}
 #endif
 
-						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-					} else {
-						ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
-							PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-					}
+					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 				} 
 				break;
 #ifndef PRI_EVENT_HANGUP_REQ
 #error please update libpri
 #endif
 			case PRI_EVENT_HANGUP_REQ:
-				chanpos = pri_find_principle(pri, e->hangup.channel);
+				chanpos = pri_find_principle_by_call(pri, e->hangup.call);
 				if (chanpos < 0) {
-					ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
+					ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d - Hanging up anyways\n", 
 						PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+					pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
 				} else {
-					chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
-					if (chanpos > -1) {
-						ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						if (pri->pvts[chanpos]->realcall) 
-							pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
-						else if (pri->pvts[chanpos]->owner) {
-							pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
-							switch (pri->pvts[chanpos]->owner->_state) {
-							case AST_STATE_BUSY:
-							case AST_STATE_UP:
-								pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-								break;
-							default:
-								switch (e->hangup.cause) {
-									case PRI_CAUSE_USER_BUSY:
-										pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
-										break;
-									case PRI_CAUSE_CALL_REJECTED:
-									case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
-									case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
-									case PRI_CAUSE_SWITCH_CONGESTION:
-									case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
-									case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
-										pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
-										break;
-									default:
-										pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
-								}
-								break;
+					ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					if (pri->pvts[chanpos]->realcall) 
+						pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
+					else if (pri->pvts[chanpos]->owner) {
+						pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
+						switch (pri->pvts[chanpos]->owner->_state) {
+						case AST_STATE_BUSY:
+						case AST_STATE_UP:
+							pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
+							break;
+						default:
+							switch (e->hangup.cause) {
+								case PRI_CAUSE_USER_BUSY:
+									pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
+									break;
+								case PRI_CAUSE_CALL_REJECTED:
+								case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
+								case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+								case PRI_CAUSE_SWITCH_CONGESTION:
+								case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
+								case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
+									pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
+									break;
+								default:
+									pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 							}
-							ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
-							if (e->hangup.aoc_units > -1)
-								ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
-										pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
-						} else {
-							pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
-							pri->pvts[chanpos]->call = NULL;
+							break;
 						}
-						if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
-							ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n",
-									PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-							pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
-							pri->pvts[chanpos]->resetting = 1;
-						}
+						ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
+						if (e->hangup.aoc_units > -1)
+							ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
+									pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
+					} else {
+						pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
+						pri->pvts[chanpos]->call = NULL;
+					}
+					if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
+						ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n",
+								PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+						pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
+						pri->pvts[chanpos]->resetting = 1;
+					}
 
 #ifdef SUPPORT_USERUSER
-						if (!ast_strlen_zero(e->hangup.useruserinfo)) {
-							struct ast_channel *owner = pri->pvts[chanpos]->owner;
-							ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-							pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
-							ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						}
+					if (!ast_strlen_zero(e->hangup.useruserinfo)) {
+						struct ast_channel *owner = pri->pvts[chanpos]->owner;
+						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+						pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
+						ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					}
 #endif
 
-						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-					} else {
-						ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-					}
+					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 				} 
 				break;
 			case PRI_EVENT_HANGUP_ACK:
-				chanpos = pri_find_principle(pri, e->hangup.channel);
+				chanpos = pri_find_principle_by_call(pri, e->hangup.call);
 				if (chanpos < 0) {
 					ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
 						PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
 				} else {
-					chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
-					if (chanpos > -1) {
-						ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						pri->pvts[chanpos]->call = NULL;
-						pri->pvts[chanpos]->resetting = 0;
-						if (pri->pvts[chanpos]->owner) {
-							ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
-						}
+					ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					pri->pvts[chanpos]->call = NULL;
+					pri->pvts[chanpos]->resetting = 0;
+					if (pri->pvts[chanpos]->owner) {
+						ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
+					}
 
 #ifdef SUPPORT_USERUSER
-						if (!ast_strlen_zero(e->hangup.useruserinfo)) {
-							struct ast_channel *owner = pri->pvts[chanpos]->owner;
-							ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-							pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
-							ast_mutex_lock(&pri->pvts[chanpos]->lock);
-						}
+					if (!ast_strlen_zero(e->hangup.useruserinfo)) {
+						struct ast_channel *owner = pri->pvts[chanpos]->owner;
+						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
+						pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
+						ast_mutex_lock(&pri->pvts[chanpos]->lock);
+					}
 #endif
 
-						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
-					}
+					ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 				}
 				break;
 			case PRI_EVENT_CONFIG_ERR:

