Removing registrar_expire from basic-pbx config
[asterisk/asterisk.git] / res / res_pjsip_phoneprov_provider.c
index 6c2c777..acb1e68 100644 (file)
@@ -135,6 +135,11 @@ struct phoneprov {
 static void phoneprov_destroy(void *obj)
 {
        struct phoneprov *pp = obj;
+       char *mac = ast_var_find(pp->vars, "MAC");
+
+       if (mac) {
+               ast_phoneprov_delete_extension(AST_MODULE, mac);
+       }
 
        ast_var_list_destroy(pp->vars);
 }
@@ -196,7 +201,7 @@ static int fields_handler(const void *obj, struct ast_variable **fields)
        struct ast_variable *var;
 
        AST_VAR_LIST_TRAVERSE(pp->vars, pvar) {
-               var = ast_variable_new(pvar->name, pvar->value, NULL);
+               var = ast_variable_new(pvar->name, pvar->value, "");
                if (!var) {
                        ast_variables_destroy(head);
                        return -1;
@@ -228,7 +233,7 @@ static int load_endpoint(const char *id, const char *endpoint_name, struct varsh
        /* We need to use res_pjsip's sorcery instance instead of our own to
         * get endpoint and auth.
         */
-       endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
+       endpoint = ast_sorcery_retrieve_by_id(sorcery, "endpoint",
                endpoint_name);
        if (!endpoint) {
                ast_log(LOG_ERROR, "phoneprov %s contained invalid endpoint %s.\n", id,
@@ -250,7 +255,7 @@ static int load_endpoint(const char *id, const char *endpoint_name, struct varsh
                        endpoint->id.self.name.str, vars);
        }
 
-       transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
+       transport = ast_sorcery_retrieve_by_id(sorcery, "transport",
                endpoint->transport);
        if (!transport) {
                ast_log(LOG_ERROR, "Endpoint %s contained invalid transport %s.\n", endpoint_name,
@@ -264,7 +269,7 @@ static int load_endpoint(const char *id, const char *endpoint_name, struct varsh
        }
        auth_name = AST_VECTOR_GET(&endpoint->inbound_auths, 0);
 
-       auth = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "auth", auth_name);
+       auth = ast_sorcery_retrieve_by_id(sorcery, "auth", auth_name);
        if (!auth) {
                ast_log(LOG_ERROR, "phoneprov %s contained invalid auth %s.\n", id, auth_name);
                return -1;
@@ -280,118 +285,106 @@ static int load_endpoint(const char *id, const char *endpoint_name, struct varsh
        return 0;
 }
 
-/*! \brief Callback that loads the users from phoneprov sections */
-static int load_users(void)
+/*! \brief Callback that validates the phoneprov object */
+static void users_apply_handler(struct phoneprov *pp)
 {
-       struct phoneprov *pp;
-       struct ao2_container *c;
-       struct ao2_iterator i;
-       int user_count = 0;
+       const char *id = ast_sorcery_object_get_id(pp);
+       const char *endpoint_name;
        char port_string[6];
 
-       c = ast_sorcery_retrieve_by_regex(sorcery, "phoneprov", "");
-       if (!c) {
-               ast_log(LOG_ERROR, "Retrieve by regex failed to allocate a container.\n");
-               return -1;
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_MAC))) {
+               ast_log(LOG_ERROR, "phoneprov %s must contain a MAC entry.\n", id);
+               return;
        }
-       if (ao2_container_count(c) == 0) {
-               ast_log(LOG_ERROR, "Unable to find any phoneprov users.\n");
-               ao2_cleanup(c);
-               return -1;
+
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_PROFILE))) {
+               ast_log(LOG_ERROR, "phoneprov %s must contain a PROFILE entry.\n", id);
+               return;
        }
 
-       i = ao2_iterator_init(c, 0);
-       while ((pp = ao2_iterator_next(&i))) {
-               const char *endpoint_name;
-               const char *id = ast_sorcery_object_get_id(pp);
-
-               endpoint_name = ast_var_find(pp->vars, "endpoint");
-               if (endpoint_name) {
-                       if (load_endpoint(id, endpoint_name, pp->vars, port_string)) {
-                               goto cleanup;
-                       }
+       endpoint_name = ast_var_find(pp->vars, "endpoint");
+       if (endpoint_name) {
+               if (load_endpoint(id, endpoint_name, pp->vars, port_string)) {
+                       return;
                }
+       }
 
-               if (!ast_var_find(pp->vars,
-                       ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_USERNAME))) {
-                       assign_and_insert(
-                               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_USERNAME), id,
-                               pp->vars);
-               }
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_USERNAME))) {
+               assign_and_insert(
+                       ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_USERNAME), id,
+                       pp->vars);
+       }
 
-               if (!ast_var_find(pp->vars,
-                       ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_LABEL))) {
-                       assign_and_insert(ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_LABEL),
-                               id, pp->vars);
-               }
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_LABEL))) {
+               assign_and_insert(ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_LABEL),
+                       id, pp->vars);
+       }
 
-               if (!ast_var_find(pp->vars,
-                       ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_SERVER_PORT))) {
-                       assign_and_insert("SERVER_PORT", S_OR(port_string, "5060"), pp->vars);
-               }
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_SERVER_PORT))) {
+               assign_and_insert("SERVER_PORT", S_OR(port_string, "5060"), pp->vars);
+       }
 
-               if (!ast_var_find(pp->vars,
-                       ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_PROFILE))) {
-                       ast_log(LOG_ERROR, "phoneprov %s didn't contain a PROFILE entry.\n", id);
-               } else if (!ast_phoneprov_add_extension(AST_MODULE, pp->vars)) {
-                       user_count++;
-               }
-               ao2_ref(pp, -1);
+       if (!ast_var_find(pp->vars,
+               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_PROFILE))) {
+               ast_log(LOG_ERROR, "phoneprov %s didn't contain a PROFILE entry.\n", id);
        }
 
-cleanup:
-       ao2_iterator_destroy(&i);
-       ao2_cleanup(pp);
-       ao2_cleanup(c);
+       ast_phoneprov_add_extension(AST_MODULE, pp->vars);
 
-       return user_count > 0 ? 0 : -1;
+       return;
 }
 
-/*! \brief Callback that validates the phoneprov object */
-static int users_apply_handler(const struct ast_sorcery *sorcery, void *obj)
+/*! \brief Callback that loads the users from phoneprov sections */
+static int load_users(void)
 {
-       struct phoneprov *pp = obj;
-       const char *id = ast_sorcery_object_get_id(pp);
+       struct ao2_container *users;
+       struct ao2_iterator i;
+       struct phoneprov *pp;
 
-       if (!ast_var_find(pp->vars,
-               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_MAC))) {
-               ast_log(LOG_ERROR, "phoneprov %s must contain a MAC entry.\n", id);
-               return -1;
+       ast_sorcery_reload_object(sorcery, "phoneprov");
+
+       users = ast_sorcery_retrieve_by_fields(sorcery, "phoneprov",
+               AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+       if (!users) {
+               return 0;
        }
 
-       if (!ast_var_find(pp->vars,
-               ast_phoneprov_std_variable_lookup(AST_PHONEPROV_STD_PROFILE))) {
-               ast_log(LOG_ERROR, "phoneprov %s must contain a PROFILE entry.\n", id);
-               return -1;
+       i = ao2_iterator_init(users, 0);
+       while ((pp = ao2_iterator_next(&i))) {
+               users_apply_handler(pp);
+               ao2_ref(pp, -1);
        }
+       ao2_iterator_destroy(&i);
+       ao2_ref(users, -1);
 
        return 0;
 }
 
 static int load_module(void)
 {
-       if (!(sorcery = ast_sorcery_open())) {
-               ast_log(LOG_ERROR, "Unable to open a sorcery instance.\n");
-               return AST_MODULE_LOAD_DECLINE;
-       }
+       sorcery = ast_sip_get_sorcery();
 
-       if (ast_sorcery_apply_default(sorcery, "phoneprov", "config",
-               "pjsip.conf,criteria=type=phoneprov")) {
-               ast_log(LOG_ERROR, "Unable to register object phoneprov.\n");
-               ast_sorcery_unref(sorcery);
-               return AST_MODULE_LOAD_DECLINE;
-       }
+       ast_sorcery_apply_config(sorcery, "res_pjsip_phoneprov_provider");
+       ast_sorcery_apply_default(sorcery, "phoneprov", "config",
+               "pjsip.conf,criteria=type=phoneprov");
 
        ast_sorcery_object_register(sorcery, "phoneprov", phoneprov_alloc, NULL,
-               users_apply_handler);
-       ast_sorcery_object_field_register(sorcery, "phoneprov", "type", "", OPT_NOOP_T, 0, 0);
+               NULL);
+
+       ast_sorcery_object_field_register(sorcery, "phoneprov", "type", "", OPT_NOOP_T, 0,
+               0);
        ast_sorcery_object_fields_register(sorcery, "phoneprov", "^", aco_handler,
                fields_handler);
-       ast_sorcery_reload_object(sorcery, "phoneprov");
+
+       ast_sorcery_load_object(sorcery, "phoneprov");
 
        if (ast_phoneprov_provider_register(AST_MODULE, load_users)) {
                ast_log(LOG_ERROR, "Unable to register pjsip phoneprov provider.\n");
-               ast_sorcery_unref(sorcery);
                return AST_MODULE_LOAD_DECLINE;
        }
 
@@ -401,22 +394,27 @@ static int load_module(void)
 static int unload_module(void)
 {
        ast_phoneprov_provider_unregister(AST_MODULE);
-       ast_sorcery_unref(sorcery);
 
        return 0;
 }
 
 static int reload_module(void)
 {
-       unload_module();
-       load_module();
+       ast_phoneprov_provider_unregister(AST_MODULE);
+
+       if (ast_phoneprov_provider_register(AST_MODULE, load_users)) {
+               ast_log(LOG_ERROR, "Unable to register pjsip phoneprov provider.\n");
+               return AST_MODULE_LOAD_DECLINE;
+       }
 
        return 0;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Phoneprov Provider",
-               .load = load_module,
-               .reload = reload_module,
-               .unload = unload_module,
-               .load_pri = AST_MODPRI_APP_DEPEND,
-               );
+       .support_level = AST_MODULE_SUPPORT_EXTENDED,
+       .load = load_module,
+       .reload = reload_module,
+       .unload = unload_module,
+       .load_pri = AST_MODPRI_APP_DEPEND,
+       .requires = "res_pjsip,res_phoneprov",
+);