Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 "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 SF_BETWEEN   600
 
#define SF_BUF_LEN   20
 
#define SF_OFF   33
 
#define SF_ON   67
 
#define VM_API_CALL(res, api_call, api_parms)
 
#define VM_GREETER_API_CALL(res, api_call, api_parms)
 

Enumerations

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

Functions

unsigned int __ast_app_separate_args (char *buf, char delim, int remove_chars, char **array, int arraylen)
 Separate a string into arguments in an array. More...
 
static int __ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, int prepend, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
 
int __ast_vm_greeter_register (const struct ast_vm_greeter_functions *vm_table, struct ast_module *module)
 Set voicemail greeter function callbacks. More...
 
int __ast_vm_register (const struct ast_vm_functions *vm_table, struct ast_module *module)
 Set voicemail function callbacks. More...
 
static AO2_GLOBAL_OBJ_STATIC (vm_greeter_provider)
 The container for the voicemail greeter provider. More...
 
static AO2_GLOBAL_OBJ_STATIC (vm_provider)
 The container for the voicemail 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_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
 Run a subroutine on a channel, placing an optional second channel into autoservice. More...
 
const char * ast_app_expand_sub_args (struct ast_channel *chan, const char *args)
 Add missing context/exten to subroutine argument string. More...
 
enum ast_getdata_result ast_app_getdata (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
 Plays a stream and gets DTMF data from a channel. More...
 
int ast_app_getdata_full (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd)
 Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions. More...
 
enum ast_getdata_result ast_app_getdata_terminator (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, char *terminator)
 Plays a stream and gets DTMF data from a channel. More...
 
int ast_app_group_discard (struct ast_channel *chan)
 Discard all group counting for a channel. 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_sub (struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_location, const char *sub_args, int ignore_hangup)
 Run a subroutine on a channel, placing an optional second channel into autoservice. More...
 
int ast_app_sayname (struct ast_channel *chan, const char *mailbox_id)
 Play a recorded user name for the mailbox to the specified channel. More...
 
void ast_close_fds_above_n (int n)
 Common routine for child processes, to close all fds prior to exec(2) More...
 
int ast_control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms)
 Stream a file with fast forward, pause, reverse, restart. More...
 
int ast_control_streamfile_lang (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, const char *lang, long *offsetms)
 Version of ast_control_streamfile() which allows the language of the media file to be specified. More...
 
int ast_control_streamfile_w_cb (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms, ast_waitstream_fr_cb cb)
 Stream a file with fast forward, pause, reverse, restart. More...
 
int ast_control_tone (struct ast_channel *chan, const char *tone)
 Controls playback of a tone. More...
 
int ast_dtmf_stream (struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
 Send a string of DTMF digits to a channel. More...
 
void ast_dtmf_stream_external (struct ast_channel *chan, const char *digits, int between, unsigned int duration)
 Send a string of DTMF digits to a channel from an external thread. More...
 
int ast_get_encoded_char (const char *stream, char *result, size_t *consumed)
 Decode an encoded control or extended ASCII character. More...
 
char * ast_get_encoded_str (const char *stream, char *result, size_t result_size)
 Decode a stream of encoded control or extended ASCII characters. More...
 
void ast_install_stack_functions (const struct ast_app_stack_funcs *funcs)
 Set stack application function callbacks. More...
 
int ast_ivr_menu_run (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 Runs an IVR menu. More...
 
static int ast_ivr_menu_run_internal (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 
int ast_linear_stream (struct ast_channel *chan, const char *filename, int fd, int allowoverride)
 Stream a filename (or file descriptor) as a generator. 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, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
 Send a string of MF digits to a channel. More...
 
int ast_play_and_prepend (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence)
 Record a file based on input frm a channel. Recording is performed in 'prepend' mode which works a little differently from normal recordings This function will not play a success message due to post-recording control in the application this was added for. More...
 
int ast_play_and_record (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path)
 Record a file based on input from a channel. Use default accept and cancel DTMF. This function will play "auth-thankyou" upon successful recording. More...
 
int ast_play_and_record_full (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
 Record a file based on input from a channel This function will play "auth-thankyou" upon successful recording if skip_confirmation_sound is false. More...
 
int ast_play_and_wait (struct ast_channel *chan, const char *fn)
 Play a stream and wait for a digit, returning the digit that was pressed. 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_sf_stream (struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
 Send a string of SF digits to a channel. More...
 
int ast_str_get_encoded_str (struct ast_str **str, int maxlen, const char *stream)
 Decode a stream of encoded control or extended ASCII characters. More...
 
 AST_THREADSTORAGE_PUBLIC (ast_str_thread_global_buf)
 
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...
 
void ast_vm_unregister (const char *module_name)
 Unregister the specified voicemail provider. More...
 
static int control_streamfile (struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *suspend, const char *restart, int skipms, long *offsetms, const char *lang, ast_waitstream_fr_cb cb)
 
static enum control_tone_frame_response_result control_tone_frame_response (struct ast_channel *chan, struct ast_frame *fr, struct ast_tone_zone_sound *ts, const char *tone, int *paused)
 
static int dtmf_stream (struct ast_channel *chan, const char *digits, int between, unsigned int duration, int is_external)
 
static int external_sleep (struct ast_channel *chan, int ms)
 
static int ivr_dispatch (struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata)
 
static void * linear_alloc (struct ast_channel *chan, void *params)
 
static int linear_generator (struct ast_channel *chan, void *data, int len, int samples)
 
static void linear_release (struct ast_channel *chan, void *params)
 
static struct ast_framemake_silence (const struct ast_frame *orig)
 Construct a silence frame of the same duration as orig. More...
 
static int mf_stream (struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
 
static int option_exists (struct ast_ivr_menu *menu, char *option)
 
static int option_matchmore (struct ast_ivr_menu *menu, char *option)
 
static int parse_options (const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
 
static int parse_tone_uri (char *tone_parser, const char **tone_indication, const char **tone_zone)
 
static void path_lock_destroy (struct path_lock *obj)
 
static int read_newoption (struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten)
 
static int set_read_to_slin (struct ast_channel *chan, struct ast_format **orig_format)
 Sets a channel's read format to ast_format_slin, recording its original format. More...
 
static int sf_stream (struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
 
static void * shaun_of_the_dead (void *data)
 
static void vm_greeter_warn_no_provider (void)
 
static void vm_warn_no_provider (void)
 

Variables

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

Detailed Description

Convenient Application Routines.

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

Definition in file main/app.c.

Macro Definition Documentation

◆ AST_MAX_FORMATS

#define AST_MAX_FORMATS   10

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

◆ FMT

#define FMT   "%30Lf%9s"

◆ RES_EXIT

#define RES_EXIT   (1 << 17)

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

◆ RES_REPEAT

#define RES_REPEAT   (1 << 18)

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

◆ RES_RESTART

#define RES_RESTART   ((1 << 19) | RES_REPEAT)

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

◆ RES_UPONE

#define RES_UPONE   (1 << 16)

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

◆ SF_BETWEEN

#define SF_BETWEEN   600

◆ SF_BUF_LEN

#define SF_BUF_LEN   20

◆ SF_OFF

#define SF_OFF   33

◆ SF_ON

#define SF_ON   67

◆ VM_API_CALL

#define VM_API_CALL (   res,
  api_call,
  api_parms 
)

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

◆ VM_GREETER_API_CALL

#define VM_GREETER_API_CALL (   res,
  api_call,
  api_parms 
)

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

Enumeration Type Documentation

◆ control_tone_frame_response_result

Enumerator
CONTROL_TONE_RESPONSE_FAILED 
CONTROL_TONE_RESPONSE_NORMAL 
CONTROL_TONE_RESPONSE_FINISHED 

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

1480 {
1484};
@ CONTROL_TONE_RESPONSE_FAILED
Definition: main/app.c:1481
@ CONTROL_TONE_RESPONSE_NORMAL
Definition: main/app.c:1482
@ CONTROL_TONE_RESPONSE_FINISHED
Definition: main/app.c:1483

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

2357{
2358 int argc;
2359 char *scan, *wasdelim = NULL;
2360 int paren = 0, quote = 0, bracket = 0;
2361
2362 if (!array || !arraylen) {
2363 return 0;
2364 }
2365
2366 memset(array, 0, arraylen * sizeof(*array));
2367
2368 if (!buf) {
2369 return 0;
2370 }
2371
2372 scan = buf;
2373
2374 for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
2375 array[argc] = scan;
2376 for (; *scan; scan++) {
2377 if (*scan == '(') {
2378 paren++;
2379 } else if (*scan == ')') {
2380 if (paren) {
2381 paren--;
2382 }
2383 } else if (*scan == '[') {
2384 bracket++;
2385 } else if (*scan == ']') {
2386 if (bracket) {
2387 bracket--;
2388 }
2389 } else if (*scan == '"' && delim != '"') {
2390 quote = quote ? 0 : 1;
2391 if (remove_chars) {
2392 /* Remove quote character from argument */
2393 memmove(scan, scan + 1, strlen(scan));
2394 scan--;
2395 }
2396 } else if (*scan == '\\') {
2397 if (remove_chars) {
2398 /* Literal character, don't parse */
2399 memmove(scan, scan + 1, strlen(scan));
2400 } else {
2401 scan++;
2402 }
2403 } else if ((*scan == delim) && !paren && !quote && !bracket) {
2404 wasdelim = scan;
2405 *scan++ = '\0';
2406 break;
2407 }
2408 }
2409 }
2410
2411 /* If the last character in the original string was the delimiter, then
2412 * there is one additional argument. */
2413 if (*scan || (scan > buf && (scan - 1) == wasdelim)) {
2414 array[argc++] = scan;
2415 }
2416
2417 return argc;
2418}
#define paren
Definition: ael_lex.c:962
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
static int quote(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define NULL
Definition: resample.c:96

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

◆ __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.
if_exists
Return values
-1failure or hangup
'S'Recording ended from silence timeout
't'Recording ended from the message exceeding the maximum duration, or via DTMF in prepend mode
dtmfcharRecording ended via the return value's DTMF character for either cancel or accept.
Note
Instead of asking how much time passed (end - start), calculate the number of seconds of audio which actually went into the file. This fixes a problem where audio is stopped up on the network and never gets to us.

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

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

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

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

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_trace, 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(), maxsilence, NULL, PATH_MAX, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_read_to_slin(), silencethreshold, strsep(), ast_frame::subclass, and ast_dsp::totalsilence.

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

◆ __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 479 of file main/app.c.

480{
482
483 if (!vm_table->module_name) {
484 ast_log(LOG_ERROR, "Voicemail greeter provider missing required information.\n");
485 return -1;
486 }
488 ast_log(LOG_ERROR, "Voicemail greeter provider '%s' has incorrect version\n",
490 return -1;
491 }
492
493 table = ao2_global_obj_ref(vm_greeter_provider);
494 if (table) {
495 ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n",
496 table->module_name);
498 }
499
501 if (!table) {
502 return -1;
503 }
504 *table = *vm_table;
505 table->module = module;
506
507 ao2_global_obj_replace_unref(vm_greeter_provider, table);
508 return 0;
509}
static const struct ast_vm_functions vm_table
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static char * table
Definition: cdr_odbc.c:55
#define VM_GREETER_MODULE_VERSION
#define LOG_ERROR
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
unsigned int module_version
The version of this function table.
const char * module_name
The name of the module that provides the voicemail functionality.
Voicemail greeter function table definition.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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_functions::module_name, ast_vm_functions::module_version, NULL, RAII_VAR, table, VM_GREETER_MODULE_VERSION, and vm_table.

◆ __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 368 of file main/app.c.

369{
371
372 if (!vm_table->module_name) {
373 ast_log(LOG_ERROR, "Voicemail provider missing required information.\n");
374 return -1;
375 }
377 ast_log(LOG_ERROR, "Voicemail provider '%s' has incorrect version\n",
379 return -1;
380 }
381
382 table = ao2_global_obj_ref(vm_provider);
383 if (table) {
384 ast_log(LOG_WARNING, "Voicemail provider already registered by %s.\n",
385 table->module_name);
387 }
388
390 if (!table) {
391 return -1;
392 }
393 *table = *vm_table;
394 table->module = module;
395
397 return 0;
398}
#define VM_MODULE_VERSION
Voicemail function table definition.

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.

◆ AO2_GLOBAL_OBJ_STATIC() [1/2]

static AO2_GLOBAL_OBJ_STATIC ( vm_greeter_provider  )
static

The container for the voicemail greeter provider.

◆ AO2_GLOBAL_OBJ_STATIC() [2/2]

static AO2_GLOBAL_OBJ_STATIC ( vm_provider  )
static

The container for the voicemail provider.

◆ app_cleanup()

static void app_cleanup ( void  )
static

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

3355{
3356#ifdef HAS_CAP
3357 cap_free(child_cap);
3358#endif
3363}
static struct stasis_topic_pool * queue_topic_pool
Definition: main/app.c:91
static struct stasis_topic * queue_topic_all
Define Stasis Message Bus API topic objects.
Definition: main/app.c:90

References ao2_cleanup, NULL, queue_topic_all, and queue_topic_pool.

Referenced by app_init().

◆ app_init()

int app_init ( void  )

Initialize the application core.

Return values
0Success
-1Failure
Since
12

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

3366{
3368#ifdef HAVE_CAP
3369 child_cap = cap_from_text("cap_net_admin-eip");
3370#endif
3371 queue_topic_all = stasis_topic_create("queue:all");
3372 if (!queue_topic_all) {
3373 return -1;
3374 }
3376 if (!queue_topic_pool) {
3377 return -1;
3378 }
3379 return 0;
3380}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static void app_cleanup(void)
Definition: main/app.c:3354
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:618
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:1834

References app_cleanup(), ast_register_cleanup(), queue_topic_all, queue_topic_pool, stasis_topic_create(), and stasis_topic_pool_create().

Referenced by asterisk_daemon().

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

597{
598 int res = -1;
599
600 VM_API_CALL(res, copy_recording_to_vm, (vm_rec_data));
601 return res;
602}
#define VM_API_CALL(res, api_call, api_parms)
Definition: main/app.c:547

References VM_API_CALL.

Referenced by copy_to_voicemail().

◆ 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

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

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

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(), voicemailpwcheck::context, ast_tone_zone_sound::data, ast_pbx::dtimeoutms, LOG_NOTICE, NULL, and S_COR.

Referenced by grab_transfer().

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

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

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(), ignore_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(), eval_sub_read(), generic_recall(), originate_exec(), page_exec(), queue_exec(), run_app_helper(), and try_calling().

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

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

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

279{
280 const struct ast_app_stack_funcs *funcs;
281 const char *new_args;
282
283 funcs = app_stack_callbacks;
284 if (!funcs || !funcs->expand_sub_args || !ast_module_running_ref(funcs->module)) {
286 "Cannot expand 'Gosub(%s)' arguments. The app_stack module is not available.\n",
287 args);
288 return NULL;
289 }
290
291 new_args = funcs->expand_sub_args(chan, args);
292 ast_module_unref(funcs->module);
293
294 return new_args;
295}
const char *(* expand_sub_args)(struct ast_channel *chan, const char *args)
Add missing context/exten to Gosub application argument string.
const char * args

References app_stack_callbacks, args, 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().

◆ ast_app_getdata()

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

Plays a stream and gets DTMF data from a channel.

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

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

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

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

References ast_app_getdata_terminator(), c, NULL, and prompt.

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

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

248{
249 int res, to = 2000, fto = 6000;
250
251 if (!ast_strlen_zero(prompt)) {
253 if (res < 0) {
254 return res;
255 }
256 }
257
258 if (timeout > 0) {
259 fto = to = timeout;
260 }
261 if (timeout < 0) {
262 fto = to = 1000000000;
263 }
264
265 res = ast_readstring_full(c, s, maxlen, to, fto, "#", audiofd, ctrlfd);
266
267 return res;
268}
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:6582
const char * ast_channel_language(const struct ast_channel *chan)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1293
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_channel_language(), ast_readstring_full(), ast_streamfile(), ast_strlen_zero(), c, and prompt.

Referenced by handle_getdata().

◆ ast_app_getdata_terminator()

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

Plays a stream and gets DTMF data from a channel.

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

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

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

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

References ast_channel_language(), ast_channel_pbx(), AST_GETDATA_EMPTY_END_TERMINATED, ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, c, ast_pbx::dtimeoutms, prompt, and ast_pbx::rtimeoutms.

Referenced by ast_app_getdata(), and read_exec().

◆ ast_app_group_discard()

int ast_app_group_discard ( struct ast_channel chan)

Discard all group counting for a channel.

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

2320{
2321 struct ast_group_info *gi = NULL;
2322
2325 if (gi->chan == chan) {
2327 ast_free(gi);
2328 }
2329 }
2332
2333 return 0;
2334}
#define ast_free(a)
Definition: astmm.h:180
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
channel group info
Definition: channel.h:2961
struct ast_group_info::@210 group_list
struct ast_channel * chan
Definition: channel.h:2962

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().

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

2241{
2242 struct ast_group_info *gi = NULL;
2243 int count = 0;
2244
2245 if (ast_strlen_zero(group)) {
2246 return 0;
2247 }
2248
2251 if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
2252 count++;
2253 }
2254 }
2256
2257 return count;
2258}
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
char * category
Definition: channel.h:2963
char * group
Definition: channel.h:2964

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().

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

2347{
2348 return AST_RWLIST_FIRST(&groups);
2349}
#define AST_RWLIST_FIRST
Definition: linkedlists.h:423

References AST_RWLIST_FIRST.

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

◆ ast_app_group_list_rdlock()

int ast_app_group_list_rdlock ( void  )

Read Lock the group count list.

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

2342{
2343 return AST_RWLIST_RDLOCK(&groups);
2344}

References AST_RWLIST_RDLOCK.

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

◆ ast_app_group_list_unlock()

int ast_app_group_list_unlock ( void  )

Unlock the group count list.

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

2352{
2353 return AST_RWLIST_UNLOCK(&groups);
2354}

References AST_RWLIST_UNLOCK.

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

◆ ast_app_group_list_wrlock()

int ast_app_group_list_wrlock ( void  )

Write Lock the group count list.

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

2337{
2338 return AST_RWLIST_WRLOCK(&groups);
2339}

References AST_RWLIST_WRLOCK.

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

2261{
2262 struct ast_group_info *gi = NULL;
2263 regex_t regexbuf_group;
2264 regex_t regexbuf_category;
2265 int count = 0;
2266
2267 if (ast_strlen_zero(groupmatch)) {
2268 ast_log(LOG_NOTICE, "groupmatch empty\n");
2269 return 0;
2270 }
2271
2272 /* if regex compilation fails, return zero matches */
2273 if (regcomp(&regexbuf_group, groupmatch, REG_EXTENDED | REG_NOSUB)) {
2274 ast_log(LOG_ERROR, "Regex compile failed on: %s\n", groupmatch);
2275 return 0;
2276 }
2277
2278 if (!ast_strlen_zero(category) && regcomp(&regexbuf_category, category, REG_EXTENDED | REG_NOSUB)) {
2279 ast_log(LOG_ERROR, "Regex compile failed on: %s\n", category);
2280 regfree(&regexbuf_group);
2281 return 0;
2282 }
2283
2286 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)))) {
2287 count++;
2288 }
2289 }
2291
2292 regfree(&regexbuf_group);
2293 if (!ast_strlen_zero(category)) {
2294 regfree(&regexbuf_category);
2295 }
2296
2297 return count;
2298}

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().

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

2194{
2195 int res = 0;
2196 char group[80] = "", category[80] = "";
2197 struct ast_group_info *gi = NULL;
2198 size_t len = 0;
2199
2200 if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) {
2201 return -1;
2202 }
2203
2204 /* Calculate memory we will need if this is new */
2205 len = sizeof(*gi) + strlen(group) + 1;
2206 if (!ast_strlen_zero(category)) {
2207 len += strlen(category) + 1;
2208 }
2209
2212 if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
2214 ast_free(gi);
2215 break;
2216 }
2217 }
2219
2220 if (ast_strlen_zero(group)) {
2221 /* Enable unsetting the group */
2222 } else if ((gi = ast_calloc(1, len))) {
2223 gi->chan = chan;
2224 gi->group = (char *) gi + sizeof(*gi);
2225 strcpy(gi->group, group);
2226 if (!ast_strlen_zero(category)) {
2227 gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1;
2228 strcpy(gi->category, category);
2229 }
2231 } else {
2232 res = -1;
2233 }
2234
2236
2237 return res;
2238}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
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:2166

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().

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

2167{
2168 int res = 0;
2169 char tmp[256];
2170 char *grp = NULL, *cat = NULL;
2171
2172 if (!ast_strlen_zero(data)) {
2173 ast_copy_string(tmp, data, sizeof(tmp));
2174 grp = tmp;
2175 if ((cat = strchr(tmp, '@'))) {
2176 *cat++ = '\0';
2177 }
2178 }
2179
2180 if (!ast_strlen_zero(grp)) {
2181 ast_copy_string(group, grp, group_max);
2182 } else {
2183 *group = '\0';
2184 }
2185
2186 if (!ast_strlen_zero(cat)) {
2187 ast_copy_string(category, cat, category_max);
2188 }
2189
2190 return res;
2191}
static int tmp()
Definition: bt_open.c:389

References ast_copy_string(), ast_strlen_zero(), ast_frame::data, NULL, and tmp().

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

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

2301{
2302 struct ast_group_info *gi = NULL;
2303
2306 if (gi->chan == old) {
2307 gi->chan = new;
2308 } else if (gi->chan == new) {
2310 ast_free(gi);
2311 }
2312 }
2315
2316 return 0;
2317}

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().

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

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

References has_voicemail(), mailboxes, and VM_API_CALL.

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

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

605{
606 int res = 0;
607
608 if (newmsgs) {
609 *newmsgs = 0;
610 }
611 if (oldmsgs) {
612 *oldmsgs = 0;
613 }
614
615 VM_API_CALL(res, inboxcount, (mailboxes, newmsgs, oldmsgs));
616 return res;
617}
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)

References inboxcount(), mailboxes, and VM_API_CALL.

Referenced by update_registry().

◆ 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
Return values
0for success
negativeupon error
Since
1.6.1

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

620{
621 int res = 0;
622
623 if (newmsgs) {
624 *newmsgs = 0;
625 }
626 if (oldmsgs) {
627 *oldmsgs = 0;
628 }
629 if (urgentmsgs) {
630 *urgentmsgs = 0;
631 }
632
633 VM_API_CALL(res, inboxcount2, (mailboxes, urgentmsgs, newmsgs, oldmsgs));
634 return res;
635}
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Check the given mailbox's message count.

References inboxcount2(), mailboxes, and VM_API_CALL.

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

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

646{
647 int res = 0;
648
649 VM_API_CALL(res, messagecount, (mailbox_id, folder));
650 return res;
651}
static int messagecount(const char *mailbox_id, const char *folder)

References messagecount(), and VM_API_CALL.

Referenced by acf_vmcount_exec().

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

3077{
3078 unsigned int i, found = 0;
3079 for (i = 32; i < 128 && found < len; i++) {
3080 if (ast_test_flag64(flags, options[i].flag)) {
3081 buf[found++] = i;
3082 }
3083 }
3084 buf[found] = '\0';
3085}
long int flag
Definition: f2c.h:83
static struct test_options options
#define ast_test_flag64(p, flag)
Definition: utils.h:120

References ast_test_flag64, buf, ast_flags64::flags, len(), and options.

◆ 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
Return values
zerofor success
non-zeroif an error occurs
See also
AST_APP_OPTIONS

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

3067{
3068 return parse_options(options, flags, args, optstr, 32);
3069}
static int parse_options(const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
Definition: main/app.c:2983

References args, ast_flags64::flags, options, and parse_options().

Referenced by agent_login_exec(), app_exec(), aqm_exec(), ast_multicast_rtp_create_options(), AST_TEST_DEFINE(), audiosocket_request(), auth_exec(), bridge_exec(), bridgewait_exec(), broadcast_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(), geoloc_profile_read(), geoloc_profile_write(), handle_options(), hint_read(), json_decode_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(), senddtmf_exec(), sendfax_exec(), sla_trunk_exec(), smdi_msg_retrieve_read(), sms_exec(), softhangup_exec(), speech_background(), unicast_rtp_request(), vm_exec(), vm_execmain(), volume_write(), and wait_exec().

◆ 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
Return values
zerofor success
non-zeroif an error occurs
See also
AST_APP_OPTIONS

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

3072{
3073 return parse_options(options, flags, args, optstr, 64);
3074}

References args, ast_flags64::flags, options, and parse_options().

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

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

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

References FMT, result, 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().

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

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

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

Referenced by ast_channel_connected_line_sub(), and ast_channel_redirecting_sub().

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

638{
639 int res = -1;
640
641 VM_GREETER_API_CALL(res, sayname, (chan, mailbox_id));
642 return res;
643}
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:568

References sayname(), and VM_GREETER_API_CALL.

Referenced by play_mailbox_owner(), and spy_sayname().

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

3203{
3204 closefrom(n + 1);
3205}
void closefrom(int lowfd)

References closefrom().

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

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

1469{
1470 return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, NULL);
1471}
unsigned int stop
Definition: app_sla.c:336
static int skipms
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3160
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:1277

References control_streamfile(), make_ari_stubs::file, NULL, skipms, stop, and suspend().

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

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

1476{
1477 return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, lang, NULL);
1478}

References control_streamfile(), make_ari_stubs::file, NULL, skipms, stop, and suspend().

Referenced by play_on_channel().

◆ 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 occurs.

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

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

1461{
1462 return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, cb);
1463}

References control_streamfile(), make_ari_stubs::file, NULL, skipms, stop, and suspend().

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

1546{
1547 struct ast_tone_zone *zone = NULL;
1548 struct ast_tone_zone_sound *ts;
1549 int paused = 0;
1550 int res = 0;
1551
1552 const char *tone_indication = NULL;
1553 const char *tone_zone = NULL;
1554 char *tone_uri_parser;
1555
1556 if (ast_strlen_zero(tone)) {
1557 return -1;
1558 }
1559
1560 tone_uri_parser = ast_strdupa(tone);
1561
1562 if (parse_tone_uri(tone_uri_parser, &tone_indication, &tone_zone)) {
1563 return -1;
1564 }
1565
1566 if (tone_zone) {
1567 zone = ast_get_indication_zone(tone_zone);
1568 }
1569
1570 ts = ast_get_indication_tone(zone ? zone : ast_channel_zone(chan), tone_indication);
1571
1572 if (ast_playtones_start(chan, 0, ts ? ts->data : tone_indication, 0)) {
1573 res = -1;
1574 }
1575
1576 while (!res) {
1577 struct ast_frame *fr;
1578
1579 if (ast_waitfor(chan, -1) < 0) {
1580 res = -1;
1581 break;
1582 }
1583
1584 fr = ast_read_noaudio(chan);
1585
1586 if (!fr) {
1587 res = -1;
1588 break;
1589 }
1590
1591 if (fr->frametype != AST_FRAME_CONTROL) {
1592 continue;
1593 }
1594
1595 res = control_tone_frame_response(chan, fr, ts, tone_indication, &paused);
1596 if (res == CONTROL_TONE_RESPONSE_FINISHED) {
1597 res = 0;
1598 break;
1599 } else if (res == CONTROL_TONE_RESPONSE_FAILED) {
1600 res = -1;
1601 break;
1602 }
1603 }
1604
1605 if (ts) {
1607 }
1608
1609 if (zone) {
1610 ast_tone_zone_unref(zone);
1611 }
1612
1613 return res;
1614}
struct ast_frame * ast_read_noaudio(struct ast_channel *chan)
Reads a frame, returning AST_FRAME_NULL frame if audio.
Definition: channel.c:4286
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
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone
Definition: indications.c:439
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:1486
static int parse_tone_uri(char *tone_parser, const char **tone_indication, const char **tone_zone)
Definition: main/app.c:1524
A set of tones for a given locale.
Definition: indications.h:74

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, parse_tone_uri(), and ast_frame::ts.

Referenced by play_on_channel().

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

1128{
1129 int res;
1130
1131 if (peer && ast_autoservice_start(peer)) {
1132 return -1;
1133 }
1134 res = dtmf_stream(chan, digits, between, duration, 0);
1135 if (peer && ast_autoservice_stop(peer)) {
1136 res = -1;
1137 }
1138
1139 return res;
1140}
static int dtmf_stream(struct ast_channel *chan, const char *digits, int between, unsigned int duration, int is_external)
Definition: main/app.c:1029

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(), senddtmf_exec(), testclient_exec(), testserver_exec(), and wait_for_answer().

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

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

1143{
1144 dtmf_stream(chan, digits, between, duration, 1);
1145}

References dtmf_stream().

Referenced by dtmf_in_bridge().

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

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

References ast_debug, ast_log, ast_strlen_zero(), LOG_ERROR, and result.

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().

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

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

References ast_get_encoded_char(), and result.

Referenced by chan_pjsip_new(), listfilter(), and replace().

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

274{
275 app_stack_callbacks = funcs;
276}

References app_stack_callbacks.

Referenced by load_module(), and unload_module().

◆ ast_ivr_menu_run()

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

Runs an IVR menu.

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

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

2943{
2944 int res = ast_ivr_menu_run_internal(chan, menu, cbdata);
2945 /* Hide internal coding */
2946 return res > 0 ? 0 : res;
2947}
static int ast_ivr_menu_run_internal(struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
Definition: main/app.c:2857

References ast_ivr_menu_run_internal().

Referenced by skel_exec().

◆ ast_ivr_menu_run_internal()

static int ast_ivr_menu_run_internal ( struct ast_channel chan,
struct ast_ivr_menu menu,
void *  cbdata 
)
static

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

2858{
2859 /* Execute an IVR menu structure */
2860 int res = 0;
2861 int pos = 0;
2862 int retries = 0;
2863 char exten[AST_MAX_EXTENSION] = "s";
2864 if (option_exists(menu, "s") < 0) {
2865 strcpy(exten, "g");
2866 if (option_exists(menu, "g") < 0) {
2867 ast_log(LOG_WARNING, "No 's' nor 'g' extension in menu '%s'!\n", menu->title);
2868 return -1;
2869 }
2870 }
2871 while (!res) {
2872 while (menu->options[pos].option) {
2873 if (!strcasecmp(menu->options[pos].option, exten)) {
2874 res = ivr_dispatch(chan, menu->options + pos, exten, cbdata);
2875 ast_debug(1, "IVR Dispatch of '%s' (pos %d) yields %d\n", exten, pos, res);
2876 if (res < 0) {
2877 break;
2878 } else if (res & RES_UPONE) {
2879 return 0;
2880 } else if (res & RES_EXIT) {
2881 return res;
2882 } else if (res & RES_REPEAT) {
2883 int maxretries = res & 0xffff;
2884 if ((res & RES_RESTART) == RES_RESTART) {
2885 retries = 0;
2886 } else {
2887 retries++;
2888 }
2889 if (!maxretries) {
2890 maxretries = 3;
2891 }
2892 if ((maxretries > 0) && (retries >= maxretries)) {
2893 ast_debug(1, "Max retries %d exceeded\n", maxretries);
2894 return -2;
2895 } else {
2896 if (option_exists(menu, "g") > -1) {
2897 strcpy(exten, "g");
2898 } else if (option_exists(menu, "s") > -1) {
2899 strcpy(exten, "s");
2900 }
2901 }
2902 pos = 0;
2903 continue;
2904 } else if (res && strchr(AST_DIGIT_ANY, res)) {
2905 ast_debug(1, "Got start of extension, %c\n", res);
2906 exten[1] = '\0';
2907 exten[0] = res;
2908 if ((res = read_newoption(chan, menu, exten, sizeof(exten)))) {
2909 break;
2910 }
2911 if (option_exists(menu, exten) < 0) {
2912 if (option_exists(menu, "i")) {
2913 ast_debug(1, "Invalid extension entered, going to 'i'!\n");
2914 strcpy(exten, "i");
2915 pos = 0;
2916 continue;
2917 } else {
2918 ast_debug(1, "Aborting on invalid entry, with no 'i' option!\n");
2919 res = -2;
2920 break;
2921 }
2922 } else {
2923 ast_debug(1, "New existing extension: %s\n", exten);
2924 pos = 0;
2925 continue;
2926 }
2927 }
2928 }
2929 pos++;
2930 }
2931 ast_debug(1, "Stopping option '%s', res is %d\n", exten, res);
2932 pos = 0;
2933 if (!strcasecmp(exten, "s")) {
2934 strcpy(exten, "g");
2935 } else {
2936 break;
2937 }
2938 }
2939 return res;
2940}
#define AST_MAX_EXTENSION
Definition: channel.h:134
#define AST_DIGIT_ANY
Definition: file.h:48
static int option_exists(struct ast_ivr_menu *menu, char *option)
Definition: main/app.c:2816
static int read_newoption(struct ast_channel *chan, struct ast_ivr_menu *menu, char *exten, int maxexten)
Definition: main/app.c:2839
#define RES_UPONE
Definition: main/app.c:2740
#define RES_EXIT
Definition: main/app.c:2741
#define RES_REPEAT
Definition: main/app.c:2742
static int ivr_dispatch(struct ast_channel *chan, struct ast_ivr_option *option, char *exten, void *cbdata)
Definition: main/app.c:2747
#define RES_RESTART
Definition: main/app.c:2743
static int maxretries
Definition: res_adsi.c:60
struct ast_ivr_option * options

References ast_debug, AST_DIGIT_ANY, ast_log, AST_MAX_EXTENSION, ast_channel::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().

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

1236{
1237 struct linear_state *lin;
1238 char tmpf[256];
1239 int autoclose = 0;
1240
1241 if (fd < 0) {
1242 if (ast_strlen_zero(filename)) {
1243 return -1;
1244 }
1245
1246 autoclose = 1;
1247
1248 if (filename[0] == '/') {
1249 ast_copy_string(tmpf, filename, sizeof(tmpf));
1250 } else {
1251 snprintf(tmpf, sizeof(tmpf), "%s/%s/%s", ast_config_AST_DATA_DIR, "sounds", filename);
1252 }
1253
1254 fd = open(tmpf, O_RDONLY);
1255 if (fd < 0) {
1256 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", tmpf, strerror(errno));
1257 return -1;
1258 }
1259 }
1260
1261 lin = ast_calloc(1, sizeof(*lin));
1262 if (!lin) {
1263 if (autoclose) {
1264 close(fd);
1265 }
1266
1267 return -1;
1268 }
1269
1270 lin->fd = fd;
1272 lin->autoclose = autoclose;
1273
1274 return ast_activate_generator(chan, &linearstream, lin);
1275}
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
Definition: channel.c:2970
static struct ast_generator linearstream
Definition: main/app.c:1228
int errno
const char * ast_config_AST_DATA_DIR
Definition: options.c:158
int allowoverride
Definition: main/app.c:1150

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, linearstream, and LOG_WARNING.

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

2615{
2617
2618 switch (ast_lock_type) {
2620 r = ast_lock_path_lockfile(path);
2621 break;
2623 r = ast_lock_path_flock(path);
2624 break;
2625 }
2626
2627 return r;
2628}
ast_lock_type
Definition: check_expr.c:35
@ AST_LOCK_FAILURE
@ AST_LOCK_TYPE_LOCKFILE
@ AST_LOCK_TYPE_FLOCK
static enum AST_LOCK_RESULT ast_lock_path_lockfile(const char *path)
Definition: main/app.c:2420
static enum AST_LOCK_RESULT ast_lock_path_flock(const char *path)
Definition: main/app.c:2494

References AST_LOCK_FAILURE, ast_lock_path_flock(), ast_lock_path_lockfile(), AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, and path_lock::path.

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

◆ ast_lock_path_flock()

static enum AST_LOCK_RESULT ast_lock_path_flock ( const char *  path)
static

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

2495{
2496 char *fs;
2497 int res;
2498 int fd;
2499 time_t start;
2500 struct path_lock *pl;
2501 struct stat st, ost;
2502
2503 fs = ast_alloca(strlen(path) + 20);
2504
2505 snprintf(fs, strlen(path) + 19, "%s/lock", path);
2506 if (lstat(fs, &st) == 0) {
2507 if ((st.st_mode & S_IFMT) == S_IFLNK) {
2508 ast_log(LOG_WARNING, "Unable to create lock file "
2509 "'%s': it's already a symbolic link\n",
2510 fs);
2511 return AST_LOCK_FAILURE;
2512 }
2513 if (st.st_nlink > 1) {
2514 ast_log(LOG_WARNING, "Unable to create lock file "
2515 "'%s': %u hard links exist\n",
2516 fs, (unsigned int) st.st_nlink);
2517 return AST_LOCK_FAILURE;
2518 }
2519 }
2520 if ((fd = open(fs, O_WRONLY | O_CREAT, 0600)) < 0) {
2521 ast_log(LOG_WARNING, "Unable to create lock file '%s': %s\n",
2522 fs, strerror(errno));
2524 }
2525 if (!(pl = ast_calloc(1, sizeof(*pl)))) {
2526 /* We don't unlink the lock file here, on the possibility that
2527 * someone else created it - better to leave a little mess
2528 * than create a big one by destroying someone else's lock
2529 * and causing something to be corrupted.
2530 */
2531 close(fd);
2532 return AST_LOCK_FAILURE;
2533 }
2534 pl->fd = fd;
2535 pl->path = ast_strdup(path);
2536
2537 time(&start);
2538 while (
2539 #ifdef SOLARIS
2540 ((res = fcntl(pl->fd, F_SETLK, fcntl(pl->fd, F_GETFL) | O_NONBLOCK)) < 0) &&
2541 #else
2542 ((res = flock(pl->fd, LOCK_EX | LOCK_NB)) < 0) &&
2543 #endif
2544 (errno == EWOULDBLOCK) &&
2545 (time(NULL) - start < 5))
2546 usleep(1000);
2547 if (res) {
2548 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n",
2549 path, strerror(errno));
2550 /* No unlinking of lock done, since we tried and failed to
2551 * flock() it.
2552 */
2554 return AST_LOCK_TIMEOUT;
2555 }
2556
2557 /* Check for the race where the file is recreated or deleted out from
2558 * underneath us.
2559 */
2560 if (lstat(fs, &st) != 0 && fstat(pl->fd, &ost) != 0 &&
2561 st.st_dev != ost.st_dev &&
2562 st.st_ino != ost.st_ino) {
2563 ast_log(LOG_WARNING, "Unable to create lock file '%s': "
2564 "file changed underneath us\n", fs);
2566 return AST_LOCK_FAILURE;
2567 }
2568
2569 /* Success: file created, flocked, and is the one we started with */
2573
2574 ast_debug(1, "Locked path '%s'\n", path);
2575
2576 return AST_LOCK_SUCCESS;
2577}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
@ AST_LOCK_SUCCESS
@ AST_LOCK_PATH_NOT_FOUND
@ AST_LOCK_TIMEOUT
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:40
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
static void path_lock_destroy(struct path_lock *obj)
Definition: main/app.c:2483
char * path
Definition: main/app.c:2478

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().

◆ ast_lock_path_lockfile()

static enum AST_LOCK_RESULT ast_lock_path_lockfile ( const char *  path)
static

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

2421{
2422 char *s;
2423 char *fs;
2424 int res;
2425 int fd;
2426 int lp = strlen(path);
2427 time_t start;
2428
2429 s = ast_alloca(lp + 10);
2430 fs = ast_alloca(lp + 20);
2431
2432 snprintf(fs, strlen(path) + 19, "%s/.lock-%08lx", path, (unsigned long)ast_random());
2433 fd = open(fs, O_WRONLY | O_CREAT | O_EXCL, AST_FILE_MODE);
2434 if (fd < 0) {
2435 ast_log(LOG_ERROR, "Unable to create lock file '%s': %s\n", path, strerror(errno));
2437 }
2438 close(fd);
2439
2440 snprintf(s, strlen(path) + 9, "%s/.lock", path);
2441 start = time(NULL);
2442 while (((res = link(fs, s)) < 0) && (errno == EEXIST) && (time(NULL) - start < 5)) {
2443 sched_yield();
2444 }
2445
2446 unlink(fs);
2447
2448 if (res) {
2449 ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
2450 return AST_LOCK_TIMEOUT;
2451 } else {
2452 ast_debug(1, "Locked path '%s'\n", path);
2453 return AST_LOCK_SUCCESS;
2454 }
2455}
long int ast_random(void)
Definition: utils.c:2312

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().

◆ ast_mf_stream()

int ast_mf_stream ( struct ast_channel chan,
struct ast_channel peer,
struct ast_channel chan2,
const char *  digits,
int  between,
unsigned int  duration,
unsigned int  durationkp,
unsigned int  durationst,
int  is_external 
)

Send a string of MF digits to a channel.

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

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

1115{
1116 int res;
1117 if (!is_external && !chan2 && peer && ast_autoservice_start(peer)) {
1118 return -1;
1119 }
1120 res = mf_stream(chan, chan2, digits, between, duration, durationkp, durationst, is_external);
1121 if (!is_external && !chan2 && peer && ast_autoservice_stop(peer)) {
1122 res = -1;
1123 }
1124 return res;
1125}
static int mf_stream(struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Definition: main/app.c:914

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

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

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

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

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

Referenced by vm_forwardoptions().

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

2155{
2156 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, default_acceptdtmf, default_canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
2157}

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

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

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

2150{
2151 return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, ""), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists);
2152}
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80

References __ast_play_and_record(), default_canceldtmf, maxsilence, S_OR, and silencethreshold.

Referenced by play_record_review(), and record_file().

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

1617{
1618 int d = 0;
1619
1620 if ((d = ast_streamfile(chan, fn, ast_channel_language(chan)))) {
1621 return d;
1622 }
1623
1625
1626 ast_stopstream(chan);
1627
1628 return d;
1629}
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1840

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(), 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_da(), 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().

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

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

3350{
3352}
struct stasis_topic * stasis_topic_pool_get_topic(struct stasis_topic_pool *pool, const char *topic_name)
Find or create a topic in the pool.
Definition: stasis.c:1885

References queue_topic_pool, and stasis_topic_pool_get_topic().

Referenced by send_agent_complete().

◆ ast_queue_topic_all()

struct stasis_topic * ast_queue_topic_all ( void  )

Get the Stasis Message Bus API topic for queue messages.

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

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

3345{
3346 return queue_topic_all;
3347}

References queue_topic_all.

Referenced by load_module().

◆ ast_read_textfile()

char * ast_read_textfile ( const char *  filename)

Read a file into asterisk.

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

2950{
2951 int fd, count = 0, res;
2952 char *output = NULL;
2953 struct stat filesize;
2954
2955 if (stat(filename, &filesize) == -1) {
2956 ast_log(LOG_WARNING, "Error can't stat %s\n", filename);
2957 return NULL;
2958 }
2959
2960 count = filesize.st_size + 1;
2961
2962 if ((fd = open(filename, O_RDONLY)) < 0) {
2963 ast_log(LOG_WARNING, "Cannot open file '%s' for reading: %s\n", filename, strerror(errno));
2964 return NULL;
2965 }
2966
2967 if ((output = ast_malloc(count))) {
2968 res = read(fd, output, count - 1);
2969 if (res == count - 1) {
2970 output[res] = '\0';
2971 } else {
2972 ast_log(LOG_WARNING, "Short read of %s (%d of %d): %s\n", filename, res, count - 1, strerror(errno));
2973 ast_free(output);
2974 output = NULL;
2975 }
2976 }
2977
2978 close(fd);
2979
2980 return output;
2981}

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

Referenced by ast_tcptls_server_start().

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

2647{
2648 int silencethreshold;
2649 int maxsilence = 0;
2650 int res = 0;
2651 int cmd = 0;
2652 int max_attempts = 3;
2653 int attempts = 0;
2654 int recorded = 0;
2655 int message_exists = 0;
2656 /* Note that urgent and private are for flagging messages as such in the future */
2657
2658 /* barf if no pointer passed to store duration in */
2659 if (!duration) {
2660 ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n");
2661 return -1;
2662 }
2663
2664 cmd = '3'; /* Want to start by recording */
2665
2667
2668 while ((cmd >= 0) && (cmd != 't')) {
2669 switch (cmd) {
2670 case '1':
2671 if (!message_exists) {
2672 /* In this case, 1 is to record a message */
2673 cmd = '3';
2674 break;
2675 } else {
2676 ast_stream_and_wait(chan, "vm-msgsaved", "");
2677 cmd = 't';
2678 return res;
2679 }
2680 case '2':
2681 /* Review */
2682 ast_verb(3, "Reviewing the recording\n");
2683 cmd = ast_stream_and_wait(chan, recordfile, AST_DIGIT_ANY);
2684 break;
2685 case '3':
2686 message_exists = 0;
2687 /* Record */
2688 ast_verb(3, "R%secording\n", recorded == 1 ? "e-r" : "");
2689 recorded = 1;
2690 if ((cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, NULL, silencethreshold, maxsilence, path)) == -1) {
2691 /* User has hung up, no options to give */
2692 return cmd;
2693 }
2694 if (cmd == '0') {
2695 break;
2696 } else if (cmd == '*') {
2697 break;
2698 } else {
2699 /* If all is well, a message exists */
2700 message_exists = 1;
2701 cmd = 0;
2702 }
2703 break;
2704 case '4':
2705 case '5':
2706 case '6':
2707 case '7':
2708 case '8':
2709 case '9':
2710 case '*':
2711 case '#':
2712 cmd = ast_play_and_wait(chan, "vm-sorry");
2713 break;
2714 default:
2715 if (message_exists) {
2716 cmd = ast_play_and_wait(chan, "vm-review");
2717 } else {
2718 if (!(cmd = ast_play_and_wait(chan, "vm-torerecord"))) {
2719 cmd = ast_waitfordigit(chan, 600);
2720 }
2721 }
2722
2723 if (!cmd) {
2724 cmd = ast_waitfordigit(chan, 6000);
2725 }
2726 if (!cmd) {
2727 attempts++;
2728 }
2729 if (attempts > max_attempts) {
2730 cmd = 't';
2731 }
2732 }
2733 }
2734 if (cmd == 't') {
2735 cmd = 0;
2736 }
2737 return cmd;
2738}
@ THRESHOLD_SILENCE
Definition: dsp.h:73
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:2009
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:2154

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, path_lock::path, silencethreshold, and THRESHOLD_SILENCE.

Referenced by conf_rec_name(), and conf_run().

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

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

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(), 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(), launch_script(), mp3play(), send_waveform_to_fd(), spawn_mp3(), and vm_check_password_shell().

◆ ast_safe_fork_cleanup()

void ast_safe_fork_cleanup ( void  )

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

Note
This must not be called unless ast_safe_fork(1) has been called previously.
Since
1.6.1

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

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

References ast_unreplace_sigchld().

Referenced by agi_exec_full().

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

2610{
2612}
static const char type[]
Definition: chan_ooh323.c:109

References type.

Referenced by load_asterisk_conf().

◆ ast_sf_stream()

int ast_sf_stream ( struct ast_channel chan,
struct ast_channel peer,
struct ast_channel chan2,
const char *  digits,
int  frequency,
int  is_external 
)

Send a string of SF digits to a channel.

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

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

1098{
1099 int res;
1100 if (frequency <= 0) {
1101 frequency = 2600;
1102 }
1103 if (!is_external && !chan2 && peer && ast_autoservice_start(peer)) {
1104 return -1;
1105 }
1106 res = sf_stream(chan, chan2, digits, frequency, is_external);
1107 if (!is_external && !chan2 && peer && ast_autoservice_stop(peer)) {
1108 res = -1;
1109 }
1110 return res;
1111}
static int sf_stream(struct ast_channel *chan, struct ast_channel *chan2, const char *digits, int frequency, int is_external)
Definition: main/app.c:763

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

Referenced by sendsf_exec(), and wait_for_answer().

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

3176{
3177 char next, *buf;
3178 size_t offset = 0;
3179 size_t consumed;
3180
3181 if (strchr(stream, '\\')) {
3182 while (!ast_get_encoded_char(stream, &next, &consumed)) {
3183 if (offset + 2 > ast_str_size(*str) && maxlen > -1) {
3184 ast_str_make_space(str, maxlen > 0 ? maxlen : (ast_str_size(*str) + 48) * 2 - 48);
3185 }
3186 if (offset + 2 > ast_str_size(*str)) {
3187 break;
3188 }
3190 buf[offset++] = next;
3191 stream += consumed;
3192 }
3194 buf[offset++] = '\0';
3196 } else {
3197 ast_str_set(str, maxlen, "%s", stream);
3198 }
3199 return 0;
3200}
const char * str
Definition: app_jack.c:147
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:1113
#define ast_str_make_space(buf, new_len)
Definition: strings.h:828
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:703
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:742

References ast_get_encoded_char(), ast_str_buffer(), ast_str_make_space, ast_str_set(), ast_str_size(), ast_str_update(), buf, and str.

Referenced by sendtext_exec(), and system_exec_helper().

◆ AST_THREADSTORAGE_PUBLIC()

AST_THREADSTORAGE_PUBLIC ( ast_str_thread_global_buf  )

◆ ast_unlock_path()

int ast_unlock_path ( const char *  path)

Unlock a path.

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

2631{
2632 int r = 0;
2633
2634 switch (ast_lock_type) {
2636 r = ast_unlock_path_lockfile(path);
2637 break;
2639 r = ast_unlock_path_flock(path);
2640 break;
2641 }
2642
2643 return r;
2644}
static int ast_unlock_path_flock(const char *path)
Definition: main/app.c:2579
static int ast_unlock_path_lockfile(const char *path)
Definition: main/app.c:2457

References AST_LOCK_TYPE_FLOCK, AST_LOCK_TYPE_LOCKFILE, ast_unlock_path_flock(), ast_unlock_path_lockfile(), and path_lock::path.

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().

◆ ast_unlock_path_flock()

static int ast_unlock_path_flock ( const char *  path)
static

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

2580{
2581 char *s;
2582 struct path_lock *p;
2583
2584 s = ast_alloca(strlen(path) + 20);
2585
2588 if (!strcmp(p->path, path)) {
2590 break;
2591 }
2592 }
2595
2596 if (p) {
2597 snprintf(s, strlen(path) + 19, "%s/lock", path);
2598 unlink(s);
2600 ast_debug(1, "Unlocked path '%s'\n", path);
2601 } else {
2602 ast_debug(1, "Failed to unlock path '%s': "
2603 "lock not found\n", path);
2604 }
2605
2606 return 0;
2607}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
struct path_lock::@294 le

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().

◆ ast_unlock_path_lockfile()

static int ast_unlock_path_lockfile ( const char *  path)
static

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

2458{
2459 char *s;
2460 int res;
2461
2462 s = ast_alloca(strlen(path) + 10);
2463
2464 snprintf(s, strlen(path) + 9, "%s/%s", path, ".lock");
2465
2466 if ((res = unlink(s))) {
2467 ast_log(LOG_ERROR, "Could not unlock path '%s': %s\n", path, strerror(errno));
2468 } else {
2469 ast_debug(1, "Unlocked path '%s'\n", path);
2470 }
2471
2472 return res;
2473}

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

Referenced by ast_unlock_path().

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

469{
471 int is_registered;
472
473 table = ao2_global_obj_ref(vm_greeter_provider);
474 is_registered = table ? 1 : 0;
476 return is_registered;
477}

References ao2_cleanup, ao2_global_obj_ref, and table.

◆ ast_vm_greeter_unregister()

void ast_vm_greeter_unregister ( const char *  module_name)

Unregister the specified voicemail greeter provider.

Since
13.0.0
Parameters
module_nameThe module name of the provider to unregister

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

512{
514
515 table = ao2_global_obj_ref(vm_greeter_provider);
516 if (table && !strcmp(table->module_name, module_name)) {
517 ao2_global_obj_release(vm_greeter_provider);
518 }
520}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
const char * module_name
The name of the module that provides the voicemail greeter functionality.

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

Referenced by unload_module().

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

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

References NULL, and VM_API_CALL.

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

358{
359 struct ast_vm_functions *table;
360 int is_registered;
361
362 table = ao2_global_obj_ref(vm_provider);
363 is_registered = table ? 1 : 0;
365 return is_registered;
366}

References ao2_cleanup, ao2_global_obj_ref, and table.

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

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

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

References voicemailpwcheck::context, voicemailpwcheck::mailbox, NULL, and VM_API_CALL.

Referenced by append_vmbox_info_astman(), complete_voicemail_move_message(), show_mailbox_snapshot(), and test_vm_api_remove_all_messages().

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

676{
677 struct ast_vm_mailbox_snapshot *res = NULL;
678
679 VM_API_CALL(res, mailbox_snapshot_destroy, (mailbox_snapshot));
680 return res;
681}

References NULL, and VM_API_CALL.

Referenced by append_vmbox_info_astman(), AST_TEST_DEFINE(), complete_voicemail_move_message(), show_mailbox_snapshot(), and test_vm_api_remove_all_messages().

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

718{
719 int res = 0;
720
721 VM_API_CALL(res, msg_forward, (from_mailbox, from_context, from_folder, to_mailbox,
722 to_context, to_folder, num_msgs, msg_ids, delete_old));
723 return res;
724}
def from_mailbox(key, val, section, pjsip, nmapped)

References sip_to_pjsip::from_mailbox(), and VM_API_CALL.

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

689{
690 int res = 0;
691
692 VM_API_CALL(res, msg_move, (mailbox, context, num_msgs, oldfolder, old_msg_ids,
693 newfolder));
694 return res;
695}

References voicemailpwcheck::context, voicemailpwcheck::mailbox, and VM_API_CALL.

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

732{
733 int res = 0;
734
735 VM_API_CALL(res, msg_play, (chan, mailbox, context, folder, msg_num, cb));
736 return res;
737}

References voicemailpwcheck::context, voicemailpwcheck::mailbox, and VM_API_CALL.

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

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

References voicemailpwcheck::context, voicemailpwcheck::mailbox, and VM_API_CALL.

◆ ast_vm_unregister()

void ast_vm_unregister ( const char *  module_name)

Unregister the specified voicemail provider.

Parameters
module_nameThe module name of the provider to unregister

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

401{
402 struct ast_vm_functions *table;
403
404 table = ao2_global_obj_ref(vm_provider);
405 if (table && !strcmp(table->module_name, module_name)) {
406 ao2_global_obj_release(vm_provider);
407 }
409}

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

Referenced by unload_module().

◆ 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

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

1288{
1289 char *breaks = NULL;
1290 char *end = NULL;
1291 int blen = 2;
1292 int res;
1293 long pause_restart_point = 0;
1294 long offset = 0;
1295 struct ast_silence_generator *silgen = NULL;
1296
1297 if (!file) {
1298 return -1;
1299 }
1300 if (offsetms) {
1301 offset = *offsetms * 8; /* XXX Assumes 8kHz */
1302 }
1303 if (lang == NULL) {
1304 lang = ast_channel_language(chan);
1305 }
1306
1307 if (stop) {
1308 blen += strlen(stop);
1309 }
1310 if (suspend) {
1311 blen += strlen(suspend);
1312 }
1313 if (restart) {
1314 blen += strlen(restart);
1315 }
1316
1317 if (blen > 2) {
1318 breaks = ast_alloca(blen + 1);
1319 breaks[0] = '\0';
1320 if (stop) {
1321 strcat(breaks, stop);
1322 }
1323 if (suspend) {
1324 strcat(breaks, suspend);
1325 }
1326 if (restart) {
1327 strcat(breaks, restart);
1328 }
1329 }
1330
1331 if ((end = strchr(file, ':'))) {
1332 if (!strcasecmp(end, ":end")) {
1333 *end = '\0';
1334 end++;
1335 } else {
1336 end = NULL;
1337 }
1338 }
1339
1340 for (;;) {
1341 ast_stopstream(chan);
1342 res = ast_streamfile(chan, file, lang);
1343 if (!res) {
1344 if (pause_restart_point) {
1345 ast_seekstream(ast_channel_stream(chan), pause_restart_point, SEEK_SET);
1346 pause_restart_point = 0;
1347 }
1348 else if (end || offset < 0) {
1349 if (offset == -8) {
1350 offset = 0;
1351 }
1352 ast_verb(3, "ControlPlayback seek to offset %ld from end\n", offset);
1353
1354 ast_seekstream(ast_channel_stream(chan), offset, SEEK_END);
1355 end = NULL;
1356 offset = 0;
1357 } else if (offset) {
1358 ast_verb(3, "ControlPlayback seek to offset %ld\n", offset);
1359 ast_seekstream(ast_channel_stream(chan), offset, SEEK_SET);
1360 offset = 0;
1361 }
1362 if (cb) {
1363 res = ast_waitstream_fr_w_cb(chan, breaks, fwd, rev, skipms, cb);
1364 } else {
1365 res = ast_waitstream_fr(chan, breaks, fwd, rev, skipms);
1366 }
1367 }
1368
1369 if (res < 1) {
1370 break;
1371 }
1372
1373 /* We go at next loop if we got the restart char */
1374 if ((restart && strchr(restart, res)) || res == AST_CONTROL_STREAM_RESTART) {
1375 ast_debug(1, "we'll restart the stream here at next loop\n");
1376 pause_restart_point = 0;
1377 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1378 "Control: %s\r\n",
1379 ast_channel_name(chan),
1380 "Restart");
1381 continue;
1382 }
1383
1384 if ((suspend && strchr(suspend, res)) || res == AST_CONTROL_STREAM_SUSPEND) {
1385 pause_restart_point = ast_tellstream(ast_channel_stream(chan));
1386
1389 }
1390 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1391 "Control: %s\r\n",
1392 ast_channel_name(chan),
1393 "Pause");
1394 for (;;) {
1395 ast_stopstream(chan);
1396 if (!(res = ast_waitfordigit(chan, 1000))) {
1397 continue;
1398 } else if (res == -1 || (suspend && strchr(suspend, res)) || (stop && strchr(stop, res))
1400 break;
1401 }
1402 }
1403 if (silgen) {
1405 silgen = NULL;
1406 }
1407
1408 if ((suspend && (res == *suspend)) || res == AST_CONTROL_STREAM_SUSPEND) {
1409 res = 0;
1410 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1411 "Control: %s\r\n",
1412 ast_channel_name(chan),
1413 "Unpause");
1414 continue;
1415 }
1416 }
1417
1418 if (res == -1) {
1419 break;
1420 }
1421
1422 /* if we get one of our stop chars, return it to the calling function */
1423 if ((stop && strchr(stop, res)) || res == AST_CONTROL_STREAM_STOP) {
1424 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1425 "Control: %s\r\n",
1426 ast_channel_name(chan),
1427 "Stop");
1428 break;
1429 }
1430 }
1431
1432 if (pause_restart_point) {
1433 offset = pause_restart_point;
1434 } else {
1435 if (ast_channel_stream(chan)) {
1436 offset = ast_tellstream(ast_channel_stream(chan));
1437 } else {
1438 offset = -8; /* indicate end of file */
1439 }
1440 }
1441
1442 if (offsetms) {
1443 *offsetms = offset / 8; /* samples --> ms ... XXX Assumes 8 kHz */
1444 }
1445
1446 ast_stopstream(chan);
1447
1448 return res;
1449}
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
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:1798
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
Definition: file.c:1075
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:1809
@ AST_CONTROL_STREAM_RESTART
@ AST_CONTROL_STREAM_SUSPEND
@ AST_CONTROL_STREAM_STOP
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189

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, make_ari_stubs::file, NULL, skipms, stop, and suspend().

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

◆ 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

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

1487{
1488 switch (fr->subclass.integer) {
1490 ast_playtones_stop(chan);
1493 if (*paused) {
1494 *paused = 0;
1495 if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1497 }
1498 } else {
1499 *paused = 1;
1500 ast_playtones_stop(chan);
1501 }
1504 ast_playtones_stop(chan);
1505 if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1507 }
1510 ast_log(LOG_NOTICE, "Media control operation 'reverse' not supported for media type 'tone'\n");
1513 ast_log(LOG_NOTICE, "Media control operation 'forward' not supported for media type 'tone'\n");
1515 case AST_CONTROL_HANGUP:
1516 case AST_CONTROL_BUSY:
1519 }
1520
1522}
@ AST_CONTROL_BUSY
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HANGUP
@ AST_CONTROL_STREAM_FORWARD

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().

◆ dtmf_stream()

static int dtmf_stream ( struct ast_channel chan,
const char *  digits,
int  between,
unsigned int  duration,
int  is_external 
)
static

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

1030{
1031 const char *ptr;
1032 int res;
1033 struct ast_silence_generator *silgen = NULL;
1034 int (*my_sleep)(struct ast_channel *chan, int ms);
1035 int (*my_senddigit)(struct ast_channel *chan, char digit, unsigned int duration);
1036
1037 if (is_external) {
1038 my_sleep = external_sleep;
1039 my_senddigit = ast_senddigit_external;
1040 } else {
1041 my_sleep = ast_safe_sleep;
1042 my_senddigit = ast_senddigit;
1043 }
1044
1045 if (!between) {
1046 between = 100;
1047 }
1048
1049 /* Need a quiet time before sending digits. */
1052 }
1053 res = my_sleep(chan, 100);
1054 if (res) {
1055 goto dtmf_stream_cleanup;
1056 }
1057
1058 for (ptr = digits; *ptr; ptr++) {
1059 if (*ptr == 'w') {
1060 /* 'w' -- wait half a second */
1061 res = my_sleep(chan, 500);
1062 if (res) {
1063 break;
1064 }
1065 } else if (*ptr == 'W') {
1066 /* 'W' -- wait a second */
1067 res = my_sleep(chan, 1000);
1068 if (res) {
1069 break;
1070 }
1071 } else if (strchr("0123456789*#abcdfABCDF", *ptr)) {
1072 if (*ptr == 'f' || *ptr == 'F') {
1073 /* ignore return values if not supported by channel */
1075 } else {
1076 /* Character represents valid DTMF */
1077 my_senddigit(chan, *ptr, duration);
1078 }
1079 /* pause between digits */
1080 res = my_sleep(chan, between);
1081 if (res) {
1082 break;
1083 }
1084 } else {
1085 ast_log(LOG_WARNING, "Illegal DTMF character '%c' in string. (0-9*#aAbBcCdD allowed)\n", *ptr);
1086 }
1087 }
1088
1089dtmf_stream_cleanup:
1090 if (silgen) {
1092 }
1093
1094 return res;
1095}
char digit
int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration)
Send a DTMF digit to a channel.
Definition: channel.c:4993
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:5006
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1593
@ AST_CONTROL_FLASH
static int external_sleep(struct ast_channel *chan, int ms)
Definition: main/app.c:757
Main Channel structure associated with a channel.

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().

◆ external_sleep()

static int external_sleep ( struct ast_channel chan,
int  ms 
)
static

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

758{
759 usleep(ms * 1000);
760 return 0;
761}

Referenced by dtmf_stream(), mf_stream(), and sf_stream().

◆ ivr_dispatch()

static int ivr_dispatch ( struct ast_channel chan,
struct ast_ivr_option option,
char *  exten,
void *  cbdata 
)
static

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

2748{
2749 int res;
2750 int (*ivr_func)(struct ast_channel *, void *);
2751 char *c;
2752 char *n;
2753
2754 switch (option->action) {
2755 case AST_ACTION_UPONE:
2756 return RES_UPONE;
2757 case AST_ACTION_EXIT:
2758 return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff);
2759 case AST_ACTION_REPEAT:
2760 return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff);
2761 case AST_ACTION_RESTART:
2762 return RES_RESTART ;
2763 case AST_ACTION_NOOP:
2764 return 0;
2766 res = ast_stream_and_wait(chan, (char *)option->adata, AST_DIGIT_ANY);
2767 if (res < 0) {
2768 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2769 res = 0;
2770 }
2771 return res;
2773 res = ast_stream_and_wait(chan, (char *)option->adata, "");
2774 if (res < 0) {
2775 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2776 res = 0;
2777 }
2778 return res;
2779 case AST_ACTION_MENU:
2780 if ((res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata)) == -2) {
2781 /* Do not pass entry errors back up, treat as though it was an "UPONE" */
2782 res = 0;
2783 }
2784 return res;
2786 if (!(res = ast_waitfordigit(chan, ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000))) {
2787 return 't';
2788 }
2789 return res;
2791 ivr_func = option->adata;
2792 res = ivr_func(chan, cbdata);
2793 return res;
2795 res = ast_parseable_goto(chan, option->adata);
2796 return 0;
2799 res = 0;
2800 c = ast_strdupa(option->adata);
2801 while ((n = strsep(&c, ";"))) {
2802 if ((res = ast_stream_and_wait(chan, n,
2803 (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : ""))) {
2804 break;
2805 }
2806 }
2807 ast_stopstream(chan);
2808 return res;
2809 default:
2810 ast_log(LOG_NOTICE, "Unknown dispatch function %u, ignoring!\n", option->action);
2811 return 0;
2812 }
2813 return -1;
2814}
@ AST_ACTION_UPONE
@ AST_ACTION_BACKLIST
@ AST_ACTION_PLAYBACK
@ AST_ACTION_RESTART
@ AST_ACTION_PLAYLIST
@ AST_ACTION_CALLBACK
@ AST_ACTION_NOOP
@ AST_ACTION_EXIT
@ AST_ACTION_BACKGROUND
@ AST_ACTION_WAITOPTION
@ AST_ACTION_MENU
@ AST_ACTION_REPEAT
@ AST_ACTION_TRANSFER
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8866
ast_ivr_action action

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().

◆ linear_alloc()

static void * linear_alloc ( struct ast_channel chan,
void *  params 
)
static

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

1202{
1203 struct linear_state *ls = params;
1204
1205 if (!params) {
1206 return NULL;
1207 }
1208
1209 /* In this case, params is already malloc'd */
1210 if (ls->allowoverride) {
1212 } else {
1214 }
1215
1217
1219 ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", ast_channel_name(chan));
1220 ao2_cleanup(ls->origwfmt);
1221 ast_free(ls);
1222 ls = params = NULL;
1223 }
1224
1225 return params;
1226}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5822
@ AST_FLAG_WRITE_INT
Definition: channel.h:1003
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
struct ast_format * origwfmt
Definition: main/app.c:1151
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70

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.

◆ linear_generator()

static int linear_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
)
static

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

1172{
1173 short buf[2048 + AST_FRIENDLY_OFFSET / 2];
1174 struct linear_state *ls = data;
1175 struct ast_frame f = {
1177 .data.ptr = buf + AST_FRIENDLY_OFFSET / 2,
1178 .offset = AST_FRIENDLY_OFFSET,
1179 };
1180 int res;
1181
1183
1184 len = samples * 2;
1185 if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
1186 ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" , len);
1187 len = sizeof(buf) - AST_FRIENDLY_OFFSET;
1188 }
1189 res = read(ls->fd, buf + AST_FRIENDLY_OFFSET/2, len);
1190 if (res > 0) {
1191 f.datalen = res;
1192 f.samples = res / 2;
1193 ast_write(chan, &f);
1194 if (res == len) {
1195 return 0;
1196 }
1197 }
1198 return -1;
1199}
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:5163
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
struct ast_format * format

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, len(), LOG_WARNING, ast_frame::samples, and ast_frame::subclass.

◆ linear_release()

static void linear_release ( struct ast_channel chan,
void *  params 
)
static

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

1155{
1156 struct linear_state *ls = params;
1157
1158 if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) {
1159 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%s'\n",
1161 }
1162 ao2_cleanup(ls->origwfmt);
1163
1164 if (ls->autoclose) {
1165 close(ls->fd);
1166 }
1167
1168 ast_free(params);
1169}

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.

◆ 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_slin.

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

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

1641{
1642 struct ast_frame *silence;
1643 size_t size;
1644 size_t datalen;
1645 size_t samples = 0;
1646
1647 if (!orig) {
1648 return NULL;
1649 }
1650 do {
1652 ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
1653 return NULL;
1654 }
1655
1656 samples += orig->samples;
1657
1658 orig = AST_LIST_NEXT(orig, frame_list);
1659 } while (orig);
1660
1661 ast_verb(4, "Silencing %zu samples\n", samples);
1662
1663
1664 datalen = sizeof(short) * samples;
1665 size = sizeof(*silence) + datalen;
1666 silence = ast_calloc(1, size);
1667 if (!silence) {
1668 return NULL;
1669 }
1670
1671 silence->mallocd = AST_MALLOCD_HDR;
1672 silence->frametype = AST_FRAME_VOICE;
1673 silence->data.ptr = (void *)(silence + 1);
1674 silence->samples = samples;
1675 silence->datalen = datalen;
1676
1678
1679 return silence;
1680}
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
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
#define AST_MALLOCD_HDR
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
union ast_frame::@226 data

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().

◆ mf_stream()

static int mf_stream ( struct ast_channel chan,
struct ast_channel chan2,
const char *  digits,
int  between,
unsigned int  duration,
unsigned int  durationkp,
unsigned int  durationst,
int  is_external 
)
static

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

916{
917 const char *ptr;
918 int res;
919 struct ast_silence_generator *silgen = NULL, *silgen2 = NULL;
920 int (*my_sleep)(struct ast_channel *chan, int ms);
921
922 if (is_external) {
923 my_sleep = external_sleep;
924 } else {
925 my_sleep = ast_safe_sleep;
926 }
927
928 if (!between) {
929 between = 100;
930 }
931
932 /* Need a quiet time before sending digits. */
935 if (chan2) {
937 }
938 }
939 if (chan2) {
941 }
942 res = my_sleep(chan, 100);
943 if (chan2) {
945 }
946 if (res) {
947 goto mf_stream_cleanup;
948 }
949
950 for (ptr = digits; *ptr; ptr++) {
951 if (*ptr == 'w') {
952 /* 'w' -- wait half a second */
953 if (chan2) {
955 }
956 res = my_sleep(chan, 500);
957 if (chan2) {
959 }
960 if (res) {
961 break;
962 }
963 } else if (*ptr == 'h' || *ptr == 'H') {
964 /* 'h' -- 2600 Hz for half a second, but
965 only to far end of trunk, not near end */
966 ast_playtones_start(chan, 0, "2600", 0);
967 if (chan2) {
968 ast_playtones_start(chan2, 0, "0", 0);
970 }
971 res = my_sleep(chan, 250);
973 if (chan2) {
976 }
977 if (res) {
978 break;
979 }
980 } else if (strchr("0123456789*#ABCwWfF", *ptr)) {
981 if (*ptr == 'f' || *ptr == 'F') {
982 /* ignore return values if not supported by channel */
984 } else if (*ptr == 'W') {
985 /* ignore return values if not supported by channel */
987 } else {
988 /* Character represents valid MF */
989 ast_senddigit_mf(chan, *ptr, duration, durationkp, durationst, is_external);
990 if (chan2) {
991 ast_senddigit_mf(chan2, *ptr, duration, durationkp, durationst, is_external);
992 }
993 }
994 /* pause between digits */
995 /* The DSP code in Asterisk does not currently properly receive repeated tones
996 if no audio is sent in the middle. Simply sending audio (even 0 Hz)
997 works around this limitation and guarantees the correct behavior.
998 */
999 ast_playtones_start(chan, 0, "0", 0);
1000 if (chan2) {
1001 ast_playtones_start(chan2, 0, "0", 0);
1002 ast_autoservice_start(chan2);
1003 }
1004 res = my_sleep(chan, between);
1006 if (chan2) {
1007 ast_autoservice_stop(chan2);
1008 ast_senddigit_mf_end(chan2);
1009 }
1010 if (res) {
1011 break;
1012 }
1013 } else {
1014 ast_log(LOG_WARNING, "Illegal MF character '%c' in string. (0-9*#ABCwWfFhH allowed)\n", *ptr);
1015 }
1016 }
1017
1018mf_stream_cleanup:
1019 if (silgen) {
1021 }
1022 if (silgen2) {
1023 ast_channel_stop_silence_generator(chan2, silgen2);
1024 }
1025
1026 return res;
1027}
int ast_senddigit_mf_end(struct ast_channel *chan)
End sending an MF digit to a channel.
Definition: channel.c:4962
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:4971
@ AST_CONTROL_WINK

References ast_autoservice_start(), ast_autoservice_stop(), 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().

◆ option_exists()

static int option_exists ( struct ast_ivr_menu menu,
char *  option 
)
static

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

2817{
2818 int x;
2819 for (x = 0; menu->options[x].option; x++) {
2820 if (!strcasecmp(menu->options[x].option, option)) {
2821 return x;
2822 }
2823 }
2824 return -1;
2825}

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

Referenced by ast_ivr_menu_run_internal().

◆ option_matchmore()

static int option_matchmore ( struct ast_ivr_menu menu,
char *  option 
)
static

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

2828{
2829 int x;
2830 for (x = 0; menu->options[x].option; x++) {
2831 if ((!strncasecmp(menu->options[x].option, option, strlen(option))) &&
2832 (menu->options[x].option[strlen(option)])) {
2833 return x;
2834 }
2835 }
2836 return -1;
2837}

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

Referenced by read_newoption().

◆ parse_options()

static int parse_options ( const struct ast_app_option options,
void *  _flags,
char **  args,
char *  optstr,
int  flaglen 
)
static

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

2984{
2985 char *s, *arg;
2986 int curarg, res = 0;
2987 unsigned int argloc;
2988 struct ast_flags *flags = _flags;
2989 struct ast_flags64 *flags64 = _flags;
2990
2991 if (flaglen == 32) {
2993 } else {
2994 flags64->flags = 0;
2995 }
2996
2997 if (!optstr) {
2998 return 0;
2999 }
3000
3001 s = optstr;
3002 while (*s) {
3003 curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */
3004 argloc = options[curarg].arg_index;
3005 if (*s == '(') {
3006 int paren = 1, quote = 0;
3007 int parsequotes = (s[1] == '"') ? 1 : 0;
3008
3009 /* Has argument */
3010 arg = ++s;
3011 for (; *s; s++) {
3012 if (*s == '(' && !quote) {
3013 paren++;
3014 } else if (*s == ')' && !quote) {
3015 /* Count parentheses, unless they're within quotes (or backslashed, below) */
3016 paren--;
3017 } else if (*s == '"' && parsequotes) {
3018 /* Leave embedded quotes alone, unless they are the first character */
3019 quote = quote ? 0 : 1;
3020 ast_copy_string(s, s + 1, INT_MAX);
3021 s--;
3022 } else if (*s == '\\') {
3023 if (!quote) {
3024 /* If a backslash is found outside of quotes, remove it */
3025 ast_copy_string(s, s + 1, INT_MAX);
3026 } else if (quote && s[1] == '"') {
3027 /* Backslash for a quote character within quotes, remove the backslash */
3028 ast_copy_string(s, s + 1, INT_MAX);
3029 } else {
3030 /* Backslash within quotes, keep both characters */
3031 s++;
3032 }
3033 }
3034
3035 if (paren == 0) {
3036 break;
3037 }
3038 }
3039 /* This will find the closing paren we found above, or none, if the string ended before we found one. */
3040 if ((s = strchr(s, ')'))) {
3041 if (argloc) {
3042 args[argloc - 1] = arg;
3043 }
3044 *s++ = '\0';
3045 } else {
3046 ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
3047 res = -1;
3048 break;
3049 }
3050 } else if (argloc) {
3051 args[argloc - 1] = "";
3052 }
3053 if (!options[curarg].flag) {
3054 ast_log(LOG_WARNING, "Unrecognized option: '%c'\n", curarg);
3055 }
3056 if (flaglen == 32) {
3057 ast_set_flag(flags, options[curarg].flag);
3058 } else {
3059 ast_set_flag64(flags64, options[curarg].flag);
3060 }
3061 }
3062
3063 return res;
3064}
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
uint64_t flags
Definition: utils.h:205
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
#define ast_set_flag64(p, flag)
Definition: utils.h:127
#define AST_FLAGS_ALL
Definition: utils.h:196

References args, 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, options, paren, and quote().

Referenced by ast_app_parse_options(), and ast_app_parse_options64().

◆ parse_tone_uri()

static int parse_tone_uri ( char *  tone_parser,
const char **  tone_indication,
const char **  tone_zone 
)
static

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

1527{
1528 *tone_indication = strsep(&tone_parser, ";");
1529
1530 if (ast_strlen_zero(tone_parser)) {
1531 /* Only the indication is included */
1532 return 0;
1533 }
1534
1535 if (!(strncmp(tone_parser, "tonezone=", 9))) {
1536 *tone_zone = tone_parser + 9;
1537 } else {
1538 ast_log(LOG_ERROR, "Unexpected Tone URI component: %s\n", tone_parser);
1539 return -1;
1540 }
1541
1542 return 0;
1543}

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

Referenced by ast_control_tone().

◆ path_lock_destroy()

static void path_lock_destroy ( struct path_lock obj)
static

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

2484{
2485 if (obj->fd >= 0) {
2486 close(obj->fd);
2487 }
2488 if (obj->path) {
2489 ast_free(obj->path);
2490 }
2491 ast_free(obj);
2492}

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

Referenced by ast_lock_path_flock(), and ast_unlock_path_flock().

◆ read_newoption()

static int read_newoption ( struct ast_channel chan,
struct ast_ivr_menu menu,
char *  exten,
int  maxexten 
)
static

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

2840{
2841 int res = 0;
2842 int ms;
2843 while (option_matchmore(menu, exten)) {
2844 ms = ast_channel_pbx(chan) ? ast_channel_pbx(chan)->dtimeoutms : 5000;
2845 if (strlen(exten) >= maxexten - 1) {
2846 break;
2847 }
2848 if ((res = ast_waitfordigit(chan, ms)) < 1) {
2849 break;
2850 }
2851 exten[strlen(exten) + 1] = '\0';
2852 exten[strlen(exten)] = res;
2853 }
2854 return res > 0 ? 0 : res;
2855}
static int option_matchmore(struct ast_ivr_menu *menu, char *option)
Definition: main/app.c:2827

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

Referenced by ast_ivr_menu_run_internal().

◆ 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_slin, recording its original format.

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

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

1693{
1694 if (!chan || !orig_format) {
1695 return -1;
1696 }
1697 *orig_format = ao2_bump(ast_channel_readformat(chan));
1699}
struct ast_format * ast_channel_readformat(struct ast_channel *chan)

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

Referenced by __ast_play_and_record().

◆ sf_stream()

static int sf_stream ( struct ast_channel chan,
struct ast_channel chan2,
const char *  digits,
int  frequency,
int  is_external 
)
static

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

764{
765 /* Bell System Technical Journal 39 (Nov. 1960) */
766 #define SF_ON 67
767 #define SF_OFF 33
768 #define SF_BETWEEN 600
769
770 const char *ptr;
771 int res;
772 struct ast_silence_generator *silgen = NULL, *silgen2 = NULL;
773 char *freq;
774 int (*my_sleep)(struct ast_channel *chan, int ms);
775
776 if (frequency >= 100000) {
777 ast_log(LOG_WARNING, "Frequency too large: %d\n", frequency);
778 return -1;
779 }
780
781 if (is_external) {
782 my_sleep = external_sleep;
783 } else {
784 my_sleep = ast_safe_sleep;
785 }
786
787 /* Need a quiet time before sending digits. */
790 if (chan2) {
792 }
793 }
794 if (chan2) {
796 }
797 res = my_sleep(chan, 100);
798 if (chan2) {
800 }
801 if (res) {
802 goto sf_stream_cleanup;
803 }
804
805/* len(SF_ON) + len(SF_OFF) + len(0) + maxlen(frequency) + /,/ + null terminator = 2 + 2 + 1 + 5 at most + 3 + 1 = 14 */
806#define SF_BUF_LEN 20
807 freq = ast_alloca(SF_BUF_LEN); /* min 20 to avoid compiler warning about insufficient buffer */
808 /* pauses need to send audio, so send 0 Hz */
809 snprintf(freq, SF_BUF_LEN, "%d/%d,%d/%d", frequency, SF_ON, 0, SF_OFF);
810
811 for (ptr = digits; *ptr; ptr++) {
812 if (*ptr == 'w') {
813 /* 'w' -- wait half a second */
814 if (chan2) {
816 }
817 res = my_sleep(chan, 500);
818 if (chan2) {
820 }
821 if (res) {
822 break;
823 }
824 } else if (*ptr == 'h' || *ptr == 'H') {
825 /* 'h' -- 2600 Hz for half a second, but
826 only to far end of trunk, not near end */
827 ast_playtones_start(chan, 0, "2600", 0);
828 if (chan2) {
829 ast_playtones_start(chan2, 0, "0", 0);
831 }
832 res = my_sleep(chan, 250);
834 if (chan2) {
837 }
838 if (res) {
839 break;
840 }
841 } else if (strchr("0123456789*#ABCDabcdwWfF", *ptr)) {
842 if (*ptr == 'f' || *ptr == 'F') {
843 /* ignore return values if not supported by channel */
845 } else if (*ptr == 'W') {
846 /* ignore return values if not supported by channel */
848 } else {
849 /* Character represents valid SF */
850 int beeps;
851 if (*ptr == '*') {
852 beeps = 11;
853 } else if (*ptr == '#') {
854 beeps = 12;
855 } else if (*ptr == 'D') {
856 beeps = 13;
857 } else if (*ptr == 'C') {
858 beeps = 14;
859 } else if (*ptr == 'B') {
860 beeps = 15;
861 } else if (*ptr == 'A') {
862 beeps = 16;
863 } else {
864 beeps = (*ptr == '0') ? 10 : *ptr - '0';
865 }
866 while (beeps-- > 0) {
867 ast_playtones_start(chan, 0, freq, 0);
868 if (chan2) {
869 ast_playtones_start(chan2, 0, freq, 0);
871 }
872 res = my_sleep(chan, SF_ON + SF_OFF);
874 if (chan2) {
877 }
878 if (res) {
879 break;
880 }
881 }
882 }
883 /* pause between digits */
884 ast_playtones_start(chan, 0, "0", 0);
885 if (chan2) {
886 ast_playtones_start(chan2, 0, "0", 0);
888 }
889 res = my_sleep(chan, SF_BETWEEN);
890 if (chan2) {
893 }
895 if (res) {
896 break;
897 }
898 } else {
899 ast_log(LOG_WARNING, "Illegal SF character '%c' in string. (0-9A-DwWfFhH allowed)\n", *ptr);
900 }
901 }
902
903sf_stream_cleanup:
904 if (silgen) {
906 }
907 if (silgen2) {
909 }
910
911 return res;
912}
#define SF_BETWEEN
#define SF_BUF_LEN
#define SF_OFF
#define SF_ON

References ast_alloca, ast_autoservice_start(), ast_autoservice_stop(), 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_end(), external_sleep(), LOG_WARNING, NULL, SF_BETWEEN, SF_BUF_LEN, SF_OFF, and SF_ON.

Referenced by ast_sf_stream().

◆ shaun_of_the_dead()

static void * shaun_of_the_dead ( void *  data)
static

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

96{
97 struct zombie *cur;
98 int status;
99 for (;;) {
100 if (!AST_LIST_EMPTY(&zombies)) {
101 /* Don't allow cancellation while we have a lock. */
102 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
105 if (waitpid(cur->pid, &status, WNOHANG) != 0) {
107 ast_free(cur);
108 }
109 }
112 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
113 }
114 pthread_testcancel();
115 /* Wait for 60 seconds, without engaging in a busy loop. */
116 ast_poll(NULL, 0, AST_LIST_FIRST(&zombies) ? 5000 : 60000);
117 }
118 return NULL;
119}
jack_status_t status
Definition: app_jack.c:146
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
#define ast_poll(a, b, c)
Definition: poll-compat.h:88

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().

◆ vm_greeter_warn_no_provider()

static void vm_greeter_warn_no_provider ( void  )
static

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

562{
563 if (vm_greeter_warnings++ % 10 == 0) {
564 ast_verb(3, "No voicemail greeter provider registered.\n");
565 }
566}
static int vm_greeter_warnings
Definition: main/app.c:466

References ast_verb, and vm_greeter_warnings.

◆ vm_warn_no_provider()

static void vm_warn_no_provider ( void  )
static

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

541{
542 if (vm_warnings++ % 10 == 0) {
543 ast_verb(3, "No voicemail provider registered.\n");
544 }
545}
static int vm_warnings
Definition: main/app.c:355

References ast_verb, and vm_warnings.

Variable Documentation

◆ app_stack_callbacks

const struct ast_app_stack_funcs* app_stack_callbacks
static

◆ ast_lock_type

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

◆ default_acceptdtmf

const char default_acceptdtmf[] = "#"
static

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

Referenced by __ast_play_and_record().

◆ global_silence_threshold

int global_silence_threshold = 128
static

Definition at line 1701 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

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

Referenced by ast_linear_stream().

◆ path_lock_list

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

◆ queue_topic_all

struct stasis_topic* queue_topic_all
static

Define Stasis Message Bus API topic objects.

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

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

◆ queue_topic_pool

struct stasis_topic_pool* queue_topic_pool
static

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

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

◆ shaun_of_the_dead_thread

pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL
static

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

Referenced by ast_safe_fork().

◆ vm_greeter_warnings

int vm_greeter_warnings
static

Voicemail greeter not registered warning

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

Referenced by vm_greeter_warn_no_provider().

◆ vm_warnings

int vm_warnings
static

Voicemail not registered warning

Definition at line 355 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