Index: chan_zap.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v retrieving revision 1.429 diff -u -r1.429 chan_zap.c --- chan_zap.c 22 Apr 2005 19:10:35 -0000 1.429 +++ chan_zap.c 26 Apr 2005 16:08:50 -0000 @@ -613,6 +613,7 @@ int alerting; int setup_ack; /* whether we received SETUP_ACKNOWLEDGE or not */ int dsp_features; + int changestatus; /* for NFAS MAINTenance SERVice message handling */ #endif #ifdef ZAPATA_R2 int r2prot; @@ -6907,7 +6908,11 @@ /* If guard time, definitely not */ if (p->guardtime && (time(NULL) < p->guardtime)) return 0; - + + /* If channel is not in service, definitely not */ + if (p->changestatus > 0) + return 0; + /* If no owner definitely available */ if (!p->owner) { /* Trust PRI */ @@ -8503,6 +8508,32 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); } break; + case PRI_EVENT_SERVICE: + chanpos = pri_find_principle(pri, e->service.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Received SERVice change status %d on unconfigured channel %d/%d span %d\n", + e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); + } else { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + pri->pvts[chanpos]->changestatus = e->service.changestatus; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + ast_log(LOG_WARNING, "Received SERVice change status %d on channel %d/%d span %d\n", + e->service.changestatus, PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span); + } + break; + case PRI_EVENT_SERVICE_ACK: + chanpos = pri_find_principle(pri, e->service_ack.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Received SERVice ACKnowledge change status %d on unconfigured channel %d/%d span %d\n", + e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); + } else { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + pri->pvts[chanpos]->changestatus = e->service_ack.changestatus; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + ast_log(LOG_WARNING, "Received SERVice ACKnowledge change status %d on channel %d/%d span %d\n", + e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span); + } + break; default: ast_log(LOG_DEBUG, "Event: %d\n", e->e); } @@ -9086,6 +9117,7 @@ } #ifdef ZAPATA_PRI if (tmp->pri) { + ast_cli(fd, "Change Status: %d\n", tmp->changestatus); ast_cli(fd, "PRI Flags: "); if (tmp->resetting) ast_cli(fd, "Resetting "); @@ -9139,6 +9171,100 @@ return RESULT_FAILURE; } +#ifdef ZAPATA_PRI +static int zap_service_generic(int fd, int argc, char **argv, int changestatus) +{ + int channel; + struct zt_pvt *tmp = NULL; + int x; + int y; + ast_mutex_t *lock; + struct zt_pvt *start; + char *c; + int trunkgroup; + struct zt_pri *pri=NULL; + + lock = &iflock; + start = iflist; + + if (argc != 5) + return RESULT_SHOWUSAGE; + if ((c = strchr(argv[4], ':'))) { + if (sscanf(argv[4], "%d:%d", &trunkgroup, &channel) != 2) + return RESULT_SHOWUSAGE; + if ((trunkgroup < 1) || (channel < 1)) + return RESULT_SHOWUSAGE; + for (x=0;xcrvs; + lock = &pri->lock; + } else { + ast_cli(fd, "No such trunk group %d\n", trunkgroup); + return RESULT_FAILURE; + } + } else + channel = atoi(argv[4]); + + /* either servicing a D-Channel */ + for (x=0;xpri, pris[x].span, -1, changestatus); + return RESULT_SUCCESS; + } + } + } + + /* or servicing a B-Channel */ + ast_mutex_lock(lock); + tmp = start; + while (tmp) { + if (tmp->channel == channel) { + pri_maintenance_service(tmp->pri->pri, PRI_SPAN(PVT_TO_CHANNEL(tmp)), PVT_TO_CHANNEL(tmp), changestatus); + ast_mutex_unlock(lock); + return RESULT_SUCCESS; + } + tmp = tmp->next; + } + ast_mutex_unlock(lock); + + ast_cli(fd, "Unable to find given channel %d\n", channel); + return RESULT_FAILURE; +} + +static int zap_service_enable_channel(int fd, int argc, char **argv) +{ + return zap_service_generic(fd, argc, argv, 0); +} + +static int zap_service_loop_channel(int fd, int argc, char **argv) +{ + return zap_service_generic(fd, argc, argv, 1); +} + +static int zap_service_disable_channel(int fd, int argc, char **argv) +{ + return zap_service_generic(fd, argc, argv, 2); +} + +static int zap_service_continuity_channel(int fd, int argc, char **argv) +{ + return zap_service_generic(fd, argc, argv, 3); +} + +static int zap_service_shutdown_channel(int fd, int argc, char **argv) +{ + return zap_service_generic(fd, argc, argv, 4); +} + +#endif + static char zap_show_cadences_help[] = "Usage: zap show cadences\n" " Shows all cadences currently defined\n"; @@ -9186,6 +9312,28 @@ "Usage: zap destroy channel \n" " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n"; +#ifdef ZAPATA_PRI +static char service_enable_channel_usage[] = + "Usage: zap service enable channel \n" + " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message to restore a channel to service\n"; + +static char service_disable_channel_usage[] = + "Usage: zap service disable channel \n" + " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message to remove a channel from service\n"; + +static char service_loop_channel_usage[] = + "Usage: zap service loop channel \n" + " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message to put a channel into a maintenance loop\n"; + +static char service_continuity_channel_usage[] = + "Usage: zap service continuity channel \n" + " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message to test channel continuity\n"; + +static char service_shutdown_channel_usage[] = + "Usage: zap service shutdown channel \n" + " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message to shutdown a channel\n"; +#endif + static struct ast_cli_entry cli_show_channels = { {"zap", "show", "channels", NULL}, zap_show_channels, "Show active zapata channels", show_channels_usage, NULL }; @@ -9195,6 +9343,23 @@ static struct ast_cli_entry cli_destroy_channel = { {"zap", "destroy", "channel", NULL}, zap_destroy_channel, "Destroy a channel", destroy_channel_usage, NULL }; +#ifdef ZAPATA_PRI +static struct ast_cli_entry cli_service_enable_channel = { + {"zap", "service", "enable", "channel", NULL}, zap_service_enable_channel, "Return a channel to service", service_enable_channel_usage, NULL }; + +static struct ast_cli_entry cli_service_disable_channel = { + {"zap", "service", "disable", "channel", NULL}, zap_service_disable_channel, "Remove a channel from service", service_disable_channel_usage, NULL }; + +static struct ast_cli_entry cli_service_loop_channel = { + {"zap", "service", "loop", "channel", NULL}, zap_service_loop_channel, "Put a channel into maintenance loop", service_loop_channel_usage, NULL }; + +static struct ast_cli_entry cli_service_continuity_channel = { + {"zap", "service", "continuity", "channel", NULL}, zap_service_continuity_channel, "Test channel continuity", service_continuity_channel_usage, NULL }; + +static struct ast_cli_entry cli_service_shutdown_channel = { + {"zap", "service", "shutdown", "channel", NULL}, zap_service_shutdown_channel, "Shutdown a channel", service_shutdown_channel_usage, NULL }; +#endif + #define TRANSFER 0 #define HANGUP 1 @@ -9390,6 +9555,11 @@ ast_cli_unregister(&pri_show_span); ast_cli_unregister(&pri_set_debug_file); ast_cli_unregister(&pri_unset_debug_file); + ast_cli_unregister(&cli_service_enable_channel); + ast_cli_unregister(&cli_service_disable_channel); + ast_cli_unregister(&cli_service_loop_channel); + ast_cli_unregister(&cli_service_continuity_channel); + ast_cli_unregister(&cli_service_shutdown_channel); #endif #ifdef ZAPATA_R2 ast_cli_unregister(&r2_debug); @@ -10269,6 +10439,11 @@ ast_cli_register(&pri_show_span); ast_cli_register(&pri_set_debug_file); ast_cli_register(&pri_unset_debug_file); + ast_cli_register(&cli_service_enable_channel); + ast_cli_register(&cli_service_disable_channel); + ast_cli_register(&cli_service_loop_channel); + ast_cli_register(&cli_service_continuity_channel); + ast_cli_register(&cli_service_shutdown_channel); #endif #ifdef ZAPATA_R2 ast_cli_register(&r2_debug);