#include "asterisk.h"
#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/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 "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/dahdi_compat.h"
Include dependency graph for res_musiconhold.c:
Go to the source code of this file.
Data Structures | |
| struct | moh_files_state |
| struct | mohclass |
| struct | mohdata |
Defines | |
| #define | INITIAL_NUM_FILES 8 |
| #define | LOCAL_MPG_123 "/usr/local/bin/mpg123" |
| #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 | |
| AST_LIST_HEAD_STATIC (mohclasses, mohclass) | |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Music On Hold Resource",.load=load_module,.unload=unload_module,.reload=reload,) | |
| static void | ast_moh_destroy (void) |
| static int | ast_moh_destroy_one (struct mohclass *moh) |
| static int | ast_moh_files_next (struct ast_channel *chan) |
| static void | ast_moh_free_class (struct mohclass **mohclass) |
| static int | cli_files_show (int fd, int argc, char *argv[]) |
| static struct mohclass * | get_mohbyname (const char *name, int warn) |
| static int | init_classes (int reload) |
| static int | load_module (void) |
| 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, const char *mclass, const char *interpclass) |
| 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 int | moh_add_file (struct mohclass *class, const char *filepath) |
| 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 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) |
| static int | reload (void) |
| static int | spawn_mp3 (struct mohclass *class) |
| static int | unload_module (void) |
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 [] |
| static struct ast_cli_entry | cli_moh_classes_show_deprecated |
| static struct ast_cli_entry | cli_moh_files_show_deprecated |
| static char * | descrip0 |
| static char * | descrip1 |
| static char * | descrip2 |
| static char * | descrip3 |
| static char * | descrip4 |
| static struct ast_generator | moh_file_stream |
| 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.
| #define INITIAL_NUM_FILES 8 |
| #define LOCAL_MPG_123 "/usr/local/bin/mpg123" |
Definition at line 168 of file res_musiconhold.c.
| #define MAX_MP3S 256 |
| #define MOH_CUSTOM (1 << 2) |
Definition at line 126 of file res_musiconhold.c.
Referenced by moh_classes_show(), moh_register(), and spawn_mp3().
| #define MOH_MS_INTERVAL 100 |
Referenced by monmp3thread().
| #define MOH_QUIET (1 << 0) |
| #define MOH_RANDOMIZE (1 << 3) |
Definition at line 127 of file res_musiconhold.c.
Referenced by ast_moh_files_next(), load_moh_classes(), moh_files_alloc(), and moh_register().
| #define MOH_SINGLE (1 << 1) |
| #define MPG_123 "/usr/bin/mpg123" |
Definition at line 169 of file res_musiconhold.c.
| AST_LIST_HEAD_STATIC | ( | mohclasses | , | |
| mohclass | ||||
| ) |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
| "Music On Hold Resource" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| static void ast_moh_destroy | ( | void | ) | [static] |
Definition at line 1185 of file res_musiconhold.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_moh_destroy_one(), ast_verbose(), moh, option_verbose, and VERBOSE_PREFIX_2.
Referenced by load_module(), and unload_module().
01186 { 01187 struct mohclass *moh; 01188 01189 if (option_verbose > 1) 01190 ast_verbose(VERBOSE_PREFIX_2 "Destroying musiconhold processes\n"); 01191 01192 AST_LIST_LOCK(&mohclasses); 01193 while ((moh = AST_LIST_REMOVE_HEAD(&mohclasses, list))) { 01194 ast_moh_destroy_one(moh); 01195 } 01196 AST_LIST_UNLOCK(&mohclasses); 01197 }
| static int ast_moh_destroy_one | ( | struct mohclass * | moh | ) | [static] |
Definition at line 1155 of file res_musiconhold.c.
References ast_log(), ast_moh_free_class(), ast_wait_for_input(), LOG_DEBUG, moh, and mohclass::pid.
Referenced by ast_moh_destroy(), init_classes(), moh_files_release(), and moh_release().
01156 { 01157 char buff[8192]; 01158 int bytes, tbytes = 0, stime = 0, pid = 0; 01159 01160 if (moh) { 01161 if (moh->pid > 1) { 01162 ast_log(LOG_DEBUG, "killing %d!\n", moh->pid); 01163 stime = time(NULL) + 2; 01164 pid = moh->pid; 01165 moh->pid = 0; 01166 /* Back when this was just mpg123, SIGKILL was fine. Now we need 01167 * to give the process a reason and time enough to kill off its 01168 * children. */ 01169 kill(pid, SIGHUP); 01170 usleep(100000); 01171 kill(pid, SIGTERM); 01172 usleep(100000); 01173 kill(pid, SIGKILL); 01174 while ((ast_wait_for_input(moh->srcfd, 100) > 0) && (bytes = read(moh->srcfd, buff, 8192)) && time(NULL) < stime) 01175 tbytes = tbytes + bytes; 01176 ast_log(LOG_DEBUG, "mpg123 pid %d and child died after %d bytes read\n", pid, tbytes); 01177 close(moh->srcfd); 01178 } 01179 ast_moh_free_class(&moh); 01180 } 01181 01182 return 0; 01183 }
| static int ast_moh_files_next | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 225 of file res_musiconhold.c.
References ast_closestream(), ast_fileexists(), ast_log(), ast_openstream_full(), ast_random(), ast_test_flag, moh_files_state::class, errno, mohclass::filearray, LOG_WARNING, MOH_RANDOMIZE, ast_channel::music_state, mohclass::name, moh_files_state::pos, moh_files_state::samples, moh_files_state::save_pos, moh_files_state::save_pos_filename, ast_channel::stream, and mohclass::total_files.
Referenced by moh_files_readframe().
00226 { 00227 struct moh_files_state *state = chan->music_state; 00228 int tries; 00229 00230 /* Discontinue a stream if it is running already */ 00231 if (chan->stream) { 00232 ast_closestream(chan->stream); 00233 chan->stream = NULL; 00234 } 00235 00236 if (!state->class->total_files) { 00237 ast_log(LOG_WARNING, "No files available for class '%s'\n", state->class->name); 00238 return -1; 00239 } 00240 00241 /* If a specific file has been saved confirm it still exists and that it is still valid */ 00242 if (state->save_pos >= 0 && state->save_pos < state->class->total_files && state->class->filearray[state->save_pos] == state->save_pos_filename) { 00243 state->pos = state->save_pos; 00244 state->save_pos = -1; 00245 } else if (ast_test_flag(state->class, MOH_RANDOMIZE)) { 00246 /* Get a random file and ensure we can open it */ 00247 for (tries = 0; tries < 20; tries++) { 00248 state->pos = ast_random() % state->class->total_files; 00249 if (ast_fileexists(state->class->filearray[state->pos], NULL, NULL) > 0) 00250 break; 00251 } 00252 state->save_pos = -1; 00253 state->samples = 0; 00254 } else { 00255 /* This is easy, just increment our position and make sure we don't exceed the total file count */ 00256 state->pos++; 00257 state->pos %= state->class->total_files; 00258 state->save_pos = -1; 00259 state->samples = 0; 00260 } 00261 00262 if (!ast_openstream_full(chan, state->class->filearray[state->pos], chan->language, 1)) { 00263 ast_log(LOG_WARNING, "Unable to open file '%s': %s\n", state->class->filearray[state->pos], strerror(errno)); 00264 state->pos++; 00265 state->pos %= state->class->total_files; 00266 return -1; 00267 } 00268 00269 /* Record the pointer to the filename for position resuming later */ 00270 state->save_pos_filename = state->class->filearray[state->pos]; 00271 00272 if (option_debug) 00273 ast_log(LOG_DEBUG, "%s Opened file %d '%s'\n", chan->name, state->pos, state->class->filearray[state->pos]); 00274 00275 if (state->samples) 00276 ast_seekstream(chan->stream, state->samples, SEEK_SET); 00277 00278 return 0; 00279 }
| static void ast_moh_free_class | ( | struct mohclass ** | mohclass | ) | [static] |
Definition at line 175 of file res_musiconhold.c.
References AST_LIST_REMOVE_HEAD, and free.
Referenced by ast_moh_destroy_one(), and moh_register().
00176 { 00177 struct mohdata *member; 00178 struct mohclass *class = *mohclass; 00179 int i; 00180 00181 while ((member = AST_LIST_REMOVE_HEAD(&class->members, list))) 00182 free(member); 00183 00184 if (class->thread) { 00185 pthread_cancel(class->thread); 00186 class->thread = 0; 00187 } 00188 00189 if (class->filearray) { 00190 for (i = 0; i < class->total_files; i++) 00191 free(class->filearray[i]); 00192 free(class->filearray); 00193 } 00194 00195 free(class); 00196 *mohclass = NULL; 00197 }
| static int cli_files_show | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1205 of file res_musiconhold.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.
01206 { 01207 int i; 01208 struct mohclass *class; 01209 01210 AST_LIST_LOCK(&mohclasses); 01211 AST_LIST_TRAVERSE(&mohclasses, class, list) { 01212 if (!class->total_files) 01213 continue; 01214 01215 ast_cli(fd, "Class: %s\n", class->name); 01216 for (i = 0; i < class->total_files; i++) 01217 ast_cli(fd, "\tFile: %s\n", class->filearray[i]); 01218 } 01219 AST_LIST_UNLOCK(&mohclasses); 01220 01221 return 0; 01222 }
| static struct mohclass* get_mohbyname | ( | const char * | name, | |
| int | warn | |||
| ) | [static] |
Definition at line 648 of file res_musiconhold.c.
References AST_LIST_TRAVERSE, ast_log(), LOG_WARNING, and moh.
Referenced by load_moh_classes(), local_ast_moh_start(), and moh_register().
00649 { 00650 struct mohclass *moh = NULL; 00651 00652 AST_LIST_TRAVERSE(&mohclasses, moh, list) { 00653 if (!strcasecmp(name, moh->name)) 00654 break; 00655 } 00656 00657 if (!moh && warn) 00658 ast_log(LOG_WARNING, "Music on Hold class '%s' not found\n", name); 00659 00660 return moh; 00661 }
| static int init_classes | ( | int | reload | ) | [static] |
Definition at line 1268 of file res_musiconhold.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_moh_destroy_one(), load_moh_classes(), and moh.
Referenced by load_module(), and reload().
01269 { 01270 struct mohclass *moh; 01271 01272 if (!load_moh_classes(reload)) /* Load classes from config */ 01273 return 0; /* Return if nothing is found */ 01274 01275 AST_LIST_LOCK(&mohclasses); 01276 AST_LIST_TRAVERSE_SAFE_BEGIN(&mohclasses, moh, list) { 01277 if (reload && moh->delete) { 01278 AST_LIST_REMOVE_CURRENT(&mohclasses, list); 01279 if (!moh->inuse) 01280 ast_moh_destroy_one(moh); 01281 } 01282 } 01283 AST_LIST_TRAVERSE_SAFE_END 01284 AST_LIST_UNLOCK(&mohclasses); 01285 01286 return 1; 01287 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1289 of file res_musiconhold.c.
References ast_cli_register_multiple(), ast_install_music_functions(), ast_log(), ast_moh_destroy(), ast_register_application(), ast_register_atexit(), cli_moh, init_classes(), local_ast_moh_cleanup(), local_ast_moh_start(), local_ast_moh_stop(), LOG_WARNING, moh0_exec(), moh1_exec(), moh2_exec(), moh3_exec(), and moh4_exec().
01290 { 01291 int res; 01292 01293 res = ast_register_application(app0, moh0_exec, synopsis0, descrip0); 01294 ast_register_atexit(ast_moh_destroy); 01295 ast_cli_register_multiple(cli_moh, sizeof(cli_moh) / sizeof(struct ast_cli_entry)); 01296 if (!res) 01297 res = ast_register_application(app1, moh1_exec, synopsis1, descrip1); 01298 if (!res) 01299 res = ast_register_application(app2, moh2_exec, synopsis2, descrip2); 01300 if (!res) 01301 res = ast_register_application(app3, moh3_exec, synopsis3, descrip3); 01302 if (!res) 01303 res = ast_register_application(app4, moh4_exec, synopsis4, descrip4); 01304 01305 if (!init_classes(0)) { /* No music classes configured, so skip it */ 01306 ast_log(LOG_WARNING, "No music on hold classes configured, disabling music on hold.\n"); 01307 } else { 01308 ast_install_music_functions(local_ast_moh_start, local_ast_moh_stop, local_ast_moh_cleanup); 01309 } 01310 01311 return 0; 01312 }
| static int load_moh_classes | ( | int | reload | ) | [static] |
Definition at line 1016 of file res_musiconhold.c.
References mohclass::args, ast_category_browse(), ast_config_destroy(), ast_config_load(), AST_FORMAT_SLINEAR, ast_getformatbyname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), free, get_mohbyname(), LOG_WARNING, moh_class_malloc(), MOH_RANDOMIZE, moh_register(), and var.
Referenced by init_classes().
01017 { 01018 struct ast_config *cfg; 01019 struct ast_variable *var; 01020 struct mohclass *class; 01021 char *data; 01022 char *args; 01023 char *cat; 01024 int numclasses = 0; 01025 static int dep_warning = 0; 01026 01027 cfg = ast_config_load("musiconhold.conf"); 01028 01029 if (!cfg) 01030 return 0; 01031 01032 if (reload) { 01033 AST_LIST_LOCK(&mohclasses); 01034 AST_LIST_TRAVERSE(&mohclasses, class, list) 01035 class->delete = 1; 01036 AST_LIST_UNLOCK(&mohclasses); 01037 } 01038 01039 cat = ast_category_browse(cfg, NULL); 01040 for (; cat; cat = ast_category_browse(cfg, cat)) { 01041 if (strcasecmp(cat, "classes") && strcasecmp(cat, "moh_files")) { 01042 if (!(class = moh_class_malloc())) { 01043 break; 01044 } 01045 ast_copy_string(class->name, cat, sizeof(class->name)); 01046 var = ast_variable_browse(cfg, cat); 01047 while (var) { 01048 if (!strcasecmp(var->name, "mode")) 01049 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 01050 else if (!strcasecmp(var->name, "directory")) 01051 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 01052 else if (!strcasecmp(var->name, "application")) 01053 ast_copy_string(class->args, var->value, sizeof(class->args)); 01054 else if (!strcasecmp(var->name, "random")) 01055 ast_set2_flag(class, ast_true(var->value), MOH_RANDOMIZE); 01056 else if (!strcasecmp(var->name, "format")) { 01057 class->format = ast_getformatbyname(var->value); 01058 if (!class->format) { 01059 ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value); 01060 class->format = AST_FORMAT_SLINEAR; 01061 } 01062 } 01063 var = var->next; 01064 } 01065 01066 if (ast_strlen_zero(class->dir)) { 01067 if (!strcasecmp(class->mode, "custom")) { 01068 strcpy(class->dir, "nodir"); 01069 } else { 01070 ast_log(LOG_WARNING, "A directory must be specified for class '%s'!\n", class->name); 01071 free(class); 01072 continue; 01073 } 01074 } 01075 if (ast_strlen_zero(class->mode)) { 01076 ast_log(LOG_WARNING, "A mode must be specified for class '%s'!\n", class->name); 01077 free(class); 01078 continue; 01079 } 01080 if (ast_strlen_zero(class->args) && !strcasecmp(class->mode, "custom")) { 01081 ast_log(LOG_WARNING, "An application must be specified for class '%s'!\n", class->name); 01082 free(class); 01083 continue; 01084 } 01085 01086 /* Don't leak a class when it's already registered */ 01087 moh_register(class, reload); 01088 01089 numclasses++; 01090 } 01091 } 01092 01093 01094 /* Deprecated Old-School Configuration */ 01095 var = ast_variable_browse(cfg, "classes"); 01096 while (var) { 01097 if (!dep_warning) { 01098 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"); 01099 dep_warning = 1; 01100 } 01101 data = strchr(var->value, ':'); 01102 if (data) { 01103 *data++ = '\0'; 01104 args = strchr(data, ','); 01105 if (args) 01106 *args++ = '\0'; 01107 if (!(get_mohbyname(var->name, 0))) { 01108 if (!(class = moh_class_malloc())) { 01109 break; 01110 } 01111 01112 ast_copy_string(class->name, var->name, sizeof(class->name)); 01113 ast_copy_string(class->dir, data, sizeof(class->dir)); 01114 ast_copy_string(class->mode, var->value, sizeof(class->mode)); 01115 if (args) 01116 ast_copy_string(class->args, args, sizeof(class->args)); 01117 01118 moh_register(class, reload); 01119 numclasses++; 01120 } 01121 } 01122 var = var->next; 01123 } 01124 var = ast_variable_browse(cfg, "moh_files"); 01125 while (var) { 01126 if (!dep_warning) { 01127 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"); 01128 dep_warning = 1; 01129 } 01130 if (!(get_mohbyname(var->name, 0))) { 01131 args = strchr(var->value, ','); 01132 if (args) 01133 *args++ = '\0'; 01134 if (!(class = moh_class_malloc())) { 01135 break; 01136 } 01137 01138 ast_copy_string(class->name, var->name, sizeof(class->name)); 01139 ast_copy_string(class->dir, var->value, sizeof(class->dir)); 01140 strcpy(class->mode, "files"); 01141 if (args) 01142 ast_copy_string(class->args, args, sizeof(class->args)); 01143 01144 moh_register(class, reload); 01145 numclasses++; 01146 } 01147 var = var->next; 01148 } 01149 01150 ast_config_destroy(cfg); 01151 01152 return numclasses; 01153 }
| static void local_ast_moh_cleanup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 947 of file res_musiconhold.c.
References free, and ast_channel::music_state.
Referenced by load_module(), and reload().
00948 { 00949 if (chan->music_state) { 00950 free(chan->music_state); 00951 chan->music_state = NULL; 00952 } 00953 }
| static int local_ast_moh_start | ( | struct ast_channel * | chan, | |
| const char * | mclass, | |||
| const char * | interpclass | |||
| ) | [static] |
Definition at line 955 of file res_musiconhold.c.
References ast_activate_generator(), AST_FLAG_MOH, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_set_flag, ast_strlen_zero(), get_mohbyname(), mohclass::inuse, moh_file_stream, mohgen, and mohclass::total_files.
Referenced by load_module(), and reload().
00956 { 00957 struct mohclass *mohclass = NULL; 00958 00959 /* The following is the order of preference for which class to use: 00960 * 1) The channels explicitly set musicclass, which should *only* be 00961 * set by a call to Set(CHANNEL(musicclass)=whatever) in the dialplan. 00962 * 2) The mclass argument. If a channel is calling ast_moh_start() as the 00963 * result of receiving a HOLD control frame, this should be the 00964 * payload that came with the frame. 00965 * 3) The interpclass argument. This would be from the mohinterpret 00966 * option from channel drivers. This is the same as the old musicclass 00967 * option. 00968 * 4) The default class. 00969 */ 00970 AST_LIST_LOCK(&mohclasses); 00971 if (!ast_strlen_zero(chan->musicclass)) 00972 mohclass = get_mohbyname(chan->musicclass, 1); 00973 if (!mohclass && !ast_strlen_zero(mclass)) 00974 mohclass = get_mohbyname(mclass, 1); 00975 if (!mohclass && !ast_strlen_zero(interpclass)) 00976 mohclass = get_mohbyname(interpclass, 1); 00977 if (!mohclass) 00978 mohclass = get_mohbyname("default", 1); 00979 if (mohclass) 00980 ast_atomic_fetchadd_int(&mohclass->inuse, +1); 00981 AST_LIST_UNLOCK(&mohclasses); 00982 00983 if (!mohclass) 00984 return -1; 00985 00986 ast_set_flag(chan, AST_FLAG_MOH); 00987 if (mohclass->total_files) { 00988 return ast_activate_generator(chan, &moh_file_stream, mohclass); 00989 } else 00990 return ast_activate_generator(chan, &mohgen, mohclass); 00991 }
| static void local_ast_moh_stop | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 993 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().
00994 { 00995 ast_clear_flag(chan, AST_FLAG_MOH); 00996 ast_deactivate_generator(chan); 00997 00998 if (chan->music_state) { 00999 if (chan->stream) { 01000 ast_closestream(chan->stream); 01001 chan->stream = NULL; 01002 } 01003 } 01004 }
| static int moh0_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 592 of file res_musiconhold.c.
References ast_log(), ast_moh_start(), ast_moh_stop(), ast_safe_sleep(), and LOG_WARNING.
Referenced by load_module().
00593 { 00594 if (ast_moh_start(chan, data, NULL)) { 00595 ast_log(LOG_WARNING, "Unable to start music on hold (class '%s') on channel %s\n", (char *)data, chan->name); 00596 return 0; 00597 } 00598 while (!ast_safe_sleep(chan, 10000)); 00599 ast_moh_stop(chan); 00600 return -1; 00601 }
| static int moh1_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 603 of file res_musiconhold.c.
References ast_log(), ast_moh_start(), ast_moh_stop(), ast_safe_sleep(), and LOG_WARNING.
Referenced by load_module().
00604 { 00605 int res; 00606 if (!data || !atoi(data)) { 00607 ast_log(LOG_WARNING, "WaitMusicOnHold requires an argument (number of seconds to wait)\n"); 00608 return -1; 00609 } 00610 if (ast_moh_start(chan, NULL, NULL)) { 00611 ast_log(LOG_WARNING, "Unable to start music on hold for %d seconds on channel %s\n", atoi(data), chan->name); 00612 return 0; 00613 } 00614 res = ast_safe_sleep(chan, atoi(data) * 1000); 00615 ast_moh_stop(chan); 00616 return res; 00617 }
| static int moh2_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 619 of file res_musiconhold.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), LOG_WARNING, and musicclass.
Referenced by load_module().
00620 { 00621 if (ast_strlen_zero(data)) { 00622 ast_log(LOG_WARNING, "SetMusicOnHold requires an argument (class)\n"); 00623 return -1; 00624 } 00625 ast_string_field_set(chan, musicclass, data); 00626 return 0; 00627 }
| static int moh3_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 629 of file res_musiconhold.c.
References ast_log(), ast_moh_start(), and LOG_NOTICE.
Referenced by load_module().
00630 { 00631 char *class = NULL; 00632 if (data && strlen(data)) 00633 class = data; 00634 if (ast_moh_start(chan, class, NULL)) 00635 ast_log(LOG_NOTICE, "Unable to start music on hold class '%s' on channel %s\n", class ? class : "default", chan->name); 00636 00637 return 0; 00638 }
| static int moh4_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 640 of file res_musiconhold.c.
References ast_moh_stop().
Referenced by load_module().
00641 { 00642 ast_moh_stop(chan); 00643 00644 return 0; 00645 }
| static int moh_add_file | ( | struct mohclass * | class, | |
| const char * | filepath | |||
| ) | [static] |
Definition at line 775 of file res_musiconhold.c.
References mohclass::allowed_files, ast_calloc, ast_realloc, ast_strdup, mohclass::filearray, INITIAL_NUM_FILES, and mohclass::total_files.
Referenced by moh_scan_files().
00776 { 00777 if (!class->allowed_files) { 00778 if (!(class->filearray = ast_calloc(1, INITIAL_NUM_FILES * sizeof(*class->filearray)))) 00779 return -1; 00780 class->allowed_files = INITIAL_NUM_FILES; 00781 } else if (class->total_files == class->allowed_files) { 00782 if (!(class->filearray = ast_realloc(class->filearray, class->allowed_files * sizeof(*class->filearray) * 2))) { 00783 class->allowed_files = 0; 00784 class->total_files = 0; 00785 return -1; 00786 } 00787 class->allowed_files *= 2; 00788 } 00789 00790 if (!(class->filearray[class->total_files] = ast_strdup(filepath))) 00791 return -1; 00792 00793 class->total_files++; 00794 00795 return 0; 00796 }
| static void* moh_alloc | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 719 of file res_musiconhold.c.
References ast_codec2str(), ast_log(), ast_set_write_format(), ast_verbose(), LOG_WARNING, moh_release(), mohalloc(), option_verbose, mohdata::origwfmt, VERBOSE_PREFIX_3, and