summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/sorcery.h11
-rw-r--r--main/sorcery.c19
-rw-r--r--res/res_pjsip_outbound_registration.c71
3 files changed, 74 insertions, 27 deletions
diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h
index 92d6f6cb7..30fb0dd02 100644
--- a/include/asterisk/sorcery.h
+++ b/include/asterisk/sorcery.h
@@ -617,6 +617,17 @@ int ast_sorcery_get_wizard_mapping(struct ast_sorcery *sorcery,
const char *type, int index, struct ast_sorcery_wizard **wizard, void **data);
/*!
+ * \brief Unregister an object type
+ *
+ * \param sorcery Pointer to a sorcery structure
+ * \param type Type of object
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type);
+
+/*!
* \brief Register an object type
*
* \param sorcery Pointer to a sorcery structure
diff --git a/main/sorcery.c b/main/sorcery.c
index 8101af055..063e8c4b0 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -1106,6 +1106,25 @@ static int sorcery_extended_fields_handler(const void *obj, struct ast_variable
return 0;
}
+int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
+{
+ struct ast_sorcery_object_type *object_type;
+ int res = -1;
+
+ ao2_wrlock(sorcery->types);
+ object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY | OBJ_NOLOCK);
+ if (object_type && object_type->type.type == ACO_ITEM) {
+ ao2_unlink_flags(sorcery->types, object_type, OBJ_NOLOCK);
+ res = 0;
+ }
+ ao2_unlock(sorcery->types);
+
+ /* XXX may need to add an instance unregister observer callback on success. */
+
+ ao2_cleanup(object_type);
+ return res;
+}
+
int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
{
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 391f1e185..78b863f49 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1762,15 +1762,19 @@ static const struct ast_sorcery_instance_observer observer_callbacks_registratio
static int unload_module(void)
{
- ast_sip_unregister_endpoint_identifier(&line_identifier);
- ast_sorcery_observer_remove(ast_sip_get_sorcery(), "auth", &observer_callbacks_auth);
- ast_sorcery_instance_observer_remove(ast_sip_get_sorcery(), &observer_callbacks_registrations);
- ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
- ast_sip_unregister_cli_formatter(cli_formatter);
ast_manager_unregister("PJSIPShowRegistrationsOutbound");
ast_manager_unregister("PJSIPUnregister");
ast_manager_unregister("PJSIPRegister");
+ ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
+ ast_sip_unregister_cli_formatter(cli_formatter);
+ cli_formatter = NULL;
+
+ ast_sip_unregister_endpoint_identifier(&line_identifier);
+
+ ast_sorcery_observer_remove(ast_sip_get_sorcery(), "auth", &observer_callbacks_auth);
+ ast_sorcery_instance_observer_remove(ast_sip_get_sorcery(), &observer_callbacks_registrations);
+
ao2_global_obj_release(current_states);
return 0;
@@ -1782,10 +1786,25 @@ static int load_module(void)
CHECK_PJSIP_MODULE_LOADED();
+ /* Create outbound registration states container. */
+ new_states = ao2_container_alloc(DEFAULT_STATE_BUCKETS,
+ registration_state_hash, registration_state_cmp);
+ if (!new_states) {
+ ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
+ unload_module();
+ return AST_MODULE_LOAD_FAILURE;
+ }
+ ao2_global_obj_replace_unref(current_states, new_states);
+ ao2_ref(new_states, -1);
+
+ /*
+ * Register sorcery object descriptions.
+ */
ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_outbound_registration");
ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "pjsip.conf,criteria=type=registration");
if (ast_sorcery_object_register(ast_sip_get_sorcery(), "registration", sip_outbound_registration_alloc, NULL, sip_outbound_registration_apply)) {
+ unload_module();
return AST_MODULE_LOAD_DECLINE;
}
@@ -1804,12 +1823,23 @@ static int load_module(void)
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, support_path));
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "line", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, line));
ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, endpoint));
- ast_sip_register_endpoint_identifier(&line_identifier);
- ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
- ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
- ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
+ /*
+ * Register sorcery observers.
+ */
+ if (ast_sorcery_instance_observer_add(ast_sip_get_sorcery(),
+ &observer_callbacks_registrations)
+ || ast_sorcery_observer_add(ast_sip_get_sorcery(), "auth",
+ &observer_callbacks_auth)) {
+ ast_log(LOG_ERROR, "Unable to register observers.\n");
+ unload_module();
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
+ /* Register how this module identifies endpoints. */
+ ast_sip_register_endpoint_identifier(&line_identifier);
+ /* Register CLI commands. */
cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
if (!cli_formatter) {
ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
@@ -1823,30 +1853,17 @@ static int load_module(void)
cli_formatter->iterate = cli_iterator;
cli_formatter->get_id = ast_sorcery_object_get_id;
cli_formatter->retrieve_by_id = cli_retrieve_by_id;
-
ast_sip_register_cli_formatter(cli_formatter);
ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
- new_states = ao2_container_alloc(DEFAULT_STATE_BUCKETS,
- registration_state_hash, registration_state_cmp);
- if (!new_states) {
- ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
- unload_module();
- return AST_MODULE_LOAD_FAILURE;
- }
- ao2_global_obj_replace_unref(current_states, new_states);
- ao2_ref(new_states, -1);
-
- if (ast_sorcery_instance_observer_add(ast_sip_get_sorcery(),
- &observer_callbacks_registrations)) {
- unload_module();
- return AST_MODULE_LOAD_FAILURE;
- }
+ /* Register AMI actions. */
+ ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
+ ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
+ ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
+ /* Load configuration objects */
ast_sorcery_load_object(ast_sip_get_sorcery(), "registration");
- ast_sorcery_observer_add(ast_sip_get_sorcery(), "auth", &observer_callbacks_auth);
-
return AST_MODULE_LOAD_SUCCESS;
}