Commit ff34444a4b for asterisk.org
commit ff34444a4b04b85077fba66f30d4a2b782b30baa
Author: Joshua C. Colp <jcolp@sangoma.com>
Date: Tue Feb 10 10:33:53 2026 -0400
endpoints: Allow access to latest snapshot directly.
This change adds an API call to allow direct access to the latest
snapshot of an ast_endpoint. This is then used by chan_pjsip when
calculating device state, eliminating the need to access the cache
which would incur a container find and access.
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index f44c51edae..4fc39d1acc 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -1188,9 +1188,7 @@ static int chan_pjsip_devicestate(const char *data)
return AST_DEVICE_INVALID;
}
- endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
- ast_endpoint_get_resource(endpoint->persistent));
-
+ endpoint_snapshot = ast_endpoint_get_snapshot(endpoint->persistent);
if (!endpoint_snapshot) {
return AST_DEVICE_INVALID;
}
diff --git a/include/asterisk/endpoints.h b/include/asterisk/endpoints.h
index 0be9d352ba..1835cbc37f 100644
--- a/include/asterisk/endpoints.h
+++ b/include/asterisk/endpoints.h
@@ -169,6 +169,18 @@ const char *ast_endpoint_get_id(const struct ast_endpoint *endpoint);
*/
enum ast_endpoint_state ast_endpoint_get_state(const struct ast_endpoint *endpoint);
+/*!
+ * \brief Gets the latest snapshot of the given endpoint.
+ *
+ * \param endpoint The endpoint.
+ * \return Latest snapshot of the endpoint.
+ * \retval NULL if endpoint is \c NULL.
+ * \since 20.19.0
+ * \since 22.9.0
+ * \since 23.3.0
+ */
+struct ast_endpoint_snapshot *ast_endpoint_get_snapshot(struct ast_endpoint *endpoint);
+
/*!
* \brief Updates the state of the given endpoint.
*
diff --git a/main/endpoints.c b/main/endpoints.c
index 15691b239d..5300b52f4f 100644
--- a/main/endpoints.c
+++ b/main/endpoints.c
@@ -71,6 +71,8 @@ struct ast_endpoint {
struct ao2_container *channel_ids;
/*! Forwarding subscription from an endpoint to its tech endpoint */
struct stasis_forward *tech_forward;
+ /*! The latest snapshot of the endpoint */
+ struct ast_endpoint_snapshot *snapshot;
};
AO2_STRING_FIELD_HASH_FN(ast_endpoint, id)
@@ -137,6 +139,10 @@ static void endpoint_publish_snapshot(struct ast_endpoint *endpoint)
return;
}
stasis_publish(ast_endpoint_topic(endpoint), message);
+
+ ao2_lock(endpoint);
+ ao2_replace(endpoint->snapshot, snapshot);
+ ao2_unlock(endpoint);
}
static void endpoint_dtor(void *obj)
@@ -149,6 +155,9 @@ static void endpoint_dtor(void *obj)
ao2_cleanup(endpoint->channel_ids);
endpoint->channel_ids = NULL;
+ ao2_cleanup(endpoint->snapshot);
+ endpoint->snapshot = NULL;
+
ast_string_field_free_memory(endpoint);
}
@@ -362,6 +371,21 @@ enum ast_endpoint_state ast_endpoint_get_state(const struct ast_endpoint *endpoi
return endpoint->state;
}
+struct ast_endpoint_snapshot *ast_endpoint_get_snapshot(struct ast_endpoint *endpoint)
+{
+ struct ast_endpoint_snapshot *snapshot;
+
+ if (!endpoint) {
+ return NULL;
+ }
+
+ ao2_lock(endpoint);
+ snapshot = ao2_bump(endpoint->snapshot);
+ ao2_unlock(endpoint);
+
+ return snapshot;
+}
+
void ast_endpoint_set_state(struct ast_endpoint *endpoint,
enum ast_endpoint_state state)
{