]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_config_wizard.c: Refactor load process
authorGeorge Joseph <gjoseph@sangoma.com>
Tue, 23 Jul 2024 16:04:26 +0000 (10:04 -0600)
committerGeorge Joseph <gjoseph@sangoma.com>
Wed, 24 Jul 2024 19:21:06 +0000 (19:21 +0000)
The way we have been initializing the config wizard prevented it
from registering its objects if res_pjsip happened to load
before it.

* We now use the object_type_registered sorcery observer to kick
things off instead of the wizard_mapped observer.

* The load_module function now checks if res_pjsip has been loaded
already and if it was it fires the proper observers so the objects
load correctly.

Resolves: #816

UserNote: The res_pjsip_config_wizard.so module can now be reloaded.

res/res_pjsip_config_wizard.c

index 91228da05c758993f4b31124f8e99b97420db27d..640e8f871404a6a6ce93d04b90e3230c67b03ba4 100644 (file)
@@ -1030,9 +1030,6 @@ static void instance_created_observer(const char *name, struct ast_sorcery *sorc
 static void instance_destroying_observer(const char *name, struct ast_sorcery *sorcery);
 static void object_type_loaded_observer(const char *name,
        const struct ast_sorcery *sorcery, const char *object_type, int reloaded);
-static void wizard_mapped_observer(const char *name, struct ast_sorcery *sorcery,
-       const char *object_type, struct ast_sorcery_wizard *wizard,
-       const char *wizard_args, void *wizard_data);
 static void object_type_registered_observer(const char *name,
        struct ast_sorcery *sorcery, const char *object_type);
 
@@ -1042,7 +1039,6 @@ const static struct ast_sorcery_global_observer global_observer = {
 };
 
 struct ast_sorcery_instance_observer observer = {
-       .wizard_mapped = wizard_mapped_observer,
        .object_type_registered = object_type_registered_observer,
        .object_type_loaded = object_type_loaded_observer,
 };
@@ -1146,20 +1142,22 @@ static void object_type_loaded_observer(const char *name,
        otw->last_config = cfg;
 }
 
-/*! \brief When each wizard is mapped, save it off to the vector. */
-static void wizard_mapped_observer(const char *name, struct ast_sorcery *sorcery,
-       const char *object_type, struct ast_sorcery_wizard *wizard,
-       const char *wizard_args, void *wizard_data)
+/*! \brief When each object type is registered, map a memory wizard to it. */
+static void object_type_registered_observer(const char *name,
+       struct ast_sorcery *sorcery, const char *object_type)
 {
+       struct ast_sorcery_wizard *wizard;
+       void *wizard_data;
        struct object_type_wizard *otw;
 
-       if (!is_one_of(object_type, object_types)) {
-               /* Not interested. */
-               return;
-       }
+       if (is_one_of(object_type, object_types)) {
+               if (ast_sorcery_object_type_apply_wizard(sorcery, object_type,
+                       "memory", "pjsip_wizard", AST_SORCERY_WIZARD_APPLY_READONLY | AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE,
+                       &wizard, &wizard_data) != AST_SORCERY_APPLY_SUCCESS) {
+                       ast_log(LOG_ERROR, "Unable to apply sangoma wizard to object type '%s'\n", object_type);
+                       return;
+               }
 
-       /* We're only interested in memory wizards with the pjsip_wizard tag. */
-       if (wizard_args && !strcmp(wizard_args, "pjsip_wizard")) {
                otw = ast_malloc(sizeof(*otw) + strlen(object_type) + 1);
                if (!otw) {
                        return;
@@ -1177,15 +1175,7 @@ static void wizard_mapped_observer(const char *name, struct ast_sorcery *sorcery
                        ast_debug(1, "Wizard mapped for object_type '%s'\n", object_type);
                }
                AST_VECTOR_RW_UNLOCK(&object_type_wizards);
-       }
-}
 
-/*! \brief When each object type is registered, map a memory wizard to it. */
-static void object_type_registered_observer(const char *name,
-       struct ast_sorcery *sorcery, const char *object_type)
-{
-       if (is_one_of(object_type, object_types)) {
-               ast_sorcery_apply_wizard_mapping(sorcery, object_type, "memory", "pjsip_wizard", 0);
        }
 }
 
@@ -1312,12 +1302,46 @@ static struct ast_cli_entry config_wizard_cli[] = {
        AST_CLI_DEFINE(handle_export_primitives, "Export config wizard primitives"),
 };
 
+static int reload_module(void)
+{
+       ast_sorcery_reload(ast_sip_get_sorcery());
+       return 0;
+}
+
 static int load_module(void)
 {
        AST_VECTOR_RW_INIT(&object_type_wizards, 12);
        ast_sorcery_global_observer_add(&global_observer);
        ast_cli_register_multiple(config_wizard_cli, ARRAY_LEN(config_wizard_cli));
 
+       /* If the PJSIP sorcery instance exists it means that we have been explicitly
+        * loaded and things are potentially already set up. Since we won't receive any
+        * observer callbacks informing us of this we add ourselves to the instance
+        * as an observer in case it goes away, and determine which object types have
+        * been registered and synthesize the observer callbacks for them. Once done
+        * we force a reload so we are aware of the state of things.
+        */
+       if (ast_sip_get_sorcery()) {
+               int i;
+
+               ast_module_ref(ast_module_info->self);
+               ast_sorcery_instance_observer_add(ast_sip_get_sorcery(), &observer);
+
+               /* See which object types already exist */
+               for (i = 0; i < ARRAY_LEN(object_types); ++i) {
+                       if (!object_types[i]) {
+                               break;
+                       } else if (!ast_sorcery_get_object_type(ast_sip_get_sorcery(), object_types[i])) {
+                               continue;
+                       }
+
+                       object_type_registered_observer("res_pjsip", ast_sip_get_sorcery(),
+                               object_types[i]);
+               }
+
+               ast_sorcery_reload(ast_sip_get_sorcery());
+       }
+
        return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -1334,6 +1358,7 @@ static int unload_module(void)
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJSIP Config Wizard",
        .support_level = AST_MODULE_SUPPORT_CORE,
        .load = load_module,
+       .reload = reload_module,
        .unload = unload_module,
        .load_pri = AST_MODPRI_REALTIME_DRIVER,
 );