Asterisk - The Open Source Telephony Project  18.5.0
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 <dirent.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"
Include dependency graph for main/app.c:

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 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. More...
 
static AO2_GLOBAL_OBJ_STATIC (vm_provider_holder)
 Holding container for the voicemail provider used while testing. More...
 
static AO2_GLOBAL_OBJ_STATIC (vm_greeter_provider)
 The container for the voicemail greeter provider. More...
 
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 More...
 
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_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
 Run a macro on a channel, placing an optional second channel into autoservice. 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)
 ast_app_getdata 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. More...
 
int ast_app_group_discard (struct ast_channel *chan)
 Discard all group counting for a channel. More...
 
int ast_app_group_get_count (const char *group, const char *category)
 Get the current channel count of the specified group and category. More...
 
struct ast_group_infoast_app_group_list_head (void)
 Get the head of the group count list. More...
 
int ast_app_group_list_rdlock (void)
 Read Lock the group count list. More...
 
int ast_app_group_list_unlock (void)
 Unlock the group count list. More...
 
int ast_app_group_list_wrlock (void)
 Write Lock the group count list. More...
 
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. More...
 
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. More...
 
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. More...
 
int ast_app_group_update (struct ast_channel *old, struct ast_channel *new)
 Update all group counting for a channel to a new one. More...
 
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_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_name, const char *macro_args)
 Run a macro on a channel, placing an optional second channel into autoservice. 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...
 
void ast_install_vm_test_functions (ast_vm_test_create_user_fn *vm_test_create_user_func, ast_vm_test_destroy_user_fn *vm_test_destroy_user_func)
 
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. More...
 
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, 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. More...
 
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. More...
 
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. More...
 
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_str_get_encoded_str (struct ast_str **str, int maxlen, const char *stream)
 Decode a stream of encoded control or extended ASCII characters. More...
 
 AST_THREADSTORAGE_PUBLIC (ast_str_thread_global_buf)
 
void ast_uninstall_vm_test_functions (void)
 
int ast_unlock_path (const char *path)
 Unlock a path. More...
 
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...
 
int ast_vm_test_create_user (const char *context, const char *mailbox)
 
int ast_vm_test_destroy_user (const char *context, const char *mailbox)
 
void ast_vm_test_swap_table_in (const struct ast_vm_functions *vm_table)
 Swap out existing voicemail functions with a temporary set of functions for use with unit tests. More...
 
void ast_vm_test_swap_table_out (void)
 Used after ast_vm_test_swap_table_in to restore the original set of voicemail functions. 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, 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_SLINEAR, recording its original format. More...
 
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 ast_vm_test_create_user_fnast_vm_test_create_user_func = NULL
 
static ast_vm_test_destroy_user_fnast_vm_test_destroy_user_func = NULL
 
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 int provider_is_swapped = 0
 
static struct stasis_topicqueue_topic_all
 
static struct stasis_topic_poolqueue_topic_pool
 
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} } , }
 

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.

Macro Definition Documentation

◆ AST_MAX_FORMATS

#define AST_MAX_FORMATS   10

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

Referenced by __ast_play_and_record().

◆ FMT

#define FMT   "%30Lf%9s"

◆ RES_EXIT

#define RES_EXIT   (1 << 17)
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().

◆ RES_REPEAT

#define RES_REPEAT   (1 << 18)
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().

◆ RES_RESTART

#define RES_RESTART   ((1 << 19) | RES_REPEAT)
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().

◆ RES_UPONE

#define RES_UPONE   (1 << 16)
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_ivr_menu_run_internal(), and ivr_dispatch().

◆ VM_API_CALL

#define VM_API_CALL (   res,
  api_call,
  api_parms 
)

◆ VM_GREETER_API_CALL

#define VM_GREETER_API_CALL (   res,
  api_call,
  api_parms 
)
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_app_sayname().

Enumeration Type Documentation

◆ control_tone_frame_response_result

Enumerator
CONTROL_TONE_RESPONSE_FAILED 
CONTROL_TONE_RESPONSE_NORMAL 
CONTROL_TONE_RESPONSE_FINISHED 

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

Function Documentation

◆ __ast_app_separate_args()

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 2199 of file main/app.c.

References buf, NULL, paren, and quote().

2200 {
2201  int argc;
2202  char *scan, *wasdelim = NULL;
2203  int paren = 0, quote = 0, bracket = 0;
2204 
2205  if (!array || !arraylen) {
2206  return 0;
2207  }
2208 
2209  memset(array, 0, arraylen * sizeof(*array));
2210 
2211  if (!buf) {
2212  return 0;
2213  }
2214 
2215  scan = buf;
2216 
2217  for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2218  array[argc] = scan;
2219  for (; *scan; scan++) {
2220  if (*scan == '(') {
2221  paren++;
2222  } else if (*scan == ')') {
2223  if (paren) {
2224  paren--;
2225  }
2226  } else if (*scan == '[') {
2227  bracket++;
2228  } else if (*scan == ']') {
2229  if (bracket) {
2230  bracket--;
2231  }
2232  } else if (*scan == '"' && delim != '"') {
2233  quote = quote ? 0 : 1;
2234  if (remove_chars) {
2235  /* Remove quote character from argument */
2236  memmove(scan, scan + 1, strlen(scan));
2237  scan--;
2238  }
2239  } else if (*scan == '\\') {
2240  if (remove_chars) {
2241  /* Literal character, don't parse */
2242  memmove(scan, scan + 1, strlen(scan));
2243  } else {
2244  scan++;
2245  }
2246  } else if ((*scan == delim) && !paren && !quote && !bracket) {
2247  wasdelim = scan;
2248  *scan++ = '\0';
2249  break;
2250  }
2251  }
2252  }
2253 
2254  /* If the last character in the original string was the delimiter, then
2255  * there is one additional argument. */
2256  if (*scan || (scan > buf && (scan - 1) == wasdelim)) {
2257  array[argc++] = scan;
2258  }
2259 
2260  return argc;
2261 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
#define paren
Definition: ael_lex.c:973

◆ __ast_play_and_record()

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.
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.
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ao2_cleanup, ast_assert, ast_channel_name(), 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_free(), ast_dsp_new(), ast_dsp_set_threshold(), ast_dsp_silence(), AST_FILE_MODE, ast_filedelete(), ast_filerename(), ast_format_get_name(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frame_dtor(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate(), ast_log, AST_MAX_FORMATS, ast_opt_transmit_silence, 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_verb, ast_waitfor(), ast_writefile(), ast_writestream(), comment, d, end, ast_frame::frametype, global_maxsilence, global_silence_threshold, ast_frame_subclass::integer, LOG_WARNING, make_silence(), muted, NULL, PATH_MAX, set_read_to_slin(), strsep(), ast_frame::subclass, and ast_dsp::totalsilence.

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

1581 {
1582  int d = 0;
1583  char *fmts;
1584  char comment[256];
1585  int x, fmtcnt = 1, res = -1, outmsg = 0;
1586  struct ast_filestream *others[AST_MAX_FORMATS];
1587  const char *sfmt[AST_MAX_FORMATS];
1588  char *stringp = NULL;
1589  time_t start, end;
1590  struct ast_dsp *sildet = NULL; /* silence detector dsp */
1591  int totalsilence = 0;
1592  int dspsilence = 0;
1593  int olddspsilence = 0;
1594  struct ast_format *rfmt = NULL;
1595  struct ast_silence_generator *silgen = NULL;
1596  char prependfile[PATH_MAX];
1597  int ioflags; /* IO flags for writing output file */
1598 
1599  ioflags = O_CREAT|O_WRONLY;
1600 
1601  switch (if_exists) {
1603  ioflags |= O_EXCL;
1604  break;
1606  ioflags |= O_TRUNC;
1607  break;
1609  ioflags |= O_APPEND;
1610  break;
1612  ast_assert(0);
1613  break;
1614  }
1615 
1616  if (silencethreshold < 0) {
1618  }
1619 
1620  if (maxsilence < 0) {
1622  }
1623 
1624  /* barf if no pointer passed to store duration in */
1625  if (!duration) {
1626  ast_log(LOG_WARNING, "Error play_and_record called without duration pointer\n");
1627  return -1;
1628  }
1629 
1630  ast_debug(1, "play_and_record: %s, %s, '%s'\n", playfile ? playfile : "<None>", recordfile, fmt);
1631  snprintf(comment, sizeof(comment), "Playing %s, Recording to: %s on %s\n", playfile ? playfile : "<None>", recordfile, ast_channel_name(chan));
1632 
1633  if (playfile || beep) {
1634  if (!beep) {
1635  d = ast_play_and_wait(chan, playfile);
1636  }
1637  if (d > -1) {
1638  d = ast_stream_and_wait(chan, "beep", "");
1639  }
1640  if (d < 0) {
1641  return -1;
1642  }
1643  }
1644 
1645  if (prepend) {
1646  ast_copy_string(prependfile, recordfile, sizeof(prependfile));
1647  strncat(prependfile, "-prepend", sizeof(prependfile) - strlen(prependfile) - 1);
1648  }
1649 
1650  fmts = ast_strdupa(fmt);
1651 
1652  stringp = fmts;
1653  strsep(&stringp, "|");
1654  ast_debug(1, "Recording Formats: sfmts=%s\n", fmts);
1655  sfmt[0] = ast_strdupa(fmts);
1656 
1657  while ((fmt = strsep(&stringp, "|"))) {
1658  if (fmtcnt > AST_MAX_FORMATS - 1) {
1659  ast_log(LOG_WARNING, "Please increase AST_MAX_FORMATS in file.h\n");
1660  break;
1661  }
1662  /*
1663  * Storage for 'fmt' is on the stack and held by 'fmts', which is maintained for
1664  * the rest of this function. So okay to not duplicate 'fmt' here, but only keep
1665  * a pointer to it.
1666  */
1667  sfmt[fmtcnt++] = fmt;
1668  }
1669 
1670  end = start = time(NULL); /* pre-initialize end to be same as start in case we never get into loop */
1671  for (x = 0; x < fmtcnt; x++) {
1672  others[x] = ast_writefile(prepend ? prependfile : recordfile, sfmt[x], comment, ioflags, 0, AST_FILE_MODE);
1673  ast_verb(3, "x=%d, open writing: %s format: %s, %p\n", x, prepend ? prependfile : recordfile, sfmt[x], others[x]);
1674 
1675  if (!others[x]) {
1676  break;
1677  }
1678  }
1679 
1680  if (path) {
1681  ast_unlock_path(path);
1682  }
1683 
1684  if (maxsilence > 0) {
1685  sildet = ast_dsp_new(); /* Create the silence detector */
1686  if (!sildet) {
1687  ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
1688  return -1;
1689  }
1691  res = set_read_to_slin(chan, &rfmt);
1692  if (res < 0) {
1693  ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
1694  ast_dsp_free(sildet);
1695  ao2_cleanup(rfmt);
1696  return -1;
1697  }
1698  }
1699 
1700  if (!prepend) {
1701  /* Request a video update */
1703 
1705  silgen = ast_channel_start_silence_generator(chan);
1706  }
1707  }
1708 
1709  if (x == fmtcnt) {
1710  /* Loop, writing the packets we read to the writer(s), until
1711  * we have reason to stop. */
1712  struct ast_frame *f;
1713  int paused = 0;
1714  int muted = 0;
1715  time_t pause_start = 0;
1716  int paused_secs = 0;
1717  int pausedsilence = 0;
1718 
1719  for (;;) {
1720  if (!(res = ast_waitfor(chan, 2000))) {
1721  ast_debug(1, "One waitfor failed, trying another\n");
1722  /* Try one more time in case of masq */
1723  if (!(res = ast_waitfor(chan, 2000))) {
1724  ast_log(LOG_WARNING, "No audio available on %s??\n", ast_channel_name(chan));
1725  res = -1;
1726  }
1727  }
1728 
1729  if (res < 0) {
1730  f = NULL;
1731  break;
1732  }
1733  if (!(f = ast_read(chan))) {
1734  break;
1735  }
1736  if (f->frametype == AST_FRAME_VOICE) {
1737  /* write each format */
1738  if (paused) {
1739  /* It's all good */
1740  res = 0;
1741  } else {
1742  struct ast_frame *silence = NULL;
1743  struct ast_frame *orig = f;
1744 
1745  if (muted) {
1746  silence = make_silence(orig);
1747  if (!silence) {
1748  ast_log(LOG_WARNING, "Error creating silence\n");
1749  break;
1750  }
1751  f = silence;
1752  }
1753  for (x = 0; x < fmtcnt; x++) {
1754  if (prepend && !others[x]) {
1755  break;
1756  }
1757  res = ast_writestream(others[x], f);
1758  }
1759  ast_frame_dtor(silence);
1760  f = orig;
1761  }
1762 
1763  /* Silence Detection */
1764  if (maxsilence > 0) {
1765  dspsilence = 0;
1766  ast_dsp_silence(sildet, f, &dspsilence);
1767  if (olddspsilence > dspsilence) {
1768  totalsilence += olddspsilence;
1769  }
1770  olddspsilence = dspsilence;
1771 
1772  if (paused) {
1773  /* record how much silence there was while we are paused */
1774  pausedsilence = dspsilence;
1775  } else if (dspsilence > pausedsilence) {
1776  /* ignore the paused silence */
1777  dspsilence -= pausedsilence;
1778  } else {
1779  /* dspsilence has reset, reset pausedsilence */
1780  pausedsilence = 0;
1781  }
1782 
1783  if (dspsilence > maxsilence) {
1784  /* Ended happily with silence */
1785  ast_verb(3, "Recording automatically stopped after a silence of %d seconds\n", dspsilence/1000);
1786  res = 'S';
1787  outmsg = 2;
1788  break;
1789  }
1790  }
1791  /* Exit on any error */
1792  if (res) {
1793  ast_log(LOG_WARNING, "Error writing frame\n");
1794  break;
1795  }
1796  } else if (f->frametype == AST_FRAME_VIDEO) {
1797  /* Write only once */
1798  ast_writestream(others[0], f);
1799  } else if (f->frametype == AST_FRAME_DTMF) {
1800  if (prepend) {
1801  /* stop recording with any digit */
1802  ast_verb(3, "User ended message by pressing %c\n", f->subclass.integer);
1803  res = 't';
1804  outmsg = 2;
1805  break;
1806  }
1807  if (strchr(acceptdtmf, f->subclass.integer)) {
1808  ast_verb(3, "User ended message by pressing %c\n", f->subclass.integer);
1809  res = f->subclass.integer;
1810  outmsg = 2;
1811  break;
1812  }
1813  if (strchr(canceldtmf, f->subclass.integer)) {
1814  ast_verb(3, "User canceled message by pressing %c\n", f->subclass.integer);
1815  res = f->subclass.integer;
1816  outmsg = 0;
1817  break;
1818  }
1819  } else if (f->frametype == AST_FRAME_CONTROL) {
1821  ast_verb(3, "Message canceled by control\n");
1822  outmsg = 0; /* cancels the recording */
1823  res = 0;
1824  break;
1825  } else if (f->subclass.integer == AST_CONTROL_RECORD_STOP) {
1826  ast_verb(3, "Message ended by control\n");
1827  res = 0;
1828  break;
1829  } else if (f->subclass.integer == AST_CONTROL_RECORD_SUSPEND) {
1830  paused = !paused;
1831  ast_verb(3, "Message %spaused by control\n",
1832  paused ? "" : "un");
1833  if (paused) {
1834  pause_start = time(NULL);
1835  } else {
1836  paused_secs += time(NULL) - pause_start;
1837  }
1838  } else if (f->subclass.integer == AST_CONTROL_RECORD_MUTE) {
1839  muted = !muted;
1840  ast_verb(3, "Message %smuted by control\n",
1841  muted ? "" : "un");
1842  /* We can only silence slin frames, so
1843  * set the mode, if we haven't already
1844  * for sildet
1845  */
1846  if (muted && !rfmt) {
1847  ast_verb(3, "Setting read format to linear mode\n");
1848  res = set_read_to_slin(chan, &rfmt);
1849  if (res < 0) {
1850  ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
1851  break;
1852  }
1853  }
1854  }
1855  }
1856  if (maxtime && !paused) {
1857  end = time(NULL);
1858  if (maxtime < (end - start - paused_secs)) {
1859  ast_verb(3, "Took too long, cutting it short...\n");
1860  res = 't';
1861  outmsg = 2;
1862  break;
1863  }
1864  }
1865  ast_frfree(f);
1866  }
1867  if (!f) {
1868  ast_verb(3, "User hung up\n");
1869  res = -1;
1870  outmsg = 1;
1871  } else {
1872  ast_frfree(f);
1873  }
1874  } else {
1875  ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", recordfile, sfmt[x]);
1876  }
1877 
1878  if (!prepend) {
1879  if (silgen) {
1880  ast_channel_stop_silence_generator(chan, silgen);
1881  }
1882  }
1883 
1884  /*!\note
1885  * Instead of asking how much time passed (end - start), calculate the number
1886  * of seconds of audio which actually went into the file. This fixes a
1887  * problem where audio is stopped up on the network and never gets to us.
1888  *
1889  * Note that we still want to use the number of seconds passed for the max
1890  * message, otherwise we could get a situation where this stream is never
1891  * closed (which would create a resource leak).
1892  */
1893  *duration = others[0] ? ast_tellstream(others[0]) / 8000 : 0;
1894  if (sound_duration) {
1895  *sound_duration = *duration;
1896  }
1897 
1898  if (!prepend) {
1899  /* Reduce duration by a total silence amount */
1900  if (olddspsilence <= dspsilence) {
1901  totalsilence += dspsilence;
1902  }
1903 
1904  if (sound_duration) {
1905  if (totalsilence > 0) {
1906  *sound_duration -= (totalsilence - 200) / 1000;
1907  }
1908  if (*sound_duration < 0) {
1909  *sound_duration = 0;
1910  }
1911  }
1912 
1913  if (dspsilence > 0) {
1914  *duration -= (dspsilence - 200) / 1000;
1915  }
1916 
1917  if (*duration < 0) {
1918  *duration = 0;
1919  }
1920 
1921  for (x = 0; x < fmtcnt; x++) {
1922  if (!others[x]) {
1923  break;
1924  }
1925  /*!\note
1926  * If we ended with silence, trim all but the first 200ms of silence
1927  * off the recording. However, if we ended with '#', we don't want
1928  * to trim ANY part of the recording.
1929  */
1930  if (res > 0 && dspsilence) {
1931  /* rewind only the trailing silence */
1932  ast_stream_rewind(others[x], dspsilence - 200);
1933  }
1934  ast_truncstream(others[x]);
1935  ast_closestream(others[x]);
1936  }
1937  } else if (prepend && outmsg) {
1938  struct ast_filestream *realfiles[AST_MAX_FORMATS];
1939  struct ast_frame *fr;
1940 
1941  for (x = 0; x < fmtcnt; x++) {
1942  snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]);
1943  realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0);
1944  if (!others[x]) {
1945  break;
1946  }
1947  if (!realfiles[x]) {
1948  ast_closestream(others[x]);
1949  continue;
1950  }
1951  /*!\note Same logic as above. */
1952  if (dspsilence) {
1953  ast_stream_rewind(others[x], dspsilence - 200);
1954  }
1955  ast_truncstream(others[x]);
1956  /* add the original file too */
1957  while ((fr = ast_readframe(realfiles[x]))) {
1958  ast_writestream(others[x], fr);
1959  ast_frfree(fr);
1960  }
1961  ast_closestream(others[x]);
1962  ast_closestream(realfiles[x]);
1963  ast_filerename(prependfile, recordfile, sfmt[x]);
1964  ast_verb(4, "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile);
1965  ast_filedelete(prependfile, sfmt[x]);
1966  }
1967  } else {
1968  for (x = 0; x < fmtcnt; x++) {
1969  if (!others[x]) {
1970  break;
1971  }
1972  ast_closestream(others[x]);
1973  }
1974  }
1975 
1976  if (rfmt && ast_set_read_format(chan, rfmt)) {
1977  ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_format_get_name(rfmt), ast_channel_name(chan));
1978  }
1979  ao2_cleanup(rfmt);
1980  if ((outmsg == 2) && (!skip_confirmation_sound)) {
1981  ast_stream_and_wait(chan, "auth-thankyou", "");
1982  }
1983  if (sildet) {
1984  ast_dsp_free(sildet);
1985  }
1986  return res;
1987 }
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define LOG_WARNING
Definition: logger.h:274
static int maxsilence
int ast_unlock_path(const char *path)
Unlock a path.
Definition: main/app.c:2473
static int muted
Definition: muted.c:82
static struct test_val d
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
Definition of a media format.
Definition: format.c:43
#define ast_assert(a)
Definition: utils.h:695
#define ast_opt_transmit_silence
Definition: options.h:124
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define AST_FRAME_DTMF
#define AST_FILE_MODE
Definition: asterisk.h:32
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
int totalsilence
Definition: dsp.c:409
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition: file.c:1048
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&#39;s read format to AST_FORMAT_SLINEAR, recording its original format.
Definition: main/app.c:1546
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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:1494
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
Definition: dsp.c:405
static int silencethreshold
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:1775
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
Definition: file.c:899
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1063
#define comment
Definition: ael_lex.c:976
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:1361
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:8312
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:1814
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1068
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:1470
int ast_truncstream(struct ast_filestream *fs)
Trunc stream at current location.
Definition: file.c:1043
int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
Process the audio frame for silence.
Definition: dsp.c:1483
static int global_silence_threshold
Definition: main/app.c:1555
char * strsep(char **str, const char *delims)
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:3171
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:209
#define ast_frfree(fr)
static int global_maxsilence
Definition: main/app.c:1556
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:1309
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:1103
enum ast_frame_type frametype
#define PATH_MAX
Definition: asterisk.h:40
#define AST_MAX_FORMATS
Definition: main/app.c:121

◆ __ast_vm_greeter_register()

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 552 of file main/app.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_replace_unref, ast_log, AST_MODULE_LOAD_DECLINE, LOG_ERROR, LOG_WARNING, ast_vm_greeter_functions::module, ast_vm_greeter_functions::module_name, ast_vm_greeter_functions::module_version, NULL, RAII_VAR, table, VM_GREETER_MODULE_VERSION, and vm_table.

553 {
555 
556  if (!vm_table->module_name) {
557  ast_log(LOG_ERROR, "Voicemail greeter provider missing required information.\n");
558  return -1;
559  }
560  if (vm_table->module_version != VM_GREETER_MODULE_VERSION) {
561  ast_log(LOG_ERROR, "Voicemail greeter provider '%s' has incorrect version\n",
562  vm_table->module_name);
563  return -1;
564  }
565 
566  table = ao2_global_obj_ref(vm_greeter_provider);
567  if (table) {
568  ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n",
569  table->module_name);
571  }
572 
574  if (!table) {
575  return -1;
576  }
577  *table = *vm_table;
578  table->module = module;
579 
580  ao2_global_obj_replace_unref(vm_greeter_provider, table);
581  return 0;
582 }
unsigned int module_version
The version of this function table.
static const struct ast_vm_functions vm_table
#define LOG_WARNING
Definition: logger.h:274
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define VM_GREETER_MODULE_VERSION
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
#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:911
#define LOG_ERROR
Definition: logger.h:285
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)
Definition: astobj2.h:908
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ __ast_vm_register()

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 441 of file main/app.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_replace_unref, ast_log, AST_MODULE_LOAD_DECLINE, LOG_ERROR, LOG_WARNING, ast_vm_functions::module, ast_vm_functions::module_name, ast_vm_functions::module_version, NULL, RAII_VAR, table, VM_MODULE_VERSION, and vm_table.

442 {
444 
445  if (!vm_table->module_name) {
446  ast_log(LOG_ERROR, "Voicemail provider missing required information.\n");
447  return -1;
448  }
449  if (vm_table->module_version != VM_MODULE_VERSION) {
450  ast_log(LOG_ERROR, "Voicemail provider '%s' has incorrect version\n",
451  vm_table->module_name);
452  return -1;
453  }
454 
455  table = ao2_global_obj_ref(vm_provider);
456  if (table) {
457  ast_log(LOG_WARNING, "Voicemail provider already registered by %s.\n",
458  table->module_name);
460  }
461 
463  if (!table) {
464  return -1;
465  }
466  *table = *vm_table;
467  table->module = module;
468 
469  ao2_global_obj_replace_unref(vm_provider, table);
470  return 0;
471 }
static const struct ast_vm_functions vm_table
#define LOG_WARNING
Definition: logger.h:274
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
static char * table
Definition: cdr_odbc.c:58
#define ast_log
Definition: astobj2.c:42
#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:911
#define VM_MODULE_VERSION
#define LOG_ERROR
Definition: logger.h:285
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)
Definition: astobj2.h:908
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int module_version
The version of this function table.
Voicemail function table definition.

◆ AO2_GLOBAL_OBJ_STATIC() [1/3]

static AO2_GLOBAL_OBJ_STATIC ( vm_provider  )
static

The container for the voicemail provider.

Referenced by ast_app_run_sub(), ast_vm_test_swap_table_out(), and ast_vm_unregister().

◆ AO2_GLOBAL_OBJ_STATIC() [2/3]

static AO2_GLOBAL_OBJ_STATIC ( vm_provider_holder  )
static

Holding container for the voicemail provider used while testing.

◆ AO2_GLOBAL_OBJ_STATIC() [3/3]

static AO2_GLOBAL_OBJ_STATIC ( vm_greeter_provider  )
static

The container for the voicemail greeter provider.

◆ app_cleanup()

static void app_cleanup ( void  )
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ao2_cleanup, child_cap, and NULL.

Referenced by app_init().

3195 {
3196 #ifdef HAS_CAP
3197  cap_free(child_cap);
3198 #endif
3203 }
static struct stasis_topic * queue_topic_all
Definition: main/app.c:90
#define NULL
Definition: resample.c:96
static struct stasis_topic_pool * queue_topic_pool
Definition: main/app.c:91
static cap_t child_cap
Definition: main/app.c:85
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ app_init()

int app_init ( void  )

Initialize the application core.

Return values
0Success
-1Failure
Since
12

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

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

Referenced by asterisk_daemon().

3206 {
3208 #ifdef HAVE_CAP
3209  child_cap = cap_from_text("cap_net_admin-eip");
3210 #endif
3211  queue_topic_all = stasis_topic_create("queue:all");
3212  if (!queue_topic_all) {
3213  return -1;
3214  }
3216  if (!queue_topic_pool) {
3217  return -1;
3218  }
3219  return 0;
3220 }
static struct stasis_topic * queue_topic_all
Definition: main/app.c:90
static void app_cleanup(void)
Definition: main/app.c:3194
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
static struct stasis_topic_pool * queue_topic_pool
Definition: main/app.c:91
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:618
static cap_t child_cap
Definition: main/app.c:85

◆ ast_app_copy_recording_to_vm()

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

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

References VM_API_CALL.

Referenced by copy_to_voicemail().

670 {
671  int res = -1;
672 
673  VM_API_CALL(res, copy_recording_to_vm, (vm_rec_data));
674  return res;
675 }
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_app_dtget()

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
Returns
0 if extension does not exist, 1 if extension exists

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

References ast_channel_caller(), ast_channel_pbx(), ast_channel_zone(), ast_exists_extension(), ast_get_indication_tone(), ast_ignore_pattern(), ast_log, ast_matchmore_extension(), ast_playtones_start(), ast_playtones_stop(), ast_tone_zone_sound_unref(), ast_waitfordigit(), ast_tone_zone_sound::data, ast_pbx::dtimeoutms, LOG_NOTICE, NULL, and S_COR.

Referenced by grab_transfer().

140 {
141  struct ast_tone_zone_sound *ts;
142  int res = 0, x = 0;
143 
144  if (maxlen > size) {
145  maxlen = size;
146  }
147 
148  if (!timeout) {
149  if (ast_channel_pbx(chan) && ast_channel_pbx(chan)->dtimeoutms) {
151  } else {
152  timeout = 5000;
153  }
154  }
155 
156  if ((ts = ast_get_indication_tone(ast_channel_zone(chan), "dial"))) {
157  res = ast_playtones_start(chan, 0, ts->data, 0);
158  ts = ast_tone_zone_sound_unref(ts);
159  } else {
160  ast_log(LOG_NOTICE, "Huh....? no dial for indications?\n");
161  }
162 
163  for (x = strlen(collect); x < maxlen; ) {
164  res = ast_waitfordigit(chan, timeout);
165  if (!ast_ignore_pattern(context, collect)) {
166  ast_playtones_stop(chan);
167  }
168  if (res < 1) {
169  break;
170  }
171  if (res == '#') {
172  break;
173  }
174  collect[x++] = res;
175  if (!ast_matchmore_extension(chan, context, collect, 1,
176  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
177  break;
178  }
179  }
180 
181  if (res >= 0) {
182  res = ast_exists_extension(chan, context, collect, 1,
183  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)) ? 1 : 0;
184  }
185 
186  return res;
187 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
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:4199
static int timeout
Definition: cdr_mysql.c:86
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition: pbx.c:6921
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
#define NULL
Definition: resample.c:96
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#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:85
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:4179
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:455
#define LOG_NOTICE
Definition: logger.h:263
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int dtimeoutms
Definition: pbx.h:212
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
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_app_exec_macro()

int ast_app_exec_macro ( struct ast_channel autoservice_chan,
struct ast_channel macro_chan,
const char *  macro_args 
)

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

Since
11.0

This is a shorthand method that makes it very easy to run a macro 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 macro is run
macro_chanChannel to execute macro on.
macro_argsMacro application argument string.
Return values
0success
-1on error

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

References ast_autoservice_start(), ast_autoservice_stop(), ast_channel_context(), ast_channel_exten(), ast_channel_name(), ast_channel_priority(), ast_check_hangup_locked(), ast_debug, ast_log, ast_queue_hangup(), LOG_WARNING, pbx_exec(), and pbx_findapp().

Referenced by ast_app_run_macro(), dial_exec_full(), generic_recall(), run_app_helper(), and try_calling().

274 {
275  struct ast_app *macro_app;
276  int res;
277 
278  macro_app = pbx_findapp("Macro");
279  if (!macro_app) {
281  "Cannot run 'Macro(%s)'. The application is not available.\n", macro_args);
282  return -1;
283  }
284  if (autoservice_chan) {
285  ast_autoservice_start(autoservice_chan);
286  }
287 
288  ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(macro_chan),
289  ast_channel_context(macro_chan), ast_channel_exten(macro_chan),
290  ast_channel_priority(macro_chan));
291 
292  res = pbx_exec(macro_chan, macro_app, macro_args);
293  ast_debug(4, "Macro exited with status %d\n", res);
294 
295  /*
296  * Assume anything negative from Macro is an error.
297  * Anything else is success.
298  */
299  if (res < 0) {
300  res = -1;
301  } else {
302  res = 0;
303  }
304 
305  ast_debug(4, "%s Ending location: %s,%s,%d\n", ast_channel_name(macro_chan),
306  ast_channel_context(macro_chan), ast_channel_exten(macro_chan),
307  ast_channel_priority(macro_chan));
308 
309  if (autoservice_chan) {
310  ast_autoservice_stop(autoservice_chan);
311  }
312 
313  if (ast_check_hangup_locked(macro_chan)) {
314  ast_queue_hangup(macro_chan);
315  }
316 
317  return res;
318 }
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 pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
#define LOG_WARNING
Definition: logger.h:274
int ast_channel_priority(const struct ast_channel *chan)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
ast_app: A registered application
Definition: pbx_app.c:45
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165

◆ ast_app_exec_sub()

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 370 of file main/app.c.

References app_stack_callbacks, ast_autoservice_start(), ast_autoservice_stop(), ast_check_hangup_locked(), ast_log, ast_module_running_ref, ast_module_unref, ast_queue_hangup(), LOG_WARNING, ast_app_stack_funcs::module, and ast_app_stack_funcs::run_sub.

Referenced by app_exec(), ast_app_run_sub(), ast_pbx_hangup_handler_run(), ast_pre_call(), dial_exec_full(), generic_recall(), originate_exec(), page_exec(), queue_exec(), run_app_helper(), and try_calling().

371 {
372  const struct ast_app_stack_funcs *funcs;
373  int res;
374 
375  funcs = app_stack_callbacks;
376  if (!funcs || !funcs->run_sub || !ast_module_running_ref(funcs->module)) {
378  "Cannot run 'Gosub(%s)'. The app_stack module is not available.\n",
379  sub_args);
380  return -1;
381  }
382 
383  if (autoservice_chan) {
384  ast_autoservice_start(autoservice_chan);
385  }
386 
387  res = funcs->run_sub(sub_chan, sub_args, ignore_hangup);
388  ast_module_unref(funcs->module);
389 
390  if (autoservice_chan) {
391  ast_autoservice_stop(autoservice_chan);
392  }
393 
394  if (!ignore_hangup && ast_check_hangup_locked(sub_chan)) {
395  ast_queue_hangup(sub_chan);
396  }
397 
398  return res;
399 }
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_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
#define LOG_WARNING
Definition: logger.h:274
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_log
Definition: astobj2.c:42
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
Stack applications callback functions.
static const struct ast_app_stack_funcs * app_stack_callbacks
Definition: main/app.c:344
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_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455

◆ ast_app_expand_sub_args()

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.

Return values
New-argsGosub argument string on success. Must be freed.
NULLon error.

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

References app_stack_callbacks, ast_log, ast_module_running_ref, ast_module_unref, ast_app_stack_funcs::expand_sub_args, LOG_WARNING, ast_app_stack_funcs::module, and NULL.

Referenced by app_exec(), ast_pbx_hangup_handler_push(), dial_exec_full(), and page_exec().

352 {
353  const struct ast_app_stack_funcs *funcs;
354  const char *new_args;
355 
356  funcs = app_stack_callbacks;
357  if (!funcs || !funcs->expand_sub_args || !ast_module_running_ref(funcs->module)) {
359  "Cannot expand 'Gosub(%s)' arguments. The app_stack module is not available.\n",
360  args);
361  return NULL;
362  }
363 
364  new_args = funcs->expand_sub_args(chan, args);
365  ast_module_unref(funcs->module);
366 
367  return new_args;
368 }
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_log
Definition: astobj2.c:42
Stack applications callback functions.
static const struct ast_app_stack_funcs * app_stack_callbacks
Definition: main/app.c:344
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
const char *(* expand_sub_args)(struct ast_channel *chan, const char *args)
Add missing context/exten to Gosub application argument string.

◆ ast_app_getdata()

enum ast_getdata_result ast_app_getdata ( struct ast_channel c,
const char *  prompt,
char *  s,
int  maxlen,
int  timeout 
)

ast_app_getdata

Plays a stream and gets DTMF data from a channel.

Parameters
cThe channel to read from
promptThe file to stream to the channel
sThe string to read in to. Must be at least the size of your length
maxlenHow many digits to read (maximum)
timeoutset timeout to 0 for "standard" timeouts. Set timeout to -1 for "ludicrous time" (essentially never times out)

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

References ast_channel_language(), ast_channel_pbx(), AST_GETDATA_EMPTY_END_TERMINATED, ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero, ast_pbx::dtimeoutms, ast_pbx::rtimeoutms, strsep(), and timeout.

Referenced by auth_exec(), conf_exec(), conf_get_pin(), dictate_exec(), find_conf(), read_exec(), testclient_exec(), testserver_exec(), and vm_exec().

198 {
199  int res = 0, to, fto;
200  char *front, *filename;
201 
202  /* XXX Merge with full version? XXX */
203 
204  if (maxlen)
205  s[0] = '\0';
206 
207  if (!prompt)
208  prompt = "";
209 
210  filename = ast_strdupa(prompt);
211  while ((front = strsep(&filename, "&"))) {
212  if (!ast_strlen_zero(front)) {
213  res = ast_streamfile(c, front, ast_channel_language(c));
214  if (res)
215  continue;
216  }
217  if (ast_strlen_zero(filename)) {
218  /* set timeouts for the last prompt */
219  fto = ast_channel_pbx(c) ? ast_channel_pbx(c)->rtimeoutms : 6000;
220  to = ast_channel_pbx(c) ? ast_channel_pbx(c)->dtimeoutms : 2000;
221 
222  if (timeout > 0) {
223  fto = to = timeout;
224  }
225  if (timeout < 0) {
226  fto = to = 1000000000;
227  }
228  } else {
229  /* there is more than one prompt, so
230  * get rid of the long timeout between
231  * prompts, and make it 50ms */
232  fto = 50;
233  to = ast_channel_pbx(c) ? ast_channel_pbx(c)->dtimeoutms : 2000;
234  }
235  res = ast_readstring(c, s, maxlen, to, fto, "#");
237  return res;
238  }
239  if (!ast_strlen_zero(s)) {
240  return res;
241  }
242  }
243 
244  return res;
245 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int timeout
Definition: cdr_mysql.c:86
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strsep(char **str, const char *delims)
int dtimeoutms
Definition: pbx.h:212
const char * ast_channel_language(const struct ast_channel *chan)
static struct ast_str * prompt
Definition: asterisk.c:2725
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6655
int rtimeoutms
Definition: pbx.h:213

◆ ast_app_getdata_full()

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.

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

References ast_channel_language(), ast_readstring_full(), ast_streamfile(), ast_strlen_zero, and timeout.

Referenced by handle_getdata().

251 {
252  int res, to = 2000, fto = 6000;
253 
254  if (!ast_strlen_zero(prompt)) {
256  if (res < 0) {
257  return res;
258  }
259  }
260 
261  if (timeout > 0) {
262  fto = to = timeout;
263  }
264  if (timeout < 0) {
265  fto = to = 1000000000;
266  }
267 
268  res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd);
269 
270  return res;
271 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
static int timeout
Definition: cdr_mysql.c:86
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd)
Definition: channel.c:6660
const char * ast_channel_language(const struct ast_channel *chan)
static struct ast_str * prompt
Definition: asterisk.c:2725

◆ ast_app_group_discard()

int ast_app_group_discard ( struct ast_channel chan)

Discard all group counting for a channel.

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

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_group_info::chan, ast_group_info::group_list, and NULL.

Referenced by ast_channel_destructor().

2163 {
2164  struct ast_group_info *gi = NULL;
2165 
2168  if (gi->chan == chan) {
2170  ast_free(gi);
2171  }
2172  }
2175 
2176  return 0;
2177 }
channel group info
Definition: channel.h:2938
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
struct ast_channel * chan
Definition: channel.h:2939
#define ast_free(a)
Definition: astmm.h:182
struct ast_group_info::@248 group_list
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_app_group_get_count()

int ast_app_group_get_count ( const char *  group,
const char *  category 
)

Get the current channel count of the specified group and category.

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

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero, ast_group_info::category, ast_group_info::group, ast_group_info::group_list, and NULL.

Referenced by group_count_function_read().

2084 {
2085  struct ast_group_info *gi = NULL;
2086  int count = 0;
2087 
2088  if (ast_strlen_zero(group)) {
2089  return 0;
2090  }
2091 
2094  if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
2095  count++;
2096  }
2097  }
2099 
2100  return count;
2101 }
channel group info
Definition: channel.h:2938
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char * group
Definition: channel.h:2941
char * category
Definition: channel.h:2940
struct ast_group_info::@248 group_list

◆ ast_app_group_list_head()

struct ast_group_info* ast_app_group_list_head ( void  )

Get the head of the group count list.

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

References AST_RWLIST_FIRST.

Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().

2190 {
2191  return AST_RWLIST_FIRST(&groups);
2192 }
#define AST_RWLIST_FIRST
Definition: linkedlists.h:422

◆ ast_app_group_list_rdlock()

int ast_app_group_list_rdlock ( void  )

Read Lock the group count list.

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

References AST_RWLIST_RDLOCK.

Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().

2185 {
2186  return AST_RWLIST_RDLOCK(&groups);
2187 }
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77

◆ ast_app_group_list_unlock()

int ast_app_group_list_unlock ( void  )

Unlock the group count list.

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

References AST_RWLIST_UNLOCK.

Referenced by group_count_function_read(), group_function_read(), group_list_function_read(), and group_show_channels().

2195 {
2196  return AST_RWLIST_UNLOCK(&groups);
2197 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150

◆ ast_app_group_list_wrlock()

int ast_app_group_list_wrlock ( void  )

Write Lock the group count list.

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

References AST_RWLIST_WRLOCK.

2180 {
2181  return AST_RWLIST_WRLOCK(&groups);
2182 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51

◆ ast_app_group_match_get_count()

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.

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

References ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero, ast_group_info::category, ast_group_info::group, ast_group_info::group_list, LOG_ERROR, LOG_NOTICE, and NULL.

Referenced by AST_TEST_DEFINE(), and group_match_count_function_read().

2104 {
2105  struct ast_group_info *gi = NULL;
2106  regex_t regexbuf_group;
2107  regex_t regexbuf_category;
2108  int count = 0;
2109 
2110  if (ast_strlen_zero(groupmatch)) {
2111  ast_log(LOG_NOTICE, "groupmatch empty\n");
2112  return 0;
2113  }
2114 
2115  /* if regex compilation fails, return zero matches */
2116  if (regcomp(&regexbuf_group, groupmatch, REG_EXTENDED | REG_NOSUB)) {
2117  ast_log(LOG_ERROR, "Regex compile failed on: %s\n", groupmatch);
2118  return 0;
2119  }
2120 
2121  if (!ast_strlen_zero(category) && regcomp(&regexbuf_category, category, REG_EXTENDED | REG_NOSUB)) {
2122  ast_log(LOG_ERROR, "Regex compile failed on: %s\n", category);
2123  regfree(&regexbuf_group);
2124  return 0;
2125  }
2126 
2129  if (!regexec(&regexbuf_group, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !regexec(&regexbuf_category, gi->category, 0, NULL, 0)))) {
2130  count++;
2131  }
2132  }
2134 
2135  regfree(&regexbuf_group);
2136  if (!ast_strlen_zero(category)) {
2137  regfree(&regexbuf_category);
2138  }
2139 
2140  return count;
2141 }
channel group info
Definition: channel.h:2938
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char * group
Definition: channel.h:2941
#define LOG_ERROR
Definition: logger.h:285
#define LOG_NOTICE
Definition: logger.h:263
char * category
Definition: channel.h:2940
struct ast_group_info::@248 group_list

◆ ast_app_group_set_channel()

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.

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

References ast_app_group_split_group(), ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero, ast_group_info::category, ast_group_info::chan, ast_group_info::group, ast_group_info::group_list, len(), and NULL.

Referenced by AST_TEST_DEFINE(), dial_exec_full(), and group_function_write().

2037 {
2038  int res = 0;
2039  char group[80] = "", category[80] = "";
2040  struct ast_group_info *gi = NULL;
2041  size_t len = 0;
2042 
2043  if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) {
2044  return -1;
2045  }
2046 
2047  /* Calculate memory we will need if this is new */
2048  len = sizeof(*gi) + strlen(group) + 1;
2049  if (!ast_strlen_zero(category)) {
2050  len += strlen(category) + 1;
2051  }
2052 
2055  if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
2057  ast_free(gi);
2058  break;
2059  }
2060  }
2062 
2063  if (ast_strlen_zero(group)) {
2064  /* Enable unsetting the group */
2065  } else if ((gi = ast_calloc(1, len))) {
2066  gi->chan = chan;
2067  gi->group = (char *) gi + sizeof(*gi);
2068  strcpy(gi->group, group);
2069  if (!ast_strlen_zero(category)) {
2070  gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1;
2071  strcpy(gi->category, category);
2072  }
2074  } else {
2075  res = -1;
2076  }
2077 
2079 
2080  return res;
2081 }
channel group info
Definition: channel.h:2938
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
char * group
Definition: channel.h:2941
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
struct ast_channel * chan
Definition: channel.h:2939
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...
Definition: main/app.c:2009
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * category
Definition: channel.h:2940
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
struct ast_group_info::@248 group_list
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_app_group_split_group()

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.

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

References ast_copy_string(), ast_strlen_zero, NULL, and tmp().

Referenced by ast_app_group_set_channel(), group_count_function_read(), and group_match_count_function_read().

2010 {
2011  int res = 0;
2012  char tmp[256];
2013  char *grp = NULL, *cat = NULL;
2014 
2015  if (!ast_strlen_zero(data)) {
2016  ast_copy_string(tmp, data, sizeof(tmp));
2017  grp = tmp;
2018  if ((cat = strchr(tmp, '@'))) {
2019  *cat++ = '\0';
2020  }
2021  }
2022 
2023  if (!ast_strlen_zero(grp)) {
2024  ast_copy_string(group, grp, group_max);
2025  } else {
2026  *group = '\0';
2027  }
2028 
2029  if (!ast_strlen_zero(cat)) {
2030  ast_copy_string(category, cat, category_max);
2031  }
2032 
2033  return res;
2034 }
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * category
Definition: channel.h:2940
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_app_group_update()

int ast_app_group_update ( struct ast_channel old,
struct ast_channel new 
)

Update all group counting for a channel to a new one.

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

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_group_info::chan, ast_group_info::group_list, and NULL.

Referenced by channel_do_masquerade().

2144 {
2145  struct ast_group_info *gi = NULL;
2146 
2149  if (gi->chan == old) {
2150  gi->chan = new;
2151  } else if (gi->chan == new) {
2153  ast_free(gi);
2154  }
2155  }
2158 
2159  return 0;
2160 }
channel group info
Definition: channel.h:2938
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
struct ast_channel * chan
Definition: channel.h:2939
#define ast_free(a)
Definition: astmm.h:182
struct ast_group_info::@248 group_list
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_app_has_voicemail()

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 655 of file main/app.c.

References has_voicemail(), and VM_API_CALL.

Referenced by action_mailboxstatus(), AST_TEST_DEFINE(), has_voicemail(), mwi_update_cb(), notify_new_message(), play_dialtone(), poll_mailbox(), run_externnotify(), skinny_register(), and unistim_send_mwi_to_peer().

656 {
657  int res = 0;
658 
659  VM_API_CALL(res, has_voicemail, (mailboxes, folder));
660  return res;
661 }
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.

◆ ast_app_inboxcount()

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 677 of file main/app.c.

References inboxcount(), and VM_API_CALL.

Referenced by AST_TEST_DEFINE(), sip_send_mwi_to_peer(), and update_registry().

678 {
679  int res = 0;
680 
681  if (newmsgs) {
682  *newmsgs = 0;
683  }
684  if (oldmsgs) {
685  *oldmsgs = 0;
686  }
687 
688  VM_API_CALL(res, inboxcount, (mailboxes, newmsgs, oldmsgs));
689  return res;
690 }
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)

◆ ast_app_inboxcount2()

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
Returns
Returns 0 for success, negative upon error
Since
1.6.1

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

References inboxcount2(), and VM_API_CALL.

Referenced by action_mailboxcount(), AST_TEST_DEFINE(), mwi_retrieve_then_create_state(), notify_new_message(), notify_new_state(), and vm_execmain().

693 {
694  int res = 0;
695 
696  if (newmsgs) {
697  *newmsgs = 0;
698  }
699  if (oldmsgs) {
700  *oldmsgs = 0;
701  }
702  if (urgentmsgs) {
703  *urgentmsgs = 0;
704  }
705 
706  VM_API_CALL(res, inboxcount2, (mailboxes, urgentmsgs, newmsgs, oldmsgs));
707  return res;
708 }
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&#39;s message count.
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_app_messagecount()

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 718 of file main/app.c.

References messagecount(), and VM_API_CALL.

Referenced by acf_vmcount_exec(), and AST_TEST_DEFINE().

719 {
720  int res = 0;
721 
722  VM_API_CALL(res, messagecount, (mailbox_id, folder));
723  return res;
724 }
static int messagecount(const char *mailbox_id, const char *folder)
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_app_options2str64()

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 2916 of file main/app.c.

References ast_test_flag64, and len().

2917 {
2918  unsigned int i, found = 0;
2919  for (i = 32; i < 128 && found < len; i++) {
2920  if (ast_test_flag64(flags, options[i].flag)) {
2921  buf[found++] = i;
2922  }
2923  }
2924  buf[found] = '\0';
2925 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
long int flag
Definition: f2c.h:83
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ ast_app_parse_options()

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
Returns
zero for success, non-zero if an error occurs
See also
AST_APP_OPTIONS

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

References parse_options().

Referenced by agent_login_exec(), app_exec(), ast_multicast_rtp_create_options(), AST_TEST_DEFINE(), audiosocket_request(), auth_exec(), bridge_exec(), bridgewait_exec(), cdr_read_callback(), cdr_write_callback(), chanspy_exec(), connectedline_write(), controlplayback_exec(), detect_write(), directory_exec(), disa_exec(), dundi_query_read(), dundifunc_read(), extenspy_exec(), forkcdr_exec(), handle_options(), hint_read(), manager_mixmonitor(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), mixmonitor_exec(), page_exec(), park_app_parse_data(), pbx_builtin_background(), pbx_builtin_waitexten(), pickupchan_exec(), queue_exec(), read_exec(), read_mf_exec(), read_sf_exec(), readexten_exec(), realtime_common(), receivefax_exec(), record_exec(), redirecting_write(), resetcdr_exec(), sendfax_exec(), sendurl_exec(), sla_trunk_exec(), smdi_msg_retrieve_read(), sms_exec(), softhangup_exec(), speech_background(), start_monitor_exec(), unicast_rtp_request(), vm_exec(), vm_execmain(), volume_write(), and wait_exec().

2907 {
2908  return parse_options(options, flags, args, optstr, 32);
2909 }
const char * args
static int parse_options(const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
Definition: main/app.c:2826

◆ ast_app_parse_options64()

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
Returns
zero for success, non-zero if an error occurs
See also
AST_APP_OPTIONS

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

References parse_options().

Referenced by AST_TEST_DEFINE(), conf_exec(), dial_exec_full(), find_conf_realtime(), originate_exec(), and sayunixtime_exec().

2912 {
2913  return parse_options(options, flags, args, optstr, 64);
2914 }
const char * args
static int parse_options(const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
Definition: main/app.c:2826

◆ ast_app_parse_timelen()

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 3113 of file main/app.c.

References FMT, TIMELEN_HOURS, TIMELEN_MILLISECONDS, TIMELEN_MINUTES, and TIMELEN_SECONDS.

Referenced by ast_eivr_senddtmf(), ast_parse_arg(), new_realtime_sqlite3_db(), pbx_builtin_wait(), pbx_builtin_waitdigit(), pbx_builtin_waitexten(), senddtmf_exec(), and sendmf_exec().

3114 {
3115  int res;
3116  char u[10];
3117 #ifdef HAVE_LONG_DOUBLE_WIDER
3118  long double amount;
3119  #define FMT "%30Lf%9s"
3120 #else
3121  double amount;
3122  #define FMT "%30lf%9s"
3123 #endif
3124  if (!timestr) {
3125  return -1;
3126  }
3127 
3128  res = sscanf(timestr, FMT, &amount, u);
3129 
3130  if (res == 0 || res == EOF) {
3131 #undef FMT
3132  return -1;
3133  } else if (res == 2) {
3134  switch (u[0]) {
3135  case 'h':
3136  case 'H':
3137  unit = TIMELEN_HOURS;
3138  if (u[1] != '\0') {
3139  return -1;
3140  }
3141  break;
3142  case 's':
3143  case 'S':
3144  unit = TIMELEN_SECONDS;
3145  if (u[1] != '\0') {
3146  return -1;
3147  }
3148  break;
3149  case 'm':
3150  case 'M':
3151  if (toupper(u[1]) == 'S') {
3152  unit = TIMELEN_MILLISECONDS;
3153  if (u[2] != '\0') {
3154  return -1;
3155  }
3156  } else if (u[1] == '\0') {
3157  unit = TIMELEN_MINUTES;
3158  } else {
3159  return -1;
3160  }
3161  break;
3162  default:
3163  return -1;
3164  }
3165  }
3166 
3167  switch (unit) {
3168  case TIMELEN_HOURS:
3169  amount *= 60;
3170  /* fall-through */
3171  case TIMELEN_MINUTES:
3172  amount *= 60;
3173  /* fall-through */
3174  case TIMELEN_SECONDS:
3175  amount *= 1000;
3176  /* fall-through */
3177  case TIMELEN_MILLISECONDS:
3178  ;
3179  }
3180  *result = amount > INT_MAX ? INT_MAX : (int) amount;
3181  return 0;
3182 }
#define FMT
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_app_run_macro()

int ast_app_run_macro ( struct ast_channel autoservice_chan,
struct ast_channel macro_chan,
const char *  macro_name,
const char *  macro_args 
)

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

Since
1.8

This is a shorthand method that makes it very easy to run a macro 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 macro is run
macro_chanChannel to execute macro on.
macro_nameThe name of the macro to run.
macro_argsThe arguments to pass to the macro.
Return values
0success
-1on error

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

References ast_app_exec_macro(), ast_free, ast_malloc, and ast_strlen_zero.

Referenced by ast_channel_connected_line_macro(), and ast_channel_redirecting_macro().

321 {
322  int res;
323  char *args_str;
324  size_t args_len;
325 
326  if (ast_strlen_zero(macro_args)) {
327  return ast_app_exec_macro(autoservice_chan, macro_chan, macro_name);
328  }
329 
330  /* Create the Macro application argument string. */
331  args_len = strlen(macro_name) + strlen(macro_args) + 2;
332  args_str = ast_malloc(args_len);
333  if (!args_str) {
334  return -1;
335  }
336  snprintf(args_str, args_len, "%s,%s", macro_name, macro_args);
337 
338  res = ast_app_exec_macro(autoservice_chan, macro_chan, args_str);
339  ast_free(args_str);
340  return res;
341 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
Run a macro on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:273
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182

◆ ast_app_run_sub()

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 401 of file main/app.c.

References AO2_GLOBAL_OBJ_STATIC(), ast_app_exec_sub(), ast_free, ast_malloc, and ast_strlen_zero.

Referenced by ast_channel_connected_line_sub(), and ast_channel_redirecting_sub().

402 {
403  int res;
404  char *args_str;
405  size_t args_len;
406 
407  if (ast_strlen_zero(sub_args)) {
408  return ast_app_exec_sub(autoservice_chan, sub_chan, sub_location, ignore_hangup);
409  }
410 
411  /* Create the Gosub application argument string. */
412  args_len = strlen(sub_location) + strlen(sub_args) + 3;
413  args_str = ast_malloc(args_len);
414  if (!args_str) {
415  return -1;
416  }
417  snprintf(args_str, args_len, "%s(%s)", sub_location, sub_args);
418 
419  res = ast_app_exec_sub(autoservice_chan, sub_chan, args_str, ignore_hangup);
420  ast_free(args_str);
421  return res;
422 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define ast_free(a)
Definition: astmm.h:182
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:370

◆ ast_app_sayname()

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 710 of file main/app.c.

References sayname(), and VM_GREETER_API_CALL.

Referenced by play_mailbox_owner(), and spy_sayname().

711 {
712  int res = -1;
713 
714  VM_GREETER_API_CALL(res, sayname, (chan, mailbox_id));
715  return res;
716 }
static int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
#define VM_GREETER_API_CALL(res, api_call, api_parms)
Definition: main/app.c:641

◆ ast_close_fds_above_n()

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 3042 of file main/app.c.

References closefrom().

Referenced by app_exec(), asterisk_daemon(), icesencode(), launch_script(), mp3play(), NBScatplay(), safe_exec_prep(), send_waveform_to_fd(), spawn_mp3(), spawn_ras(), and vm_check_password_shell().

3043 {
3044  closefrom(n + 1);
3045 }
void closefrom(int lowfd)
Definition: strcompat.c:429

◆ ast_control_streamfile()

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 1319 of file main/app.c.

References control_streamfile(), and NULL.

Referenced by controlplayback_exec(), handle_controlstreamfile(), and wait_file().

1323 {
1324  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, NULL);
1325 }
unsigned int stop
Definition: app_meetme.c:1096
#define NULL
Definition: resample.c:96
static int skipms
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
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)
Definition: main/app.c:1131

◆ ast_control_streamfile_lang()

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 1327 of file main/app.c.

References control_streamfile(), and NULL.

Referenced by play_on_channel().

1330 {
1331  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, lang, NULL);
1332 }
unsigned int stop
Definition: app_meetme.c:1096
#define NULL
Definition: resample.c:96
static int skipms
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
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)
Definition: main/app.c:1131

◆ ast_control_streamfile_w_cb()

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 occurrs.

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 1305 of file main/app.c.

References control_streamfile(), and NULL.

1315 {
1316  return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, cb);
1317 }
unsigned int stop
Definition: app_meetme.c:1096
#define NULL
Definition: resample.c:96
static int skipms
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
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)
Definition: main/app.c:1131

◆ ast_control_tone()

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 1399 of file main/app.c.

References ast_channel_zone(), AST_FRAME_CONTROL, ast_get_indication_tone(), ast_get_indication_zone(), ast_playtones_start(), ast_read_noaudio(), ast_strdupa, ast_strlen_zero, ast_tone_zone_sound_unref(), ast_tone_zone_unref(), ast_waitfor(), control_tone_frame_response(), CONTROL_TONE_RESPONSE_FAILED, CONTROL_TONE_RESPONSE_FINISHED, ast_tone_zone_sound::data, ast_frame::frametype, NULL, and parse_tone_uri().

Referenced by play_on_channel().

1400 {
1401  struct ast_tone_zone *zone = NULL;
1402  struct ast_tone_zone_sound *ts;
1403  int paused = 0;
1404  int res = 0;
1405 
1406  const char *tone_indication = NULL;
1407  const char *tone_zone = NULL;
1408  char *tone_uri_parser;
1409 
1410  if (ast_strlen_zero(tone)) {
1411  return -1;
1412  }
1413 
1414  tone_uri_parser = ast_strdupa(tone);
1415 
1416  if (parse_tone_uri(tone_uri_parser, &tone_indication, &tone_zone)) {
1417  return -1;
1418  }
1419 
1420  if (tone_zone) {
1421  zone = ast_get_indication_zone(tone_zone);
1422  }
1423 
1424  ts = ast_get_indication_tone(zone ? zone : ast_channel_zone(chan), tone_indication);
1425 
1426  if (ast_playtones_start(chan, 0, ts ? ts->data : tone_indication, 0)) {
1427  res = -1;
1428  }
1429 
1430  while (!res) {
1431  struct ast_frame *fr;
1432 
1433  if (ast_waitfor(chan, -1) < 0) {
1434  res = -1;
1435  break;
1436  }
1437 
1438  fr = ast_read_noaudio(chan);
1439 
1440  if (!fr) {
1441  res = -1;
1442  break;
1443  }
1444 
1445  if (fr->frametype != AST_FRAME_CONTROL) {
1446  continue;
1447  }
1448 
1449  res = control_tone_frame_response(chan, fr, ts, tone_indication, &paused);
1450  if (res == CONTROL_TONE_RESPONSE_FINISHED) {
1451  res = 0;
1452  break;
1453  } else if (res == CONTROL_TONE_RESPONSE_FAILED) {
1454  res = -1;
1455  break;
1456  }
1457  }
1458 
1459  if (ts) {
1461  }
1462 
1463  if (zone) {
1464  ast_tone_zone_unref(zone);
1465  }
1466 
1467  return res;
1468 }
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
static int parse_tone_uri(char *tone_parser, const char **tone_indication, const char **tone_zone)
Definition: main/app.c:1378
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:300
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:433
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:455
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)
Definition: main/app.c:1340
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
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:4312

◆ ast_dtmf_stream()

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 981 of file main/app.c.

References ast_autoservice_start(), ast_autoservice_stop(), and dtmf_stream().

Referenced by ast_eivr_senddtmf(), bridge_channel_dtmf_stream(), dial_exec_full(), dtmf_no_bridge(), handle_cli_misdn_send_digit(), senddtmf_exec(), testclient_exec(), testserver_exec(), and wait_for_answer().

982 {
983  int res;
984 
985  if (peer && ast_autoservice_start(peer)) {
986  return -1;
987  }
988  res = dtmf_stream(chan, digits, between, duration, 0);
989  if (peer && ast_autoservice_stop(peer)) {
990  res = -1;
991  }
992 
993  return res;
994 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
static int dtmf_stream(struct ast_channel *chan, const char *digits, int between, unsigned int duration, int is_external)
Definition: main/app.c:899
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266

◆ ast_dtmf_stream_external()

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.
Returns
Nothing

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

References dtmf_stream().

Referenced by dtmf_in_bridge().

997 {
998  dtmf_stream(chan, digits, between, duration, 1);
999 }
static int dtmf_stream(struct ast_channel *chan, const char *digits, int between, unsigned int duration, int is_external)
Definition: main/app.c:899

◆ ast_get_encoded_char()

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 2927 of file main/app.c.

References ast_debug, ast_log, ast_strlen_zero, and LOG_ERROR.

Referenced by ast_get_encoded_str(), ast_str_get_encoded_str(), cut_internal(), filter(), function_fieldnum_helper(), function_fieldqty_helper(), replace(), shift_pop(), and unshift_push().

2928 {
2929  int i;
2930  *consumed = 1;
2931  *result = 0;
2932  if (ast_strlen_zero(stream)) {
2933  *consumed = 0;
2934  return -1;
2935  }
2936 
2937  if (*stream == '\\') {
2938  *consumed = 2;
2939  switch (*(stream + 1)) {
2940  case 'n':
2941  *result = '\n';
2942  break;
2943  case 'r':
2944  *result = '\r';
2945  break;
2946  case 't':
2947  *result = '\t';
2948  break;
2949  case 'x':
2950  /* Hexadecimal */
2951  if (strchr("0123456789ABCDEFabcdef", *(stream + 2)) && *(stream + 2) != '\0') {
2952  *consumed = 3;
2953  if (*(stream + 2) <= '9') {
2954  *result = *(stream + 2) - '0';
2955  } else if (*(stream + 2) <= 'F') {
2956  *result = *(stream + 2) - 'A' + 10;
2957  } else {
2958  *result = *(stream + 2) - 'a' + 10;
2959  }
2960  } else {
2961  ast_log(LOG_ERROR, "Illegal character '%c' in hexadecimal string\n", *(stream + 2));
2962  return -1;
2963  }
2964 
2965  if (strchr("0123456789ABCDEFabcdef", *(stream + 3)) && *(stream + 3) != '\0') {
2966  *consumed = 4;
2967  *result <<= 4;
2968  if (*(stream + 3) <= '9') {
2969  *result += *(stream + 3) - '0';
2970  } else if (*(stream + 3) <= 'F') {
2971  *result += *(stream + 3) - 'A' + 10;
2972  } else {
2973  *result += *(stream + 3) - 'a' + 10;
2974  }
2975  }
2976  break;
2977  case '0':
2978  /* Octal */
2979  *consumed = 2;
2980  for (i = 2; ; i++) {
2981  if (strchr("01234567", *(stream + i)) && *(stream + i) != '\0') {
2982  (*consumed)++;
2983  ast_debug(5, "result was %d, ", *result);
2984  *result <<= 3;
2985  *result += *(stream + i) - '0';
2986  ast_debug(5, "is now %d\n", *result);
2987  } else {
2988  break;
2989  }
2990  }
2991  break;
2992  default:
2993  *result = *(stream + 1);
2994  }
2995  } else {
2996  *result = *stream;
2997  *consumed = 1;
2998  }
2999  return 0;
3000 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_get_encoded_str()

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 3002 of file main/app.c.

References ast_get_encoded_char(), and result.

Referenced by chan_pjsip_new(), listfilter(), mgcp_new(), replace(), sip_addheader(), and sip_new().

3003 {
3004  char *cur = result;
3005  size_t consumed;
3006 
3007  while (cur < result + result_size - 1 && !ast_get_encoded_char(stream, cur, &consumed)) {
3008  cur++;
3009  stream += consumed;
3010  }
3011  *cur = '\0';
3012  return result;
3013 }
static PGresult * result
Definition: cel_pgsql.c:88
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:2927

◆ ast_install_stack_functions()

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 346 of file main/app.c.

Referenced by load_module(), and unload_module().

347 {
348  app_stack_callbacks = funcs;
349 }
static const struct ast_app_stack_funcs * app_stack_callbacks
Definition: main/app.c:344

◆ ast_install_vm_test_functions()

void ast_install_vm_test_functions ( ast_vm_test_create_user_fn vm_test_create_user_func,
ast_vm_test_destroy_user_fn vm_test_destroy_user_func 
)

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

References ast_vm_test_create_user_func, and ast_vm_test_destroy_user_func.

Referenced by load_module().

601 {
602  ast_vm_test_create_user_func = vm_test_create_user_func;
603  ast_vm_test_destroy_user_func = vm_test_destroy_user_func;
604 }
static ast_vm_test_create_user_fn * ast_vm_test_create_user_func
Definition: main/app.c:596
static ast_vm_test_destroy_user_fn * ast_vm_test_destroy_user_func
Definition: main/app.c:597

◆ ast_ivr_menu_run()

int ast_ivr_menu_run ( struct ast_channel c,
struct ast_ivr_menu menu,
void *  cbdata 
)

Runs an IVR menu.

Returns
returns 0 on successful completion, -1 on hangup, or -2 on user error in menu

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

References ast_ivr_menu_run_internal().

Referenced by skel_exec().

2786 {
2787  int res = ast_ivr_menu_run_internal(chan, menu, cbdata);
2788  /* Hide internal coding */
2789  return res > 0 ? 0 : res;
2790 }
static int ast_ivr_menu_run_internal(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
Definition: main/app.c:2700

◆ ast_ivr_menu_run_internal()

static int ast_ivr_menu_run_internal ( struct ast_channel chan,
struct ast_ivr_menu menu,
void *  cbdata 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_debug, AST_DIGIT_ANY, ast_log, AST_MAX_EXTENSION, exten, ivr_dispatch(), LOG_WARNING, maxretries, ast_ivr_option::option, option_exists(), ast_ivr_menu::options, read_newoption(), RES_EXIT, RES_REPEAT, RES_RESTART, RES_UPONE, and ast_ivr_menu::title.

Referenced by ast_ivr_menu_run(), and ivr_dispatch().

2701 {
2702  /* Execute an IVR menu structure */
2703  int res = 0;
2704  int pos = 0;
2705  int retries = 0;
2706  char exten[AST_MAX_EXTENSION] = "s";
2707  if (option_exists(menu, "s") < 0) {
2708  strcpy(exten, "g");
2709  if (option_exists(menu, "g") < 0) {
2710  ast_log(LOG_WARNING, "No 's' nor 'g' extension in menu '%s'!\n", menu->title);
2711  return -1;
2712  }
2713  }
2714  while (!res) {
2715  while (menu->options[pos].option) {
2716  if (!strcasecmp(menu->options[pos].option, exten)) {
2717  res = ivr_dispatch(chan, menu->options + pos, exten, cbdata);
2718  ast_debug(1, "IVR Dispatch of '%s' (pos %d) yields %d\n", exten, pos, res);
2719  if (res < 0) {
2720  break;
2721  } else if (res & RES_UPONE) {
2722  return 0;
2723  } else if (res & RES_EXIT) {
2724  return res;
2725  } else if (res & RES_REPEAT) {
2726  int maxretries = res & 0xffff;
2727  if ((res & RES_RESTART) == RES_RESTART) {
2728  retries = 0;
2729  } else {
2730  retries++;
2731  }
2732  if (!maxretries) {
2733  maxretries = 3;
2734  }
2735  if ((maxretries > 0) && (retries >= maxretries)) {
2736  ast_debug(1, "Max retries %d exceeded\n", maxretries);
2737  return -2;
2738  } else {
2739  if (option_exists(menu, "g") > -1) {
2740  strcpy(exten, "g");
2741  } else if (option_exists(menu, "s") > -1) {
2742  strcpy(exten, "s");
2743  }
2744  }
2745  pos = 0;
2746  continue;
2747  } else if (res && strchr(AST_DIGIT_ANY, res)) {
2748  ast_debug(1, "Got start of extension, %c\n", res);
2749  exten[1] = '\0';
2750  exten[0] = res;
2751  if ((res = read_newoption(chan, menu, exten, sizeof(exten)))) {
2752  break;
2753  }
2754  if (option_exists(menu, exten) < 0) {
2755  if (option_exists(menu, "i")) {
2756  ast_debug(1, "Invalid extension entered, going to 'i'!\n");
2757  strcpy(exten, "i");
2758  pos = 0;
2759  continue;
2760  } else {
2761  ast_debug(1, "Aborting on invalid entry, with no 'i' option!\n");
2762  res = -2;
2763  break;
2764  }
2765  } else {
2766  ast_debug(1, "New existing extension: %s\n", exten);
2767  pos = 0;
2768  continue;
2769  }
2770  }
2771  }
2772  pos++;
2773  }
2774  ast_debug(1, "Stopping option '%s', res is %d\n", exten, res);
2775  pos = 0;
2776  if (!strcasecmp(exten, "s")) {
2777  strcpy(exten, "g");
2778  } else {
2779  break;
2780  }
2781  }
2782  return res;
2783 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define RES_EXIT
Definition: main/app.c:2584
#define AST_DIGIT_ANY
Definition: file.h:48
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int option_exists(struct ast_ivr_menu *menu, char *option)
Definition: main/app.c:2659
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define RES_REPEAT
Definition: main/app.c:2585
static int read_newoption(struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten)
Definition: main/app.c:2682
static int maxretries
Definition: res_adsi.c:60
struct ast_ivr_option * options
#define RES_UPONE
Definition: main/app.c:2583
static int ivr_dispatch(struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata)
Definition: main/app.c:2590
#define RES_RESTART
Definition: main/app.c:2586

◆ ast_linear_stream()

int ast_linear_stream ( struct ast_channel chan,
const char *  filename,
int  fd,
int  allowoverride 
)

Stream a filename (or file descriptor) as a generator.

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

References linear_state::allowoverride, ast_activate_generator(), ast_calloc, ast_config_AST_DATA_DIR, ast_copy_string(), ast_log, ast_strlen_zero, linear_state::autoclose, errno, linear_state::fd, and LOG_WARNING.

1090 {
1091  struct linear_state *lin;
1092  char tmpf[256];
1093  int autoclose = 0;
1094 
1095  if (fd < 0) {
1096  if (ast_strlen_zero(filename)) {
1097  return -1;
1098  }
1099 
1100  autoclose = 1;
1101 
1102  if (filename[0] == '/') {
1103  ast_copy_string(tmpf, filename, sizeof(tmpf));
1104  } else {
1105  snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename);
1106  }
1107 
1108  fd = open(tmpf, O_RDONLY);
1109  if (fd < 0) {
1110  ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno));
1111  return -1;
1112  }
1113  }
1114 
1115  lin = ast_calloc(1, sizeof(*lin));
1116  if (!lin) {
1117  if (autoclose) {
1118  close(fd);
1119  }
1120 
1121  return -1;
1122  }
1123 
1124  lin->fd = fd;
1126  lin->autoclose = autoclose;
1127 
1128  return ast_activate_generator(chan, &linearstream, lin);
1129 }
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
Definition: channel.c:2960
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
int errno
static struct ast_generator linearstream
Definition: main/app.c:1082
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int allowoverride
Definition: main/app.c:1004
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_lock_path()

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 2457 of file main/app.c.

References AST_LOCK_FAILURE, ast_lock_path_flock(), ast_lock_path_lockfile(), AST_LOCK_TYPE_FLOCK, and AST_LOCK_TYPE_LOCKFILE.

Referenced by ast_module_reload(), test_vm_api_create_voicemail_files(), and vm_lock_path().

2458 {
2460 
2461  switch (ast_lock_type) {
2463  r = ast_lock_path_lockfile(path);
2464  break;
2465  case AST_LOCK_TYPE_FLOCK:
2466  r = ast_lock_path_flock(path);
2467  break;
2468  }
2469 
2470  return r;
2471 }
static enum AST_LOCK_RESULT ast_lock_path_lockfile(const char *path)
Definition: main/app.c:2263
ast_lock_type
Definition: lock.h:252
static enum AST_LOCK_RESULT ast_lock_path_flock(const char *path)
Definition: main/app.c:2337

◆ ast_lock_path_flock()

static enum AST_LOCK_RESULT ast_lock_path_flock ( const char *  path)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_alloca, ast_calloc, ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_LOCK_FAILURE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log, ast_strdup, errno, path_lock::fd, LOG_WARNING, NULL, path_lock::path, and path_lock_destroy().

Referenced by ast_lock_path().

2338 {
2339  char *fs;
2340  int res;
2341  int fd;
2342  time_t start;
2343  struct path_lock *pl;
2344  struct stat st, ost;
2345 
2346  fs = ast_alloca(strlen(path) + 20);
2347 
2348  snprintf(fs, strlen(path) + 19, "%s/lock", path);
2349  if (lstat(fs, &st) == 0) {
2350  if ((st.st_mode & S_IFMT) == S_IFLNK) {
2351  ast_log(LOG_WARNING, "Unable to create lock file "
2352  "'%s': it's already a symbolic link\n",
2353  fs);
2354  return AST_LOCK_FAILURE;
2355  }
2356  if (st.st_nlink > 1) {
2357  ast_log(LOG_WARNING, "Unable to create lock file "
2358  "'%s': %u hard links exist\n",
2359  fs, (unsigned int) st.st_nlink);
2360  return AST_LOCK_FAILURE;
2361  }
2362  }
2363  if ((fd = open(fs, O_WRONLY | O_CREAT, 0600)) < 0) {
2364  ast_log(LOG_WARNING, "Unable to create lock file '%s': %s\n",
2365  fs, strerror(errno));
2366  return AST_LOCK_PATH_NOT_FOUND;
2367  }
2368  if (!(pl = ast_calloc(1, sizeof(*pl)))) {
2369  /* We don't unlink the lock file here, on the possibility that
2370  * someone else created it - better to leave a little mess
2371  * than create a big one by destroying someone else's lock
2372  * and causing something to be corrupted.
2373  */
2374  close(fd);
2375  return AST_LOCK_FAILURE;
2376  }
2377  pl->fd = fd;
2378  pl->path = ast_strdup(path);
2379 
2380  time(&start);
2381  while (
2382  #ifdef SOLARIS
2383  ((res = fcntl(pl->fd, F_SETLK, fcntl(pl->fd, F_GETFL) | O_NONBLOCK)) < 0) &&
2384  #else
2385  ((res = flock(pl->fd, LOCK_EX | LOCK_NB)) < 0) &&
2386  #endif
2387  (errno == EWOULDBLOCK) &&
2388  (time(NULL) - start < 5))
2389  usleep(1000);
2390  if (res) {
2391  ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n",
2392  path, strerror(errno));
2393  /* No unlinking of lock done, since we tried and failed to
2394  * flock() it.
2395  */
2396  path_lock_destroy(pl);
2397  return AST_LOCK_TIMEOUT;
2398  }
2399 
2400  /* Check for the race where the file is recreated or deleted out from
2401  * underneath us.
2402  */
2403  if (lstat(fs, &st) != 0 && fstat(pl->fd, &ost) != 0 &&
2404  st.st_dev != ost.st_dev &&
2405  st.st_ino != ost.st_ino) {
2406  ast_log(LOG_WARNING, "Unable to create lock file '%s': "
2407  "file changed underneath us\n", fs);
2408  path_lock_destroy(pl);
2409  return AST_LOCK_FAILURE;
2410  }
2411 
2412  /* Success: file created, flocked, and is the one we started with */
2416 
2417  ast_debug(1, "Locked path '%s'\n", path);
2418 
2419  return AST_LOCK_SUCCESS;
2420 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
int errno
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char * path
Definition: main/app.c:2321
static void path_lock_destroy(struct path_lock *obj)
Definition: main/app.c:2326

◆ ast_lock_path_lockfile()

static enum AST_LOCK_RESULT ast_lock_path_lockfile ( const char *  path)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_alloca, ast_debug, AST_FILE_MODE, AST_LOCK_PATH_NOT_FOUND, AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log, ast_random(), errno, LOG_ERROR, LOG_WARNING, and NULL.

Referenced by ast_lock_path().

2264 {
2265  char *s;
2266  char *fs;
2267  int res;
2268  int fd;
2269  int lp = strlen(path);
2270  time_t start;
2271 
2272  s = ast_alloca(lp + 10);
2273  fs = ast_alloca(lp + 20);
2274 
2275  snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, (unsigned long)ast_random());
2276  fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, AST_FILE_MODE);
2277  if (fd < 0) {
2278  ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno));
2279  return AST_LOCK_PATH_NOT_FOUND;
2280  }
2281  close(fd);
2282 
2283  snprintf(s, strlen(path) + 9, "%s/.lock", path);
2284  start = time(NULL);
2285  while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) {
2286  sched_yield();
2287  }
2288 
2289  unlink(fs);
2290 
2291  if (res) {
2292  ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
2293  return AST_LOCK_TIMEOUT;
2294  } else {
2295  ast_debug(1, "Locked path '%s'\n", path);
2296  return AST_LOCK_SUCCESS;
2297  }
2298 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define AST_FILE_MODE
Definition: asterisk.h:32
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
int errno

◆ ast_mf_stream()

int ast_mf_stream ( struct ast_channel chan,
struct ast_channel peer,
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 frames
peer(optional) Peer channel that will be autoserviced while the primary channel is receiving MF
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 967 of file main/app.c.

References ast_autoservice_start(), ast_autoservice_stop(), and mf_stream().

Referenced by dial_exec_full(), manager_play_mf(), sendmf_exec(), and wait_for_answer().

969 {
970  int res;
971  if (!is_external && peer && ast_autoservice_start(peer)) {
972  return -1;
973  }
974  res = mf_stream(chan, digits, between, duration, durationkp, durationst, is_external);
975  if (!is_external && peer && ast_autoservice_stop(peer)) {
976  res = -1;
977  }
978  return res;
979 }
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
static int mf_stream(struct ast_channel *chan, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Definition: main/app.c:836
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266

◆ ast_play_and_prepend()

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 2002 of file main/app.c.

References __ast_play_and_record(), AST_RECORD_IF_EXISTS_OVERWRITE, default_acceptdtmf, default_canceldtmf, and NULL.

Referenced by vm_forwardoptions().

2003 {
2004  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);
2005 }
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:1580
static const char default_acceptdtmf[]
Definition: main/app.c:1989
static const char default_canceldtmf[]
Definition: main/app.c:1990
static int maxsilence
#define NULL
Definition: resample.c:96
static int silencethreshold

◆ ast_play_and_record()

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 1997 of file main/app.c.

References __ast_play_and_record(), AST_RECORD_IF_EXISTS_OVERWRITE, default_acceptdtmf, and default_canceldtmf.

Referenced by app_exec(), ast_record_review(), conf_rec_name(), conf_run(), and setup_privacy_args().

1998 {
1999  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);
2000 }
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:1580
static const char default_acceptdtmf[]
Definition: main/app.c:1989
static const char default_canceldtmf[]
Definition: main/app.c:1990
static int maxsilence
static int silencethreshold

◆ ast_play_and_record_full()

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 1992 of file main/app.c.

References __ast_play_and_record(), default_canceldtmf, and S_OR.

Referenced by play_record_review(), and record_file().

1993 {
1994  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);
1995 }
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:1580
static const char default_canceldtmf[]
Definition: main/app.c:1990
static int maxsilence
static int silencethreshold
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ ast_play_and_wait()

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 at line 1470 of file main/app.c.

References ast_channel_language(), AST_DIGIT_ANY, ast_stopstream(), ast_streamfile(), ast_waitstream(), and d.

Referenced by __ast_play_and_record(), advanced_options(), ast_record_review(), ast_say_counted_adjective(), ast_say_counted_noun(), dialout(), forward_message(), get_folder(), get_folder2(), get_folder_ja(), leave_voicemail(), minivm_greet_exec(), play_message_category(), play_message_duration(), play_record_review(), valid_priv_reply(), vm_allocate_dh(), vm_authenticate(), vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_ja(), vm_browse_messages_pt(), vm_browse_messages_vi(), vm_browse_messages_zh(), vm_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions_en(), vm_instructions_ja(), vm_instructions_zh(), vm_intro(), vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_is(), vm_intro_it(), vm_intro_ja(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), vm_newuser_setup(), vm_options(), vm_play_folder_name(), vm_play_folder_name_gr(), vm_play_folder_name_ja(), vm_play_folder_name_pl(), vm_play_folder_name_ua(), vm_tempgreeting(), and vmauthenticate().

1471 {
1472  int d = 0;
1473 
1474  if ((d = ast_streamfile(chan, fn, ast_channel_language(chan)))) {
1475  return d;
1476  }
1477 
1478  d = ast_waitstream(chan, AST_DIGIT_ANY);
1479 
1480  ast_stopstream(chan);
1481 
1482  return d;
1483 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define AST_DIGIT_ANY
Definition: file.h:48
static struct test_val d
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ ast_queue_topic()

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
Return values
Thetopic structure for queue messages for a given name
NULLif it failed to be found or allocated
Since
12

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

References stasis_topic_pool_get_topic().

Referenced by send_agent_complete().

3190 {
3191  return stasis_topic_pool_get_topic(queue_topic_pool, queuename);
3192 }
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
static struct stasis_topic_pool * queue_topic_pool
Definition: main/app.c:91

◆ ast_queue_topic_all()

struct stasis_topic* ast_queue_topic_all ( void  )

Get the Stasis Message Bus API topic for queue messages.

Return values
Thetopic structure for queue messages
NULLif it has not been allocated
Since
12

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

References queue_topic_all.

Referenced by load_module().

3185 {
3186  return queue_topic_all;
3187 }
static struct stasis_topic * queue_topic_all
Definition: main/app.c:90

◆ ast_read_textfile()

char* ast_read_textfile ( const char *  filename)

Read a file into asterisk.

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

References ast_free, ast_log, ast_malloc, errno, LOG_WARNING, and NULL.

Referenced by ast_tcptls_server_start().

2793 {
2794  int fd, count = 0, res;
2795  char *output = NULL;
2796  struct stat filesize;
2797 
2798  if (stat(filename, &filesize) == -1) {
2799  ast_log(LOG_WARNING, "Error can't stat %s\n", filename);
2800  return NULL;
2801  }
2802 
2803  count = filesize.st_size + 1;
2804 
2805  if ((fd = open(filename, O_RDONLY)) < 0) {
2806  ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno));
2807  return NULL;
2808  }
2809 
2810  if ((output = ast_malloc(count))) {
2811  res = read(fd, output, count - 1);
2812  if (res == count - 1) {
2813  output[res] = '\0';
2814  } else {
2815  ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno));
2816  ast_free(output);
2817  output = NULL;
2818  }
2819  }
2820 
2821  close(fd);
2822 
2823  return output;
2824 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int errno
#define ast_free(a)
Definition: astmm.h:182

◆ ast_record_review()

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.

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

References AST_DIGIT_ANY, ast_dsp_get_threshold_from_settings(), ast_log, ast_play_and_record(), ast_play_and_wait(), ast_stream_and_wait(), ast_verb, ast_waitfordigit(), LOG_WARNING, maxsilence, NULL, silencethreshold, and THRESHOLD_SILENCE.

Referenced by conf_rec_name(), and conf_run().

2490 {
2491  int silencethreshold;
2492  int maxsilence = 0;
2493  int res = 0;
2494  int cmd = 0;
2495  int max_attempts = 3;
2496  int attempts = 0;
2497  int recorded = 0;
2498  int message_exists = 0;
2499  /* Note that urgent and private are for flagging messages as such in the future */
2500 
2501  /* barf if no pointer passed to store duration in */
2502  if (!duration) {
2503  ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n");
2504  return -1;
2505  }
2506 
2507  cmd = '3'; /* Want to start by recording */
2508 
2510 
2511  while ((cmd >= 0) && (cmd != 't')) {
2512  switch (cmd) {
2513  case '1':
2514  if (!message_exists) {
2515  /* In this case, 1 is to record a message */
2516  cmd = '3';
2517  break;
2518  } else {
2519  ast_stream_and_wait(chan, "vm-msgsaved", "");
2520  cmd = 't';
2521  return res;
2522  }
2523  case '2':
2524  /* Review */
2525  ast_verb(3, "Reviewing the recording\n");
2526  cmd = ast_stream_and_wait(chan, recordfile, AST_DIGIT_ANY);
2527  break;
2528  case '3':
2529  message_exists = 0;
2530  /* Record */
2531  ast_verb(3, "R%secording\n", recorded == 1 ? "e-r" : "");
2532  recorded = 1;
2533  if ((cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, NULL, silencethreshold, maxsilence, path)) == -1) {
2534  /* User has hung up, no options to give */
2535  return cmd;
2536  }
2537  if (cmd == '0') {
2538  break;
2539  } else if (cmd == '*') {
2540  break;
2541  } else {
2542  /* If all is well, a message exists */
2543  message_exists = 1;
2544  cmd = 0;
2545  }
2546  break;
2547  case '4':
2548  case '5':
2549  case '6':
2550  case '7':
2551  case '8':
2552  case '9':
2553  case '*':
2554  case '#':
2555  cmd = ast_play_and_wait(chan, "vm-sorry");
2556  break;
2557  default:
2558  if (message_exists) {
2559  cmd = ast_play_and_wait(chan, "vm-review");
2560  } else {
2561  if (!(cmd = ast_play_and_wait(chan, "vm-torerecord"))) {
2562  cmd = ast_waitfordigit(chan, 600);
2563  }
2564  }
2565 
2566  if (!cmd) {
2567  cmd = ast_waitfordigit(chan, 6000);
2568  }
2569  if (!cmd) {
2570  attempts++;
2571  }
2572  if (attempts > max_attempts) {
2573  cmd = 't';
2574  }
2575  }
2576  }
2577  if (cmd == 't') {
2578  cmd = 0;
2579  }
2580  return cmd;
2581 }
#define AST_DIGIT_ANY
Definition: file.h:48
#define LOG_WARNING
Definition: logger.h:274
static int maxsilence
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
static int silencethreshold
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 p...
Definition: main/app.c:1997
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:1814
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:1470
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996

◆ ast_safe_fork()

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 3047 of file main/app.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, ast_pthread_create_background, AST_PTHREADT_NULL, ast_replace_sigchld(), child_cap, errno, zombie::list, LOG_ERROR, LOG_WARNING, NULL, zombie::pid, shaun_of_the_dead(), and shaun_of_the_dead_thread.

Referenced by app_exec(), filestream_destructor(), icesencode(), launch_script(), mp3play(), NBScatplay(), send_waveform_to_fd(), spawn_mp3(), spawn_ras(), and vm_check_password_shell().

3048 {
3049  sigset_t signal_set, old_set;
3050  int pid;
3051 
3052  /* Don't let the default signal handler for children reap our status */
3053  if (stop_reaper) {
3055  }
3056 
3057  /* GCC 4.9 gives a bogus "right-hand operand of comma expression has
3058  * no effect" warning */
3059  (void) sigfillset(&signal_set);
3060  pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
3061 
3062  pid = fork();
3063 
3064  if (pid != 0) {
3065  /* Fork failed or parent */
3066  pthread_sigmask(SIG_SETMASK, &old_set, NULL);
3067  if (!stop_reaper && pid > 0) {
3068  struct zombie *cur = ast_calloc(1, sizeof(*cur));
3069  if (cur) {
3070  cur->pid = pid;
3076  ast_log(LOG_ERROR, "Shaun of the Dead wants to kill zombies, but can't?!!\n");
3078  }
3079  }
3080  }
3081  }
3082  return pid;
3083  } else {
3084  /* Child */
3085 #ifdef HAVE_CAP
3086  cap_set_proc(child_cap);
3087 #endif
3088 
3089  /* Before we unblock our signals, return our trapped signals back to the defaults */
3090  signal(SIGHUP, SIG_DFL);
3091  signal(SIGCHLD, SIG_DFL);
3092  signal(SIGINT, SIG_DFL);
3093  signal(SIGURG, SIG_DFL);
3094  signal(SIGTERM, SIG_DFL);
3095  signal(SIGPIPE, SIG_DFL);
3096  signal(SIGXFSZ, SIG_DFL);
3097 
3098  /* unblock important signal handlers */
3099  if (pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL)) {
3100  ast_log(LOG_WARNING, "unable to unblock signals: %s\n", strerror(errno));
3101  _exit(1);
3102  }
3103 
3104  return pid;
3105  }
3106 }
pid_t pid
Definition: main/app.c:78
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static pthread_t shaun_of_the_dead_thread
Definition: main/app.c:75
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
struct zombie::@333 list
static void * shaun_of_the_dead(void *data)
Definition: main/app.c:94
void ast_replace_sigchld(void)
Replace the SIGCHLD handler.
Definition: extconf.c:801
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
int errno
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static cap_t child_cap
Definition: main/app.c:85

◆ ast_safe_fork_cleanup()

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 3108 of file main/app.c.

References ast_unreplace_sigchld().

Referenced by agi_exec_full(), and run_ras().

3109 {
3111 }
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
Definition: extconf.c:815

◆ ast_set_lock_type()

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 2452 of file main/app.c.

References type.

Referenced by load_asterisk_conf().

2453 {
2454  ast_lock_type = type;
2455 }
static const char type[]
Definition: chan_ooh323.c:109
ast_lock_type
Definition: lock.h:252

◆ ast_str_get_encoded_str()

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.

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

References ast_get_encoded_char(), ast_str_buffer(), ast_str_make_space, ast_str_set(), ast_str_size(), ast_str_update(), buf, and zombie::next.

Referenced by sendtext_exec(), and system_exec_helper().

3016 {
3017  char next, *buf;
3018  size_t offset = 0;
3019  size_t consumed;
3020 
3021  if (strchr(stream, '\\')) {
3022  while (!ast_get_encoded_char(stream, &next, &consumed)) {
3023  if (offset + 2 > ast_str_size(*str) && maxlen > -1) {
3024  ast_str_make_space(str, maxlen > 0 ? maxlen : (ast_str_size(*str) + 48) * 2 - 48);
3025  }
3026  if (offset + 2 > ast_str_size(*str)) {
3027  break;
3028  }
3029  buf = ast_str_buffer(*str);
3030  buf[offset++] = next;
3031  stream += consumed;
3032  }
3033  buf = ast_str_buffer(*str);
3034  buf[offset++] = '\0';
3035  ast_str_update(*str);
3036  } else {
3037  ast_str_set(str, maxlen, "%s", stream);
3038  }
3039  return 0;
3040 }
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_str_make_space(buf, new_len)
Definition: strings.h:780
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
struct zombie * next
Definition: main/app.c:79
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
Definition: strings.h:663
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:2927

◆ AST_THREADSTORAGE_PUBLIC()

AST_THREADSTORAGE_PUBLIC ( ast_str_thread_global_buf  )

◆ ast_uninstall_vm_test_functions()

void ast_uninstall_vm_test_functions ( void  )

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

References ast_vm_test_create_user_func, ast_vm_test_destroy_user_func, and NULL.

Referenced by unload_module().

607 {
610 }
static ast_vm_test_create_user_fn * ast_vm_test_create_user_func
Definition: main/app.c:596
#define NULL
Definition: resample.c:96
static ast_vm_test_destroy_user_fn * ast_vm_test_destroy_user_func
Definition: main/app.c:597

◆ ast_unlock_path()

int ast_unlock_path ( const char *  path)

Unlock a path.

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

References AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_unlock_path_flock(), and ast_unlock_path_lockfile().

Referenced by __ast_play_and_record(), access_counter_file(), ast_module_reload(), close_mailbox(), copy_message(), count_messages(), leave_voicemail(), msg_create_from_file(), open_mailbox(), resequence_mailbox(), save_to_folder(), and test_vm_api_create_voicemail_files().

2474 {
2475  int r = 0;
2476 
2477  switch (ast_lock_type) {
2479  r = ast_unlock_path_lockfile(path);
2480  break;
2481  case AST_LOCK_TYPE_FLOCK:
2482  r = ast_unlock_path_flock(path);
2483  break;
2484  }
2485 
2486  return r;
2487 }
static int ast_unlock_path_flock(const char *path)
Definition: main/app.c:2422
ast_lock_type
Definition: lock.h:252
static int ast_unlock_path_lockfile(const char *path)
Definition: main/app.c:2300

◆ ast_unlock_path_flock()

static int ast_unlock_path_flock ( const char *  path)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_alloca, ast_debug, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, path_lock::le, path_lock::path, and path_lock_destroy().

Referenced by ast_unlock_path().

2423 {
2424  char *s;
2425  struct path_lock *p;
2426 
2427  s = ast_alloca(strlen(path) + 20);
2428 
2431  if (!strcmp(p->path, path)) {
2433  break;
2434  }
2435  }
2438 
2439  if (p) {
2440  snprintf(s, strlen(path) + 19, "%s/lock", path);
2441  unlink(s);
2442  path_lock_destroy(p);
2443  ast_debug(1, "Unlocked path '%s'\n", path);
2444  } else {
2445  ast_debug(1, "Failed to unlock path '%s': "
2446  "lock not found\n", path);
2447  }
2448 
2449  return 0;
2450 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
char * path
Definition: main/app.c:2321
struct path_lock::@334 le
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static void path_lock_destroy(struct path_lock *obj)
Definition: main/app.c:2326

◆ ast_unlock_path_lockfile()

static int ast_unlock_path_lockfile ( const char *  path)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_alloca, ast_debug, ast_log, errno, and LOG_ERROR.

Referenced by ast_unlock_path().

2301 {
2302  char *s;
2303  int res;
2304 
2305  s = ast_alloca(strlen(path) + 10);
2306 
2307  snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
2308 
2309  if ((res = unlink(s))) {
2310  ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno));
2311  } else {
2312  ast_debug(1, "Unlocked path '%s'\n", path);
2313  }
2314 
2315  return res;
2316 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
int errno
char * path
Definition: main/app.c:2321

◆ ast_vm_greeter_is_registered()

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 541 of file main/app.c.

References ao2_cleanup, ao2_global_obj_ref, and table.

542 {
544  int is_registered;
545 
546  table = ao2_global_obj_ref(vm_greeter_provider);
547  is_registered = table ? 1 : 0;
548  ao2_cleanup(table);
549  return is_registered;
550 }
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static char * table
Definition: cdr_odbc.c:58
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_vm_greeter_unregister()

void ast_vm_greeter_unregister ( const char *  module_name)

Unregister the specified voicemail greeter provider.

Since
13.0.0
Parameters
Themodule name of the provider to unregister
Returns
Nothing

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

References ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_release, ast_vm_greeter_functions::module_name, and table.

Referenced by unload_module().

585 {
587 
588  table = ao2_global_obj_ref(vm_greeter_provider);
589  if (table && !strcmp(table->module_name, module_name)) {
590  ao2_global_obj_release(vm_greeter_provider);
591  }
592  ao2_cleanup(table);
593 }
Voicemail greeter function table definition.
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static char * table
Definition: cdr_odbc.c:58
const char * module_name
The name of the module that provides the voicemail greeter functionality.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_vm_index_to_foldername()

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 726 of file main/app.c.

References NULL, and VM_API_CALL.

727 {
728  const char *res = NULL;
729 
730  VM_API_CALL(res, index_to_foldername, (id));
731  return res;
732 }
#define NULL
Definition: resample.c:96
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_vm_is_registered()

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 430 of file main/app.c.

References ao2_cleanup, ao2_global_obj_ref, and table.

431 {
432  struct ast_vm_functions *table;
433  int is_registered;
434 
435  table = ao2_global_obj_ref(vm_provider);
436  is_registered = table ? 1 : 0;
437  ao2_cleanup(table);
438  return is_registered;
439 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static char * table
Definition: cdr_odbc.c:58
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Voicemail function table definition.

◆ ast_vm_mailbox_snapshot_create()

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
mailbox,themailbox to look for
context,thecontext to look for the mailbox in
folder,OPTIONAL.When not NULL only msgs from the specified folder will be included.
descending,listthe msgs in descending order rather than ascending order.
combine_INBOX_and_OLD,Whenthis 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.
Return values
snapshoton success
NULLon failure

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

References NULL, and VM_API_CALL.

Referenced by test_vm_api_remove_all_messages().

740 {
741  struct ast_vm_mailbox_snapshot *res = NULL;
742 
743  VM_API_CALL(res, mailbox_snapshot_create, (mailbox, context, folder, descending,
744  sort_val, combine_INBOX_and_OLD));
745  return res;
746 }
#define NULL
Definition: resample.c:96
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_mailbox_snapshot_destroy()

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 748 of file main/app.c.

References NULL, and VM_API_CALL.

Referenced by AST_TEST_DEFINE(), and test_vm_api_remove_all_messages().

749 {
750  struct ast_vm_mailbox_snapshot *res = NULL;
751 
752  VM_API_CALL(res, mailbox_snapshot_destroy, (mailbox_snapshot));
753  return res;
754 }
#define NULL
Definition: resample.c:96
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_vm_msg_forward()

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 782 of file main/app.c.

References VM_API_CALL.

791 {
792  int res = 0;
793 
794  VM_API_CALL(res, msg_forward, (from_mailbox, from_context, from_folder, to_mailbox,
795  to_context, to_folder, num_msgs, msg_ids, delete_old));
796  return res;
797 }
def from_mailbox(key, val, section, pjsip, nmapped)
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620

◆ ast_vm_msg_move()

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 756 of file main/app.c.

References VM_API_CALL.

762 {
763  int res = 0;
764 
765  VM_API_CALL(res, msg_move, (mailbox, context, num_msgs, oldfolder, old_msg_ids,
766  newfolder));
767  return res;
768 }
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_msg_play()

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 799 of file main/app.c.

References VM_API_CALL.

805 {
806  int res = 0;
807 
808  VM_API_CALL(res, msg_play, (chan, mailbox, context, folder, msg_num, cb));
809  return res;
810 }
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_msg_remove()

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 770 of file main/app.c.

References VM_API_CALL.

775 {
776  int res = 0;
777 
778  VM_API_CALL(res, msg_remove, (mailbox, context, num_msgs, folder, msgs));
779  return res;
780 }
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:620
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_test_create_user()

int ast_vm_test_create_user ( const char *  context,
const char *  mailbox 
)

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

References ast_vm_test_create_user_func.

Referenced by test_vm_api_test_setup().

814 {
817  }
818  return 0;
819 }
static ast_vm_test_create_user_fn * ast_vm_test_create_user_func
Definition: main/app.c:596
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_test_destroy_user()

int ast_vm_test_destroy_user ( const char *  context,
const char *  mailbox 
)

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

References ast_vm_test_destroy_user_func.

Referenced by test_vm_api_test_teardown().

822 {
825  }
826  return 0;
827 }
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
static ast_vm_test_destroy_user_fn * ast_vm_test_destroy_user_func
Definition: main/app.c:597
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ ast_vm_test_swap_table_in()

void ast_vm_test_swap_table_in ( const struct ast_vm_functions vm_table)

Swap out existing voicemail functions with a temporary set of functions for use with unit tests.

Parameters
vm_tablefunction table to use for testing
Note
ast_vm_test_swap_table_out should be called to restore the original set before testing concludes

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

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_replace_unref, ast_log, LOG_ERROR, NULL, provider_is_swapped, RAII_VAR, and vm_table.

490 {
491  RAII_VAR(struct ast_vm_functions *, holding_table, NULL, ao2_cleanup);
492  RAII_VAR(struct ast_vm_functions *, new_table, NULL, ao2_cleanup);
493 
494  if (provider_is_swapped) {
495  ast_log(LOG_ERROR, "Attempted to swap in test function table without swapping out old test table.\n");
496  return;
497  }
498 
499  holding_table = ao2_global_obj_ref(vm_provider);
500 
501  if (holding_table) {
502  ao2_global_obj_replace_unref(vm_provider_holder, holding_table);
503  }
504 
505  new_table = ao2_alloc_options(sizeof(*new_table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
506  if (!new_table) {
507  return;
508  }
509  *new_table = *vm_table;
510 
511  ao2_global_obj_replace_unref(vm_provider, new_table);
513 }
static const struct ast_vm_functions vm_table
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#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:911
static int provider_is_swapped
Definition: main/app.c:487
#define LOG_ERROR
Definition: logger.h:285
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Voicemail function table definition.

◆ ast_vm_test_swap_table_out()

void ast_vm_test_swap_table_out ( void  )

Used after ast_vm_test_swap_table_in to restore the original set of voicemail functions.

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

References ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_release, ao2_global_obj_replace_unref, AO2_GLOBAL_OBJ_STATIC(), ast_log, LOG_ERROR, NULL, provider_is_swapped, and RAII_VAR.

516 {
517  RAII_VAR(struct ast_vm_functions *, held_table, NULL, ao2_cleanup);
518 
519  if (!provider_is_swapped) {
520  ast_log(LOG_ERROR, "Attempted to swap out test function table, but none is currently installed.\n");
521  return;
522  }
523 
524  held_table = ao2_global_obj_ref(vm_provider_holder);
525  if (!held_table) {
526  return;
527  }
528 
529  ao2_global_obj_replace_unref(vm_provider, held_table);
530  ao2_global_obj_release(vm_provider_holder);
532 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#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:911
static int provider_is_swapped
Definition: main/app.c:487
#define LOG_ERROR
Definition: logger.h:285
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Voicemail function table definition.

◆ ast_vm_unregister()

void ast_vm_unregister ( const char *  module_name)

Unregister the specified voicemail provider.

Parameters
Themodule name of the provider to unregister
Returns
Nothing

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

References ao2_cleanup, ao2_global_obj_ref, ao2_global_obj_release, AO2_GLOBAL_OBJ_STATIC(), ast_vm_functions::module_name, and table.

Referenced by unload_module().

474 {
475  struct ast_vm_functions *table;
476 
477  table = ao2_global_obj_ref(vm_provider);
478  if (table && !strcmp(table->module_name, module_name)) {
479  ao2_global_obj_release(vm_provider);
480  }
481  ao2_cleanup(table);
482 }
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static char * table
Definition: cdr_odbc.c:58
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
const char * module_name
The name of the module that provides the voicemail functionality.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Voicemail function table definition.

◆ control_streamfile()

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
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_alloca, ast_channel_language(), ast_channel_name(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_stream(), AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_STOP, AST_CONTROL_STREAM_SUSPEND, ast_debug, ast_opt_transmit_silence, ast_seekstream(), ast_stopstream(), ast_streamfile(), ast_tellstream(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_waitstream_fr(), ast_waitstream_fr_w_cb(), end, and NULL.

Referenced by ast_control_streamfile(), ast_control_streamfile_lang(), and ast_control_streamfile_w_cb().

1142 {
1143  char *breaks = NULL;
1144  char *end = NULL;
1145  int blen = 2;
1146  int res;
1147  long pause_restart_point = 0;
1148  long offset = 0;
1149  struct ast_silence_generator *silgen = NULL;
1150 
1151  if (!file) {
1152  return -1;
1153  }
1154  if (offsetms) {
1155  offset = *offsetms * 8; /* XXX Assumes 8kHz */
1156  }
1157  if (lang == NULL) {
1158  lang = ast_channel_language(chan);
1159  }
1160 
1161  if (stop) {
1162  blen += strlen(stop);
1163  }
1164  if (suspend) {
1165  blen += strlen(suspend);
1166  }
1167  if (restart) {
1168  blen += strlen(restart);
1169  }
1170 
1171  if (blen > 2) {
1172  breaks = ast_alloca(blen + 1);
1173  breaks[0] = '\0';
1174  if (stop) {
1175  strcat(breaks, stop);
1176  }
1177  if (suspend) {
1178  strcat(breaks, suspend);
1179  }
1180  if (restart) {
1181  strcat(breaks, restart);
1182  }
1183  }
1184 
1185  if ((end = strchr(file, ':'))) {
1186  if (!strcasecmp(end, ":end")) {
1187  *end = '\0';
1188  end++;
1189  } else {
1190  end = NULL;
1191  }
1192  }
1193 
1194  for (;;) {
1195  ast_stopstream(chan);
1196  res = ast_streamfile(chan, file, lang);
1197  if (!res) {
1198  if (pause_restart_point) {
1199  ast_seekstream(ast_channel_stream(chan), pause_restart_point, SEEK_SET);
1200  pause_restart_point = 0;
1201  }
1202  else if (end || offset < 0) {
1203  if (offset == -8) {
1204  offset = 0;
1205  }
1206  ast_verb(3, "ControlPlayback seek to offset %ld from end\n", offset);
1207 
1208  ast_seekstream(ast_channel_stream(chan), offset, SEEK_END);
1209  end = NULL;
1210  offset = 0;
1211  } else if (offset) {
1212  ast_verb(3, "ControlPlayback seek to offset %ld\n", offset);
1213  ast_seekstream(ast_channel_stream(chan), offset, SEEK_SET);
1214  offset = 0;
1215  }
1216  if (cb) {
1217  res = ast_waitstream_fr_w_cb(chan, breaks, fwd, rev, skipms, cb);
1218  } else {
1219  res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms);
1220  }
1221  }
1222 
1223  if (res < 1) {
1224  break;
1225  }
1226 
1227  /* We go at next loop if we got the restart char */
1228  if ((restart && strchr(restart, res)) || res == AST_CONTROL_STREAM_RESTART) {
1229  ast_debug(1, "we'll restart the stream here at next loop\n");
1230  pause_restart_point = 0;
1231  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1232  "Control: %s\r\n",
1233  ast_channel_name(chan),
1234  "Restart");
1235  continue;
1236  }
1237 
1238  if ((suspend && strchr(suspend, res)) || res == AST_CONTROL_STREAM_SUSPEND) {
1239  pause_restart_point = ast_tellstream(ast_channel_stream(chan));
1240 
1242  silgen = ast_channel_start_silence_generator(chan);
1243  }
1244  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1245  "Control: %s\r\n",
1246  ast_channel_name(chan),
1247  "Pause");
1248  for (;;) {
1249  ast_stopstream(chan);
1250  if (!(res = ast_waitfordigit(chan, 1000))) {
1251  continue;
1252  } else if (res == -1 || (suspend && strchr(suspend, res)) || (stop && strchr(stop, res))
1254  break;
1255  }
1256  }
1257  if (silgen) {
1258  ast_channel_stop_silence_generator(chan, silgen);
1259  silgen = NULL;
1260  }
1261 
1262  if ((suspend && (res == *suspend)) || res == AST_CONTROL_STREAM_SUSPEND) {
1263  res = 0;
1264  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1265  "Control: %s\r\n",
1266  ast_channel_name(chan),
1267  "Unpause");
1268  continue;
1269  }
1270  }
1271 
1272  if (res == -1) {
1273  break;
1274  }
1275 
1276  /* if we get one of our stop chars, return it to the calling function */
1277  if ((stop && strchr(stop, res)) || res == AST_CONTROL_STREAM_STOP) {
1278  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1279  "Control: %s\r\n",
1280  ast_channel_name(chan),
1281  "Stop");
1282  break;
1283  }
1284  }
1285 
1286  if (pause_restart_point) {
1287  offset = pause_restart_point;
1288  } else {
1289  if (ast_channel_stream(chan)) {
1290  offset = ast_tellstream(ast_channel_stream(chan));
1291  } else {
1292  offset = -8; /* indicate end of file */
1293  }
1294  }
1295 
1296  if (offsetms) {
1297  *offsetms = offset / 8; /* samples --> ms ... XXX Assumes 8 kHz */
1298  }
1299 
1300  ast_stopstream(chan);
1301 
1302  return res;
1303 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
unsigned int stop
Definition: app_meetme.c:1096
#define ast_opt_transmit_silence
Definition: options.h:124
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
#define ast_verb(level,...)
Definition: logger.h:463
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition: file.c:1048
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
Same as waitstream but allows stream to be forwarded or rewound.
Definition: file.c:1745
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
static int skipms
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
Definition: file.c:1038
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:8312
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
int ast_waitstream_fr_w_cb(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms, ast_waitstream_fr_cb cb)
Same as waitstream_fr but allows a callback to be alerted when a user fastforwards or rewinds the fil...
Definition: file.c:1734

◆ control_tone_frame_response()

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
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_STREAM_FORWARD, AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_REVERSE, AST_CONTROL_STREAM_STOP, AST_CONTROL_STREAM_SUSPEND, ast_log, ast_playtones_start(), ast_playtones_stop(), CONTROL_TONE_RESPONSE_FAILED, CONTROL_TONE_RESPONSE_FINISHED, CONTROL_TONE_RESPONSE_NORMAL, ast_tone_zone_sound::data, ast_frame_subclass::integer, LOG_NOTICE, and ast_frame::subclass.

Referenced by ast_control_tone().

1341 {
1342  switch (fr->subclass.integer) {
1344  ast_playtones_stop(chan);
1347  if (*paused) {
1348  *paused = 0;
1349  if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1351  }
1352  } else {
1353  *paused = 1;
1354  ast_playtones_stop(chan);
1355  }
1358  ast_playtones_stop(chan);
1359  if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1361  }
1364  ast_log(LOG_NOTICE, "Media control operation 'reverse' not supported for media type 'tone'\n");
1367  ast_log(LOG_NOTICE, "Media control operation 'forward' not supported for media type 'tone'\n");
1369  case AST_CONTROL_HANGUP:
1370  case AST_CONTROL_BUSY:
1373  }
1374 
1376 }
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
Definition: logger.h:263
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

◆ dtmf_stream()

static int dtmf_stream ( struct ast_channel chan,
const char *  digits,
int  between,
unsigned int  duration,
int  is_external 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), AST_CONTROL_FLASH, ast_indicate(), ast_log, ast_opt_transmit_silence, ast_safe_sleep(), ast_senddigit(), ast_senddigit_external(), digit, external_sleep(), LOG_WARNING, and NULL.

Referenced by ast_dtmf_stream(), and ast_dtmf_stream_external().

900 {
901  const char *ptr;
902  int res;
903  struct ast_silence_generator *silgen = NULL;
904  int (*my_sleep)(struct ast_channel *chan, int ms);
905  int (*my_senddigit)(struct ast_channel *chan, char digit, unsigned int duration);
906 
907  if (is_external) {
908  my_sleep = external_sleep;
909  my_senddigit = ast_senddigit_external;
910  } else {
911  my_sleep = ast_safe_sleep;
912  my_senddigit = ast_senddigit;
913  }
914 
915  if (!between) {
916  between = 100;
917  }
918 
919  /* Need a quiet time before sending digits. */
922  }
923  res = my_sleep(chan, 100);
924  if (res) {
925  goto dtmf_stream_cleanup;
926  }
927 
928  for (ptr = digits; *ptr; ptr++) {
929  if (*ptr == 'w') {
930  /* 'w' -- wait half a second */
931  res = my_sleep(chan, 500);
932  if (res) {
933  break;
934  }
935  } else if (*ptr == 'W') {
936  /* 'W' -- wait a second */
937  res = my_sleep(chan, 1000);
938  if (res) {
939  break;
940  }
941  } else if (strchr("0123456789*#abcdfABCDF", *ptr)) {
942  if (*ptr == 'f' || *ptr == 'F') {
943  /* ignore return values if not supported by channel */
945  } else {
946  /* Character represents valid DTMF */
947  my_senddigit(chan, *ptr, duration);
948  }
949  /* pause between digits */
950  res = my_sleep(chan, between);
951  if (res) {
952  break;
953  }
954  } else {
955  ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n", *ptr);
956  }
957  }
958 
959 dtmf_stream_cleanup:
960  if (silgen) {
962  }
963 
964  return res;
965 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
char digit
Main Channel structure associated with a channel.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define LOG_WARNING
Definition: logger.h:274
int ast_senddigit_external(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel from an external thread.
Definition: channel.c:5032
#define ast_opt_transmit_silence
Definition: options.h:124
#define NULL
Definition: resample.c:96
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:5019
#define ast_log
Definition: astobj2.c:42
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
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:8312
static int external_sleep(struct ast_channel *chan, int ms)
Definition: main/app.c:830

◆ external_sleep()

static int external_sleep ( struct ast_channel chan,
int  ms 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by dtmf_stream(), and mf_stream().

831 {
832  usleep(ms * 1000);
833  return 0;
834 }

◆ ivr_dispatch()

static int ivr_dispatch ( struct ast_channel chan,
struct ast_ivr_option option,
char *  exten,
void *  cbdata 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_ivr_option::action, ast_ivr_option::adata, AST_ACTION_BACKGROUND, AST_ACTION_BACKLIST, AST_ACTION_CALLBACK, AST_ACTION_EXIT, AST_ACTION_MENU, AST_ACTION_NOOP, AST_ACTION_PLAYBACK, AST_ACTION_PLAYLIST, AST_ACTION_REPEAT, AST_ACTION_RESTART, AST_ACTION_TRANSFER, AST_ACTION_UPONE, AST_ACTION_WAITOPTION, ast_channel_pbx(), AST_DIGIT_ANY, ast_ivr_menu_run_internal(), ast_log, ast_parseable_goto(), ast_stopstream(), ast_strdupa, ast_stream_and_wait(), ast_waitfordigit(), c, LOG_NOTICE, RES_EXIT, RES_REPEAT, RES_RESTART, RES_UPONE, and strsep().

Referenced by ast_ivr_menu_run_internal().

2591 {
2592  int res;
2593  int (*ivr_func)(struct ast_channel *, void *);
2594  char *c;
2595  char *n;
2596 
2597  switch (option->action) {
2598  case AST_ACTION_UPONE:
2599  return RES_UPONE;
2600  case AST_ACTION_EXIT:
2601  return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff);
2602  case AST_ACTION_REPEAT:
2603  return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff);
2604  case AST_ACTION_RESTART:
2605  return RES_RESTART ;
2606  case AST_ACTION_NOOP:
2607  return 0;
2608  case AST_ACTION_BACKGROUND:
2609  res = ast_stream_and_wait(chan, (char *)option->adata, AST_DIGIT_ANY);
2610  if (res < 0) {
2611  ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2612  res = 0;
2613  }
2614  return res;
2615  case AST_ACTION_PLAYBACK:
2616  res = ast_stream_and_wait(chan, (char *)option->adata, "");
2617  if (res < 0) {
2618  ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2619  res = 0;
2620  }
2621  return res;
2622  case AST_ACTION_MENU:
2623  if ((res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata)) == -2) {
2624  /* Do not pass entry errors back up, treat as though it was an "UPONE" */
2625  res = 0;
2626  }
2627  return res;
2628  case AST_ACTION_WAITOPTION:
2629  if (!(res = ast_waitfordigit(chan, ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000))) {
2630  return 't';
2631  }
2632  return res;
2633  case AST_ACTION_CALLBACK:
2634  ivr_func = option->adata;
2635  res = ivr_func(chan, cbdata);
2636  return res;
2637  case AST_ACTION_TRANSFER:
2638  res = ast_parseable_goto(chan, option->adata);
2639  return 0;
2640  case AST_ACTION_PLAYLIST:
2641  case AST_ACTION_BACKLIST:
2642  res = 0;
2643  c = ast_strdupa(option->adata);
2644  while ((n = strsep(&c, ";"))) {
2645  if ((res = ast_stream_and_wait(chan, n,
2646  (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : ""))) {
2647  break;
2648  }
2649  }
2650  ast_stopstream(chan);
2651  return res;
2652  default:
2653  ast_log(LOG_NOTICE, "Unknown dispatch function %u, ignoring!\n", option->action);
2654  return 0;
2655  }
2656  return -1;
2657 }
Main Channel structure associated with a channel.
#define RES_EXIT
Definition: main/app.c:2584
ast_ivr_action action
#define AST_DIGIT_ANY
Definition: file.h:48
static struct test_val c
static int ast_ivr_menu_run_internal(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
Definition: main/app.c:2700
#define ast_log
Definition: astobj2.c:42
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8859
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define RES_REPEAT
Definition: main/app.c:2585
#define LOG_NOTICE
Definition: logger.h:263
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:1814
#define RES_UPONE
Definition: main/app.c:2583
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
char * strsep(char **str, const char *delims)
#define RES_RESTART
Definition: main/app.c:2586
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ linear_alloc()

static void* linear_alloc ( struct ast_channel chan,
void *  params 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References linear_state::allowoverride, ao2_bump, ao2_cleanup, ast_channel_flags(), ast_channel_name(), ast_channel_writeformat(), ast_clear_flag, AST_FLAG_WRITE_INT, ast_format_slin, ast_free, ast_log, ast_set_flag, ast_set_write_format(), LOG_WARNING, NULL, and linear_state::origwfmt.

1056 {
1057  struct linear_state *ls = params;
1058 
1059  if (!params) {
1060  return NULL;
1061  }
1062 
1063  /* In this case, params is already malloc'd */
1064  if (ls->allowoverride) {
1066  } else {
1068  }
1069 
1071 
1073  ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", ast_channel_name(chan));
1074  ao2_cleanup(ls->origwfmt);
1075  ast_free(ls);
1076  ls = params = NULL;
1077  }
1078 
1079  return params;
1080 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
struct ast_format * origwfmt
Definition: main/app.c:1005
#define ast_free(a)
Definition: astmm.h:182
int allowoverride
Definition: main/app.c:1004
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)

◆ linear_generator()

static int linear_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_format_slin, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log, ast_write(), buf, ast_frame::datalen, linear_state::fd, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_frame::samples, and ast_frame::subclass.

1026 {
1027  short buf[2048 + AST_FRIENDLY_OFFSET / 2];
1028  struct linear_state *ls = data;
1029  struct ast_frame f = {
1031  .data.ptr = buf + AST_FRIENDLY_OFFSET / 2,
1032  .offset = AST_FRIENDLY_OFFSET,
1033  };
1034  int res;
1035 
1037 
1038  len = samples * 2;
1039  if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
1040  ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" , len);
1041  len = sizeof(buf) - AST_FRIENDLY_OFFSET;
1042  }
1043  res = read(ls->fd, buf + AST_FRIENDLY_OFFSET/2, len);
1044  if (res > 0) {
1045  f.datalen = res;
1046  f.samples = res / 2;
1047  ast_write(chan, &f);
1048  if (res == len) {
1049  return 0;
1050  }
1051  }
1052  return -1;
1053 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5189
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

◆ linear_release()

static void linear_release ( struct ast_channel chan,
void *  params 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ao2_cleanup, ast_channel_name(), ast_format_get_name(), ast_free, ast_log, ast_set_write_format(), linear_state::autoclose, linear_state::fd, LOG_WARNING, and linear_state::origwfmt.

1009 {
1010  struct linear_state *ls = params;
1011 
1012  if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) {
1013  ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%s'\n",
1015  }
1016  ao2_cleanup(ls->origwfmt);
1017 
1018  if (ls->autoclose) {
1019  close(ls->fd);
1020  }
1021 
1022  ast_free(params);
1023 }
#define LOG_WARNING
Definition: logger.h:274
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define ast_log
Definition: astobj2.c:42
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
struct ast_format * origwfmt
Definition: main/app.c:1005
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)

◆ make_silence()

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_SLINEAR.

Parameters
origFrame as basis for silence to generate.
Returns
New frame of silence; free with ast_frfree().
NULL on error.
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

Definition at line 1494 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_log, AST_MALLOCD_HDR, ast_verb, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_frame::mallocd, NULL, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by __ast_play_and_record().

1495 {
1496  struct ast_frame *silence;
1497  size_t size;
1498  size_t datalen;
1499  size_t samples = 0;
1500 
1501  if (!orig) {
1502  return NULL;
1503  }
1504  do {
1506  ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
1507  return NULL;
1508  }
1509 
1510  samples += orig->samples;
1511 
1512  orig = AST_LIST_NEXT(orig, frame_list);
1513  } while (orig);
1514 
1515  ast_verb(4, "Silencing %zu samples\n", samples);
1516 
1517 
1518  datalen = sizeof(short) * samples;
1519  size = sizeof(*silence) + datalen;
1520  silence = ast_calloc(1, size);
1521  if (!silence) {
1522  return NULL;
1523  }
1524 
1525  silence->mallocd = AST_MALLOCD_HDR;
1526  silence->frametype = AST_FRAME_VOICE;
1527  silence->data.ptr = (void *)(silence + 1);
1528  silence->samples = samples;
1529  silence->datalen = datalen;
1530 
1532 
1533  return silence;
1534 }
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
#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
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Data structure associated with a single frame of data.
union ast_frame::@263 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

◆ mf_stream()

static int mf_stream ( struct ast_channel chan,
const char *  digits,
int  between,
unsigned int  duration,
unsigned int  durationkp,
unsigned int  durationst,
int  is_external 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), AST_CONTROL_FLASH, AST_CONTROL_WINK, ast_indicate(), ast_log, ast_opt_transmit_silence, ast_playtones_start(), ast_safe_sleep(), ast_senddigit_mf(), ast_senddigit_mf_end(), external_sleep(), LOG_WARNING, and NULL.

Referenced by ast_mf_stream().

838 {
839  const char *ptr;
840  int res;
841  struct ast_silence_generator *silgen = NULL;
842  int (*my_sleep)(struct ast_channel *chan, int ms);
843 
844  if (is_external) {
845  my_sleep = external_sleep;
846  } else {
847  my_sleep = ast_safe_sleep;
848  }
849 
850  if (!between) {
851  between = 100;
852  }
853 
854  /* Need a quiet time before sending digits. */
857  }
858  res = my_sleep(chan, 100);
859  if (res) {
860  goto mf_stream_cleanup;
861  }
862 
863  for (ptr = digits; *ptr; ptr++) {
864  if (strchr("0123456789*#ABCwWfF", *ptr)) {
865  if (*ptr == 'f' || *ptr == 'F') {
866  /* ignore return values if not supported by channel */
868  } else if (*ptr == 'w' || *ptr == 'W') {
869  /* ignore return values if not supported by channel */
871  } else {
872  /* Character represents valid MF */
873  ast_senddigit_mf(chan, *ptr, duration, durationkp, durationst, is_external);
874  }
875  /* pause between digits */
876  /* The DSP code in Asterisk does not currently properly receive repeated tones
877  if no audio is sent in the middle. Simply sending audio (even 0 Hz)
878  works around this limitation and guarantees the correct behavior.
879  */
880  ast_playtones_start(chan, 0, "0", 0);
881  res = my_sleep(chan, between);
882  ast_senddigit_mf_end(chan);
883  if (res) {
884  break;
885  }
886  } else {
887  ast_log(LOG_WARNING, "Illegal MF character '%c' in string. (0-9*#ABCwWfF allowed)\n", *ptr);
888  }
889  }
890 
891 mf_stream_cleanup:
892  if (silgen) {
894  }
895 
896  return res;
897 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
Main Channel structure associated with a channel.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
#define LOG_WARNING
Definition: logger.h:274
#define ast_opt_transmit_silence
Definition: options.h:124
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8266
int ast_senddigit_mf_end(struct ast_channel *chan)
End sending an MF digit to a channel.
Definition: channel.c:4988
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:8312
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
static int external_sleep(struct ast_channel *chan, int ms)
Definition: main/app.c:830
int ast_senddigit_mf(struct ast_channel *chan, char digit, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Send an MF digit to a channel.
Definition: channel.c:4997

◆ option_exists()

static int option_exists ( struct ast_ivr_menu menu,
char *  option 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_ivr_option::option, ast_ivr_menu::options, and ast_channel::x.

Referenced by ast_ivr_menu_run_internal().

2660 {
2661  int x;
2662  for (x = 0; menu->options[x].option; x++) {
2663  if (!strcasecmp(menu->options[x].option, option)) {
2664  return x;
2665  }
2666  }
2667  return -1;
2668 }
struct ast_ivr_option * options
char x
Definition: extconf.c:81

◆ option_matchmore()

static int option_matchmore ( struct ast_ivr_menu menu,
char *  option 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_ivr_option::option, ast_ivr_menu::options, and ast_channel::x.

Referenced by read_newoption().

2671 {
2672  int x;
2673  for (x = 0; menu->options[x].option; x++) {
2674  if ((!strncasecmp(menu->options[x].option, option, strlen(option))) &&
2675  (menu->options[x].option[strlen(option)])) {
2676  return x;
2677  }
2678  }
2679  return -1;
2680 }
struct ast_ivr_option * options
char x
Definition: extconf.c:81

◆ parse_options()

static int parse_options ( const struct ast_app_option options,
void *  _flags,
char **  args,
char *  optstr,
int  flaglen 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_app_option::arg_index, ast_clear_flag, ast_copy_string(), AST_FLAGS_ALL, ast_log, ast_set_flag, ast_set_flag64, ast_flags::flags, ast_flags64::flags, LOG_WARNING, paren, and quote().

Referenced by ast_app_parse_options(), and ast_app_parse_options64().

2827 {
2828  char *s, *arg;
2829  int curarg, res = 0;
2830  unsigned int argloc;
2831  struct ast_flags *flags = _flags;
2832  struct ast_flags64 *flags64 = _flags;
2833 
2834  if (flaglen == 32) {
2835  ast_clear_flag(flags, AST_FLAGS_ALL);
2836  } else {
2837  flags64->flags = 0;
2838  }
2839 
2840  if (!optstr) {
2841  return 0;
2842  }
2843 
2844  s = optstr;
2845  while (*s) {
2846  curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */
2847  argloc = options[curarg].arg_index;
2848  if (*s == '(') {
2849  int paren = 1, quote = 0;
2850  int parsequotes = (s[1] == '"') ? 1 : 0;
2851 
2852  /* Has argument */
2853  arg = ++s;
2854  for (; *s; s++) {
2855  if (*s == '(' && !quote) {
2856  paren++;
2857  } else if (*s == ')' && !quote) {
2858  /* Count parentheses, unless they're within quotes (or backslashed, below) */
2859  paren--;
2860  } else if (*s == '"' && parsequotes) {
2861  /* Leave embedded quotes alone, unless they are the first character */
2862  quote = quote ? 0 : 1;
2863  ast_copy_string(s, s + 1, INT_MAX);
2864  s--;
2865  } else if (*s == '\\') {
2866  if (!quote) {
2867  /* If a backslash is found outside of quotes, remove it */
2868  ast_copy_string(s, s + 1, INT_MAX);
2869  } else if (quote && s[1] == '"') {
2870  /* Backslash for a quote character within quotes, remove the backslash */
2871  ast_copy_string(s, s + 1, INT_MAX);
2872  } else {
2873  /* Backslash within quotes, keep both characters */
2874  s++;
2875  }
2876  }
2877 
2878  if (paren == 0) {
2879  break;
2880  }
2881  }
2882  /* This will find the closing paren we found above, or none, if the string ended before we found one. */
2883  if ((s = strchr(s, ')'))) {
2884  if (argloc) {
2885  args[argloc - 1] = arg;
2886  }
2887  *s++ = '\0';
2888  } else {
2889  ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
2890  res = -1;
2891  break;
2892  }
2893  } else if (argloc) {
2894  args[argloc - 1] = "";
2895  }
2896  if (flaglen == 32) {
2897  ast_set_flag(flags, options[curarg].flag);
2898  } else {
2899  ast_set_flag64(flags64, options[curarg].flag);
2900  }
2901  }
2902 
2903  return res;
2904 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
unsigned int flags
Definition: utils.h:200
#define ast_set_flag64(p, flag)
Definition: utils.h:127
const char * args
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
#define ast_log
Definition: astobj2.c:42
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
uint64_t flags
Definition: utils.h:205
long int flag
Definition: f2c.h:83
#define AST_FLAGS_ALL
Definition: utils.h:196
unsigned int arg_index
The index of the entry in the arguments array that should be used for this option&#39;s argument...
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define paren
Definition: ael_lex.c:973

◆ parse_tone_uri()

static int parse_tone_uri ( char *  tone_parser,
const char **  tone_indication,
const char **  tone_zone 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_log, ast_strlen_zero, LOG_ERROR, and strsep().

Referenced by ast_control_tone().

1381 {
1382  *tone_indication = strsep(&tone_parser, ";");
1383 
1384  if (ast_strlen_zero(tone_parser)) {
1385  /* Only the indication is included */
1386  return 0;
1387  }
1388 
1389  if (!(strncmp(tone_parser, "tonezone=", 9))) {
1390  *tone_zone = tone_parser + 9;
1391  } else {
1392  ast_log(LOG_ERROR, "Unexpected Tone URI component: %s\n", tone_parser);
1393  return -1;
1394  }
1395 
1396  return 0;
1397 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
char * strsep(char **str, const char *delims)

◆ path_lock_destroy()

static void path_lock_destroy ( struct path_lock obj)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_free, path_lock::fd, and path_lock::path.

Referenced by ast_lock_path_flock(), and ast_unlock_path_flock().

2327 {
2328  if (obj->fd >= 0) {
2329  close(obj->fd);
2330  }
2331  if (obj->path) {
2332  ast_free(obj->path);
2333  }
2334  ast_free(obj);
2335 }
#define ast_free(a)
Definition: astmm.h:182
char * path
Definition: main/app.c:2321

◆ read_newoption()

static int read_newoption ( struct ast_channel chan,
struct ast_ivr_menu menu,
char *  exten,
int  maxexten 
)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_channel_pbx(), ast_waitfordigit(), ast_pbx::dtimeoutms, and option_matchmore().

Referenced by ast_ivr_menu_run_internal().

2683 {
2684  int res = 0;
2685  int ms;
2686  while (option_matchmore(menu, exten)) {
2687  ms = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 5000;
2688  if (strlen(exten) >= maxexten - 1) {
2689  break;
2690  }
2691  if ((res = ast_waitfordigit(chan, ms)) < 1) {
2692  break;
2693  }
2694  exten[strlen(exten) + 1] = '\0';
2695  exten[strlen(exten)] = res;
2696  }
2697  return res > 0 ? 0 : res;
2698 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
static int option_matchmore(struct ast_ivr_menu *menu, char *option)
Definition: main/app.c:2670
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int dtimeoutms
Definition: pbx.h:212

◆ set_read_to_slin()

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_SLINEAR, 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.
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ao2_bump, ast_channel_readformat(), ast_format_slin, and ast_set_read_format().

Referenced by __ast_play_and_record().

1547 {
1548  if (!chan || !orig_format) {
1549  return -1;
1550  }
1551  *orig_format = ao2_bump(ast_channel_readformat(chan));
1552  return ast_set_read_format(chan, ast_format_slin);
1553 }
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41

◆ shaun_of_the_dead()

static void* shaun_of_the_dead ( void *  data)
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_free, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_poll, zombie::list, NULL, zombie::pid, and status.

Referenced by ast_safe_fork().

95 {
96  struct zombie *cur;
97  int status;
98  for (;;) {
99  if (!AST_LIST_EMPTY(&zombies)) {
100  /* Don't allow cancellation while we have a lock. */
101  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
104  if (waitpid(cur->pid, &status, WNOHANG) != 0) {
106  ast_free(cur);
107  }
108  }
111  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
112  }
113  pthread_testcancel();
114  /* Wait for 60 seconds, without engaging in a busy loop. */
115  ast_poll(NULL, 0, AST_LIST_FIRST(&zombies) ? 5000 : 60000);
116  }
117  return NULL;
118 }
pid_t pid
Definition: main/app.c:78
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct zombie::@333 list
#define ast_free(a)
Definition: astmm.h:182
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
jack_status_t status
Definition: app_jack.c:146

◆ vm_greeter_warn_no_provider()

static void vm_greeter_warn_no_provider ( void  )
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_verb, and vm_greeter_warnings.

635 {
636  if (vm_greeter_warnings++ % 10 == 0) {
637  ast_verb(3, "No voicemail greeter provider registered.\n");
638  }
639 }
static int vm_greeter_warnings
Definition: main/app.c:539
#define ast_verb(level,...)
Definition: logger.h:463

◆ vm_warn_no_provider()

static void vm_warn_no_provider ( void  )
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

References ast_verb, and vm_warnings.

614 {
615  if (vm_warnings++ % 10 == 0) {
616  ast_verb(3, "No voicemail provider registered.\n");
617  }
618 }
#define ast_verb(level,...)
Definition: logger.h:463
static int vm_warnings
Definition: main/app.c:428

Variable Documentation

◆ app_stack_callbacks

const struct ast_app_stack_funcs* app_stack_callbacks
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_app_exec_sub(), and ast_app_expand_sub_args().

◆ ast_lock_type

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

◆ ast_vm_test_create_user_func

ast_vm_test_create_user_fn* ast_vm_test_create_user_func = NULL
static

◆ ast_vm_test_destroy_user_func

ast_vm_test_destroy_user_fn* ast_vm_test_destroy_user_func = NULL
static

◆ child_cap

cap_t child_cap
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by app_cleanup(), app_init(), and ast_safe_fork().

◆ default_acceptdtmf

const char default_acceptdtmf[] = "#"
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_play_and_prepend(), and ast_play_and_record().

◆ default_canceldtmf

const char default_canceldtmf[] = ""
static

◆ global_maxsilence

int global_maxsilence = 0
static

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

Referenced by __ast_play_and_record().

◆ global_silence_threshold

int global_silence_threshold = 128
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by __ast_play_and_record().

◆ groups

struct groups groups = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

Referenced by ast_ref_namedgroups().

◆ linearstream

struct ast_generator linearstream
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

◆ path_lock_list

struct path_lock_list path_lock_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ provider_is_swapped

int provider_is_swapped = 0
static

◆ queue_topic_all

struct stasis_topic* queue_topic_all
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_queue_topic_all().

◆ queue_topic_pool

struct stasis_topic_pool* queue_topic_pool
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

◆ shaun_of_the_dead_thread

pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL
static
Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by ast_safe_fork().

◆ vm_greeter_warnings

int vm_greeter_warnings
static

Voicemail greeter not registered warning

Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by vm_greeter_warn_no_provider().

◆ vm_warnings

int vm_warnings
static

Voicemail not registered warning

Examples:
/usr/src/asterisk-18.5.0/main/app.c.

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

Referenced by vm_warn_no_provider().

◆ zombies

struct zombies zombies = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static