Sat Nov 1 06:29:17 2008

Asterisk developer's documentation


res_musiconhold.c File Reference

Routines implementing music on hold. More...

#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 mohclassget_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 mohclassmoh_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_framemoh_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 mohdatamohalloc (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"


Detailed Description

Routines implementing music on hold.

Author:
Mark Spencer <markster@digium.com>

Definition in file res_musiconhold.c.


Define Documentation

#define INITIAL_NUM_FILES   8

Definition at line 73 of file res_musiconhold.c.

Referenced by moh_add_file().

#define LOCAL_MPG_123   "/usr/local/bin/mpg123"

Definition at line 168 of file res_musiconhold.c.

#define MAX_MP3S   256

Definition at line 170 of file res_musiconhold.c.

Referenced by spawn_mp3().

#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)

Definition at line 124 of file res_musiconhold.c.

Referenced by moh_register(), and spawn_mp3().

#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)

Definition at line 125 of file res_musiconhold.c.

Referenced by moh_register(), and spawn_mp3().

#define MPG_123   "/usr/bin/mpg123"

Definition at line 169 of file res_musiconhold.c.


Function Documentation

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]

Note:
This function should be called with the mohclasses list locked

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