Trivial application to playback a sound file. More...
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/say.h"
#include "asterisk/cli.h"
Go to the source code of this file.
Data Structures | |
struct | say_args_t |
Functions | |
static char * | __say_cli_init (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Sound File Playback Application",.load=load_module,.unload=unload_module,.reload=reload,) | |
static int | do_say (say_args_t *a, const char *s, const char *options, int depth) |
static int | load_module (void) |
static int | playback_exec (struct ast_channel *chan, const char *data) |
static int | reload (void) |
static void | restore_say_mode (void *arg) |
static int | s_streamwait3 (const say_args_t *a, const char *fn) |
static void | save_say_mode (const void *arg) |
static int | say_date (struct ast_channel *chan, time_t t, const char *ints, const char *lang) |
static int | say_date_generic (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezonename, const char *prefix) |
static int | say_date_with_format (struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezonename) |
static int | say_datetime (struct ast_channel *chan, time_t t, const char *ints, const char *lang) |
static int | say_enumeration_full (struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) |
static int | say_full (struct ast_channel *chan, const char *string, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) |
static int | say_init_mode (const char *mode) |
static int | say_number_full (struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) |
static int | say_time (struct ast_channel *chan, time_t t, const char *ints, const char *lang) |
static int | unload_module (void) |
Variables | |
static char * | app = "Playback" |
static struct ast_cli_entry | cli_playback [] |
static const void * | say_api_buf [40] |
static struct ast_config * | say_cfg = NULL |
static const char *const | say_new = "new" |
static const char *const | say_old = "old" |
Trivial application to playback a sound file.
Definition in file app_playback.c.
static char* __say_cli_init | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 388 of file app_playback.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, say_init_mode(), and ast_cli_entry::usage.
00389 { 00390 const char *old_mode = say_api_buf[0] ? say_new : say_old; 00391 const char *mode; 00392 switch (cmd) { 00393 case CLI_INIT: 00394 e->command = "say load [new|old]"; 00395 e->usage = 00396 "Usage: say load [new|old]\n" 00397 " say load\n" 00398 " Report status of current say mode\n" 00399 " say load new\n" 00400 " Set say method, configured in say.conf\n" 00401 " say load old\n" 00402 " Set old say method, coded in asterisk core\n"; 00403 return NULL; 00404 case CLI_GENERATE: 00405 return NULL; 00406 } 00407 if (a->argc == 2) { 00408 ast_cli(a->fd, "say mode is [%s]\n", old_mode); 00409 return CLI_SUCCESS; 00410 } else if (a->argc != e->args) 00411 return CLI_SHOWUSAGE; 00412 mode = a->argv[2]; 00413 if (!strcmp(mode, old_mode)) 00414 ast_cli(a->fd, "say mode is %s already\n", mode); 00415 else 00416 if (say_init_mode(mode) == 0) 00417 ast_cli(a->fd, "setting say mode from %s to %s\n", old_mode, mode); 00418 00419 return CLI_SUCCESS; 00420 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Sound File Playback Application" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
static int do_say | ( | say_args_t * | a, | |
const char * | s, | |||
const char * | options, | |||
int | depth | |||
) | [static] |
Definition at line 166 of file app_playback.c.
References ast_debug, ast_extension_match(), AST_LIST_INSERT_HEAD, ast_log(), ast_skip_blanks(), ast_strdupa, ast_trim_blanks(), ast_var_assign(), ast_var_delete(), ast_variable_browse(), say_args_t::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_substitute_variables_varshead(), s_streamwait3(), and ast_variable::value.
Referenced by say_date_generic(), say_enumeration_full(), say_full(), and say_number_full().
00167 { 00168 struct ast_variable *v; 00169 char *lang, *x, *rule = NULL; 00170 int ret = 0; 00171 struct varshead head = { .first = NULL, .last = NULL }; 00172 struct ast_var_t *n; 00173 00174 ast_debug(2, "string <%s> depth <%d>\n", s, depth); 00175 if (depth++ > 10) { 00176 ast_log(LOG_WARNING, "recursion too deep, exiting\n"); 00177 return -1; 00178 } else if (!say_cfg) { 00179 ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s); 00180 return -1; 00181 } 00182 00183 /* scan languages same as in file.c */ 00184 if (a->language == NULL) 00185 a->language = "en"; /* default */ 00186 ast_debug(2, "try <%s> in <%s>\n", s, a->language); 00187 lang = ast_strdupa(a->language); 00188 for (;;) { 00189 for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) { 00190 if (ast_extension_match(v->name, s)) { 00191 rule = ast_strdupa(v->value); 00192 break; 00193 } 00194 } 00195 if (rule) 00196 break; 00197 if ( (x = strchr(lang, '_')) ) 00198 *x = '\0'; /* try without suffix */ 00199 else if (strcmp(lang, "en")) 00200 lang = "en"; /* last resort, try 'en' if not done yet */ 00201 else 00202 break; 00203 } 00204 if (!rule) 00205 return 0; 00206 00207 /* skip up to two prefixes to get the value */ 00208 if ( (x = strchr(s, ':')) ) 00209 s = x + 1; 00210 if ( (x = strchr(s, ':')) ) 00211 s = x + 1; 00212 ast_debug(2, "value is <%s>\n", s); 00213 n = ast_var_assign("SAY", s); 00214 if (!n) { 00215 ast_log(LOG_ERROR, "Memory allocation error in do_say\n"); 00216 return -1; 00217 } 00218 AST_LIST_INSERT_HEAD(&head, n, entries); 00219 00220 /* scan the body, one piece at a time */ 00221 while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */ 00222 char fn[128]; 00223 const char *p, *fmt, *data; /* format and data pointers */ 00224 00225 /* prepare a decent file name */ 00226 x = ast_skip_blanks(x); 00227 ast_trim_blanks(x); 00228 00229 /* replace variables */ 00230 pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn)); 00231 ast_debug(2, "doing [%s]\n", fn); 00232 00233 /* locate prefix and data, if any */ 00234 fmt = strchr(fn, ':'); 00235 if (!fmt || fmt == fn) { /* regular filename */ 00236 ret = s_streamwait3(a, fn); 00237 continue; 00238 } 00239 fmt++; 00240 data = strchr(fmt, ':'); /* colon before data */ 00241 if (!data || data == fmt) { /* simple prefix-fmt */ 00242 ret = do_say(a, fn, options, depth); 00243 continue; 00244 } 00245 /* prefix:fmt:data */ 00246 for (p = fmt; p < data && ret <= 0; p++) { 00247 char fn2[sizeof(fn)]; 00248 if (*p == ' ' || *p == '\t') /* skip blanks */ 00249 continue; 00250 if (*p == '\'') {/* file name - we trim them */ 00251 char *y; 00252 strcpy(fn2, ast_skip_blanks(p+1)); /* make a full copy */ 00253 y = strchr(fn2, '\''); 00254 if (!y) { 00255 p = data; /* invalid. prepare to end */ 00256 break; 00257 } 00258 *y = '\0'; 00259 ast_trim_blanks(fn2); 00260 p = strchr(p+1, '\''); 00261 ret = s_streamwait3(a, fn2); 00262 } else { 00263 int l = fmt-fn; 00264 strcpy(fn2, fn); /* copy everything */ 00265 /* after prefix, append the format */ 00266 fn2[l++] = *p; 00267 strcpy(fn2 + l, data); 00268 ret = do_say(a, fn2, options, depth); 00269 } 00270 00271 if (ret) { 00272 break; 00273 } 00274 } 00275 } 00276 ast_var_delete(n); 00277 return ret; 00278 }
static int load_module | ( | void | ) | [static] |
Definition at line 539 of file app_playback.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_load, ast_extension_match(), ast_register_application_xml, ast_variable_browse(), CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, playback_exec(), say_init_mode(), and ast_variable::value.
00540 { 00541 struct ast_variable *v; 00542 struct ast_flags config_flags = { 0 }; 00543 00544 say_cfg = ast_config_load("say.conf", config_flags); 00545 if (say_cfg && say_cfg != CONFIG_STATUS_FILEINVALID) { 00546 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) { 00547 if (ast_extension_match(v->name, "mode")) { 00548 say_init_mode(v->value); 00549 break; 00550 } 00551 } 00552 } 00553 00554 ast_cli_register_multiple(cli_playback, ARRAY_LEN(cli_playback)); 00555 return ast_register_application_xml(app, playback_exec); 00556 }
static int playback_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 426 of file app_playback.c.
References ast_channel::_state, args, ast_answer(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_waitstream(), LOG_WARNING, pbx_builtin_setvar_helper(), and say_full().
Referenced by load_module().
00427 { 00428 int res = 0; 00429 int mres = 0; 00430 char *tmp; 00431 int option_skip=0; 00432 int option_say=0; 00433 int option_noanswer = 0; 00434 00435 AST_DECLARE_APP_ARGS(args, 00436 AST_APP_ARG(filenames); 00437 AST_APP_ARG(options); 00438 ); 00439 00440 if (ast_strlen_zero(data)) { 00441 ast_log(LOG_WARNING, "Playback requires an argument (filename)\n"); 00442 return -1; 00443 } 00444 00445 tmp = ast_strdupa(data); 00446 AST_STANDARD_APP_ARGS(args, tmp); 00447 00448 if (args.options) { 00449 if (strcasestr(args.options, "skip")) 00450 option_skip = 1; 00451 if (strcasestr(args.options, "say")) 00452 option_say = 1; 00453 if (strcasestr(args.options, "noanswer")) 00454 option_noanswer = 1; 00455 } 00456 if (chan->_state != AST_STATE_UP) { 00457 if (option_skip) { 00458 /* At the user's option, skip if the line is not up */ 00459 goto done; 00460 } else if (!option_noanswer) { 00461 /* Otherwise answer unless we're supposed to send this while on-hook */ 00462 res = ast_answer(chan); 00463 } 00464 } 00465 if (!res) { 00466 char *back = args.filenames; 00467 char *front; 00468 00469 ast_stopstream(chan); 00470 while (!res && (front = strsep(&back, "&"))) { 00471 if (option_say) 00472 res = say_full(chan, front, "", chan->language, NULL, -1, -1); 00473 else 00474 res = ast_streamfile(chan, front, chan->language); 00475 if (!res) { 00476 res = ast_waitstream(chan, ""); 00477 ast_stopstream(chan); 00478 } else { 00479 ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data); 00480 res = 0; 00481 mres = 1; 00482 } 00483 } 00484 } 00485 done: 00486 pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", mres ? "FAILED" : "SUCCESS"); 00487 return res; 00488 }
static int reload | ( | void | ) | [static] |
Definition at line 490 of file app_playback.c.
References ast_config_destroy(), ast_config_load, ast_extension_match(), ast_log(), ast_variable_browse(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, LOG_NOTICE, ast_variable::name, ast_variable::next, say_init_mode(), and ast_variable::value.
00491 { 00492 struct ast_variable *v; 00493 struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED }; 00494 struct ast_config *newcfg; 00495 00496 if ((newcfg = ast_config_load("say.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 00497 return 0; 00498 } else if (newcfg == CONFIG_STATUS_FILEINVALID) { 00499 ast_log(LOG_ERROR, "Config file say.conf is in an invalid format. Aborting.\n"); 00500 return 0; 00501 } 00502 00503 if (say_cfg) { 00504 ast_config_destroy(say_cfg); 00505 ast_log(LOG_NOTICE, "Reloading say.conf\n"); 00506 } 00507 say_cfg = newcfg; 00508 00509 if (say_cfg) { 00510 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) { 00511 if (ast_extension_match(v->name, "mode")) { 00512 say_init_mode(v->value); 00513 break; 00514 } 00515 } 00516 } 00517 00518 /* 00519 * XXX here we should sort rules according to the same order 00520 * we have in pbx.c so we have the same matching behaviour. 00521 */ 00522 return 0; 00523 }
static void restore_say_mode | ( | void * | arg | ) | [static] |
Definition at line 117 of file app_playback.c.
References ast_say_character_str_full, ast_say_date, ast_say_date_with_format, ast_say_datetime, ast_say_datetime_from_now, ast_say_digit_str_full, ast_say_enumeration_full, ast_say_number_full, ast_say_phonetic_str_full, and ast_say_time.
Referenced by say_init_mode().
00118 { 00119 int i = 0; 00120 say_api_buf[i++] = arg; 00121 00122 ast_say_number_full = say_api_buf[i++]; 00123 ast_say_enumeration_full = say_api_buf[i++]; 00124 ast_say_digit_str_full = say_api_buf[i++]; 00125 ast_say_character_str_full = say_api_buf[i++]; 00126 ast_say_phonetic_str_full = say_api_buf[i++]; 00127 ast_say_datetime = say_api_buf[i++]; 00128 ast_say_time = say_api_buf[i++]; 00129 ast_say_date = say_api_buf[i++]; 00130 ast_say_datetime_from_now = say_api_buf[i++]; 00131 ast_say_date_with_format = say_api_buf[i++]; 00132 }
static int s_streamwait3 | ( | const say_args_t * | a, | |
const char * | fn | |||
) | [static] |
Definition at line 148 of file app_playback.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), say_args_t::audiofd, say_args_t::chan, say_args_t::ctrlfd, say_args_t::ints, say_args_t::language, and LOG_WARNING.
Referenced by do_say().
00149 { 00150 int res = ast_streamfile(a->chan, fn, a->language); 00151 if (res) { 00152 ast_log(LOG_WARNING, "Unable to play message %s\n", fn); 00153 return res; 00154 } 00155 res = (a->audiofd > -1 && a->ctrlfd > -1) ? 00156 ast_waitstream_full(a->chan, a->ints, a->audiofd, a->ctrlfd) : 00157 ast_waitstream(a->chan, a->ints); 00158 ast_stopstream(a->chan); 00159 return res; 00160 }
static void save_say_mode | ( | const void * | arg | ) | [static] |
Definition at line 100 of file app_playback.c.
References ast_say_character_str_full, ast_say_date, ast_say_date_with_format, ast_say_datetime, ast_say_datetime_from_now, ast_say_digit_str_full, ast_say_enumeration_full, ast_say_number_full, ast_say_phonetic_str_full, and ast_say_time.
Referenced by say_init_mode().
00101 { 00102 int i = 0; 00103 say_api_buf[i++] = arg; 00104 00105 say_api_buf[i++] = ast_say_number_full; 00106 say_api_buf[i++] = ast_say_enumeration_full; 00107 say_api_buf[i++] = ast_say_digit_str_full; 00108 say_api_buf[i++] = ast_say_character_str_full; 00109 say_api_buf[i++] = ast_say_phonetic_str_full; 00110 say_api_buf[i++] = ast_say_datetime; 00111 say_api_buf[i++] = ast_say_time; 00112 say_api_buf[i++] = ast_say_date; 00113 say_api_buf[i++] = ast_say_datetime_from_now; 00114 say_api_buf[i++] = ast_say_date_with_format; 00115 }
static int say_date | ( | struct ast_channel * | chan, | |
time_t | t, | |||
const char * | ints, | |||
const char * | lang | |||
) | [static] |
Definition at line 339 of file app_playback.c.
References say_date_generic().
Referenced by say_init_mode().
00340 { 00341 return say_date_generic(chan, t, ints, lang, "", NULL, "date"); 00342 }
static int say_date_generic | ( | struct ast_channel * | chan, | |
time_t | t, | |||
const char * | ints, | |||
const char * | lang, | |||
const char * | format, | |||
const char * | timezonename, | |||
const char * | prefix | |||
) | [static] |
Definition at line 308 of file app_playback.c.
References ast_localtime(), do_say(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, ast_tm::tm_wday, ast_tm::tm_yday, and ast_tm::tm_year.
Referenced by say_date(), say_date_with_format(), say_datetime(), and say_time().
00310 { 00311 char buf[128]; 00312 struct ast_tm tm; 00313 struct timeval when = { t, 0 }; 00314 say_args_t a = { chan, ints, lang, -1, -1 }; 00315 if (format == NULL) 00316 format = ""; 00317 00318 ast_localtime(&when, &tm, NULL); 00319 snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d", 00320 prefix, 00321 format, 00322 tm.tm_year+1900, 00323 tm.tm_mon+1, 00324 tm.tm_mday, 00325 tm.tm_hour, 00326 tm.tm_min, 00327 tm.tm_sec, 00328 tm.tm_wday, 00329 tm.tm_yday); 00330 return do_say(&a, buf, NULL, 0); 00331 }
static int say_date_with_format | ( | struct ast_channel * | chan, | |
time_t | t, | |||
const char * | ints, | |||
const char * | lang, | |||
const char * | format, | |||
const char * | timezonename | |||
) | [static] |
Definition at line 333 of file app_playback.c.
References say_date_generic().
Referenced by say_init_mode().
00335 { 00336 return say_date_generic(chan, t, ints, lang, format, timezonename, "datetime"); 00337 }
static int say_datetime | ( | struct ast_channel * | chan, | |
time_t | t, | |||
const char * | ints, | |||
const char * | lang | |||
) | [static] |
Definition at line 349 of file app_playback.c.
References say_date_generic().
Referenced by say_init_mode().
00350 { 00351 return say_date_generic(chan, t, ints, lang, "", NULL, "datetime"); 00352 }
static int say_enumeration_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
const char * | options, | |||
int | audiofd, | |||
int | ctrlfd | |||
) | [static] |
Definition at line 298 of file app_playback.c.
References do_say().
Referenced by say_init_mode().
00301 { 00302 char buf[64]; 00303 say_args_t a = { chan, ints, lang, audiofd, ctrlfd }; 00304 snprintf(buf, sizeof(buf), "enum:%d", num); 00305 return do_say(&a, buf, options, 0); 00306 }
static int say_full | ( | struct ast_channel * | chan, | |
const char * | string, | |||
const char * | ints, | |||
const char * | lang, | |||
const char * | options, | |||
int | audiofd, | |||
int | ctrlfd | |||
) | [static] |
Definition at line 280 of file app_playback.c.
References do_say().
Referenced by playback_exec().
00283 { 00284 say_args_t a = { chan, ints, lang, audiofd, ctrlfd }; 00285 return do_say(&a, string, options, 0); 00286 }
static int say_init_mode | ( | const char * | mode | ) | [static] |
Definition at line 357 of file app_playback.c.
References ast_log(), ast_say_character_str_full, ast_say_date, ast_say_date_with_format, ast_say_datetime, ast_say_datetime_from_now, ast_say_digit_str_full, ast_say_digits_full(), ast_say_enumeration_full, ast_say_number_full, ast_say_phonetic_str_full, ast_say_time, LOG_ERROR, LOG_WARNING, restore_say_mode(), save_say_mode(), say_character_str_full(), say_date(), say_date_with_format(), say_datetime(), say_datetime_from_now(), say_digit_str_full(), say_enumeration_full(), say_number_full(), say_phonetic_str_full(), and say_time().
Referenced by __say_cli_init(), load_module(), and reload().
00357 { 00358 if (!strcmp(mode, say_new)) { 00359 if (say_cfg == NULL) { 00360 ast_log(LOG_ERROR, "There is no say.conf file to use new mode\n"); 00361 return -1; 00362 } 00363 save_say_mode(say_new); 00364 ast_say_number_full = say_number_full; 00365 00366 ast_say_enumeration_full = say_enumeration_full; 00367 #if 0 00368 ast_say_digits_full = say_digits_full; 00369 ast_say_digit_str_full = say_digit_str_full; 00370 ast_say_character_str_full = say_character_str_full; 00371 ast_say_phonetic_str_full = say_phonetic_str_full; 00372 ast_say_datetime_from_now = say_datetime_from_now; 00373 #endif 00374 ast_say_datetime = say_datetime; 00375 ast_say_time = say_time; 00376 ast_say_date = say_date; 00377 ast_say_date_with_format = say_date_with_format; 00378 } else if (!strcmp(mode, say_old) && say_api_buf[0] == say_new) { 00379 restore_say_mode(NULL); 00380 } else if (strcmp(mode, say_old)) { 00381 ast_log(LOG_WARNING, "unrecognized mode %s\n", mode); 00382 return -1; 00383 } 00384 00385 return 0; 00386 }
static int say_number_full | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | ints, | |||
const char * | lang, | |||
const char * | options, | |||
int | audiofd, | |||
int | ctrlfd | |||
) | [static] |
Definition at line 288 of file app_playback.c.
References do_say().
Referenced by say_init_mode().
00291 { 00292 char buf[64]; 00293 say_args_t a = { chan, ints, lang, audiofd, ctrlfd }; 00294 snprintf(buf, sizeof(buf), "num:%d", num); 00295 return do_say(&a, buf, options, 0); 00296 }
static int say_time | ( | struct ast_channel * | chan, | |
time_t | t, | |||
const char * | ints, | |||
const char * | lang | |||
) | [static] |
Definition at line 344 of file app_playback.c.
References say_date_generic().
Referenced by say_init_mode().
00345 { 00346 return say_date_generic(chan, t, ints, lang, "", NULL, "time"); 00347 }
static int unload_module | ( | void | ) | [static] |
Definition at line 525 of file app_playback.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_config_destroy(), and ast_unregister_application().
00526 { 00527 int res; 00528 00529 res = ast_unregister_application(app); 00530 00531 ast_cli_unregister_multiple(cli_playback, ARRAY_LEN(cli_playback)); 00532 00533 if (say_cfg) 00534 ast_config_destroy(say_cfg); 00535 00536 return res; 00537 }
char* app = "Playback" [static] |
Definition at line 88 of file app_playback.c.
struct ast_cli_entry cli_playback[] [static] |
{ AST_CLI_DEFINE(__say_cli_init, "Set or show the say mode"), }
Definition at line 422 of file app_playback.c.
const void* say_api_buf[40] [static] |
Definition at line 96 of file app_playback.c.
struct ast_config* say_cfg = NULL [static] |
Definition at line 90 of file app_playback.c.
const char* const say_new = "new" [static] |
Definition at line 98 of file app_playback.c.
const char* const say_old = "old" [static] |
Definition at line 97 of file app_playback.c.