[asterisk-commits] rmudgett: branch 1.8 r353867 - /branches/1.8/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 2 14:01:02 CST 2012


Author: rmudgett
Date: Thu Feb  2 14:01:00 2012
New Revision: 353867

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=353867
Log:
Restore the 'w' modifier support for ISDN spans.  Dial(DAHDI/g0/1234w888)

This feature also causes the sending complete ie to be sent for switch
types that do not automatically send the ie.  (EuroISDN/ETSI)

The main difference between dialing Dial(DAHDI/g0/1234w888) and
Dial(DAHDI/g0/1234,,D(888)) is the sending of the sending complete ie.

(closes issue ASTERISK-19176)
Reported by: rmudgett
Tested by: rmudgett

Modified:
    branches/1.8/channels/chan_dahdi.c
    branches/1.8/channels/sig_pri.c
    branches/1.8/channels/sig_pri.h

Modified: branches/1.8/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_dahdi.c?view=diff&rev=353867&r1=353866&r2=353867
==============================================================================
--- branches/1.8/channels/chan_dahdi.c (original)
+++ branches/1.8/channels/chan_dahdi.c Thu Feb  2 14:01:00 2012
@@ -2644,6 +2644,39 @@
 }
 #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) */
+
 static int unalloc_sub(struct dahdi_pvt *p, int x);
 
 static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
@@ -3342,6 +3375,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,
 	.open_media = my_pri_open_media,
 	.ami_channel_event = my_ami_channel_event,
 };
@@ -7892,6 +7926,29 @@
 			tone_zone_play_tone(p->subs[idx].dfd, -1);
 		break;
 	case DAHDI_EVENT_DIALCOMPLETE:
+		/* DAHDI has completed dialing all digits sent using DAHDI_DIAL. */
+#if defined(HAVE_PRI)
+		if (dahdi_sig_pri_lib_handles(p->sig)) {
+			if (p->inalarm) {
+				break;
+			}
+			if (ioctl(p->subs[idx].dfd, DAHDI_DIALING, &x) == -1) {
+				ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n", ast->name,
+					strerror(errno));
+				return NULL;
+			}
+			if (x) {
+				/* Still dialing in DAHDI driver */
+				break;
+			}
+			/*
+			 * The ast channel is locked and the private may be locked more
+			 * than once.
+			 */
+			sig_pri_dial_complete(p->sig_pvt, ast);
+			break;
+		}
+#endif	/* defined(HAVE_PRI) */
 #ifdef HAVE_OPENR2
 		if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) {
 			/* we don't need to do anything for this event for R2 signaling

Modified: branches/1.8/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/sig_pri.c?view=diff&rev=353867&r1=353866&r2=353867
==============================================================================
--- branches/1.8/channels/sig_pri.c (original)
+++ branches/1.8/channels/sig_pri.c Thu Feb  2 14:01:00 2012
@@ -137,6 +137,8 @@
 		return "Proceeding";
 	case SIG_PRI_CALL_LEVEL_ALERTING:
 		return "Alerting";
+	case SIG_PRI_CALL_LEVEL_DEFER_DIAL:
+		return "DeferDial";
 	case SIG_PRI_CALL_LEVEL_CONNECT:
 		return "Connect";
 	}
@@ -213,6 +215,13 @@
 	}
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
+
+static void sig_pri_dial_digits(struct sig_pri_chan *p, const char *dial_string)
+{
+	if (p->calls->dial_digits) {
+		p->calls->dial_digits(p->chan_pvt, dial_string);
+	}
+}
 
 /*!
  * \internal
@@ -1460,6 +1469,7 @@
 #if defined(HAVE_PRI_SETUP_KEYPAD)
 		strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
 #endif	/* defined(HAVE_PRI_SETUP_KEYPAD) */
+		strcpy(new_chan->deferred_digits, old_chan->deferred_digits);
 #if defined(HAVE_PRI_AOC_EVENTS)
 		new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
 		new_chan->aoc_e = old_chan->aoc_e;
@@ -5719,14 +5729,28 @@
 #endif	/* defined(HAVE_PRI_CALL_WAITING) */
 				sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.channel,
 					e->answer.subcmds, e->answer.call);
-				if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
-					pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
-				}
-				sig_pri_open_media(pri->pvts[chanpos]);
-				pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER);
-				/* Enable echo cancellation if it's not on already */
-				sig_pri_set_dialing(pri->pvts[chanpos], 0);
-				sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
+				if (!ast_strlen_zero(pri->pvts[chanpos]->deferred_digits)) {
+					/* We have some 'w' deferred digits to dial now. */
+					ast_verb(3,
+						"Span %d: Channel %d/%d dialing deferred digit string: %s\n",
+						pri->span, pri->pvts[chanpos]->logicalspan,
+						pri->pvts[chanpos]->prioffset,
+						pri->pvts[chanpos]->deferred_digits);
+					if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
+						pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_DEFER_DIAL;
+					}
+					sig_pri_dial_digits(pri->pvts[chanpos],
+						pri->pvts[chanpos]->deferred_digits);
+				} else {
+					if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
+						pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
+					}
+					sig_pri_open_media(pri->pvts[chanpos]);
+					pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER);
+					sig_pri_set_dialing(pri->pvts[chanpos], 0);
+					/* Enable echo cancellation if it's not on already */
+					sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
+				}
 
 #ifdef SUPPORT_USERUSER
 				if (!ast_strlen_zero(e->answer.useruserinfo)) {
@@ -6432,7 +6456,14 @@
 	if (strlen(number) < p->stripmsd) {
 		number = "";
 	} else {
+		char *deferred;
+
 		number += p->stripmsd;
+		deferred = strchr(number, 'w');
+		if (deferred) {
+			/* Remove any 'w' deferred digits. */
+			*deferred = '\0';
+		}
 		while (isalpha(*number)) {
 			++number;
 		}
@@ -6548,7 +6579,6 @@
 		}
 		dialed_subaddress.str = s;
 		dialed_subaddress.valid = 1;
-		s = NULL;
 	}
 
 	l = NULL;
@@ -6577,6 +6607,21 @@
 		ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
 		return -1;
 	}
+
+	/* Extract any 'w' deferred digits. */
+	s = strchr(c + p->stripmsd, 'w');
+	if (s) {
+		*s++ = '\0';
+		ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits));
+		/*
+		 * Since we have a 'w', this means that there will not be any
+		 * more normal dialed digits.  Therefore, the sending complete
+		 * ie needs to be sent with any normal digits.
+		 */
+	} else {
+		p->deferred_digits[0] = '\0';
+	}
+
 	pri_grab(p, p->pri);
 	if (!(p->call = pri_new_call(p->pri->pri))) {
 		ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
@@ -6584,7 +6629,8 @@
 		return -1;
 	}
 	if (!(sr = pri_sr_new())) {
-		ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
+		ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n",
+			p->channel);
 		pri_destroycall(p->pri->pri, p->call);
 		p->call = NULL;
 		pri_rel(p->pri);
@@ -7306,6 +7352,40 @@
 	return 1;
 }
 
+/*!
+ * \brief DTMF dial string complete.
+ * \since 1.8.11
+ *
+ * \param pvt sig_pri private channel structure.
+ * \param ast Asterisk channel
+ *
+ * \note Channel and private lock are already held.
+ *
+ * \return Nothing
+ */
+void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
+{
+	/* If we just completed 'w' deferred dialing digits, we need to answer now. */
+	if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
+		pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
+
+		sig_pri_open_media(pvt);
+		{
+			struct ast_frame f = {AST_FRAME_CONTROL, };
+
+			if (pvt->calls->queue_control) {
+				pvt->calls->queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER);
+			}
+
+			f.subclass.integer = AST_CONTROL_ANSWER;
+			ast_queue_frame(ast, &f);
+		}
+		sig_pri_set_dialing(pvt, 0);
+		/* Enable echo cancellation if it's not on already */
+		sig_pri_set_echocanceller(pvt, 1);
+	}
+}
+
 #if defined(HAVE_PRI_MWI)
 /*!
  * \internal

Modified: branches/1.8/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/sig_pri.h?view=diff&rev=353867&r1=353866&r2=353867
==============================================================================
--- branches/1.8/channels/sig_pri.h (original)
+++ branches/1.8/channels/sig_pri.h Thu Feb  2 14:01:00 2012
@@ -95,6 +95,8 @@
 	SIG_PRI_CALL_LEVEL_PROCEEDING,
 	/*! Called party is being alerted of the call. (ALERTING) */
 	SIG_PRI_CALL_LEVEL_ALERTING,
+	/*! Call is dialing 'w' deferred digits. (CONNECT) */
+	SIG_PRI_CALL_LEVEL_DEFER_DIAL,
 	/*! Call is connected/answered. (CONNECT) */
 	SIG_PRI_CALL_LEVEL_CONNECT,
 };
@@ -136,6 +138,7 @@
 	const char *(* const get_orig_dialstring)(void *pvt);
 	void (* const make_cc_dialstring)(void *pvt, char *buf, size_t buf_size);
 	void (* const update_span_devstate)(struct sig_pri_span *pri);
+	void (* const dial_digits)(void *pvt, const char *dial_string);
 
 	void (* const open_media)(void *pvt);
 
@@ -227,6 +230,8 @@
 	/*! \brief Keypad digits that came in with the SETUP message. */
 	char keypad_digits[AST_MAX_EXTENSION];
 #endif	/* defined(HAVE_PRI_SETUP_KEYPAD) */
+	/*! 'w' deferred dialing digits. */
+	char deferred_digits[AST_MAX_EXTENSION];
 
 #if defined(HAVE_PRI_AOC_EVENTS)
 	struct pri_subcmd_aoc_e aoc_e;
@@ -507,6 +512,7 @@
 /* If return 0, it means this function was able to handle it (pre setup digits).  If non zero, the user of this
  * functions should handle it normally (generate inband DTMF) */
 int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit);
+void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast);
 
 void sig_pri_stop_pri(struct sig_pri_span *pri);
 int sig_pri_start_pri(struct sig_pri_span *pri);




More information about the asterisk-commits mailing list