From 9b34815eb0597917b9b6e2e5d0afdd79a8b6d31e Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Fri, 18 Jun 2010 00:28:01 +0300 Subject: [PATCH] handle DAHDI_EVENT_REMOVED on a D-Channel When a DAHDI device is removed at run-time it sends the event DAHDI_EVENT_REMOVED on each channel. This is intended to signal the userspace program to close the respective file handle, as the driver of the device will need all of them closed to properly clean-up. This event has long since been handled in chan_dahdi (chan_zap at the time). However the event that is sent on a D-Channel of a "PRI" (ISDN) span simply gets ignored. This code adds handling for closing the file descriptor (and shutting down the span, while we're at it). It also adds a CLI command to help test it. --- channels/chan_dahdi.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 72 insertions(+), 0 deletions(-) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 2a256f2..b2af9dd 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -1430,6 +1430,7 @@ static const struct ast_channel_tech dahdi_tech = { struct dahdi_pvt *round_robin[32]; #if defined(HAVE_PRI) +static int pri_destroy_dchan(struct dahdi_pri *pri); static inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri) { int res; @@ -12706,6 +12707,8 @@ static void *pri_dchannel(void *vpri) } else if (x == DAHDI_EVENT_NOALARM) { pri->dchanavail[which] |= DCHAN_NOTINALARM; pri_restart(pri->dchans[which]); + } else if (x == DAHDI_EVENT_REMOVED) { + pri_destroy_dchan(pri); } ast_debug(1, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span); @@ -13934,6 +13937,74 @@ static char *handle_pri_show_spans(struct ast_cli_entry *e, int cmd, struct ast_ #endif /* defined(HAVE_PRI) */ #if defined(HAVE_PRI) +/*! + * \internal + * \brief Destroy a D-Channel of a PRI span + * \since 1.8 + * + * \param pri the pri span + * + * \return TRUE if the span was valid and we attempted destroying. + * + * Shuts down a span and destroys its D-Channel. Further destruction + * of the B-channels using dahdi_destroy_channel() would probably be required + * for the B-Channels. + */ +static int pri_destroy_dchan(struct dahdi_pri *pri) { + int i; + + if (!pri->master || (pri->master == AST_PTHREADT_NULL)) { + return 0; + } + ast_debug(1, "Stopping PRI span [FIXME: num/name]\n"); + pthread_cancel(pri->master); + + for (i = 0; i < NUM_DCHANS; i++) { + ast_debug(4, "closing pri_fd %d\n", i); + dahdi_close_pri_fd(pri, i); + } + return 1; +} + +static char *handle_pri_destroy_span(struct ast_cli_entry *e, int cmd, + struct ast_cli_args *a) +{ + int span; + + switch (cmd) { + case CLI_INIT: + e->command = "pri destroy span"; + e->usage = + "Usage: pri destroy span \n" + " Destorys D-channel of span.\n" + " B-Channels will need to be destroyed separately\n" + " (with: dahdi destroy channel).\n" + " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"; + return NULL; + case CLI_GENERATE: + return complete_span_4(a->line, a->word, a->pos, a->n); + } + + if (a->argc < 4) + return CLI_SHOWUSAGE; + span = atoi(a->argv[3]); + if ((span < 1) || (span > NUM_SPANS)) { + ast_cli(a->fd, "Invalid span '%s'. Should be a number from %d to %d\n", a->argv[3], 1, NUM_SPANS); + return CLI_SUCCESS; + } + if (!pris[span-1].pri) { + ast_cli(a->fd, "No PRI running on span %d\n", span); + return CLI_SUCCESS; + } + + pri_destroy_dchan(&(pris[span-1].pri)); + + return CLI_SUCCESS; +} + +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) static char *handle_pri_show_span(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int span; @@ -14053,6 +14124,7 @@ static struct ast_cli_entry dahdi_pri_cli[] = { AST_CLI_DEFINE(handle_pri_debug, "Enables PRI debugging on a span"), 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_destroy_span, "Destroy a PRI span"), 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"), -- 1.5.6.5