[asterisk-commits] kmoore: trunk r369185 - in /trunk/channels: sig_analog.c sig_pri.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jun 22 10:10:44 CDT 2012


Author: kmoore
Date: Fri Jun 22 10:10:38 2012
New Revision: 369185

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=369185
Log:
Add HANGUPCAUSE hash support for analog and PRI DAHDI subtechs

This is part of the DAHDI support for the Asterisk 11 "Who Hung Up?"
project and covers the implementation for the technologies implemented
in sig_analog.c and sig_pri.c. Tested on a local machine to verify
protocol and cause information is available.

Review: https://reviewboard.asterisk.org/r/1953/
(issue SWP-4222)

Modified:
    trunk/channels/sig_analog.c
    trunk/channels/sig_pri.c

Modified: trunk/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_analog.c?view=diff&rev=369185&r1=369184&r2=369185
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Fri Jun 22 10:10:38 2012
@@ -2663,6 +2663,9 @@
 	pthread_t threadid;
 	struct ast_channel *chan;
 	struct ast_frame *f;
+	struct ast_control_pvt_cause_code *cause_code;
+	int data_size = sizeof(*cause_code);
+	char *subclass = NULL;
 
 	ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
 
@@ -2693,7 +2696,29 @@
 
 	ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", analog_event2str(res), res, p->channel, idx);
 
+	/* add length of "ANALOG " */
+	data_size += 7;
+
 	if (res & (ANALOG_EVENT_PULSEDIGIT | ANALOG_EVENT_DTMFUP)) {
+		/* add length of "ANALOG_EVENT_" */
+		data_size += 13;
+		if (res & ANALOG_EVENT_PULSEDIGIT) {
+			/* add length of "PULSEDIGIT" */
+			data_size += 10;
+		} else {
+			/* add length of "DTMFUP" */
+			data_size += 6;
+		}
+
+		/* add length of " (c)" */
+		data_size += 4;
+
+		cause_code = alloca(data_size);
+		ast_copy_string(cause_code->chan_name, ast_channel_name(ast), AST_CHANNEL_NAME);
+		snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "ANALOG ANALOG_EVENT_%s (%c)",
+			(res & ANALOG_EVENT_DTMFUP) ? "DTMFUP" : "PULSEDIGIT", res & 0xff);
+		ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+
 		analog_set_pulsedial(p, (res & ANALOG_EVENT_PULSEDIGIT) ? 1 : 0);
 		ast_debug(1, "Detected %sdigit '%c'\n", (res & ANALOG_EVENT_PULSEDIGIT) ? "pulse ": "", res & 0xff);
 		analog_confmute(p, 0);
@@ -2704,6 +2729,14 @@
 	}
 
 	if (res & ANALOG_EVENT_DTMFDOWN) {
+		/* add length of "ANALOG_EVENT_DTMFDOWN (c)" */
+		data_size += 25;
+
+		cause_code = alloca(data_size);
+		ast_copy_string(cause_code->chan_name, ast_channel_name(ast), AST_CHANNEL_NAME);
+		snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "ANALOG ANALOG_EVENT_DTMFDOWN (%c)", res & 0xff);
+		ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+
 		ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
 		/* Mute conference */
 		analog_confmute(p, 1);
@@ -2712,6 +2745,13 @@
 		analog_handle_dtmf(p, ast, idx, &f);
 		return f;
 	}
+
+	subclass = analog_event2str(res);
+	data_size += strlen(subclass);
+	cause_code = alloca(data_size);
+	ast_copy_string(cause_code->chan_name, ast_channel_name(ast), AST_CHANNEL_NAME);
+	snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "ANALOG %s", subclass);
+	ast_queue_control_data(ast, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
 
 	switch (res) {
 	case ANALOG_EVENT_EC_DISABLED:

Modified: trunk/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_pri.c?view=diff&rev=369185&r1=369184&r2=369185
==============================================================================
--- trunk/channels/sig_pri.c (original)
+++ trunk/channels/sig_pri.c Fri Jun 22 10:10:38 2012
@@ -1257,6 +1257,37 @@
 
 	f.subclass.integer = subclass;
 	pri_queue_frame(pri, chanpos, &f);
+}
+
+/*!
+ * \internal
+ * \brief Queue a PVT_CAUSE_CODE frame onto the owner channel.
+ * \since 11
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos Channel position in the span.
+ * \param cause String describing the cause to be placed into the frame.
+ *
+ * \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 pri_queue_pvt_cause_data(struct sig_pri_span *pri, int chanpos, const char *cause)
+{
+	struct ast_channel *chan;
+	struct ast_control_pvt_cause_code *cause_code;
+
+	sig_pri_lock_owner(pri, chanpos);
+	chan = pri->pvts[chanpos]->owner;
+	if (chan) {
+		int datalen = sizeof(*cause_code) + strlen(cause);
+		cause_code = alloca(datalen);
+		ast_copy_string(cause_code->chan_name, ast_channel_name(chan), AST_CHANNEL_NAME);
+		ast_copy_string(cause_code->code, cause, datalen + 1 - sizeof(*cause_code));
+		ast_queue_control_data(chan, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
+		ast_channel_unlock(chan);
+	}
 }
 
 /*!
@@ -5440,7 +5471,6 @@
 	pri_event *e;
 	struct pollfd fds[SIG_PRI_NUM_DCHANS];
 	int res;
-	int chanpos = 0;
 	int x;
 	int law;
 	struct ast_channel *c;
@@ -5648,6 +5678,9 @@
 			ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
 
 		if (e) {
+			int chanpos = -1;
+			char cause_str[35];
+
 			if (pri->debug) {
 				ast_verbose("Span %d: Processing event %s(%d)\n",
 					pri->span, pri_event2str(e->e), e->e);
@@ -6448,6 +6481,11 @@
 					e->proceeding.call);
 
 				if (e->proceeding.cause > -1) {
+					if (pri->pvts[chanpos]->owner) {
+						snprintf(cause_str, sizeof(cause_str), "PRI PRI_EVENT_PROGRESS (%d)", e->proceeding.cause);
+						pri_queue_pvt_cause_data(pri, chanpos, cause_str);
+					}
+
 					ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
 
 					/* Work around broken, out of spec USER_BUSY cause in a progress message */
@@ -6459,6 +6497,8 @@
 							pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
 						}
 					}
+				} else if (pri->pvts[chanpos]->owner) {
+					pri_queue_pvt_cause_data(pri, chanpos, "PRI PRI_EVENT_PROGRESS");
 				}
 
 				if (!pri->pvts[chanpos]->progress
@@ -6736,6 +6776,9 @@
 					if (pri->pvts[chanpos]->owner) {
 						int do_hangup = 0;
 
+						snprintf(cause_str, sizeof(cause_str), "PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
+						pri_queue_pvt_cause_data(pri, chanpos, cause_str);
+
 						/* Queue a BUSY instead of a hangup if our cause is appropriate */
 						ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
 						switch (ast_channel_state(pri->pvts[chanpos]->owner)) {
@@ -6884,6 +6927,9 @@
 				}
 				if (pri->pvts[chanpos]->owner) {
 					int do_hangup = 0;
+
+					snprintf(cause_str, sizeof(cause_str), "PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
+					pri_queue_pvt_cause_data(pri, chanpos, cause_str);
 
 					ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
 					switch (ast_channel_state(pri->pvts[chanpos]->owner)) {
@@ -7218,6 +7264,27 @@
 					pri->span, pri_event2str(e->e), e->e);
 				break;
 			}
+
+			/* send tech-specific information for HANGUPCAUSE hash */
+			if (chanpos > -1 && pri->pvts[chanpos]) {
+				switch (e->e) {
+				/* already handled above */
+				case PRI_EVENT_PROGRESS:
+				case PRI_EVENT_HANGUP:
+				case PRI_EVENT_HANGUP_REQ:
+					break;
+				default:
+					sig_pri_lock_private(pri->pvts[chanpos]);
+					if (pri->pvts[chanpos]->owner) {
+						char *event_str = pri_event2str(e->e);
+
+						snprintf(cause_str, sizeof(cause_str), "PRI %s", event_str);
+						pri_queue_pvt_cause_data(pri, chanpos, cause_str);
+					}
+					sig_pri_unlock_private(pri->pvts[chanpos]);
+					break;
+				}
+			}
 		}
 		ast_mutex_unlock(&pri->lock);
 	}




More information about the asterisk-commits mailing list