mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
Fix ExtenSpy and simplify the channel search functions.
When ast_channel name was opaquified, the channel search functions did not get converted correctly. As a result ExtenSpy which uses a channel iterator search by exten@context could never find anything. * Updated the doxygen documentation for the search functions in channel.h. Review: https://reviewboard.asterisk.org/r/1702/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@353647 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -2527,10 +2527,11 @@ struct ast_channel_iterator;
|
||||
/*!
|
||||
* \brief Destroy a channel iterator
|
||||
*
|
||||
* \arg i the itereator to destroy
|
||||
* \param i the itereator to destroy
|
||||
*
|
||||
* \details
|
||||
* This function is used to destroy a channel iterator that was retrieved by
|
||||
* using one of the channel_iterator_new() functions.
|
||||
* using one of the channel_iterator_xxx_new() functions.
|
||||
*
|
||||
* \return NULL, for convenience to clear out the pointer to the iterator that
|
||||
* was just destroyed.
|
||||
@@ -2542,13 +2543,16 @@ struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_ite
|
||||
/*!
|
||||
* \brief Create a new channel iterator based on extension
|
||||
*
|
||||
* \arg exten The extension that channels must be in
|
||||
* \arg context The context that channels must be in (optional)
|
||||
* \param exten The extension that channels must be in
|
||||
* \param context The context that channels must be in
|
||||
*
|
||||
* \details
|
||||
* After creating an iterator using this function, the ast_channel_iterator_next()
|
||||
* function can be used to iterate through all channels that are currently
|
||||
* in the specified context and extension.
|
||||
*
|
||||
* \note You must call ast_channel_iterator_destroy() when done.
|
||||
*
|
||||
* \retval NULL on failure
|
||||
* \retval a new channel iterator based on the specified parameters
|
||||
*
|
||||
@@ -2559,15 +2563,18 @@ struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten
|
||||
/*!
|
||||
* \brief Create a new channel iterator based on name
|
||||
*
|
||||
* \arg name channel name or channel uniqueid to match
|
||||
* \arg name_len number of characters in the channel name to match on. This
|
||||
* \param name channel name or channel uniqueid to match
|
||||
* \param name_len number of characters in the channel name to match on. This
|
||||
* would be used to match based on name prefix. If matching on the full
|
||||
* channel name is desired, then this parameter should be 0.
|
||||
*
|
||||
* \details
|
||||
* After creating an iterator using this function, the ast_channel_iterator_next()
|
||||
* function can be used to iterate through all channels that exist that have
|
||||
* the specified name or name prefix.
|
||||
*
|
||||
* \note You must call ast_channel_iterator_destroy() when done.
|
||||
*
|
||||
* \retval NULL on failure
|
||||
* \retval a new channel iterator based on the specified parameters
|
||||
*
|
||||
@@ -2578,9 +2585,12 @@ struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name,
|
||||
/*!
|
||||
* \brief Create a new channel iterator
|
||||
*
|
||||
* \details
|
||||
* After creating an iterator using this function, the ast_channel_iterator_next()
|
||||
* function can be used to iterate through all channels that exist.
|
||||
*
|
||||
* \note You must call ast_channel_iterator_destroy() when done.
|
||||
*
|
||||
* \retval NULL on failure
|
||||
* \retval a new channel iterator
|
||||
*
|
||||
@@ -2591,9 +2601,10 @@ struct ast_channel_iterator *ast_channel_iterator_all_new(void);
|
||||
/*!
|
||||
* \brief Get the next channel for a channel iterator
|
||||
*
|
||||
* \arg i the channel iterator that was created using one of the
|
||||
* channel_iterator_new() functions.
|
||||
* \param i the channel iterator that was created using one of the
|
||||
* channel_iterator_xxx_new() functions.
|
||||
*
|
||||
* \details
|
||||
* This function should be used to iterate through all channels that match a
|
||||
* specified set of parameters that were provided when the iterator was created.
|
||||
*
|
||||
@@ -2610,6 +2621,7 @@ struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i);
|
||||
/*!
|
||||
* \brief Call a function with every active channel
|
||||
*
|
||||
* \details
|
||||
* This function executes a callback one time for each active channel on the
|
||||
* system. The channel is provided as an argument to the function.
|
||||
*
|
||||
@@ -2624,8 +2636,9 @@ struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg,
|
||||
/*!
|
||||
* \brief Find a channel by name
|
||||
*
|
||||
* \arg name the name or uniqueid of the channel to search for
|
||||
* \param name the name or uniqueid of the channel to search for
|
||||
*
|
||||
* \details
|
||||
* Find a channel that has the same name as the provided argument.
|
||||
*
|
||||
* \retval a channel with the name specified by the argument
|
||||
@@ -2638,9 +2651,10 @@ struct ast_channel *ast_channel_get_by_name(const char *name);
|
||||
/*!
|
||||
* \brief Find a channel by a name prefix
|
||||
*
|
||||
* \arg name The channel name or uniqueid prefix to search for
|
||||
* \arg name_len Only search for up to this many characters from the name
|
||||
* \param name The channel name or uniqueid prefix to search for
|
||||
* \param name_len Only search for up to this many characters from the name
|
||||
*
|
||||
* \details
|
||||
* Find a channel that has the same name prefix as specified by the arguments.
|
||||
*
|
||||
* \retval a channel with the name prefix specified by the arguments
|
||||
@@ -2653,9 +2667,10 @@ struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name
|
||||
/*!
|
||||
* \brief Find a channel by extension and context
|
||||
*
|
||||
* \arg exten the extension to search for
|
||||
* \arg context the context to search for (optional)
|
||||
* \param exten the extension to search for
|
||||
* \param context the context to search for
|
||||
*
|
||||
* \details
|
||||
* Return a channel that is currently at the specified extension and context.
|
||||
*
|
||||
* \retval a channel that is at the specified extension and context
|
||||
|
112
main/channel.c
112
main/channel.c
@@ -1421,17 +1421,17 @@ static int ast_channel_by_name_cb(void *obj, void *arg, void *data, int flags)
|
||||
{
|
||||
struct ast_channel *chan = obj;
|
||||
const char *name = arg;
|
||||
size_t name_len = *(size_t *)data;
|
||||
size_t name_len = *(size_t *) data;
|
||||
int ret = CMP_MATCH;
|
||||
|
||||
if (ast_strlen_zero(name)) {
|
||||
ast_log(LOG_ERROR, "BUG! Must supply a name, or a channel with a name to match on!\n");
|
||||
ast_log(LOG_ERROR, "BUG! Must supply a channel name or partial name to match!\n");
|
||||
return CMP_STOP;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
|
||||
if ((!name_len && strcasecmp(ast_channel_name(chan), name)) || (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
|
||||
if ((!name_len && strcasecmp(ast_channel_name(chan), name))
|
||||
|| (name_len && strncasecmp(ast_channel_name(chan), name, name_len))) {
|
||||
ret = 0; /* name match failed, keep looking */
|
||||
}
|
||||
ast_channel_unlock(chan);
|
||||
@@ -1442,7 +1442,8 @@ static int ast_channel_by_name_cb(void *obj, void *arg, void *data, int flags)
|
||||
static int ast_channel_by_exten_cb(void *obj, void *arg, void *data, int flags)
|
||||
{
|
||||
struct ast_channel *chan = obj;
|
||||
char *context = arg, *exten = data;
|
||||
char *context = arg;
|
||||
char *exten = data;
|
||||
int ret = CMP_MATCH;
|
||||
|
||||
if (ast_strlen_zero(exten) || ast_strlen_zero(context)) {
|
||||
@@ -1465,18 +1466,18 @@ static int ast_channel_by_uniqueid_cb(void *obj, void *arg, void *data, int flag
|
||||
{
|
||||
struct ast_channel *chan = obj;
|
||||
char *uniqueid = arg;
|
||||
size_t name_len = *(size_t *) data;
|
||||
size_t id_len = *(size_t *) data;
|
||||
int ret = CMP_MATCH;
|
||||
|
||||
if (ast_strlen_zero(uniqueid)) {
|
||||
ast_log(LOG_ERROR, "BUG! Must have a uniqueid to match!\n");
|
||||
ast_log(LOG_ERROR, "BUG! Must supply a uniqueid or partial uniqueid to match!\n");
|
||||
return CMP_STOP;
|
||||
}
|
||||
|
||||
ast_channel_lock(chan);
|
||||
if ((!name_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid)) ||
|
||||
(name_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, name_len))) {
|
||||
ret = 0;
|
||||
if ((!id_len && strcasecmp(ast_channel_uniqueid(chan), uniqueid))
|
||||
|| (id_len && strncasecmp(ast_channel_uniqueid(chan), uniqueid, id_len))) {
|
||||
ret = 0; /* uniqueid match failed, keep looking */
|
||||
}
|
||||
ast_channel_unlock(chan);
|
||||
|
||||
@@ -1500,11 +1501,9 @@ struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_ite
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ast_channel_iterator *channel_iterator_search(const char *name,
|
||||
size_t name_len, const char *exten, const char *context)
|
||||
struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten, const char *context)
|
||||
{
|
||||
struct ast_channel_iterator *i;
|
||||
char *l_name = (char *) name;
|
||||
char *l_exten = (char *) exten;
|
||||
char *l_context = (char *) context;
|
||||
|
||||
@@ -1512,14 +1511,9 @@ static struct ast_channel_iterator *channel_iterator_search(const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(name)
|
||||
&& !(i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
|
||||
l_context, l_exten, OBJ_MULTIPLE))) {
|
||||
ast_free(i);
|
||||
return NULL;
|
||||
} else if (!(i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
|
||||
l_name, &name_len,
|
||||
OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0)))) {
|
||||
i->active_iterator = (void *) ast_channel_callback(ast_channel_by_exten_cb,
|
||||
l_context, l_exten, OBJ_MULTIPLE);
|
||||
if (!i->active_iterator) {
|
||||
ast_free(i);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1527,14 +1521,24 @@ static struct ast_channel_iterator *channel_iterator_search(const char *name,
|
||||
return i;
|
||||
}
|
||||
|
||||
struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten, const char *context)
|
||||
{
|
||||
return channel_iterator_search(NULL, 0, exten, context);
|
||||
}
|
||||
|
||||
struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name, size_t name_len)
|
||||
{
|
||||
return channel_iterator_search(name, name_len, NULL, NULL);
|
||||
struct ast_channel_iterator *i;
|
||||
char *l_name = (char *) name;
|
||||
|
||||
if (!(i = ast_calloc(1, sizeof(*i)))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i->active_iterator = (void *) ast_channel_callback(ast_channel_by_name_cb,
|
||||
l_name, &name_len,
|
||||
OBJ_MULTIPLE | (name_len == 0 /* match the whole word, so optimize */ ? OBJ_KEY : 0));
|
||||
if (!i->active_iterator) {
|
||||
ast_free(i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
struct ast_channel_iterator *ast_channel_iterator_all_new(void)
|
||||
@@ -1559,67 +1563,41 @@ struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
|
||||
/* Legacy function, not currently used for lookups, but we need a cmp_fn */
|
||||
static int ast_channel_cmp_cb(void *obj, void *arg, int flags)
|
||||
{
|
||||
struct ast_channel *cmp_args = arg;
|
||||
size_t name_len;
|
||||
int ret = CMP_MATCH;
|
||||
|
||||
/* This is sort of a hack. Basically, we're using an arbitrary field
|
||||
* in ast_channel to pass the name_len for a prefix match. If this
|
||||
* gets changed, then the uses of ao2_find() must be changed, too. */
|
||||
name_len = cmp_args->rings;
|
||||
|
||||
if (!ast_strlen_zero(ast_channel_name(cmp_args))) { /* match by name */
|
||||
ret = ast_channel_by_name_cb(obj, arg, &name_len, flags);
|
||||
} else if (!ast_strlen_zero(cmp_args->exten)) {
|
||||
ret = ast_channel_by_exten_cb(obj, cmp_args->context, cmp_args->exten, flags);
|
||||
} else if (!ast_strlen_zero(ast_channel_uniqueid(cmp_args))) {
|
||||
ret = ast_channel_by_uniqueid_cb(obj, (void *) ast_channel_uniqueid(cmp_args), &name_len, flags);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
ast_log(LOG_ERROR, "BUG! Should never be called!\n");
|
||||
return CMP_STOP;
|
||||
}
|
||||
|
||||
static struct ast_channel *ast_channel_get_full(const char *name, size_t name_len,
|
||||
const char *exten, const char *context)
|
||||
struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
|
||||
{
|
||||
struct ast_channel *chan;
|
||||
char *l_name = (char *) name;
|
||||
char *l_exten = (char *) exten;
|
||||
char *l_context = (char *) context;
|
||||
|
||||
if (ast_strlen_zero(name)
|
||||
&& (chan = ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0))) {
|
||||
return chan;
|
||||
} else if ((chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
|
||||
(name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0))) {
|
||||
chan = ast_channel_callback(ast_channel_by_name_cb, l_name, &name_len,
|
||||
(name_len == 0) /* optimize if it is a complete name match */ ? OBJ_KEY : 0);
|
||||
if (chan) {
|
||||
return chan;
|
||||
}
|
||||
|
||||
/* If we haven't found by name or context yet and don't have a name, give up. */
|
||||
if (!name) {
|
||||
if (ast_strlen_zero(l_name)) {
|
||||
/* We didn't have a name to search for so quit. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If name was specified, but the result was NULL,
|
||||
* try a search on uniqueid, instead. */
|
||||
/* Now try a search for uniqueid. */
|
||||
return ast_channel_callback(ast_channel_by_uniqueid_cb, l_name, &name_len, 0);
|
||||
}
|
||||
|
||||
struct ast_channel *ast_channel_get_by_name(const char *name)
|
||||
{
|
||||
return ast_channel_get_full(name, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
|
||||
{
|
||||
return ast_channel_get_full(name, name_len, NULL, NULL);
|
||||
return ast_channel_get_by_name_prefix(name, 0);
|
||||
}
|
||||
|
||||
struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
|
||||
{
|
||||
return ast_channel_get_full(NULL, 0, exten, context);
|
||||
char *l_exten = (char *) exten;
|
||||
char *l_context = (char *) context;
|
||||
|
||||
return ast_channel_callback(ast_channel_by_exten_cb, l_context, l_exten, 0);
|
||||
}
|
||||
|
||||
int ast_is_deferrable_frame(const struct ast_frame *frame)
|
||||
|
Reference in New Issue
Block a user