Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 126 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 130 of file app_record.c.

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

◆ dtmf_response

Enumerator
RESPONSE_NO_MATCH 
RESPONSE_OPERATOR 
RESPONSE_DTMF 

Definition at line 143 of file app_record.c.

143 {
147};
@ RESPONSE_OPERATOR
Definition: app_record.c:145
@ RESPONSE_DTMF
Definition: app_record.c:146
@ RESPONSE_NO_MATCH
Definition: app_record.c:144

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 546 of file app_record.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 546 of file app_record.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 546 of file app_record.c.

◆ create_destination_directory()

static int create_destination_directory ( const char *  path)
static

Definition at line 190 of file app_record.c.

191{
192 int res;
193 char directory[PATH_MAX], *file_sep;
194
195 if (!(file_sep = strrchr(path, '/'))) {
196 /* No directory to create */
197 return 0;
198 }
199
200 /* Overwrite temporarily */
201 *file_sep = '\0';
202
203 /* Absolute path? */
204 if (path[0] == '/') {
205 res = ast_mkdir(path, 0777);
206 *file_sep = '/';
207 return res;
208 }
209
210 /* Relative path */
211 res = snprintf(directory, sizeof(directory), "%s/sounds/%s",
213
214 *file_sep = '/';
215
216 if (res >= sizeof(directory)) {
217 /* We truncated, so we fail */
218 return -1;
219 }
220
221 return ast_mkdir(directory, 0777);
222}
#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 541 of file app_record.c.

542{
544}
static int record_exec(struct ast_channel *chan, const char *data)
Definition: app_record.c:224
static char * app
Definition: app_record.c:128
#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 174 of file app_record.c.

176{
177 if ((dtmf_integer == OPERATOR_KEY) &&
179 return RESPONSE_OPERATOR;
180 }
181
182 if ((dtmf_integer == terminator) ||
184 return RESPONSE_DTMF;
185 }
186
187 return RESPONSE_NO_MATCH;
188}
#define OPERATOR_KEY
Definition: app_record.c:126
#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 224 of file app_record.c.

225{
226 int res = 0;
227 char *ext = NULL, *opts[0];
228 char *parse;
229 int i = 0;
230 char tmp[PATH_MAX];
231
232 struct ast_filestream *s = NULL;
233 struct ast_frame *f = NULL;
234
235 struct ast_dsp *sildet = NULL; /* silence detector dsp */
236 int totalsilence = 0;
237 int dspsilence = 0;
238 int silence = 0; /* amount of silence to allow */
239 int gotsilence = 0; /* did we timeout for silence? */
240 int truncate_silence = 1; /* truncate on complete silence recording */
241 int maxduration = 0; /* max duration of recording in milliseconds */
242 int gottimeout = 0; /* did we timeout for maxduration exceeded? */
243 int terminator = '#';
244 RAII_VAR(struct ast_format *, rfmt, NULL, ao2_cleanup);
245 int ioflags;
246 struct ast_silence_generator *silgen = NULL;
247 struct ast_flags flags = { 0, };
249 AST_APP_ARG(filename);
250 AST_APP_ARG(silence);
251 AST_APP_ARG(maxduration);
253 );
254 int ms;
255 struct timeval start;
256 const char *status_response = "ERROR";
257
258 /* The next few lines of code parse out the filename and header from the input string */
259 if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
260 ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
261 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
262 return -1;
263 }
264
265 parse = ast_strdupa(data);
267 if (args.argc == 4)
268 ast_app_parse_options(app_opts, &flags, opts, args.options);
269
270 if (!ast_strlen_zero(args.filename)) {
271 ext = strrchr(args.filename, '.'); /* to support filename with a . in the filename, not format */
272 if (!ext)
273 ext = strchr(args.filename, ':');
274 if (ext) {
275 *ext = '\0';
276 ext++;
277 }
278 }
279 if (!ext) {
280 ast_log(LOG_WARNING, "No extension specified to filename!\n");
281 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
282 return -1;
283 }
284 if (args.silence) {
285 if ((sscanf(args.silence, "%30d", &i) == 1) && (i > -1)) {
286 silence = i * 1000;
287 } else if (!ast_strlen_zero(args.silence)) {
288 ast_log(LOG_WARNING, "'%s' is not a valid silence duration\n", args.silence);
289 }
290 }
291
293 truncate_silence = 0;
294
295 if (args.maxduration) {
296 if ((sscanf(args.maxduration, "%30d", &i) == 1) && (i > -1))
297 /* Convert duration to milliseconds */
298 maxduration = i * 1000;
299 else if (!ast_strlen_zero(args.maxduration))
300 ast_log(LOG_WARNING, "'%s' is not a valid maximum duration\n", args.maxduration);
301 }
302
304 terminator = '*';
306 terminator = '\0';
307
308 /*
309 If a '%d' is specified as part of the filename, we replace that token with
310 sequentially incrementing numbers until we find a unique filename.
311 */
312 if (strchr(args.filename, '%')) {
313 size_t src, dst, count = 0;
314 size_t src_len = strlen(args.filename);
315 size_t dst_len = sizeof(tmp) - 1;
316
317 do {
318 for (src = 0, dst = 0; src < src_len && dst < dst_len; src++) {
319 if (!strncmp(&args.filename[src], "%d", 2)) {
320 int s = snprintf(&tmp[dst], PATH_MAX - dst, "%zu", count);
321 if (s >= PATH_MAX - dst) {
322 /* We truncated, so we need to bail */
323 ast_log(LOG_WARNING, "Failed to create unique filename from template: %s\n", args.filename);
324 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
325 return -1;
326 }
327 dst += s;
328 src++;
329 } else {
330 tmp[dst] = args.filename[src];
331 tmp[++dst] = '\0';
332 }
333 }
334 count++;
335 } while (ast_fileexists(tmp, ext, ast_channel_language(chan)) > 0);
336 } else
337 ast_copy_string(tmp, args.filename, sizeof(tmp));
338
339 pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
340
341 if (ast_channel_state(chan) != AST_STATE_UP) {
342 if (ast_test_flag(&flags, OPTION_SKIP)) {
343 /* At the user's option, skip if the line is not up */
344 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "SKIP");
345 return 0;
346 } else if (!ast_test_flag(&flags, OPTION_NOANSWER)) {
347 /* Otherwise answer unless we're supposed to record while on-hook */
348 res = ast_answer(chan);
349 }
350 }
351
352 if (res) {
353 ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(chan));
354 status_response = "ERROR";
355 goto out;
356 }
357
358 if (!ast_test_flag(&flags, OPTION_QUIET)) {
359 /* Some code to play a nice little beep to signify the start of the record operation */
360 res = ast_streamfile(chan, "beep", ast_channel_language(chan));
361 if (!res) {
362 res = ast_waitstream(chan, "");
363 } else {
364 ast_log(LOG_WARNING, "ast_streamfile(beep) failed on %s\n", ast_channel_name(chan));
365 res = 0;
366 }
367 ast_stopstream(chan);
368 }
369
370 /* The end of beep code. Now the recording starts */
371
372 if (silence > 0) {
373 rfmt = ao2_bump(ast_channel_readformat(chan));
375 if (res < 0) {
376 ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
377 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
378 return -1;
379 }
380 sildet = ast_dsp_new();
381 if (!sildet) {
382 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
383 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
384 return -1;
385 }
387 }
388
390 ast_log(LOG_WARNING, "Could not create directory for file %s\n", args.filename);
391 status_response = "ERROR";
392 goto out;
393 }
394
395 ioflags = ast_test_flag(&flags, OPTION_APPEND) ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
396 s = ast_writefile(tmp, ext, NULL, ioflags, 0, AST_FILE_MODE);
397
398 if (!s) {
399 ast_log(LOG_WARNING, "Could not create file %s\n", args.filename);
400 status_response = "ERROR";
401 goto out;
402 }
403
406
407 /* Request a video update */
409
410 if (maxduration <= 0)
411 maxduration = -1;
412
413 start = ast_tvnow();
414 while ((ms = ast_remaining_ms(start, maxduration))) {
415 ms = ast_waitfor(chan, ms);
416 if (ms < 0) {
417 break;
418 }
419
420 if (maxduration > 0 && ms == 0) {
421 break;
422 }
423
424 f = ast_read(chan);
425 if (!f) {
426 res = -1;
427 break;
428 }
429 if (f->frametype == AST_FRAME_VOICE) {
430 res = ast_writestream(s, f);
431
432 if (res) {
433 ast_log(LOG_WARNING, "Problem writing frame\n");
434 ast_frfree(f);
435 status_response = "ERROR";
436 break;
437 }
438
439 if (silence > 0) {
440 dspsilence = 0;
441 ast_dsp_silence(sildet, f, &dspsilence);
442 if (dspsilence) {
443 totalsilence = dspsilence;
444 } else {
445 totalsilence = 0;
446 }
447 if (totalsilence > silence) {
448 /* Ended happily with silence */
449 ast_frfree(f);
450 gotsilence = 1;
451 status_response = "SILENCE";
452 break;
453 }
454 }
455 } else if (f->frametype == AST_FRAME_VIDEO) {
456 res = ast_writestream(s, f);
457
458 if (res) {
459 ast_log(LOG_WARNING, "Problem writing frame\n");
460 status_response = "ERROR";
461 ast_frfree(f);
462 break;
463 }
464 } else if (f->frametype == AST_FRAME_DTMF) {
465 enum dtmf_response rc =
466 record_dtmf_response(chan, &flags, f->subclass.integer, terminator);
467 switch(rc) {
469 break;
471 status_response = "OPERATOR";
472 ast_debug(1, "Got OPERATOR\n");
473 break;
474 case RESPONSE_DTMF:
475 status_response = "DTMF";
476 ast_debug(1, "Got DTMF\n");
477 break;
478 }
479 if (rc != RESPONSE_NO_MATCH) {
480 ast_frfree(f);
481 break;
482 }
483 }
484 ast_frfree(f);
485 }
486
487 if (maxduration > 0 && !ms) {
488 gottimeout = 1;
489 status_response = "TIMEOUT";
490 }
491
492 if (!f) {
493 ast_debug(1, "Got hangup\n");
494 res = -1;
495 status_response = "HANGUP";
496 if (!ast_test_flag(&flags, OPTION_KEEP)) {
497 ast_filedelete(args.filename, NULL);
498 }
499 }
500
501 if (gotsilence && truncate_silence) {
502 ast_stream_rewind(s, silence - 1000);
504 } else if (!gottimeout && f) {
505 /*
506 * Strip off the last 1/4 second of it, if we didn't end because of a timeout,
507 * or a hangup. This must mean we ended because of a DTMF tone and while this
508 * 1/4 second stripping is very old code the most likely explanation is that it
509 * relates to stripping a partial DTMF tone.
510 */
511 ast_stream_rewind(s, 250);
513 }
515
516 if (silgen)
518
519out:
520 if ((silence > 0) && rfmt) {
521 res = ast_set_read_format(chan, rfmt);
522 if (res) {
523 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
524 }
525 }
526
527 if (sildet) {
528 ast_dsp_free(sildet);
529 }
530
531 pbx_builtin_setvar_helper(chan, "RECORD_STATUS", status_response);
532
533 return res;
534}
static enum dtmf_response record_dtmf_response(struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator)
Definition: app_record.c:174
static int create_destination_directory(const char *path)
Definition: app_record.c:190
static const struct ast_app_option app_opts[128]
Definition: app_record.c:160
dtmf_response
Definition: app_record.c:143
#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
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:8190
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3190
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:8236
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4274
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5779
const char * ast_channel_language(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2834
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4294
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:1108
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1301
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:1431
int ast_truncstream(struct ast_filestream *fs)
Trunc stream at current location.
Definition: file.c:1088
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1119
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1137
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1149
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
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, and ast_dsp::totalsilence.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 536 of file app_record.c.

537{
539}
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 546 of file app_record.c.

◆ app

char* app = "Record"
static

Definition at line 128 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 160 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 546 of file app_record.c.