Skip to content

Commit 5abf499

Browse files
InterLinked1kharwell
authored andcommitted
app_queue: Fix hint updates for included contexts
Previously, if custom hints were used with the hint: format in app_queue, when device state changes occured, app_queue would only do a literal string comparison of the context used for the hint in app_queue and the context of the hint which just changed state. This caused hints to not update and become stale if the context associated with the agent included the context which actually changes state, essentially completely breaking device state for any such agents defined in this manner. This fix adds an additional check to ensure that included contexts are also compared against the context which changed state, so that the behavior is correct no matter whether the context is specified to app_queue directly or indirectly. ASTERISK-29578 #close Change-Id: I8caf2f8da8157ef3d9ea71a8568c1eec95592b78
1 parent 02f54e2 commit 5abf499

File tree

1 file changed

+47
-2
lines changed

1 file changed

+47
-2
lines changed

apps/app_queue.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,6 +2630,46 @@ static int extensionstate2devicestate(int state)
26302630
return state;
26312631
}
26322632

2633+
/*!
2634+
* \brief Returns if one context includes another context
2635+
*
2636+
* \param parent Parent context to search for child
2637+
* \param child Context to check for inclusion in parent
2638+
*
2639+
* This function recrusively checks if the context child is included in the context parent.
2640+
*
2641+
* \return 1 if child is included in parent, 0 if not
2642+
*/
2643+
static int context_included(const char *parent, const char *child);
2644+
static int context_included(const char *parent, const char *child)
2645+
{
2646+
struct ast_context *c = NULL;
2647+
2648+
c = ast_context_find(parent);
2649+
if (!c) {
2650+
/* well, if parent doesn't exist, how can the child be included in it? */
2651+
return 0;
2652+
}
2653+
if (!strcmp(ast_get_context_name(c), parent)) {
2654+
/* found the context of the hint app_queue is using. Now, see
2655+
if that context includes the one that just changed state */
2656+
struct ast_include *inc = NULL;
2657+
2658+
while ((inc = (struct ast_include*) ast_walk_context_includes(c, inc))) {
2659+
const char *includename = ast_get_include_name(inc);
2660+
if (!strcasecmp(child, includename)) {
2661+
return 1;
2662+
}
2663+
/* recurse on this context, for nested includes. The
2664+
PBX extension parser will prevent infinite recursion. */
2665+
if (context_included(includename, child)) {
2666+
return 1;
2667+
}
2668+
}
2669+
}
2670+
return 0;
2671+
}
2672+
26332673
static int extension_state_cb(const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
26342674
{
26352675
struct ao2_iterator miter, qiter;
@@ -2650,9 +2690,14 @@ static int extension_state_cb(const char *context, const char *exten, struct ast
26502690
miter = ao2_iterator_init(q->members, 0);
26512691
for (; (m = ao2_iterator_next(&miter)); ao2_ref(m, -1)) {
26522692
if (!strcmp(m->state_context, context) && !strcmp(m->state_exten, exten)) {
2693+
found = 1;
2694+
} else if (!strcmp(m->state_exten, exten) && context_included(m->state_context, context)) {
2695+
/* context could be included in m->state_context. We need to check. */
2696+
found = 1;
2697+
}
2698+
if (found) {
26532699
update_status(q, m, device_state);
26542700
ao2_ref(m, -1);
2655-
found = 1;
26562701
break;
26572702
}
26582703
}
@@ -2663,7 +2708,7 @@ static int extension_state_cb(const char *context, const char *exten, struct ast
26632708
}
26642709
ao2_iterator_destroy(&qiter);
26652710

2666-
if (found) {
2711+
if (found) {
26672712
ast_debug(1, "Extension '%s@%s' changed to state '%d' (%s)\n", exten, context, device_state, ast_devstate2str(device_state));
26682713
} else {
26692714
ast_debug(3, "Extension '%s@%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n",

0 commit comments

Comments
 (0)