Index: main/pbx.c =================================================================== --- main/pbx.c (revision 58880) +++ main/pbx.c (working copy) @@ -1794,7 +1794,7 @@ /*! \brief ast_extensions_state2: Check state of extension by using hints */ static int ast_extension_state2(struct ast_exten *e) { - char hint[AST_MAX_EXTENSION]; + char hint[AST_MAX_EXTENSION] = ""; char *cur, *rest; int allunavailable = 1, allbusy = 1, allfree = 1, allonhold = 1; int busy = 0, inuse = 0, ring = 0; @@ -1802,7 +1802,14 @@ if (!e) return -1; - ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); + if (strstr(ast_get_extension_app(e), "${")) { + /* Expand any variable definitions now */ + struct ast_channel c = {0,}; + ast_copy_string(c.exten, e->exten, sizeof(c.exten)); + ast_copy_string(c.context, e->parent->name, sizeof(c.context)); + pbx_substitute_variables_helper(&c, ast_get_extension_app(e), hint, sizeof(hint) - 1); + } else + ast_copy_string(hint, ast_get_extension_app(e), sizeof(hint)); rest = hint; /* One or more devices separated with a & character */ while ( (cur = strsep(&rest, "&")) ) { @@ -1912,8 +1919,12 @@ char *parse = buf; char *cur; int state; + struct ast_channel c = {0, }; - ast_copy_string(buf, ast_get_extension_app(hint->exten), sizeof(buf)); + ast_copy_string(c.exten, hint->exten->exten, sizeof(c.exten)); + ast_copy_string(c.context, hint->exten->parent->name, sizeof(c.context)); + pbx_substitute_variables_helper(&c, ast_get_extension_app(hint->exten), buf, sizeof(buf)); + while ( (cur = strsep(&parse, "&")) ) { if (!strcasecmp(cur, device)) break; @@ -1988,6 +1999,20 @@ return -1; } + /* If this is a pattern, dynamically create a new extension for this + * particular match. Note that this will only happen once for each + * individual extension, because the pattern will no longer match first. + */ + if (e->exten[0] == '_') { + ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, + e->cidmatch, e->app, (void *)strdup(e->data), free, + e->registrar); + e = ast_hint_extension(NULL, context, exten); + if (!e || e->exten[0] == '_') { + return -1; + } + } + /* Find the hint in the list of hints */ AST_RWLIST_WRLOCK(&hints); @@ -3914,6 +3939,16 @@ */ while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { exten = ast_hint_extension(NULL, this->context, this->exten); + /* If this is a pattern, dynamically create a new extension for this + * particular match. Note that this will only happen once for each + * individual extension, because the pattern will no longer match first. + */ + if (exten && exten->exten[0] == '_') { + ast_add_extension(exten->parent->name, 0, this->exten, PRIORITY_HINT, NULL, + 0, exten->app, strdup(exten->data), free, registrar); + exten = ast_hint_extension(NULL, this->context, this->exten); + } + /* Find the hint in the list of hints */ AST_RWLIST_TRAVERSE(&hints, hint, list) { if (hint->exten == exten) @@ -4686,18 +4721,7 @@ int res; int length; char *p; - char expand_buf[VAR_BUF_SIZE] = { 0, }; - /* if we are adding a hint, and there are global variables, and the hint - contains variable references, then expand them - */ - ast_rwlock_rdlock(&globalslock); - if (priority == PRIORITY_HINT && AST_LIST_FIRST(&globals) && strstr(application, "${")) { - pbx_substitute_variables_varshead(&globals, application, expand_buf, sizeof(expand_buf)); - application = expand_buf; - } - ast_rwlock_unlock(&globalslock); - length = sizeof(struct ast_exten); length += strlen(extension) + 1; length += strlen(application) + 1;