Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:48 2009

## Asterisk developer's documentation

# app_playback.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2005, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief Trivial application to playback a sound file
    00022  *
    00023  * \ingroup applications
    00024  */
    00025
    00026 #include <string.h>
    00027 #include <stdlib.h>
    00028 #include <stdio.h>
    00029
    00030 #include "asterisk.h"
    00031
    00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 43800 $")
    00033
    00034 #include "asterisk/lock.h"
    00035 #include "asterisk/file.h"
    00036 #include "asterisk/logger.h"
    00037 #include "asterisk/channel.h"
    00038 #include "asterisk/pbx.h"
    00039 #include "asterisk/module.h"
    00040 #include "asterisk/translate.h"
    00041 #include "asterisk/utils.h"
    00042 #include "asterisk/options.h"
    00043 #include "asterisk/app.h"
    00044
    00045 static char *tdesc = "Sound File Playback Application";
    00046
    00047 static char *app = "Playback";
    00048
    00049 static char *synopsis = "Play a file";
    00050
    00051 static char *descrip =
    00052 "  Playback(filename[&filename2...][|option]):  Plays back given filenames (do not put\n"
    00053 "extension). Options may also be included following a pipe symbol. The 'skip'\n"
    00054 "option causes the playback of the message to be skipped if the channel\n"
    00055 "is not in the 'up' state (i.e. it hasn't been  answered  yet). If 'skip' is \n"
    00056 "specified, the application will return immediately should the channel not be\n"
    00057 "off hook.  Otherwise, unless 'noanswer' is specified, the channel will\n"
    00058 "be answered before the sound is played. Not all channels support playing\n"
    00059 "messages while still on hook. If 'j' is specified, the application\n"
    00060 "will jump to priority n+101 if present when a file specified to be played\n"
    00061 "does not exist.\n"
    00062 "This application sets the following channel variable upon completion:\n"
    00063 " PLAYBACKSTATUS    The status of the playback attempt as a text string, one of\n"
    00064 "               SUCCESS | FAILED\n"
    00065 ;
    00066
    00067 STANDARD_LOCAL_USER;
    00068
    00069 LOCAL_USER_DECL;
    00070
    00071 static int playback_exec(struct ast_channel *chan, void *data)
    00072 {
    00073    int res = 0, mres = 0;
    00074    struct localuser *u;
    00075    char *tmp = NULL;
    00076    int option_skip=0;
    00077    int option_noanswer = 0;
    00078    char *front = NULL, *back = NULL;
    00079    int priority_jump = 0;
    00080    AST_DECLARE_APP_ARGS(args,
    00081       AST_APP_ARG(filenames);
    00082       AST_APP_ARG(options);
    00083    );
    00084
    00085    if (ast_strlen_zero(data)) {
    00086       ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
    00087       return -1;
    00088    }
    00089
    00090    LOCAL_USER_ADD(u);
    00091
    00092    tmp = ast_strdupa(data);
    00093    if (!tmp) {
    00094       ast_log(LOG_ERROR, "Out of memory!\n");
    00095       LOCAL_USER_REMOVE(u);
    00096       return -1;
    00097    }
    00098
    00099    AST_STANDARD_APP_ARGS(args, tmp);
    00100
    00101    if (args.options) {
    00102       if (strcasestr(args.options, "skip"))
    00103          option_skip = 1;
    00104       if (strcasestr(args.options, "noanswer"))
    00105          option_noanswer = 1;
    00106       if (strchr(args.options, 'j'))
    00107          priority_jump = 1;
    00108    }
    00109
    00110    if (chan->_state != AST_STATE_UP) {
    00111       if (option_skip) {
    00112          /* At the user's option, skip if the line is not up */
    00113          pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", "SUCCESS");
    00114          LOCAL_USER_REMOVE(u);
    00115          return 0;
    00116       } else if (!option_noanswer)
    00117          /* Otherwise answer unless we're supposed to send this while on-hook */
    00118          res = ast_answer(chan);
    00119    }
    00120    if (!res) {
    00121       ast_stopstream(chan);
    00122       front = tmp;
    00123       while (!res && front) {
    00124          if ((back = strchr(front, '&'))) {
    00125             *back = '\0';
    00126             back++;
    00127          }
    00128          res = ast_streamfile(chan, front, chan->language);
    00129          if (!res) {
    00130             res = ast_waitstream(chan, "");
    00131             ast_stopstream(chan);
    00132          } else {
    00133             ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
    00134             if (priority_jump || option_priority_jumping)
    00135                ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
    00136             res = 0;
    00137             mres = 1;
    00138          }
    00139          front = back;
    00140       }
    00141    }
    00142    if (mres)
    00143       pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", "FAILED");
    00144    else
    00145       pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", "SUCCESS");
    00146    LOCAL_USER_REMOVE(u);
    00147    return res;
    00148 }
    00149
    00150 int unload_module(void)
    00151 {
    00152    int res;
    00153
    00154    res = ast_unregister_application(app);
    00155
    00156    STANDARD_HANGUP_LOCALUSERS;
    00157
    00158    return res;
    00159 }
    00160
    00161 int load_module(void)
    00162 {
    00163    return ast_register_application(app, playback_exec, synopsis, descrip);
    00164 }
    00165
    00166 char *description(void)
    00167 {
    00168    return tdesc;
    00169 }
    00170
    00171 int usecount(void)
    00172 {
    00173    int res;
    00174    STANDARD_USECOUNT(res);
    00175    return res;
    00176 }
    00177
    00178 char *key()
    00179 {
    00180    return ASTERISK_GPL_KEY;
    00181 }