From b7ba23e0421ef3742247e30432e90764c47599f7 Mon Sep 17 00:00:00 2001 From: Matt Jordan Date: Thu, 3 Nov 2016 10:28:10 -0500 Subject: [PATCH] res_respoke: Support dynamic endpoint creation Using ARI, endpoints managed by Asterisk's sorcery "ORM" can be dynamically created/destroyed. Unfortunately, a bug in res_respoke kept this functionality from working; in fact, attempting to create an endpoint backed by a realtime or AstDB wizard would crash. This crash occurred due to an infinite recursive call in respoke_endpoint_alloc. Objects in Sorcery that are managed by certain wizards are explicitly immutable, which necessitates that all Sorcery objects be treated as immutable. res_respoke was storing a pointer to the endpoint registration state on the endpoint Sorcery object. In order to determine if the state already existed, a call to Sorcery's 'retrieve_by_id' function was made; in the AstDB and other wizards, this creates a new instance of the endpoint object, which would attempt to retrieve the endpoint object, etc. The solution is to not store mutable state on the immutable object. A global ao2 container now holds the endpoint states. This allows endpoints created via Sorcery to query that container to see if they have any state on object creation/deletion. In order to manage this process, Sorcery observers have been added for object type registration and for object deletion. The result of this patch is that ARI PUT/DELETE commands now work with res_respoke, and endpoints can be created on the fly dynamically. --- res/res_respoke/respoke_endpoint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/res/res_respoke/respoke_endpoint.c b/res/res_respoke/respoke_endpoint.c index 243b9cc..ba9941c 100644 --- a/res/res_respoke/respoke_endpoint.c +++ b/res/res_respoke/respoke_endpoint.c @@ -786,6 +786,7 @@ static const struct ast_sorcery_instance_observer observer_callbacks = { static void endpoint_deleted_observer(const void *obj) { const struct respoke_endpoint *endpoint = obj; + struct respoke_endpoint_state *state; struct ao2_container *states; states = ao2_global_obj_ref(endpoint_states);