Asterisk - The Open Source Telephony Project GIT-master-f36a736
Macros | Enumerations | Functions | Variables
app_record.c File Reference

Trivial application to record 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/channel.h"
#include "asterisk/dsp.h"
#include "asterisk/format_cache.h"
#include "asterisk/paths.h"
Include dependency graph for app_record.c:

Go to the source code of this file.

Macros

#define OPERATOR_KEY   '0'
 

Enumerations

enum  {
  OPTION_APPEND = (1 << 0) , OPTION_NOANSWER = (1 << 1) , OPTION_QUIET = (1 << 2) , OPTION_SKIP = (1 << 3) ,
  OPTION_STAR_TERMINATE = (1 << 4) , OPTION_IGNORE_TERMINATE = (1 << 5) , OPTION_KEEP = (1 << 6) , OPTION_ANY_TERMINATE = (1 << 7) ,
  OPTION_OPERATOR_EXIT = (1 << 8) , OPTION_NO_TRUNCATE = (1 << 9)
}
 
enum  dtmf_response { RESPONSE_NO_MATCH = 0 , RESPONSE_OPERATOR , RESPONSE_DTMF }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int create_destination_directory (const char *path)
 
static int load_module (void)
 
static enum dtmf_response record_dtmf_response (struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator)
 
static int record_exec (struct ast_channel *chan, const char *data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Trivial Record Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static char * app = "Record"
 
static const struct ast_app_option app_opts [128] = { [ 'a' ] = { .flag = OPTION_APPEND }, [ 'k' ] = { .flag = OPTION_KEEP }, [ 'n' ] = { .flag = OPTION_NOANSWER }, [ 'o' ] = { .flag = OPTION_OPERATOR_EXIT }, [ 'q' ] = { .flag = OPTION_QUIET }, [ 's' ] = { .flag = OPTION_SKIP }, [ 't' ] = { .flag = OPTION_STAR_TERMINATE }, [ 'u' ] = { .flag = OPTION_NO_TRUNCATE }, [ 'y' ] = { .flag = OPTION_ANY_TERMINATE }, [ 'x' ] = { .flag = OPTION_IGNORE_TERMINATE }, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

Trivial application to record a sound file.

Author
Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com

Definition in file app_record.c.

Macro Definition Documentation

◆ OPERATOR_KEY

#define OPERATOR_KEY   '0'

Definition at line 123 of file app_record.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPTION_APPEND 
OPTION_NOANSWER 
OPTION_QUIET 
OPTION_SKIP 
OPTION_STAR_TERMINATE 
OPTION_IGNORE_TERMINATE 
OPTION_KEEP 
OPTION_ANY_TERMINATE 
OPTION_OPERATOR_EXIT 
OPTION_NO_TRUNCATE 

Definition at line 127 of file app_record.c.

127 {
128 OPTION_APPEND = (1 << 0),
129 OPTION_NOANSWER = (1 << 1),
130 OPTION_QUIET = (1 << 2),
131 OPTION_SKIP = (1 << 3),
132 OPTION_STAR_TERMINATE = (1 << 4),
133 OPTION_IGNORE_TERMINATE = (1 << 5),
134 OPTION_KEEP = (1 << 6),
135 OPTION_ANY_TERMINATE = (1 << 7),
136 OPTION_OPERATOR_EXIT = (1 << 8),
137 OPTION_NO_TRUNCATE = (1 << 9),
138};
@ OPTION_NOANSWER
Definition: app_record.c:129
@ OPTION_STAR_TERMINATE
Definition: app_record.c:132
@ OPTION_KEEP
Definition: app_record.c:134
@ OPTION_NO_TRUNCATE
Definition: app_record.c:137
@ OPTION_QUIET
Definition: app_record.c:130
@ OPTION_OPERATOR_EXIT
Definition: app_record.c:136
@ OPTION_IGNORE_TERMINATE
Definition: app_record.c:133
@ OPTION_ANY_TERMINATE
Definition: app_record.c:135
@ OPTION_SKIP
Definition: app_record.c:131
@ OPTION_APPEND
Definition: app_record.c:128

◆ dtmf_response

Enumerator
RESPONSE_NO_MATCH 
RESPONSE_OPERATOR 
RESPONSE_DTMF 

Definition at line 140 of file app_record.c.

140 {
144};
@ RESPONSE_OPERATOR
Definition: app_record.c:142
@ RESPONSE_DTMF
Definition: app_record.c:143
@ RESPONSE_NO_MATCH
Definition: app_record.c:141

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 543 of file app_record.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 543 of file app_record.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 543 of file app_record.c.

◆ create_destination_directory()

static int create_destination_directory ( const char *  path)
static

Definition at line 187 of file app_record.c.

188{
189 int res;
190 char directory[PATH_MAX], *file_sep;
191
192 if (!(file_sep = strrchr(path, '/'))) {
193 /* No directory to create */
194 return 0;
195 }
196
197 /* Overwrite temporarily */
198 *file_sep = '\0';
199
200 /* Absolute path? */
201 if (path[0] == '/') {
202 res = ast_mkdir(path, 0777);
203 *file_sep = '/';
204 return res;
205 }
206
207 /* Relative path */
208 res = snprintf(directory, sizeof(directory), "%s/sounds/%s",
210
211 *file_sep = '/';
212
213 if (res >= sizeof(directory)) {
214 /* We truncated, so we fail */
215 return -1;
216 }
217
218 return ast_mkdir(directory, 0777);
219}
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2479

References ast_config_AST_DATA_DIR, ast_mkdir(), and PATH_MAX.

Referenced by record_exec().

◆ load_module()

static int load_module ( void  )
static

Definition at line 538 of file app_record.c.

539{
541}
static int record_exec(struct ast_channel *chan, const char *data)
Definition: app_record.c:221
static char * app
Definition: app_record.c:125
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640

References app, ast_register_application_xml, and record_exec().

◆ record_dtmf_response()

static enum dtmf_response record_dtmf_response ( struct ast_channel chan,
struct ast_flags flags,
int  dtmf_integer,
int  terminator 
)
static

Definition at line 171 of file app_record.c.

173{
174 if ((dtmf_integer == OPERATOR_KEY) &&
176 return RESPONSE_OPERATOR;
177 }
178
179 if ((dtmf_integer == terminator) ||
181 return RESPONSE_DTMF;
182 }
183
184 return RESPONSE_NO_MATCH;
185}
#define OPERATOR_KEY
Definition: app_record.c:123
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_test_flag, OPERATOR_KEY, OPTION_ANY_TERMINATE, OPTION_OPERATOR_EXIT, RESPONSE_DTMF, RESPONSE_NO_MATCH, and RESPONSE_OPERATOR.

Referenced by record_exec().

◆ record_exec()

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

Definition at line 221 of file app_record.c.

222{
223 int res = 0;
224 char *ext = NULL, *opts[0];
225 char *parse;
226 int i = 0;
227 char tmp[PATH_MAX];
228
229 struct ast_filestream *s = NULL;
230 struct ast_frame *f = NULL;
231
232 struct ast_dsp *sildet = NULL; /* silence detector dsp */
233 int totalsilence = 0;
234 int dspsilence = 0;
235 int silence = 0; /* amount of silence to allow */
236 int gotsilence = 0; /* did we timeout for silence? */
237 int truncate_silence = 1; /* truncate on complete silence recording */
238 int maxduration = 0; /* max duration of recording in milliseconds */
239 int gottimeout = 0; /* did we timeout for maxduration exceeded? */
240 int terminator = '#';
241 RAII_VAR(struct ast_format *, rfmt, NULL, ao2_cleanup);
242 int ioflags;
243 struct ast_silence_generator *silgen = NULL;
244 struct ast_flags flags = { 0, };
246 AST_APP_ARG(filename);
247 AST_APP_ARG(silence);
248 AST_APP_ARG(maxduration);
250 );
251 int ms;
252 struct timeval start;
253 const char *status_response = "ERROR";
254
255 /* The next few lines of code parse out the filename and header from the input string */
256 if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
257 ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
258 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
259 return -1;
260 }
261
262 parse = ast_strdupa(data);
264 if (args.argc == 4)
265 ast_app_parse_options(app_opts, &flags, opts, args.options);
266
267 if (!ast_strlen_zero(args.filename)) {
268 ext = strrchr(args.filename, '.'); /* to support filename with a . in the filename, not format */
269 if (!ext)
270 ext = strchr(args.filename, ':');
271 if (ext) {
272 *ext = '\0';
273 ext++;
274 }
275 }
276 if (!ext) {
277 ast_log(LOG_WARNING, "No extension specified to filename!\n");
278 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
279 return -1;
280 }
281 if (args.silence) {
282 if ((sscanf(args.silence, "%30d", &i) == 1) && (i > -1)) {
283 silence = i * 1000;
284 } else if (!ast_strlen_zero(args.silence)) {
285 ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", args.silence);
286 }
287 }
288
290 truncate_silence = 0;
291
292 if (args.maxduration) {
293 if ((sscanf(args.maxduration, "%30d", &i) == 1) && (i > -1))
294 /* Convert duration to milliseconds */
295 maxduration = i * 1000;
296 else if (!ast_strlen_zero(args.maxduration))
297 ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", args.maxduration);
298 }
299
301 terminator = '*';
303 terminator = '\0';
304
305 /*
306 If a '%d' is specified as part of the filename, we replace that token with
307 sequentially incrementing numbers until we find a unique filename.
308 */
309 if (strchr(args.filename, '%')) {
310 size_t src, dst, count = 0;
311 size_t src_len = strlen(args.filename);
312 size_t dst_len = sizeof(tmp) - 1;
313
314 do {
315 for (src = 0, dst = 0; src < src_len && dst < dst_len; src++) {
316 if (!strncmp(&args.filename[src], "%d", 2)) {
317 int s = snprintf(&tmp[dst], PATH_MAX - dst, "%zu", count);
318 if (s >= PATH_MAX - dst) {
319 /* We truncated, so we need to bail */
320 ast_log(LOG_WARNING, "Failed to create unique filename from template: %s\n", args.filename);
321 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
322 return -1;
323 }
324 dst += s;
325 src++;
326 } else {
327 tmp[dst] = args.filename[src];
328 tmp[++dst] = '\0';
329 }
330 }
331 count++;
332 } while (ast_fileexists(tmp, ext, ast_channel_language(chan)) > 0);
333 } else
334 ast_copy_string(tmp, args.filename, sizeof(tmp));
335
336 pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
337
338 if (ast_channel_state(chan) != AST_STATE_UP) {
339 if (ast_test_flag(&flags, OPTION_SKIP)) {
340 /* At the user's option, skip if the line is not up */
341 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "SKIP");
342 return 0;
343 } else if (!ast_test_flag(&flags, OPTION_NOANSWER)) {
344 /* Otherwise answer unless we're supposed to record while on-hook */
345 res = ast_answer(chan);
346 }
347 }
348
349 if (res) {
350 ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(chan));
351 status_response = "ERROR";
352 goto out;
353 }
354
355 if (!ast_test_flag(&flags, OPTION_QUIET)) {
356 /* Some code to play a nice little beep to signify the start of the record operation */
357 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
358 if (!res) {
359 res = ast_waitstream(chan, "");
360 } else {
361 ast_log(LOG_WARNING, "ast_streamfile(beep) failed on %s\n", ast_channel_name(chan));
362 res = 0;
363 }
364 ast_stopstream(chan);
365 }
366
367 /* The end of beep code. Now the recording starts */
368
369 if (silence > 0) {
370 rfmt = ao2_bump(ast_channel_readformat(chan));
372 if (res < 0) {
373 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
374 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
375 return -1;
376 }
377 sildet = ast_dsp_new();
378 if (!sildet) {
379 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
380 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
381 return -1;
382 }
384 }
385
387 ast_log(LOG_WARNING, "Could not create directory for file %s\n", args.filename);
388 status_response = "ERROR";
389 goto out;
390 }
391
392 ioflags = ast_test_flag(&flags, OPTION_APPEND) ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
393 s = ast_writefile(tmp, ext, NULL, ioflags, 0, AST_FILE_MODE);
394
395 if (!s) {
396 ast_log(LOG_WARNING, "Could not create file %s\n", args.filename);
397 status_response = "ERROR";
398 goto out;
399 }
400
403
404 /* Request a video update */
406
407 if (maxduration <= 0)
408 maxduration = -1;
409
410 start = ast_tvnow();
411 while ((ms = ast_remaining_ms(start, maxduration))) {
412 ms = ast_waitfor(chan, ms);
413 if (ms < 0) {
414 break;
415 }
416
417 if (maxduration > 0 && ms == 0) {
418 break;
419 }
420
421 f = ast_read(chan);
422 if (!f) {
423 res = -1;
424 break;
425 }
426 if (f->frametype == AST_FRAME_VOICE) {
427 res = ast_writestream(s, f);
428
429 if (res) {
430 ast_log(LOG_WARNING, "Problem writing frame\n");
431 ast_frfree(f);
432 status_response = "ERROR";
433 break;
434 }
435
436 if (silence > 0) {
437 dspsilence = 0;
438 ast_dsp_silence(sildet, f, &dspsilence);
439 if (dspsilence) {
440 totalsilence = dspsilence;
441 } else {
442 totalsilence = 0;
443 }
444 if (totalsilence > silence) {
445 /* Ended happily with silence */
446 ast_frfree(f);
447 gotsilence = 1;
448 status_response = "SILENCE";
449 break;
450 }
451 }
452 } else if (f->frametype == AST_FRAME_VIDEO) {
453 res = ast_writestream(s, f);
454
455 if (res) {
456 ast_log(LOG_WARNING, "Problem writing frame\n");
457 status_response = "ERROR";
458 ast_frfree(f);
459 break;
460 }
461 } else if (f->frametype == AST_FRAME_DTMF) {
462 enum dtmf_response rc =
463 record_dtmf_response(chan, &flags, f->subclass.integer, terminator);
464 switch(rc) {
466 break;
468 status_response = "OPERATOR";
469 ast_debug(1, "Got OPERATOR\n");
470 break;
471 case RESPONSE_DTMF:
472 status_response = "DTMF";
473 ast_debug(1, "Got DTMF\n");
474 break;
475 }
476 if (rc != RESPONSE_NO_MATCH) {
477 ast_frfree(f);
478 break;
479 }
480 }
481 ast_frfree(f);
482 }
483
484 if (maxduration > 0 && !ms) {
485 gottimeout = 1;
486 status_response = "TIMEOUT";
487 }
488
489 if (!f) {
490 ast_debug(1, "Got hangup\n");
491 res = -1;
492 status_response = "HANGUP";
493 if (!ast_test_flag(&flags, OPTION_KEEP)) {
494 ast_filedelete(args.filename, NULL);
495 }
496 }
497
498 if (gotsilence && truncate_silence) {
499 ast_stream_rewind(s, silence - 1000);
501 } else if (!gottimeout && f) {
502 /*
503 * Strip off the last 1/4 second of it, if we didn't end because of a timeout,
504 * or a hangup. This must mean we ended because of a DTMF tone and while this
505 * 1/4 second stripping is very old code the most likely explanation is that it
506 * relates to stripping a partial DTMF tone.
507 */
508 ast_stream_rewind(s, 250);
510 }
512
513 if (silgen)
515
516out:
517 if ((silence > 0) && rfmt) {
518 res = ast_set_read_format(chan, rfmt);
519 if (res) {
520 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
521 }
522 }
523
524 if (sildet) {
525 ast_dsp_free(sildet);
526 }
527
528 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", status_response);
529
530 return res;
531}
static enum dtmf_response record_dtmf_response(struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator)
Definition: app_record.c:171
static int create_destination_directory(const char *path)
Definition: app_record.c:187
static const struct ast_app_option app_opts[128]
Definition: app_record.c:157
dtmf_response
Definition: app_record.c:140
#define AST_FILE_MODE
Definition: asterisk.h:32
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int tmp()
Definition: bt_open.c:389
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8186
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3181
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition: channel.c:8232
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4276
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5781
const char * ast_channel_language(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2824
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4296
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
Set the minimum average magnitude threshold to determine talking by the DSP.
Definition: dsp.c:1788
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1783
@ THRESHOLD_SILENCE
Definition: dsp.h:73
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1488
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:2009
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:244
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1100
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition: file.c:1423
int ast_truncstream(struct ast_filestream *fs)
Trunc stream at current location.
Definition: file.c:1080
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1111
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1129
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1141
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
const char * ext
Definition: http.c:150
#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 ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
#define AST_FRAME_DTMF
#define ast_frfree(fr)
@ AST_FRAME_VIDEO
@ AST_FRAME_VOICE
@ AST_CONTROL_VIDUPDATE
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define ast_opt_transmit_silence
Definition: options.h:124
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.
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Definition: dsp.c:407
int totalsilence
Definition: dsp.c:411
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:101
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
Definition of a media format.
Definition: format.c:43
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
const char * args
static struct test_options options
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
FILE * out
Definition: utils/frame.c:33
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_bump, ao2_cleanup, app_opts, args, ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_channel_language(), ast_channel_name(), ast_channel_readformat(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_closestream(), AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_dsp_free(), ast_dsp_get_threshold_from_settings(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FILE_MODE, ast_filedelete(), ast_fileexists(), ast_format_slin, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate(), ast_log, ast_opt_transmit_silence, ast_read(), ast_remaining_ms(), ast_set_read_format(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_stream_rewind(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_truncstream(), ast_tvnow(), ast_waitfor(), ast_waitstream(), ast_writefile(), ast_writestream(), create_destination_directory(), ext, ast_flags::flags, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, OPTION_APPEND, OPTION_IGNORE_TERMINATE, OPTION_KEEP, OPTION_NO_TRUNCATE, OPTION_NOANSWER, OPTION_QUIET, OPTION_SKIP, OPTION_STAR_TERMINATE, options, out, PATH_MAX, pbx_builtin_setvar_helper(), RAII_VAR, record_dtmf_response(), RESPONSE_DTMF, RESPONSE_NO_MATCH, RESPONSE_OPERATOR, ast_frame::subclass, THRESHOLD_SILENCE, tmp(), and ast_dsp::totalsilence.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 533 of file app_record.c.

534{
536}
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app, and ast_unregister_application().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Trivial Record Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 543 of file app_record.c.

◆ app

char* app = "Record"
static

Definition at line 125 of file app_record.c.

Referenced by load_module(), and unload_module().

◆ app_opts

const struct ast_app_option app_opts[128] = { [ 'a' ] = { .flag = OPTION_APPEND }, [ 'k' ] = { .flag = OPTION_KEEP }, [ 'n' ] = { .flag = OPTION_NOANSWER }, [ 'o' ] = { .flag = OPTION_OPERATOR_EXIT }, [ 'q' ] = { .flag = OPTION_QUIET }, [ 's' ] = { .flag = OPTION_SKIP }, [ 't' ] = { .flag = OPTION_STAR_TERMINATE }, [ 'u' ] = { .flag = OPTION_NO_TRUNCATE }, [ 'y' ] = { .flag = OPTION_ANY_TERMINATE }, [ 'x' ] = { .flag = OPTION_IGNORE_TERMINATE }, }
static

Definition at line 157 of file app_record.c.

Referenced by record_exec().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 543 of file app_record.c.