Index: channels/sig_pri.h =================================================================== --- channels/sig_pri.h (revision 328986) +++ channels/sig_pri.h (working copy) @@ -521,6 +521,8 @@ int pri_is_up(struct sig_pri_span *pri); +void sig_pri_cli_show_channels_header(int fd); +void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri); void sig_pri_cli_show_spans(int fd, int span, struct sig_pri_span *pri); void sig_pri_cli_show_span(int fd, int *dchannels, struct sig_pri_span *pri); Index: channels/chan_dahdi.c =================================================================== --- channels/chan_dahdi.c (revision 328986) +++ channels/chan_dahdi.c (working copy) @@ -14128,6 +14128,7 @@ } #endif /* defined(HAVE_PRI) */ +#if defined(HAVE_PRI) #if defined(HAVE_PRI_SERVICE_MESSAGES) static char *handle_pri_service_generic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a, int changestatus) { @@ -14271,8 +14272,41 @@ return handle_pri_service_generic(e, cmd, a, 2); } #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ +#endif /* defined(HAVE_PRI) */ #if defined(HAVE_PRI) +static char *handle_pri_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + int span; + + switch (cmd) { + case CLI_INIT: + e->command = "pri show channels"; + e->usage = + "Usage: pri show channels\n" + " Displays PRI channel information such as the current mapping\n" + " of DAHDI B channels to Asterisk channel names and which calls\n" + " are on hold or call-waiting. Calls on hold or call-waiting\n" + " are not associated with any B channel.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + + sig_pri_cli_show_channels_header(a->fd); + for (span = 0; span < NUM_SPANS; ++span) { + if (pris[span].pri.pri) { + sig_pri_cli_show_channels(a->fd, &pris[span].pri); + } + } + return CLI_SUCCESS; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) static char *handle_pri_show_spans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int span; @@ -14282,7 +14316,7 @@ e->command = "pri show spans"; e->usage = "Usage: pri show spans\n" - " Displays PRI Information\n"; + " Displays PRI span information\n"; return NULL; case CLI_GENERATE: return NULL; @@ -14403,8 +14437,9 @@ AST_CLI_DEFINE(handle_pri_service_enable_channel, "Return a channel to service"), AST_CLI_DEFINE(handle_pri_service_disable_channel, "Remove a channel from service"), #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */ - AST_CLI_DEFINE(handle_pri_show_spans, "Displays PRI Information"), - AST_CLI_DEFINE(handle_pri_show_span, "Displays PRI Information"), + AST_CLI_DEFINE(handle_pri_show_channels, "Displays PRI channel information"), + AST_CLI_DEFINE(handle_pri_show_spans, "Displays PRI span information"), + AST_CLI_DEFINE(handle_pri_show_span, "Displays PRI span information"), AST_CLI_DEFINE(handle_pri_show_debug, "Displays current PRI debug settings"), AST_CLI_DEFINE(handle_pri_set_debug_file, "Sends PRI debug output to the specified file"), AST_CLI_DEFINE(handle_pri_version, "Displays libpri version"), @@ -14995,7 +15030,7 @@ } break; default: - ; + break; } } if (tmp->channel > 0) { Index: channels/sig_pri.c =================================================================== --- channels/sig_pri.c (revision 328986) +++ channels/sig_pri.c (working copy) @@ -124,6 +124,25 @@ static int pri_active_dchan_index(struct sig_pri_span *pri); +static const char *sig_pri_call_level2str(enum sig_pri_call_level level) +{ + switch (level) { + case SIG_PRI_CALL_LEVEL_IDLE: + return "Idle"; + case SIG_PRI_CALL_LEVEL_SETUP: + return "Setup"; + case SIG_PRI_CALL_LEVEL_OVERLAP: + return "Overlap"; + case SIG_PRI_CALL_LEVEL_PROCEEDING: + return "Proceeding"; + case SIG_PRI_CALL_LEVEL_ALERTING: + return "Alerting"; + case SIG_PRI_CALL_LEVEL_CONNECT: + return "Connect"; + } + return "Unknown"; +} + static inline void pri_rel(struct sig_pri_span *pri) { ast_mutex_unlock(&pri->lock); @@ -7213,8 +7232,9 @@ } if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) { ast_log(LOG_WARNING, - "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n", - pvt->pri->span, digit, pvt->call_level); + "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n", + pvt->pri->span, digit, pvt->call_level, + sig_pri_call_level2str(pvt->call_level)); } } return 1; @@ -7634,6 +7654,55 @@ ast_free(doomed); } +#define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n" +#define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s" +void sig_pri_cli_show_channels_header(int fd) +{ + ast_cli(fd, SIG_PRI_SC_HEADER, "PRI", "", "B", "Chan", "Call", "PRI", "Channel"); + ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name"); +} + +void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri) +{ + char line[256]; + int idx; + struct sig_pri_chan *pvt; + + ast_mutex_lock(&pri->lock); + for (idx = 0; idx < pri->numchans; ++idx) { + if (!pri->pvts[idx]) { + continue; + } + pvt = pri->pvts[idx]; + sig_pri_lock_private(pvt); + sig_pri_lock_owner(pri, idx); + if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) { + /* Don't show held/call-waiting channels if they are not in use. */ + sig_pri_unlock_private(pvt); + continue; + } + + snprintf(line, sizeof(line), SIG_PRI_SC_LINE, + pri->span, + pvt->channel, + pvt->no_b_channel ? "No" : "Yes",/* Has media */ + sig_pri_is_chan_available(pvt) ? "Yes" : "No", + sig_pri_call_level2str(pvt->call_level), + pvt->call ? "Yes" : "No", + pvt->owner ? pvt->owner->name : ""); + + if (pvt->owner) { + ast_channel_unlock(pvt->owner); + } + sig_pri_unlock_private(pvt); + + ast_mutex_unlock(&pri->lock); + ast_cli(fd, "%s\n", line); + ast_mutex_lock(&pri->lock); + } + ast_mutex_unlock(&pri->lock); +} + static void build_status(char *s, size_t len, int status, int active) { if (!s || len < 1) {