#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"
Go to the source code of this file.
Data Structures | |
struct | moh_files_state |
struct | mohclass |
struct | mohdata |
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 | |
void | ast_moh_destroy (void) |
int | ast_moh_files_next (struct ast_channel *chan) |
void | ast_moh_free_class (struct mohclass **class) |
AST_MUTEX_DEFINE_STATIC (moh_lock) | |
int | cli_files_show (int fd, int argc, char *argv[]) |
char * | description (void) |
Provides a description of the module. | |
mohclass * | get_mohbyname (char *name) |
int | init_classes (int reload) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | load_moh_classes (int reload) |
void | local_ast_moh_cleanup (struct ast_channel *chan) |
int | local_ast_moh_start (struct ast_channel *chan, char *class) |
void | local_ast_moh_stop (struct ast_channel *chan) |
int | moh0_exec (struct ast_channel *chan, void *data) |
int | moh1_exec (struct ast_channel *chan, void *data) |
int | moh2_exec (struct ast_channel *chan, void *data) |
int | moh3_exec (struct ast_channel *chan, void *data) |
int | moh4_exec (struct ast_channel *chan, void *data) |
void * | moh_alloc (struct ast_channel *chan, void *params) |
mohclass * | moh_class_malloc (void) |
int | moh_classes_show (int fd, int argc, char *argv[]) |
int | moh_cli (int fd, int argc, char *argv[]) |
void * | moh_files_alloc (struct ast_channel *chan, void *params) |
int | moh_files_generator (struct ast_channel *chan, void *data, int len, int samples) |
ast_frame * | moh_files_readframe (struct ast_channel *chan) |
void | moh_files_release (struct ast_channel *chan, void *data) |
int | moh_generate (struct ast_channel *chan, void *data, int len, int samples) |
void | moh_on_off (int on) |
int | moh_register (struct mohclass *moh, int reload) |
void | moh_release (struct ast_channel *chan, void *data) |
int | moh_scan_files (struct mohclass *class) |
mohdata * | mohalloc (struct mohclass *cl) |
void * | monmp3thread (void *data) |
int | reload (void) |
Reload stuff. | |
int | spawn_mp3 (struct mohclass *class) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
char * | app0 = "MusicOnHold" |
char * | app1 = "WaitMusicOnHold" |
char * | app2 = "SetMusicOnHold" |
char * | app3 = "StartMusicOnHold" |
char * | app4 = "StopMusicOnHold" |
ast_cli_entry | cli_moh = { { "moh", "reload"}, moh_cli, "Music On Hold", "Music On Hold", NULL} |
ast_cli_entry | cli_moh_classes_show = { { "moh", "classes", "show"}, moh_classes_show, "List MOH classes", "Lists all MOH classes", NULL} |
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} |
char * | descrip0 |
char * | descrip1 |
char * | descrip2 |
char * | descrip3 |
char * | descrip4 |
ast_generator | moh_file_stream |
mohclass * | mohclasses |
ast_generator | mohgen |
int | respawn_time = 20 |
char * | synopsis0 = "Play Music On Hold indefinitely" |
char * | synopsis1 = "Wait, playing Music On Hold" |
char * | synopsis2 = "Set default Music On Hold class" |
char * | synopsis3 = "Play Music On Hold" |
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 1059 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, mohclasses, mohclass::next, option_verbose, mohclass::pid, mohclass::srcfd, and VERBOSE_PREFIX_2. Referenced by load_module(), and moh_cli(). 01060 { 01061 struct mohclass *moh, *tmp; 01062 char buff[8192]; 01063 int bytes, tbytes=0, stime = 0, pid = 0; 01064 01065 if (option_verbose > 1) 01066 ast_verbose(VERBOSE_PREFIX_2 "Destroying musiconhold processes\n"); 01067 ast_mutex_lock(&moh_lock); 01068 moh = mohclasses; 01069 01070 while (moh) { 01071 if (moh->pid) { 01072 ast_log(LOG_DEBUG, "killing %d!\n", moh->pid); 01073 stime = time(NULL) + 2; 01074 pid = moh->pid; 01075 moh->pid = 0; 01076 kill(pid, SIGKILL); 01077 while ((ast_wait_for_input(moh->srcfd, 100) > 0) && (bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime) { 01078 tbytes = tbytes + bytes; 01079 } 01080 ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", pid, tbytes); 01081 close(moh->srcfd); 01082 } 01083 tmp = moh; 01084 moh = moh->next; 01085 ast_moh_free_class(&tmp); 01086 } 01087 mohclasses = NULL; 01088 ast_mutex_unlock(&moh_lock); 01089 }
|
|
Definition at line 190 of file res_musiconhold.c. References ast_closestream(), ast_fileexists(), AST_FORMAT_SLINEAR, ast_log(), ast_openstream_full(), ast_seekstream(), ast_set_write_format(), 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, 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(). 00191 { 00192 struct moh_files_state *state = chan->music_state; 00193 int tries; 00194 00195 if (state->save_pos) { 00196 state->pos = state->save_pos - 1; 00197 state->save_pos = 0; 00198 } else { 00199 /* Try 20 times to find something good */ 00200 for (tries=0;tries < 20;tries++) { 00201 state->samples = 0; 00202 if (chan->stream) { 00203 ast_closestream(chan->stream); 00204 chan->stream = NULL; 00205 state->pos++; 00206 } 00207 00208 if (ast_test_flag(state->class, MOH_RANDOMIZE)) 00209 state->pos = rand(); 00210 00211 /* check to see if this file's format can be opened */ 00212 if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) != -1) 00213 break; 00214 00215 } 00216 } 00217 00218 state->pos = state->pos % state->class->total_files; 00219 00220 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00221 ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name); 00222 return -1; 00223 } 00224 if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) { 00225 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno)); 00226 state->pos++; 00227 return -1; 00228 } 00229 00230 if (option_debug) 00231 ast_log(LOG_DEBUG, "%s Opened file %d '%s'\n", chan->name, state->pos, state->class->filearray[state->pos]); 00232 00233 if (state->samples) 00234 ast_seekstream(chan->stream, state->samples, SEEK_SET); 00235 00236 return 0; 00237 }
|
|
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 free(*class); 00170 *class = NULL; 00171 }
|
|
|
|
Definition at line 1118 of file res_musiconhold.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), and mohclasses. 01119 { 01120 int i; 01121 struct mohclass *class; 01122 01123 ast_mutex_lock(&moh_lock); 01124 for (class = mohclasses; class; class = class->next) { 01125 if (!class->total_files) 01126 continue; 01127 01128 ast_cli(fd, "Class: %s\n", class->name); 01129 for (i = 0; i < class->total_files; i++) 01130 ast_cli(fd, "\tFile: %s\n", class->filearray[i]); 01131 } 01132 ast_mutex_unlock(&moh_lock); 01133 01134 return 0; 01135 }
|
|
Provides a description of the module.
Definition at line 1216 of file res_musiconhold.c. 01217 { 01218 return "Music On Hold Resource"; 01219 }
|
|
Definition at line 598 of file res_musiconhold.c. References mohclass::name, name, and mohclass::next. Referenced by load_moh_classes(), local_ast_moh_start(), and moh_register(). 00599 { 00600 struct mohclass *moh; 00601 moh = mohclasses; 00602 while (moh) { 00603 if (!strcasecmp(name, moh->name)) 00604 return moh; 00605 moh = moh->next; 00606 } 00607 return NULL; 00608 }
|
|
Definition at line 1161 of file res_musiconhold.c. References load_moh_classes(), moh_scan_files(), mohclass::next, reload(), and mohclass::total_files. Referenced by load_module(), and reload(). 01162 { 01163 struct mohclass *moh; 01164 01165 if (!load_moh_classes(reload)) /* Load classes from config */ 01166 return 0; /* Return if nothing is found */ 01167 moh = mohclasses; 01168 while (moh) { 01169 if (moh->total_files) 01170 moh_scan_files(moh); 01171 moh = moh->next; 01172 } 01173 return 1; 01174 }
|
|
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 1234 of file res_musiconhold.c. 01235 {
01236 return ASTERISK_GPL_KEY;
01237 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 1176 of file res_musiconhold.c. References app0, app1, app2, app3, app4, ast_cli_register(), ast_install_music_functions(), ast_log(), ast_moh_destroy(), ast_register_application(), ast_register_atexit(), cli_moh, cli_moh_classes_show, cli_moh_files_show, descrip0, descrip1, descrip2, descrip3, descrip4, init_classes(), local_ast_moh_cleanup(), local_ast_moh_start(), local_ast_moh_stop(), LOG_WARNING, moh0_exec(), moh1_exec(), moh2_exec(), moh3_exec(), moh4_exec(), synopsis0, synopsis1, synopsis2, synopsis3, and synopsis4. 01177 { 01178 int res; 01179 01180 res = ast_register_application(app0, moh0_exec, synopsis0, descrip0); 01181 ast_register_atexit(ast_moh_destroy); 01182 ast_cli_register(&cli_moh); 01183 ast_cli_register(&cli_moh_files_show); 01184 ast_cli_register(&cli_moh_classes_show); 01185 if (!res) 01186 res = ast_register_application(app1, moh1_exec, synopsis1, descrip1); 01187 if (!res) 01188 res = ast_register_application(app2, moh2_exec, synopsis2, descrip2); 01189 if (!res) 01190 res = ast_register_application(app3, moh3_exec, synopsis3, descrip3); 01191 if (!res) 01192 res = ast_register_application(app4, moh4_exec, synopsis4, descrip4); 01193 01194 if (!init_classes(0)) { /* No music classes configured, so skip it */ 01195 ast_log(LOG_WARNING, "No music on hold classes configured, disabling music on hold."); 01196 } else { 01197 ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup); 01198 } 01199 01200 return 0; 01201 }
|
|
Definition at line 921 of file res_musiconhold.c. References ast_category_browse(), ast_config_destroy(), ast_config_load(), 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, reload(), ast_variable::value, and var. Referenced by init_classes(), and moh_cli(). 00922 { 00923 struct ast_config *cfg; 00924 struct ast_variable *var; 00925 struct mohclass *class; 00926 char *data; 00927 char *args; 00928 char *cat; 00929 int numclasses = 0; 00930 static int dep_warning = 0; 00931 00932 cfg = ast_config_load("musiconhold.conf"); 00933 00934 if (!cfg) 00935 return 0; 00936 00937 cat = ast_category_browse(cfg, NULL); 00938 for (; cat; cat = ast_category_browse(cfg, cat)) { 00939 if (strcasecmp(cat, "classes") && strcasecmp(cat, "moh_files")) { 00940 class = moh_class_malloc(); 00941 if (!class) { 00942 ast_log(LOG_WARNING, "Out of memory!\n"); 00943 break; 00944 } 00945 ast_copy_string(class->name, cat, sizeof(class->name)); 00946 var = ast_variable_browse(cfg, cat); 00947 while (var) { 00948 if (!strcasecmp(var->name, "mode")) 00949 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 00950 else if (!strcasecmp(var->name, "directory")) 00951 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 00952 else if (!strcasecmp(var->name, "application")) 00953 ast_copy_string(class->args, var->value, sizeof(class->args)); 00954 else if (!strcasecmp(var->name, "random")) 00955 ast_set2_flag(class, ast_true(var->value), MOH_RANDOMIZE); 00956 else if (!strcasecmp(var->name, "format")) { 00957 class->format = ast_getformatbyname(var->value); 00958 if (!class->format) { 00959 ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value); 00960 class->format = AST_FORMAT_SLINEAR; 00961 } 00962 } 00963 var = var->next; 00964 } 00965 00966 if (ast_strlen_zero(class->dir)) { 00967 if (!strcasecmp(class->mode, "custom")) { 00968 strcpy(class->dir, "nodir"); 00969 } else { 00970 ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", class->name); 00971 free(class); 00972 continue; 00973 } 00974 } 00975 if (ast_strlen_zero(class->mode)) { 00976 ast_log(LOG_WARNING, "A mode must be specified for class '%s'!\n", class->name); 00977 free(class); 00978 continue; 00979 } 00980 if (ast_strlen_zero(class->args) && !strcasecmp(class->mode, "custom")) { 00981 ast_log(LOG_WARNING, "An application must be specified for class '%s'!\n", class->name); 00982 free(class); 00983 continue; 00984 } 00985 00986 /* Don't leak a class when it's already registered */ 00987 moh_register(class, reload); 00988 00989 numclasses++; 00990 } 00991 } 00992 00993 00994 /* Deprecated Old-School Configuration */ 00995 var = ast_variable_browse(cfg, "classes"); 00996 while (var) { 00997 if (!dep_warning) { 00998 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"); 00999 dep_warning = 1; 01000 } 01001 data = strchr(var->value, ':'); 01002 if (data) { 01003 *data++ = '\0'; 01004 args = strchr(data, ','); 01005 if (args) 01006 *args++ = '\0'; 01007 if (!(get_mohbyname(var->name))) { 01008 class = moh_class_malloc(); 01009 if (!class) { 01010 ast_log(LOG_WARNING, "Out of memory!\n"); 01011 return numclasses; 01012 } 01013 01014 ast_copy_string(class->name, var->name, sizeof(class->name)); 01015 ast_copy_string(class->dir, data, sizeof(class->dir)); 01016 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 01017 if (args) 01018 ast_copy_string(class->args, args, sizeof(class->args)); 01019 01020 moh_register(class, reload); 01021 numclasses++; 01022 } 01023 } 01024 var = var->next; 01025 } 01026 var = ast_variable_browse(cfg, "moh_files"); 01027 while (var) { 01028 if (!dep_warning) { 01029 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"); 01030 dep_warning = 1; 01031 } 01032 if (!(get_mohbyname(var->name))) { 01033 args = strchr(var->value, ','); 01034 if (args) 01035 *args++ = '\0'; 01036 class = moh_class_malloc(); 01037 if (!class) { 01038 ast_log(LOG_WARNING, "Out of memory!\n"); 01039 return numclasses; 01040 } 01041 01042 ast_copy_string(class->name, var->name, sizeof(class->name)); 01043 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 01044 strcpy(class->mode, "files"); 01045 if (args) 01046 ast_copy_string(class->args, args, sizeof(class->args)); 01047 01048 moh_register(class, reload); 01049 numclasses++; 01050 } 01051 var = var->next; 01052 } 01053 01054 ast_config_destroy(cfg); 01055 01056 return numclasses; 01057 }
|
|
Definition at line 860 of file res_musiconhold.c. References free, and ast_channel::music_state. Referenced by load_module(), and reload(). 00861 { 00862 if (chan->music_state) { 00863 free(chan->music_state); 00864 chan->music_state = NULL; 00865 } 00866 }
|
|
Definition at line 868 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, moh_file_stream, mohgen, and mohclass::total_files. Referenced by load_module(), moh_on_off(), and reload(). 00869 { 00870 struct mohclass *mohclass; 00871 00872 if (ast_strlen_zero(class)) 00873 class = chan->musicclass; 00874 if (ast_strlen_zero(class)) 00875 class = "default"; 00876 ast_mutex_lock(&moh_lock); 00877 mohclass = get_mohbyname(class); 00878 ast_mutex_unlock(&moh_lock); 00879 00880 if (!mohclass) { 00881 ast_log(LOG_WARNING, "No class: %s\n", (char *)class); 00882 return -1; 00883 } 00884 00885 ast_set_flag(chan, AST_FLAG_MOH); 00886 if (mohclass->total_files) { 00887 return ast_activate_generator(chan, &moh_file_stream, mohclass); 00888 } else 00889 return ast_activate_generator(chan, &mohgen, mohclass); 00890 }
|
|
Definition at line 892 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(). 00893 { 00894 ast_clear_flag(chan, AST_FLAG_MOH); 00895 ast_deactivate_generator(chan); 00896 00897 if (chan->music_state) { 00898 if (chan->stream) { 00899 ast_closestream(chan->stream); 00900 chan->stream = NULL; 00901 } 00902 } 00903 }
|
|
Definition at line 543 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(). 00544 { 00545 if (ast_moh_start(chan, data)) { 00546 ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name); 00547 return -1; 00548 } 00549 while (!ast_safe_sleep(chan, 10000)); 00550 ast_moh_stop(chan); 00551 return -1; 00552 }
|
|
Definition at line 554 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(). 00555 { 00556 int res; 00557 if (!data || !atoi(data)) { 00558 ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n"); 00559 return -1; 00560 } 00561 if (ast_moh_start(chan, NULL)) { 00562 ast_log(LOG_WARNING, "Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->name); 00563 return -1; 00564 } 00565 res = ast_safe_sleep(chan, atoi(data) * 1000); 00566 ast_moh_stop(chan); 00567 return res; 00568 }
|
|
Definition at line 570 of file res_musiconhold.c. References ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_channel::musicclass. Referenced by load_module(). 00571 { 00572 if (ast_strlen_zero(data)) { 00573 ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n"); 00574 return -1; 00575 } 00576 strncpy(chan->musicclass, data, sizeof(chan->musicclass) - 1); 00577 return 0; 00578 }
|
|
Definition at line 580 of file res_musiconhold.c. References ast_log(), ast_moh_start(), LOG_NOTICE, and ast_channel::name. Referenced by load_module(). 00581 { 00582 char *class = NULL; 00583 if (data && strlen(data)) 00584 class = data; 00585 if (ast_moh_start(chan, class)) 00586 ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name); 00587 00588 return 0; 00589 }
|
|
Definition at line 591 of file res_musiconhold.c. References ast_moh_stop(). Referenced by load_module(). 00592 { 00593 ast_moh_stop(chan); 00594 00595 return 0; 00596 }
|
|
Definition at line 666 of file res_musiconhold.c. References ast_codec2str(), ast_log(), ast_set_write_format(), ast_verbose(), LOG_WARNING, moh_release(), mohalloc(), ast_channel::name, option_verbose, VERBOSE_PREFIX_3, and ast_channel::writeformat. 00667 { 00668 struct mohdata *res; 00669 struct mohclass *class = params; 00670 00671 res = mohalloc(class); 00672 if (res) { 00673 res->origwfmt = chan->writeformat; 00674 if (ast_set_write_format(chan, class->format)) { 00675 ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(class->format)); 00676 moh_release(NULL, res); 00677 res = NULL; 00678 } 00679 if (option_verbose > 2) 00680 ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on channel '%s'\n", class->name, chan->name); 00681 } 00682 return res; 00683 }
|
|
Definition at line 905 of file res_musiconhold.c. References mohclass::format, and malloc. Referenced by load_moh_classes(). 00906 { 00907 struct mohclass *class; 00908 00909 class = malloc(sizeof(struct mohclass)); 00910 00911 if (!class) 00912 return NULL; 00913 00914 memset(class, 0, sizeof(struct mohclass)); 00915 00916 class->format = AST_FORMAT_SLINEAR; 00917 00918 return class; 00919 }
|
|
Definition at line 1137 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 mohclasses. 01138 { 01139 struct mohclass *class; 01140 01141 ast_mutex_lock(&moh_lock); 01142 for (class = mohclasses; class; class = class->next) { 01143 ast_cli(fd, "Class: %s\n", class->name); 01144 ast_cli(fd, "\tMode: %s\n", ast_strlen_zero(class->mode) ? "<none>" : class->mode); 01145 ast_cli(fd, "\tDirectory: %s\n", ast_strlen_zero(class->dir) ? "<none>" : class->dir); 01146 if (ast_test_flag(class, MOH_CUSTOM)) 01147 ast_cli(fd, "\tApplication: %s\n", ast_strlen_zero(class->args) ? "<none>" : class->args); 01148 ast_cli(fd, "\tFormat: %s\n", ast_getformatname(class->format)); 01149 } 01150 ast_mutex_unlock(&moh_lock); 01151 01152 return 0; 01153 }
|
|
Definition at line 1106 of file res_musiconhold.c. References ast_cli(), ast_moh_destroy(), load_moh_classes(), and moh_on_off(). 01107 { 01108 int x; 01109 01110 moh_on_off(0); 01111 ast_moh_destroy(); 01112 x = load_moh_classes(1); 01113 moh_on_off(1); 01114 ast_cli(fd, "\n%d class%s reloaded.\n", x, x == 1 ? "" : "es"); 01115 return 0; 01116 }
|
|
Definition at line 277 of file res_musiconhold.c. References AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), ast_verbose(), moh_files_state::class, free, LOG_WARNING, malloc, ast_channel::music_state, ast_channel::name, option_verbose, moh_files_state::origwfmt, VERBOSE_PREFIX_3, and ast_channel::writeformat. 00278 { 00279 struct moh_files_state *state; 00280 struct mohclass *class = params; 00281 int allocated = 0; 00282 00283 if (!chan->music_state && (state = malloc(sizeof(struct moh_files_state)))) { 00284 chan->music_state = state; 00285 allocated = 1; 00286 } else 00287 state = chan->music_state; 00288 00289 if (state) { 00290 if (allocated || state->class != class) { 00291 /* initialize */ 00292 memset(state, 0, sizeof(struct moh_files_state)); 00293 state->class = class; 00294 } 00295 00296 state->origwfmt = chan->writeformat; 00297 00298 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00299 ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name); 00300 free(chan->music_state); 00301 chan->music_state = NULL; 00302 } else { 00303 if (option_verbose > 2) 00304 ast_verbose(VERBOSE_PREFIX_3 "Started music on hold, class '%s', on %s\n", class->name, chan->name); 00305 } 00306 } 00307 00308 return chan->music_state; 00309 }
|
|
Definition at line 252 of file res_musiconhold.c. References ast_frfree(), ast_log(), ast_write(), LOG_WARNING, moh_files_readframe(), ast_channel::music_state, ast_channel::name, moh_files_state::sample_queue, ast_frame::samples, and moh_files_state::samples. 00253 { 00254 struct moh_files_state *state = chan->music_state; 00255 struct ast_frame *f = NULL; 00256 int res = 0; 00257 00258 state->sample_queue += samples; 00259 00260 while (state->sample_queue > 0) { 00261 if ((f = moh_files_readframe(chan))) { 00262 state->samples += f->samples; 00263 res = ast_write(chan, f); 00264 state->sample_queue -= f->samples; 00265 ast_frfree(f); 00266 if (res < 0) { 00267 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno)); 00268 return -1; 00269 } 00270 } else 00271 return -1; 00272 } 00273 return res; 00274 }
|
|
Definition at line 240 of file res_musiconhold.c. References ast_moh_files_next(), ast_readframe(), and ast_channel::stream. Referenced by moh_files_generator(). 00241 { 00242 struct ast_frame *f = NULL; 00243 00244 if (!(chan->stream && (f = ast_readframe(chan->stream)))) { 00245 if (!ast_moh_files_next(chan)) 00246 f = ast_readframe(chan->stream); 00247 } 00248 00249 return f; 00250 }
|
|
Definition at line 174 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. 00175 { 00176 struct moh_files_state *state = chan->music_state; 00177 00178 if (chan && state) { 00179 if (option_verbose > 2) 00180 ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name); 00181 00182 if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) { 00183 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, state->origwfmt); 00184 } 00185 state->save_pos = state->pos + 1; 00186 } 00187 }
|
|
Definition at line 685 of file res_musiconhold.c. References ast_codec_get_len(), ast_codec_get_samples(), AST_FRIENDLY_OFFSET, ast_log(), ast_write(), mohclass::format, ast_frame::frametype, LOG_WARNING, ast_channel::name, mohdata::parent, mohclass::pid, mohdata::pipe, and ast_frame::subclass. 00686 { 00687 struct ast_frame f; 00688 struct mohdata *moh = data; 00689 short buf[1280 + AST_FRIENDLY_OFFSET / 2]; 00690 int res; 00691 00692 if (!moh->parent->pid) 00693 return -1; 00694 00695 len = ast_codec_get_len(moh->parent->format, samples); 00696 00697 if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) { 00698 ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", (int)sizeof(buf), len, chan->name); 00699 len = sizeof(buf) - AST_FRIENDLY_OFFSET; 00700 } 00701 res = read(moh->pipe[0], buf + AST_FRIENDLY_OFFSET/2, len); 00702 #if 0 00703 if (res != len) { 00704 ast_log(LOG_WARNING, "Read only %d of %d bytes: %s\n", res, len, strerror(errno)); 00705 } 00706 #endif 00707 if (res <= 0) 00708 return 0; 00709 00710 memset(&f, 0, sizeof(f)); 00711 00712 f.frametype = AST_FRAME_VOICE; 00713 f.subclass = moh->parent->format; 00714 f.mallocd = 0; 00715 f.datalen = res; 00716 f.data = buf + AST_FRIENDLY_OFFSET / 2; 00717 f.offset = AST_FRIENDLY_OFFSET; 00718 f.samples = ast_codec_get_samples(&f); 00719 00720 if (ast_write(chan, &f) < 0) { 00721 ast_log(LOG_WARNING, "Failed to write frame to '%s': %s\n", chan->name, strerror(errno)); 00722 return -1; 00723 } 00724 00725 return 0; 00726 }
|
|
Definition at line 1091 of file res_musiconhold.c. References ast_channel_walk_locked(), ast_deactivate_generator(), AST_FLAG_MOH, ast_mutex_unlock(), ast_test_flag, local_ast_moh_start(), and ast_channel::lock. Referenced by moh_cli(). 01092 { 01093 struct ast_channel *chan = NULL; 01094 01095 while ( (chan = ast_channel_walk_locked(chan)) != NULL) { 01096 if (ast_test_flag(chan, AST_FLAG_MOH)) { 01097 if (on) 01098 local_ast_moh_start(chan, NULL); 01099 else 01100 ast_deactivate_generator(chan); 01101 } 01102 ast_mutex_unlock(&chan->lock); 01103 } 01104 }
|
|
Definition at line 788 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, mohclasses, monmp3thread(), mohclass::name, mohclass::next, mohclass::pseudofd, mohclass::srcfd, mohclass::start, and mohclass::thread. Referenced by load_moh_classes(). 00789 { 00790 #ifdef ZAPATA_MOH 00791 int x; 00792 #endif 00793 ast_mutex_lock(&moh_lock); 00794 if (get_mohbyname(moh->name)) { 00795 if (reload) { 00796 ast_log(LOG_DEBUG, "Music on Hold class '%s' left alone from initial load.\n", moh->name); 00797 } else { 00798 ast_log(LOG_WARNING, "Music on Hold class '%s' already exists\n", moh->name); 00799 } 00800 free(moh); 00801 ast_mutex_unlock(&moh_lock); 00802 return -1; 00803 } 00804 ast_mutex_unlock(&moh_lock); 00805 00806 time(&moh->start); 00807 moh->start -= respawn_time; 00808 00809 if (!strcasecmp(moh->mode, "files")) { 00810 if (!moh_scan_files(moh)) { 00811 ast_moh_free_class(&moh); 00812 return -1; 00813 } 00814 if (strchr(moh->args, 'r')) 00815 ast_set_flag(moh, MOH_RANDOMIZE); 00816 } 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")) { 00817 00818 if (!strcasecmp(moh->mode, "custom")) 00819 ast_set_flag(moh, MOH_CUSTOM); 00820 else if (!strcasecmp(moh->mode, "mp3nb")) 00821 ast_set_flag(moh, MOH_SINGLE); 00822 else if (!strcasecmp(moh->mode, "quietmp3nb")) 00823 ast_set_flag(moh, MOH_SINGLE | MOH_QUIET); 00824 else if (!strcasecmp(moh->mode, "quietmp3")) 00825 ast_set_flag(moh, MOH_QUIET); 00826 00827 moh->srcfd = -1; 00828 #ifdef ZAPATA_MOH 00829 /* Open /dev/zap/pseudo for timing... Is 00830 there a better, yet reliable way to do this? */ 00831 moh->pseudofd = open("/dev/zap/pseudo", O_RDONLY); 00832 if (moh->pseudofd < 0) { 00833 ast_log(LOG_WARNING, "Unable to open pseudo channel for timing... Sound may be choppy.\n"); 00834 } else { 00835 x = 320; 00836 ioctl(moh->pseudofd, ZT_SET_BLOCKSIZE, &x); 00837 } 00838 #else 00839 moh->pseudofd = -1; 00840 #endif 00841 if (ast_pthread_create(&moh->thread, NULL, monmp3thread, moh)) { 00842 ast_log(LOG_WARNING, "Unable to create moh...\n"); 00843 if (moh->pseudofd > -1) 00844 close(moh->pseudofd); 00845 ast_moh_free_class(&moh); 00846 return -1; 00847 } 00848 } else { 00849 ast_log(LOG_WARNING, "Don't know how to do a mode '%s' music on hold\n", moh->mode); 00850 ast_moh_free_class(&moh); 00851 return -1; 00852 } 00853 ast_mutex_lock(&moh_lock); 00854 moh->next = mohclasses; 00855 mohclasses = moh; 00856 ast_mutex_unlock(&moh_lock); 00857 return 0; 00858 }
|
|
Definition at line 634 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, ast_channel::name, mohdata::next, option_verbose, mohdata::origwfmt, mohdata::parent, mohdata::pipe, and VERBOSE_PREFIX_3. Referenced by moh_alloc(). 00635 { 00636 struct mohdata *moh = data, *prev, *cur; 00637 int oldwfmt; 00638 ast_mutex_lock(&moh_lock); 00639 /* Unlink */ 00640 prev = NULL; 00641 cur = moh->parent->members; 00642 while (cur) { 00643 if (cur == moh) { 00644 if (prev) 00645 prev->next = cur->next; 00646 else 00647 moh->parent->members = cur->next; 00648 break; 00649 } 00650 prev = cur; 00651 cur = cur->next; 00652 } 00653 ast_mutex_unlock(&moh_lock); 00654 close(moh->pipe[0]); 00655 close(moh->pipe[1]); 00656 oldwfmt = moh->origwfmt; 00657 free(moh); 00658 if (chan) { 00659 if (oldwfmt && ast_set_write_format(chan, oldwfmt)) 00660 ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(oldwfmt)); 00661 if (option_verbose > 2) 00662 ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name); 00663 } 00664 }
|
|
Definition at line 735 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(). 00735 { 00736 00737 DIR *files_DIR; 00738 struct dirent *files_dirent; 00739 char path[512]; 00740 char filepath[MAX_MOHFILE_LEN]; 00741 char *ext; 00742 struct stat statbuf; 00743 int dirnamelen; 00744 int i; 00745 00746 files_DIR = opendir(class->dir); 00747 if (!files_DIR) { 00748 ast_log(LOG_WARNING, "Cannot open dir %s or dir does not exist", class->dir); 00749 return -1; 00750 } 00751 00752 class->total_files = 0; 00753 dirnamelen = strlen(class->dir) + 2; 00754 getcwd(path, 512); 00755 chdir(class->dir); 00756 memset(class->filearray, 0, MAX_MOHFILES*MAX_MOHFILE_LEN); 00757 while ((files_dirent = readdir(files_DIR))) { 00758 if ((strlen(files_dirent->d_name) < 4) || ((strlen(files_dirent->d_name) + dirnamelen) >= MAX_MOHFILE_LEN)) 00759 continue; 00760 00761 snprintf(filepath, MAX_MOHFILE_LEN, "%s/%s", class->dir, files_dirent->d_name); 00762 00763 if (stat(filepath, &statbuf)) 00764 continue; 00765 00766 if (!S_ISREG(statbuf.st_mode)) 00767 continue; 00768 00769 if ((ext = strrchr(filepath, '.'))) { 00770 *ext = '\0'; 00771 ext++; 00772 } 00773 00774 /* if the file is present in multiple formats, ensure we only put it into the list once */ 00775 for (i = 0; i < class->total_files; i++) 00776 if (!strcmp(filepath, class->filearray[i])) 00777 break; 00778 00779 if (i == class->total_files) 00780 strcpy(class->filearray[class->total_files++], filepath); 00781 } 00782 00783 closedir(files_DIR); 00784 chdir(path); 00785 return class->total_files; 00786 }
|
|
Definition at line 610 of file res_musiconhold.c. References ast_log(), free, LOG_WARNING, malloc, mohclass::members, mohdata::next, mohdata::parent, and mohdata::pipe. Referenced by moh_alloc(). 00611 { 00612 struct mohdata *moh; 00613 long flags; 00614 moh = malloc(sizeof(struct mohdata)); 00615 if (!moh) 00616 return NULL; 00617 memset(moh, 0, sizeof(struct mohdata)); 00618 if (pipe(moh->pipe)) { 00619 ast_log(LOG_WARNING, "Failed to create pipe: %s\n", strerror(errno)); 00620 free(moh); 00621 return NULL; 00622 } 00623 /* Make entirely non-blocking */ 00624 flags = fcntl(moh->pipe[0], F_GETFL); 00625 fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK); 00626 flags = fcntl(moh->pipe[1], F_GETFL); 00627 fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK); 00628 moh->parent = cl; 00629 moh->next = cl->members; 00630 cl->members = moh; 00631 return moh; 00632 }
|
|
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_MS_INTERVAL, mohdata::next, mohdata::pipe, spawn_mp3(), and tv. 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 /* Spawn mp3 player if it's not there */ 00486 if (class->srcfd < 0) { 00487 if ((class->srcfd = spawn_mp3(class)) < 0) { 00488 ast_log(LOG_WARNING, "Unable to spawn mp3player\n"); 00489 /* Try again later */ 00490 sleep(500); 00491 } 00492 } 00493 if (class->pseudofd > -1) { 00494 /* Pause some amount of time */ 00495 res = read(class->pseudofd, buf, sizeof(buf)); 00496 } else { 00497 long delta; 00498 /* Reliable sleep */ 00499 tv_tmp = ast_tvnow(); 00500 if (ast_tvzero(tv)) 00501 tv = tv_tmp; 00502 delta = ast_tvdiff_ms(tv_tmp, tv); 00503 if (delta < MOH_MS_INTERVAL) { /* too early */ 00504 tv = ast_tvadd(tv, ast_samp2tv(MOH_MS_INTERVAL, 1000)); /* next deadline */ 00505 usleep(1000 * (MOH_MS_INTERVAL - delta)); 00506 } else { 00507 ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n"); 00508 tv = tv_tmp; 00509 } 00510 res = 8 * MOH_MS_INTERVAL; /* 8 samples per millisecond */ 00511 } 00512 if (!class->members) 00513 continue; 00514 /* Read mp3 audio */ 00515 len = ast_codec_get_len(class->format, res); 00516 00517 if ((res2 = read(class->srcfd, sbuf, len)) != len) { 00518 if (!res2) { 00519 close(class->srcfd); 00520 class->srcfd = -1; 00521 if (class->pid) { 00522 kill(class->pid, SIGKILL); 00523 class->pid = 0; 00524 } 00525 } else 00526 ast_log(LOG_DEBUG, "Read %d bytes of audio while expecting %d\n", res2, len); 00527 continue; 00528 } 00529 ast_mutex_lock(&moh_lock); 00530 moh = class->members; 00531 while (moh) { 00532 /* Write data */ 00533 if ((res = write(moh->pipe[1], sbuf, res2)) != res2) 00534 if (option_debug) 00535 ast_log(LOG_DEBUG, "Only wrote %d of %d bytes to pipe\n", res, res2); 00536 moh = moh->next; 00537 } 00538 ast_mutex_unlock(&moh_lock); 00539 } 00540 return NULL; 00541 }
|
|
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 1203 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(). 01204 { 01205 if (init_classes(1)) 01206 ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup); 01207 01208 return 0; 01209 }
|
|
Definition at line 318 of file res_musiconhold.c. References mohclass::args, ast_log(), ast_strlen_zero(), ast_test_flag, mohclass::dir, LOCAL_MPG_123, LOG_WARNING, MAX_MP3S, MOH_CUSTOM, MOH_QUIET, MOH_SINGLE, MPG_123, respawn_time, and mohclass::start. Referenced by monmp3thread(). 00319 { 00320 int fds[2]; 00321 int files = 0; 00322 char fns[MAX_MP3S][80]; 00323 char *argv[MAX_MP3S + 50]; 00324 char xargs[256]; 00325 char *argptr; 00326 int argc = 0; 00327 DIR *dir = NULL; 00328 struct dirent *de; 00329 00330 00331 if (!strcasecmp(class->dir, "nodir")) { 00332 files = 1; 00333 } else { 00334 dir = opendir(class->dir); 00335 if (!dir && !strstr(class->dir,"http://") && !strstr(class->dir,"HTTP://")) { 00336 ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir); 00337 return -1; 00338 } 00339 } 00340 00341 if (!ast_test_flag(class, MOH_CUSTOM)) { 00342 argv[argc++] = "mpg123"; 00343 argv[argc++] = "-q"; 00344 argv[argc++] = "-s"; 00345 argv[argc++] = "--mono"; 00346 argv[argc++] = "-r"; 00347 argv[argc++] = "8000"; 00348 00349 if (!ast_test_flag(class, MOH_SINGLE)) { 00350 argv[argc++] = "-b"; 00351 argv[argc++] = "2048"; 00352 } 00353 00354 argv[argc++] = "-f"; 00355 00356 if (ast_test_flag(class, MOH_QUIET)) 00357 argv[argc++] = "4096"; 00358 else 00359 argv[argc++] = "8192"; 00360 00361 /* Look for extra arguments and add them to the list */ 00362 strncpy(xargs, class->args, sizeof(xargs) - 1); 00363 argptr = xargs; 00364 while (!ast_strlen_zero(argptr)) { 00365 argv[argc++] = argptr; 00366 argptr = strchr(argptr, ','); 00367 if (argptr) { 00368 *argptr = '\0'; 00369 argptr++; 00370 } 00371 } 00372 } else { 00373 /* Format arguments for argv vector */ 00374 strncpy(xargs, class->args, sizeof(xargs) - 1); 00375 argptr = xargs; 00376 while (!ast_strlen_zero(argptr)) { 00377 argv[argc++] = argptr; 00378 argptr = strchr(argptr, ' '); 00379 if (argptr) { 00380 *argptr = '\0'; 00381 argptr++; 00382 } 00383 } 00384 } 00385 00386 00387 if (strstr(class->dir,"http://") || strstr(class->dir,"HTTP://")) { 00388 strncpy(fns[files], class->dir, sizeof(fns[files]) - 1); 00389 argv[argc++] = fns[files]; 00390 files++; 00391 } else if (dir) { 00392 while ((de = readdir(dir)) && (files < MAX_MP3S)) { 00393 if ((strlen(de->d_name) > 3) && 00394 ((ast_test_flag(class, MOH_CUSTOM) && 00395 (!strcasecmp(de->d_name + strlen(de->d_name) - 4, ".raw") || 00396 !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".sln"))) || 00397 !strcasecmp(de->d_name + strlen(de->d_name) - 4, ".mp3"))) { 00398 strncpy(fns[files], de->d_name, sizeof(fns[files]) - 1); 00399 argv[argc++] = fns[files]; 00400 files++; 00401 } 00402 } 00403 } 00404 argv[argc] = NULL; 00405 if (dir) { 00406 closedir(dir); 00407 } 00408 if (pipe(fds)) { 00409 ast_log(LOG_WARNING, "Pipe failed\n"); 00410 return -1; 00411 } 00412 #if 0 00413 printf("%d files total, %d args total\n", files, argc); 00414 { 00415 int x; 00416 for (x=0;argv[x];x++) 00417 printf("arg%d: %s\n", x, argv[x]); 00418 } 00419 #endif 00420 if (!files) { 00421 ast_log(LOG_WARNING, "Found no files in '%s'\n", class->dir); 00422 close(fds[0]); 00423 close(fds[1]); 00424 return -1; 00425 } 00426 if (time(NULL) - class->start < respawn_time) { 00427 sleep(respawn_time - (time(NULL) - class->start)); 00428 } 00429 time(&class->start); 00430 class->pid = fork(); 00431 if (class->pid < 0) { 00432 close(fds[0]); 00433 close(fds[1]); 00434 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00435 return -1; 00436 } 00437 if (!class->pid) { 00438 int x; 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 1211 of file res_musiconhold.c. 01212 {
01213 return -1;
01214 }
|
|
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 1221 of file res_musiconhold.c. References STANDARD_USECOUNT. 01222 { 01223 /* Never allow Music On Hold to be unloaded 01224 unresolve needed symbols in the dialer */ 01225 #if 0 01226 int res; 01227 STANDARD_USECOUNT(res); 01228 return res; 01229 #else 01230 return 1; 01231 #endif 01232 }
|
|
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. Referenced by load_module(). |
|
Definition at line 73 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 74 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 1155 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 1157 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 1159 of file res_musiconhold.c. Referenced by load_module(). |
|
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. Referenced by load_module(). |
|
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. Referenced by load_module(). |
|
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 311 of file res_musiconhold.c. Referenced by local_ast_moh_start(). |
|
Definition at line 150 of file res_musiconhold.c. Referenced by ast_moh_destroy(), cli_files_show(), moh_classes_show(), and moh_register(). |
|
Definition at line 728 of file res_musiconhold.c. Referenced by local_ast_moh_start(). |
|
Definition at line 107 of file res_musiconhold.c. Referenced by 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. Referenced by load_module(). |
|
Definition at line 79 of file res_musiconhold.c. Referenced by load_module(). |
|
Definition at line 80 of file res_musiconhold.c. Referenced by load_module(). |