[asterisk-commits] branch file/app_playlist - r7378 /team/file/app_playlist/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Dec 6 23:10:48 CST 2005


Author: file
Date: Tue Dec  6 23:10:46 2005
New Revision: 7378

URL: http://svn.digium.com/view/asterisk?rev=7378&view=rev
Log:
Add the preliminary application - still needs more error checking when doing actual playback

Added:
    team/file/app_playlist/apps/app_playlist.c
Modified:
    team/file/app_playlist/apps/Makefile

Modified: team/file/app_playlist/apps/Makefile
URL: http://svn.digium.com/view/asterisk/team/file/app_playlist/apps/Makefile?rev=7378&r1=7377&r2=7378&view=diff
==============================================================================
--- team/file/app_playlist/apps/Makefile (original)
+++ team/file/app_playlist/apps/Makefile Tue Dec  6 23:10:46 2005
@@ -29,7 +29,7 @@
      app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
      app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so \
      app_dictate.so app_externalivr.so app_directed_pickup.so \
-     app_mixmonitor.so app_stack.so
+     app_mixmonitor.so app_stack.so app_playlist.so
 
 #
 # Obsolete things...

Added: team/file/app_playlist/apps/app_playlist.c
URL: http://svn.digium.com/view/asterisk/team/file/app_playlist/apps/app_playlist.c?rev=7378&view=auto
==============================================================================
--- team/file/app_playlist/apps/app_playlist.c (added)
+++ team/file/app_playlist/apps/app_playlist.c Tue Dec  6 23:10:46 2005
@@ -1,0 +1,249 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2005, Joshua Colp.
+ *
+ * Joshua Colp <jcolp at asterlink.com>
+ * Based upon app_playback.c by:
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Small application that implements playlists for audio files
+ * 
+ * \ingroup applications
+ */
+ 
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "asterisk.h"
+
+#include "asterisk/lock.h"
+#include "asterisk/file.h"
+#include "asterisk/logger.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+#include "asterisk/module.h"
+#include "asterisk/translate.h"
+#include "asterisk/utils.h"
+#include "asterisk/options.h"
+#include "asterisk/app.h"
+
+static char *tdesc = "Playback Playlist Application";
+
+static char *play_app = "Playlist";
+static char *add_app = "PlaylistAdd";
+
+static char *play_synopsis = "Play a playlist";
+static char *add_synopsis = "Add a filename to a playlist";
+
+static char *descrip = 
+"Toast\n";
+
+STANDARD_LOCAL_USER;
+
+LOCAL_USER_DECL;
+
+struct ast_playlist {
+	struct ast_channel *owner;
+	char *list;
+	char *filenames;
+	struct ast_playlist *next;
+};
+
+AST_MUTEX_DEFINE_STATIC(playlist_lock);
+static struct ast_playlist *playlists = NULL;
+
+static int add_exec(struct ast_channel *chan, void *data)
+{
+	int res = 0;
+	struct localuser *u = NULL;
+	struct ast_playlist *new_list = NULL, *current = NULL;
+	char *tmp = NULL, *list = NULL, *filenames = NULL;
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_WARNING, "PlaylistAdd requires an argument (list|filename)\n");
+		return -1;
+	}
+
+	LOCAL_USER_ADD(u);
+
+	tmp = ast_strdupa(data);
+	if (tmp == NULL) {
+		ast_log(LOG_ERROR, "Out of memory!\n");
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	/* Do string parsing */
+	list = tmp;
+	filenames = strchr(list,'|');
+	if (filenames != NULL) {
+		*filenames = '\0';
+		filenames++;
+	}
+
+	if (filenames == NULL) {
+		ast_log(LOG_WARNING, "PlaylistAdd requires an argument (list|filename)\n");
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	/* Now create a new playlist entry */
+	new_list = (struct ast_playlist*)malloc(sizeof(struct ast_playlist));
+	if (new_list == NULL) {
+                ast_log(LOG_ERROR, "Out of memory!\n");
+                LOCAL_USER_REMOVE(u);
+                return -1;
+        }
+	memset(new_list, 0, sizeof(struct ast_playlist));
+	new_list->owner = chan; /* Make sure we have some unique tie */
+	new_list->list = strdup(list);
+	new_list->filenames = strdup(filenames);
+
+	/* Now add it to the list */
+	ast_mutex_lock(&playlist_lock);
+	if (playlists == NULL) {
+		/* This is easy - it's at the front */
+		playlists = new_list;
+	} else {
+		/* Not so easy... have to get to the end so we can keep the order */
+		current = playlists;
+		while (current) {
+			if (current->next == NULL) {
+				current->next = new_list;
+				break;
+			}
+			current = current->next;
+		}
+	}
+	ast_mutex_unlock(&playlist_lock);
+
+	LOCAL_USER_REMOVE(u);
+
+	return res;
+}
+
+static int playlist_exec(struct ast_channel *chan, void *data)
+{
+	int res = 0;
+	struct ast_playlist *current = NULL, *previous = NULL, *erasure = NULL;
+	struct localuser *u;
+	char *tmp = NULL, *front = NULL, *back = NULL;
+	
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_WARNING, "Playlist requires an argument (list)\n");
+		return -1;
+	}
+
+	LOCAL_USER_ADD(u);
+
+	tmp = ast_strdupa(data);
+	if (!tmp) {
+		ast_log(LOG_ERROR, "Out of memory!\n");
+		LOCAL_USER_REMOVE(u);
+		return -1;	
+	}
+
+	/* Stop any streams on the channel */
+	ast_stopstream(chan);
+
+	/* Now iterate through the list finding our stuff */
+	ast_mutex_lock(&playlist_lock);
+	current = playlists;
+	while (current) {
+		/* See if this is one of ours */
+		if (current->owner == chan && !strcasecmp(current->list, tmp)) {
+			/* Okay this is ours - do the playback stuff... */
+			front = current->filenames;
+			while (front) {
+				if ((back = strchr(front, '&'))) {
+					*back = '\0';
+					back++;
+				}
+				/* Stream the file */
+				ast_streamfile(chan, front, chan->language);
+				ast_waitstream(chan, "");
+				ast_stopstream(chan);
+				front = back;
+			}
+			/* Now get rid of it */
+			erasure = current;
+			current = current->next;
+			/* Reshuffle the list slightly */
+			if (erasure == playlists) {
+				playlists = current;
+			} else {
+				previous->next = current;
+			}
+			/* Now get rid of the used memory! */
+			erasure->owner = NULL;
+			free(erasure->list);
+			free(erasure->filenames);
+			free(erasure);
+			erasure = NULL;
+		} else {
+			/* Simply skip over it */
+			previous = current;
+			current = current->next;
+		}
+	}
+	ast_mutex_unlock(&playlist_lock);
+
+	LOCAL_USER_REMOVE(u);
+	return res;
+}
+
+int unload_module(void)
+{
+	int res = 0;
+
+	res = ast_unregister_application(play_app);
+	if (!res)
+	  res = ast_unregister_application(add_app);
+
+	STANDARD_HANGUP_LOCALUSERS;
+
+	return res;	
+}
+
+int load_module(void)
+{
+	int res = 0;
+
+	res = ast_register_application(play_app, playlist_exec, play_synopsis, descrip);
+	if (!res)
+		res = ast_register_application(add_app, add_exec, add_synopsis, descrip);
+
+	return res;
+}
+
+char *description(void)
+{
+	return tdesc;
+}
+
+int usecount(void)
+{
+	int res;
+	STANDARD_USECOUNT(res);
+	return res;
+}
+
+char *key()
+{
+	return ASTERISK_GPL_KEY;
+}



More information about the asterisk-commits mailing list