40 #include <sys/signal.h>
41 #include <netinet/in.h>
70 #define INITIAL_NUM_FILES 8
149 static const char set_moh[] =
"SetMusicOnHold";
168 #define MOH_QUIET (1 << 0)
169 #define MOH_SINGLE (1 << 1)
170 #define MOH_CUSTOM (1 << 2)
171 #define MOH_RANDOMIZE (1 << 3)
172 #define MOH_SORTALPHA (1 << 4)
174 #define MOH_CACHERTCLASSES (1 << 5)
177 #define MOH_NOTDELETED (1 << 30)
206 unsigned int delete:1;
221 #define LOCAL_MPG_123 "/usr/local/bin/mpg123"
222 #define MPG_123 "/usr/bin/mpg123"
227 #define mohclass_ref(class,string) (ao2_t_ref((class), +1, (string)), class)
230 #define mohclass_unref(class,string) ({ ao2_t_ref((class), -1, (string)); (struct mohclass *) NULL; })
232 #define mohclass_unref(class,string) _mohclass_unref(class, string, __FILE__,__LINE__,__PRETTY_FUNCTION__)
233 static struct mohclass *_mohclass_unref(
struct mohclass *
class,
const char *tag,
const char *file,
int line,
const char *funcname)
238 if (
__ao2_ref_debug(dup, -1, (
char *) tag, (
char *) file, line, funcname) == 2) {
239 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",
240 class, class->name, file, line, funcname);
245 __ao2_ref_debug(
class, -1, (
char *) tag, (
char *) file, line, funcname);
304 for (tries = 0; tries < 20; tries++) {
346 if (state->
samples > loc && loc) {
422 if (state->
save_total != class->total_files || strcmp(state->
name, class->name) != 0) {
424 memset(state, 0,
sizeof(*state));
436 ast_verb(3,
"Started music on hold, class '%s', on %s\n", class->name, chan->
name);
458 const char *classname = NULL;
462 class =
mohclass_unref(class, "Unreffing ao2_find from finding by digit");
490 if (!strcasecmp(class->dir,
"nodir")) {
493 dir = opendir(class->dir);
494 if (!dir && strncasecmp(class->dir,
"http://", 7)) {
501 argv[argc++] =
"mpg123";
504 argv[argc++] =
"--mono";
506 argv[argc++] =
"8000";
510 argv[argc++] =
"2048";
516 argv[argc++] =
"4096";
518 argv[argc++] =
"8192";
524 argv[argc++] = argptr;
532 argv[argc++] = argptr;
537 if (!strncasecmp(class->dir,
"http://", 7)) {
539 argv[argc++] = fns[files];
542 while ((de = readdir(dir)) && (files <
MAX_MP3S)) {
543 if ((strlen(de->d_name) > 3) &&
545 (!strcasecmp(de->d_name + strlen(de->d_name) - 4,
".raw") ||
546 !strcasecmp(de->d_name + strlen(de->d_name) - 4,
".sln"))) ||
547 !strcasecmp(de->d_name + strlen(de->d_name) - 4,
".mp3"))) {
549 argv[argc++] = fns[files];
568 if (!strncasecmp(class->dir,
"http://", 7) && time(NULL) - class->start < respawn_time) {
569 sleep(respawn_time - (time(NULL) - class->start));
574 if (class->pid < 0) {
586 dup2(fds[1], STDOUT_FILENO);
592 if (strncasecmp(class->dir,
"http://", 7) && strcasecmp(class->dir,
"nodir") && chdir(class->dir) < 0) {
596 setpgid(0, getpid());
598 execv(argv[0], argv);
605 execvp(
"mpg123", argv);
608 fprintf(stderr,
"MOH: exec failed: %s\n", strerror(
errno));
620 #define MOH_MS_INTERVAL 100
627 struct timeval deadline, tv_tmp;
630 deadline.tv_usec = 0;
632 pthread_testcancel();
634 if (class->srcfd < 0) {
635 if ((class->srcfd =
spawn_mp3(
class)) < 0) {
643 struct pollfd pfd = { .fd =
ast_timer_fd(class->timer), .events = POLLIN | POLLPRI, };
659 pthread_testcancel();
670 pthread_testcancel();
677 if ((strncasecmp(class->dir,
"http://", 7) && strcasecmp(class->dir,
"nodir")) &&
AST_LIST_EMPTY(&class->members))
682 if ((res2 = read(class->srcfd, sbuf, len)) != len) {
686 pthread_testcancel();
687 if (class->pid > 1) {
689 if (killpg(class->pid, SIGHUP) < 0) {
690 if (
errno == ESRCH) {
696 if (killpg(class->pid, SIGTERM) < 0) {
697 if (
errno == ESRCH) {
703 if (killpg(class->pid, SIGKILL) < 0) {
704 if (
errno == ESRCH) {
713 ast_debug(1,
"Read %d bytes of audio while expecting %d\n", res2, len);
718 pthread_testcancel();
723 if ((res = write(moh->
pipe[1], sbuf, res2)) != res2) {
724 ast_debug(1,
"Only wrote %d of %d bytes to pipe\n", res, res2);
748 if (sscanf(
args.duration,
"%30d", &timeout) == 1) {
755 class =
S_OR(args.class, NULL);
774 static int deprecation_warning = 0;
777 if (!deprecation_warning) {
778 deprecation_warning = 1;
779 ast_log(
LOG_WARNING,
"WaitMusicOnHold application is deprecated and will be removed. Use MusicOnHold with duration parameter instead\n");
782 if (!data || !atoi(data)) {
783 ast_log(
LOG_WARNING,
"WaitMusicOnHold requires an argument (number of seconds to wait)\n");
787 ast_log(
LOG_WARNING,
"Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->
name);
797 static int deprecation_warning = 0;
799 if (!deprecation_warning) {
800 deprecation_warning = 1;
801 ast_log(
LOG_WARNING,
"SetMusicOnHold application is deprecated and will be removed. Use Set(CHANNEL(musicclass)=...) instead\n");
824 class =
S_OR(args.class, NULL);
838 #define get_mohbyname(a,b,c) _get_mohbyname(a,b,c,__FILE__,__LINE__,__PRETTY_FUNCTION__)
850 moh =
__ao2_find_debug(mohclasses, &tmp_class, flags,
"get_mohbyname", (
char *) file, lineno, funcname);
852 moh =
__ao2_find(mohclasses, &tmp_class, flags);
877 flags = fcntl(moh->
pipe[0], F_GETFL);
878 fcntl(moh->
pipe[0], F_SETFL, flags | O_NONBLOCK);
879 flags = fcntl(moh->
pipe[1], F_GETFL);
880 fcntl(moh->
pipe[1], F_SETFL, flags | O_NONBLOCK);
897 struct mohdata *
moh = data;
898 struct mohclass *
class = moh->parent;
910 moh->
parent =
class =
mohclass_unref(class, "unreffing moh->parent upon deactivation of generator");
918 if (state && state->
class) {
926 ast_verb(3,
"Stopped music on hold on %s\n", chan->
name);
949 memset(state, 0,
sizeof(*state));
968 struct mohdata *
moh = data;
1003 if (!class->allowed_files) {
1005 if (!class->filearray) {
1009 }
else if (class->total_files == class->allowed_files) {
1012 new_array =
ast_realloc(class->filearray, class->allowed_files *
sizeof(*class->filearray) * 2);
1016 class->filearray = new_array;
1017 class->allowed_files *= 2;
1020 class->filearray[
class->total_files] =
ast_strdup(filepath);
1021 if (!class->filearray[class->total_files]) {
1025 class->total_files++;
1034 s1 = ((
char **)i1)[0];
1035 s2 = ((
char **)i2)[0];
1037 return strcasecmp(s1, s2);
1043 struct dirent *files_dirent;
1044 char dir_path[PATH_MAX];
1045 char path[PATH_MAX];
1046 char filepath[PATH_MAX];
1048 struct stat statbuf;
1051 if (class->dir[0] !=
'/') {
1053 strncat(dir_path,
"/",
sizeof(dir_path) - 1);
1054 strncat(dir_path, class->dir,
sizeof(dir_path) - 1);
1058 ast_debug(4,
"Scanning '%s' for files for class '%s'\n", dir_path, class->name);
1059 files_DIR = opendir(dir_path);
1065 for (i = 0; i <
class->total_files; i++)
1068 class->total_files = 0;
1069 if (!getcwd(path,
sizeof(path))) {
1071 closedir(files_DIR);
1074 if (chdir(dir_path) < 0) {
1076 closedir(files_DIR);
1079 while ((files_dirent = readdir(files_DIR))) {
1081 if ((strlen(files_dirent->d_name) < 4))
1085 if (files_dirent->d_name[0] ==
'.')
1089 if (!strchr(files_dirent->d_name,
'.'))
1092 snprintf(filepath,
sizeof(filepath),
"%s/%s", dir_path, files_dirent->d_name);
1094 if (stat(filepath, &statbuf))
1097 if (!S_ISREG(statbuf.st_mode))
1100 if ((ext = strrchr(filepath,
'.')))
1104 for (i = 0; i <
class->total_files; i++)
1105 if (!strcmp(filepath, class->filearray[i]))
1108 if (i == class->total_files) {
1114 closedir(files_DIR);
1115 if (chdir(path) < 0) {
1120 qsort(&class->filearray[0], class->total_files,
sizeof(
char *),
moh_sort_compare);
1121 return class->total_files;
1137 class->dir, class->name);
1152 if (!strcasecmp(c->
mode,
"files")) {
1167 if (strcmp(old->
dir, new->dir)) {
1169 }
else if (strcmp(old->
mode, new->mode)) {
1171 }
else if (strcmp(old->
args, new->args)) {
1173 }
else if (old->
flags != new->flags) {
1182 if (!strcasecmp(class->mode,
"custom")) {
1184 }
else if (!strcasecmp(class->mode,
"mp3nb")) {
1186 }
else if (!strcasecmp(class->mode,
"quietmp3nb")) {
1188 }
else if (!strcasecmp(class->mode,
"quietmp3")) {
1201 class->timer = NULL;
1208 class->timer = NULL;
1219 #define moh_register(a,b,c) _moh_register(a,b,c,__FILE__,__LINE__,__PRETTY_FUNCTION__)
1226 if (mohclass && !
moh_diff(mohclass, moh)) {
1228 mohclass =
mohclass_unref(mohclass,
"unreffing mohclass we just found by name");
1230 moh =
mohclass_unref(moh,
"unreffing potential new moh class (it is a duplicate)");
1233 }
else if (mohclass) {
1235 mohclass =
mohclass_unref(mohclass,
"unreffing mohclass we just found by name");
1241 if (!strcasecmp(moh->
mode,
"files")) {
1244 moh =
mohclass_unref(moh,
"unreffing potential new moh class (init_files_class failed)");
1248 }
else if (!strcasecmp(moh->
mode,
"mp3") || !strcasecmp(moh->
mode,
"mp3nb") ||
1249 !strcasecmp(moh->
mode,
"quietmp3") || !strcasecmp(moh->
mode,
"quietmp3nb") ||
1250 !strcasecmp(moh->
mode,
"httpmp3") || !strcasecmp(moh->
mode,
"custom")) {
1253 moh =
mohclass_unref(moh,
"unreffing potential new moh class (init_app_class_failed)");
1260 moh =
mohclass_unref(moh,
"unreffing potential new moh class (unknown mode)");
1265 ao2_t_link(mohclasses, moh,
"Adding class to container");
1268 moh =
mohclass_unref(moh,
"Unreffing new moh class because we just added it to the container");
1294 #define moh_class_malloc() _moh_class_malloc(__FILE__,__LINE__,__PRETTY_FUNCTION__)
1337 if (!mohclass && realtime_possible) {
1343 if (!mohclass && realtime_possible) {
1349 if (!mohclass && realtime_possible) {
1354 if (!mohclass && !var) {
1356 if (!mohclass && realtime_possible) {
1369 for (tmp = var; tmp; tmp = tmp->
next) {
1370 if (!strcasecmp(tmp->
name,
"name"))
1372 else if (!strcasecmp(tmp->
name,
"mode"))
1374 else if (!strcasecmp(tmp->
name,
"directory"))
1376 else if (!strcasecmp(tmp->
name,
"application"))
1378 else if (!strcasecmp(tmp->
name,
"digit") && (isdigit(*tmp->
value) || strchr(
"*#", *tmp->
value)))
1380 else if (!strcasecmp(tmp->
name,
"random"))
1382 else if (!strcasecmp(tmp->
name,
"sort") && !strcasecmp(tmp->
value,
"random"))
1384 else if (!strcasecmp(tmp->
name,
"sort") && !strcasecmp(tmp->
value,
"alpha"))
1386 else if (!strcasecmp(tmp->
name,
"format")) {
1396 if (!strcasecmp(mohclass->
mode,
"custom")) {
1397 strcpy(mohclass->
dir,
"nodir");
1400 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (no directory specified)");
1406 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (no mode specified)");
1411 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (no app specified for custom mode");
1417 if (state && state->
class) {
1428 mohclass =
mohclass_unref(mohclass,
"unreffing mohclass failed to register");
1434 time(&mohclass->
start);
1437 if (!strcasecmp(mohclass->
mode,
"files")) {
1439 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (moh_scan_files failed)");
1442 if (strchr(mohclass->
args,
'r'))
1444 }
else if (!strcasecmp(mohclass->
mode,
"mp3") || !strcasecmp(mohclass->
mode,
"mp3nb") || !strcasecmp(mohclass->
mode,
"quietmp3") || !strcasecmp(mohclass->
mode,
"quietmp3nb") || !strcasecmp(mohclass->
mode,
"httpmp3") || !strcasecmp(mohclass->
mode,
"custom")) {
1446 if (!strcasecmp(mohclass->
mode,
"custom"))
1448 else if (!strcasecmp(mohclass->
mode,
"mp3nb"))
1450 else if (!strcasecmp(mohclass->
mode,
"quietmp3nb"))
1452 else if (!strcasecmp(mohclass->
mode,
"quietmp3"))
1455 mohclass->
srcfd = -1;
1462 mohclass->
timer = NULL;
1466 if (state && state->
class) {
1471 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (channel already has one)");
1477 if (mohclass->
timer) {
1479 mohclass->
timer = NULL;
1481 mohclass =
mohclass_unref(mohclass,
"Unreffing potential mohclass (failed to create background thread)");
1487 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (unknown mode)");
1504 mohclass =
mohclass_unref(mohclass,
"unreffing potential mohclass (moh_scan_files failed)");
1527 mohclass =
mohclass_unref(mohclass,
"unreffing local reference to mohclass in local_ast_moh_start");
1559 ast_debug(1,
"Destroying MOH class '%s'\n", class->name);
1570 tid =
class->thread;
1572 pthread_cancel(tid);
1577 if (class->pid > 1) {
1579 int bytes, tbytes = 0, stime = 0,
pid = 0;
1583 stime = time(NULL) + 2;
1591 if (killpg(
pid, SIGHUP) < 0) {
1595 if (killpg(
pid, SIGTERM) < 0) {
1596 if (
errno == ESRCH) {
1602 if (killpg(
pid, SIGKILL) < 0) {
1603 if (
errno == ESRCH) {
1611 (bytes = read(class->srcfd, buff, 8192)) && time(NULL) < stime) {
1612 tbytes = tbytes + bytes;
1617 close(class->srcfd);
1621 if (class->filearray) {
1623 for (i = 0; i <
class->total_files; i++) {
1627 class->filearray = NULL;
1632 class->timer = NULL;
1637 pthread_join(tid, NULL);
1690 if (!strcasecmp(cat,
"general")) {
1692 if (!strcasecmp(var->
name,
"cachertclasses")) {
1700 if (!strcasecmp(cat,
"classes") || !strcasecmp(cat,
"moh_files") ||
1701 !strcasecmp(cat,
"general")) {
1711 if (!strcasecmp(var->
name,
"mode"))
1713 else if (!strcasecmp(var->
name,
"directory"))
1715 else if (!strcasecmp(var->
name,
"application"))
1717 else if (!strcasecmp(var->
name,
"digit") && (isdigit(*var->
value) || strchr(
"*#", *var->
value)))
1718 class->digit = *var->
value;
1719 else if (!strcasecmp(var->
name,
"random"))
1721 else if (!strcasecmp(var->
name,
"sort") && !strcasecmp(var->
value,
"random"))
1723 else if (!strcasecmp(var->
name,
"sort") && !strcasecmp(var->
value,
"alpha"))
1725 else if (!strcasecmp(var->
name,
"format")) {
1727 if (!class->format) {
1735 if (!strcasecmp(class->mode,
"custom")) {
1736 strcpy(class->dir,
"nodir");
1738 ast_log(
LOG_WARNING,
"A directory must be specified for class '%s'!\n", class->name);
1739 class =
mohclass_unref(class, "unreffing potential mohclass (no directory)");
1745 class =
mohclass_unref(class, "unreffing potential mohclass (no mode)");
1748 if (
ast_strlen_zero(class->args) && !strcasecmp(class->mode,
"custom")) {
1749 ast_log(
LOG_WARNING,
"An application must be specified for class '%s'!\n", class->name);
1750 class =
mohclass_unref(class, "unreffing potential mohclass (no app for custom mode)");
1770 ast_verb(2,
"Destroying musiconhold processes\n");
1784 "Usage: moh reload\n"
1785 " Reloads the MusicOnHold module.\n"
1786 " Alias for 'module reload res_musiconhold.so'\n";
1807 e->
command =
"moh show files";
1809 "Usage: moh show files\n"
1810 " Lists all loaded file-based MusicOnHold classes and their\n"
1824 if (!class->total_files) {
1828 ast_cli(a->
fd,
"Class: %s\n", class->name);
1829 for (x = 0; x <
class->total_files; x++) {
1830 ast_cli(a->
fd,
"\tFile: %s\n", class->filearray[x]);
1845 e->
command =
"moh show classes";
1847 "Usage: moh show classes\n"
1848 " Lists all MusicOnHold classes.\n";
1859 ast_cli(a->
fd,
"Class: %s\n", class->name);
1860 ast_cli(a->
fd,
"\tMode: %s\n",
S_OR(class->mode,
"<none>"));
1861 ast_cli(a->
fd,
"\tDirectory: %s\n",
S_OR(class->dir,
"<none>"));
1863 ast_cli(a->
fd,
"\tApplication: %s\n",
S_OR(class->args,
"<none>"));
1865 if (strcasecmp(class->mode,
"files")) {
1882 const struct mohclass *
class = obj;
1889 struct mohclass *
class = obj, *class2 = arg;
1891 return strcasecmp(class->name, class2->name) ? 0 :
1892 (flags &
MOH_NOTDELETED) && (class->delete || class2->delete) ? 0 :
1906 "disabling music on hold.\n");
1952 class =
mohclass_unref(class, "unref of class from module unload callback");
1957 ast_log(
LOG_WARNING,
"Unable to unload res_musiconhold due to active MOH channels\n");
static int _moh_register(struct mohclass *moh, int reload, int unref, const char *file, int line, const char *funcname)
static int stop_moh_exec(struct ast_channel *chan, const char *data)
static struct ao2_container * mohclasses
static char musicclass[MAX_MUSICCLASS]
static void moh_release(struct ast_channel *chan, void *data)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
static int wait_moh_exec(struct ast_channel *chan, const char *data)
union ast_frame_subclass subclass
enum sip_cc_notify_state state
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
#define AST_CLI_DEFINE(fn, txt,...)
char name[MAX_MUSICCLASS]
static struct ast_frame * moh_files_readframe(struct ast_channel *chan)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
static int init_files_class(struct mohclass *class)
void ast_module_unref(struct ast_module *)
static int moh_sort_compare(const void *i1, const void *i2)
char * strsep(char **str, const char *delims)
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child...
static int moh_digit_match(void *obj, void *arg, int flags)
const ast_string_field uniqueid
static const char stop_moh[]
static int moh_files_generator(struct ast_channel *chan, void *data, int len, int samples)
static int moh_classes_delete_marked(void *obj, void *arg, int flags)
static const char set_moh[]
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define moh_register(a, b, c)
static int start_moh_exec(struct ast_channel *chan, const char *data)
#define ast_set2_flag(p, value, flag)
#define ast_test_flag(p, flag)
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
Support for translation of data formats. translate.c.
Time-related functions and macros.
static int load_moh_classes(int reload)
#define ao2_iterator_next(arg1)
#define ast_set_flag(p, flag)
descriptor for a cli entry.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
#define ao2_callback(c, flags, cb_fn, arg)
void ast_verbose(const char *fmt,...)
static struct ast_cli_entry cli_moh[]
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
void * __ao2_find(struct ao2_container *c, void *arg, enum search_flags flags)
Structure for variables, used for configurations and for channel variables.
#define ao2_t_iterator_next(arg1, arg2)
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
#define __AST_DEBUG_MALLOC
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
static int init_app_class(struct mohclass *class)
Configuration File Parser.
struct ast_timer * ast_timer_open(void)
Open a timer.
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
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.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
static void * moh_files_alloc(struct ast_channel *chan, void *params)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define ao2_t_container_alloc(arg1, arg2, arg3, arg4)
Allocate and initialize a container with the desired number of buckets.
void ast_cli(int fd, const char *fmt,...)
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static struct mohclass * _moh_class_malloc(const char *file, int line, const char *funcname)
int ast_unregister_application(const char *app)
Unregister an application.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
static void ast_moh_destroy(void)
static int moh_scan_files(struct mohclass *class)
#define INITIAL_NUM_FILES
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
static struct mohdata * mohalloc(struct mohclass *cl)
void ast_uninstall_music_functions(void)
#define mohclass_ref(class, string)
struct mohclass::@334 members
String fields in structures.
#define ao2_t_link(arg1, arg2, arg3)
Add an object to a container.
int args
This gets set in ast_cli_register()
static void local_ast_moh_cleanup(struct ast_channel *chan)
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
#define ast_manager_event(chan, category, event, contents,...)
#define ast_pthread_create_background(a, b, c, d)
#define CONFIG_STATUS_FILEMISSING
static void moh_rescan_files(void)
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of "format" is ...
static void local_ast_moh_stop(struct ast_channel *chan)
#define ast_debug(level,...)
Log a DEBUG message.
char save_pos_filename[PATH_MAX]
void * __ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, char *tag, const char *file, int line, const char *funcname, int ref_debug)
static int set_moh_exec(struct ast_channel *chan, const char *data)
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
Asterisk file paths, configured in asterisk.conf.
void ast_unregister_atexit(void(*func)(void))
Unregister a function registered with ast_register_atexit().
#define MOH_CACHERTCLASSES
#define ast_config_load(filename, flags)
Load a config file.
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_poll(a, b, c)
static char * handle_cli_moh_show_classes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define ao2_ref(o, delta)
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
long int ast_random(void)
static struct mohclass * _get_mohbyname(const char *name, int warn, int flags, const char *file, int lineno, const char *funcname)
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 ...
A set of macros to manage forward-linked lists.
static void moh_handle_digit(struct ast_channel *chan, char digit)
static int moh_class_inuse(void *obj, void *arg, int flags)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static char * handle_cli_moh_show_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Core PBX routines and definitions.
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...
static int moh_diff(struct mohclass *old, struct mohclass *new)
static const char start_moh[]
const char * ast_config_AST_DATA_DIR
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#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_strdupa(s)
duplicate a string in memory from the stack
format_t ast_getformatbyname(const char *name)
Gets a format from a name.
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
static int play_moh_exec(struct ast_channel *chan, const char *data)
char * ast_getformatname(format_t format)
Get the name of a format.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
static int unload_module(void)
static void moh_files_release(struct ast_channel *chan, void *data)
struct mohclass::@335 list
struct ast_frame * ast_readframe(struct ast_filestream *s)
Read a frame from a filestream.
static int moh_class_cmp(void *obj, void *arg, int flags)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
const ast_string_field name
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
static struct ast_generator moh_file_stream
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
#define ao2_alloc(data_size, destructor_fn)
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#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_channel_unlock(chan)
void *(* alloc)(struct ast_channel *chan, void *params)
static void parse(struct mgcp_request *req)
int ast_closestream(struct ast_filestream *f)
Closes a stream.
static int moh_generate(struct ast_channel *chan, void *data, int len, int samples)
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
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 *))
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.
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Structure used to handle boolean flags.
#define ast_clear_flag(p, flag)
ao2_callback_fn ao2_match_by_addr
a very common callback is one that matches by address.
static struct ast_flags global_flags[1]
static int moh_class_mark(void *obj, void *arg, int flags)
void ast_deactivate_generator(struct ast_channel *chan)
static int moh_class_hash(const void *obj, const int flags)
#define AST_FORMAT_SLINEAR
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static unsigned char * buff
int ast_codec_get_samples(struct ast_frame *f)
Returns the number of samples contained in the frame.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define ast_realloc(a, b)
static const char wait_moh[]
static void moh_class_destructor(void *obj)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
static char * handle_cli_moh_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int moh_add_file(struct mohclass *class, const char *filepath)
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const ast_string_field musicclass
Data structure associated with a single frame of data.
void * __ao2_find_debug(struct ao2_container *c, void *arg, enum search_flags flags, char *tag, char *file, int line, const char *funcname)
#define mohclass_unref(class, string)
int ast_wait_for_input(int fd, int ms)
#define AST_APP_ARG(name)
Define an application argument.
enum ast_frame_type frametype
struct ast_variable * next
static const char play_moh[]
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int __ao2_ref_debug(void *o, int delta, const char *tag, const char *file, int line, const char *funcname)
#define CONFIG_STATUS_FILEINVALID
struct ast_filestream * stream
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
static struct ast_generator mohgen
static struct mohclass * get_mohbydigit(char digit)
char name[MAX_MUSICCLASS]
static void * monmp3thread(void *data)
union ast_frame::@172 data
int ast_codec_get_len(format_t format, int samples)
Returns the number of bytes for the number of samples of the given format.
static void * moh_alloc(struct ast_channel *chan, void *params)
#define moh_class_malloc()
static int ast_moh_files_next(struct ast_channel *chan)
static int load_module(void)
const ast_string_field language
Timing source management.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
#define get_mohbyname(a, b, c)
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define ast_opt_high_priority
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
static int spawn_mp3(struct mohclass *class)
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
char * ast_codec2str(format_t codec)
Get a name from a format Gets a name from a format.
struct ast_module * ast_module_ref(struct ast_module *)