Most of Asterisk’s applications, functions and channel drivers are controlled by configuration files. Each file, be it a dialplan configuration, a SIP channel driver configuration file or even the voicemail application, is more or less similar in format – however, this is not the case when dealing with the application level configuration parser.
When I started working on app_xmlrpc_request, I had reached an understanding that the best methodology to go about an manage the various requests would be to do this via a configuration file. As I was browsing the source, I was more or less amazed at the fact that there was no specific methodology of performing the configuration parsing and management within Asterisk. Actually, it would appear that the code includes 3 or 4 different approaches to reading the configuration file and parsing it – appears to be directly related to how old the application/channel_driver is.
In general, all configuration parsing and management, within the Asterisk core applications, is performed via 3 distinct functions:
ast_config_load() – Load a configuration file
ast_category_browse() - Traverse configuration categories (The stuff in square brackets)
ast_variable_browse() – Traverse key/value pairs within a certain configuration category
(courtesy of Russell Bryant).
Now, while the above makes perfect sense, the actual usage is slightly more ambiguous. As I’m building my application, I’ll document my findings in regards to Asterisk configuration parsing and management, so that other people seeking this information will be able to find it and utilize it in the future.
When an application is loaded for the first time into the Asterisk memory and execution space, it would automatically invoke the load_module() function of the application. Upon unloading (eg. shutting down Asterisk), it would load the unload_module() function, which is used mostly for clean ups and memory freeing – depending on your application.
If you were to examine a few applications/channel_drivers, you would notice that that oddly enough, the configuration loading function is called “reload_config”. In my opinion, it’s a little odd to call a configuration loader function as “reload”, however, due to the fact that once Asterisk is running, you’re either “unloading” or “reloading” an application/channel driver – it makes a certain sense.
Examination of the chan_sip.c channel driver, while searching the term “sip.conf”, yields the following:
/*!< Main configuration file */ static const char config[] = "sip.conf";
/*!< Configuration file for sending Notify with CLI commands to reconfigure or reboot phones */ static const char notify_config[] = "sip_notify.conf";
So, looks like the configuration file is pre-defined in a char array called “config” – OK, nothing special about that. Let’s take a look into the reload_config function.
Let’s take a loog at reload_config from chan_sip.c:
struct ast_config *cfg, *ucfg;
struct ast_variable *v;
struct sip_peer *peer;
char *cat, *stringp, *context, *oldregcontext;
char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
struct ast_flags dummy[2];
struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : CONFIG_FLAG_FILEUNCHANGED };
int auto_sip_domains = FALSE;
struct sockaddr_in old_bindaddr = bindaddr;
int registry_count = 0, peer_count = 0;
time_t run_start, run_end;
run_start = time(0);
ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");
cfg = ast_config_load(config, config_flags);
Pay attention to the bold-ed lines.
[TBD]: What is the purpose of the first bold-ed line exactly? is it some form of criteria to know if a configuration really needs to be reloaded or not?
It is fairly clear that the second bold-ed line instructs Asterisk to load the configuration file, indicated by the “config” variable, utilizing the “config_flags”. Let’s check what the result of “ast_config_load” is. The following is taken directly from the code again:
/*! \brief Load a config file
* \param filename path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR
* Create a config structure from a given configuration file.
* \param who_asked The module which is making this request.
* \param flags Optional flags:
* CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact;
* CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or
* CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files).
*
* \retval an ast_config data structure on success
* \retval NULL on error
*/
struct ast_config *ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags);
#define ast_config_load(filename, flags) ast_config_load2(filename, AST_MODULE, flags)
So, after running the second command, the “cfg” variable will hold our configuration information as as complete structure. OK, that’s more or less the idea of loading the configuration file prior to parsing and loading into memory.
You must be logged in to post a comment.