[Asterisk-code-review] chan dahdi/sig pri: Make post AMI HangupRequest events on PR... (asterisk[master])

Mark Michelson asteriskteam at digium.com
Tue Apr 21 09:56:15 CDT 2015


Mark Michelson has submitted this change and it was merged.

Change subject: chan_dahdi/sig_pri: Make post AMI HangupRequest events on PRI channels.
......................................................................


chan_dahdi/sig_pri: Make post AMI HangupRequest events on PRI channels.

The chan_dahdi channel driver is a very old driver.  The ability for it to
support ISDN was added well after the initial analog support.  Setting the
softhangup flags is a carry over from the original analog code.  The
driver was not updated to call ast_queue_hangup() which will post the AMI
HangupRequest event.

* Changed sig_pri.c to call ast_queue_hangup() instead of setting the
softhangup flag when the remote party initiates a hangup.

ASTERISK-24895 #close
Reported by: Andrew Zherdin

Change-Id: I5fe2e48556507785fd8ab8e1c960683fd5d20325
---
M channels/sig_pri.c
1 file changed, 43 insertions(+), 70 deletions(-)

Approvals:
  Mark Michelson: Looks good to me, approved; Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index a7cc3d7..e4ad589 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -1376,14 +1376,38 @@
 static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
 {
 	struct ast_frame f = {AST_FRAME_CONTROL, };
-	struct sig_pri_chan *p = pri->pvts[chanpos];
 
 	if (sig_pri_callbacks.queue_control) {
-		sig_pri_callbacks.queue_control(p->chan_pvt, subclass);
+		sig_pri_callbacks.queue_control(pri->pvts[chanpos]->chan_pvt, subclass);
 	}
 
 	f.subclass.integer = subclass;
 	pri_queue_frame(pri, chanpos, &f);
+}
+
+/*!
+ * \internal
+ * \brief Queue a request to hangup control frame onto the owner channel.
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos Channel position in the span.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
+ *
+ * \return Nothing
+ */
+static void sig_pri_queue_hangup(struct sig_pri_span *pri, int chanpos)
+{
+	if (sig_pri_callbacks.queue_control) {
+		sig_pri_callbacks.queue_control(pri->pvts[chanpos]->chan_pvt, AST_CONTROL_HANGUP);
+	}
+
+	sig_pri_lock_owner(pri, chanpos);
+	if (pri->pvts[chanpos]->owner) {
+		ast_queue_hangup(pri->pvts[chanpos]->owner);
+		ast_channel_unlock(pri->pvts[chanpos]->owner);
+	}
 }
 
 /*!
@@ -4035,14 +4059,14 @@
 	}
 
 	if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
-		ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+		ast_queue_hangup(pvt->owner);
 		goto cleanup_termination_request;
 	}
 
 	ast_aoc_set_termination_request(decoded);
 
 	if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
-		ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+		ast_queue_hangup(pvt->owner);
 		goto cleanup_termination_request;
 	}
 
@@ -4051,7 +4075,7 @@
 	whentohangup.tv_sec = ms / 1000;
 
 	if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) {
-		ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+		ast_queue_hangup(pvt->owner);
 		goto cleanup_termination_request;
 	}
 
@@ -4294,43 +4318,6 @@
 		}
 	}
 }
-
-#if defined(HAVE_PRI_AOC_EVENTS)
-/*!
- * \internal
- * \brief detect if AOC-S subcmd is present.
- * \since 1.8
- *
- * \param subcmds Subcommands to process if any. (Could be NULL).
- *
- * \note Knowing whether or not an AOC-E subcmd is present on certain
- * PRI hangup events is necessary to determine what method to use to hangup
- * the ast_channel.  If an AOC-E subcmd just came in, then a new AOC-E was queued
- * on the ast_channel.  If a soft hangup is used, the AOC-E msg will never make it
- * across the bridge, but if a AST_CONTROL_HANGUP frame is queued behind it
- * we can ensure the AOC-E frame makes it to it's destination before the hangup
- * frame is read.
- *
- *
- * \retval 0 AOC-E is not present in subcmd list
- * \retval 1 AOC-E is present in subcmd list
- */
-static int detect_aoc_e_subcmd(const struct pri_subcommands *subcmds)
-{
-	int i;
-
-	if (!subcmds) {
-		return 0;
-	}
-	for (i = 0; i < subcmds->counter_subcmd; ++i) {
-		const struct pri_subcommand *subcmd = &subcmds->subcmd[i];
-		if (subcmd->cmd == PRI_SUBCMD_AOC_E) {
-			return 1;
-		}
-	}
-	return 0;
-}
-#endif	/* defined(HAVE_PRI_AOC_EVENTS) */
 
 /*!
  * \internal
@@ -6567,9 +6554,8 @@
 								pri->pvts[chanpos]->call = NULL;
 							}
 						}
-						/* Force soft hangup if appropriate */
-						if (pri->pvts[chanpos]->owner)
-							ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+						/* Force hangup if appropriate */
+						sig_pri_queue_hangup(pri, chanpos);
 						sig_pri_unlock_private(pri->pvts[chanpos]);
 					}
 				} else {
@@ -6581,8 +6567,8 @@
 								pri_destroycall(pri->pri, pri->pvts[x]->call);
 								pri->pvts[x]->call = NULL;
 							}
- 							if (pri->pvts[x]->owner)
-								ast_channel_softhangup_internal_flag_add(pri->pvts[x]->owner, AST_SOFTHANGUP_DEV);
+							/* Force hangup if appropriate */
+							sig_pri_queue_hangup(pri, x);
 							sig_pri_unlock_private(pri->pvts[x]);
 						}
 				}
@@ -7154,17 +7140,7 @@
 						}
 
 						if (do_hangup) {
-#if defined(HAVE_PRI_AOC_EVENTS)
-							if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
-								/* If a AOC-E msg was sent during the release, we must use a
-								 * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */
-								pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
-							} else {
-								ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-							}
-#else
-							ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-#endif	/* defined(HAVE_PRI_AOC_EVENTS) */
+							sig_pri_queue_hangup(pri, chanpos);
 						}
 					} else {
 						/*
@@ -7314,16 +7290,11 @@
 							&& ast_channel_is_bridged(pri->pvts[chanpos]->owner)) {
 							sig_pri_send_aoce_termination_request(pri, chanpos,
 								pri_get_timer(pri->pri, PRI_TIMER_T305) / 2);
-						} else if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
-							/* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame
-							 * to guarantee that frame gets read before hangup */
-							pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
-						} else {
-							ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-						}
-#else
-						ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+						} else
 #endif	/* defined(HAVE_PRI_AOC_EVENTS) */
+						{
+							sig_pri_queue_hangup(pri, chanpos);
+						}
 					}
 					ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n",
 						pri->span, pri->pvts[chanpos]->logicalspan,
@@ -8619,16 +8590,18 @@
 					if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
 						sig_pri_aoc_e_from_ast(p, decoded);
 					}
-					/* if hangup was delayed for this AOC-E msg, waiting_for_aoc
+					/*
+					 * If hangup was delayed for this AOC-E msg, waiting_for_aoc
 					 * will be set.  A hangup is already occuring via a timeout during
 					 * this delay.  Instead of waiting for that timeout to occur, go ahead
-					 * and initiate the softhangup since the delay is no longer necessary */
+					 * and initiate the hangup since the delay is no longer necessary.
+					 */
 					if (p->waiting_for_aoce) {
 						p->waiting_for_aoce = 0;
 						ast_debug(1,
 							"Received final AOC-E msg, continue with hangup on %s\n",
 							ast_channel_name(chan));
-						ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
+						ast_queue_hangup(chan);
 					}
 					break;
 				case AST_AOC_REQUEST:

-- 
To view, visit https://gerrit.asterisk.org/173
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5fe2e48556507785fd8ab8e1c960683fd5d20325
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Richard Mudgett <rmudgett at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>



More information about the asterisk-code-review mailing list