[asterisk-commits] oej: branch oej/pinedanish-copybridgeflags-1.8 r371335 - in /team/oej/pinedan...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 16 09:44:06 CDT 2012


Author: oej
Date: Thu Aug 16 09:43:59 2012
New Revision: 371335

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

Modified:
    team/oej/pinedanish-copybridgeflags-1.8/   (props changed)
    team/oej/pinedanish-copybridgeflags-1.8/apps/app_directed_pickup.c
    team/oej/pinedanish-copybridgeflags-1.8/channels/chan_dahdi.c
    team/oej/pinedanish-copybridgeflags-1.8/channels/chan_sip.c
    team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.c
    team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.h

Propchange: team/oej/pinedanish-copybridgeflags-1.8/
            ('svnmerge-integrated' removed)

Modified: team/oej/pinedanish-copybridgeflags-1.8/apps/app_directed_pickup.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinedanish-copybridgeflags-1.8/apps/app_directed_pickup.c?view=diff&rev=371335&r1=371334&r2=371335
==============================================================================
--- team/oej/pinedanish-copybridgeflags-1.8/apps/app_directed_pickup.c (original)
+++ team/oej/pinedanish-copybridgeflags-1.8/apps/app_directed_pickup.c Thu Aug 16 09:43:59 2012
@@ -55,25 +55,37 @@
 		<synopsis>
 			Directed extension call pickup.
 		</synopsis>
-		<syntax argsep="&amp;">
-			<parameter name="ext" argsep="@" required="true">
-				<argument name="extension" required="true"/>
-				<argument name="context" />
-			</parameter>
-			<parameter name="ext2" argsep="@" multiple="true">
-				<argument name="extension2" required="true"/>
-				<argument name="context2"/>
+		<syntax>
+			<parameter name="targets" argsep="&amp;">
+				<argument name="extension" argsep="@" required="true">
+					<para>Specification of the pickup target.</para>
+					<argument name="extension" required="true"/>
+					<argument name="context" />
+				</argument>
+				<argument name="extension2" argsep="@" multiple="true">
+					<para>Additional specifications of pickup targets.</para>
+					<argument name="extension2" required="true"/>
+					<argument name="context2"/>
+				</argument>
 			</parameter>
 		</syntax>
 		<description>
-			<para>This application can pickup any ringing channel that is calling
-			the specified <replaceable>extension</replaceable>. If no <replaceable>context</replaceable>
-			is specified, the current context will be used. If you use the special string <literal>PICKUPMARK</literal>
-			for the context parameter, for example 10 at PICKUPMARK, this application
-			tries to find a channel which has defined a <variable>PICKUPMARK</variable>
-			channel variable with the same value as <replaceable>extension</replaceable>
-			(in this example, <literal>10</literal>). When no parameter is specified, the application
-			will pickup a channel matching the pickup group of the active channel.</para>
+			<para>This application can pickup a specified ringing channel.  The channel
+			to pickup can be specified in the following ways.</para>
+			<para>1) If no <replaceable>extension</replaceable> targets are specified,
+			the application will pickup a channel matching the pickup group of the
+			requesting channel.</para>
+			<para>2) If the <replaceable>extension</replaceable> is specified with a
+			<replaceable>context</replaceable> of the special string
+			<literal>PICKUPMARK</literal> (for example 10 at PICKUPMARK), the application
+			will pickup a channel which has defined a channel variable
+			<variable>PICKUPMARK</variable> with the same value as
+			<replaceable>extension</replaceable> (in this example,
+			<literal>10</literal>).</para>
+			<para>3) If the <replaceable>extension</replaceable> is specified
+			with a <replaceable>context</replaceable>, the channel executing at that
+			dialplan location will be picked up.  If no <replaceable>context</replaceable>
+			is specified, the current context will be used.</para>
 		</description>
 	</application>
 	<application name="PickupChan" language="en_US">

Modified: team/oej/pinedanish-copybridgeflags-1.8/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinedanish-copybridgeflags-1.8/channels/chan_dahdi.c?view=diff&rev=371335&r1=371334&r2=371335
==============================================================================
--- team/oej/pinedanish-copybridgeflags-1.8/channels/chan_dahdi.c (original)
+++ team/oej/pinedanish-copybridgeflags-1.8/channels/chan_dahdi.c Thu Aug 16 09:43:59 2012
@@ -5910,7 +5910,7 @@
 	/* Data will be our digit string */
 	struct dahdi_pvt *pvt;
 	char *parse;
-	int res = -1;
+	int res;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(destination);
 		AST_APP_ARG(original);
@@ -5957,10 +5957,17 @@
 		args.reason = NULL;
 	}
 
-	pri_send_callrerouting_facility_exec(pvt->sig_pvt, chan->_state, args.destination,
-		args.original, args.reason);
-
-	return res;
+	res = pri_send_callrerouting_facility_exec(pvt->sig_pvt, chan->_state,
+		args.destination, args.original, args.reason);
+	if (!res) {
+		/*
+		 * Wait up to 5 seconds for a reply before hanging up this call
+		 * leg if the peer does not disconnect first.
+		 */
+		ast_safe_sleep(chan, 5000);
+	}
+
+	return -1;
 }
 #endif	/* defined(HAVE_PRI_PROG_W_CAUSE) */
 #endif	/* defined(HAVE_PRI) */
@@ -15394,8 +15401,9 @@
 				struct sig_pri_chan *chan = tmp->sig_pvt;
 
 				ast_cli(a->fd, "PRI Flags: ");
-				if (chan->resetting)
-					ast_cli(a->fd, "Resetting ");
+				if (chan->resetting != SIG_PRI_RESET_IDLE) {
+					ast_cli(a->fd, "Resetting=%d ", chan->resetting);
+				}
 				if (chan->call)
 					ast_cli(a->fd, "Call ");
 				if (chan->allocated) {

Modified: team/oej/pinedanish-copybridgeflags-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinedanish-copybridgeflags-1.8/channels/chan_sip.c?view=diff&rev=371335&r1=371334&r2=371335
==============================================================================
--- team/oej/pinedanish-copybridgeflags-1.8/channels/chan_sip.c (original)
+++ team/oej/pinedanish-copybridgeflags-1.8/channels/chan_sip.c Thu Aug 16 09:43:59 2012
@@ -5808,8 +5808,12 @@
 	}
 	if (p->udptl)
 		ast_udptl_destroy(p->udptl);
-	if (p->refer)
+	if (p->refer) {
+		if (p->refer->refer_call) {
+			p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
+		}
 		ast_free(p->refer);
+	}
 	if (p->route) {
 		free_old_route(p->route);
 		p->route = NULL;
@@ -22445,6 +22449,7 @@
 				if (subscription->owner) {
 					ast_channel_unlock(subscription->owner);
 				}
+				subscription = dialog_unref(subscription, "unref dialog subscription");
 			}
 		}
 
@@ -22463,7 +22468,6 @@
 
 		if (p->refer->refer_call == p) {
 			ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
-			p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
 			transmit_response_reliable(p, "400 Bad request", req);	/* The best way to not not accept the transfer */
 			error = 1;
 		}
@@ -22491,6 +22495,7 @@
 				if (p->refer->refer_call->owner) {
 					ast_channel_unlock(p->refer->refer_call->owner);
 				}
+				p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
 			}
 			refer_locked = 0;
 			p->invitestate = INV_COMPLETED;
@@ -25662,6 +25667,7 @@
 		ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
 		ao2_lock(peer);
 	}
+
 	if (peer->mwipvt) {
 		/* Base message on subscription */
 		p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt");
@@ -28668,7 +28674,8 @@
 		} else if (!strcasecmp(v->name, "use_q850_reason")) {
 			ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
 		} else if (!strcasecmp(v->name, "maxforwards")) {
-			if ((sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1) || (sip_cfg.default_max_forwards < 1)) {
+			if (sscanf(v->value, "%30d", &sip_cfg.default_max_forwards) != 1
+				|| sip_cfg.default_max_forwards < 1 || 255 < sip_cfg.default_max_forwards) {
 				ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d.  Using default.\n", v->value, v->lineno);
 				sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
 			}

Modified: team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.c?view=diff&rev=371335&r1=371334&r2=371335
==============================================================================
--- team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.c (original)
+++ team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.c Thu Aug 16 09:43:59 2012
@@ -196,11 +196,11 @@
 	}
 
 	/*
-	 * Clear the channel restart flag when the channel alarm changes
-	 * to prevent the flag from getting stuck when the link goes
-	 * down.
+	 * Clear the channel restart state when the channel alarm
+	 * changes to prevent the state from getting stuck when the link
+	 * goes down.
 	 */
-	p->resetting = 0;
+	p->resetting = SIG_PRI_RESET_IDLE;
 
 	p->inalarm = in_alarm;
 	if (p->calls->set_alarm) {
@@ -1147,7 +1147,8 @@
  */
 static int sig_pri_is_chan_in_use(struct sig_pri_chan *pvt)
 {
-	return pvt->owner || pvt->call || pvt->allocated || pvt->resetting || pvt->inalarm;
+	return pvt->owner || pvt->call || pvt->allocated || pvt->inalarm
+		|| pvt->resetting != SIG_PRI_RESET_IDLE;
 }
 
 /*!
@@ -1709,7 +1710,7 @@
 	}
 	if (pri->resetpos < pri->numchans) {
 		/* Mark the channel as resetting and restart it */
-		pri->pvts[pri->resetpos]->resetting = 1;
+		pri->pvts[pri->resetpos]->resetting = SIG_PRI_RESET_ACTIVE;
 		pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
 	} else {
 		pri->resetting = 0;
@@ -5099,13 +5100,40 @@
 							"Span %d: SETUP on unconfigured channel %d/%d\n",
 							pri->span, PRI_SPAN(e->ring.channel),
 							PRI_CHANNEL(e->ring.channel));
-					} else if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
-						/* This is where we handle initial glare */
-						ast_debug(1,
-							"Span %d: SETUP requested unavailable channel %d/%d.  Attempting to renegotiate.\n",
-							pri->span, PRI_SPAN(e->ring.channel),
-							PRI_CHANNEL(e->ring.channel));
-						chanpos = -1;
+					} else {
+						switch (pri->pvts[chanpos]->resetting) {
+						case SIG_PRI_RESET_IDLE:
+							break;
+						case SIG_PRI_RESET_ACTIVE:
+							/*
+							 * The peer may have lost the expected ack or not received the
+							 * RESTART yet.
+							 */
+							pri->pvts[chanpos]->resetting = SIG_PRI_RESET_NO_ACK;
+							break;
+						case SIG_PRI_RESET_NO_ACK:
+							/* The peer likely is not going to ack the RESTART. */
+							ast_debug(1,
+								"Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
+								pri->span, PRI_SPAN(e->ring.channel),
+								PRI_CHANNEL(e->ring.channel));
+
+							/* Assume we got the ack. */
+							pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
+							if (pri->resetting) {
+								/* Go on to the next idle channel to RESTART. */
+								pri_check_restart(pri);
+							}
+							break;
+						}
+						if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
+							/* This is where we handle initial glare */
+							ast_debug(1,
+								"Span %d: SETUP requested unavailable channel %d/%d.  Attempting to renegotiate.\n",
+								pri->span, PRI_SPAN(e->ring.channel),
+								PRI_CHANNEL(e->ring.channel));
+							chanpos = -1;
+						}
 					}
 #if defined(ALWAYS_PICK_CHANNEL)
 					if (e->ring.flexible) {
@@ -5927,12 +5955,12 @@
 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
 				if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
 					&& pri->sig != SIG_BRI_PTMP && !pri->resetting
-					&& !pri->pvts[chanpos]->resetting) {
+					&& pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
 					ast_verb(3,
 						"Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
 						pri->span, pri->pvts[chanpos]->logicalspan,
 						pri->pvts[chanpos]->prioffset);
-					pri->pvts[chanpos]->resetting = 1;
+					pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
 					pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
 				}
 #endif	/* defined(FORCE_RESTART_UNAVAIL_CHANS) */
@@ -6075,12 +6103,12 @@
 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
 				if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
 					&& pri->sig != SIG_BRI_PTMP && !pri->resetting
-					&& !pri->pvts[chanpos]->resetting) {
+					&& pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
 					ast_verb(3,
 						"Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
 						pri->span, pri->pvts[chanpos]->logicalspan,
 						pri->pvts[chanpos]->prioffset);
-					pri->pvts[chanpos]->resetting = 1;
+					pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
 					pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
 				}
 #endif	/* defined(FORCE_RESTART_UNAVAIL_CHANS) */
@@ -6144,7 +6172,8 @@
 					   channel number, so we have to figure it out...  This must be why
 					   everybody resets exactly a channel at a time. */
 					for (x = 0; x < pri->numchans; x++) {
-						if (pri->pvts[x] && pri->pvts[x]->resetting) {
+						if (pri->pvts[x]
+							&& pri->pvts[x]->resetting != SIG_PRI_RESET_IDLE) {
 							chanpos = x;
 							sig_pri_lock_private(pri->pvts[chanpos]);
 							ast_debug(1,
@@ -6158,7 +6187,7 @@
 									pri->pvts[chanpos]->prioffset);
 								pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 							}
-							pri->pvts[chanpos]->resetting = 0;
+							pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
 							ast_verb(3,
 								"Span %d: Channel %d/%d successfully restarted\n",
 								pri->span, pri->pvts[chanpos]->logicalspan,
@@ -6177,6 +6206,15 @@
 					}
 				} else {
 					sig_pri_lock_private(pri->pvts[chanpos]);
+					if (pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
+						/* The channel is not in the resetting state. */
+						ast_debug(1,
+							"Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
+							pri->span, pri->pvts[chanpos]->logicalspan,
+							pri->pvts[chanpos]->prioffset);
+						sig_pri_unlock_private(pri->pvts[chanpos]);
+						break;
+					}
 					if (pri->pvts[chanpos]->owner) {
 						ast_log(LOG_WARNING,
 							"Span %d: Got restart ack on channel %d/%d with owner\n",
@@ -6184,7 +6222,7 @@
 							pri->pvts[chanpos]->prioffset);
 						pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
 					}
-					pri->pvts[chanpos]->resetting = 0;
+					pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
 					ast_verb(3,
 						"Span %d: Channel %d/%d successfully restarted\n",
 						pri->span, pri->pvts[chanpos]->logicalspan,
@@ -7972,7 +8010,7 @@
 
 int pri_send_callrerouting_facility_exec(struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
 {
-	int res = -1;
+	int res;
 
 	sig_pri_lock_private(p);
 

Modified: team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.h?view=diff&rev=371335&r1=371334&r2=371335
==============================================================================
--- team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.h (original)
+++ team/oej/pinedanish-copybridgeflags-1.8/channels/sig_pri.h Thu Aug 16 09:43:59 2012
@@ -101,6 +101,27 @@
 	SIG_PRI_CALL_LEVEL_CONNECT,
 };
 
+enum sig_pri_reset_state {
+	/*! \brief The channel is not being RESTARTed. */
+	SIG_PRI_RESET_IDLE,
+	/*!
+	 * \brief The channel is being RESTARTed.
+	 * \note Waiting for a RESTART ACKNOWLEDGE from the peer.
+	 */
+	SIG_PRI_RESET_ACTIVE,
+	/*!
+	 * \brief Peer may not be sending the expected RESTART ACKNOWLEDGE.
+	 *
+	 * \details We have already received a SETUP on this channel.
+	 * If another SETUP comes in on this channel then the peer
+	 * considers this channel useable.  Assume that the peer is
+	 * never going to give us a RESTART ACKNOWLEDGE and assume that
+	 * we have received one.  This is not according to Q.931, but
+	 * some peers occasionally fail to send a RESTART ACKNOWLEDGE.
+	 */
+	SIG_PRI_RESET_NO_ACK,
+};
+
 struct sig_pri_span;
 
 struct sig_pri_callback {
@@ -245,7 +266,6 @@
 	unsigned int alreadyhungup:1;	/*!< TRUE if the call has already gone/hungup */
 	unsigned int isidlecall:1;		/*!< TRUE if this is an idle call */
 	unsigned int progress:1;		/*!< TRUE if the call has seen inband-information progress through the network */
-	unsigned int resetting:1;		/*!< TRUE if this channel is being reset/restarted */
 
 	/*!
 	 * \brief TRUE when this channel is allocated.
@@ -274,6 +294,8 @@
 
 	/*! Call establishment life cycle level for simple comparisons. */
 	enum sig_pri_call_level call_level;
+	/*! \brief Channel reset/restart state. */
+	enum sig_pri_reset_state resetting;
 	int prioffset;					/*!< channel number in span */
 	int logicalspan;				/*!< logical span number within trunk group */
 	int mastertrunkgroup;			/*!< what trunk group is our master */




More information about the asterisk-commits mailing list