Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
main/app.c File Reference

Convenient Application Routines. More...

#include "asterisk.h"
#include <sys/stat.h>
#include <regex.h>
#include <sys/file.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/capability.h>
#include "asterisk/paths.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/dsp.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"
#include "asterisk/threadstorage.h"
#include "asterisk/test.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/json.h"
#include "asterisk/format_cache.h"

Go to the source code of this file.

Data Structures

struct  groups
 
struct  linear_state
 
struct  path_lock
 
struct  path_lock_list
 
struct  zombie
 
struct  zombies
 

Macros

#define AST_MAX_FORMATS   10
 
#define FMT   "%30Lf%9s"
 
#define RES_EXIT   (1 << 17)
 
#define RES_REPEAT   (1 << 18)
 
#define RES_RESTART   ((1 << 19) | RES_REPEAT)
 
#define RES_UPONE   (1 << 16)
 
#define SF_BETWEEN   600
 
#define SF_BUF_LEN   20
 
#define SF_OFF   33
 
#define SF_ON   67
 
#define VM_API_CALL(res, api_call, api_parms)
 
#define VM_GREETER_API_CALL(res, api_call, api_parms)
 

Enumerations

enum  control_tone_frame_response_result { CONTROL_TONE_RESPONSE_FAILED = -1, CONTROL_TONE_RESPONSE_NORMAL = 0, CONTROL_TONE_RESPONSE_FINISHED = 1 }
 

Functions

unsigned int __ast_app_separate_args (char *buf, char delim, int remove_chars, char **array, int arraylen)
 Separate a string into arguments in an array. More...
 
static int __ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
 
int __ast_vm_greeter_register (const struct ast_vm_greeter_functions *vm_table, struct ast_module *module)
 Set voicemail greeter function callbacks. More...
 
int __ast_vm_register (const struct ast_vm_functions *vm_table, struct ast_module *module)
 Set voicemail function callbacks. More...
 
static AO2_GLOBAL_OBJ_STATIC (vm_provider)
 The container for the voicemail provider.
 
static AO2_GLOBAL_OBJ_STATIC (vm_greeter_provider)
 The container for the voicemail greeter provider.
 
static void app_cleanup (void)
 
int app_init (void)
 Initialize the application core. More...
 
int ast_app_copy_recording_to_vm (struct ast_vm_recording_data *vm_rec_data)
 param[in] vm_rec_data Contains data needed to make the recording. retval 0 voicemail successfully created from recording. retval -1 Failure
 
int ast_app_dtget (struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout)
 This function presents a dialtone and reads an extension into 'collect' which must be a pointer to a pre-initialized array of char having a size of 'size' suitable for writing to. It will collect no more than the smaller of 'maxlen' or 'size' minus the original strlen() of collect digits. More...
 
int ast_app_exec_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
 Run a subroutine on a channel, placing an optional second channel into autoservice. More...
 
const char * ast_app_expand_sub_args (struct ast_channel *chan, const char *args)
 Add missing context/exten to subroutine argument string. More...
 
enum ast_getdata_result ast_app_getdata (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
 Plays a stream and gets DTMF data from a channel. More...
 
int ast_app_getdata_full (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd)
 Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
 
enum ast_getdata_result ast_app_getdata_terminator (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, char *terminator)
 Plays a stream and gets DTMF data from a channel. More...
 
int ast_app_group_discard (struct ast_channel *chan)
 Discard all group counting for a channel.
 
int ast_app_group_get_count (const char *group, const char *category)
 Get the current channel count of the specified group and category.
 
struct ast_group_infoast_app_group_list_head (void)
 Get the head of the group count list.
 
int ast_app_group_list_rdlock (void)
 Read Lock the group count list.
 
int ast_app_group_list_unlock (void)
 Unlock the group count list.
 
int ast_app_group_list_wrlock (void)
 Write Lock the group count list.
 
int ast_app_group_match_get_count (const char *groupmatch, const char *category)
 Get the current channel count of all groups that match the specified pattern and category.
 
int ast_app_group_set_channel (struct ast_channel *chan, const char *data)
 Set the group for a channel, splitting the provided data into group and category, if specified.
 
int ast_app_group_split_group (const char *data, char *group, int group_max, char *category, int category_max)
 Split a group string into group and category, returning a default category if none is provided.
 
int ast_app_group_update (struct ast_channel *old, struct ast_channel *new)
 Update all group counting for a channel to a new one.
 
int ast_app_has_voicemail (const char *mailboxes, const char *folder)
 Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX". If folder is "INBOX", includes the number of messages in the "Urgent" folder. More...
 
int ast_app_inboxcount (const char *mailboxes, int *newmsgs, int *oldmsgs)
 Determine number of new/old messages in a mailbox. More...
 
int ast_app_inboxcount2 (const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
 Determine number of urgent/new/old messages in a mailbox. More...
 
int ast_app_messagecount (const char *mailbox_id, const char *folder)
 Get the number of messages in a given mailbox folder. More...
 
void ast_app_options2str64 (const struct ast_app_option *options, struct ast_flags64 *flags, char *buf, size_t len)
 Given a list of options array, return an option string based on passed flags. More...
 
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. More...
 
int ast_app_parse_options64 (const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
 Parses a string containing application options and sets flags/arguments. More...
 
int ast_app_parse_timelen (const char *timestr, int *result, enum ast_timelen unit)
 Common routine to parse time lengths, with optional time unit specifier. More...
 
int ast_app_run_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_location, const char *sub_args, int ignore_hangup)
 Run a subroutine on a channel, placing an optional second channel into autoservice. More...
 
int ast_app_sayname (struct ast_channel *chan, const char *mailbox_id)
 Play a recorded user name for the mailbox to the specified channel. More...
 
void ast_close_fds_above_n (int n)
 Common routine for child processes, to close all fds prior to exec(2) More...
 
int ast_control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms)
 Stream a file with fast forward, pause, reverse, restart. More...
 
int ast_control_streamfile_lang (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, const char *lang, long *offsetms)
 Version of ast_control_streamfile() which allows the language of the media file to be specified. More...
 
int ast_control_streamfile_w_cb (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms, ast_waitstream_fr_cb cb)
 Stream a file with fast forward, pause, reverse, restart. More...
 
int ast_control_tone (struct ast_channel *chan, const char *tone)
 Controls playback of a tone. More...
 
int ast_dtmf_stream (struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
 Send a string of DTMF digits to a channel. More...
 
void ast_dtmf_stream_external (struct ast_channel *chan, const char *digits, int between, unsigned int duration)
 Send a string of DTMF digits to a channel from an external thread. More...
 
int ast_get_encoded_char (const char *stream, char *result, size_t *consumed)
 Decode an encoded control or extended ASCII character. More...
 
char * ast_get_encoded_str (const char *stream, char *result, size_t result_size)
 Decode a stream of encoded control or extended ASCII characters. More...
 
void ast_install_stack_functions (const struct ast_app_stack_funcs *funcs)
 Set stack application function callbacks. More...
 
int ast_ivr_menu_run (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 Runs an IVR menu. More...
 
static int ast_ivr_menu_run_internal (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 
int ast_linear_stream (struct ast_channel *chan, const char *filename, int fd, int allowoverride)
 Stream a filename (or file descriptor) as a generator.
 
enum AST_LOCK_RESULT ast_lock_path (const char *path)
 Lock a filesystem path. More...
 
static enum AST_LOCK_RESULT ast_lock_path_flock (const char *path)
 
static enum AST_LOCK_RESULT ast_lock_path_lockfile (const char *path)
 
int ast_mf_stream (struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
 Send a string of MF digits to a channel. More...
 
int ast_play_and_prepend (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence)
 Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a little differently from normal recordings This function will not play a success message due to post-recording control in the application this was added for. More...
 
int ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path)
 Record a file based on input from a channel. Use default accept and cancel DTMF. This function will play "auth-thankyou" upon successful recording. More...
 
int ast_play_and_record_full (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
 Record a file based on input from a channel This function will play "auth-thankyou" upon successful recording if skip_confirmation_sound is false. More...
 
int ast_play_and_wait (struct ast_channel *chan, const char *fn)
 Play a stream and wait for a digit, returning the digit that was pressed.
 
struct stasis_topicast_queue_topic (const char *queuename)
 Get the Stasis Message Bus API topic for queue messages for a particular queue name. More...
 
struct stasis_topicast_queue_topic_all (void)
 Get the Stasis Message Bus API topic for queue messages. More...
 
char * ast_read_textfile (const char *filename)
 Read a file into asterisk.
 
int ast_record_review (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
 Allow to record message and have a review option.
 
int ast_safe_fork (int stop_reaper)
 Common routine to safely fork without a chance of a signal handler firing badly in the child. More...
 
void ast_safe_fork_cleanup (void)
 Common routine to cleanup after fork'ed process is complete (if reaping was stopped) More...
 
void ast_set_lock_type (enum AST_LOCK_TYPE type)
 Set the type of locks used by ast_lock_path() More...
 
int ast_sf_stream (struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
 Send a string of SF digits to a channel. More...
 
int ast_str_get_encoded_str (struct ast_str **str, int maxlen, const char *stream)
 Decode a stream of encoded control or extended ASCII characters.
 
 AST_THREADSTORAGE_PUBLIC (ast_str_thread_global_buf)
 
int ast_unlock_path (const char *path)
 Unlock a path.
 
static int ast_unlock_path_flock (const char *path)
 
static int ast_unlock_path_lockfile (const char *path)
 
int ast_vm_greeter_is_registered (void)
 Determine if a voicemail greeter provider is registered. More...
 
void ast_vm_greeter_unregister (const char *module_name)
 Unregister the specified voicemail greeter provider. More...
 
const char * ast_vm_index_to_foldername (int id)
 Return name of folder, given an id. More...
 
int ast_vm_is_registered (void)
 Determine if a voicemail provider is registered. More...
 
struct ast_vm_mailbox_snapshotast_vm_mailbox_snapshot_create (const char *mailbox, const char *context, const char *folder, int descending, enum ast_vm_snapshot_sort_val sort_val, int combine_INBOX_and_OLD)
 Create a snapshot of a mailbox which contains information about every msg. More...
 
struct ast_vm_mailbox_snapshotast_vm_mailbox_snapshot_destroy (struct ast_vm_mailbox_snapshot *mailbox_snapshot)
 destroy a snapshot More...
 
int ast_vm_msg_forward (const char *from_mailbox, const char *from_context, const char *from_folder, const char *to_mailbox, const char *to_context, const char *to_folder, size_t num_msgs, const char *msg_ids[], int delete_old)
 forward a message from one mailbox to another. More...
 
int ast_vm_msg_move (const char *mailbox, const char *context, size_t num_msgs, const char *oldfolder, const char *old_msg_ids[], const char *newfolder)
 Move messages from one folder to another. More...
 
int ast_vm_msg_play (struct ast_channel *chan, const char *mailbox, const char *context, const char *folder, const char *msg_num, ast_vm_msg_play_cb *cb)
 Play a voicemail msg back on a channel. More...
 
int ast_vm_msg_remove (const char *mailbox, const char *context, size_t num_msgs, const char *folder, const char *msgs[])
 Remove/delete messages from a mailbox folder. More...
 
void ast_vm_unregister (const char *module_name)
 Unregister the specified voicemail provider. More...
 
static int control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms, const char *lang, ast_waitstream_fr_cb cb)
 
static enum control_tone_frame_response_result control_tone_frame_response (struct ast_channel *chan, struct ast_frame *fr, struct ast_tone_zone_sound *ts, const char *tone, int *paused)
 
static int dtmf_stream (struct ast_channel *chan, const char *digits, int between, unsigned int duration, int is_external)
 
static int external_sleep (struct ast_channel *chan, int ms)
 
static int ivr_dispatch (struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata)
 
static void * linear_alloc (struct ast_channel *chan, void *params)
 
static int linear_generator (struct ast_channel *chan, void *data, int len, int samples)
 
static void linear_release (struct ast_channel *chan, void *params)
 
static struct ast_framemake_silence (const struct ast_frame *orig)
 Construct a silence frame of the same duration as orig. More...
 
static int mf_stream (struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
 
static int option_exists (struct ast_ivr_menu *menu, char *option)
 
static int option_matchmore (struct ast_ivr_menu *menu, char *option)
 
static int parse_options (const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
 
static int parse_tone_uri (char *tone_parser, const char **tone_indication, const char **tone_zone)
 
static void path_lock_destroy (struct path_lock *obj)
 
static int read_newoption (struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten)
 
static int set_read_to_slin (struct ast_channel *chan, struct ast_format **orig_format)
 Sets a channel's read format to ast_format_slin, recording its original format. More...
 
static int sf_stream (struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
 
static void * shaun_of_the_dead (void *data)
 
static void vm_greeter_warn_no_provider (void)
 
static void vm_warn_no_provider (void)
 

Variables

static const struct ast_app_stack_funcsapp_stack_callbacks
 
static enum AST_LOCK_TYPE ast_lock_type = AST_LOCK_TYPE_LOCKFILE
 
static cap_t child_cap
 
static const char default_acceptdtmf [] = "#"
 
static const char default_canceldtmf [] = ""
 
static int global_maxsilence = 0
 
static int global_silence_threshold = 128
 
static struct groups groups = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct ast_generator linearstream
 
static struct path_lock_list path_lock_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL
 
static int vm_greeter_warnings
 
static int vm_warnings
 
static struct zombies zombies = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static struct stasis_topicqueue_topic_all
 Define Stasis Message Bus API topic objects.
 
static struct stasis_topic_poolqueue_topic_pool
 

Detailed Description

Convenient Application Routines.

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

Definition in file main/app.c.

Function Documentation

unsigned int __ast_app_separate_args ( char *  buf,
char  delim,
int  remove_chars,
char **  array,
int  arraylen 
)

Separate a string into arguments in an array.

Parameters
bufThe string to be parsed (this must be a writable copy, as it will be modified)
delimThe character to be used to delimit arguments
remove_charsRemove backslashes and quote characters, while parsing
arrayAn array of 'char *' to be filled in with pointers to the found arguments
arraylenThe number of elements in the array (i.e. the number of arguments you will accept)

Note: if there are more arguments in the string than the array will hold, the last element of the array will contain the remaining arguments, not separated.

The array will be completely zeroed by this function before it populates any entries.

Returns
The number of arguments found, or zero if the function arguments are not valid.

Definition at line 2356 of file main/app.c.

2357 {
2358  int argc;
2359  char *scan, *wasdelim = NULL;
2360  int paren = 0, quote = 0, bracket = 0;
2361 
2362  if (!array || !arraylen) {
2363  return 0;
2364  }
2365 
2366  memset(array, 0, arraylen * sizeof(*array));
2367 
2368  if (!buf) {
2369  return 0;
2370  }
2371 
2372  scan = buf;
2373 
2374  for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2375  array[argc] = scan;
2376  for (; *scan; scan++) {
2377  if (*scan == '(') {
2378  paren++;
2379  } else if (*scan == ')') {
2380  if (paren) {
2381  paren--;
2382  }
2383  } else if (*scan == '[') {
2384  bracket++;
2385  } else if (*scan == ']') {
2386  if (bracket) {
2387  bracket--;
2388  }
2389  } else if (*scan == '"' && delim != '"') {
2390  quote = quote ? 0 : 1;
2391  if (remove_chars) {
2392  /* Remove quote character from argument */
2393  memmove(scan, scan + 1, strlen(scan));
2394  scan--;
2395  }
2396  } else if (*scan == '\\') {
2397  if (remove_chars) {
2398  /* Literal character, don't parse */
2399  memmove(scan, scan + 1, strlen(scan));
2400  } else {
2401  scan++;
2402  }
2403  } else if ((*scan == delim) && !paren && !quote && !bracket) {
2404  wasdelim = scan;
2405  *scan++ = '\0';
2406  break;
2407  }
2408  }
2409  }
2410 
2411  /* If the last character in the original string was the delimiter, then
2412  * there is one additional argument. */
2413  if (*scan || (scan > buf && (scan - 1) == wasdelim)) {
2414  array[argc++] = scan;
2415  }
2416 
2417  return argc;
2418 }
static int __ast_play_and_record ( struct ast_channel chan,
const char *  playfile,
const char *  recordfile,
int  maxtime,
const char *  fmt,
int *  duration,
int *  sound_duration,
int  beep,
int  silencethreshold,
int  maxsilence,
const char *  path,
int  prepend,
const char *  acceptdtmf,
const char *  canceldtmf,
int  skip_confirmation_sound,
enum ast_record_if_exists  if_exists 
)
static

Optionally play a sound file or a beep, then record audio and video from the channel.

Parameters
chanChannel to playback to/record from.
playfileFilename of sound to play before recording begins.
recordfileFilename to record to.
maxtimeMaximum length of recording (in seconds).
fmtFormat(s) to record message in. Multiple formats may be specified by separating them with a '|'.
durationWhere to store actual length of the recorded message (in milliseconds).
sound_durationWhere to store the length of the recorded message (in milliseconds), minus any silence
beepWhether to play a beep before starting to record.
silencethreshold
maxsilenceLength of silence that will end a recording (in milliseconds).
pathOptional filesystem path to unlock.
prependIf true, prepend the recorded audio to an existing file and follow prepend mode recording rules
acceptdtmfDTMF digits that will end the recording.
canceldtmfDTMF digits that will cancel the recording.
skip_confirmation_soundIf true, don't play auth-thankyou at end. Nice for custom recording prompts in apps.
if_exists
Return values
-1failure or hangup
'S'Recording ended from silence timeout
't'Recording ended from the message exceeding the maximum duration, or via DTMF in prepend mode
dtmfcharRecording ended via the return value's DTMF character for either cancel or accept.
Note
Instead of asking how much time passed (end - start), calculate the number of seconds of audio which actually went into the file. This fixes a problem where audio is stopped up on the network and never gets to us.

Note that we still want to use the number of seconds passed for the max message, otherwise we could get a situation where this stream is never closed (which would create a resource leak).

Note
If we ended with silence, trim all but the first 200ms of silence off the recording. However, if we ended with '#', we don't want to trim ANY part of the recording.
Same logic as above.

Definition at line 1727 of file main/app.c.

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_closestream(), AST_CONTROL_RECORD_CANCEL, AST_CONTROL_RECORD_MUTE, AST_CONTROL_RECORD_STOP, AST_CONTROL_RECORD_SUSPEND, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), ast_filedelete(), ast_filerename(), ast_format_get_name(), AST_FRAME_CONTROL, ast_frame_dtor(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_indicate(), AST_MAX_FORMATS, ast_play_and_wait(), ast_read(), ast_readfile(), ast_readframe(), AST_RECORD_IF_EXISTS_APPEND, AST_RECORD_IF_EXISTS_ERROR, AST_RECORD_IF_EXISTS_FAIL, AST_RECORD_IF_EXISTS_OVERWRITE, ast_set_read_format(), ast_strdupa, ast_stream_and_wait(), ast_stream_rewind(), ast_tellstream(), ast_truncstream(), ast_unlock_path(), ast_waitfor(), ast_writefile(), ast_writestream(), ast_frame::frametype, global_maxsilence, ast_frame_subclass::integer, make_silence(), set_read_to_slin(), ast_frame::subclass, and ast_dsp::totalsilence.

Referenced by ast_play_and_prepend(), ast_play_and_record(), and ast_play_and_record_full().

1732 {
1733  int d = 0;
1734  char *fmts;
1735  char comment[256];
1736  int x, fmtcnt = 1, res = -1, outmsg = 0;
1737  struct ast_filestream *others[AST_MAX_FORMATS];
1738  const char *sfmt[AST_MAX_FORMATS];
1739  char *stringp = NULL;
1740  time_t start, end;
1741  struct ast_dsp *sildet = NULL; /* silence detector dsp */
1742  int totalsilence = 0;
1743  int dspsilence = 0;
1744  int olddspsilence = 0;
1745  struct ast_format *rfmt = NULL;
1746  struct ast_silence_generator *silgen = NULL;
1747  char prependfile[PATH_MAX];
1748  int ioflags; /* IO flags for writing output file */
1749  SCOPE_ENTER(3, "%s: play: '%s' record: '%s' path: '%s' prepend: %d\n",
1750  ast_channel_name(chan), playfile, recordfile, path, prepend);
1751 
1752  ioflags = O_CREAT|O_WRONLY;
1753 
1754  switch (if_exists) {
1756  ioflags |= O_EXCL;
1757  break;
1759  ioflags |= O_TRUNC;
1760  break;
1762  ioflags |= O_APPEND;
1763  break;
1765  ast_assert(0);
1766  break;
1767  }
1768 
1769  if (silencethreshold < 0) {
1770  silencethreshold = global_silence_threshold;
1771  }
1772 
1773  if (maxsilence < 0) {
1774  maxsilence = global_maxsilence;
1775  }
1776 
1777  /* barf if no pointer passed to store duration in */
1778  if (!duration) {
1779  ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n");
1780  return -1;
1781  }
1782 
1783  ast_debug(1, "play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
1784  snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, ast_channel_name(chan));
1785 
1786  if (playfile || beep) {
1787  if (!beep) {
1788  ast_trace(-1, "Playing '%s' to '%s'\n", playfile, ast_channel_name(chan));
1789  d = ast_play_and_wait(chan, playfile);
1790  }
1791  if (d > -1) {
1792  ast_trace(-1, "Playing 'beep' to '%s'\n", ast_channel_name(chan));
1793  d = ast_stream_and_wait(chan, "beep", "");
1794  }
1795  if (d < 0) {
1796  SCOPE_EXIT_RTN_VALUE(-1, "Failed to play. RC: %d\n", d);
1797  }
1798  }
1799 
1800  if (prepend) {
1801  ast_copy_string(prependfile, recordfile, sizeof(prependfile));
1802  strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
1803  ast_trace(-1, "Prepending to '%s'\n", prependfile);
1804  }
1805 
1806  fmts = ast_strdupa(fmt);
1807 
1808  stringp = fmts;
1809  strsep(&stringp, "|");
1810  ast_debug(1, "Recording Formats: sfmts=%s\n", fmts);
1811  sfmt[0] = ast_strdupa(fmts);
1812 
1813  while ((fmt = strsep(&stringp, "|"))) {
1814  if (fmtcnt > AST_MAX_FORMATS - 1) {
1815  ast_log(LOG_WARNING, "Please increase AST_MAX_FORMATS in file.h\n");
1816  break;
1817  }
1818  /*
1819  * Storage for 'fmt' is on the stack and held by 'fmts', which is maintained for
1820  * the rest of this function. So okay to not duplicate 'fmt' here, but only keep
1821  * a pointer to it.
1822  */
1823  sfmt[fmtcnt++] = fmt;
1824  }
1825 
1826  end = start = time(NULL); /* pre-initialize end to be same as start in case we never get into loop */
1827  for (x = 0; x < fmtcnt; x++) {
1828  others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, ioflags, 0, AST_FILE_MODE);
1829  ast_trace(-1, "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]);
1830 
1831  if (!others[x]) {
1832  break;
1833  }
1834  }
1835 
1836  if (path) {
1837  ast_unlock_path(path);
1838  }
1839 
1840  if (maxsilence > 0) {
1841  sildet = ast_dsp_new(); /* Create the silence detector */
1842  if (!sildet) {
1843  ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
1844  return -1;
1845  }
1846  ast_dsp_set_threshold(sildet, silencethreshold);
1847  res = set_read_to_slin(chan, &rfmt);
1848  if (res < 0) {
1849  ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
1850  ast_dsp_free(sildet);
1851  ao2_cleanup(rfmt);
1852  return -1;
1853  }
1854  }
1855 
1856  if (!prepend) {
1857  /* Request a video update */
1859 
1860  if (ast_opt_transmit_silence) {
1861  silgen = ast_channel_start_silence_generator(chan);
1862  }
1863  }
1864 
1865  if (x == fmtcnt) {
1866  /* Loop, writing the packets we read to the writer(s), until
1867  * we have reason to stop. */
1868  struct ast_frame *f;
1869  int paused = 0;
1870  int muted = 0;
1871  time_t pause_start = 0;
1872  int paused_secs = 0;
1873  int pausedsilence = 0;
1874 
1875  for (;;) {
1876  if (!(res = ast_waitfor(chan, 2000))) {
1877  ast_debug(1, "One waitfor failed, trying another\n");
1878  /* Try one more time in case of masq */
1879  if (!(res = ast_waitfor(chan, 2000))) {
1880  ast_log(LOG_WARNING, "No audio available on %s??\n", ast_channel_name(chan));
1881  res = -1;
1882  }
1883  }
1884 
1885  if (res < 0) {
1886  f = NULL;
1887  break;
1888  }
1889  if (!(f = ast_read(chan))) {
1890  break;
1891  }
1892  if (f->frametype == AST_FRAME_VOICE) {
1893  /* write each format */
1894  if (paused) {
1895  /* It's all good */
1896  res = 0;
1897  } else {
1898  struct ast_frame *silence = NULL;
1899  struct ast_frame *orig = f;
1900 
1901  if (muted) {
1902  silence = make_silence(orig);
1903  if (!silence) {
1904  ast_log(LOG_WARNING, "Error creating silence\n");
1905  break;
1906  }
1907  f = silence;
1908  }
1909  for (x = 0; x < fmtcnt; x++) {
1910  if (prepend && !others[x]) {
1911  break;
1912  }
1913  res = ast_writestream(others[x], f);
1914  }
1915  ast_frame_dtor(silence);
1916  f = orig;
1917  }
1918 
1919  /* Silence Detection */
1920  if (maxsilence > 0) {
1921  dspsilence = 0;
1922  ast_dsp_silence(sildet, f, &dspsilence);
1923  if (olddspsilence > dspsilence) {
1924  totalsilence += olddspsilence;
1925  }
1926  olddspsilence = dspsilence;
1927 
1928  if (paused) {
1929  /* record how much silence there was while we are paused */
1930  pausedsilence = dspsilence;
1931  } else if (dspsilence > pausedsilence) {
1932  /* ignore the paused silence */
1933  dspsilence -= pausedsilence;
1934  } else {
1935  /* dspsilence has reset, reset pausedsilence */
1936  pausedsilence = 0;
1937  }
1938 
1939  if (dspsilence > maxsilence) {
1940  /* Ended happily with silence */
1941  ast_verb(3, "Recording automatically stopped after a silence of %d seconds\n", dspsilence/1000);
1942  res = 'S';
1943  outmsg = 2;
1944  break;
1945  }
1946  }
1947  /* Exit on any error */
1948  if (res) {
1949  ast_log(LOG_WARNING, "Error writing frame\n");
1950  break;
1951  }
1952  } else if (f->frametype == AST_FRAME_VIDEO) {
1953  /* Write only once */
1954  ast_writestream(others[0], f);
1955  } else if (f->frametype == AST_FRAME_DTMF) {
1956  if (prepend) {
1957  /* stop recording with any digit */
1958  ast_verb(3, "User ended message by pressing %c\n", f->subclass.integer);
1959  res = 't';
1960  outmsg = 2;
1961  break;
1962  }
1963  if (strchr(acceptdtmf, f->subclass.integer)) {
1964  ast_verb(3, "User ended message by pressing %c\n", f->subclass.integer);
1965  res = f->subclass.integer;
1966  outmsg = 2;
1967  break;
1968  }
1969  if (strchr(canceldtmf, f->subclass.integer)) {
1970  ast_verb(3, "User canceled message by pressing %c\n", f->subclass.integer);
1971  res = f->subclass.integer;
1972  outmsg = 0;
1973  break;
1974  }
1975  } else if (f->frametype == AST_FRAME_CONTROL) {
1977  ast_verb(3, "Message canceled by control\n");
1978  outmsg = 0; /* cancels the recording */
1979  res = 0;
1980  break;
1981  } else if (f->subclass.integer == AST_CONTROL_RECORD_STOP) {
1982  ast_verb(3, "Message ended by control\n");
1983  res = 0;
1984  break;
1985  } else if (f->subclass.integer == AST_CONTROL_RECORD_SUSPEND) {
1986  paused = !paused;
1987  ast_verb(3, "Message %spaused by control\n",
1988  paused ? "" : "un");
1989  if (paused) {
1990  pause_start = time(NULL);
1991  } else {
1992  paused_secs += time(NULL) - pause_start;
1993  }
1994  } else if (f->subclass.integer == AST_CONTROL_RECORD_MUTE) {
1995  muted = !muted;
1996  ast_verb(3, "Message %smuted by control\n",
1997  muted ? "" : "un");
1998  /* We can only silence slin frames, so
1999  * set the mode, if we haven't already
2000  * for sildet
2001  */
2002  if (muted && !rfmt) {
2003  ast_verb(3, "Setting read format to linear mode\n");
2004  res = set_read_to_slin(chan, &rfmt);
2005  if (res < 0) {
2006  ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
2007  break;
2008  }
2009  }
2010  }
2011  }
2012  if (maxtime && !paused) {
2013  end = time(NULL);
2014  if (maxtime < (end - start - paused_secs)) {
2015  ast_verb(3, "Took too long, cutting it short...\n");
2016  res = 't';
2017  outmsg = 2;
2018  break;
2019  }
2020  }
2021  ast_frfree(f);
2022  }
2023  if (!f) {
2024  ast_verb(3, "User hung up\n");
2025  res = -1;
2026  outmsg = 1;
2027  } else {
2028  ast_frfree(f);
2029  }
2030  } else {
2031  ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
2032  }
2033 
2034  if (!prepend) {
2035  if (silgen) {
2036  ast_channel_stop_silence_generator(chan, silgen);
2037  }
2038  }
2039 
2040  /*!\note
2041  * Instead of asking how much time passed (end - start), calculate the number
2042  * of seconds of audio which actually went into the file. This fixes a
2043  * problem where audio is stopped up on the network and never gets to us.
2044  *
2045  * Note that we still want to use the number of seconds passed for the max
2046  * message, otherwise we could get a situation where this stream is never
2047  * closed (which would create a resource leak).
2048  */
2049  *duration = others[0] ? ast_tellstream(others[0]) / 8000 : 0;
2050  if (sound_duration) {
2051  *sound_duration = *duration;
2052  }
2053 
2054  if (!prepend) {
2055  /* Reduce duration by a total silence amount */
2056  if (olddspsilence <= dspsilence) {
2057  totalsilence += dspsilence;
2058  }
2059 
2060  if (sound_duration) {
2061  if (totalsilence > 0) {
2062  *sound_duration -= (totalsilence - 200) / 1000;
2063  }
2064  if (*sound_duration < 0) {
2065  *sound_duration = 0;
2066  }
2067  }
2068 
2069  if (dspsilence > 0) {
2070  *duration -= (dspsilence - 200) / 1000;
2071  }
2072 
2073  if (*duration < 0) {
2074  *duration = 0;
2075  }
2076 
2077  for (x = 0; x < fmtcnt; x++) {
2078  if (!others[x]) {
2079  break;
2080  }
2081  /*!\note
2082  * If we ended with silence, trim all but the first 200ms of silence
2083  * off the recording. However, if we ended with '#', we don't want
2084  * to trim ANY part of the recording.
2085  */
2086  if (res > 0 && dspsilence) {
2087  /* rewind only the trailing silence */
2088  ast_stream_rewind(others[x], dspsilence - 200);
2089  }
2090  ast_truncstream(others[x]);
2091  ast_closestream(others[x]);
2092  }
2093  } else if (prepend && outmsg) {
2094  struct ast_filestream *realfiles[AST_MAX_FORMATS];
2095  struct ast_frame *fr;
2096 
2097  for (x = 0; x < fmtcnt; x++) {
2098  snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
2099  realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
2100  if (!others[x]) {
2101  break;
2102  }
2103  if (!realfiles[x]) {
2104  ast_closestream(others[x]);
2105  continue;
2106  }
2107  /*!\note Same logic as above. */
2108  if (dspsilence) {
2109  ast_stream_rewind(others[x], dspsilence - 200);
2110  }
2111  ast_truncstream(others[x]);
2112  /* add the original file too */
2113  while ((fr = ast_readframe(realfiles[x]))) {
2114  ast_writestream(others[x], fr);
2115  ast_frfree(fr);
2116  }
2117  ast_closestream(others[x]);
2118  ast_closestream(realfiles[x]);
2119  ast_filerename(prependfile, recordfile, sfmt[x]);
2120  ast_trace(-1, "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile);
2121  ast_trace(-1, "Deleting the prepend file %s.%s\n", recordfile, sfmt[x]);
2122  ast_filedelete(prependfile, sfmt[x]);
2123  }
2124  } else {
2125  for (x = 0; x < fmtcnt; x++) {
2126  if (!others[x]) {
2127  break;
2128  }
2129  ast_closestream(others[x]);
2130  }
2131  }
2132 
2133  if (rfmt && ast_set_read_format(chan, rfmt)) {
2134  ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_format_get_name(rfmt), ast_channel_name(chan));
2135  }
2136  ao2_cleanup(rfmt);
2137  if ((outmsg == 2) && (!skip_confirmation_sound)) {
2138  ast_stream_and_wait(chan, "auth-thankyou", "");
2139  }
2140  if (sildet) {
2141  ast_dsp_free(sildet);
2142  }
2143  SCOPE_EXIT_RTN_VALUE(res, "Done. RC: %d\n", res);
2144 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
int ast_unlock_path(const char *path)
Unlock a path.
Definition: main/app.c:2630
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4257
Definition of a media format.
Definition: format.c:43
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1141
struct ast_frame_subclass subclass
int totalsilence
Definition: dsp.c:411
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition: file.c:1085
void ast_frame_dtor(struct ast_frame *frame)
NULL-safe wrapper for ast_frfree, good for RAII_VAR.
Definition: main/frame.c:187
static int set_read_to_slin(struct ast_channel *chan, struct ast_format **orig_format)
Sets a channel's read format to ast_format_slin, recording its original format.
Definition: main/app.c:1692
static struct ast_frame * make_silence(const struct ast_frame *orig)
Construct a silence frame of the same duration as orig.
Definition: main/app.c:1640
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5762
Definition: dsp.c:407
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_debug(level,...)
Log a DEBUG message.
static int global_maxsilence
Definition: app_minivm.c:691
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
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8164
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
Definition: file.c:936
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1100
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
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:8210
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1878
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1111
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: main/app.c:1616
int ast_truncstream(struct ast_filestream *fs)
Trunc stream at current location.
Definition: file.c:1080
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1488
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
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:244
Data structure associated with a single frame of data.
struct ast_filestream * ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts reading from a file.
Definition: file.c:1371
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:1146
enum ast_frame_type frametype
#define AST_MAX_FORMATS
Definition: file.h:44
int __ast_vm_greeter_register ( const struct ast_vm_greeter_functions vm_table,
struct ast_module module 
)

Set voicemail greeter function callbacks.

Since
13.0.0
Parameters
vm_tableVoicemail greeter function table to install.
modulePointer to the module implementing the interface
Return values
0on success.
-1on error.
AST_MODULE_LOAD_DECLINEif there's already another greeter registered.

Definition at line 479 of file main/app.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_global_obj_ref, ao2_global_obj_replace_unref, AST_MODULE_LOAD_DECLINE, ast_vm_greeter_functions::module, ast_vm_greeter_functions::module_name, ast_vm_greeter_functions::module_version, and RAII_VAR.

480 {
481  RAII_VAR(struct ast_vm_greeter_functions *, table, NULL, ao2_cleanup);
482 
483  if (!vm_table->module_name) {
484  ast_log(LOG_ERROR, "Voicemail greeter provider missing required information.\n");
485  return -1;
486  }
487  if (vm_table->module_version != VM_GREETER_MODULE_VERSION) {
488  ast_log(LOG_ERROR, "Voicemail greeter provider '%s' has incorrect version\n",
489  vm_table->module_name);
490  return -1;
491  }
492 
493  table = ao2_global_obj_ref(vm_greeter_provider);
494  if (table) {
495  ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n",
496  table->module_name);
498  }
499 
500  table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
501  if (!table) {
502  return -1;
503  }
504  *table = *vm_table;
505  table->module = module;
506 
507  ao2_global_obj_replace_unref(vm_greeter_provider, table);
508  return 0;
509 }
unsigned int module_version
The version of this function table.
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
struct ast_module * module
The module for the voicemail greeter provider.
const char * module_name
The name of the module that provides the voicemail greeter functionality.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#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
int __ast_vm_register ( const struct ast_vm_functions vm_table,
struct ast_module module 
)

Set voicemail function callbacks.

Parameters
vm_tableVoicemail function table to install.
modulePointer to the module implementing the interface
Return values
0on success.
-1on error.
AST_MODULE_LOAD_DECLINEif there's already another provider registered.

Definition at line 368 of file main/app.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_global_obj_ref, ao2_global_obj_replace_unref, AST_MODULE_LOAD_DECLINE, ast_vm_functions::module, ast_vm_functions::module_name, ast_vm_functions::module_version, and RAII_VAR.

369 {
370  RAII_VAR(struct ast_vm_functions *, table, NULL, ao2_cleanup);
371 
372  if (!vm_table->module_name) {
373  ast_log(LOG_ERROR, "Voicemail provider missing required information.\n");
374  return -1;
375  }
376  if (vm_table->module_version != VM_MODULE_VERSION) {
377  ast_log(LOG_ERROR, "Voicemail provider '%s' has incorrect version\n",
378  vm_table->module_name);
379  return -1;
380  }
381 
382  table = ao2_global_obj_ref(vm_provider);
383  if (table) {
384  ast_log(LOG_WARNING, "Voicemail provider already registered by %s.\n",
385  table->module_name);
387  }
388 
389  table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
390  if (!table) {
391  return -1;
392  }
393  *table = *vm_table;
394  table->module = module;
395 
396  ao2_global_obj_replace_unref(vm_provider, table);
397  return 0;
398 }
struct ast_module * module
The module for the voicemail provider.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
const char * module_name
The name of the module that provides the voicemail functionality.
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
unsigned int module_version
The version of this function table.
Voicemail function table definition.
#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
int app_init ( void  )

Initialize the application core.

Return values
0Success
-1Failure
Since
12

Definition at line 3365 of file main/app.c.

References ast_register_cleanup(), stasis_topic_create(), and stasis_topic_pool_create().

3366 {
3367  ast_register_cleanup(app_cleanup);
3368 #ifdef HAVE_CAP
3369  child_cap = cap_from_text("cap_net_admin-eip");
3370 #endif
3371  queue_topic_all = stasis_topic_create("queue:all");
3372  if (!queue_topic_all) {
3373  return -1;
3374  }
3375  queue_topic_pool = stasis_topic_pool_create(queue_topic_all);
3376  if (!queue_topic_pool) {
3377  return -1;
3378  }
3379  return 0;
3380 }
static struct stasis_topic * queue_topic_all
Define Stasis Message Bus API topic objects.
Definition: main/app.c:90
struct stasis_topic_pool * stasis_topic_pool_create(struct stasis_topic *pooled_topic)
Create a topic pool that routes messages from dynamically generated topics to the given topic...
Definition: stasis.c:1833
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:617
int ast_app_dtget ( struct ast_channel chan,
const char *  context,
char *  collect,
size_t  size,
int  maxlen,
int  timeout 
)

This function presents a dialtone and reads an extension into 'collect' which must be a pointer to a pre-initialized array of char having a size of 'size' suitable for writing to. It will collect no more than the smaller of 'maxlen' or 'size' minus the original strlen() of collect digits.

Present a dialtone and collect a certain length extension.

Parameters
chanstruct.
context
collect
size
maxlen
timeouttimeout in milliseconds

Definition at line 138 of file main/app.c.

References ast_exists_extension(), ast_get_indication_tone(), ast_ignore_pattern(), ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_tone_zone_sound_unref(), ast_waitfordigit(), ast_tone_zone_sound::data, ast_pbx::dtimeoutms, and S_COR.

Referenced by grab_transfer().

139 {
140  struct ast_tone_zone_sound *ts;
141  int res = 0, x = 0;
142 
143  if (maxlen > size) {
144  maxlen = size;
145  }
146 
147  if (!timeout) {
148  if (ast_channel_pbx(chan) && ast_channel_pbx(chan)->dtimeoutms) {
149  timeout = ast_channel_pbx(chan)->dtimeoutms;
150  } else {
151  timeout = 5000;
152  }
153  }
154 
155  if ((ts = ast_get_indication_tone(ast_channel_zone(chan), "dial"))) {
156  res = ast_playtones_start(chan, 0, ts->data, 0);
157  ts = ast_tone_zone_sound_unref(ts);
158  } else {
159  ast_log(LOG_NOTICE, "Huh....? no dial for indications?\n");
160  }
161 
162  for (x = strlen(collect); x < maxlen; ) {
163  res = ast_waitfordigit(chan, timeout);
164  if (!ast_ignore_pattern(context, collect)) {
165  ast_playtones_stop(chan);
166  }
167  if (res < 1) {
168  break;
169  }
170  if (res == '#') {
171  break;
172  }
173  collect[x++] = res;
174  if (!ast_matchmore_extension(chan, context, collect, 1,
175  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
176  break;
177  }
178  }
179 
180  if (res >= 0) {
181  res = ast_exists_extension(chan, context, collect, 1,
182  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)) ? 1 : 0;
183  }
184 
185  return res;
186 }
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
Definition: pbx.c:4195
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6879
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
Number structure.
Definition: app_followme.c:154
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
Description of a tone.
Definition: indications.h:35
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:461
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3175
int dtimeoutms
Definition: pbx.h:215
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
const char * data
Description of a tone.
Definition: indications.h:52
int ast_app_exec_sub ( struct ast_channel autoservice_chan,
struct ast_channel sub_chan,
const char *  sub_args,
int  ignore_hangup 
)

Run a subroutine on a channel, placing an optional second channel into autoservice.

Since
11

This is a shorthand method that makes it very easy to run a subroutine on any given channel. It is perfectly reasonable to supply a NULL autoservice_chan here in case there is no channel to place into autoservice.

Note
Absolutely NO channel locks should be held before calling this function.
Parameters
autoservice_chanA channel to place into autoservice while the subroutine is run
sub_chanChannel to execute subroutine on.
sub_argsGosub application argument string.
ignore_hangupTRUE if a hangup does not stop execution of the routine.
Return values
0success
-1on error

Definition at line 297 of file main/app.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_module_running_ref, ast_module_unref, ast_queue_hangup(), ast_app_stack_funcs::module, and ast_app_stack_funcs::run_sub.

Referenced by ast_app_run_sub(), ast_pbx_hangup_handler_run(), ast_pre_call(), dial_exec_full(), and queue_exec().

298 {
299  const struct ast_app_stack_funcs *funcs;
300  int res;
301 
302  funcs = app_stack_callbacks;
303  if (!funcs || !funcs->run_sub || !ast_module_running_ref(funcs->module)) {
304  ast_log(LOG_WARNING,
305  "Cannot run 'Gosub(%s)'. The app_stack module is not available.\n",
306  sub_args);
307  return -1;
308  }
309 
310  if (autoservice_chan) {
311  ast_autoservice_start(autoservice_chan);
312  }
313 
314  res = funcs->run_sub(sub_chan, sub_args, ignore_hangup);
315  ast_module_unref(funcs->module);
316 
317  if (autoservice_chan) {
318  ast_autoservice_stop(autoservice_chan);
319  }
320 
321  if (!ignore_hangup && ast_check_hangup_locked(sub_chan)) {
322  ast_queue_hangup(sub_chan);
323  }
324 
325  return res;
326 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
Stack applications callback functions.
int(* run_sub)(struct ast_channel *chan, const char *args, int ignore_hangup)
Callback for the routine to run a subroutine on a channel.
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
const char* ast_app_expand_sub_args ( struct ast_channel chan,
const char *  args 
)

Add missing context/exten to subroutine argument string.

Parameters
chanChannel to obtain context/exten.
argsGosub application argument string.

Fills in the optional context and exten from the given channel.

Returns
New-args Gosub argument string on success. Must be freed.
Return values
NULLon error.

Definition at line 278 of file main/app.c.

References ast_module_running_ref, ast_module_unref, ast_app_stack_funcs::expand_sub_args, and ast_app_stack_funcs::module.

Referenced by ast_pbx_hangup_handler_push(), and dial_exec_full().

279 {
280  const struct ast_app_stack_funcs *funcs;
281  const char *new_args;
282 
283  funcs = app_stack_callbacks;
284  if (!funcs || !funcs->expand_sub_args || !ast_module_running_ref(funcs->module)) {
285  ast_log(LOG_WARNING,
286  "Cannot expand 'Gosub(%s)' arguments. The app_stack module is not available.\n",
287  args);
288  return NULL;
289  }
290 
291  new_args = funcs->expand_sub_args(chan, args);
292  ast_module_unref(funcs->module);
293 
294  return new_args;
295 }
Stack applications callback functions.
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
const char *(* expand_sub_args)(struct ast_channel *chan, const char *args)
Add missing context/exten to Gosub application argument string.
enum ast_getdata_result ast_app_getdata ( struct ast_channel c,
const char *  prompt,
char *  s,
int  maxlen,
int  timeout 
)

Plays a stream and gets DTMF data from a channel.

Parameters
cWhich channel one is interacting with
promptFile to pass to ast_streamfile (the one that you wish to play). It is also valid for this to be multiple files concatenated by "&". For example, "file1&file2&file3".
sThe location where the DTMF data will be stored
maxlenMax Length of the data
timeoutTimeout length waiting for data(in milliseconds). Set to 0 for standard timeout(six seconds), or -1 for no time out.

This function was designed for application programmers for situations where they need to play a message and then get some DTMF data in response to the message. If a digit is pressed during playback, it will immediately break out of the message and continue execution of your code.

Definition at line 188 of file main/app.c.

References ast_app_getdata_terminator().

Referenced by conf_exec().

189 {
190  return ast_app_getdata_terminator(c, prompt, s, maxlen, timeout, NULL);
191 }
enum ast_getdata_result ast_app_getdata_terminator(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, char *terminator)
Plays a stream and gets DTMF data from a channel.
Definition: main/app.c:193
enum ast_getdata_result ast_app_getdata_terminator ( struct ast_channel c,
const char *  prompt,
char *  s,
int  maxlen,
int  timeout,
char *  terminator 
)

Plays a stream and gets DTMF data from a channel.

Parameters
cWhich channel one is interacting with
promptFile to pass to ast_streamfile (the one that you wish to play). It is also valid for this to be multiple files concatenated by "&". For example, "file1&file2&file3".
sThe location where the DTMF data will be stored
maxlenMax Length of the data
timeoutTimeout length waiting for data(in milliseconds). Set to 0 for standard timeout(six seconds), or -1 for no time out.
terminatorA string of characters that may be used as terminators to end input. If NULL, "#" will be used.

This function was designed for application programmers for situations where they need to play a message and then get some DTMF data in response to the message. If a digit is pressed during playback, it will immediately break out of the message and continue execution of your code.

Definition at line 193 of file main/app.c.

References AST_GETDATA_EMPTY_END_TERMINATED, ast_readstring(), ast_strdupa, ast_streamfile(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, ast_pbx::dtimeoutms, and ast_pbx::rtimeoutms.

Referenced by ast_app_getdata().

195 {
196  int res = 0, to, fto;
197  char *front, *filename;
198 
199  /* XXX Merge with full version? XXX */
200 
201  if (maxlen)
202  s[0] = '\0';
203 
204  if (!prompt)
205  prompt = "";
206 
207  filename = ast_strdupa(prompt);
208  while ((front = ast_strsep(&filename, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))) {
209  if (!ast_strlen_zero(front)) {
210  res = ast_streamfile(c, front, ast_channel_language(c));
211  if (res)
212  continue;
213  }
214  if (ast_strlen_zero(filename)) {
215  /* set timeouts for the last prompt */
216  fto = ast_channel_pbx(c) ? ast_channel_pbx(c)->rtimeoutms : 6000;
217  to = ast_channel_pbx(c) ? ast_channel_pbx(c)->dtimeoutms : 2000;
218 
219  if (timeout > 0) {
220  fto = to = timeout;
221  }
222  if (timeout < 0) {
223  fto = to = 1000000000;
224  }
225  } else {
226  /* there is more than one prompt, so
227  * get rid of the long timeout between
228  * prompts, and make it 50ms */
229  fto = 50;
230  to = ast_channel_pbx(c) ? ast_channel_pbx(c)->dtimeoutms : 2000;
231  }
232  res = ast_readstring(c, s, maxlen, to, fto, (terminator ? terminator : "#"));
234  return res;
235  }
236  if (!ast_strlen_zero(s)) {
237  return res;
238  }
239  }
240 
241  return res;
242 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
int dtimeoutms
Definition: pbx.h:215
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6558
int rtimeoutms
Definition: pbx.h:216
int ast_app_has_voicemail ( const char *  mailboxes,
const char *  folder 
)

Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX". If folder is "INBOX", includes the number of messages in the "Urgent" folder.

Return values
1Mailbox has voicemail
0No new voicemail in specified mailbox
-1Failure
Since
1.0

Definition at line 582 of file main/app.c.

References has_voicemail().

Referenced by notify_new_message(), and poll_mailbox().

583 {
584  int res = 0;
585 
586  VM_API_CALL(res, has_voicemail, (mailboxes, folder));
587  return res;
588 }
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.
int ast_app_inboxcount ( const char *  mailboxes,
int *  newmsgs,
int *  oldmsgs 
)

Determine number of new/old messages in a mailbox.

Since
1.0
Parameters
[in]mailboxesMailbox specification in the format /code mbox[@context][&mbox2[@context2]][...] /code
[out]newmsgsNumber of messages in the "INBOX" folder. Includes number of messages in the "Urgent" folder, if any.
[out]oldmsgsNumber of messages in the "Old" folder.
Return values
0Success
-1Failure

Definition at line 604 of file main/app.c.

Referenced by update_registry().

605 {
606  int res = 0;
607 
608  if (newmsgs) {
609  *newmsgs = 0;
610  }
611  if (oldmsgs) {
612  *oldmsgs = 0;
613  }
614 
615  VM_API_CALL(res, inboxcount, (mailboxes, newmsgs, oldmsgs));
616  return res;
617 }
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
int ast_app_inboxcount2 ( const char *  mailboxes,
int *  urgentmsgs,
int *  newmsgs,
int *  oldmsgs 
)

Determine number of urgent/new/old messages in a mailbox.

Parameters
[in]mailboxesthe mailbox context to use
[out]urgentmsgsthe urgent message count
[out]newmsgsthe new message count
[out]oldmsgsthe old message count
Return values
0for success
negativeupon error
Since
1.6.1

Definition at line 619 of file main/app.c.

References inboxcount2().

Referenced by notify_new_message().

620 {
621  int res = 0;
622 
623  if (newmsgs) {
624  *newmsgs = 0;
625  }
626  if (oldmsgs) {
627  *oldmsgs = 0;
628  }
629  if (urgentmsgs) {
630  *urgentmsgs = 0;
631  }
632 
633  VM_API_CALL(res, inboxcount2, (mailboxes, urgentmsgs, newmsgs, oldmsgs));
634  return res;
635 }
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Check the given mailbox's message count.
int ast_app_messagecount ( const char *  mailbox_id,
const char *  folder 
)

Get the number of messages in a given mailbox folder.

Parameters
[in]mailbox_idMailbox name
[in]folderThe folder to look in. Default is INBOX if not provided.
Note
If requesting INBOX then the returned count is INBOX + Urgent.
Returns
The number of messages in the mailbox folder (zero or more).

Definition at line 645 of file main/app.c.

646 {
647  int res = 0;
648 
649  VM_API_CALL(res, messagecount, (mailbox_id, folder));
650  return res;
651 }
void ast_app_options2str64 ( const struct ast_app_option options,
struct ast_flags64 flags,
char *  buf,
size_t  len 
)

Given a list of options array, return an option string based on passed flags.

Parameters
optionsThe array of possible options declared with AST_APP_OPTIONS
flagsThe flags of the options that you wish to populate the buffer with
bufThe buffer to fill with the string of options
lenThe maximum length of buf

Definition at line 3076 of file main/app.c.

3077 {
3078  unsigned int i, found = 0;
3079  for (i = 32; i < 128 && found < len; i++) {
3080  if (ast_test_flag64(flags, options[i].flag)) {
3081  buf[found++] = i;
3082  }
3083  }
3084  buf[found] = '\0';
3085 }
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.

Parameters
optionsThe array of possible options declared with AST_APP_OPTIONS
flagsThe flag structure to have option flags set
argsThe array of argument pointers to hold arguments found
optstrThe string containing the options to be parsed
Return values
zerofor success
non-zeroif an error occurs
See also
AST_APP_OPTIONS

Definition at line 3066 of file main/app.c.

Referenced by agent_login_exec(), ast_multicast_rtp_create_options(), audiosocket_request(), bridge_exec(), handle_options(), minivm_accmess_exec(), queue_exec(), receivefax_exec(), sendfax_exec(), sig_pri_call(), speech_background(), and unicast_rtp_request().

3067 {
3068  return parse_options(options, flags, args, optstr, 32);
3069 }
int ast_app_parse_options64 ( const struct ast_app_option options,
struct ast_flags64 flags,
char **  args,
char *  optstr 
)

Parses a string containing application options and sets flags/arguments.

Parameters
optionsThe array of possible options declared with AST_APP_OPTIONS
flagsThe 64-bit flag structure to have option flags set
argsThe array of argument pointers to hold arguments found
optstrThe string containing the options to be parsed
Return values
zerofor success
non-zeroif an error occurs
See also
AST_APP_OPTIONS

Definition at line 3071 of file main/app.c.

Referenced by conf_exec(), and dial_exec_full().

3072 {
3073  return parse_options(options, flags, args, optstr, 64);
3074 }
int ast_app_parse_timelen ( const char *  timestr,
int *  result,
enum ast_timelen  defunit 
)

Common routine to parse time lengths, with optional time unit specifier.

Parameters
[in]timestrString to parse
[in]defunitDefault unit type
[out]resultResulting value, specified in milliseconds
Return values
0Success
-1Failure
Since
1.8

Definition at line 3273 of file main/app.c.

Referenced by ast_parse_arg(), and new_realtime_sqlite3_db().

3274 {
3275  int res;
3276  char u[10];
3277 #ifdef HAVE_LONG_DOUBLE_WIDER
3278  long double amount;
3279  #define FMT "%30Lf%9s"
3280 #else
3281  double amount;
3282  #define FMT "%30lf%9s"
3283 #endif
3284  if (!timestr) {
3285  return -1;
3286  }
3287 
3288  res = sscanf(timestr, FMT, &amount, u);
3289 
3290  if (res == 0 || res == EOF) {
3291 #undef FMT
3292  return -1;
3293  } else if (res == 2) {
3294  switch (u[0]) {
3295  case 'h':
3296  case 'H':
3297  unit = TIMELEN_HOURS;
3298  if (u[1] != '\0') {
3299  return -1;
3300  }
3301  break;
3302  case 's':
3303  case 'S':
3304  unit = TIMELEN_SECONDS;
3305  if (u[1] != '\0') {
3306  return -1;
3307  }
3308  break;
3309  case 'm':
3310  case 'M':
3311  if (toupper(u[1]) == 'S') {
3312  unit = TIMELEN_MILLISECONDS;
3313  if (u[2] != '\0') {
3314  return -1;
3315  }
3316  } else if (u[1] == '\0') {
3317  unit = TIMELEN_MINUTES;
3318  } else {
3319  return -1;
3320  }
3321  break;
3322  default:
3323  return -1;
3324  }
3325  }
3326 
3327  switch (unit) {
3328  case TIMELEN_HOURS:
3329  amount *= 60;
3330  /* fall-through */
3331  case TIMELEN_MINUTES:
3332  amount *= 60;
3333  /* fall-through */
3334  case TIMELEN_SECONDS:
3335  amount *= 1000;
3336  /* fall-through */
3337  case TIMELEN_MILLISECONDS:
3338  ;
3339  }
3340  *result = amount > INT_MAX ? INT_MAX : (int) amount;
3341  return 0;
3342 }
int ast_app_run_sub ( struct ast_channel autoservice_chan,
struct ast_channel sub_chan,
const char *  sub_location,
const char *  sub_args,
int  ignore_hangup 
)

Run a subroutine on a channel, placing an optional second channel into autoservice.

Since
11

This is a shorthand method that makes it very easy to run a subroutine on any given channel. It is perfectly reasonable to supply a NULL autoservice_chan here in case there is no channel to place into autoservice.

Note
Absolutely NO channel locks should be held before calling this function.
Parameters
autoservice_chanA channel to place into autoservice while the subroutine is run
sub_chanChannel to execute subroutine on.
sub_locationThe location of the subroutine to run.
sub_argsThe arguments to pass to the subroutine.
ignore_hangupTRUE if a hangup does not stop execution of the routine.
Return values
0success
-1on error

Definition at line 328 of file main/app.c.

References ast_app_exec_sub(), and ast_malloc.

Referenced by ast_channel_connected_line_sub(), and ast_channel_redirecting_sub().

329 {
330  int res;
331  char *args_str;
332  size_t args_len;
333 
334  if (ast_strlen_zero(sub_args)) {
335  return ast_app_exec_sub(autoservice_chan, sub_chan, sub_location, ignore_hangup);
336  }
337 
338  /* Create the Gosub application argument string. */
339  args_len = strlen(sub_location) + strlen(sub_args) + 3;
340  args_str = ast_malloc(args_len);
341  if (!args_str) {
342  return -1;
343  }
344  snprintf(args_str, args_len, "%s(%s)", sub_location, sub_args);
345 
346  res = ast_app_exec_sub(autoservice_chan, sub_chan, args_str, ignore_hangup);
347  ast_free(args_str);
348  return res;
349 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:297
int ast_app_sayname ( struct ast_channel chan,
const char *  mailbox_id 
)

Play a recorded user name for the mailbox to the specified channel.

Parameters
chanWhere to play the recorded name file.
mailbox_idThe mailbox name.
Return values
0Name played without interruption
dtmfASCII value of the DTMF which interrupted playback.
-1Unable to locate mailbox or hangup occurred.

Definition at line 637 of file main/app.c.

638 {
639  int res = -1;
640 
641  VM_GREETER_API_CALL(res, sayname, (chan, mailbox_id));
642  return res;
643 }
void ast_close_fds_above_n ( int  n)

Common routine for child processes, to close all fds prior to exec(2)

Parameters
[in]nstarting file descriptor number for closing all higher file descriptors
Since
1.6.1

Definition at line 3202 of file main/app.c.

Referenced by safe_exec_prep().

3203 {
3204  closefrom(n + 1);
3205 }
int ast_control_streamfile ( struct ast_channel chan,
const char *  file,
const char *  fwd,
const char *  rev,
const char *  stop,
const char *  pause,
const char *  restart,
int  skipms,
long *  offsetms 
)

Stream a file with fast forward, pause, reverse, restart.

Parameters
chanChannel
fileFile to play.
fwd,rev,stop,pause,restartDTMF keys for media control
skipmsNumber of milliseconds to skip for fwd/rev.
offsetmsNumber of milliseconds to skip when starting the media.

Before calling this function, set this to be the number of ms to start from the beginning of the file. When the function returns, it will be the number of ms from the beginning where the playback stopped. Pass NULL if you don't care.

Return values
0on success
Non-zeroon failure

Definition at line 1465 of file main/app.c.

1469 {
1470  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, NULL);
1471 }
unsigned int stop
Definition: res_smdi.c:217
int ast_control_streamfile_lang ( struct ast_channel chan,
const char *  file,
const char *  fwd,
const char *  rev,
const char *  stop,
const char *  suspend,
const char *  restart,
int  skipms,
const char *  lang,
long *  offsetms 
)

Version of ast_control_streamfile() which allows the language of the media file to be specified.

Return values
0on success
Non-zeroon failure

Definition at line 1473 of file main/app.c.

1476 {
1477  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, lang, NULL);
1478 }
unsigned int stop
Definition: res_smdi.c:217
int ast_control_streamfile_w_cb ( struct ast_channel chan,
const char *  file,
const char *  fwd,
const char *  rev,
const char *  stop,
const char *  pause,
const char *  restart,
int  skipms,
long *  offsetms,
ast_waitstream_fr_cb  cb 
)

Stream a file with fast forward, pause, reverse, restart.

Parameters
chan
filefilename
fwd,rev,stop,pause,restart,skipms,offsetms
cbwaitstream callback to invoke when fastforward or rewind occurs.

Before calling this function, set this to be the number of ms to start from the beginning of the file. When the function returns, it will be the number of ms from the beginning where the playback stopped. Pass NULL if you don't care.

Definition at line 1451 of file main/app.c.

1461 {
1462  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, cb);
1463 }
unsigned int stop
Definition: res_smdi.c:217
int ast_control_tone ( struct ast_channel chan,
const char *  tone 
)

Controls playback of a tone.

Return values
0on success
Non-zeroon failure

Definition at line 1545 of file main/app.c.

References AST_FRAME_CONTROL, ast_get_indication_tone(), ast_get_indication_zone(), ast_playtones_start(), ast_read_noaudio(), ast_strdupa, ast_tone_zone_sound_unref(), ast_tone_zone_unref(), ast_waitfor(), ast_tone_zone_sound::data, and ast_frame::frametype.

1546 {
1547  struct ast_tone_zone *zone = NULL;
1548  struct ast_tone_zone_sound *ts;
1549  int paused = 0;
1550  int res = 0;
1551 
1552  const char *tone_indication = NULL;
1553  const char *tone_zone = NULL;
1554  char *tone_uri_parser;
1555 
1556  if (ast_strlen_zero(tone)) {
1557  return -1;
1558  }
1559 
1560  tone_uri_parser = ast_strdupa(tone);
1561 
1562  if (parse_tone_uri(tone_uri_parser, &tone_indication, &tone_zone)) {
1563  return -1;
1564  }
1565 
1566  if (tone_zone) {
1567  zone = ast_get_indication_zone(tone_zone);
1568  }
1569 
1570  ts = ast_get_indication_tone(zone ? zone : ast_channel_zone(chan), tone_indication);
1571 
1572  if (ast_playtones_start(chan, 0, ts ? ts->data : tone_indication, 0)) {
1573  res = -1;
1574  }
1575 
1576  while (!res) {
1577  struct ast_frame *fr;
1578 
1579  if (ast_waitfor(chan, -1) < 0) {
1580  res = -1;
1581  break;
1582  }
1583 
1584  fr = ast_read_noaudio(chan);
1585 
1586  if (!fr) {
1587  res = -1;
1588  break;
1589  }
1590 
1591  if (fr->frametype != AST_FRAME_CONTROL) {
1592  continue;
1593  }
1594 
1595  res = control_tone_frame_response(chan, fr, ts, tone_indication, &paused);
1596  if (res == CONTROL_TONE_RESPONSE_FINISHED) {
1597  res = 0;
1598  break;
1599  } else if (res == CONTROL_TONE_RESPONSE_FAILED) {
1600  res = -1;
1601  break;
1602  }
1603  }
1604 
1605  if (ts) {
1607  }
1608 
1609  if (zone) {
1610  ast_tone_zone_unref(zone);
1611  }
1612 
1613  return res;
1614 }
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
Definition: indications.h:205
A set of tones for a given locale.
Definition: indications.h:74
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:439
Description of a tone.
Definition: indications.h:35
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:461
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
Data structure associated with a single frame of data.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
const char * data
Description of a tone.
Definition: indications.h:52
enum ast_frame_type frametype
struct ast_frame * ast_read_noaudio(struct ast_channel *chan)
Reads a frame, returning AST_FRAME_NULL frame if audio.
Definition: channel.c:4267
int ast_dtmf_stream ( struct ast_channel chan,
struct ast_channel peer,
const char *  digits,
int  between,
unsigned int  duration 
)

Send a string of DTMF digits to a channel.

Parameters
chanThe channel that will receive the DTMF frames
peer(optional) Peer channel that will be autoserviced while the primary channel is receiving DTMF
digitsThis is a string of characters representing the DTMF digits to be sent to the channel. Valid characters are "0123456789*#abcdABCD". Note: You can pass arguments 'f' or 'F', if you want to Flash the channel (if supported by the channel), or 'w' to add a 500 millisecond pause to the DTMF sequence.
betweenThis is the number of milliseconds to wait in between each DTMF digit. If zero milliseconds is specified, then the default value of 100 will be used.
durationThis is the duration that each DTMF digit should have.
Precondition
This must only be called by the channel's media handler thread.
Return values
0on success.
-1on failure or a channel hung up.

Definition at line 1127 of file main/app.c.

References ast_autoservice_start(), and ast_autoservice_stop().

Referenced by dial_exec_full().

1128 {
1129  int res;
1130 
1131  if (peer && ast_autoservice_start(peer)) {
1132  return -1;
1133  }
1134  res = dtmf_stream(chan, digits, between, duration, 0);
1135  if (peer && ast_autoservice_stop(peer)) {
1136  res = -1;
1137  }
1138 
1139  return res;
1140 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
void ast_dtmf_stream_external ( struct ast_channel chan,
const char *  digits,
int  between,
unsigned int  duration 
)

Send a string of DTMF digits to a channel from an external thread.

Parameters
chanThe channel that will receive the DTMF frames
digitsThis is a string of characters representing the DTMF digits to be sent to the channel. Valid characters are "0123456789*#abcdABCD". Note: You can pass arguments 'f' or 'F', if you want to Flash the channel (if supported by the channel), or 'w' to add a 500 millisecond pause to the DTMF sequence.
betweenThis is the number of milliseconds to wait in between each DTMF digit. If zero milliseconds is specified, then the default value of 100 will be used.
durationThis is the duration that each DTMF digit should have.
Precondition
This must only be called by threads that are not the channel's media handler thread.

Definition at line 1142 of file main/app.c.

1143 {
1144  dtmf_stream(chan, digits, between, duration, 1);
1145 }
int ast_get_encoded_char ( const char *  stream,
char *  result,
size_t *  consumed 
)

Decode an encoded control or extended ASCII character.

Parameters
[in]streamString to decode
[out]resultDecoded character
[out]consumedNumber of characters used in stream to encode the character
Return values
-1Stream is of zero length
0Success

Definition at line 3087 of file main/app.c.

References ast_debug.

Referenced by ast_get_encoded_str(), ast_str_get_encoded_str(), and filter().

3088 {
3089  int i;
3090  *consumed = 1;
3091  *result = 0;
3092  if (ast_strlen_zero(stream)) {
3093  *consumed = 0;
3094  return -1;
3095  }
3096 
3097  if (*stream == '\\') {
3098  *consumed = 2;
3099  switch (*(stream + 1)) {
3100  case 'n':
3101  *result = '\n';
3102  break;
3103  case 'r':
3104  *result = '\r';
3105  break;
3106  case 't':
3107  *result = '\t';
3108  break;
3109  case 'x':
3110  /* Hexadecimal */
3111  if (strchr("0123456789ABCDEFabcdef", *(stream + 2)) && *(stream + 2) != '\0') {
3112  *consumed = 3;
3113  if (*(stream + 2) <= '9') {
3114  *result = *(stream + 2) - '0';
3115  } else if (*(stream + 2) <= 'F') {
3116  *result = *(stream + 2) - 'A' + 10;
3117  } else {
3118  *result = *(stream + 2) - 'a' + 10;
3119  }
3120  } else {
3121  ast_log(LOG_ERROR, "Illegal character '%c' in hexadecimal string\n", *(stream + 2));
3122  return -1;
3123  }
3124 
3125  if (strchr("0123456789ABCDEFabcdef", *(stream + 3)) && *(stream + 3) != '\0') {
3126  *consumed = 4;
3127  *result <<= 4;
3128  if (*(stream + 3) <= '9') {
3129  *result += *(stream + 3) - '0';
3130  } else if (*(stream + 3) <= 'F') {
3131  *result += *(stream + 3) - 'A' + 10;
3132  } else {
3133  *result += *(stream + 3) - 'a' + 10;
3134  }
3135  }
3136  break;
3137  case '0':
3138  /* Octal */
3139  *consumed = 2;
3140  for (i = 2; ; i++) {
3141  if (strchr("01234567", *(stream + i)) && *(stream + i) != '\0') {
3142  (*consumed)++;
3143  ast_debug(5, "result was %d, ", *result);
3144  *result <<= 3;
3145  *result += *(stream + i) - '0';
3146  ast_debug(5, "is now %d\n", *result);
3147  } else {
3148  break;
3149  }
3150  }
3151  break;
3152  default:
3153  *result = *(stream + 1);
3154  }
3155  } else {
3156  *result = *stream;
3157  *consumed = 1;
3158  }
3159  return 0;
3160 }
#define ast_debug(level,...)
Log a DEBUG message.
char* ast_get_encoded_str ( const char *  stream,
char *  result,
size_t  result_len 
)

Decode a stream of encoded control or extended ASCII characters.

Parameters
[in]streamEncoded string
[out]resultDecoded string
[in]result_lenMaximum size of the result buffer
Returns
A pointer to the result string

Definition at line 3162 of file main/app.c.

References ast_get_encoded_char().

Referenced by chan_pjsip_new().

3163 {
3164  char *cur = result;
3165  size_t consumed;
3166 
3167  while (cur < result + result_size - 1 && !ast_get_encoded_char(stream, cur, &consumed)) {
3168  cur++;
3169  stream += consumed;
3170  }
3171  *cur = '\0';
3172  return result;
3173 }
int ast_get_encoded_char(const char *stream, char *result, size_t *consumed)
Decode an encoded control or extended ASCII character.
Definition: main/app.c:3087
void ast_install_stack_functions ( const struct ast_app_stack_funcs funcs)

Set stack application function callbacks.

Since
11
Parameters
funcsStack applications callback functions.

Definition at line 273 of file main/app.c.

274 {
275  app_stack_callbacks = funcs;
276 }
int ast_ivr_menu_run ( struct ast_channel c,
struct ast_ivr_menu menu,
void *  cbdata 
)

Runs an IVR menu.

Return values
0on successful completion.
-1on hangup.
-2on user error in menu.

Definition at line 2942 of file main/app.c.

2943 {
2944  int res = ast_ivr_menu_run_internal(chan, menu, cbdata);
2945  /* Hide internal coding */
2946  return res > 0 ? 0 : res;
2947 }
enum AST_LOCK_RESULT ast_lock_path ( const char *  path)

Lock a filesystem path.

Parameters
paththe path to be locked
Returns
one of AST_LOCK_RESULT values

Definition at line 2614 of file main/app.c.

Referenced by ast_module_reload(), and vm_lock_path().

2615 {
2616  enum AST_LOCK_RESULT r = AST_LOCK_FAILURE;
2617 
2618  switch (ast_lock_type) {
2619  case AST_LOCK_TYPE_LOCKFILE:
2620  r = ast_lock_path_lockfile(path);
2621  break;
2622  case AST_LOCK_TYPE_FLOCK:
2623  r = ast_lock_path_flock(path);
2624  break;
2625  }
2626 
2627  return r;
2628 }
int ast_mf_stream ( struct ast_channel chan,
struct ast_channel peer,
struct ast_channel chan2,
const char *  digits,
int  between,
unsigned int  duration,
unsigned int  durationkp,
unsigned int  durationst,
int  is_external 
)

Send a string of MF digits to a channel.

Parameters
chanThe channel that will receive the MF digits.
peer(optional) Peer channel that will be autoserviced while the primary channel is receiving MF
chan2A second channel that will simultaneously receive MF digits. This option may only be used if is_external is 0.
digitsThis is a string of characters representing the MF digits to be sent to the channel. Valid characters are "0123456789*#abcdABCD". Note: You can pass arguments 'f' or 'F', if you want to Flash the channel (if supported by the channel), or 'w' or 'W' to add a wink (if supported by the channel).
betweenThis is the number of milliseconds to wait in between each MF digit. If zero milliseconds is specified, then the default value of 50 will be used.
durationThis is the duration that each numeric MF digit should have. Default value is 55.
durationkpThis is the duration that each KP digit should have. Default is 120.
durationstThis is the duration that each ST, STP, ST2P, or ST3P digit should have. Default is 65.
is_external1 if called by a thread that is not the channel's media handler thread, 0 if called by the channel's media handler thread.
Return values
0on success.
-1on failure or a channel hung up.

Definition at line 1113 of file main/app.c.

References ast_autoservice_start(), and ast_autoservice_stop().

1115 {
1116  int res;
1117  if (!is_external && !chan2 && peer && ast_autoservice_start(peer)) {
1118  return -1;
1119  }
1120  res = mf_stream(chan, chan2, digits, between, duration, durationkp, durationst, is_external);
1121  if (!is_external && !chan2 && peer && ast_autoservice_stop(peer)) {
1122  res = -1;
1123  }
1124  return res;
1125 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_play_and_prepend ( struct ast_channel chan,
char *  playfile,
char *  recordfile,
int  maxtime_sec,
char *  fmt,
int *  duration,
int *  sound_duration,
int  beep,
int  silencethreshold,
int  maxsilence_ms 
)

Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a little differently from normal recordings This function will not play a success message due to post-recording control in the application this was added for.

Parameters
chanthe channel being recorded
playfileFilename of sound to play before recording begins
recordfileFilename to save the recording
maxtime_secLongest possible message length in seconds
fmtstring containing all formats to be recorded delimited by '|'
durationpointer to integer for storing length of the recording
sound_durationpointer to integer for storing length of the recording minus all silence
beepwhether to play a beep to prompt the recording
silencethresholdtolerance of noise levels that can be considered silence for the purpose of silence timeout, -1 for default
maxsilence_mslength of time in milliseconds which will trigger a timeout from silence, -1 for default.
Return values
-1failure or hangup
'S'Recording ended from silence timeout
't'Recording either exceeded maximum duration or the call was ended via DTMF

Definition at line 2159 of file main/app.c.

References __ast_play_and_record(), and AST_RECORD_IF_EXISTS_OVERWRITE.

Referenced by vm_forwardoptions().

2160 {
2161  return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, NULL, 1, default_acceptdtmf, default_canceldtmf, 1, AST_RECORD_IF_EXISTS_OVERWRITE);
2162 }
static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
Definition: main/app.c:1727
int ast_play_and_record ( struct ast_channel chan,
const char *  playfile,
const char *  recordfile,
int  maxtime_sec,
const char *  fmt,
int *  duration,
int *  sound_duration,
int  silencethreshold,
int  maxsilence_ms,
const char *  path 
)

Record a file based on input from a channel. Use default accept and cancel DTMF. This function will play "auth-thankyou" upon successful recording.

Parameters
chanthe channel being recorded
playfileFilename of sound to play before recording begins
recordfileFilename to save the recording
maxtime_secLongest possible message length in seconds
fmtstring containing all formats to be recorded delimited by '|'
durationpointer to integer for storing length of the recording
sound_durationpointer to integer for storing length of the recording minus all silence
silencethresholdtolerance of noise levels that can be considered silence for the purpose of silence timeout, -1 for default
maxsilence_mslength of time in milliseconds which will trigger a timeout from silence, -1 for default
pathOptional filesystem path to unlock
Return values
-1failure or hangup
'S'Recording ended from silence timeout
't'Recording ended from the message exceeding the maximum duration
dtmfcharRecording ended via the return value's DTMF character for either cancel or accept.

Definition at line 2154 of file main/app.c.

References __ast_play_and_record(), and AST_RECORD_IF_EXISTS_OVERWRITE.

Referenced by ast_record_review(), and setup_privacy_args().

2155 {
2156  return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
2157 }
static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
Definition: main/app.c:1727
int ast_play_and_record_full ( struct ast_channel chan,
const char *  playfile,
const char *  recordfile,
int  maxtime_sec,
const char *  fmt,
int *  duration,
int *  sound_duration,
int  beep,
int  silencethreshold,
int  maxsilence_ms,
const char *  path,
const char *  acceptdtmf,
const char *  canceldtmf,
int  skip_confirmation_sound,
enum ast_record_if_exists  if_exists 
)

Record a file based on input from a channel This function will play "auth-thankyou" upon successful recording if skip_confirmation_sound is false.

Parameters
chanthe channel being recorded
playfileFilename of sound to play before recording begins. A beep is also played when playfile completes, before the recording begins.
recordfileFilename to save the recording
maxtime_secLongest possible message length in seconds
fmtstring containing all formats to be recorded delimited by '|'
durationpointer to integer for storing length of the recording
beepIf true, play a beep before recording begins (and doesn't play playfile)
sound_durationpointer to integer for storing length of the recording minus all silence
silencethresholdtolerance of noise levels that can be considered silence for the purpose of silence timeout, -1 for default
maxsilence_msLength of time in milliseconds which will trigger a timeout from silence, -1 for default
pathOptional filesystem path to unlock
acceptdtmfCharacter of DTMF to end and accept the recording
canceldtmfCharacter of DTMF to end and cancel the recording
skip_confirmation_soundIf true, don't play auth-thankyou at end. Nice for custom recording prompts in apps.
if_existsAction to take if recording already exists.
Return values
-1failure or hangup
'S'Recording ended from silence timeout
't'Recording ended from the message exceeding the maximum duration
dtmfcharRecording ended via the return value's DTMF character for either cancel or accept.

Definition at line 2149 of file main/app.c.

References __ast_play_and_record(), and S_OR.

2150 {
2151  return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, ""), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists);
2152 }
static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
Definition: main/app.c:1727
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
struct stasis_topic* ast_queue_topic ( const char *  queuename)

Get the Stasis Message Bus API topic for queue messages for a particular queue name.

Parameters
queuenameThe name for which to get the topic
Returns
The topic structure for queue messages for a given name
Return values
NULLif it failed to be found or allocated
Since
12

Definition at line 3349 of file main/app.c.

References stasis_topic_pool_get_topic().

Referenced by send_agent_complete().

3350 {
3351  return stasis_topic_pool_get_topic(queue_topic_pool, queuename);
3352 }
struct stasis_topic * stasis_topic_pool_get_topic(struct stasis_topic_pool *pool, const char *topic_name)
Find or create a topic in the pool.
Definition: stasis.c:1884
struct stasis_topic* ast_queue_topic_all ( void  )

Get the Stasis Message Bus API topic for queue messages.

Returns
The topic structure for queue messages
Return values
NULLif it has not been allocated
Since
12

Definition at line 3344 of file main/app.c.

References queue_topic_all.

Referenced by load_module().

3345 {
3346  return queue_topic_all;
3347 }
static struct stasis_topic * queue_topic_all
Define Stasis Message Bus API topic objects.
Definition: main/app.c:90
int ast_safe_fork ( int  stop_reaper)

Common routine to safely fork without a chance of a signal handler firing badly in the child.

Parameters
[in]stop_reaperflag to determine if sigchld handler is replaced or not
Since
1.6.1

Definition at line 3207 of file main/app.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_replace_sigchld().

3208 {
3209  sigset_t signal_set, old_set;
3210  int pid;
3211 
3212  /* Don't let the default signal handler for children reap our status */
3213  if (stop_reaper) {
3215  }
3216 
3217  /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
3218  * no effect" warning */
3219  (void) sigfillset(&signal_set);
3220  pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
3221 
3222  pid = fork();
3223 
3224  if (pid != 0) {
3225  /* Fork failed or parent */
3226  pthread_sigmask(SIG_SETMASK, &old_set, NULL);
3227  if (!stop_reaper && pid > 0) {
3228  struct zombie *cur = ast_calloc(1, sizeof(*cur));
3229  if (cur) {
3230  cur->pid = pid;
3232  AST_LIST_INSERT_TAIL(&zombies, cur, list);
3234  if (shaun_of_the_dead_thread == AST_PTHREADT_NULL) {
3235  if (ast_pthread_create_background(&shaun_of_the_dead_thread, NULL, shaun_of_the_dead, NULL)) {
3236  ast_log(LOG_ERROR, "Shaun of the Dead wants to kill zombies, but can't?!!\n");
3237  shaun_of_the_dead_thread = AST_PTHREADT_NULL;
3238  }
3239  }
3240  }
3241  }
3242  return pid;
3243  } else {
3244  /* Child */
3245 #ifdef HAVE_CAP
3246  cap_set_proc(child_cap);
3247 #endif
3248 
3249  /* Before we unblock our signals, return our trapped signals back to the defaults */
3250  signal(SIGHUP, SIG_DFL);
3251  signal(SIGCHLD, SIG_DFL);
3252  signal(SIGINT, SIG_DFL);
3253  signal(SIGURG, SIG_DFL);
3254  signal(SIGTERM, SIG_DFL);
3255  signal(SIGPIPE, SIG_DFL);
3256  signal(SIGXFSZ, SIG_DFL);
3257 
3258  /* unblock important signal handlers */
3259  if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
3260  ast_log(LOG_WARNING, "unable to unblock signals: %s\n", strerror(errno));
3261  _exit(1);
3262  }
3263 
3264  return pid;
3265  }
3266 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
Definition: extconf.c:801
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void ast_safe_fork_cleanup ( void  )

Common routine to cleanup after fork'ed process is complete (if reaping was stopped)

Since
1.6.1

Definition at line 3268 of file main/app.c.

References ast_unreplace_sigchld().

3269 {
3271 }
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
Definition: extconf.c:815
void ast_set_lock_type ( enum AST_LOCK_TYPE  type)

Set the type of locks used by ast_lock_path()

Parameters
typethe locking type to use

Definition at line 2609 of file main/app.c.

2610 {
2611  ast_lock_type = type;
2612 }
int ast_sf_stream ( struct ast_channel chan,
struct ast_channel peer,
struct ast_channel chan2,
const char *  digits,
int  frequency,
int  is_external 
)

Send a string of SF digits to a channel.

Parameters
chanThe channel that will receive the SF digits
peer(optional) Peer channel that will be autoserviced while the primary channel is receiving SF
chan2A second channel that will simultaneously receive SF digits. This option may only be used if is_external is 0.
digitsThis is a string of characters representing the SF digits to be sent to the channel. Valid characters are "0123456789". Note: You can pass arguments 'f' or 'F', if you want to Flash the channel (if supported by the channel), or 'w' or 'W' to add a wink (if supported by the channel).
frequencyThe frequency to use for signaling. 0 can be specified for the default, which is 2600 Hz.
is_external1 if called by a thread that is not the channel's media handler thread, 0 if called by the channel's media handler thread.
Return values
0on success.
-1on failure or a channel hung up.

Definition at line 1097 of file main/app.c.

References ast_autoservice_start(), and ast_autoservice_stop().

1098 {
1099  int res;
1100  if (frequency <= 0) {
1101  frequency = 2600;
1102  }
1103  if (!is_external && !chan2 && peer && ast_autoservice_start(peer)) {
1104  return -1;
1105  }
1106  res = sf_stream(chan, chan2, digits, frequency, is_external);
1107  if (!is_external && !chan2 && peer && ast_autoservice_stop(peer)) {
1108  res = -1;
1109  }
1110  return res;
1111 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
int ast_vm_greeter_is_registered ( void  )

Determine if a voicemail greeter provider is registered.

Since
13.0.0
Return values
0if no provider registered.
1if a provider is registered.

Definition at line 468 of file main/app.c.

References ao2_global_obj_ref.

469 {
470  struct ast_vm_greeter_functions *table;
471  int is_registered;
472 
473  table = ao2_global_obj_ref(vm_greeter_provider);
474  is_registered = table ? 1 : 0;
475  ao2_cleanup(table);
476  return is_registered;
477 }
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
void ast_vm_greeter_unregister ( const char *  module_name)

Unregister the specified voicemail greeter provider.

Since
13.0.0
Parameters
module_nameThe module name of the provider to unregister

Definition at line 511 of file main/app.c.

References ao2_global_obj_ref, ao2_global_obj_release, and ast_vm_greeter_functions::module_name.

512 {
513  struct ast_vm_greeter_functions *table;
514 
515  table = ao2_global_obj_ref(vm_greeter_provider);
516  if (table && !strcmp(table->module_name, module_name)) {
517  ao2_global_obj_release(vm_greeter_provider);
518  }
519  ao2_cleanup(table);
520 }
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
const char * module_name
The name of the module that provides the voicemail greeter functionality.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
const char* ast_vm_index_to_foldername ( int  id)

Return name of folder, given an id.

Parameters
[in]idFolder id
Returns
Name of folder

Definition at line 653 of file main/app.c.

654 {
655  const char *res = NULL;
656 
657  VM_API_CALL(res, index_to_foldername, (id));
658  return res;
659 }
int ast_vm_is_registered ( void  )

Determine if a voicemail provider is registered.

Since
12.0.0
Return values
0if no provider registered.
1if a provider is registered.

Definition at line 357 of file main/app.c.

References ao2_global_obj_ref.

358 {
359  struct ast_vm_functions *table;
360  int is_registered;
361 
362  table = ao2_global_obj_ref(vm_provider);
363  is_registered = table ? 1 : 0;
364  ao2_cleanup(table);
365  return is_registered;
366 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
Voicemail function table definition.
struct ast_vm_mailbox_snapshot* ast_vm_mailbox_snapshot_create ( const char *  mailbox,
const char *  context,
const char *  folder,
int  descending,
enum ast_vm_snapshot_sort_val  sort_val,
int  combine_INBOX_and_OLD 
)

Create a snapshot of a mailbox which contains information about every msg.

Parameters
mailboxthe mailbox to look for
contextthe context to look for the mailbox in
folderOPTIONAL. When not NULL only msgs from the specified folder will be included.
descendinglist the msgs in descending order rather than ascending order.
sort_valWhat to sort in the snapshot.
combine_INBOX_and_OLDWhen this argument is set, The OLD folder will be represented in the INBOX folder of the snapshot. This allows the snapshot to represent the OLD and INBOX messages in sorted order merged together.
Returns
snapshot on success
Return values
NULLon failure

Definition at line 661 of file main/app.c.

Referenced by append_vmbox_info_astman().

667 {
668  struct ast_vm_mailbox_snapshot *res = NULL;
669 
670  VM_API_CALL(res, mailbox_snapshot_create, (mailbox, context, folder, descending,
671  sort_val, combine_INBOX_and_OLD));
672  return res;
673 }
struct ast_vm_mailbox_snapshot* ast_vm_mailbox_snapshot_destroy ( struct ast_vm_mailbox_snapshot mailbox_snapshot)

destroy a snapshot

Parameters
mailbox_snapshotThe snapshot to destroy.
Return values
NULL

Definition at line 675 of file main/app.c.

Referenced by append_vmbox_info_astman().

676 {
677  struct ast_vm_mailbox_snapshot *res = NULL;
678 
679  VM_API_CALL(res, mailbox_snapshot_destroy, (mailbox_snapshot));
680  return res;
681 }
int ast_vm_msg_forward ( const char *  from_mailbox,
const char *  from_context,
const char *  from_folder,
const char *  to_mailbox,
const char *  to_context,
const char *  to_folder,
size_t  num_msgs,
const char *  msg_ids[],
int  delete_old 
)

forward a message from one mailbox to another.

from_mailbox The original mailbox the message is being forwarded from from_context The voicemail context of the from_mailbox from_folder The folder from which the message is being forwarded to_mailbox The mailbox to forward the message to to_context The voicemail context of the to_mailbox to_folder The folder to which the message is being forwarded num_msgs The number of messages being forwarded msg_ids The message IDs of the messages in from_mailbox to forward delete_old If non-zero, the forwarded messages are also deleted from from_mailbox. Otherwise, the messages will remain in the from_mailbox.

Return values
-1Failure
0Success

Definition at line 709 of file main/app.c.

718 {
719  int res = 0;
720 
721  VM_API_CALL(res, msg_forward, (from_mailbox, from_context, from_folder, to_mailbox,
722  to_context, to_folder, num_msgs, msg_ids, delete_old));
723  return res;
724 }
int ast_vm_msg_move ( const char *  mailbox,
const char *  context,
size_t  num_msgs,
const char *  oldfolder,
const char *  old_msg_ids[],
const char *  newfolder 
)

Move messages from one folder to another.

Parameters
mailboxThe mailbox to which the folders belong
contextThe voicemail context for the mailbox
num_msgsThe number of messages to move
oldfolderThe folder from where messages should be moved
old_msg_idsThe message IDs of the messages to move
newfolderThe folder to which messages should be moved new folder. This array must be num_msgs sized.
Return values
-1Failure
0Success

Definition at line 683 of file main/app.c.

689 {
690  int res = 0;
691 
692  VM_API_CALL(res, msg_move, (mailbox, context, num_msgs, oldfolder, old_msg_ids,
693  newfolder));
694  return res;
695 }
int ast_vm_msg_play ( struct ast_channel chan,
const char *  mailbox,
const char *  context,
const char *  folder,
const char *  msg_num,
ast_vm_msg_play_cb cb 
)

Play a voicemail msg back on a channel.

Parameters
chan
mailboxmsg is in.
contextof mailbox.
foldervoicemail folder to look in.
msg_nummessage number in the voicemailbox to playback to the channel.
cb
Return values
0success
-1failure

Definition at line 726 of file main/app.c.

732 {
733  int res = 0;
734 
735  VM_API_CALL(res, msg_play, (chan, mailbox, context, folder, msg_num, cb));
736  return res;
737 }
int ast_vm_msg_remove ( const char *  mailbox,
const char *  context,
size_t  num_msgs,
const char *  folder,
const char *  msgs[] 
)

Remove/delete messages from a mailbox folder.

Parameters
mailboxThe mailbox from which to delete messages
contextThe voicemail context for the mailbox
num_msgsThe number of messages to delete
folderThe folder from which to remove messages
msgsThe message IDs of the messages to delete
Return values
-1Failure
0Success

Definition at line 697 of file main/app.c.

702 {
703  int res = 0;
704 
705  VM_API_CALL(res, msg_remove, (mailbox, context, num_msgs, folder, msgs));
706  return res;
707 }
void ast_vm_unregister ( const char *  module_name)

Unregister the specified voicemail provider.

Parameters
module_nameThe module name of the provider to unregister

Definition at line 400 of file main/app.c.

References ao2_global_obj_ref, ao2_global_obj_release, and ast_vm_functions::module_name.

401 {
402  struct ast_vm_functions *table;
403 
404  table = ao2_global_obj_ref(vm_provider);
405  if (table && !strcmp(table->module_name, module_name)) {
406  ao2_global_obj_release(vm_provider);
407  }
408  ao2_cleanup(table);
409 }
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
const char * module_name
The name of the module that provides the voicemail functionality.
Voicemail function table definition.
static struct ast_frame* make_silence ( const struct ast_frame orig)
static

Construct a silence frame of the same duration as orig.

The orig frame must be ast_format_slin.

Parameters
origFrame as basis for silence to generate.
Returns
New frame of silence; free with ast_frfree().
Return values
NULLon error.

Definition at line 1640 of file main/app.c.

References ao2_bump, ast_calloc, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_slin, AST_FRAME_VOICE, AST_LIST_NEXT, AST_MALLOCD_HDR, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame::mallocd, ast_frame::samples, and ast_frame::subclass.

Referenced by __ast_play_and_record().

1641 {
1642  struct ast_frame *silence;
1643  size_t size;
1644  size_t datalen;
1645  size_t samples = 0;
1646 
1647  if (!orig) {
1648  return NULL;
1649  }
1650  do {
1652  ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
1653  return NULL;
1654  }
1655 
1656  samples += orig->samples;
1657 
1658  orig = AST_LIST_NEXT(orig, frame_list);
1659  } while (orig);
1660 
1661  ast_verb(4, "Silencing %zu samples\n", samples);
1662 
1663 
1664  datalen = sizeof(short) * samples;
1665  size = sizeof(*silence) + datalen;
1666  silence = ast_calloc(1, size);
1667  if (!silence) {
1668  return NULL;
1669  }
1670 
1671  silence->mallocd = AST_MALLOCD_HDR;
1672  silence->frametype = AST_FRAME_VOICE;
1673  silence->data.ptr = (void *)(silence + 1);
1674  silence->samples = samples;
1675  silence->datalen = datalen;
1676 
1678 
1679  return silence;
1680 }
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
struct ast_frame_subclass subclass
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define AST_MALLOCD_HDR
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
Data structure associated with a single frame of data.
enum ast_frame_type frametype
struct ast_format * format
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static int set_read_to_slin ( struct ast_channel chan,
struct ast_format **  orig_format 
)
static

Sets a channel's read format to ast_format_slin, recording its original format.

Parameters
chanChannel to modify.
[out]orig_formatOutput variable to store channel's original read format.
Returns
0 on success.
-1 on error.

Definition at line 1692 of file main/app.c.

References ao2_bump, ast_format_slin, and ast_set_read_format().

Referenced by __ast_play_and_record().

1693 {
1694  if (!chan || !orig_format) {
1695  return -1;
1696  }
1697  *orig_format = ao2_bump(ast_channel_readformat(chan));
1698  return ast_set_read_format(chan, ast_format_slin);
1699 }
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5762
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41

Variable Documentation

int vm_greeter_warnings
static

Voicemail greeter not registered warning

Definition at line 466 of file main/app.c.

int vm_warnings
static

Voicemail not registered warning

Definition at line 355 of file main/app.c.