#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/say.h"
#include "asterisk/musiconhold.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
Include dependency graph for res_musiconhold.c:
Go to the source code of this file.
Defines | |
#define | LOCAL_MPG_123 "/usr/local/bin/mpg123" |
#define | MAX_MOHFILE_LEN 128 |
#define | MAX_MOHFILES 512 |
#define | MAX_MP3S 256 |
#define | MOH_CUSTOM (1 << 2) |
#define | MOH_MS_INTERVAL 100 |
#define | MOH_QUIET (1 << 0) |
#define | MOH_RANDOMIZE (1 << 3) |
#define | MOH_SINGLE (1 << 1) |
#define | MPG_123 "/usr/bin/mpg123" |
Functions | |
static void | ast_moh_destroy (void) |
static int | ast_moh_files_next (struct ast_channel *chan) |
static void | ast_moh_free_class (struct mohclass **class) |
AST_MUTEX_DEFINE_STATIC (moh_lock) | |
static int | cli_files_show (int fd, int argc, char *argv[]) |
char * | description (void) |
Provides a description of the module. | |
static struct mohclass * | get_mohbyname (char *name) |
static int | init_classes (int reload) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static int | load_moh_classes (int reload) |
static void | local_ast_moh_cleanup (struct ast_channel *chan) |
static int | local_ast_moh_start (struct ast_channel *chan, char *class) |
static void | local_ast_moh_stop (struct ast_channel *chan) |
static int | moh0_exec (struct ast_channel *chan, void *data) |
static int | moh1_exec (struct ast_channel *chan, void *data) |
static int | moh2_exec (struct ast_channel *chan, void *data) |
static int | moh3_exec (struct ast_channel *chan, void *data) |
static int | moh4_exec (struct ast_channel *chan, void *data) |
static void * | moh_alloc (struct ast_channel *chan, void *params) |
static struct mohclass * | moh_class_malloc (void) |
static int | moh_classes_show (int fd, int argc, char *argv[]) |
static int | moh_cli (int fd, int argc, char *argv[]) |
static void * | moh_files_alloc (struct ast_channel *chan, void *params) |
static int | moh_files_generator (struct ast_channel *chan, void *data, int len, int samples) |
static struct ast_frame * | moh_files_readframe (struct ast_channel *chan) |
static void | moh_files_release (struct ast_channel *chan, void *data) |
static int | moh_generate (struct ast_channel *chan, void *data, int len, int samples) |
static void | moh_on_off (int on) |
static int | moh_register (struct mohclass *moh, int reload) |
static void | moh_release (struct ast_channel *chan, void *data) |
static int | moh_scan_files (struct mohclass *class) |
static struct mohdata * | mohalloc (struct mohclass *cl) |
static void * | monmp3thread (void *data) |
int | reload (void) |
Reload stuff. | |
static int | spawn_mp3 (struct mohclass *class) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static char * | app0 = "MusicOnHold" |
static char * | app1 = "WaitMusicOnHold" |
static char * | app2 = "SetMusicOnHold" |
static char * | app3 = "StartMusicOnHold" |
static char * | app4 = "StopMusicOnHold" |
static struct ast_cli_entry | cli_moh = { { "moh", "reload"}, moh_cli, "Music On Hold", "Music On Hold", NULL} |
static struct ast_cli_entry | cli_moh_classes_show = { { "moh", "classes", "show"}, moh_classes_show, "List MOH classes", "Lists all MOH classes", NULL} |
static struct ast_cli_entry | cli_moh_files_show = { { "moh", "files", "show"}, cli_files_show, "List MOH file-based classes", "Lists all loaded file-based MOH classes and their files", NULL} |
static char * | descrip0 |
static char * | descrip1 |
static char * | descrip2 |
static char * | descrip3 |
static char * | descrip4 |
static struct ast_generator | moh_file_stream |
static struct mohclass * | mohclasses |
static struct ast_generator | mohgen |
static int | respawn_time = 20 |
static char * | synopsis0 = "Play Music On Hold indefinitely" |
static char * | synopsis1 = "Wait, playing Music On Hold" |
static char * | synopsis2 = "Set default Music On Hold class" |
static char * | synopsis3 = "Play Music On Hold" |
static char * | synopsis4 = "Stop Playing Music On Hold" |
Definition in file res_musiconhold.c.
|
Definition at line 154 of file res_musiconhold.c. |
|
Definition at line 68 of file res_musiconhold.c. Referenced by moh_scan_files(). |
|
Definition at line 67 of file res_musiconhold.c. Referenced by moh_scan_files(). |
|
Definition at line 156 of file res_musiconhold.c. Referenced by spawn_mp3(). |
|
Definition at line 120 of file res_musiconhold.c. Referenced by moh_classes_show(), moh_register(), and spawn_mp3(). |
|
Referenced by monmp3thread(). |
|
Definition at line 118 of file res_musiconhold.c. Referenced by moh_register(), and spawn_mp3(). |
|
Definition at line 121 of file res_musiconhold.c. Referenced by ast_moh_files_next(), load_moh_classes(), and moh_register(). |
|
Definition at line 119 of file res_musiconhold.c. Referenced by moh_register(), and spawn_mp3(). |
|
Definition at line 155 of file res_musiconhold.c. |
|
Definition at line 1074 of file res_musiconhold.c. References ast_log(), ast_moh_free_class(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_wait_for_input(), LOG_DEBUG, moh, mohclass::next, option_verbose, mohclass::pid, mohclass::srcfd, and VERBOSE_PREFIX_2. Referenced by load_module(), and moh_cli(). 01075 { 01076 struct mohclass *moh, *tmp; 01077 char buff[8192]; 01078 int bytes, tbytes=0, stime = 0, pid = 0; 01079 01080 if (option_verbose > 1) 01081 ast_verbose(VERBOSE_PREFIX_2 "Destroying musiconhold processes\n"); 01082 ast_mutex_lock(&moh_lock); 01083 moh = mohclasses; 01084 01085 while (moh) { 01086 if (moh->pid) { 01087 ast_log(LOG_DEBUG, "killing %d!\n", moh->pid); 01088 stime = time(NULL) + 2; 01089 pid = moh->pid; 01090 moh->pid = 0; 01091 /* Back when this was just mpg123, SIGKILL was fine. Now we need 01092 * to give the process a reason and time enough to kill off its 01093 * children. */ 01094 kill(pid, SIGHUP); 01095 usleep(100000); 01096 kill(pid, SIGTERM); 01097 usleep(100000); 01098 kill(pid, SIGKILL); 01099 while ((ast_wait_for_input(moh->srcfd, 100) > 0) && (bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime) { 01100 tbytes = tbytes + bytes; 01101 } 01102 ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", pid, tbytes); 01103 close(moh->srcfd); 01104 } 01105 tmp = moh; 01106 moh = moh->next; 01107 ast_moh_free_class(&tmp); 01108 } 01109 mohclasses = NULL; 01110 ast_mutex_unlock(&moh_lock); 01111 }
|
|
Definition at line 194 of file res_musiconhold.c. References ast_closestream(), ast_fileexists(), ast_log(), ast_openstream_full(), ast_seekstream(), ast_test_flag, moh_files_state::class, mohclass::filearray, ast_channel::language, LOG_DEBUG, LOG_WARNING, MOH_RANDOMIZE, ast_channel::music_state, ast_channel::name, option_debug, moh_files_state::pos, moh_files_state::samples, moh_files_state::save_pos, ast_channel::stream, and mohclass::total_files. Referenced by moh_files_readframe(). 00195 { 00196 struct moh_files_state *state = chan->music_state; 00197 int tries; 00198 00199 if (state->save_pos) { 00200 state->pos = state->save_pos - 1; 00201 state->save_pos = 0; 00202 } else { 00203 /* Try 20 times to find something good */ 00204 for (tries=0;tries < 20;tries++) { 00205 state->samples = 0; 00206 if (chan->stream) { 00207 ast_closestream(chan->stream); 00208 chan->stream = NULL; 00209 state->pos++; 00210 } 00211 00212 if (ast_test_flag(state->class, MOH_RANDOMIZE)) 00213 state->pos = rand(); 00214 00215 state->pos %= state->class->total_files; 00216 00217 /* check to see if this file's format can be opened */ 00218 if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) != -1) 00219 break; 00220 00221 } 00222 } 00223 00224 state->pos = state->pos % state->class->total_files; 00225 00226 if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) { 00227 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno)); 00228 state->pos++; 00229 return -1; 00230 } 00231 00232 if (option_debug) 00233 ast_log(LOG_DEBUG, "%s Opened file %d '%s'\n", chan->name, state->pos, state->class->filearray[state->pos]); 00234 00235 if (state->samples) 00236 ast_seekstream(chan->stream, state->samples, SEEK_SET); 00237 00238 return 0; 00239 }
|
|
Definition at line 159 of file res_musiconhold.c. References free, and mohdata::next. Referenced by ast_moh_destroy(), and moh_register(). 00160 { 00161 struct mohdata *members, *mtmp; 00162 00163 members = (*class)->members; 00164 while(members) { 00165 mtmp = members; 00166 members = members->next; 00167 free(mtmp); 00168 } 00169 if ((*class)->thread) { 00170 pthread_cancel((*class)->thread); 00171 (*class)->thread = 0; 00172 } 00173 free(*class); 00174 *class = NULL; 00175 }
|
|
|
|
Definition at line 1140 of file res_musiconhold.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), mohclass::next, and mohclass::total_files. 01141 { 01142 int i; 01143 struct mohclass *class; 01144 01145 ast_mutex_lock(&moh_lock); 01146 for (class = mohclasses; class; class = class->next) { 01147 if (!class->total_files) 01148 continue; 01149 01150 ast_cli(fd, "Class: %s\n", class->name); 01151 for (i = 0; i < class->total_files; i++) 01152 ast_cli(fd, "\tFile: %s\n", class->filearray[i]); 01153 } 01154 ast_mutex_unlock(&moh_lock); 01155 01156 return 0; 01157 }
|
|
Provides a description of the module.
Definition at line 1238 of file res_musiconhold.c. 01239 { 01240 return "Music On Hold Resource"; 01241 }
|
|
Definition at line 608 of file res_musiconhold.c. References moh, mohclass::name, and mohclass::next. Referenced by load_moh_classes(), local_ast_moh_start(), and moh_register(). 00609 { 00610 struct mohclass *moh; 00611 moh = mohclasses; 00612 while (moh) { 00613 if (!strcasecmp(name, moh->name)) 00614 return moh; 00615 moh = moh->next; 00616 } 00617 return NULL; 00618 }
|
|
Definition at line 1183 of file res_musiconhold.c. References load_moh_classes(), moh, and moh_scan_files(). Referenced by load_module(), and reload(). 01184 { 01185 struct mohclass *moh; 01186 01187 if (!load_moh_classes(reload)) /* Load classes from config */ 01188 return 0; /* Return if nothing is found */ 01189 moh = mohclasses; 01190 while (moh) { 01191 if (moh->total_files) 01192 moh_scan_files(moh); 01193 moh = moh->next; 01194 } 01195 return 1; 01196 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 1256 of file res_musiconhold.c. References ASTERISK_GPL_KEY. 01257 { 01258 return ASTERISK_GPL_KEY; 01259 }
|
|
|
Definition at line 936 of file res_musiconhold.c. References mohclass::args, ast_category_browse(), ast_config_destroy(), ast_config_load(), AST_FORMAT_SLINEAR, ast_getformatbyname(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), cfg, dep_warning, free, get_mohbyname(), LOG_WARNING, moh_class_malloc(), MOH_RANDOMIZE, moh_register(), ast_variable::name, ast_variable::next, ast_variable::value, and var. Referenced by init_classes(), and moh_cli(). 00937 { 00938 struct ast_config *cfg; 00939 struct ast_variable *var; 00940 struct mohclass *class; 00941 char *data; 00942 char *args; 00943 char *cat; 00944 int numclasses = 0; 00945 static int dep_warning = 0; 00946 00947 cfg = ast_config_load("musiconhold.conf"); 00948 00949 if (!cfg) 00950 return 0; 00951 00952 cat = ast_category_browse(cfg, NULL); 00953 for (; cat; cat = ast_category_browse(cfg, cat)) { 00954 if (strcasecmp(cat, "classes") && strcasecmp(cat, "moh_files")) { 00955 class = moh_class_malloc(); 00956 if (!class) { 00957 ast_log(LOG_WARNING, "Out of memory!\n"); 00958 break; 00959 } 00960 ast_copy_string(class->name, cat, sizeof(class->name)); 00961 var = ast_variable_browse(cfg, cat); 00962 while (var) { 00963 if (!strcasecmp(var->name, "mode")) 00964 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 00965 else if (!strcasecmp(var->name, "directory")) 00966 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 00967 else if (!strcasecmp(var->name, "application")) 00968 ast_copy_string(class->args, var->value, sizeof(class->args)); 00969 else if (!strcasecmp(var->name, "random")) 00970 ast_set2_flag(class, ast_true(var->value), MOH_RANDOMIZE); 00971 else if (!strcasecmp(var->name, "format")) { 00972 class->format = ast_getformatbyname(var->value); 00973 if (!class->format) { 00974 ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value); 00975 class->format = AST_FORMAT_SLINEAR; 00976 } 00977 } 00978 var = var->next; 00979 } 00980 00981 if (ast_strlen_zero(class->dir)) { 00982 if (!strcasecmp(class->mode, "custom")) { 00983 strcpy(class->dir, "nodir"); 00984 } else { 00985 ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", class->name); 00986 free(class); 00987 continue; 00988 } 00989 } 00990 if (ast_strlen_zero(class->mode)) { 00991 ast_log(LOG_WARNING, "A mode must be specified for class '%s'!\n", class->name); 00992 free(class); 00993 continue; 00994 } 00995 if (ast_strlen_zero(class->args) && !strcasecmp(class->mode, "custom")) { 00996 ast_log(LOG_WARNING, "An application must be specified for class '%s'!\n", class->name); 00997 free(class); 00998 continue; 00999 } 01000 01001 /* Don't leak a class when it's already registered */ 01002 moh_register(class, reload); 01003 01004 numclasses++; 01005 } 01006 } 01007 01008 01009 /* Deprecated Old-School Configuration */ 01010 var = ast_variable_browse(cfg, "classes"); 01011 while (var) { 01012 if (!dep_warning) { 01013 ast_log(LOG_WARNING, "The old musiconhold.conf syntax has been deprecated! Please refer to the sample configuration for information on the new syntax.\n"); 01014 dep_warning = 1; 01015 } 01016 data = strchr(var->value, ':'); 01017 if (data) { 01018 *data++ = '\0'; 01019 args = strchr(data, ','); 01020 if (args) 01021 *args++ = '\0'; 01022 if (!(get_mohbyname(var->name))) { 01023 class = moh_class_malloc(); 01024 if (!class) { 01025 ast_log(LOG_WARNING, "Out of memory!\n"); 01026 return numclasses; 01027 } 01028 01029 ast_copy_string(class->name, var->name, sizeof(class->name)); 01030 ast_copy_string(class->dir, data, sizeof(class->dir)); 01031 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 01032 if (args) 01033 ast_copy_string(class->args, args, sizeof(class->args)); 01034 01035 moh_register(class, reload); 01036 numclasses++; 01037 } 01038 } 01039 var = var->next; 01040 } 01041 var = ast_variable_browse(cfg, "moh_files"); 01042 while (var) { 01043 if (!dep_warning) { 01044 ast_log(LOG_WARNING, "The old musiconhold.conf syntax has been deprecated! Please refer to the sample configuration for information on the new syntax.\n"); 01045 dep_warning = 1; 01046 } 01047 if (!(get_mohbyname(var->name))) { 01048 args = strchr(var->value, ','); 01049 if (args) 01050 *args++ = '\0'; 01051 class = moh_class_malloc(); 01052 if (!class) { 01053 ast_log(LOG_WARNING, "Out of memory!\n"); 01054 return numclasses; 01055 } 01056 01057 ast_copy_string(class->name, var->name, sizeof(class->name)); 01058 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 01059 strcpy(class->mode, "files"); 01060 if (args) 01061 ast_copy_string(class->args, args, sizeof(class->args)); 01062 01063 moh_register(class, reload); 01064 numclasses++; 01065 } 01066 var = var->next; 01067 } 01068 01069 ast_config_destroy(cfg); 01070 01071 return numclasses; 01072 }
|
|
Definition at line 875 of file res_musiconhold.c. References free, and ast_channel::music_state. Referenced by load_module(), and reload(). 00876 { 00877 if (chan->music_state) { 00878 free(chan->music_state); 00879 chan->music_state = NULL; 00880 } 00881 }
|
|
Definition at line 883 of file res_musiconhold.c. References ast_activate_generator(), AST_FLAG_MOH, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), get_mohbyname(), LOG_WARNING, and mohclass::total_files. Referenced by load_module(), moh_on_off(), and reload(). 00884 { 00885 struct mohclass *mohclass; 00886 00887 if (ast_strlen_zero(class)) 00888 class = chan->musicclass; 00889 if (ast_strlen_zero(class)) 00890 class = "default"; 00891 ast_mutex_lock(&moh_lock); 00892 mohclass = get_mohbyname(class); 00893 ast_mutex_unlock(&moh_lock); 00894 00895 if (!mohclass) { 00896 ast_log(LOG_WARNING, "No class: %s\n", (char *)class); 00897 return -1; 00898 } 00899 00900 ast_set_flag(chan, AST_FLAG_MOH); 00901 if (mohclass->total_files) { 00902 return ast_activate_generator(chan, &moh_file_stream, mohclass); 00903 } else 00904 return ast_activate_generator(chan, &mohgen, mohclass); 00905 }
|
|
Definition at line 907 of file res_musiconhold.c. References ast_clear_flag, ast_closestream(), ast_deactivate_generator(), AST_FLAG_MOH, ast_channel::music_state, and ast_channel::stream. Referenced by load_module(), and reload(). 00908 { 00909 ast_clear_flag(chan, AST_FLAG_MOH); 00910 ast_deactivate_generator(chan); 00911 00912 if (chan->music_state) { 00913 if (chan->stream) { 00914 ast_closestream(chan->stream); 00915 chan->stream = NULL; 00916 } 00917 } 00918 }
|
|
Definition at line 553 of file res_musiconhold.c. References ast_log(), ast_moh_start(), ast_moh_stop(), ast_safe_sleep(), LOG_WARNING, and ast_channel::name. Referenced by load_module(). 00554 { 00555 if (ast_moh_start(chan, data)) { 00556 ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name); 00557 return -1; 00558 } 00559 while (!ast_safe_sleep(chan, 10000)); 00560 ast_moh_stop(chan); 00561 return -1; 00562 }
|
|
Definition at line 564 of file res_musiconhold.c. References ast_log(), ast_moh_start(), ast_moh_stop(), ast_safe_sleep(), LOG_WARNING, and ast_channel::name. Referenced by load_module(). 00565 { 00566 int res; 00567 if (!data || !atoi(data)) { 00568 ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n"); 00569 return -1; 00570 } 00571 if (ast_moh_start(chan, NULL)) { 00572 ast_log(LOG_WARNING, "Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->name); 00573 return -1; 00574 } 00575 res = ast_safe_sleep(chan, atoi(data) * 1000); 00576 ast_moh_stop(chan); 00577 return res; 00578 }
|
|
Definition at line 580 of file res_musiconhold.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_channel::musicclass. Referenced by load_module(). 00581 { 00582 if (ast_strlen_zero(data)) { 00583 ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n"); 00584 return -1; 00585 } 00586 strncpy(chan->musicclass, data, sizeof(chan->musicclass) - 1); 00587 return 0; 00588 }
|
|
Definition at line 590 of file res_musiconhold.c. References ast_log(), ast_moh_start(), and LOG_NOTICE. Referenced by load_module(). 00591 { 00592 char *class = NULL; 00593 if (data && strlen(data)) 00594 class = data; 00595 if (ast_moh_start(chan, class)) 00596 ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name); 00597 00598 return 0; 00599 }
|
|
Definition at line 601 of file res_musiconhold.c. References ast_moh_stop(). Referenced by load_module(). 00602 { 00603 ast_moh_stop(chan); 00604 00605 return 0; 00606 }
|
|
Definition at line 676 of file res_musiconhold.c. References ast_codec2str(), ast_log(), ast_set_write_format(), ast_verbose(), LOG_WARNING, moh_release(), mohalloc(), option_verbose, VERBOSE_PREFIX_3, and ast_channel::writeformat. 00677 { 00678 struct mohdata *res; 00679 struct mohclass *class = params; 00680 00681 res = mohalloc(class); 00682 if (res) { 00683 res->origwfmt = chan->writeformat; 00684 if (ast_set_write_format(chan, class->format)) { 00685 ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(class->format)); 00686 moh_release(NULL, res); 00687 res = NULL; 00688 } 00689 if (option_verbose > 2) 00690 ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on channel '%s'\n", class->name, chan->name); 00691 } 00692 return res; 00693 }
|
|
Definition at line 920 of file res_musiconhold.c. References AST_FORMAT_SLINEAR, and malloc. Referenced by load_moh_classes(). 00921 { 00922 struct mohclass *class; 00923 00924 class = malloc(sizeof(struct mohclass)); 00925 00926 if (!class) 00927 return NULL; 00928 00929 memset(class, 0, sizeof(struct mohclass)); 00930 00931 class->format = AST_FORMAT_SLINEAR; 00932 00933 return class; 00934 }
|
|
Definition at line 1159 of file res_musiconhold.c. References ast_cli(), ast_getformatname(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, MOH_CUSTOM, and mohclass::next. 01160 { 01161 struct mohclass *class; 01162 01163 ast_mutex_lock(&moh_lock); 01164 for (class = mohclasses; class; class = class->next) { 01165 ast_cli(fd, "Class: %s\n", class->name); 01166 ast_cli(fd, "\tMode: %s\n", ast_strlen_zero(class->mode) ? "<none>" : class->mode); 01167 ast_cli(fd, "\tDirectory: %s\n", ast_strlen_zero(class->dir) ? "<none>" : class->dir); 01168 if (ast_test_flag(class, MOH_CUSTOM)) 01169 ast_cli(fd, "\tApplication: %s\n", ast_strlen_zero(class->args) ? "<none>" : class->args); 01170 ast_cli(fd, "\tFormat: %s\n", ast_getformatname(class->format)); 01171 } 01172 ast_mutex_unlock(&moh_lock); 01173 01174 return 0; 01175 }
|
|
Definition at line 1128 of file res_musiconhold.c. References ast_cli(), ast_moh_destroy(), load_moh_classes(), and moh_on_off(). 01129 { 01130 int x; 01131 01132 moh_on_off(0); 01133 ast_moh_destroy(); 01134 x = load_moh_classes(1); 01135 moh_on_off(1); 01136 ast_cli(fd, "\n%d class%s reloaded.\n", x, x == 1 ? "" : "es"); 01137 return 0; 01138 }
|
|
Definition at line 279 of file res_musiconhold.c. References ast_verbose(), malloc, ast_channel::music_state, ast_channel::name, option_verbose, VERBOSE_PREFIX_3, and ast_channel::writeformat. 00280 { 00281 struct moh_files_state *state; 00282 struct mohclass *class = params; 00283 int allocated = 0; 00284 00285 if (!chan->music_state && (state = malloc(sizeof(struct moh_files_state)))) { 00286 chan->music_state = state; 00287 allocated = 1; 00288 } else 00289 state = chan->music_state; 00290 00291 if (state) { 00292 if (allocated || state->class != class) { 00293 /* initialize */ 00294 memset(state, 0, sizeof(struct moh_files_state)); 00295 state->class = class; 00296 } 00297 00298 state->origwfmt = chan->writeformat; 00299 00300 if (option_verbose > 2) 00301 ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on %s\n", class->name, chan->name); 00302 } 00303 00304 return chan->music_state; 00305 }
|
|
Definition at line 254 of file res_musiconhold.c. References ast_frfree(), ast_log(), ast_write(), LOG_WARNING, moh_files_readframe(), ast_channel::music_state, moh_files_state::sample_queue, ast_frame::samples, and moh_files_state::samples. 00255 { 00256 struct moh_files_state *state = chan->music_state; 00257 struct ast_frame *f = NULL; 00258 int res = 0; 00259 00260 state->sample_queue += samples; 00261 00262 while (state->sample_queue > 0) { 00263 if ((f = moh_files_readframe(chan))) { 00264 state->samples += f->samples; 00265 res = ast_write(chan, f); 00266 state->sample_queue -= f->samples; 00267 ast_frfree(f); 00268 if (res < 0) { 00269 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno)); 00270 return -1; 00271 } 00272 } else 00273 return -1; 00274 } 00275 return res; 00276 }
|
|
Definition at line 242 of file res_musiconhold.c. References ast_moh_files_next(), ast_readframe(), and ast_channel::stream. Referenced by moh_files_generator(). 00243 { 00244 struct ast_frame *f = NULL; 00245 00246 if (!(chan->stream && (f = ast_readframe(chan->stream)))) { 00247 if (!ast_moh_files_next(chan)) 00248 f = ast_readframe(chan->stream); 00249 } 00250 00251 return f; 00252 }
|
|
Definition at line 178 of file res_musiconhold.c. References ast_log(), ast_set_write_format(), ast_verbose(), LOG_WARNING, ast_channel::music_state, ast_channel::name, option_verbose, moh_files_state::origwfmt, moh_files_state::pos, moh_files_state::save_pos, and VERBOSE_PREFIX_3. 00179 { 00180 struct moh_files_state *state = chan->music_state; 00181 00182 if (chan && state) { 00183 if (option_verbose > 2) 00184 ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name); 00185 00186 if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) { 00187 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, state->origwfmt); 00188 } 00189 state->save_pos = state->pos + 1; 00190 } 00191 }
|
|
Definition at line 695 of file res_musiconhold.c. References ast_codec_get_len(), ast_codec_get_samples(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), mohclass::format, LOG_WARNING, moh, ast_channel::name, mohdata::parent, mohclass::pid, and mohdata::pipe. 00696 { 00697 struct ast_frame f; 00698 struct mohdata *moh = data; 00699 short buf[1280 + AST_FRIENDLY_OFFSET / 2]; 00700 int res; 00701 00702 if (!moh->parent->pid) 00703 return -1; 00704 00705 len = ast_codec_get_len(moh->parent->format, samples); 00706 00707 if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) { 00708 ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", (int)sizeof(buf), len, chan->name); 00709 len = sizeof(buf) - AST_FRIENDLY_OFFSET; 00710 } 00711 res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len); 00712 #if 0 00713 if (res != len) { 00714 ast_log(LOG_WARNING, "Read only %d of %d bytes: %s\n", res, len, strerror(errno)); 00715 } 00716 #endif 00717 if (res <= 0) 00718 return 0; 00719 00720 memset(&f, 0, sizeof(f)); 00721 00722 f.frametype = AST_FRAME_VOICE; 00723 f.subclass = moh->parent->format; 00724 f.mallocd = 0; 00725 f.datalen = res; 00726 f.data = buf + AST_FRIENDLY_OFFSET / 2; 00727 f.offset = AST_FRIENDLY_OFFSET; 00728 f.samples = ast_codec_get_samples(&f); 00729 00730 if (ast_write(chan, &f) < 0) { 00731 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno)); 00732 return -1; 00733 } 00734 00735 return 0; 00736 }
|
|
Definition at line 1113 of file res_musiconhold.c. References ast_channel_walk_locked(), ast_deactivate_generator(), AST_FLAG_MOH, ast_mutex_unlock(), ast_test_flag, and local_ast_moh_start(). Referenced by moh_cli(). 01114 { 01115 struct ast_channel *chan = NULL; 01116 01117 while ( (chan = ast_channel_walk_locked(chan)) != NULL) { 01118 if (ast_test_flag(chan, AST_FLAG_MOH)) { 01119 if (on) 01120 local_ast_moh_start(chan, NULL); 01121 else 01122 ast_deactivate_generator(chan); 01123 } 01124 ast_mutex_unlock(&chan->lock); 01125 } 01126 }
|
|
Definition at line 803 of file res_musiconhold.c. References mohclass::args, ast_log(), ast_moh_free_class(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_set_flag, free, get_mohbyname(), LOG_DEBUG, LOG_WARNING, mohclass::mode, MOH_CUSTOM, MOH_QUIET, MOH_RANDOMIZE, moh_scan_files(), MOH_SINGLE, monmp3thread(), mohclass::name, mohclass::next, mohclass::pseudofd, respawn_time, mohclass::srcfd, mohclass::start, and mohclass::thread. Referenced by load_moh_classes(). 00804 { 00805 #ifdef ZAPATA_MOH 00806 int x; 00807 #endif 00808 ast_mutex_lock(&moh_lock); 00809 if (get_mohbyname(moh->name)) { 00810 if (reload) { 00811 ast_log(LOG_DEBUG, "Music on Hold class '%s' left alone from initial load.\n", moh->name); 00812 } else { 00813 ast_log(LOG_WARNING, "Music on Hold class '%s' already exists\n", moh->name); 00814 } 00815 free(moh); 00816 ast_mutex_unlock(&moh_lock); 00817 return -1; 00818 } 00819 ast_mutex_unlock(&moh_lock); 00820 00821 time(&moh->start); 00822 moh->start -= respawn_time; 00823 00824 if (!strcasecmp(moh->mode, "files")) { 00825 if (!moh_scan_files(moh)) { 00826 ast_moh_free_class(&moh); 00827 return -1; 00828 } 00829 if (strchr(moh->args, 'r')) 00830 ast_set_flag(moh, MOH_RANDOMIZE); 00831 } else if (!strcasecmp(moh->mode, "mp3") || !strcasecmp(moh->mode, "mp3nb") || !strcasecmp(moh->mode, "quietmp3") || !strcasecmp(moh->mode, "quietmp3nb") || !strcasecmp(moh->mode, "httpmp3") || !strcasecmp(moh->mode, "custom")) { 00832 00833 if (!strcasecmp(moh->mode, "custom")) 00834 ast_set_flag(moh, MOH_CUSTOM); 00835 else if (!strcasecmp(moh->mode, "mp3nb")) 00836 ast_set_flag(moh, MOH_SINGLE); 00837 else if (!strcasecmp(moh->mode, "quietmp3nb")) 00838 ast_set_flag(moh, MOH_SINGLE | MOH_QUIET); 00839 else if (!strcasecmp(moh->mode, "quietmp3")) 00840 ast_set_flag(moh, MOH_QUIET); 00841 00842 moh->srcfd = -1; 00843 #ifdef ZAPATA_MOH 00844 /* Open /dev/zap/pseudo for timing... Is 00845 there a better, yet reliable way to do this? */ 00846 moh->pseudofd = open("/dev/zap/pseudo", O_RDONLY); 00847 if (moh->pseudofd < 0) { 00848 ast_log(LOG_WARNING, "Unable to open pseudo channel for timing... Sound may be choppy.\n"); 00849 } else { 00850 x = 320; 00851 ioctl(moh->pseudofd, ZT_SET_BLOCKSIZE, &x); 00852 } 00853 #else 00854 moh->pseudofd = -1; 00855 #endif 00856 if (ast_pthread_create(&moh->thread, NULL, monmp3thread, moh)) { 00857 ast_log(LOG_WARNING, "Unable to create moh...\n"); 00858 if (moh->pseudofd > -1) 00859 close(moh->pseudofd); 00860 ast_moh_free_class(&moh); 00861 return -1; 00862 } 00863 } else { 00864 ast_log(LOG_WARNING, "Don't know how to do a mode '%s' music on hold\n", moh->mode); 00865 ast_moh_free_class(&moh); 00866 return -1; 00867 } 00868 ast_mutex_lock(&moh_lock); 00869 moh->next = mohclasses; 00870 mohclasses = moh; 00871 ast_mutex_unlock(&moh_lock); 00872 return 0; 00873 }
|
|
Definition at line 644 of file res_musiconhold.c. References ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_write_format(), ast_verbose(), free, LOG_WARNING, mohclass::members, moh, ast_channel::name, mohdata::next, option_verbose, mohdata::origwfmt, mohdata::parent, mohdata::pipe, and VERBOSE_PREFIX_3. Referenced by moh_alloc(). 00645 { 00646 struct mohdata *moh = data, *prev, *cur; 00647 int oldwfmt; 00648 ast_mutex_lock(&moh_lock); 00649 /* Unlink */ 00650 prev = NULL; 00651 cur = moh->parent->members; 00652 while (cur) { 00653 if (cur == moh) { 00654 if (prev) 00655 prev->next = cur->next; 00656 else 00657 moh->parent->members = cur->next; 00658 break; 00659 } 00660 prev = cur; 00661 cur = cur->next; 00662 } 00663 ast_mutex_unlock(&moh_lock); 00664 close(moh->pipe[0]); 00665 close(moh->pipe[1]); 00666 oldwfmt = moh->origwfmt; 00667 free(moh); 00668 if (chan) { 00669 if (oldwfmt && ast_set_write_format(chan, oldwfmt)) 00670 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(oldwfmt)); 00671 if (option_verbose > 2) 00672 ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name); 00673 } 00674 }
|
|
Definition at line 745 of file res_musiconhold.c. References ast_log(), mohclass::dir, mohclass::filearray, LOG_WARNING, MAX_MOHFILE_LEN, MAX_MOHFILES, and mohclass::total_files. Referenced by init_classes(), and moh_register(). 00745 { 00746 00747 DIR *files_DIR; 00748 struct dirent *files_dirent; 00749 char path[512]; 00750 char filepath[MAX_MOHFILE_LEN]; 00751 char *ext; 00752 struct stat statbuf; 00753 int dirnamelen; 00754 int i; 00755 00756 files_DIR = opendir(class->dir); 00757 if (!files_DIR) { 00758 ast_log(LOG_WARNING, "Cannot open dir %s or dir does not exist", class->dir); 00759 return -1; 00760 } 00761 00762 class->total_files = 0; 00763 dirnamelen = strlen(class->dir) + 2; 00764 getcwd(path, 512); 00765 chdir(class->dir); 00766 memset(class->filearray, 0, MAX_MOHFILES*MAX_MOHFILE_LEN); 00767 while ((files_dirent = readdir(files_DIR))) { 00768 if ((strlen(files_dirent->d_name) < 4) || ((strlen(files_dirent->d_name) + dirnamelen) >= MAX_MOHFILE_LEN)) 00769 continue; 00770 00771 snprintf(filepath, MAX_MOHFILE_LEN, "%s/%s", class->dir, files_dirent->d_name); 00772 00773 if (stat(filepath, &statbuf)) 00774 continue; 00775 00776 if (!S_ISREG(statbuf.st_mode)) 00777 continue; 00778 00779 if ((ext = strrchr(filepath, '.'))) { 00780 *ext = '\0'; 00781 ext++; 00782 } 00783 00784 /* if the file is present in multiple formats, ensure we only put it into the list once */ 00785 for (i = 0; i < class->total_files; i++) 00786 if (!strcmp(filepath, class->filearray[i])) 00787 break; 00788 00789 if (i == class->total_files) 00790 strcpy(class->filearray[class->total_files++], filepath); 00791 00792 /* If the new total files is equal to the maximum allowed, stop adding new ones */ 00793 if (class->total_files == MAX_MOHFILES) 00794 break; 00795 00796 } 00797 00798 closedir(files_DIR); 00799 chdir(path); 00800 return class->total_files; 00801 }
|
|
Definition at line 620 of file res_musiconhold.c. References ast_log(), free, LOG_WARNING, malloc, mohclass::members, moh, mohclass::next, and mohdata::pipe. Referenced by moh_alloc(). 00621 { 00622 struct mohdata *moh; 00623 long flags; 00624 moh = malloc(sizeof(struct mohdata)); 00625 if (!moh) 00626 return NULL; 00627 memset(moh, 0, sizeof(struct mohdata)); 00628 if (pipe(moh->pipe)) { 00629 ast_log(LOG_WARNING, "Failed to create pipe: %s\n", strerror(errno)); 00630 free(moh); 00631 return NULL; 00632 } 00633 /* Make entirely non-blocking */ 00634 flags = fcntl(moh->pipe[0], F_GETFL); 00635 fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK); 00636 flags = fcntl(moh->pipe[1], F_GETFL); 00637 fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK); 00638 moh->parent = cl; 00639 moh->next = cl->members; 00640 cl->members = moh; 00641 return moh; 00642 }
|
|
Definition at line 470 of file res_musiconhold.c. References ast_codec_get_len(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, moh, MOH_MS_INTERVAL, mohdata::next, option_debug, mohdata::pipe, and spawn_mp3(). Referenced by moh_register(). 00471 { 00472 #define MOH_MS_INTERVAL 100 00473 00474 struct mohclass *class = data; 00475 struct mohdata *moh; 00476 char buf[8192]; 00477 short sbuf[8192]; 00478 int res, res2; 00479 int len; 00480 struct timeval tv, tv_tmp; 00481 00482 tv.tv_sec = 0; 00483 tv.tv_usec = 0; 00484 for(;/* ever */;) { 00485 pthread_testcancel(); 00486 /* Spawn mp3 player if it's not there */ 00487 if (class->srcfd < 0) { 00488 if ((class->srcfd = spawn_mp3(class)) < 0) { 00489 ast_log(LOG_WARNING, "Unable to spawn mp3player\n"); 00490 /* Try again later */ 00491 sleep(500); 00492 pthread_testcancel(); 00493 } 00494 } 00495 if (class->pseudofd > -1) { 00496 /* Pause some amount of time */ 00497 res = read(class->pseudofd, buf, sizeof(buf)); 00498 pthread_testcancel(); 00499 } else { 00500 long delta; 00501 /* Reliable sleep */ 00502 tv_tmp = ast_tvnow(); 00503 if (ast_tvzero(tv)) 00504 tv = tv_tmp; 00505 delta = ast_tvdiff_ms(tv_tmp, tv); 00506 if (delta < MOH_MS_INTERVAL) { /* too early */ 00507 tv = ast_tvadd(tv, ast_samp2tv(MOH_MS_INTERVAL, 1000)); /* next deadline */ 00508 usleep(1000 * (MOH_MS_INTERVAL - delta)); 00509 pthread_testcancel(); 00510 } else { 00511 ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n"); 00512 tv = tv_tmp; 00513 } 00514 res = 8 * MOH_MS_INTERVAL; /* 8 samples per millisecond */ 00515 } 00516 if (!class->members) 00517 continue; 00518 /* Read mp3 audio */ 00519 len = ast_codec_get_len(class->format, res); 00520 00521 if ((res2 = read(class->srcfd, sbuf, len)) != len) { 00522 if (!res2) { 00523 close(class->srcfd); 00524 class->srcfd = -1; 00525 pthread_testcancel(); 00526 if (class->pid) { 00527 kill(class->pid, SIGHUP); 00528 usleep(100000); 00529 kill(class->pid, SIGTERM); 00530 usleep(100000); 00531 kill(class->pid, SIGKILL); 00532 class->pid = 0; 00533 } 00534 } else 00535 ast_log(LOG_DEBUG, "Read %d bytes of audio while expecting %d\n", res2, len); 00536 continue; 00537 } 00538 pthread_testcancel(); 00539 ast_mutex_lock(&moh_lock); 00540 moh = class->members; 00541 while (moh) { 00542 /* Write data */ 00543 if ((res = write(moh->pipe[1], sbuf, res2)) != res2) 00544 if (option_debug) 00545 ast_log(LOG_DEBUG, "Only wrote %d of %d bytes to pipe\n", res, res2); 00546 moh = moh->next; 00547 } 00548 ast_mutex_unlock(&moh_lock); 00549 } 00550 return NULL; 00551 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 1225 of file res_musiconhold.c. References ast_install_music_functions(), init_classes(), local_ast_moh_cleanup(), local_ast_moh_start(), and local_ast_moh_stop(). 01226 { 01227 if (init_classes(1)) 01228 ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup); 01229 01230 return 0; 01231 }
|
|
Definition at line 314 of file res_musiconhold.c. References mohclass::args, ast_log(), ast_set_priority(), ast_strlen_zero(), ast_test_flag, mohclass::dir, LOCAL_MPG_123, LOG_WARNING, MAX_MP3S, MOH_CUSTOM, MOH_QUIET, MOH_SINGLE, MPG_123, option_highpriority, mohclass::pid, respawn_time, and mohclass::start. Referenced by monmp3thread(). 00315 { 00316 int fds[2]; 00317 int files = 0; 00318 char fns[MAX_MP3S][80]; 00319 char *argv[MAX_MP3S + 50]; 00320 char xargs[256]; 00321 char *argptr; 00322 int argc = 0; 00323 DIR *dir = NULL; 00324 struct dirent *de; 00325 00326 00327 if (!strcasecmp(class->dir, "nodir")) { 00328 files = 1; 00329 } else { 00330 dir = opendir(class->dir); 00331 if (!dir && !strstr(class->dir,"http://") && !strstr(class->dir,"HTTP://")) { 00332 ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir); 00333 return -1; 00334 } 00335 } 00336 00337 if (!ast_test_flag(class, MOH_CUSTOM)) { 00338 argv[argc++] = "mpg123"; 00339 argv[argc++] = "-q"; 00340 argv[argc++] = "-s"; 00341 argv[argc++] = "--mono"; 00342 argv[argc++] = "-r"; 00343 argv[argc++] = "8000"; 00344 00345 if (!ast_test_flag(class, MOH_SINGLE)) { 00346 argv[argc++] = "-b"; 00347 argv[argc++] = "2048"; 00348 } 00349 00350 argv[argc++] = "-f"; 00351 00352 if (ast_test_flag(class, MOH_QUIET)) 00353 argv[argc++] = "4096"; 00354 else 00355 argv[argc++] = "8192"; 00356 00357 /* Look for extra arguments and add them to the list */ 00358 strncpy(xargs, class->args, sizeof(xargs) - 1); 00359 argptr = xargs; 00360 while (!ast_strlen_zero(argptr)) { 00361 argv[argc++] = argptr; 00362 argptr = strchr(argptr, ','); 00363 if (argptr) { 00364 *argptr = '\0'; 00365 argptr++; 00366 } 00367 } 00368 } else { 00369 /* Format arguments for argv vector */ 00370 strncpy(xargs, class->args, sizeof(xargs) - 1); 00371 argptr = xargs; 00372 while (!ast_strlen_zero(argptr)) { 00373 argv[argc++] = argptr; 00374 argptr = strchr(argptr, ' '); 00375 if (argptr) { 00376 *argptr = '\0'; 00377 argptr++; 00378 } 00379 } 00380 } 00381 00382 00383 if (strstr(class->dir,"http://") || strstr(class->dir,"HTTP://")) { 00384 strncpy(fns[files], class->dir, sizeof(fns[files]) - 1); 00385 argv[argc++] = fns[files]; 00386 files++; 00387 } else if (dir) { 00388 while ((de = readdir(dir)) && (files < MAX_MP3S)) { 00389 if ((strlen(de->d_name) > 3) && 00390 ((ast_test_flag(class, MOH_CUSTOM) && 00391 (!strcasecmp(de->d_name + strlen(de->d_name) - 4, ".raw") || 00392 !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".sln"))) || 00393 !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".mp3"))) { 00394 strncpy(fns[files], de->d_name, sizeof(fns[files]) - 1); 00395 argv[argc++] = fns[files]; 00396 files++; 00397 } 00398 } 00399 } 00400 argv[argc] = NULL; 00401 if (dir) { 00402 closedir(dir); 00403 } 00404 if (pipe(fds)) { 00405 ast_log(LOG_WARNING, "Pipe failed\n"); 00406 return -1; 00407 } 00408 #if 0 00409 printf("%d files total, %d args total\n", files, argc); 00410 { 00411 int x; 00412 for (x=0;argv[x];x++) 00413 printf("arg%d: %s\n", x, argv[x]); 00414 } 00415 #endif 00416 if (!files) { 00417 ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir); 00418 close(fds[0]); 00419 close(fds[1]); 00420 return -1; 00421 } 00422 if (time(NULL) - class->start < respawn_time) { 00423 sleep(respawn_time - (time(NULL) - class->start)); 00424 } 00425 time(&class->start); 00426 class->pid = fork(); 00427 if (class->pid < 0) { 00428 close(fds[0]); 00429 close(fds[1]); 00430 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00431 return -1; 00432 } 00433 if (!class->pid) { 00434 int x; 00435 00436 if (option_highpriority) 00437 ast_set_priority(0); 00438 00439 close(fds[0]); 00440 /* Stdout goes to pipe */ 00441 dup2(fds[1], STDOUT_FILENO); 00442 /* Close unused file descriptors */ 00443 for (x=3;x<8192;x++) { 00444 if (-1 != fcntl(x, F_GETFL)) { 00445 close(x); 00446 } 00447 } 00448 /* Child */ 00449 chdir(class->dir); 00450 if (ast_test_flag(class, MOH_CUSTOM)) { 00451 execv(argv[0], argv); 00452 } else { 00453 /* Default install is /usr/local/bin */ 00454 execv(LOCAL_MPG_123, argv); 00455 /* Many places have it in /usr/bin */ 00456 execv(MPG_123, argv); 00457 /* Check PATH as a last-ditch effort */ 00458 execvp("mpg123", argv); 00459 } 00460 ast_log(LOG_WARNING, "Exec failed: %s\n", strerror(errno)); 00461 close(fds[1]); 00462 exit(1); 00463 } else { 00464 /* Parent */ 00465 close(fds[1]); 00466 } 00467 return fds[0]; 00468 }
|
|
Cleanup all module structures, sockets, etc. Standard module functions ... Definition at line 1233 of file res_musiconhold.c. 01234 {
01235 return -1;
01236 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 1243 of file res_musiconhold.c. References STANDARD_USECOUNT. 01244 { 01245 /* Never allow Music On Hold to be unloaded 01246 unresolve needed symbols in the dialer */ 01247 #if 0 01248 int res; 01249 STANDARD_USECOUNT(res); 01250 return res; 01251 #else 01252 return 1; 01253 #endif 01254 }
|
|
Definition at line 70 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 71 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 72 of file res_musiconhold.c. |
|
Definition at line 73 of file res_musiconhold.c. |
|
Definition at line 74 of file res_musiconhold.c. |
|
Definition at line 1177 of file res_musiconhold.c. |
|
Definition at line 1179 of file res_musiconhold.c. |
|
Definition at line 1181 of file res_musiconhold.c. |
|
Definition at line 82 of file res_musiconhold.c. Referenced by load_module(). |
|
Initial value: "WaitMusicOnHold(delay): " "Plays hold music specified number of seconds. Returns 0 when\n" "done, or -1 on hangup. If no hold music is available, the delay will\n" "still occur with no sound.\n" Definition at line 89 of file res_musiconhold.c. Referenced by load_module(). |
|
Initial value: "SetMusicOnHold(class): " "Sets the default class for music on hold for a given channel. When\n" "music on hold is activated, this class will be used to select which\n" "music is played.\n" Definition at line 94 of file res_musiconhold.c. |
|
Initial value: "StartMusicOnHold(class): " "Starts playing music on hold, uses default music class for channel.\n" "Starts playing music specified by class. If omitted, the default\n" "music source for the channel will be used. Always returns 0.\n" Definition at line 99 of file res_musiconhold.c. |
|
Initial value: "StopMusicOnHold: " "Stops playing music on hold.\n" Definition at line 104 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 307 of file res_musiconhold.c. |
|
Definition at line 150 of file res_musiconhold.c. |
|
Definition at line 738 of file res_musiconhold.c. |
|
Definition at line 107 of file res_musiconhold.c. Referenced by moh_register(), and spawn_mp3(). |
|
Definition at line 76 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 77 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 78 of file res_musiconhold.c. |
|
Definition at line 79 of file res_musiconhold.c. |
|
Definition at line 80 of file res_musiconhold.c. Referenced by load_module(). |