Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
app_playback.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Trivial application to playback a sound file
22 *
23 * \author Mark Spencer <markster@digium.com>
24 *
25 * \ingroup applications
26 */
27
28/*** MODULEINFO
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#include "asterisk/file.h"
35#include "asterisk/pbx.h"
36#include "asterisk/module.h"
37#include "asterisk/app.h"
38/* This file provides config-file based 'say' functions, and implements
39 * some CLI commands.
40 */
41#include "asterisk/say.h" /*!< provides config-file based 'say' functions */
42#include "asterisk/cli.h"
43
44/*** DOCUMENTATION
45 <application name="Playback" language="en_US">
46 <since>
47 <version>0.1.0</version>
48 </since>
49 <synopsis>
50 Play a file.
51 </synopsis>
52 <syntax>
53 <parameter name="filenames" required="true" argsep="&amp;">
54 <para>Ampersand separated list of filenames. If the filename
55 is a relative filename (it does not begin with a slash), it
56 will be searched for in the Asterisk sounds directory. If the
57 filename is able to be parsed as a URL, Asterisk will
58 download the file and then begin playback on it. To include a
59 literal <literal>&amp;</literal> in the URL you can enclose
60 the URL in single quotes.</para>
61 <argument name="filename" required="true" />
62 <argument name="filename2" multiple="true" />
63 </parameter>
64 <parameter name="options">
65 <para>Comma separated list of options</para>
66 <optionlist>
67 <option name="skip">
68 <para>Do not play if not answered</para>
69 </option>
70 <option name="noanswer">
71 <para>Playback without answering, otherwise the channel will
72 be answered before the sound is played.</para>
73 <note><para>Not all channel types support playing messages while still on hook.</para></note>
74 </option>
75 <option name="say">
76 <para>Play using the say.conf file.</para>
77 </option>
78 <option name="mix">
79 <para>Play using a mix of filename and the say.conf file.</para>
80 </option>
81 </optionlist>
82 </parameter>
83 </syntax>
84 <description>
85 <para>Plays back given filenames (do not put extension of wav/alaw etc).
86 The Playback application answers the channel if no options are specified.
87 If the file is non-existent it will fail.</para>
88 <para>This application sets the following channel variable upon completion:</para>
89 <variablelist>
90 <variable name="PLAYBACKSTATUS">
91 <para>The status of the playback attempt as a text string.</para>
92 <value name="SUCCESS"/>
93 <value name="FAILED"/>
94 </variable>
95 </variablelist>
96 <para>See Also: Background (application) -- for playing sound files that are interruptible</para>
97 <para>WaitExten (application) -- wait for digits from caller, optionally play music on hold</para>
98 </description>
99 <see-also>
100 <ref type="application">BackGround</ref>
101 <ref type="application">WaitExten</ref>
102 <ref type="application">ControlPlayback</ref>
103 <ref type="agi">stream file</ref>
104 <ref type="agi">control stream file</ref>
105 <ref type="manager">ControlPlayback</ref>
106 </see-also>
107 </application>
108 ***/
109
110static char *app = "Playback";
111
112static struct ast_config *say_cfg = NULL;
113
114/*! \brief save the say' api calls.
115 * The first entry is NULL if we have the standard source,
116 * otherwise we are sourcing from here.
117 * 'say load [new|old]' will enable the new or old method, or report status
118 */
119static const void *say_api_buf[40];
120static const char * const say_old = "old";
121static const char * const say_new = "new";
122
123static void save_say_mode(const void *arg)
124{
125 int i = 0;
126 say_api_buf[i++] = arg;
127
138}
139
140static void restore_say_mode(void *arg)
141{
142 int i = 0;
143 say_api_buf[i++] = arg;
144
155}
156
157/*! \brief
158 * Typical 'say' arguments in addition to the date or number or string
159 * to say. We do not include 'options' because they may be different
160 * in recursive calls, and so they are better left as an external
161 * parameter.
162 */
163typedef struct {
165 const char *ints;
166 const char *language;
169} say_args_t;
170
171static int s_streamwait3(const say_args_t *a, const char *fn)
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}
184
185/*! \brief
186 * the string is 'prefix:data' or prefix:fmt:data'
187 * with ':' being invalid in strings.
188 */
189static int do_say(say_args_t *a, const char *s, const char *options, int depth)
190{
191 struct ast_variable *v;
192 char *lang;
193 char *x;
194 char *rule = NULL;
195 char *rule_head = NULL;
196 int ret = 0;
197 struct varshead head = { .first = NULL, .last = NULL };
198 struct ast_var_t *n;
199
200 ast_debug(2, "string <%s> depth <%d>\n", s, depth);
201 if (depth++ > 10) {
202 ast_log(LOG_WARNING, "recursion too deep, exiting\n");
203 return -1;
204 } else if (!say_cfg) {
205 ast_log(LOG_WARNING, "no say.conf, cannot spell '%s'\n", s);
206 return -1;
207 }
208
209 /* scan languages same as in file.c */
210 if (a->language == NULL)
211 a->language = "en"; /* default */
212 ast_debug(2, "try <%s> in <%s>\n", s, a->language);
213 lang = ast_strdupa(a->language);
214 for (;;) {
215 for (v = ast_variable_browse(say_cfg, lang); v ; v = v->next) {
216 if (ast_extension_match(v->name, s)) {
217 rule_head = rule = ast_strdup(v->value);
218 break;
219 }
220 }
221 if (rule)
222 break;
223 if ( (x = strchr(lang, '_')) )
224 *x = '\0'; /* try without suffix */
225 else if (strcmp(lang, "en"))
226 lang = "en"; /* last resort, try 'en' if not done yet */
227 else
228 break;
229 }
230 if (!rule)
231 return 0;
232
233 /* skip up to two prefixes to get the value */
234 if ( (x = strchr(s, ':')) )
235 s = x + 1;
236 if ( (x = strchr(s, ':')) )
237 s = x + 1;
238 ast_debug(2, "value is <%s>\n", s);
239 n = ast_var_assign("SAY", s);
240 if (!n) {
241 ast_log(LOG_ERROR, "Memory allocation error in do_say\n");
242 ast_free(rule_head);
243 return -1;
244 }
245 AST_LIST_INSERT_HEAD(&head, n, entries);
246
247 /* scan the body, one piece at a time */
248 while ( !ret && (x = strsep(&rule, ",")) ) { /* exit on key */
249 char fn[128];
250 const char *p, *fmt, *data; /* format and data pointers */
251
252 /* prepare a decent file name */
253 x = ast_skip_blanks(x);
255
256 /* replace variables */
257 pbx_substitute_variables_varshead(&head, x, fn, sizeof(fn));
258 ast_debug(2, "doing [%s]\n", fn);
259
260 /* locate prefix and data, if any */
261 fmt = strchr(fn, ':');
262 if (!fmt || fmt == fn) { /* regular filename */
263 ret = s_streamwait3(a, fn);
264 continue;
265 }
266 fmt++;
267 data = strchr(fmt, ':'); /* colon before data */
268 if (!data || data == fmt) { /* simple prefix-fmt */
269 ret = do_say(a, fn, options, depth);
270 continue;
271 }
272 /* prefix:fmt:data */
273 for (p = fmt; p < data && ret <= 0; p++) {
274 char fn2[sizeof(fn)];
275 if (*p == ' ' || *p == '\t') /* skip blanks */
276 continue;
277 if (*p == '\'') {/* file name - we trim them */
278 char *y;
279 strcpy(fn2, ast_skip_blanks(p+1)); /* make a full copy */
280 y = strchr(fn2, '\'');
281 if (!y) {
282 p = data; /* invalid. prepare to end */
283 break;
284 }
285 *y = '\0';
286 ast_trim_blanks(fn2);
287 p = strchr(p+1, '\'');
288 ret = s_streamwait3(a, fn2);
289 } else {
290 int l = fmt-fn;
291 strcpy(fn2, fn); /* copy everything */
292 /* after prefix, append the format */
293 fn2[l++] = *p;
294 strcpy(fn2 + l, data);
295 ret = do_say(a, fn2, options, depth);
296 }
297
298 if (ret) {
299 break;
300 }
301 }
302 }
304 ast_free(rule_head);
305 return ret;
306}
307
308static int say_full(struct ast_channel *chan, const char *string,
309 const char *ints, const char *lang, const char *options,
310 int audiofd, int ctrlfd)
311{
312 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
313 return do_say(&a, string, options, 0);
314}
315
316static int say_number_full(struct ast_channel *chan, int num,
317 const char *ints, const char *lang, const char *options,
318 int audiofd, int ctrlfd)
319{
320 char buf[64];
321 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
322 snprintf(buf, sizeof(buf), "num:%d", num);
323 return do_say(&a, buf, options, 0);
324}
325
326static int say_enumeration_full(struct ast_channel *chan, int num,
327 const char *ints, const char *lang, const char *options,
328 int audiofd, int ctrlfd)
329{
330 char buf[64];
331 say_args_t a = { chan, ints, lang, audiofd, ctrlfd };
332 snprintf(buf, sizeof(buf), "enum:%d", num);
333 return do_say(&a, buf, options, 0);
334}
335
336static int say_date_generic(struct ast_channel *chan, time_t t,
337 const char *ints, const char *lang, const char *format, const char *timezonename, const char *prefix)
338{
339 char buf[128];
340 struct ast_tm tm;
341 struct timeval when = { t, 0 };
342 say_args_t a = { chan, ints, lang, -1, -1 };
343 if (format == NULL)
344 format = "";
345
346 ast_localtime(&when, &tm, timezonename);
347 snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d",
348 prefix,
349 format,
350 tm.tm_year+1900,
351 tm.tm_mon+1,
352 tm.tm_mday,
353 tm.tm_hour,
354 tm.tm_min,
355 tm.tm_sec,
356 tm.tm_wday,
357 tm.tm_yday);
358 return do_say(&a, buf, NULL, 0);
359}
360
361static int say_date_with_format(struct ast_channel *chan, time_t t,
362 const char *ints, const char *lang, const char *format, const char *timezonename)
363{
364 return say_date_generic(chan, t, ints, lang, format, timezonename, "datetime");
365}
366
367static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
368{
369 return say_date_generic(chan, t, ints, lang, "", NULL, "date");
370}
371
372static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
373{
374 return say_date_generic(chan, t, ints, lang, "", NULL, "time");
375}
376
377static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
378{
379 return say_date_generic(chan, t, ints, lang, "", NULL, "datetime");
380}
381
382/*! \brief
383 * remap the 'say' functions to use those in this file
384 */
385static int say_init_mode(const char *mode) {
386 if (!strcmp(mode, say_new)) {
387 if (say_cfg == NULL) {
388 ast_log(LOG_ERROR, "There is no say.conf file to use new mode\n");
389 return -1;
390 }
393
395#if 0
396 /*! \todo XXX
397 These functions doesn't exist.
398 say.conf.sample indicates this is working...
399 */
400 ast_say_digits_full = say_digits_full;
405#endif
410 } else if (!strcmp(mode, say_old) && say_api_buf[0] == say_new) {
412 } else if (strcmp(mode, say_old)) {
413 ast_log(LOG_WARNING, "unrecognized mode %s\n", mode);
414 return -1;
415 }
416
417 return 0;
418}
419
420static char *__say_cli_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
421{
422 const char *old_mode = say_api_buf[0] ? say_new : say_old;
423 const char *mode;
424 switch (cmd) {
425 case CLI_INIT:
426 e->command = "say load [new|old]";
427 e->usage =
428 "Usage: say load [new|old]\n"
429 " say load\n"
430 " Report status of current say mode\n"
431 " say load new\n"
432 " Set say method, configured in say.conf\n"
433 " say load old\n"
434 " Set old say method, coded in asterisk core\n";
435 return NULL;
436 case CLI_GENERATE:
437 return NULL;
438 }
439 if (a->argc == 2) {
440 ast_cli(a->fd, "say mode is [%s]\n", old_mode);
441 return CLI_SUCCESS;
442 } else if (a->argc != e->args)
443 return CLI_SHOWUSAGE;
444 mode = a->argv[2];
445 if (!strcmp(mode, old_mode))
446 ast_cli(a->fd, "say mode is %s already\n", mode);
447 else
448 if (say_init_mode(mode) == 0)
449 ast_cli(a->fd, "setting say mode from %s to %s\n", old_mode, mode);
450
451 return CLI_SUCCESS;
452}
453
454static struct ast_cli_entry cli_playback[] = {
455 AST_CLI_DEFINE(__say_cli_init, "Set or show the say mode"),
456};
457
458static int playback_exec(struct ast_channel *chan, const char *data)
459{
460 int res = 0;
461 int mres = 0;
462 char *tmp;
463 int option_skip=0;
464 int option_say=0;
465 int option_mix=0;
466 int option_noanswer = 0;
467
469 AST_APP_ARG(filenames);
471 );
472
473 if (ast_strlen_zero(data)) {
474 ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
475 return -1;
476 }
477
478 tmp = ast_strdupa(data);
480
481 if (args.options) {
482 if (strcasestr(args.options, "skip"))
483 option_skip = 1;
484 if (strcasestr(args.options, "say"))
485 option_say = 1;
486 if (strcasestr(args.options, "mix"))
487 option_mix = 1;
488 if (strcasestr(args.options, "noanswer"))
489 option_noanswer = 1;
490 }
491 if (ast_channel_state(chan) != AST_STATE_UP) {
492 if (option_skip) {
493 /* At the user's option, skip if the line is not up */
494 goto done;
495 } else if (!option_noanswer) {
496 /* Otherwise answer unless we're supposed to send this while on-hook */
497 res = ast_answer(chan);
498 }
499 }
500 if (!res) {
501 char *back = args.filenames;
502 char *front;
503
504 ast_stopstream(chan);
505 while (!res && (front = ast_strsep(&back, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
506 if (option_say)
507 res = say_full(chan, front, "", ast_channel_language(chan), NULL, -1, -1);
508 else if (option_mix){
509 /* Check if it is in say format but not remote audio file */
510 if (strcasestr(front, ":") && !strcasestr(front, "://"))
511 res = say_full(chan, front, "", ast_channel_language(chan), NULL, -1, -1);
512 else
513 res = ast_streamfile(chan, front, ast_channel_language(chan));
514 }
515 else
516 res = ast_streamfile(chan, front, ast_channel_language(chan));
517 if (!res) {
518 res = ast_waitstream(chan, "");
519 ast_stopstream(chan);
520 } else {
521 if (!ast_check_hangup(chan)) {
522 ast_log(LOG_WARNING, "Playback failed on %s for %s\n", ast_channel_name(chan), (char *)data);
523 }
524 res = 0;
525 mres = 1;
526 }
527 }
528 }
529done:
530 pbx_builtin_setvar_helper(chan, "PLAYBACKSTATUS", mres ? "FAILED" : "SUCCESS");
531 return res;
532}
533
534static int reload(void)
535{
536 struct ast_variable *v;
537 struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
538 struct ast_config *newcfg;
539
540 if ((newcfg = ast_config_load("say.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
541 return 0;
542 } else if (newcfg == CONFIG_STATUS_FILEINVALID) {
543 ast_log(LOG_ERROR, "Config file say.conf is in an invalid format. Aborting.\n");
544 return 0;
545 }
546
547 if (say_cfg) {
549 ast_log(LOG_NOTICE, "Reloading say.conf\n");
550 }
551 say_cfg = newcfg;
552
553 if (say_cfg) {
554 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
555 if (ast_extension_match(v->name, "mode")) {
557 break;
558 }
559 }
560 }
561
562 /*! \todo
563 * XXX here we should sort rules according to the same order
564 * we have in pbx.c so we have the same matching behaviour.
565 */
566 return 0;
567}
568
569static int unload_module(void)
570{
571 int res;
572
574
576
577 if (say_cfg)
579
580 return res;
581}
582
583static int load_module(void)
584{
585 struct ast_variable *v;
586 struct ast_flags config_flags = { 0 };
587
588 say_cfg = ast_config_load("say.conf", config_flags);
590 for (v = ast_variable_browse(say_cfg, "general"); v ; v = v->next) {
591 if (ast_extension_match(v->name, "mode")) {
593 break;
594 }
595 }
596 }
597
600}
601
602AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Sound File Playback Application",
603 .support_level = AST_MODULE_SUPPORT_CORE,
604 .load = load_module,
605 .unload = unload_module,
606 .reload = reload,
static struct ast_config * say_cfg
Definition: app_playback.c:112
static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: app_playback.c:372
static void restore_say_mode(void *arg)
Definition: app_playback.c:140
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)
Definition: app_playback.c:336
static char * __say_cli_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_playback.c:420
static int s_streamwait3(const say_args_t *a, const char *fn)
Definition: app_playback.c:171
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)
Definition: app_playback.c:361
static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd)
Definition: app_playback.c:326
static int say_full(struct ast_channel *chan, const char *string, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd)
Definition: app_playback.c:308
static void save_say_mode(const void *arg)
Definition: app_playback.c:123
static int say_number_full(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd)
Definition: app_playback.c:316
static char * app
Definition: app_playback.c:110
static struct ast_cli_entry cli_playback[]
Definition: app_playback.c:454
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.
Definition: app_playback.c:189
static const char *const say_old
Definition: app_playback.c:120
static int load_module(void)
Definition: app_playback.c:583
static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: app_playback.c:377
static int unload_module(void)
Definition: app_playback.c:569
static int reload(void)
Definition: app_playback.c:534
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...
Definition: app_playback.c:119
static const char *const say_new
Definition: app_playback.c:121
static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: app_playback.c:367
static int say_init_mode(const char *mode)
remap the 'say' functions to use those in this file
Definition: app_playback.c:385
static int playback_exec(struct ast_channel *chan, const char *data)
Definition: app_playback.c:458
char * strsep(char **str, const char *delims)
char * strcasestr(const char *, const char *)
Asterisk main include file. File version handling, generic pbx functions.
#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
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:2834
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
#define ast_var_assign(name, value)
Definition: chanvars.h:40
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
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 ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd)
Definition: file.c:1857
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1301
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1848
static char prefix[MAX_PREFIX]
Definition: http.c:144
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#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.
#define ast_config_load(filename, flags)
Load a config file.
@ CONFIG_FLAG_FILEUNCHANGED
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
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
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition: module.h:329
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
Core PBX routines and definitions.
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
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.
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:4295
#define NULL
Definition: resample.c:96
static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
Definition: say.c:7994
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
Say numbers and dates (maybe words one day too)
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
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:8309
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
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_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:186
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
Main Channel structure associated with a channel.
descriptor for a cli entry.
Definition: cli.h:171
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
Structure used to handle boolean flags.
Definition: utils.h:199
int tm_mday
Definition: localtime.h:39
int tm_sec
Definition: localtime.h:36
int tm_wday
Definition: localtime.h:42
int tm_hour
Definition: localtime.h:38
int tm_yday
Definition: localtime.h:43
int tm_min
Definition: localtime.h:37
int tm_year
Definition: localtime.h:41
int tm_mon
Definition: localtime.h:40
struct ast_var_t::@213 entries
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Typical 'say' arguments in addition to the date or number or string to say. We do not include 'option...
Definition: app_playback.c:163
struct ast_channel * chan
Definition: app_playback.c:164
const char * ints
Definition: app_playback.c:165
const char * language
Definition: app_playback.c:166
struct ast_var_t * first
Definition: chanvars.h:34
int done
Definition: test_amihooks.c:48
const char * args
static struct test_options options
static struct test_val a
#define ARRAY_LEN(a)
Definition: utils.h:666