[svn-commits] twilson: trunk r223874 - in /trunk: apps/ include/asterisk/ res/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Oct 12 20:51:49 CDT 2009


Author: twilson
Date: Mon Oct 12 20:51:46 2009
New Revision: 223874

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=223874
Log:
Fix handling of notification calls w/ the dialing api

Modified:
    trunk/apps/app_originate.c
    trunk/include/asterisk/calendar.h
    trunk/res/res_calendar.c

Modified: trunk/apps/app_originate.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_originate.c?view=diff&rev=223874&r1=223873&r2=223874
==============================================================================
--- trunk/apps/app_originate.c (original)
+++ trunk/apps/app_originate.c Mon Oct 12 20:51:46 2009
@@ -41,6 +41,7 @@
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/app.h"
+#include "asterisk/dial.h"
 
 static const char app_originate[] = "Originate";
 
@@ -105,6 +106,9 @@
 	int outgoing_status = 0;
 	static const unsigned int timeout = 30;
 	static const char default_exten[] = "s";
+	struct ast_dial *dial = NULL;
+	struct ast_str *buf = NULL;
+	struct ast_channel *c = NULL;
 
 	ast_autoservice_start(chan);
 
@@ -130,7 +134,30 @@
 		goto return_cleanup;
 	}
 
-	if (!strcasecmp(args.type, "exten")) {
+	if (strstr(args.type, "async")) {
+		if (!(dial = ast_dial_create())) {
+			goto return_cleanup;
+		}
+
+		if (ast_dial_append(dial, chantech, chandata)) {
+			goto return_cleanup;
+		}
+
+		if (!(buf = ast_str_create(32))) {
+			goto return_cleanup;
+		}
+
+		if (!(c = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Originate/%s-%08lx", args.arg1, ast_random()))) {
+			ast_free(buf);
+			goto return_cleanup;
+		}
+
+		c->nativeformats = AST_FORMAT_SLINEAR;
+		ast_dial_set_global_timeout(dial, 30 * 1000);
+
+	}
+
+	if (!strncasecmp(args.type, "exten", 5)) {
 		int priority = 1; /* Initialized in case priority not specified */
 		const char *exten = args.arg2;
 
@@ -148,16 +175,28 @@
 		ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
 				chantech, chandata, args.arg1, exten, priority);
 
-		outgoing_res = ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
-				timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
-				NULL, NULL, NULL, NULL);
-	} else if (!strcasecmp(args.type, "app")) {
+		if (!strcasecmp(args.type, "exten-async")) {
+			ast_str_set(&buf, 0, "Dial,Local/%s@%s", exten, args.arg1);
+			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(buf));
+			ast_dial_run(dial, NULL, 1);
+		} else {
+			outgoing_res = ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
+					timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
+					NULL, NULL, NULL, NULL);
+		}
+	} else if (!strncasecmp(args.type, "app", 3)) {
 		ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
 				chantech, chandata, args.arg1, S_OR(args.arg2, ""));
 
-		outgoing_res = ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
-				timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
-				NULL, NULL, NULL, NULL);
+		if (!strcasecmp(args.type, "app-async")) {
+			ast_str_set(&buf, 0, "%s,%s", args.arg1, args.arg2);
+			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(buf));
+			ast_dial_run(dial, c, 1);
+		} else {
+			outgoing_res = ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
+					timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
+					NULL, NULL, NULL, NULL);
+		}
 	} else {
 		ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
 				args.type);
@@ -194,6 +233,12 @@
 			break;
 		}
 	}
+	if (buf) {
+		ast_free(buf);
+	}
+	if (c) {
+		ast_channel_release(c);
+	}
 
 	ast_autoservice_stop(chan);
 

Modified: trunk/include/asterisk/calendar.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/calendar.h?view=diff&rev=223874&r1=223873&r2=223874
==============================================================================
--- trunk/include/asterisk/calendar.h (original)
+++ trunk/include/asterisk/calendar.h Mon Oct 12 20:51:46 2009
@@ -24,6 +24,7 @@
 #include "asterisk/config.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/lock.h"
+#include "asterisk/dial.h"
 
 /*! \file calendar.h
  * \brief A general API for managing calendar events with Asterisk
@@ -103,6 +104,8 @@
 	int notify_sched;    /*!< The sched for event notification */
 	int bs_start_sched;  /*!< The sched for changing the device state at the start of an event */
 	int bs_end_sched;    /*!< The sched for changing the device state at the end of an event */
+	struct ast_dial *dial;
+	struct ast_channel *notify_chan;
 	AST_LIST_HEAD_NOLOCK(attendees, ast_calendar_attendee) attendees;
 };
 

Modified: trunk/res/res_calendar.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_calendar.c?view=diff&rev=223874&r1=223873&r2=223874
==============================================================================
--- trunk/res/res_calendar.c (original)
+++ trunk/res/res_calendar.c Mon Oct 12 20:51:46 2009
@@ -611,31 +611,33 @@
 	return buf;
 }
 
-static int calendar_event_notify(const void *data)
-{
-	struct ast_calendar_event *event = (void *)data;
-	char tech[256], dest[256], buf[8], *tmp;
-	struct ast_dial *dial = NULL;
+static int null_chan_write(struct ast_channel *chan, struct ast_frame *frame)
+{
+	return 0;
+}
+
+static const struct ast_channel_tech null_tech = {
+        .type = "NULL",
+        .description = "Null channel (should not see this)",
+		.write = null_chan_write,
+};
+
+static void *do_notify(void *data)
+{
+	struct ast_calendar_event *event = data;
+	struct ast_dial *dial;
+	struct ast_str *apptext = NULL;
+	struct ast_datastore *datastore;
+	enum ast_dial_result res;
 	struct ast_channel *chan = NULL;
-	struct ast_str *apptext = NULL;
-	int res = -1;
-	char start[12], end[12], busystate[2];
-	struct ast_datastore *datastore;
-
-	if (!(event && event->owner)) {
-		ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
-		goto notify_cleanup;
-	}
-
-	ao2_ref(event, +1);
-	event->notify_sched = -1;
-
-	ast_copy_string(tech, event->owner->notify_channel, sizeof(tech));
-
-	if ((tmp = strchr(tech, '/'))) {
-		*tmp = '\0';
-		tmp++;
-		ast_copy_string(dest, tmp, sizeof(dest));
+	char *tech, *dest;
+	char buf[8];
+
+	tech = ast_strdupa(event->owner->notify_channel);
+
+	if ((dest = strchr(tech, '/'))) {
+		*dest = '\0';
+		dest++;
 	} else {
 		ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
 		goto notify_cleanup;
@@ -653,16 +655,15 @@
 
 	ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
 	generate_random_string(buf, sizeof(buf));
+
 	if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Calendar/%s-%s", event->owner->name, buf))) {
 		ast_log(LOG_ERROR, "Could not allocate notification channel\n");
 		goto notify_cleanup;
 	}
 
-	snprintf(busystate, sizeof(busystate), "%d", event->busy_state);
-	snprintf(start, sizeof(start), "%lu", (long) event->start);
-	snprintf(end, sizeof(end), "%lu", (long) event->end);
-
-	chan->nativeformats = AST_FORMAT_SLINEAR;
+	chan->tech = &null_tech;
+	chan->nativeformats = chan->writeformat = chan->rawwriteformat =
+		chan->readformat = chan->rawreadformat = AST_FORMAT_SLINEAR;
 
 	if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
 		ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
@@ -681,25 +682,63 @@
 
 	if (!ast_strlen_zero(event->owner->notify_app)) {
 		ast_str_set(&apptext, 0, "%s,%s", event->owner->notify_app, event->owner->notify_appdata);
+		ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(apptext));
 	} else {
-		ast_str_set(&apptext, 0, "Dial,Local/%s@%s", event->owner->notify_extension, event->owner->notify_context);
-	}
-	ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, ast_str_buffer(apptext));
-
-	ast_dial_run(dial, chan, 1);
-	res = 0;
+	}
+
+	ast_verb(3, "Dialing %s for notification on calendar %s\n", event->owner->notify_channel, event->owner->name);
+	res = ast_dial_run(dial, chan, 0);
+
+	if (res != AST_DIAL_RESULT_ANSWERED) {
+		ast_verb(3, "Notification call for %s was not completed\n", event->owner->name);
+	} else {
+		struct ast_channel *answered;
+
+		answered = ast_dial_answered_steal(dial);
+		if (ast_strlen_zero(event->owner->notify_app)) {
+			ast_copy_string(answered->context, event->owner->notify_context, sizeof(answered->context));
+			ast_copy_string(answered->exten, event->owner->notify_extension, sizeof(answered->exten));
+			answered->priority = 1;
+			ast_pbx_run(answered);
+		}
+	}
 
 notify_cleanup:
-	event = ast_calendar_unref_event(event);
-	if (res == -1 && dial) {
-		ast_dial_destroy(dial);
-	}
 	if (apptext) {
 		ast_free(apptext);
 	}
+	if (dial) {
+		ast_dial_destroy(dial);
+	}
 	if (chan) {
 		ast_channel_release(chan);
 	}
+
+	event = ast_calendar_unref_event(event);
+
+	return NULL;
+}
+
+static int calendar_event_notify(const void *data)
+{
+	struct ast_calendar_event *event = (void *)data;
+	int res = -1;
+	pthread_t notify_thread = AST_PTHREADT_NULL;
+
+	if (!(event && event->owner)) {
+		ast_log(LOG_ERROR, "Extremely low-cal...in fact cal is NULL!\n");
+		return res;
+	}
+
+	ao2_ref(event, +1);
+	event->notify_sched = -1;
+
+	if (ast_pthread_create_background(&notify_thread, NULL, do_notify, event) < 0) {
+		ast_log(LOG_ERROR, "Could not create notification thread\n");
+		return res;
+	}
+
+	res = 0;
 
 	return res;
 }
@@ -1342,7 +1381,7 @@
 		return buf;
 	}
 	ast_localtime(&tv, &tm, NULL);
-	ast_strftime(buf, buflen, "%F %r", &tm);
+	ast_strftime(buf, buflen, "%F %r %z", &tm);
 
 	return buf;
 }




More information about the svn-commits mailing list