diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h index e521e05eb805ec5ce6f847f002c1b3e4857410a0..64224c04f04acaa98bf03ef6fb707f3e9f1a13d9 100644 --- a/include/asterisk/stasis_channels.h +++ b/include/asterisk/stasis_channels.h @@ -102,6 +102,15 @@ struct stasis_topic *ast_channel_topic_all(void); */ struct stasis_caching_topic *ast_channel_topic_all_cached(void); +/*! + * \since 12 + * \brief A caching topic which caches \ref ast_channel_snapshot messages from + * ast_channel_events_all(void) and indexes them by name. + * + * \retval Topic for all channel events. + */ +struct stasis_caching_topic *ast_channel_topic_all_cached_by_name(void); + /*! * \since 12 * \brief Message type for \ref ast_channel_snapshot. @@ -135,6 +144,18 @@ struct ast_channel_snapshot *ast_channel_snapshot_create( */ struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid); +/*! + * \since 12 + * \brief Obtain the latest \ref ast_channel_snapshot from the \ref stasis cache. This is + * an ao2 object, so use \ref ao2_cleanup() to deallocate. + * + * \param name The channel's name + * + * \retval A \ref ast_channel_snapshot on success + * \retval NULL on error + */ +struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name); + /*! * \since 12 * \brief Creates a \ref ast_channel_blob message. diff --git a/main/stasis_channels.c b/main/stasis_channels.c index c08bbd99fdca746c74f17f5ede4d4b3207601083..ae253ddca830ff49572f4a15e9db57e301fb6ecb 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -66,6 +66,9 @@ struct stasis_topic *channel_topic_all; /*! \brief Caching topic for all channels */ struct stasis_caching_topic *channel_topic_all_cached; +/*! \brief Caching topic for all channels indexed by name */ +struct stasis_caching_topic *channel_topic_all_cached_by_name; + struct stasis_topic *ast_channel_topic_all(void) { return channel_topic_all; @@ -86,6 +89,21 @@ static const char *channel_snapshot_get_id(struct stasis_message *message) return snapshot->uniqueid; } +struct stasis_caching_topic *ast_channel_topic_all_cached_by_name(void) +{ + return channel_topic_all_cached_by_name; +} + +static const char *channel_snapshot_get_name(struct stasis_message *message) +{ + struct ast_channel_snapshot *snapshot; + if (ast_channel_snapshot_type() != stasis_message_type(message)) { + return NULL; + } + snapshot = stasis_message_data(message); + return snapshot->name; +} + /*! \internal \brief Hash function for \ref ast_channel_snapshot objects */ static int channel_snapshot_hash_cb(const void *obj, const int flags) { @@ -366,6 +384,28 @@ struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniquei return snapshot; } +struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name) +{ + RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct ast_channel_snapshot *snapshot; + + ast_assert(!ast_strlen_zero(name)); + + message = stasis_cache_get(ast_channel_topic_all_cached_by_name(), + ast_channel_snapshot_type(), + name); + if (!message) { + return NULL; + } + + snapshot = stasis_message_data(message); + if (!snapshot) { + return NULL; + } + ao2_ref(snapshot, +1); + return snapshot; +} + static void channel_role_snapshot_dtor(void *obj) { struct channel_role_snapshot *role_snapshot = obj; @@ -578,6 +618,7 @@ int ast_channel_snapshot_caller_id_equal( static void stasis_channels_cleanup(void) { channel_topic_all_cached = stasis_caching_unsubscribe_and_join(channel_topic_all_cached); + channel_topic_all_cached_by_name = stasis_caching_unsubscribe_and_join(channel_topic_all_cached_by_name); ao2_cleanup(channel_topic_all); channel_topic_all = NULL; STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_snapshot_type); @@ -623,4 +664,5 @@ void ast_stasis_channels_init(void) channel_topic_all = stasis_topic_create("ast_channel_topic_all"); channel_topic_all_cached = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_id); + channel_topic_all_cached_by_name = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_name); }