46#include <netinet/in.h>
76#define INITIAL_NUM_FILES 8
144#define MOH_QUIET (1 << 0)
145#define MOH_SINGLE (1 << 1)
146#define MOH_CUSTOM (1 << 2)
147#define MOH_RANDOMIZE (1 << 3)
148#define MOH_SORTALPHA (1 << 4)
149#define MOH_RANDSTART (MOH_RANDOMIZE | MOH_SORTALPHA)
150#define MOH_SORTMODE (3 << 3)
152#define MOH_CACHERTCLASSES (1 << 5)
153#define MOH_ANNOUNCEMENT (1 << 6)
154#define MOH_PREFERCHANNELCLASS (1 << 7)
156#define MOH_LOOPLAST (1 << 8)
159#define MOH_NOTDELETED (1 << 30)
160#define MOH_REALTIME (1 << 31)
195 unsigned int delete:1;
212#define LOCAL_MPG_123 "/usr/local/bin/mpg123"
213#define MPG_123 "/usr/bin/mpg123"
219#define mohclass_ref(class,string) (ao2_t_ref((class), +1, (string)), class)
222#define mohclass_unref(class,string) ({ ao2_t_ref((class), -1, (string)); (struct mohclass *) NULL; })
224#define mohclass_unref(class,string) _mohclass_unref(class, string, __FILE__,__LINE__,__PRETTY_FUNCTION__)
225static struct mohclass *_mohclass_unref(
struct mohclass *
class,
const char *tag,
const char *
file,
int line,
const char *funcname)
231 ast_log(
LOG_WARNING,
"Attempt to unref mohclass %p (%s) when only 1 ref remained, and class is still in a container! (at %s:%d (%s))\n",
232 class, class->name,
file, line, funcname);
248 ast_verb(3,
"Started music on hold, class '%s', on channel '%s'\n",
251 json_object =
ast_json_pack(
"{s: s}",
"class", moh_class_name);
312 state->announcement = 0;
331 state->announcement = 1;
337 state->announcement = 0;
353 state->save_pos = -1;
357 state->save_pos = -1;
360 for (tries = 0; tries < 20; tries++) {
366 state->save_pos = -1;
374 state->pos %= file_count;
376 state->save_pos = -1;
380 for (tries = 0; tries < file_count; ++tries) {
387 state->pos %= file_count;
390 if (tries == file_count) {
400 if (
state->samples) {
407 if (
state->samples > loc && loc) {
453 if (
state->origwfmt) {
458 if (
state->mohwfmt) {
469 int res = 0, sample_queue = 0;
475 sample_queue =
state->sample_queue;
478 while (sample_queue > 0) {
488 if (!
state->announcement) {
506 sample_queue =
state->sample_queue;
544 if (
state->save_total != file_count || strcmp(
state->
name, class->name) != 0) {
560 state->save_total = file_count;
584 const char *classname =
NULL;
589 ast_channel_musicclass_set(chan, classname);
616 if (!strcasecmp(class->dir,
"nodir")) {
619 dir = opendir(class->dir);
620 if (!dir && strncasecmp(class->dir,
"http://", 7)) {
627 argv[argc++] =
"mpg123";
630 argv[argc++] =
"--mono";
632 argv[argc++] =
"8000";
636 argv[argc++] =
"2048";
642 argv[argc++] =
"4096";
644 argv[argc++] =
"8192";
650 argv[argc++] = argptr;
658 argv[argc++] = argptr;
663 if (!strncasecmp(class->dir,
"http://", 7)) {
665 argv[argc++] = fns[files];
668 while ((de = readdir(dir)) && (files <
MAX_MP3S)) {
669 if ((strlen(de->d_name) > 3) &&
671 (!strcasecmp(de->d_name + strlen(de->d_name) - 4,
".raw") ||
672 !strcasecmp(de->d_name + strlen(de->d_name) - 4,
".sln"))) ||
673 !strcasecmp(de->d_name + strlen(de->d_name) - 4,
".mp3"))) {
675 argv[argc++] = fns[files];
694 if (!strncasecmp(class->dir,
"http://", 7) && time(
NULL) - class->start <
respawn_time) {
700 if (class->pid < 0) {
712 dup2(fds[1], STDOUT_FILENO);
718 if (strncasecmp(class->dir,
"http://", 7) && strcasecmp(class->dir,
"nodir") && chdir(class->dir) < 0) {
722 setpgid(0, getpid());
724 execv(argv[0], argv);
731 execvp(
"mpg123", argv);
734 fprintf(stderr,
"MOH: exec failed: %s\n", strerror(
errno));
746 switch (kill_method) {
748 return killpg(pid, signum);
750 return kill(pid, signum);
758 if (
killer(pid, SIGHUP, kill_method) < 0) {
759 if (
errno == ESRCH) {
764 ast_debug(1,
"Sent HUP to pid %d%s\n", pid,
768 if (
killer(pid, SIGTERM, kill_method) < 0) {
769 if (
errno == ESRCH) {
774 ast_debug(1,
"Sent TERM to pid %d%s\n", pid,
778 if (
killer(pid, SIGKILL, kill_method) < 0) {
779 if (
errno == ESRCH) {
784 ast_debug(1,
"Sent KILL to pid %d%s\n", pid,
791#define MOH_MS_INTERVAL 100
798 struct timeval deadline, tv_tmp;
801 deadline.tv_usec = 0;
803 pthread_testcancel();
805 if (class->srcfd < 0) {
806 if ((class->srcfd =
spawn_mp3(
class)) < 0) {
814 struct pollfd pfd = { .fd =
ast_timer_fd(class->timer), .events = POLLIN | POLLPRI, };
831 pthread_testcancel();
842 pthread_testcancel();
853 if ((strncasecmp(class->dir,
"http://", 7) && strcasecmp(class->dir,
"nodir")) &&
AST_LIST_EMPTY(&class->members))
858 if ((res2 = read(class->srcfd, sbuf,
len)) !=
len) {
862 pthread_testcancel();
863 if (class->pid > 1) {
864 killpid(class->pid, class->kill_delay, class->kill_method);
868 ast_debug(1,
"Read %d bytes of audio while expecting %d\n", res2,
len);
873 pthread_testcancel();
878 if ((res = write(moh->
pipe[1], sbuf, res2)) != res2) {
879 ast_debug(1,
"Only wrote %d of %d bytes to pipe\n", res, res2);
903 if (sscanf(
args.duration,
"%30d", &timeout) == 1) {
953#define get_mohbyname(a,b,c) _get_mohbyname(a,b,c,__FILE__,__LINE__,__PRETTY_FUNCTION__)
965 "get_mohbyname",
file, lineno, funcname);
1003 struct mohclass *
class = moh->parent;
1010 close(moh->
pipe[0]);
1011 close(moh->
pipe[1]);
1015 moh->
parent =
class =
mohclass_unref(class, "unreffing moh->parent upon deactivation of generator");
1135 if (!strcasecmp(
var->name,
"name")) {
1137 }
else if (!strcasecmp(
var->name,
"mode")) {
1139 }
else if (!strcasecmp(
var->name,
"entry")) {
1143 if (!playlist_entries) {
1145 if (!playlist_entries) {
1156 char *last_pos_dot = strrchr(dup,
'.');
1157 char *last_pos_slash = strrchr(dup,
'/');
1158 if (last_pos_dot && last_pos_dot > last_pos_slash) {
1159 ast_log(
LOG_WARNING,
"The playlist entry '%s' may include an extension, which could prevent it from playing.\n",
1166 ast_log(
LOG_ERROR,
"Playlist entries must be a URL or an absolute path, '%s' provided.\n",
var->value);
1168 }
else if (!strcasecmp(
var->name,
"directory")) {
1170 }
else if (!strcasecmp(
var->name,
"application")) {
1172 }
else if (!strcasecmp(
var->name,
"announcement")) {
1175 }
else if (!strcasecmp(
var->name,
"digit") && (isdigit(*
var->value) || strchr(
"*#", *
var->value))) {
1177 }
else if (!strcasecmp(
var->name,
"random")) {
1178 static int deprecation_warning = 0;
1179 if (!deprecation_warning) {
1180 ast_log(
LOG_WARNING,
"Music on hold 'random' setting is deprecated in 14. Please use 'sort=random' instead.\n");
1181 deprecation_warning = 1;
1184 }
else if (!strcasecmp(
var->name,
"sort")) {
1185 if (!strcasecmp(
var->value,
"random")) {
1187 }
else if (!strcasecmp(
var->value,
"alpha")) {
1189 }
else if (!strcasecmp(
var->value,
"randstart")) {
1192 }
else if (!strcasecmp(
var->name,
"loop_last")) {
1205 }
else if (!strcasecmp(
var->name,
"kill_escalation_delay")) {
1212 }
else if (!strcasecmp(
var->name,
"kill_method")) {
1213 if (!strcasecmp(
var->value,
"process")) {
1215 }
else if (!strcasecmp(
var->value,
"process_group")) {
1221 }
else if (!strcasecmp(
var->name,
"answeredonly")) {
1226 if (playlist_entries) {
1231 ao2_ref(playlist_entries, -1);
1244static int on_moh_file(
const char *directory,
const char *filename,
void *obj)
1251 if (*filename ==
'.') {
1252 ast_debug(4,
"Skipping '%s/%s' because it starts with a dot\n",
1253 directory, filename);
1261 ast_debug(4,
"Skipping '%s/%s' because it doesn't have an extension\n",
1262 directory, filename);
1268 ast_debug(4,
"Skipping '%s/%s' because it doesn't have at least a two "
1269 "character extension\n", directory, filename);
1276 (
int) (
extension - filename), filename) < 0) {
1301 const char **s1 = (
const char **)
a;
1302 const char **s2 = (
const char **)
b;
1303 return strcasecmp(*s1, *s2);
1308 char dir_path[
PATH_MAX -
sizeof(
class->dir)];
1311 if (class->dir[0] !=
'/') {
1317 ast_debug(4,
"Scanning '%s' for files for class '%s'\n", dir_path, class->name);
1338 class->files = files;
1355 ast_verb(3,
"Files not found in %s for moh class:%s\n",
1356 class->dir, class->name);
1370 if (!strcasecmp(
c->mode,
"files")) {
1385 if (strcmp(old->
dir, new->dir)) {
1387 }
else if (strcmp(old->
mode, new->mode)) {
1389 }
else if (strcmp(old->
args, new->args)) {
1391 }
else if (old->
flags != new->flags) {
1400 if (!strcasecmp(class->mode,
"custom")) {
1402 }
else if (!strcasecmp(class->mode,
"mp3nb")) {
1404 }
else if (!strcasecmp(class->mode,
"quietmp3nb")) {
1406 }
else if (!strcasecmp(class->mode,
"quietmp3")) {
1419 class->timer =
NULL;
1426 class->timer =
NULL;
1437#define moh_register(moh, reload, unref) _moh_register(moh, reload, unref, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1448 moh =
mohclass_unref(moh,
"unreffing potential new moh class (it is a duplicate)");
1459 if (!strcasecmp(moh->
mode,
"files")) {
1462 moh =
mohclass_unref(moh,
"unreffing potential new moh class (init_files_class failed)");
1466 }
else if (!strcasecmp(moh->
mode,
"playlist")) {
1475 moh =
mohclass_unref(moh,
"unreffing potential new moh class (no playlist entries)");
1479 }
else if (!strcasecmp(moh->
mode,
"mp3") || !strcasecmp(moh->
mode,
"mp3nb") ||
1480 !strcasecmp(moh->
mode,
"quietmp3") || !strcasecmp(moh->
mode,
"quietmp3nb") ||
1481 !strcasecmp(moh->
mode,
"httpmp3") || !strcasecmp(moh->
mode,
"custom")) {
1484 moh =
mohclass_unref(moh,
"unreffing potential new moh class (init_app_class_failed)");
1491 moh =
mohclass_unref(moh,
"unreffing potential new moh class (unknown mode)");
1499 moh =
mohclass_unref(moh,
"Unreffing new moh class because we just added it to the container");
1505#define moh_unregister(a) _moh_unregister(a,__FILE__,__LINE__,__PRETTY_FUNCTION__)
1542 int wordlen = strlen(
word);
1572 e->
command =
"moh unregister class";
1574 "Usage: moh unregister class <class>\n"
1575 " Unregisters a realtime moh class.\n";
1584 len = strlen(
a->argv[3]);
1600 ast_cli(
a->fd,
"No such realtime moh class '%s'\n",
a->argv[3]);
1610#define moh_class_malloc() _moh_class_malloc(__FILE__,__LINE__,__PRETTY_FUNCTION__)
1617 "Allocating new moh class",
file, line, funcname);
1621 class->kill_delay = 100000;
1625 if (!class->files) {
1642 char *category =
NULL;
1643 size_t entry_count = 0;
1661 if (entry_count == 0) {
1671 "Music on Hold class '%s' not found in memory/database. "
1672 "Verify your configuration.\n",
1686 int warn_if_not_in_memory = !realtime_possible;
1687 const char *classes[] = {
NULL,
NULL, interpclass,
"default"};
1691 classes[1] = mclass;
1693 classes[0] = mclass;
1712 for (i = 0; i <
ARRAY_LEN(classes); ++i) {
1715 if (!
mohclass && realtime_possible) {
1790 static int deprecation_warning = 0;
1791 if (!deprecation_warning) {
1792 ast_log(
LOG_WARNING,
"Music on hold 'application=r' setting is deprecated in 14. Please use 'sort=random' instead.\n");
1793 deprecation_warning = 1;
1900 ast_channel_latest_musicclass_set(chan,
mohclass->
name);
1931 ast_debug(1,
"Destroying MOH class '%s'\n", class->name);
1943 tid =
class->thread;
1945 pthread_cancel(tid);
1950 if (class->pid > 1) {
1952 int bytes, tbytes = 0, stime = 0;
1954 ast_debug(1,
"killing %d!\n", class->pid);
1956 stime = time(
NULL) + 2;
1957 killpid(class->pid, class->kill_delay, class->kill_method);
1960 (bytes = read(class->srcfd,
buff, 8192)) && time(
NULL) < stime) {
1961 tbytes = tbytes + bytes;
1964 ast_debug(1,
"mpg123 pid %d and child died after %d bytes read\n",
1965 class->pid, tbytes);
1968 close(class->srcfd);
1974 class->timer =
NULL;
1981 pthread_join(tid,
NULL);
2042 if (!strcasecmp(cat,
"general")) {
2044 if (!strcasecmp(
var->name,
"cachertclasses")) {
2046 }
else if (!strcasecmp(
var->name,
"preferchannelclass")) {
2065 if (!strcasecmp(class->mode,
"custom") || !strcasecmp(class->mode,
"playlist")) {
2066 strcpy(class->dir,
"nodir");
2068 ast_log(
LOG_WARNING,
"A directory must be specified for class '%s'!\n", class->name);
2078 if (
ast_strlen_zero(class->args) && !strcasecmp(class->mode,
"custom")) {
2079 ast_log(
LOG_WARNING,
"An application must be specified for class '%s'!\n", class->name);
2100 ast_verb(2,
"Destroying musiconhold processes\n");
2114 "Usage: moh reload\n"
2115 " Reloads the MusicOnHold module.\n"
2116 " Alias for 'module reload res_musiconhold.so'\n";
2122 if (
a->argc != e->
args)
2138 e->
command =
"moh show files";
2140 "Usage: moh show files\n"
2141 " Lists all loaded file-based MusicOnHold classes and their\n"
2148 if (
a->argc != e->
args)
2181 e->
command =
"moh show classes";
2183 "Usage: moh show classes\n"
2184 " Lists all MusicOnHold classes.\n";
2190 if (
a->argc != e->
args)
2196 ast_cli(
a->fd,
"\tMode: %s\n",
S_OR(class->mode,
"<none>"));
2197 ast_cli(
a->fd,
"\tDirectory: %s\n",
S_OR(class->dir,
"<none>"));
2199 ast_cli(
a->fd,
"\tAnnouncement: %s\n",
S_OR(class->announcement,
"<none>"));
2202 ast_cli(
a->fd,
"\tApplication: %s\n",
S_OR(class->args,
"<none>"));
2203 ast_cli(
a->fd,
"\tKill Escalation Delay: %zu ms\n", class->kill_delay / 1000);
2204 ast_cli(
a->fd,
"\tKill Method: %s\n",
2207 if (strcasecmp(class->mode,
"files")) {
2225 const struct mohclass *
class = obj;
2232 struct mohclass *
class = obj, *class2 = arg;
2234 return strcasecmp(class->name, class2->name) ? 0 :
2235 (flags &
MOH_NOTDELETED) && (class->delete || class2->delete) ? 0 :
2261 "disabling music on hold.\n");
2303 class =
mohclass_unref(class, "unref of class from module unload callback");
2308 ast_log(
LOG_WARNING,
"Unable to unload res_musiconhold due to active MOH channels\n");
Asterisk main include file. File version handling, generic pbx functions.
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
int ast_set_priority(int)
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy ac...
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_iterator_next(iter)
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_t_iterator_next(iter, tag)
int ao2_match_by_addr(void *obj, void *arg, int flags)
A common ao2_callback is one that matches by address.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_t_link(container, obj, tag)
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void * __ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
#define ao2_t_unlink(container, obj, tag)
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
static unsigned char * buff
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
void ast_channel_stream_set(struct ast_channel *chan, struct ast_filestream *value)
void * ast_channel_music_state(const struct ast_channel *chan)
const char * ast_channel_musicclass(const struct ast_channel *chan)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
#define ast_channel_lock(chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
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.
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.
const char * ast_channel_language(const struct ast_channel *chan)
void ast_channel_music_state_set(struct ast_channel *chan, void *value)
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
#define ast_channel_unlock(chan)
ast_channel_state
ast_channel states
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Generic File Format Support. Should be included by clients of the file handling routines....
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
#define ast_file_read_dir(dir_name, on_file, obj)
Iterate over each file in a given directory.
struct ast_filestream * ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis)
Opens stream for use in seeking, playing.
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
int ast_closestream(struct ast_filestream *f)
Closes a stream.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct stasis_message_type * ast_channel_moh_stop_type(void)
Message type for stopping music on hold on a channel.
struct stasis_message * ast_channel_blob_create_from_cache(const char *uniqueid, struct stasis_message_type *type, struct ast_json *blob)
Create a ast_channel_blob message, pulling channel state from the cache.
struct stasis_message_type * ast_channel_moh_start_type(void)
Message type for starting music on hold on a channel.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
char * strsep(char **str, const char *delims)
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define CONFIG_STATUS_FILEMISSING
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
@ CONFIG_FLAG_FILEUNCHANGED
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Asterisk locking-related definitions:
#define AST_PTHREADT_NULL
Asterisk module definitions.
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_module_ref(mod)
Hold a reference to the module.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
void ast_install_music_functions(int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
void ast_uninstall_music_functions(void)
#define ast_opt_high_priority
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_DATA_DIR
Core PBX routines and definitions.
#define ast_poll(a, b, c)
static struct ast_frame * moh_files_readframe(struct ast_channel *chan)
static char * complete_mohclass_realtime(const char *line, const char *word, int pos, int state)
Support routing for 'moh unregister class' CLI This is in charge of generating all strings that match...
static int moh_filename_strcasecmp(const void *a, const void *b)
static int moh_files_generator(struct ast_channel *chan, void *data, int len, int samples)
static void moh_release(struct ast_channel *chan, void *data)
static void moh_handle_digit(struct ast_channel *chan, char digit)
static struct ast_generator mohgen
static void moh_file_vector_destructor(void *obj)
static struct ast_cli_entry cli_moh[]
static struct ast_variable * load_realtime_musiconhold(const char *name)
static void * monmp3thread(void *data)
static int _moh_unregister(struct mohclass *moh, const char *file, int line, const char *funcname)
static void ast_moh_destroy(void)
static int play_moh_exec(struct ast_channel *chan, const char *data)
#define get_mohbyname(a, b, c)
static void local_ast_moh_stop(struct ast_channel *chan)
static int moh_class_mark(void *obj, void *arg, int flags)
static void moh_rescan_files(void)
static struct ao2_container * mohclasses
static void moh_post_stop(struct ast_channel *chan)
static int _moh_register(struct mohclass *moh, int reload, int unref, const char *file, int line, const char *funcname)
#define moh_register(moh, reload, unref)
static int moh_scan_files(struct mohclass *class)
static void killpid(int pid, size_t delay, enum kill_methods kill_method)
static int load_moh_classes(int reload)
static char * handle_cli_moh_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int init_app_class(struct mohclass *class)
static int init_files_class(struct mohclass *class)
static int stop_moh_exec(struct ast_channel *chan, const char *data)
@ KILL_METHOD_PROCESS_GROUP
#define moh_class_malloc()
static int moh_diff(struct mohclass *old, struct mohclass *new)
#define MOH_PREFERCHANNELCLASS
static void * moh_files_alloc(struct ast_channel *chan, void *params)
static struct mohdata * mohalloc(struct mohclass *cl)
static int moh_generate(struct ast_channel *chan, void *data, int len, int samples)
static int start_moh_exec(struct ast_channel *chan, const char *data)
static char * handle_cli_moh_show_classes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define mohclass_ref(class, string)
static struct ast_generator moh_file_stream
#define MOH_CACHERTCLASSES
static void moh_files_release(struct ast_channel *chan, void *data)
static int moh_class_inuse(void *obj, void *arg, int flags)
static int moh_digit_match(void *obj, void *arg, int flags)
static int moh_class_cmp(void *obj, void *arg, int flags)
static int killer(pid_t pid, int signum, enum kill_methods kill_method)
static void moh_files_write_format_change(struct ast_channel *chan, void *data)
static int on_moh_file(const char *directory, const char *filename, void *obj)
static int spawn_mp3(struct mohclass *class)
static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclass)
static void moh_class_destructor(void *obj)
static char * handle_cli_moh_show_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void moh_post_start(struct ast_channel *chan, const char *moh_class_name)
static int load_module(void)
Load the module.
static const char play_moh[]
#define moh_unregister(a)
static int unload_module(void)
static int moh_class_hash(const void *obj, const int flags)
static const char start_moh[]
static int ast_moh_files_next(struct ast_channel *chan)
static const char stop_moh[]
static void local_ast_moh_cleanup(struct ast_channel *chan)
static struct mohclass * _get_mohbyname(const char *name, int warn, int flags, const char *file, int lineno, const char *funcname)
#define mohclass_unref(class, string)
static struct mohclass * get_mohbydigit(char digit)
static struct mohclass * _moh_class_malloc(const char *file, int line, const char *funcname)
static struct ast_vector_string * moh_file_vector_alloc(int initial_capacity)
static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
static struct ast_flags global_flags[1]
static char * handle_cli_moh_unregister_class(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int moh_classes_delete_marked(void *obj, void *arg, int flags)
static void * moh_alloc(struct ast_channel *chan, void *params)
Say numbers and dates (maybe words one day too)
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Blob of data associated with a channel.
Main Channel structure associated with a channel.
const ast_string_field name
descriptor for a cli entry.
int args
This gets set in ast_cli_register()
Structure used to handle boolean flags.
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
void *(* alloc)(struct ast_channel *chan, void *params)
Abstract JSON element (object, array, string, int, ...).
Structure for variables, used for configurations and for channel variables.
String vector definitions.
structure to hold extensions
char name[MAX_MUSICCLASS]
struct ast_format * mohwfmt
struct ast_format * origwfmt
char save_pos_filename[PATH_MAX]
struct mohclass::@439 list
char name[MAX_MUSICCLASS]
struct ast_vector_string * files
struct mohclass::@438 members
enum kill_methods kill_method
struct ast_format * format
struct ast_format * origwfmt
struct mohdata::@440 list
char name[TZ_STRLEN_MAX+1]
Time-related functions and macros.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Timing source management.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
struct ast_timer * ast_timer_open(void)
Open a timer.
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Support for translation of data formats. translate.c.
#define ast_test_flag(p, flag)
#define ast_pthread_create_background(a, b, c, d)
int ast_wait_for_input(int fd, int ms)
#define ast_set2_flag(p, value, flag)
#define ast_clear_flag(p, flag)
long int ast_random(void)
#define ast_pipe_nonblock(filedes)
Create a non-blocking pipe.
#define ast_set_flag(p, flag)
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_SORT(vec, cmp)
Sort a vector in-place.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR_COMPACT(vec)
Resize a vector so that its capacity is the same as its size.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.