diff -Nru a/channels/chan_iax2.c b/channels/chan_iax2.c --- a/channels/chan_iax2.c 2005-02-19 01:53:58 -07:00 +++ b/channels/chan_iax2.c 2005-02-19 01:53:58 -07:00 @@ -274,6 +274,7 @@ int pokeexpire; /* When to expire poke */ int lastms; /* How long last response took (in ms), or -1 for no response */ int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ + char qualifycontext[80]; /* context to active/deactivate based on qualify status */ struct ast_ha *ha; struct iax2_peer *next; @@ -6414,6 +6415,8 @@ } } peer->lastms = iaxs[fr.callno]->pingtime; + if (!ast_strlen_zero(peer->qualifycontext)) + ast_activate_context(peer->qualifycontext); if (peer->pokeexpire > -1) ast_sched_del(sched, peer->pokeexpire); send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); @@ -7050,6 +7053,8 @@ ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); } + if (!ast_strlen_zero(peer->qualifycontext)) + ast_deactivate_context(peer->qualifycontext); if (peer->callno > 0) iax2_destroy(peer->callno); peer->callno = 0; @@ -7394,6 +7399,8 @@ } else if (!strcasecmp(v->name, "context")) { if (ast_strlen_zero(peer->context)) strncpy(peer->context, v->value, sizeof(peer->context) - 1); + } else if (!strcasecmp(v->name, "qualifycontext")) { + strncpy(peer->qualifycontext, v->value, sizeof(peer->qualifycontext) - 1); } else if (!strcasecmp(v->name, "regexten")) { strncpy(peer->regexten, v->value, sizeof(peer->regexten) - 1); } else if (!strcasecmp(v->name, "peercontext")) { diff -Nru a/channels/chan_sip.c b/channels/chan_sip.c --- a/channels/chan_sip.c 2005-02-19 01:53:58 -07:00 +++ b/channels/chan_sip.c 2005-02-19 01:53:58 -07:00 @@ -504,6 +504,7 @@ int lastms; /* How long last response took (in ms), or -1 for no response */ int maxms; /* Max ms we will accept for the host to be up, 0 to not monitor */ struct timeval ps; /* Ping send time */ + char qualifycontext[80]; /* context to active/deactivate based on qualify status */ struct sockaddr_in defaddr; /* Default IP address, used until registration */ struct ast_ha *ha; /* Access control list */ @@ -7362,6 +7363,9 @@ } } + if (!ast_strlen_zero(peer->qualifycontext)) + ast_activate_context(peer->qualifycontext); + if (peer->pokeexpire > -1) ast_sched_del(sched, peer->pokeexpire); if (!strcasecmp(msg, "INVITE")) @@ -8717,6 +8721,8 @@ peer->call = NULL; peer->lastms = -1; ast_device_state_changed("SIP/%s", peer->name); + if (!ast_strlen_zero(peer->qualifycontext)) + ast_deactivate_context(peer->qualifycontext); /* Try again quickly */ peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); return 0; @@ -9220,10 +9226,12 @@ strncpy(peer->secret, v->value, sizeof(peer->secret)-1); else if (!strcasecmp(v->name, "md5secret")) strncpy(peer->md5secret, v->value, sizeof(peer->md5secret)-1); - else if (!strcasecmp(v->name, "callerid")) { + else if (!strcasecmp(v->name, "callerid")) ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); - } else if (!strcasecmp(v->name, "context")) + else if (!strcasecmp(v->name, "context")) strncpy(peer->context, v->value, sizeof(peer->context)-1); + else if (!strcasecmp(v->name, "qualifycontext")) + strncpy(peer->qualifycontext, v->value, sizeof(peer->qualifycontext)-1); else if (!strcasecmp(v->name, "fromdomain")) strncpy(peer->fromdomain, v->value, sizeof(peer->fromdomain)-1); else if (!strcasecmp(v->name, "usereqphone")) diff -Nru a/channels/chan_zap.c b/channels/chan_zap.c --- a/channels/chan_zap.c 2005-02-19 01:53:58 -07:00 +++ b/channels/chan_zap.c 2005-02-19 01:53:58 -07:00 @@ -254,6 +254,7 @@ static char unknownprefix[20] = ""; static long resetinterval = 3600; /* How often (in seconds) to reset unused channels. Default 1 hour. */ static struct ast_channel inuse = { "GR-303InUse" }; +static char activecontext[80]; #ifdef PRI_GETSET_TIMERS static int pritimers[PRI_MAX_TIMERS]; #endif @@ -364,6 +365,7 @@ char localprefix[20]; /* area access code + area code ('0'+area code for european dialplans) */ char privateprefix[20]; /* for private dialplans */ char unknownprefix[20]; /* for unknown dialplans */ + char activecontext[80]; /* context to activate/deactivate as span goes up/down */ int dchannels[NUM_DCHANS]; /* What channel are the dchannels on */ int trunkgroup; /* What our trunkgroup is */ int mastertrunkgroup; /* What trunk group is our master */ @@ -6502,6 +6504,11 @@ destroy_zt_pvt(&tmp); return NULL; } + if (!ast_strlen_zero(pris[span].activecontext) && strcmp(pris[span].activecontext, activecontext)) { + ast_log(LOG_ERROR, "Span %d already has activecontext '%s'.\n", span + 1, activecontext); + destroy_zt_pvt(&tmp); + return NULL; + } if (pris[span].numchans >= MAX_CHANNELS) { ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel, pris[span].trunkgroup); @@ -6524,6 +6531,7 @@ strncpy(pris[span].localprefix, localprefix, sizeof(pris[span].localprefix)-1); strncpy(pris[span].privateprefix, privateprefix, sizeof(pris[span].privateprefix)-1); strncpy(pris[span].unknownprefix, unknownprefix, sizeof(pris[span].unknownprefix)-1); + strncpy(pris[span].activecontext, activecontext, sizeof(pris[span].activecontext) - 1); pris[span].resetinterval = resetinterval; tmp->pri = &pris[span]; @@ -7627,6 +7635,8 @@ if (pri->pvts[i]) { pri->pvts[i]->inalarm = 0; } + if (!ast_strlen_zero(pri->activecontext)) + ast_activate_context(pri->activecontext); break; case PRI_EVENT_DCHAN_DOWN: if (option_verbose > 1) @@ -7654,6 +7664,8 @@ p->inalarm = 1; } } + if (!ast_strlen_zero(pri->activecontext)) + ast_deactivate_context(pri->activecontext); } break; case PRI_EVENT_RESTART: @@ -9882,6 +9894,8 @@ strncpy(idledial, v->value, sizeof(idledial) - 1); } else if (!strcasecmp(v->name, "overlapdial")) { overlapdial = ast_true(v->value); + } else if (!strcasecmp(v->name, "activecontext")) { + strncpy(activecontext, v->value, sizeof(activecontext) - 1); } else if (!strcasecmp(v->name, "pritimer")) { #ifdef PRI_GETSET_TIMERS char *timerc; diff -Nru a/configs/sip.conf.sample b/configs/sip.conf.sample --- a/configs/sip.conf.sample 2005-02-19 01:53:58 -07:00 +++ b/configs/sip.conf.sample 2005-02-19 01:53:58 -07:00 @@ -212,6 +212,7 @@ ; defaultip ; rtptimeout ; rtpholdtimeout +; qualifycontext ;[sip_proxy] ; For incoming calls only. Example: FWD (Free World Dialup) diff -Nru a/include/asterisk/pbx.h b/include/asterisk/pbx.h --- a/include/asterisk/pbx.h 2005-02-19 01:53:58 -07:00 +++ b/include/asterisk/pbx.h 2005-02-19 01:53:58 -07:00 @@ -519,6 +519,21 @@ */ int ast_unlock_context(struct ast_context *con); +/*! Activates the given context */ +/*! + * \param context context to activate + * Activates the given context + * Returns 0 on success, -1 on failure + */ +int ast_activate_context(const char *context); + +/*! Deactivates the given context */ +/*! + * \param context context to deactivate + * Deactivates the given context + * Returns 0 on success, -1 on failure + */ +int ast_deactivate_context(const char *context); int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority); diff -Nru a/pbx.c b/pbx.c --- a/pbx.c 2005-02-19 01:53:58 -07:00 +++ b/pbx.c 2005-02-19 01:53:58 -07:00 @@ -119,6 +119,7 @@ struct ast_ignorepat *ignorepats; /* Patterns for which to continue playing dialtone */ const char *registrar; /* Registrar */ struct ast_sw *alts; /* Alternative switches */ + unsigned int active:1; /* if inactive, ignore context during matches */ char name[0]; /* Name of the context */ }; @@ -726,7 +727,7 @@ tmp = contexts; while(tmp) { /* Match context */ - if (bypass || !strcmp(tmp->name, context)) { + if ((bypass || !strcmp(tmp->name, context)) && tmp->active) { if (*status < STATUS_NO_EXTENSION) *status = STATUS_NO_EXTENSION; eroot = tmp->root; @@ -3177,6 +3178,7 @@ tmp->next = *local_contexts; tmp->includes = NULL; tmp->ignorepats = NULL; + tmp->active = 1; *local_contexts = tmp; if (option_debug) ast_log(LOG_DEBUG, "Registered context '%s'\n", tmp->name); @@ -5403,6 +5405,37 @@ int ast_unlock_context(struct ast_context *con) { return ast_mutex_unlock(&con->lock); +} + +/* + * Activate/deactivate context + */ +int ast_activate_context(const char *context) +{ + struct ast_context *con = ast_context_find(context); + + if (con) { + ast_lock_context(con); + con->active = 1; + ast_unlock_context(con); + return 0; + } + + return -1; +} + +int ast_deactivate_context(const char *context) +{ + struct ast_context *con = ast_context_find(context); + + if (con) { + ast_lock_context(con); + con->active = 0; + ast_unlock_context(con); + return 0; + } + + return -1; } /*