Skip to content
Snippets Groups Projects
app_playback.c 2.96 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    /*
     * Asterisk -- A telephony toolkit for Linux.
     *
     * Trivial application to playback a sound file
     * 
    
    Mark Spencer's avatar
    Mark Spencer committed
     * Copyright (C) 1999, Mark Spencer
    
    Mark Spencer's avatar
    Mark Spencer committed
     *
     * Mark Spencer <markster@linux-support.net>
     *
     * This program is free software, distributed under the terms of
     * the GNU General Public License
     */
     
    
    Mark Spencer's avatar
    Mark Spencer committed
    #include <asterisk/lock.h>
    
    Mark Spencer's avatar
    Mark Spencer committed
    #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 <string.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    static char *tdesc = "Trivial Playback Application";
    
    static char *app = "Playback";
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    static char *synopsis = "Play a file";
    
    static char *descrip = 
    
    Mark Spencer's avatar
    Mark Spencer committed
    "  Playback(filename[|option]):  Plays  back  a  given  filename (do not put\n"
    "extension). Options may also be  included following a pipe symbol. The only\n"
    "defined option at this time is 'skip',  which  causes  the  playback of the\n"
    "message to  be  skipped  if  the  channel is not in the 'up' state (i.e. it\n"
    
    Mark Spencer's avatar
    Mark Spencer committed
    "hasn't been  answered  yet. If 'skip' is specified, the application will\n"
    "return immediately should the channel not be off hook.  Otherwise, unless\n"
    "'noanswer' is specified, the channel channel will be answered before the sound\n"
    "is played. Not all channels support playing messages while on hook. Returns -1\n"
    "if the channel was hung up, or if the file does not exist. Returns 0 otherwise.\n";
    
    Mark Spencer's avatar
    Mark Spencer committed
    STANDARD_LOCAL_USER;
    
    LOCAL_USER_DECL;
    
    static int playback_exec(struct ast_channel *chan, void *data)
    {
    
    Mark Spencer's avatar
    Mark Spencer committed
    	int res = 0;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	struct localuser *u;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char tmp[256];
    	char *options;
    	int option_skip=0;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	int option_noanswer = 0;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	char *stringp;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (!data || !strlen((char *)data)) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
    		return -1;
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	strncpy(tmp, (char *)data, sizeof(tmp)-1);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	stringp=tmp;
    	strsep(&stringp, "|");
    	options = strsep(&stringp, "|");
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (options && !strcasecmp(options, "skip"))
    		option_skip = 1;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (options && !strcasecmp(options, "noanswer"))
    		option_noanswer = 1;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	LOCAL_USER_ADD(u);
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (chan->_state != AST_STATE_UP) {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (option_skip) {
    			/* At the user's option, skip if the line is not up */
    			LOCAL_USER_REMOVE(u);
    			return 0;
    
    Mark Spencer's avatar
    Mark Spencer committed
    		} else if (!option_noanswer)
    			/* Otherwise answer unless we're supposed to send this while on-hook */
    
    Mark Spencer's avatar
    Mark Spencer committed
    			res = ast_answer(chan);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	if (!res) {
    		ast_stopstream(chan);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		res = ast_streamfile(chan, tmp, chan->language);
    
    Mark Spencer's avatar
    Mark Spencer committed
    		if (!res) 
    
    Mark Spencer's avatar
    Mark Spencer committed
    			res = ast_waitstream(chan, "");
    
    Mark Spencer's avatar
    Mark Spencer committed
    		else {
    
    Mark Spencer's avatar
    Mark Spencer committed
    			ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
    
    Mark Spencer's avatar
    Mark Spencer committed
    			res = 0;
    		}
    
    Mark Spencer's avatar
    Mark Spencer committed
    		ast_stopstream(chan);
    	}
    
    Mark Spencer's avatar
    Mark Spencer committed
    	LOCAL_USER_REMOVE(u);
    	return res;
    }
    
    int unload_module(void)
    {
    	STANDARD_HANGUP_LOCALUSERS;
    	return ast_unregister_application(app);
    }
    
    int load_module(void)
    {
    
    Mark Spencer's avatar
    Mark Spencer committed
    	return ast_register_application(app, playback_exec, synopsis, descrip);
    
    Mark Spencer's avatar
    Mark Spencer committed
    }
    
    char *description(void)
    {
    	return tdesc;
    }
    
    int usecount(void)
    {
    	int res;
    	STANDARD_USECOUNT(res);
    	return res;
    }
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    char *key()
    {
    	return ASTERISK_GPL_KEY;
    }