--- pbx.orig 2005-12-17 08:58:00.000000000 -0600 +++ pbx.c 2005-12-17 11:56:29.000000000 -0600 @@ -455,6 +455,11 @@ struct ast_hint *hints = NULL; struct ast_state_cb *statecbs = NULL; +// SMS HACK HERE ***************************** +static struct ast_sw *swCached = NULL; +static struct ast_switch *aswCached = NULL; +// END SMS HACK ****************************** + /* \note This function is special. It saves the stack so that no matter how many times it is called, it returns to the same place */ @@ -729,6 +734,101 @@ if (!strcasecmp(incstack[x], context)) return NULL; } + + /**************************************************************************************** + * + * Master Switch Bypass Hack + * + * This hack (and it is a dirty, dirty hack) captures a switch (realtime) and makes + * it the default switch -- placing it ahead of the standard in-memory switch. It + * does this by finding a context named "bypass_switch" and then finding the first valid + * switch within that context. (A better programmer could simply construct the + * switch and pass it off without need of looking in the extensins.conf file, but I + * wanted a way to turn this on/off). + * + * The hack swaps out the value for the realtime context on each call -- allowing the + * system to place calls directly to the context assigned in the channel, rather than + * the context assigned in our bogus "bypass_switch" static config context's switch statement. + * + * The net of this is that the system becomes 100% realtime. This has some obvious + * drawbacks for large systems and also has a problem if the database goes down, but... + * it makes some things very easy. + * + * As a side note - this will probably work for any switch you want to make the "king", not + * just realtime. + * + */ + + /* If we have a switch already cached, use that captured switch */ + if ((swCached) && (aswCached)) { + *swo = aswCached; + /* switch out for the requested context */ + sprintf(swCached->data, "%s@extensions", context); + *data = swCached->eval ? swCached->tmpdata : swCached->data; + *foundcontext = context; + return NULL; + } + + /* Otherwise find the "realtime" context in the list of contexts */ + tmp = contexts; + while (tmp) { + if (!strcmp(tmp->name, "bypass_switch")) { + + /* now find the switch entry in that context */ + sw = tmp->alts; + while(sw) { + + /* now make sure the requested switch is available */ + if ((asw = pbx_findswitch(sw->name))) { + + /* Tell me about the switch sw (ast_sw) and switch asw (ast_switch) + ast_verbose("asw description: %s\n", asw->description); + ast_verbose("asw name: %s\n", asw->name); + ast_verbose("sw name: %s\n", sw->name); + ast_verbose("sw registrar: %s\n", sw->registrar); + ast_verbose("sw data: %s\n", sw->data); + ast_verbose("sw tmpdata: %s\n", sw->tmpdata); + ast_verbose("sw eval: %d\n", sw->eval); + ast_verbose("sw stuff: %s\n", sw->stuff); + */ + + /* Replace the data - use the requested context name instead */ + sprintf(sw->data, "%s@extensions", context); + + /* Cache The Switch */ + ast_verbose("Mounting Bypass Switch: %s.\n", sw->name); + swCached = sw; + aswCached = asw; + + /* Substitute variables now */ + if (sw->eval) { + pbx_substitute_variables_helper(chan, sw->data, sw->tmpdata, SWITCH_DATA_LENGTH - 1); + } + if (action == HELPER_CANMATCH) { + res = asw->canmatch ? asw->canmatch(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; + } + else if (action == HELPER_MATCHMORE) { + res = asw->matchmore ? asw->matchmore(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; + } else { + res = asw->exists ? asw->exists(chan, context, exten, priority, callerid, sw->eval ? sw->tmpdata : sw->data) : 0; + } + if (res) { + /* Got a match */ + *swo = asw; + *data = sw->eval ? sw->tmpdata : sw->data; + *foundcontext = context; + return NULL; + } + } else { + ast_log(LOG_WARNING, "No such switch '%s'\n", sw->name); + } + sw = sw->next; + } + } + tmp = tmp->next; + } + // END SMS HACK ****************************** + if (bypass) tmp = bypass; else