Asterisk - The Open Source Telephony Project GIT-master-773870a
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
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.
 
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.
 
int __ast_vm_register (const struct ast_vm_functions *vm_table, struct ast_module *module)
 Set voicemail function callbacks.
 
static AO2_GLOBAL_OBJ_STATIC (vm_greeter_provider)
 The container for the voicemail greeter provider.
 
static AO2_GLOBAL_OBJ_STATIC (vm_provider)
 The container for the voicemail provider.
 
static void app_cleanup (void)
 
int app_init (void)
 Initialize the application core.
 
int ast_app_copy_recording_to_vm (struct ast_vm_recording_data *vm_rec_data)
 param[in] vm_rec_data Contains data needed to make the recording. retval 0 voicemail successfully created from recording. retval -1 Failure
 
int ast_app_dtget (struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout)
 This function presents a dialtone and reads an extension into 'collect' which must be a pointer to a pre-initialized array of char having a size of 'size' suitable for writing to. It will collect no more than the smaller of 'maxlen' or 'size' minus the original strlen() of collect digits.
 
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.
 
const char * ast_app_expand_sub_args (struct ast_channel *chan, const char *args)
 Add missing context/exten to subroutine argument string.
 
enum ast_getdata_result ast_app_getdata (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
 Plays a stream and gets DTMF data from a channel.
 
int ast_app_getdata_full (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd)
 Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions.
 
enum ast_getdata_result ast_app_getdata_terminator (struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, char *terminator)
 Plays a stream and gets DTMF data from a channel.
 
int ast_app_group_discard (struct ast_channel *chan)
 Discard all group counting for a channel.
 
int ast_app_group_get_count (const char *group, const char *category)
 Get the current channel count of the specified group and category.
 
struct ast_group_infoast_app_group_list_head (void)
 Get the head of the group count list.
 
int ast_app_group_list_rdlock (void)
 Read Lock the group count list.
 
int ast_app_group_list_unlock (void)
 Unlock the group count list.
 
int ast_app_group_list_wrlock (void)
 Write Lock the group count list.
 
int ast_app_group_match_get_count (const char *groupmatch, const char *category)
 Get the current channel count of all groups that match the specified pattern and category.
 
int ast_app_group_set_channel (struct ast_channel *chan, const char *data)
 Set the group for a channel, splitting the provided data into group and category, if specified.
 
int ast_app_group_split_group (const char *data, char *group, int group_max, char *category, int category_max)
 Split a group string into group and category, returning a default category if none is provided.
 
int ast_app_group_update (struct ast_channel *old, struct ast_channel *new)
 Update all group counting for a channel to a new one.
 
int ast_app_has_voicemail (const char *mailboxes, const char *folder)
 Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX". If folder is "INBOX", includes the number of messages in the "Urgent" folder.
 
int ast_app_inboxcount (const char *mailboxes, int *newmsgs, int *oldmsgs)
 Determine number of new/old messages in a mailbox.
 
int ast_app_inboxcount2 (const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
 Determine number of urgent/new/old messages in a mailbox.
 
int ast_app_messagecount (const char *mailbox_id, const char *folder)
 Get the number of messages in a given mailbox folder.
 
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.
 
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.
 
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.
 
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.
 
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.
 
int ast_app_sayname (struct ast_channel *chan, const char *mailbox_id)
 Play a recorded user name for the mailbox to the specified channel.
 
void ast_close_fds_above_n (int n)
 Common routine for child processes, to close all fds prior to exec(2)
 
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.
 
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.
 
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.
 
int ast_control_tone (struct ast_channel *chan, const char *tone)
 Controls playback of a tone.
 
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.
 
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.
 
int ast_get_encoded_char (const char *stream, char *result, size_t *consumed)
 Decode an encoded control or extended ASCII character.
 
char * ast_get_encoded_str (const char *stream, char *result, size_t result_size)
 Decode a stream of encoded control or extended ASCII characters.
 
void ast_install_stack_functions (const struct ast_app_stack_funcs *funcs)
 Set stack application function callbacks.
 
int ast_ivr_menu_run (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 Runs an IVR menu.
 
static int ast_ivr_menu_run_internal (struct ast_channel *chan, struct ast_ivr_menu *menu, void *cbdata)
 
int ast_linear_stream (struct ast_channel *chan, const char *filename, int fd, int allowoverride)
 Stream a filename (or file descriptor) as a generator.
 
enum AST_LOCK_RESULT ast_lock_path (const char *path)
 Lock a filesystem path.
 
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.
 
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.
 
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.
 
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.
 
int ast_play_and_wait (struct ast_channel *chan, const char *fn)
 Play a stream and wait for a digit, returning the digit that was pressed.
 
struct stasis_topicast_queue_topic (const char *queuename)
 Get the Stasis Message Bus API topic for queue messages for a particular queue name.
 
struct stasis_topicast_queue_topic_all (void)
 Get the Stasis Message Bus API topic for queue messages.
 
char * ast_read_textfile (const char *filename)
 Read a file into asterisk.
 
int ast_record_review (struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path)
 Allow to record message and have a review option.
 
int ast_safe_fork (int stop_reaper)
 Common routine to safely fork without a chance of a signal handler firing badly in the child.
 
void ast_safe_fork_cleanup (void)
 Common routine to cleanup after fork'ed process is complete (if reaping was stopped)
 
void ast_set_lock_type (enum AST_LOCK_TYPE type)
 Set the type of locks used by ast_lock_path()
 
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.
 
int ast_str_get_encoded_str (struct ast_str **str, int maxlen, const char *stream)
 Decode a stream of encoded control or extended ASCII characters.
 
 AST_THREADSTORAGE_PUBLIC (ast_str_thread_global_buf)
 
int ast_unlock_path (const char *path)
 Unlock a path.
 
static int ast_unlock_path_flock (const char *path)
 
static int ast_unlock_path_lockfile (const char *path)
 
int ast_vm_greeter_is_registered (void)
 Determine if a voicemail greeter provider is registered.
 
void ast_vm_greeter_unregister (const char *module_name)
 Unregister the specified voicemail greeter provider.
 
const char * ast_vm_index_to_foldername (int id)
 Return name of folder, given an id.
 
int ast_vm_is_registered (void)
 Determine if a voicemail provider is registered.
 
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.
 
struct ast_vm_mailbox_snapshotast_vm_mailbox_snapshot_destroy (struct ast_vm_mailbox_snapshot *mailbox_snapshot)
 destroy a snapshot
 
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.
 
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.
 
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.
 
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.
 
void ast_vm_unregister (const char *module_name)
 Unregister the specified voicemail provider.
 
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.
 
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.
 
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 = AST_RWLIST_HEAD_INIT_VALUE
 
static struct ast_generator linearstream
 
static struct path_lock_list path_lock_list = AST_LIST_HEAD_INIT_VALUE
 
static pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL
 
static int vm_greeter_warnings
 
static int vm_warnings
 
static struct zombies zombies = AST_LIST_HEAD_INIT_VALUE
 
static struct stasis_topicqueue_topic_all
 Define Stasis Message Bus API topic objects.
 
static struct stasis_topic_poolqueue_topic_pool
 

Detailed Description

Convenient Application Routines.

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

Definition in file main/app.c.

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

◆ RES_REPEAT

#define RES_REPEAT   (1 << 18)

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

◆ RES_RESTART

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

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

◆ RES_UPONE

#define RES_UPONE   (1 << 16)

Definition at line 2741 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.

548 { \
549 struct ast_vm_functions *table; \
550 table = ao2_global_obj_ref(vm_provider); \
551 if (!table) { \
552 vm_warn_no_provider(); \
553 } else if (table->api_call) { \
554 ast_module_ref(table->module); \
555 (res) = table->api_call api_parms; \
556 ast_module_unref(table->module); \
557 } \
558 ao2_cleanup(table); \
559 } while (0)
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition astobj2.h:918
Voicemail function table definition.

◆ VM_GREETER_API_CALL

#define VM_GREETER_API_CALL (   res,
  api_call,
  api_parms 
)

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

569 { \
570 struct ast_vm_greeter_functions *table; \
571 table = ao2_global_obj_ref(vm_greeter_provider); \
572 if (!table) { \
573 vm_greeter_warn_no_provider(); \
574 } else if (table->api_call) { \
575 ast_module_ref(table->module); \
576 (res) = table->api_call api_parms; \
577 ast_module_unref(table->module); \
578 } \
579 ao2_cleanup(table); \
580 } while (0)
Voicemail greeter function table definition.

Enumeration Type Documentation

◆ control_tone_frame_response_result

Enumerator
CONTROL_TONE_RESPONSE_FAILED 
CONTROL_TONE_RESPONSE_NORMAL 
CONTROL_TONE_RESPONSE_FINISHED 

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

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

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

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

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

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
500 table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
501 if (!table) {
502 return -1;
503 }
504 *table = *vm_table;
505 table->module = module;
506
507 ao2_global_obj_replace_unref(vm_greeter_provider, table);
508 return 0;
509}
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_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
#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.
#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:981

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_name, ast_vm_functions::module_version, NULL, RAII_VAR, 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{
370 RAII_VAR(struct ast_vm_functions *, table, NULL, ao2_cleanup);
371
372 if (!vm_table->module_name) {
373 ast_log(LOG_ERROR, "Voicemail provider missing required information.\n");
374 return -1;
375 }
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
389 table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
390 if (!table) {
391 return -1;
392 }
393 *table = *vm_table;
394 table->module = module;
395
396 ao2_global_obj_replace_unref(vm_provider, table);
397 return 0;
398}
#define VM_MODULE_VERSION

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_name, ast_vm_functions::module_version, NULL, RAII_VAR, 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 3355 of file main/app.c.

3356{
3357#ifdef HAS_CAP
3358 cap_free(child_cap);
3359#endif
3364}
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 3366 of file main/app.c.

3367{
3369#ifdef HAVE_CAP
3370 child_cap = cap_from_text("cap_net_admin-eip");
3371#endif
3372 queue_topic_all = stasis_topic_create("queue:all");
3373 if (!queue_topic_all) {
3374 return -1;
3375 }
3377 if (!queue_topic_pool) {
3378 return -1;
3379 }
3380 return 0;
3381}
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:3355
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition stasis.c:684
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:1918

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:3172
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.
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
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:4196
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Definition pbx.c:6904
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:4216
#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:216
Description of a tone.
Definition indications.h:35
const char * data
Description of a tone.
Definition indications.h:52
Number structure.

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

Referenced by grab_transfer().

◆ 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...
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition channel.c:1181
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...
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.
void *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, 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}
static struct @522 args
const char *(* expand_sub_args)(struct ast_channel *chan, const char *args)
Add missing context/exten to Gosub application argument string.

References app_stack_callbacks, args, ast_log, ast_module_running_ref, ast_module_unref, ast_app_stack_funcs::expand_sub_args, LOG_WARNING, 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:2803
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:6558
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:1312
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:6553
@ 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:1869
int rtimeoutms
Definition pbx.h:217

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

2321{
2322 struct ast_group_info *gi = NULL;
2323
2326 if (gi->chan == chan) {
2328 ast_free(gi);
2329 }
2330 }
2333
2334 return 0;
2335}
#define ast_free(a)
Definition astmm.h:180
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#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.
#define AST_RWLIST_TRAVERSE_SAFE_END
channel group info
Definition channel.h:2975
struct ast_group_info::@223 group_list
struct ast_channel * chan
Definition channel.h:2976

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

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

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

2348{
2349 return AST_RWLIST_FIRST(&groups);
2350}
#define AST_RWLIST_FIRST

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

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

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

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

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

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

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

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

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

2195{
2196 int res = 0;
2197 char group[80] = "", category[80] = "";
2198 struct ast_group_info *gi = NULL;
2199 size_t len = 0;
2200
2201 if (ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category))) {
2202 return -1;
2203 }
2204
2205 /* Calculate memory we will need if this is new */
2206 len = sizeof(*gi) + strlen(group) + 1;
2207 if (!ast_strlen_zero(category)) {
2208 len += strlen(category) + 1;
2209 }
2210
2213 if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) {
2215 ast_free(gi);
2216 break;
2217 }
2218 }
2220
2221 if (ast_strlen_zero(group)) {
2222 /* Enable unsetting the group */
2223 } else if ((gi = ast_calloc(1, len))) {
2224 gi->chan = chan;
2225 gi->group = (char *) gi + sizeof(*gi);
2226 strcpy(gi->group, group);
2227 if (!ast_strlen_zero(category)) {
2228 gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1;
2229 strcpy(gi->category, category);
2230 }
2232 } else {
2233 res = -1;
2234 }
2235
2237
2238 return res;
2239}
#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
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:2167

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

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

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

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

2302{
2303 struct ast_group_info *gi = NULL;
2304
2307 if (gi->chan == old) {
2308 gi->chan = new;
2309 } else if (gi->chan == new) {
2311 ast_free(gi);
2312 }
2313 }
2316
2317 return 0;
2318}

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

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

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

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

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

Referenced by agent_login_exec(), app_exec(), app_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(), wait_exec(), and webchan_request().

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

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

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

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

3204{
3205 closefrom(n + 1);
3206}
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 1466 of file main/app.c.

1470{
1471 return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, NULL, NULL);
1472}
unsigned int stop
Definition app_sla.c:342
static int skipms
static void suspend(struct cc_core_instance *core_instance)
Definition ccss.c:3211
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(), 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 1474 of file main/app.c.

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

References control_streamfile(), 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 1452 of file main/app.c.

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

References control_streamfile(), 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 1546 of file main/app.c.

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

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

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

3164{
3165 char *cur = result;
3166 size_t consumed;
3167
3168 while (cur < result + result_size - 1 && !ast_get_encoded_char(stream, cur, &consumed)) {
3169 cur++;
3170 stream += consumed;
3171 }
3172 *cur = '\0';
3173 return result;
3174}
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:3088

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

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

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

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

2616{
2618
2619 switch (ast_lock_type) {
2621 r = ast_lock_path_lockfile(path);
2622 break;
2624 r = ast_lock_path_flock(path);
2625 break;
2626 }
2627
2628 return r;
2629}
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:2421
static enum AST_LOCK_RESULT ast_lock_path_flock(const char *path)
Definition main/app.c:2495

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

◆ ast_lock_path_flock()

static enum AST_LOCK_RESULT ast_lock_path_flock ( const char *  path)
static

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

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

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

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

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

2161{
2162 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);
2163}
static const char default_acceptdtmf[]
Definition main/app.c:2147
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:1728
static const char default_canceldtmf[]
Definition main/app.c:2148

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

2156{
2157 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);
2158}

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

2151{
2152 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);
2153}
#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(), 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 1617 of file main/app.c.

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

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(), 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 3350 of file main/app.c.

3351{
3353}
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:1985

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

3346{
3347 return queue_topic_all;
3348}

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

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

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

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

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

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

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

3270{
3272}
void ast_unreplace_sigchld(void)
Restore the SIGCHLD handler.
Definition extconf.c:813

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

2611{
2613}
static const char type[]

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

3177{
3178 char next, *buf;
3179 size_t offset = 0;
3180 size_t consumed;
3181
3182 if (strchr(stream, '\\')) {
3183 while (!ast_get_encoded_char(stream, &next, &consumed)) {
3184 if (offset + 2 > ast_str_size(*str) && maxlen > -1) {
3185 ast_str_make_space(str, maxlen > 0 ? maxlen : (ast_str_size(*str) + 48) * 2 - 48);
3186 }
3187 if (offset + 2 > ast_str_size(*str)) {
3188 break;
3189 }
3191 buf[offset++] = next;
3192 stream += consumed;
3193 }
3195 buf[offset++] = '\0';
3197 } else {
3198 ast_str_set(str, maxlen, "%s", stream);
3199 }
3200 return 0;
3201}
const char * str
Definition app_jack.c:150
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
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
size_t attribute_pure 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 2631 of file main/app.c.

2632{
2633 int r = 0;
2634
2635 switch (ast_lock_type) {
2637 r = ast_unlock_path_lockfile(path);
2638 break;
2640 r = ast_unlock_path_flock(path);
2641 break;
2642 }
2643
2644 return r;
2645}
static int ast_unlock_path_flock(const char *path)
Definition main/app.c:2580
static int ast_unlock_path_lockfile(const char *path)
Definition main/app.c:2458

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

2581{
2582 char *s;
2583 struct path_lock *p;
2584
2585 s = ast_alloca(strlen(path) + 20);
2586
2589 if (!strcmp(p->path, path)) {
2591 break;
2592 }
2593 }
2596
2597 if (p) {
2598 snprintf(s, strlen(path) + 19, "%s/lock", path);
2599 unlink(s);
2601 ast_debug(1, "Unlocked path '%s'\n", path);
2602 } else {
2603 ast_debug(1, "Failed to unlock path '%s': "
2604 "lock not found\n", path);
2605 }
2606
2607 return 0;
2608}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
struct path_lock::@315 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 2458 of file main/app.c.

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

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{
470 struct ast_vm_greeter_functions *table;
471 int is_registered;
472
473 table = ao2_global_obj_ref(vm_greeter_provider);
474 is_registered = table ? 1 : 0;
475 ao2_cleanup(table);
476 return is_registered;
477}

References ao2_cleanup, and ao2_global_obj_ref.

◆ 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{
513 struct ast_vm_greeter_functions *table;
514
515 table = ao2_global_obj_ref(vm_greeter_provider);
516 if (table && !strcmp(table->module_name, module_name)) {
517 ao2_global_obj_release(vm_greeter_provider);
518 }
519 ao2_cleanup(table);
520}
#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, and ast_vm_greeter_functions::module_name.

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;
364 ao2_cleanup(table);
365 return is_registered;
366}

References ao2_cleanup, and ao2_global_obj_ref.

◆ 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 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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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}

References 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 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 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 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 }
408 ao2_cleanup(table);
409}

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

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

1488{
1489 switch (fr->subclass.integer) {
1491 ast_playtones_stop(chan);
1494 if (*paused) {
1495 *paused = 0;
1496 if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1498 }
1499 } else {
1500 *paused = 1;
1501 ast_playtones_stop(chan);
1502 }
1505 ast_playtones_stop(chan);
1506 if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) {
1508 }
1511 ast_log(LOG_NOTICE, "Media control operation 'reverse' not supported for media type 'tone'\n");
1514 ast_log(LOG_NOTICE, "Media control operation 'forward' not supported for media type 'tone'\n");
1516 case AST_CONTROL_HANGUP:
1517 case AST_CONTROL_BUSY:
1520 }
1521
1523}
@ 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:4969
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:4982
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition channel.c:1560
@ 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 2748 of file main/app.c.

2749{
2750 int res;
2751 int (*ivr_func)(struct ast_channel *, void *);
2752 char *c;
2753 char *n;
2754
2755 switch (option->action) {
2756 case AST_ACTION_UPONE:
2757 return RES_UPONE;
2758 case AST_ACTION_EXIT:
2759 return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff);
2760 case AST_ACTION_REPEAT:
2761 return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff);
2762 case AST_ACTION_RESTART:
2763 return RES_RESTART ;
2764 case AST_ACTION_NOOP:
2765 return 0;
2767 res = ast_stream_and_wait(chan, (char *)option->adata, AST_DIGIT_ANY);
2768 if (res < 0) {
2769 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2770 res = 0;
2771 }
2772 return res;
2774 res = ast_stream_and_wait(chan, (char *)option->adata, "");
2775 if (res < 0) {
2776 ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
2777 res = 0;
2778 }
2779 return res;
2780 case AST_ACTION_MENU:
2781 if ((res = ast_ivr_menu_run_internal(chan, (struct ast_ivr_menu *)option->adata, cbdata)) == -2) {
2782 /* Do not pass entry errors back up, treat as though it was an "UPONE" */
2783 res = 0;
2784 }
2785 return res;
2787 if (!(res = ast_waitfordigit(chan, ast_channel_pbx(chan) ? ast_channel_pbx(chan)->rtimeoutms : 10000))) {
2788 return 't';
2789 }
2790 return res;
2792 ivr_func = option->adata;
2793 res = ivr_func(chan, cbdata);
2794 return res;
2796 res = ast_parseable_goto(chan, option->adata);
2797 return 0;
2800 res = 0;
2801 c = ast_strdupa(option->adata);
2802 while ((n = strsep(&c, ";"))) {
2803 if ((res = ast_stream_and_wait(chan, n,
2804 (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : ""))) {
2805 break;
2806 }
2807 }
2808 ast_stopstream(chan);
2809 return res;
2810 default:
2811 ast_log(LOG_NOTICE, "Unknown dispatch function %u, ignoring!\n", option->action);
2812 return 0;
2813 }
2814 return -1;
2815}
@ 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:8895
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:5798
@ AST_FLAG_WRITE_INT
Definition channel.h:1003
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
struct ast_format * origwfmt
Definition main/app.c:1151
#define ast_clear_flag(p, flag)
Definition utils.h:78
#define ast_set_flag(p, flag)
Definition utils.h:71

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:5139
#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 1641 of file main/app.c.

1642{
1643 struct ast_frame *silence;
1644 size_t size;
1645 size_t datalen;
1646 size_t samples = 0;
1647
1648 if (!orig) {
1649 return NULL;
1650 }
1651 do {
1653 ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
1654 return NULL;
1655 }
1656
1657 samples += orig->samples;
1658
1659 orig = AST_LIST_NEXT(orig, frame_list);
1660 } while (orig);
1661
1662 ast_verb(4, "Silencing %zu samples\n", samples);
1663
1664
1665 datalen = sizeof(short) * samples;
1666 size = sizeof(*silence) + datalen;
1667 silence = ast_calloc(1, size);
1668 if (!silence) {
1669 return NULL;
1670 }
1671
1672 silence->mallocd = AST_MALLOCD_HDR;
1673 silence->frametype = AST_FRAME_VOICE;
1674 silence->data.ptr = (void *)(silence + 1);
1675 silence->samples = samples;
1676 silence->datalen = datalen;
1677
1679
1680 return silence;
1681}
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.
union ast_frame::@239 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:4938
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:4947

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

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

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

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

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

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

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

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

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

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

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

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

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

1694{
1695 if (!chan || !orig_format) {
1696 return -1;
1697 }
1698 *orig_format = ao2_bump(ast_channel_readformat(chan));
1700}
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:149
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
#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 2147 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 1703 of file main/app.c.

Referenced by __ast_play_and_record().

◆ global_silence_threshold

int global_silence_threshold = 128
static

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

Referenced by __ast_play_and_record().

◆ groups

◆ linearstream

struct ast_generator linearstream
static

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

1229{
1230 .alloc = linear_alloc,
1231 .release = linear_release,
1232 .generate = linear_generator,
1233};
static int linear_generator(struct ast_channel *chan, void *data, int len, int samples)
Definition main/app.c:1171
static void linear_release(struct ast_channel *chan, void *params)
Definition main/app.c:1154
static void * linear_alloc(struct ast_channel *chan, void *params)
Definition main/app.c:1201

Referenced by ast_linear_stream().

◆ path_lock_list

◆ 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