Asterisk - The Open Source Telephony Project GIT-master-773870a
Loading...
Searching...
No Matches
Data Structures | Functions | Variables
app_playback.c File Reference

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"
Include dependency graph for app_playback.c:

Go to the source code of this file.

Data Structures

struct  say_args_t
 Typical 'say' arguments in addition to the date or number or string to say. We do not include 'options' because they may be different in recursive calls, and so they are better left as an external parameter. More...
 

Functions

static void __reg_module (void)
 
static char * __say_cli_init (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int do_say (say_args_t *a, const char *s, const char *options, int depth)
 the string is 'prefix:data' or prefix:fmt:data' with ':' being invalid in strings.
 
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)
 remap the 'say' functions to use those in this file
 
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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Sound File Playback Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, }
 
static char * app = "Playback"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_playback []
 
static const void * say_api_buf [40]
 save the say' api calls. The first entry is NULL if we have the standard source, otherwise we are sourcing from here. 'say load [new|old]' will enable the new or old method, or report status
 
static struct ast_configsay_cfg = NULL
 
static const char *const say_new = "new"
 
static const char *const say_old = "old"
 

Detailed Description

Trivial application to playback a sound file.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file app_playback.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 608 of file app_playback.c.

◆ __say_cli_init()

static char * __say_cli_init ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 421 of file app_playback.c.

422{
423 const char *old_mode = say_api_buf[0] ? say_new : say_old;
424 const char *mode;
425 switch (cmd) {
426 case CLI_INIT:
427 e->command = "say load [new|old]";
428 e->usage =
429 "Usage: say load [new|old]\n"
430 " say load\n"
431 " Report status of current say mode\n"
432 " say load new\n"
433 " Set say method, configured in say.conf\n"
434 " say load old\n"
435 " Set old say method, coded in asterisk core\n";
436 return NULL;
437 case CLI_GENERATE:
438 return NULL;
439 }
440 if (a->argc == 2) {
441 ast_cli(a->fd, "say mode is [%s]\n", old_mode);
442 return CLI_SUCCESS;
443 } else if (a->argc != e->args)
444 return CLI_SHOWUSAGE;
445 mode = a->argv[2];
446 if (!strcmp(mode, old_mode))
447 ast_cli(a->fd, "say mode is %s already\n", mode);
448 else
449 if (say_init_mode(mode) == 0)
450 ast_cli(a->fd, "setting say mode from %s to %s\n", old_mode, mode);
451
452 return CLI_SUCCESS;
453}
static const char *const say_old
static const void * say_api_buf[40]
save the say' api calls. The first entry is NULL if we have the standard source, otherwise we are sou...
static const char *const say_new
static int say_init_mode(const char *mode)
remap the 'say' functions to use those in this file
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define NULL
Definition resample.c:96
int args
This gets set in ast_cli_register()
Definition cli.h:185
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
static struct test_val a

References a, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, say_api_buf, say_init_mode(), say_new, say_old, and ast_cli_entry::usage.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 608 of file app_playback.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 608 of file app_playback.c.

◆ do_say()

static int do_say ( say_args_t a,
const char *  s,
const char *  options,
int  depth 
)
static

the string is 'prefix:data' or prefix:fmt:data' with ':' being invalid in strings.

Definition at line 189 of file app_playback.c.

190{
191 struct ast_variable *v;
192 char *lang;
193 char *x;
194 const char *y;
195 char *rule = NULL;
196 char *rule_head = NULL;
197 int ret = 0;
198 struct varshead head = { .first = NULL, .last = NULL };
199 struct ast_var_t *n;
200
201 ast_debug(2, "string <%s> depth <%d>\n", s, depth);
202 if (depth++ > 10) {
203 ast_log(LOG_WARNING, "recursion too deep, exiting\n");
204 return -1;
205 } else if (!say_cfg) {
206 ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s);
207 return -1;
208 }
209
210 /* scan languages same as in file.c */
211 if (a->language == NULL)
212 a->language = "en"; /* default */
213 ast_debug(2, "try <%s> in <%s>\n", s, a->language);
214 lang = ast_strdupa(a->language);
215 for (;;) {
216 for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) {
217 if (ast_extension_match(v->name, s)) {
218 rule_head = rule = ast_strdup(v->value);
219 break;
220 }
221 }
222 if (rule)
223 break;
224 if ( (x = strchr(lang, '_')) )
225 *x = '\0'; /* try without suffix */
226 else if (strcmp(lang, "en"))
227 lang = "en"; /* last resort, try 'en' if not done yet */
228 else
229 break;
230 }
231 if (!rule)
232 return 0;
233
234 /* skip up to two prefixes to get the value */
235 if ( (y = strchr(s, ':')) )
236 s = y + 1;
237 if ( (y = strchr(s, ':')) )
238 s = y + 1;
239 ast_debug(2, "value is <%s>\n", s);
240 n = ast_var_assign("SAY", s);
241 if (!n) {
242 ast_log(LOG_ERROR, "Memory allocation error in do_say\n");
243 ast_free(rule_head);
244 return -1;
245 }
246 AST_LIST_INSERT_HEAD(&head, n, entries);
247
248 /* scan the body, one piece at a time */
249 while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */
250 char fn[128];
251 const char *p, *fmt, *data; /* format and data pointers */
252
253 /* prepare a decent file name */
254 x = ast_skip_blanks(x);
256
257 /* replace variables */
258 pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn));
259 ast_debug(2, "doing [%s]\n", fn);
260
261 /* locate prefix and data, if any */
262 fmt = strchr(fn, ':');
263 if (!fmt || fmt == fn) { /* regular filename */
264 ret = s_streamwait3(a, fn);
265 continue;
266 }
267 fmt++;
268 data = strchr(fmt, ':'); /* colon before data */
269 if (!data || data == fmt) { /* simple prefix-fmt */
270 ret = do_say(a, fn, options, depth);
271 continue;
272 }
273 /* prefix:fmt:data */
274 for (p = fmt; p < data && ret <= 0; p++) {
275 char fn2[sizeof(fn)];
276 if (*p == ' ' || *p == '\t') /* skip blanks */
277 continue;
278 if (*p == '\'') {/* file name - we trim them */
279 char *y;
280 strcpy(fn2, ast_skip_blanks(p+1)); /* make a full copy */
281 y = strchr(fn2, '\'');
282 if (!y) {
283 p = data; /* invalid. prepare to end */
284 break;
285 }
286 *y = '\0';
287 ast_trim_blanks(fn2);
288 p = strchr(p+1, '\'');
289 ret = s_streamwait3(a, fn2);
290 } else {
291 int l = fmt-fn;
292 strcpy(fn2, fn); /* copy everything */
293 /* after prefix, append the format */
294 fn2[l++] = *p;
295 strcpy(fn2 + l, data);
296 ret = do_say(a, fn2, options, depth);
297 }
298
299 if (ret) {
300 break;
301 }
302 }
303 }
305 ast_free(rule_head);
306 return ret;
307}
static struct ast_config * say_cfg
static int s_streamwait3(const say_args_t *a, const char *fn)
static int do_say(say_args_t *a, const char *s, const char *options, int depth)
the string is 'prefix:data' or prefix:fmt:data' with ':' being invalid in strings.
char * strsep(char **str, const char *delims)
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_log
Definition astobj2.c:42
#define ast_var_assign(name, value)
Definition chanvars.h:40
void ast_var_delete(struct ast_var_t *var)
Definition extconf.c:2469
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition extconf.c:4293
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition strings.h:186
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition strings.h:161
struct ast_var_t::@224 entries
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct ast_var_t * first
Definition chanvars.h:34
static struct test_options options

References a, ast_debug, ast_extension_match(), ast_free, AST_LIST_INSERT_HEAD, ast_log, ast_skip_blanks(), ast_strdup, ast_strdupa, ast_trim_blanks(), ast_var_assign, ast_var_delete(), ast_variable_browse(), do_say(), ast_var_t::entries, varshead::first, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, options, pbx_substitute_variables_varshead(), s_streamwait3(), say_cfg, strsep(), and ast_variable::value.

Referenced by do_say(), say_date_generic(), say_enumeration_full(), say_full(), and say_number_full().

◆ load_module()

static int load_module ( void  )
static

Definition at line 584 of file app_playback.c.

585{
586 struct ast_variable *v;
587 struct ast_flags config_flags = { 0 };
588
589 say_cfg = ast_config_load("say.conf", config_flags);
591 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
592 if (ast_extension_match(v->name, "mode")) {
594 break;
595 }
596 }
597 }
598
601}
static char * app
static struct ast_cli_entry cli_playback[]
static int playback_exec(struct ast_channel *chan, const char *data)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEINVALID
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition module.h:640
Structure used to handle boolean flags.
Definition utils.h:220
#define ARRAY_LEN(a)
Definition utils.h:706

References app, ARRAY_LEN, ast_cli_register_multiple, ast_config_load, ast_extension_match(), ast_register_application_xml, ast_variable_browse(), cli_playback, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, playback_exec(), say_cfg, say_init_mode(), and ast_variable::value.

◆ playback_exec()

static int playback_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 459 of file app_playback.c.

460{
461 int res = 0;
462 int mres = 0;
463 char *tmp;
464 int option_skip=0;
465 int option_say=0;
466 int option_mix=0;
467 int option_noanswer = 0;
468
470 AST_APP_ARG(filenames);
472 );
473
474 if (ast_strlen_zero(data)) {
475 ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
476 return -1;
477 }
478
479 tmp = ast_strdupa(data);
481
482 if (args.options) {
483 if (strcasestr(args.options, "skip"))
484 option_skip = 1;
485 if (strcasestr(args.options, "say"))
486 option_say = 1;
487 if (strcasestr(args.options, "mix"))
488 option_mix = 1;
489 if (strcasestr(args.options, "noanswer"))
490 option_noanswer = 1;
491 }
492 if (ast_channel_state(chan) != AST_STATE_UP) {
493 if (option_skip) {
494 /* At the user's option, skip if the line is not up */
495 goto done;
496 } else if (!option_noanswer) {
497 /* Otherwise answer unless we're supposed to send this while on-hook */
498 res = ast_answer(chan);
499 }
500 }
501 if (!res) {
502 char *back = args.filenames;
503 char *front;
504
505 ast_stopstream(chan);
506 while (!res && (front = ast_strsep(&back, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
507 if (option_say)
508 res = say_full(chan, front, "", ast_channel_language(chan), NULL, -1, -1);
509 else if (option_mix){
510 /* Check if it is in say format but not remote audio file */
511 if (strcasestr(front, ":") && !strcasestr(front, "://"))
512 res = say_full(chan, front, "", ast_channel_language(chan), NULL, -1, -1);
513 else
514 res = ast_streamfile(chan, front, ast_channel_language(chan));
515 }
516 else
517 res = ast_streamfile(chan, front, ast_channel_language(chan));
518 if (!res) {
519 res = ast_waitstream(chan, "");
520 ast_stopstream(chan);
521 } else {
522 if (!ast_check_hangup(chan)) {
523 ast_log(LOG_WARNING, "Playback failed on %s for %s\n", ast_channel_name(chan), (char *)data);
524 }
525 res = 0;
526 mres = 1;
527 }
528 }
529 }
530done:
531 pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", mres ? "FAILED" : "SUCCESS");
532 return res;
533}
static int say_full(struct ast_channel *chan, const char *string, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd)
char * strcasestr(const char *, const char *)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition channel.c:445
const char * ast_channel_language(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition channel.c:2803
ast_channel_state
ast_channel states
@ AST_STATE_UP
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition file.c:223
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition file.c:1312
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition file.c:1874
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
static struct @522 args
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
@ AST_STRSEP_TRIM
Definition strings.h:256
@ AST_STRSEP_STRIP
Definition strings.h:255
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition utils.c:1869
int done

References args, ast_answer(), AST_APP_ARG, ast_channel_language(), ast_channel_name(), ast_check_hangup(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, ast_waitstream(), done, LOG_WARNING, NULL, options, pbx_builtin_setvar_helper(), say_full(), and strcasestr().

Referenced by load_module().

◆ reload()

static int reload ( void  )
static
Todo:
XXX here we should sort rules according to the same order we have in pbx.c so we have the same matching behaviour.

Definition at line 535 of file app_playback.c.

536{
537 struct ast_variable *v;
538 struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
539 struct ast_config *newcfg;
540
541 if ((newcfg = ast_config_load("say.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
542 return 0;
543 } else if (newcfg == CONFIG_STATUS_FILEINVALID) {
544 ast_log(LOG_ERROR, "Config file say.conf is in an invalid format. Aborting.\n");
545 return 0;
546 }
547
548 if (say_cfg) {
550 ast_log(LOG_NOTICE, "Reloading say.conf\n");
551 }
552 say_cfg = newcfg;
553
554 if (say_cfg) {
555 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
556 if (ast_extension_match(v->name, "mode")) {
558 break;
559 }
560 }
561 }
562
563 /*! \todo
564 * XXX here we should sort rules according to the same order
565 * we have in pbx.c so we have the same matching behaviour.
566 */
567 return 0;
568}
#define CONFIG_STATUS_FILEUNCHANGED
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
@ CONFIG_FLAG_FILEUNCHANGED
#define LOG_NOTICE

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_cfg, say_init_mode(), and ast_variable::value.

◆ restore_say_mode()

static void restore_say_mode ( void *  arg)
static

Definition at line 140 of file app_playback.c.

141{
142 int i = 0;
143 say_api_buf[i++] = arg;
144
155}
SAY_EXTERN int(* ast_say_datetime_from_now)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime_from_now)
Definition say.h:206
SAY_EXTERN int(* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date)
Definition say.h:204
SAY_EXTERN int(* ast_say_number_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_number_full)
Same as ast_say_number() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition say.h:86
SAY_EXTERN int(* ast_say_enumeration_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_enumeration_full)
Same as ast_say_enumeration() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition say.h:125
SAY_EXTERN int(* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full)
Definition say.h:194
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
Definition say.h:208
SAY_EXTERN int(* ast_say_digit_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digit_str_full)
Same as ast_say_digit_str() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition say.h:162
SAY_EXTERN int(* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time)
Definition say.h:202
SAY_EXTERN int(* ast_say_phonetic_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_phonetic_str_full)
Definition say.h:199
SAY_EXTERN int(* ast_say_datetime)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime)
Definition say.h:201

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, ast_say_time, and say_api_buf.

Referenced by say_init_mode().

◆ s_streamwait3()

static int s_streamwait3 ( const say_args_t a,
const char *  fn 
)
static

Definition at line 171 of file app_playback.c.

172{
173 int res = ast_streamfile(a->chan, fn, a->language);
174 if (res) {
175 ast_log(LOG_WARNING, "Unable to play message %s\n", fn);
176 return res;
177 }
178 res = (a->audiofd > -1 && a->ctrlfd > -1) ?
179 ast_waitstream_full(a->chan, a->ints, a->audiofd, a->ctrlfd) :
180 ast_waitstream(a->chan, a->ints);
181 ast_stopstream(a->chan);
182 return res;
183}
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition file.c:1883

References a, ast_log, ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_waitstream_full(), and LOG_WARNING.

Referenced by do_say().

◆ save_say_mode()

static void save_say_mode ( const void *  arg)
static

◆ say_date()

static int say_date ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Definition at line 368 of file app_playback.c.

369{
370 return say_date_generic(chan, t, ints, lang, "", NULL, "date");
371}
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)

References NULL, and say_date_generic().

Referenced by say_init_mode().

◆ say_date_generic()

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 337 of file app_playback.c.

339{
340 char buf[128];
341 struct ast_tm tm;
342 struct timeval when = { t, 0 };
343 say_args_t a = { chan, ints, lang, -1, -1 };
344 if (format == NULL)
345 format = "";
346
347 ast_localtime(&when, &tm, timezonename);
348 snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d",
349 prefix,
350 format,
351 tm.tm_year+1900,
352 tm.tm_mon+1,
353 tm.tm_mday,
354 tm.tm_hour,
355 tm.tm_min,
356 tm.tm_sec,
357 tm.tm_wday,
358 tm.tm_yday);
359 return do_say(&a, buf, NULL, 0);
360}
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static char prefix[MAX_PREFIX]
Definition http.c:144
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition localtime.c:1739
Typical 'say' arguments in addition to the date or number or string to say. We do not include 'option...

References a, ast_localtime(), buf, do_say(), NULL, prefix, 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().

◆ say_date_with_format()

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 362 of file app_playback.c.

364{
365 return say_date_generic(chan, t, ints, lang, format, timezonename, "datetime");
366}

References say_date_generic().

Referenced by say_init_mode().

◆ say_datetime()

static int say_datetime ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Definition at line 378 of file app_playback.c.

379{
380 return say_date_generic(chan, t, ints, lang, "", NULL, "datetime");
381}

References NULL, and say_date_generic().

Referenced by say_init_mode().

◆ say_enumeration_full()

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 327 of file app_playback.c.

330{
331 char buf[64];
332 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
333 snprintf(buf, sizeof(buf), "enum:%d", num);
334 return do_say(&a, buf, options, 0);
335}

References a, buf, do_say(), and options.

Referenced by say_init_mode().

◆ say_full()

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 309 of file app_playback.c.

312{
313 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
314 return do_say(&a, string, options, 0);
315}

References a, do_say(), and options.

Referenced by playback_exec().

◆ say_init_mode()

static int say_init_mode ( const char *  mode)
static

remap the 'say' functions to use those in this file

Definition at line 386 of file app_playback.c.

386 {
387 if (!strcmp(mode, say_new)) {
388 if (say_cfg == NULL) {
389 ast_log(LOG_ERROR, "There is no say.conf file to use new mode\n");
390 return -1;
391 }
394
396#if 0
397 /*! \todo XXX
398 These functions doesn't exist.
399 say.conf.sample indicates this is working...
400 */
401 ast_say_digits_full = say_digits_full;
406#endif
411 } else if (!strcmp(mode, say_old) && say_api_buf[0] == say_new) {
413 } else if (strcmp(mode, say_old)) {
414 ast_log(LOG_WARNING, "unrecognized mode %s\n", mode);
415 return -1;
416 }
417
418 return 0;
419}
static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
static void restore_say_mode(void *arg)
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_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd)
static void save_say_mode(const void *arg)
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_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition say.c:8436
static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
Definition say.c:348
static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
Definition say.c:294
static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
Definition say.c:210
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
Same as ast_say_digits() with audiofd for received audio and returns 1 on ctrlfd being readable.
Definition channel.c:8327

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, NULL, restore_say_mode(), save_say_mode(), say_api_buf, say_cfg, say_character_str_full(), say_date(), say_date_with_format(), say_datetime(), say_datetime_from_now(), say_digit_str_full(), say_enumeration_full(), say_new, say_number_full(), say_old, say_phonetic_str_full(), and say_time().

Referenced by __say_cli_init(), load_module(), and reload().

◆ say_number_full()

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 317 of file app_playback.c.

320{
321 char buf[64];
322 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
323 snprintf(buf, sizeof(buf), "num:%d", num);
324 return do_say(&a, buf, options, 0);
325}

References a, buf, do_say(), and options.

Referenced by say_init_mode().

◆ say_time()

static int say_time ( struct ast_channel chan,
time_t  t,
const char *  ints,
const char *  lang 
)
static

Definition at line 373 of file app_playback.c.

374{
375 return say_date_generic(chan, t, ints, lang, "", NULL, "time");
376}

References NULL, and say_date_generic().

Referenced by say_init_mode().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 570 of file app_playback.c.

571{
572 int res;
573
575
577
578 if (say_cfg)
580
581 return res;
582}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
int ast_unregister_application(const char *app)
Unregister an application.
Definition pbx_app.c:392

References app, ARRAY_LEN, ast_cli_unregister_multiple(), ast_config_destroy(), ast_unregister_application(), cli_playback, and say_cfg.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Sound File Playback Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 608 of file app_playback.c.

◆ app

char* app = "Playback"
static

< provides config-file based 'say' functions

Definition at line 110 of file app_playback.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 608 of file app_playback.c.

◆ cli_playback

struct ast_cli_entry cli_playback[]
static
Initial value:
= {
{ .handler = __say_cli_init , .summary = "Set or show the say mode" ,},
}
static char * __say_cli_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 455 of file app_playback.c.

455 {
456 AST_CLI_DEFINE(__say_cli_init, "Set or show the say mode"),
457};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by load_module(), and unload_module().

◆ say_api_buf

const void* say_api_buf[40]
static

save the say' api calls. The first entry is NULL if we have the standard source, otherwise we are sourcing from here. 'say load [new|old]' will enable the new or old method, or report status

Definition at line 119 of file app_playback.c.

Referenced by __say_cli_init(), restore_say_mode(), save_say_mode(), and say_init_mode().

◆ say_cfg

struct ast_config* say_cfg = NULL
static

Definition at line 112 of file app_playback.c.

Referenced by do_say(), load_module(), reload(), say_init_mode(), and unload_module().

◆ say_new

const char* const say_new = "new"
static

Definition at line 121 of file app_playback.c.

Referenced by __say_cli_init(), and say_init_mode().

◆ say_old

const char* const say_old = "old"
static

Definition at line 120 of file app_playback.c.

Referenced by __say_cli_init(), and say_init_mode().