voicemail: Move app_voicemail / res_mwi_external conflict to runtime
authorGeorge Joseph <george.joseph@fairview5.com>
Wed, 30 Dec 2015 16:49:03 +0000 (09:49 -0700)
committerGeorge Joseph <george.joseph@fairview5.com>
Mon, 4 Jan 2016 23:31:24 +0000 (17:31 -0600)
The menuselect conflict between app_voicemail and res_mwi_external
makes it hard to package 1 version of Asterisk.  There no actual
build dependencies between the 2 so moving this check to runtime
seems like a better solution.

The ast_vm_register and ast_vm_greeter_register functions in app.c
were modified to return AST_MODULE_LOAD_DECLINE instead of -1 if there
is already a voicemail module registered. The modules' load_module
functions were then modified to return DECLINE instead of -1 to the
loader.  Since -1 is interpreted by the loader as AST_MODULE_LOAD_FAILURE,
the modules were incorrectly causing Asterisk to stop so this needed
to be cleaned up anyway.

Now you can build both and use modules.conf to decide which voicemail
implementation to load.

The default menuselect options still build app_voicemail and not
res_mwi_external but if both ARE built, res_mwi_external will load
first and become the voicemail provider unless modules.conf rules
prevent it.  This is noted in CHANGES.

Change-Id: I7d98d4e8a3b87b8df9e51c2608f0da6ddfb89247

CHANGES
apps/app_voicemail.c
include/asterisk/app.h
include/asterisk/module.h
main/app.c
res/res_mwi_external.c

diff --git a/CHANGES b/CHANGES
index e07f0e5..8d5f5b3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -226,6 +226,14 @@ res_pjsip_history
         information on filtering, view the current CLI help for the
         'pjsip show history' command.
 
+Voicemail
+------------------
+ * app_voicemail and res_mwi_external can now be built together.  The default
+   remains to build app_voicemail and not res_mwi_external but if they are
+   both built, the load order will cause res_mwi_external to load first and
+   app_voicemail will be skipped.  Use 'preload=app_voicemail.so' in
+   modules.conf to force app_voicemail to be the voicemail provider.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.6.0 to Asterisk 13.7.0 ------------
 ------------------------------------------------------------------------------
index f2f7bad..cd55254 100644 (file)
@@ -48,7 +48,6 @@
 
 /*** MODULEINFO
        <defaultenabled>yes</defaultenabled>
-       <conflict>res_mwi_external</conflict>
        <use type="module">res_adsi</use>
        <use type="module">res_smdi</use>
        <support_level>core</support_level>
@@ -14702,10 +14701,14 @@ static int unload_module(void)
  *
  * Module loading including tests for configuration or dependencies.
  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
- * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
- * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
- * configuration file or other non-critical problem return 
- * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
+ * or AST_MODULE_LOAD_SUCCESS.
+ *
+ * If a dependency, allocation or environment variable fails tests, return AST_MODULE_LOAD_FAILURE.
+ *
+ * If the module can't load the configuration file, can't register as a provider or
+ * has another issue not fatal to Asterisk itself, return AST_MODULE_LOAD_DECLINE.
+ *
+ * On success return AST_MODULE_LOAD_SUCCESS.
  */
 static int load_module(void)
 {
@@ -14714,7 +14717,7 @@ static int load_module(void)
        umask(my_umask);
 
        if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) {
-               return AST_MODULE_LOAD_DECLINE;
+               return AST_MODULE_LOAD_FAILURE;
        }
 
        /* compute the location of the voicemail spool directory */
@@ -14724,8 +14727,10 @@ static int load_module(void)
                ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor.  MWI will not work\n");
        }
 
-       if ((res = load_config(0)))
-               return res;
+       if ((res = load_config(0))) {
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
+       }
 
        res = ast_register_application_xml(app, vm_exec);
        res |= ast_register_application_xml(app2, vm_execmain);
@@ -14746,10 +14751,26 @@ static int load_module(void)
        res |= AST_TEST_REGISTER(test_voicemail_vm_info);
 #endif
 
-       res |= ast_vm_register(&vm_table);
-       res |= ast_vm_greeter_register(&vm_greeter_table);
        if (res) {
-               return res;
+               ast_log(LOG_ERROR, "Failure registering applications, functions or tests\n");
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
+       }
+
+       /* ast_vm_register may return DECLINE if another module registered for vm */
+       res = ast_vm_register(&vm_table);
+       if (res) {
+               ast_log(LOG_ERROR, "Failure registering as a voicemail provider\n");
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
+       }
+
+       /* ast_vm_greeter_register may return DECLINE if another module registered as a greeter */
+       res = ast_vm_greeter_register(&vm_greeter_table);
+       if (res) {
+               ast_log(LOG_ERROR, "Failure registering as a greeter provider\n");
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
        }
 
        ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
@@ -14762,7 +14783,7 @@ static int load_module(void)
        ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL);
        ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL);
 
-       return res;
+       return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) 
index 3975fda..d86b633 100644 (file)
@@ -580,6 +580,7 @@ int ast_vm_is_registered(void);
  *
  * \retval 0 on success.
  * \retval -1 on error.
+ * \retval AST_MODULE_LOAD_DECLINE if there's already another provider registered.
  */
 int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module *module);
 
@@ -648,6 +649,7 @@ int ast_vm_greeter_is_registered(void);
  *
  * \retval 0 on success.
  * \retval -1 on error.
+ * \retval AST_MODULE_LOAD_DECLINE if there's already another greeter registered.
  */
 int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, struct ast_module *module);
 
index 9fbeb5e..d5616e9 100644 (file)
@@ -68,7 +68,7 @@ enum ast_module_unload_mode {
 enum ast_module_load_result {
        AST_MODULE_LOAD_SUCCESS = 0,    /*!< Module loaded and configured */
        AST_MODULE_LOAD_DECLINE = 1,    /*!< Module is not configured */
-       AST_MODULE_LOAD_SKIP = 2,       /*!< Module was skipped for some reason */
+       AST_MODULE_LOAD_SKIP = 2,       /*!< Module was skipped for some reason (For loader.c use only. Should never be returned by modules)*/
        AST_MODULE_LOAD_PRIORITY = 3,   /*!< Module is not loaded yet, but is added to prioity heap */
        AST_MODULE_LOAD_FAILURE = -1,   /*!< Module could not be loaded properly */
 };
index dabf15d..36330ac 100644 (file)
@@ -494,7 +494,7 @@ int __ast_vm_register(const struct ast_vm_functions *vm_table, struct ast_module
        if (table) {
                ast_log(LOG_WARNING, "Voicemail provider already registered by %s.\n",
                        table->module_name);
-               return -1;
+               return AST_MODULE_LOAD_DECLINE;
        }
 
        table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
@@ -605,7 +605,7 @@ int __ast_vm_greeter_register(const struct ast_vm_greeter_functions *vm_table, s
        if (table) {
                ast_log(LOG_WARNING, "Voicemail greeter provider already registered by %s.\n",
                        table->module_name);
-               return -1;
+               return AST_MODULE_LOAD_DECLINE;
        }
 
        table = ao2_alloc_options(sizeof(*table), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
index 9722822..3499885 100644 (file)
@@ -33,7 +33,6 @@
 
 /*** MODULEINFO
        <defaultenabled>no</defaultenabled>
-       <conflict>app_voicemail</conflict>
        <support_level>core</support_level>
  ***/
 
@@ -935,12 +934,22 @@ static int unload_module(void)
 
 static int load_module(void)
 {
+       int res;
+
        if (mwi_sorcery_init()
                || ast_sorcery_observer_add(mwi_sorcery, MWI_MAILBOX_TYPE, &mwi_observers)
 #if defined(MWI_DEBUG_CLI)
                || ast_cli_register_multiple(mwi_cli, ARRAY_LEN(mwi_cli))
 #endif /* defined(MWI_DEBUG_CLI) */
-               || ast_vm_register(&vm_table)) {
+               ) {
+               unload_module();
+               return AST_MODULE_LOAD_DECLINE;
+       }
+
+       /* ast_vm_register may return DECLINE if another module registered for vm */
+       res = ast_vm_register(&vm_table);
+       if (res) {
+               ast_log(LOG_ERROR, "Failure registering as a voicemail provider\n");
                unload_module();
                return AST_MODULE_LOAD_DECLINE;
        }