module.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."
#define AST_MODULE_CONFIG   "modules.conf"
#define AST_FORCE_SOFT   0
#define AST_FORCE_FIRM   1
#define AST_FORCE_HARD   2
#define STANDARD_LOCAL_USER
#define LOCAL_USER_DECL
#define LOCAL_USER_ADD(u)
#define LOCAL_USER_REMOVE(u)
#define STANDARD_HANGUP_LOCALUSERS
#define STANDARD_USECOUNT(res)

Functions

int load_module (void)
 Initialize the module.
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.
char * description (void)
 Description.
char * key (void)
 Returns the ASTERISK_GPL_KEY.
int reload (void)
 Reload stuff.
int ast_load_resource (char *resource_name)
 Loads a module.
int ast_unload_resource (char *resource_name, int force)
 Unloads a module.
void ast_update_use_count (void)
 Notify when usecount has been changed.
int ast_update_module_list (int(*modentry)(char *module, char *description, int usecnt))
 Ask for a list of modules, descriptions, and use counts.
int ast_loader_register (int(*updater)(void))
 Ask this procedure to be run with modules have been updated.
int ast_loader_unregister (int(*updater)(void))
 No longer run me when modules are updated.
void ast_module_reload (const char *name)
 Reload all modules.
int ast_register_atexit (void(*func)(void))
void ast_unregister_atexit (void(*func)(void))


Define Documentation

#define AST_FORCE_FIRM   1

Definition at line 80 of file module.h.

#define AST_FORCE_HARD   2

Definition at line 81 of file module.h.

#define AST_FORCE_SOFT   0

Definition at line 79 of file module.h.

#define AST_MODULE_CONFIG   "modules.conf"

Definition at line 77 of file module.h.

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."

reload configs

Definition at line 69 of file module.h.

#define LOCAL_USER_ADD (  ) 

Definition at line 159 of file module.h.

#define LOCAL_USER_DECL

Value:

AST_MUTEX_DEFINE_STATIC(localuser_lock); \
                  static struct localuser *localusers = NULL; \
                  static int localusecnt = 0;

Definition at line 155 of file module.h.

#define LOCAL_USER_REMOVE (  ) 

Definition at line 174 of file module.h.

#define STANDARD_HANGUP_LOCALUSERS

Definition at line 195 of file module.h.

#define STANDARD_LOCAL_USER

Value:

struct localuser { \
                        struct ast_channel *chan; \
                        struct localuser *next; \
                     }

Definition at line 150 of file module.h.

#define STANDARD_USECOUNT ( res   ) 

Value:

{ \
   ast_mutex_lock(&localuser_lock); \
   res = localusecnt; \
   ast_mutex_unlock(&localuser_lock); \
}

Definition at line 209 of file module.h.


Function Documentation

int ast_load_resource ( char *  resource_name  ) 

Loads a module.

Parameters:
resource_name the filename of the module to load This function is ran by the PBX to load the modules. It performs all loading, setting up of it's module related data structures, etc. Basically, to load a module, you just give it the name of the module and it will do the rest. It returns 0 on success, -1 on error

Definition at line 196 of file loader.c.

00197 {
00198    static char fn[256];
00199    int errors=0;
00200    int res;
00201    struct module *m;
00202    int flags=RTLD_NOW;
00203 #ifdef RTLD_GLOBAL
00204    char *val;
00205 #endif
00206    char *key;
00207    int o;
00208    struct ast_config *cfg;
00209    char tmp[80];
00210    /* Keep the module file parsing silent */
00211    o = option_verbose;
00212    if (strncasecmp(resource_name, "res_", 4)) {
00213       option_verbose = 0;
00214       cfg = ast_load(AST_MODULE_CONFIG);
00215       option_verbose = o;
00216       if (cfg) {
00217 #ifdef RTLD_GLOBAL
00218          if ((val = ast_variable_retrieve(cfg, "global", resource_name))
00219                && ast_true(val))
00220             flags |= RTLD_GLOBAL;
00221 #endif
00222          ast_destroy(cfg);
00223       }
00224    } else {
00225       /* Resource modules are always loaded global and lazy */
00226 #ifdef RTLD_GLOBAL
00227       flags = (RTLD_GLOBAL | RTLD_LAZY);
00228 #else
00229       flags = RTLD_LAZY;
00230 #endif
00231    }
00232    
00233    if (ast_mutex_lock(&modlock))
00234       ast_log(LOG_WARNING, "Failed to lock\n");
00235    m = module_list;
00236    while(m) {
00237       if (!strcasecmp(m->resource, resource_name)) {
00238          ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name);
00239          ast_mutex_unlock(&modlock);
00240          return -1;
00241       }
00242       m = m->next;
00243    }
00244    m = malloc(sizeof(struct module));  
00245    if (!m) {
00246       ast_log(LOG_WARNING, "Out of memory\n");
00247       ast_mutex_unlock(&modlock);
00248       return -1;
00249    }
00250    strncpy(m->resource, resource_name, sizeof(m->resource)-1);
00251    if (resource_name[0] == '/') {
00252       strncpy(fn, resource_name, sizeof(fn)-1);
00253    } else {
00254       snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name);
00255    }
00256    m->lib = dlopen(fn, flags);
00257    if (!m->lib) {
00258       ast_log(LOG_WARNING, "%s\n", dlerror());
00259       free(m);
00260       ast_mutex_unlock(&modlock);
00261       return -1;
00262    }
00263    m->load_module = dlsym(m->lib, "load_module");
00264    if (m->load_module == NULL)
00265       m->load_module = dlsym(m->lib, "_load_module");
00266    if (!m->load_module) {
00267       ast_log(LOG_WARNING, "No load_module in module %s\n", fn);
00268       errors++;
00269    }
00270    m->unload_module = dlsym(m->lib, "unload_module");
00271    if (m->unload_module == NULL)
00272       m->unload_module = dlsym(m->lib, "_unload_module");
00273    if (!m->unload_module) {
00274       ast_log(LOG_WARNING, "No unload_module in module %s\n", fn);
00275       errors++;
00276    }
00277    m->usecount = dlsym(m->lib, "usecount");
00278    if (m->usecount == NULL)
00279       m->usecount = dlsym(m->lib, "_usecount");
00280    if (!m->usecount) {
00281       ast_log(LOG_WARNING, "No usecount in module %s\n", fn);
00282       errors++;
00283    }
00284    m->description = dlsym(m->lib, "description");
00285    if (m->description == NULL)
00286       m->description = dlsym(m->lib, "_description");
00287    if (!m->description) {
00288       ast_log(LOG_WARNING, "No description in module %s\n", fn);
00289       errors++;
00290    }
00291    m->key = dlsym(m->lib, "key");
00292    if (m->key == NULL)
00293       m->key = dlsym(m->lib, "_key");
00294    if (!m->key) {
00295       ast_log(LOG_WARNING, "No key routine in module %s\n", fn);
00296       errors++;
00297    }
00298    m->reload = dlsym(m->lib, "reload");
00299    if (m->reload == NULL)
00300       m->reload = dlsym(m->lib, "_reload");
00301    if (!m->key || !(key = m->key())) {
00302       ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn);
00303       key = NULL;
00304       errors++;
00305    }
00306    if (key && verify_key(key)) {
00307       ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn);
00308       errors++;
00309    }
00310    if (errors) {
00311       ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn);
00312       dlclose(m->lib);
00313       free(m);
00314       ast_mutex_unlock(&modlock);
00315       return -1;
00316    }
00317    if (!fully_booted) {
00318       if (option_verbose) 
00319          ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
00320       if (option_console && !option_verbose)
00321          ast_verbose( ".");
00322    } else {
00323       if (option_verbose)
00324          ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
00325    }
00326 
00327    // add module 'm' to end of module_list chain
00328    // so reload commands will be issued in same order modules were loaded
00329    m->next = NULL;
00330    if (module_list == NULL) {
00331       // empty list so far, add at front
00332       module_list = m;
00333    }
00334    else {
00335       struct module *i;
00336       // find end of chain, and add there
00337       for (i = module_list; i->next; i = i->next)
00338          ;
00339       i->next = m;
00340    }
00341 
00342    modlistver = rand();
00343    ast_mutex_unlock(&modlock);
00344    if ((res = m->load_module())) {
00345       ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
00346       ast_unload_resource(resource_name, 0);
00347       return -1;
00348    }
00349    ast_update_use_count();
00350    return 0;
00351 }  

int ast_loader_register ( int(*)(void)  updater  ) 

Ask this procedure to be run with modules have been updated.

Parameters:
updater the function to run when modules have been updated This function adds the given function to a linked list of functions to be run when the modules are updated. It returns 0 on success and -1 on failure.

Definition at line 490 of file loader.c.

00491 {
00492    struct loadupdate *tmp;
00493    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00494    if ((tmp = malloc(sizeof (struct loadupdate)))) {
00495       tmp->updater = v;
00496       if (ast_mutex_lock(&modlock))
00497          ast_log(LOG_WARNING, "Failed to lock\n");
00498       tmp->next = updaters;
00499       updaters = tmp;
00500       ast_mutex_unlock(&modlock);
00501       return 0;
00502    }
00503    return -1;
00504 }

int ast_loader_unregister ( int(*)(void)  updater  ) 

No longer run me when modules are updated.

Parameters:
updater function to unregister This removes the given function from the updater list. It returns 0 on success, -1 on failure.

Definition at line 506 of file loader.c.

00507 {
00508    int res = -1;
00509    struct loadupdate *tmp, *tmpl=NULL;
00510    if (ast_mutex_lock(&modlock))
00511       ast_log(LOG_WARNING, "Failed to lock\n");
00512    tmp = updaters;
00513    while(tmp) {
00514       if (tmp->updater == v)  {
00515          if (tmpl)
00516             tmpl->next = tmp->next;
00517          else
00518             updaters = tmp->next;
00519          break;
00520       }
00521       tmpl = tmp;
00522       tmp = tmp->next;
00523    }
00524    if (tmp)
00525       res = 0;
00526    ast_mutex_unlock(&modlock);
00527    return res;
00528 }

void ast_module_reload ( const char *  name  ) 

Reload all modules.

This reloads all modules set to load in asterisk. It does NOT run the unload routine and then loads them again, it runs the given reload routine.

Definition at line 152 of file loader.c.

00153 {
00154    struct module *m;
00155    int oldversion;
00156    int (*reload)(void);
00157 
00158    /* We'll do the logger and manager the favor of calling its reload here first */
00159 
00160    if (ast_mutex_trylock(&reloadlock)) {
00161       ast_verbose("The previous reload command didn't finish yet\n");
00162       return;
00163    }
00164    if (!name || !strcasecmp(name, "astconfig"))
00165       read_ast_cust_config();
00166    if (!name || !strcasecmp(name, "manager"))
00167       reload_manager();
00168    if (!name || !strcasecmp(name, "enum"))
00169       ast_enum_reload();
00170    if (!name || !strcasecmp(name, "rtp"))
00171       ast_rtp_reload();
00172    time(&ast_lastreloadtime);
00173 
00174    ast_mutex_lock(&modlock);
00175    oldversion = modlistver;   
00176    m = module_list;
00177    while(m) {
00178       if (!name || !strcasecmp(name, m->resource)) {
00179          reload = m->reload;
00180          ast_mutex_unlock(&modlock);
00181          if (reload) {
00182             if (option_verbose > 2) 
00183                ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description());
00184             reload();   
00185          }
00186          ast_mutex_lock(&modlock);
00187          if (oldversion != modlistver)
00188             break;
00189       }
00190       m = m->next;
00191    }
00192    ast_mutex_unlock(&modlock);
00193    ast_mutex_unlock(&reloadlock);
00194 }

int ast_register_atexit ( void(*)(void)  func  ) 

Definition at line 133 of file asterisk.c.

00134 {
00135    int res = -1;
00136    struct ast_atexit *ae;
00137    ast_unregister_atexit(func);
00138    ae = malloc(sizeof(struct ast_atexit));
00139    ast_mutex_lock(&atexitslock);
00140    if (ae) {
00141       memset(ae, 0, sizeof(struct ast_atexit));
00142       ae->next = atexits;
00143       ae->func = func;
00144       atexits = ae;
00145       res = 0;
00146    }
00147    ast_mutex_unlock(&atexitslock);
00148    return res;
00149 }

int ast_unload_resource ( char *  resource_name,
int  force 
)

Unloads a module.

Parameters:
resourcename the name of the module to unload
force the force flag. Setting this to non-zero will force the module to be unloaded This function unloads a particular module. If the force flag is not set, it will not unload a module with a usecount > 0. However, if it is set, it will unload the module regardless of consequences (NOT_RECOMMENDED)

Definition at line 108 of file loader.c.

00109 {
00110    struct module *m, *ml = NULL;
00111    int res = -1;
00112    if (ast_mutex_lock(&modlock))
00113       ast_log(LOG_WARNING, "Failed to lock\n");
00114    m = module_list;
00115    while(m) {
00116       if (!strcasecmp(m->resource, resource_name)) {
00117          if ((res = m->usecount()) > 0)  {
00118             if (force) 
00119                ast_log(LOG_WARNING, "Warning:  Forcing removal of module %s with use count %d\n", resource_name, res);
00120             else {
00121                ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res);
00122                ast_mutex_unlock(&modlock);
00123                return -1;
00124             }
00125          }
00126          res = m->unload_module();
00127          if (res) {
00128             ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
00129             if (force <= AST_FORCE_FIRM) {
00130                ast_mutex_unlock(&modlock);
00131                return -1;
00132             } else
00133                ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
00134          }
00135          if (ml)
00136             ml->next = m->next;
00137          else
00138             module_list = m->next;
00139          dlclose(m->lib);
00140          free(m);
00141          break;
00142       }
00143       ml = m;
00144       m = m->next;
00145    }
00146    modlistver = rand();
00147    ast_mutex_unlock(&modlock);
00148    ast_update_use_count();
00149    return res;
00150 }

void ast_unregister_atexit ( void(*)(void)  func  ) 

Definition at line 151 of file asterisk.c.

00152 {
00153    struct ast_atexit *ae, *prev = NULL;
00154    ast_mutex_lock(&atexitslock);
00155    ae = atexits;
00156    while(ae) {
00157       if (ae->func == func) {
00158          if (prev)
00159             prev->next = ae->next;
00160          else
00161             atexits = ae->next;
00162          break;
00163       }
00164       prev = ae;
00165       ae = ae->next;
00166    }
00167    ast_mutex_unlock(&atexitslock);
00168 }

int ast_update_module_list ( int(*)(char *module, char *description, int usecnt)  modentry  ) 

Ask for a list of modules, descriptions, and use counts.

Parameters:
modentry a callback to an updater function For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.

Definition at line 474 of file loader.c.

00475 {
00476    struct module *m;
00477    int unlock = -1;
00478    if (ast_mutex_trylock(&modlock))
00479       unlock = 0;
00480    m = module_list;
00481    while(m) {
00482       modentry(m->resource, m->description(), m->usecount());
00483       m = m->next;
00484    }
00485    if (unlock)
00486       ast_mutex_unlock(&modlock);
00487    return 0;
00488 }

void ast_update_use_count ( void   ) 

Notify when usecount has been changed.

This function goes through and calulates use counts. It also notifies anybody trying to keep track of them.

Definition at line 458 of file loader.c.

00459 {
00460    /* Notify any module monitors that the use count for a 
00461       resource has changed */
00462    struct loadupdate *m;
00463    if (ast_mutex_lock(&modlock))
00464       ast_log(LOG_WARNING, "Failed to lock\n");
00465    m = updaters;
00466    while(m) {
00467       m->updater();
00468       m = m->next;
00469    }
00470    ast_mutex_unlock(&modlock);
00471    
00472 }

char* description ( void   ) 

Description.

How many channels provided by this module are in use?

Returns a short description of your module.

char* key ( void   ) 

Returns the ASTERISK_GPL_KEY.

Description of this module

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, i.e. char *key(void){return ASTERISK_GPL_KEY;}

int load_module ( void   ) 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

int reload ( void   ) 

Reload stuff.

Return the below mentioned key, unmodified

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload. Return 0 on success, and other than 0 on problem.

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit). Return 0 on success, or other than 0 if there is a problem.

int usecount ( void   ) 

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.


Generated on Wed Oct 28 17:00:58 2009 for Asterisk by  doxygen 1.5.6