From f258a0f975336ae888626d13881054d3cb0cef43 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 10 Mar 2009 20:56:38 +0000 Subject: [PATCH] fix unclean shutdown git-svn-id: http://svn.openzap.org/svn/openzap/trunk@693 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/src/include/openzap.h | 1 + libs/openzap/src/include/zap_types.h | 5 +- .../src/ozmod/ozmod_libpri/lpwrap_pri.c | 24 +++-- .../src/ozmod/ozmod_libpri/lpwrap_pri.h | 10 +- .../src/ozmod/ozmod_libpri/ozmod_libpri.c | 96 ++++++++++++------- libs/openzap/src/zap_io.c | 15 ++- 6 files changed, 98 insertions(+), 53 deletions(-) diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index ed4308be07..88fd998b43 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -543,6 +543,7 @@ struct zap_span { zio_channel_outgoing_call_t outgoing_call; zio_channel_request_t channel_request; zap_span_start_t start; + zap_span_stop_t stop; void *mod_data; char *type; char *dtmf_hangup; diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h index 09ea5fa4ac..e5218ca4b8 100644 --- a/libs/openzap/src/include/zap_types.h +++ b/libs/openzap/src/include/zap_types.h @@ -282,7 +282,9 @@ typedef enum { ZAP_SPAN_CONFIGURED = (1 << 0), ZAP_SPAN_READY = (1 << 1), ZAP_SPAN_STATE_CHANGE = (1 << 2), - ZAP_SPAN_SUSPENDED = (1 << 3) + ZAP_SPAN_SUSPENDED = (1 << 3), + ZAP_SPAN_IN_THREAD = (1 << 4), + ZAP_SPAN_STOP_THREAD = (1 << 5) } zap_span_flag_t; typedef enum { @@ -529,6 +531,7 @@ typedef struct value zap_hash_val_t; typedef struct zap_bitstream zap_bitstream_t; typedef struct zap_fsk_modulator zap_fsk_modulator_t; typedef zap_status_t (*zap_span_start_t)(zap_span_t *span); +typedef zap_status_t (*zap_span_stop_t)(zap_span_t *span); typedef enum { ZAP_CAUSE_NONE = 0, diff --git a/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.c b/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.c index 1220a93a77..ce38d8ea76 100644 --- a/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.c +++ b/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.c @@ -98,7 +98,8 @@ static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[] = { {16, LPWRAP_PRI_EVENT_NOTIFY, "NOTIFY"}, {17, LPWRAP_PRI_EVENT_PROGRESS, "PROGRESS"}, {18, LPWRAP_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"}, - {19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"} + {19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"}, + {20, LPWRAP_PRI_EVENT_TIME_CHECK, "TIME_CHECK"} }; #define LINE "--------------------------------------------------------------------------------" @@ -114,8 +115,8 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) zap_size_t len = buflen; int res; - if (zap_channel_read(spri->zdchan, buf, &len) != ZAP_SUCCESS) { - zap_log(ZAP_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span, spri->zdchan->last_error); + if (zap_channel_read(spri->dchan, buf, &len) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_CRIT, "span %d D-READ FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error); zap_clear_flag(spri, LPWRAP_PRI_READY); return -1; } @@ -134,8 +135,8 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen) struct lpwrap_pri *spri = (struct lpwrap_pri *) pri_get_userdata(pri); zap_size_t len = buflen -2; - if (zap_channel_write(spri->zdchan, buf, buflen, &len) != ZAP_SUCCESS) { - zap_log(ZAP_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span, spri->zdchan->last_error); + if (zap_channel_write(spri->dchan, buf, buflen, &len) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error); zap_clear_flag(spri, LPWRAP_PRI_READY); return -1; } @@ -146,15 +147,15 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen) return (int) buflen; } -int lpwrap_init_pri(struct lpwrap_pri *spri, int span, zap_channel_t *dchan, int swtype, int node, int debug) +int lpwrap_init_pri(struct lpwrap_pri *spri, zap_span_t *span, zap_channel_t *dchan, int swtype, int node, int debug) { int ret = -1; memset(spri, 0, sizeof(struct lpwrap_pri)); - spri->zdchan = dchan; + spri->dchan = dchan; - if ((spri->pri = pri_new_cb(spri->zdchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ + if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ spri->span = span; pri_set_debug(spri->pri, debug); ret = 0; @@ -203,6 +204,13 @@ int lpwrap_one_loop(struct lpwrap_pri *spri) event = NULL; if (!sel) { + if ((handler = spri->eventmap[LPWRAP_PRI_EVENT_TIME_CHECK] ? + spri->eventmap[LPWRAP_PRI_EVENT_TIME_CHECK] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) { + if (handler(spri, LPWRAP_PRI_EVENT_TIME_CHECK, NULL) < 0) { + return -1; + } + } + if ((next = pri_schedule_next(spri->pri))) { gettimeofday(&now, NULL); if (now.tv_sec >= next->tv_sec && (now.tv_usec >= next->tv_usec || next->tv_usec <= 100000)) { diff --git a/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.h b/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.h index 8ed6ab016f..5137ee4190 100644 --- a/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.h +++ b/libs/openzap/src/ozmod/ozmod_libpri/lpwrap_pri.h @@ -59,7 +59,8 @@ typedef enum { LPWRAP_PRI_EVENT_NOTIFY = PRI_EVENT_NOTIFY, LPWRAP_PRI_EVENT_PROGRESS = PRI_EVENT_PROGRESS, LPWRAP_PRI_EVENT_KEYPAD_DIGIT = PRI_EVENT_KEYPAD_DIGIT, - LPWRAP_PRI_EVENT_IO_FAIL = 19 + LPWRAP_PRI_EVENT_IO_FAIL = 19, + LPWRAP_PRI_EVENT_TIME_CHECK = 20 } lpwrap_pri_event_t; typedef enum { @@ -92,13 +93,12 @@ typedef int (*loop_handler)(struct lpwrap_pri *); struct lpwrap_pri { struct pri *pri; - int span; - int dchan; + zap_span_t *span; + zap_channel_t *dchan; unsigned int flags; void *private_info; event_handler eventmap[MAX_EVENT+1]; loop_handler on_loop; - zap_channel_t *zdchan; }; typedef struct lpwrap_pri lpwrap_pri_t; @@ -115,7 +115,7 @@ struct lpwrap_pri_event_list { const char *lpwrap_pri_event_str(lpwrap_pri_event_t event_id); int lpwrap_one_loop(struct lpwrap_pri *spri); -int lpwrap_init_pri(struct lpwrap_pri *spri, int span, zap_channel_t *dchan, int swtype, int node, int debug); +int lpwrap_init_pri(struct lpwrap_pri *spri, zap_span_t *span, zap_channel_t *dchan, int swtype, int node, int debug); int lpwrap_run_pri(struct lpwrap_pri *spri); #endif diff --git a/libs/openzap/src/ozmod/ozmod_libpri/ozmod_libpri.c b/libs/openzap/src/ozmod/ozmod_libpri/ozmod_libpri.c index a3f4a6a205..494751a7ab 100644 --- a/libs/openzap/src/ozmod/ozmod_libpri/ozmod_libpri.c +++ b/libs/openzap/src/ozmod/ozmod_libpri/ozmod_libpri.c @@ -99,7 +99,7 @@ static int parse_debug(const char *in) if (strstr(in, "q931_dump")) { flags |= PRI_DEBUG_Q931_DUMP; } - + if (strstr(in, "q931_state")) { flags |= PRI_DEBUG_Q931_STATE; } @@ -501,7 +501,7 @@ static __inline__ void check_state(zap_span_t *span) -static int on_info(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_info(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_log(ZAP_LOG_DEBUG, "number is: %s\n", pevent->ring.callednum); @@ -512,7 +512,7 @@ static int on_info(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event return 0; } -static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_span_t *span = spri->private_info; zap_channel_t *zchan = NULL; @@ -521,20 +521,20 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even if (zchan) { call = (q931_call *) zchan->call_data; - zap_log(ZAP_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span, pevent->hangup.channel); + zap_log(ZAP_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span->span_id, pevent->hangup.channel); zchan->caller_data.hangup_cause = pevent->hangup.cause; pri_release(spri->pri, call, 0); pri_destroycall(spri->pri, call); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING); } else { - zap_log(ZAP_LOG_DEBUG, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span, + zap_log(ZAP_LOG_DEBUG, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->hangup.channel, zchan->chan_id); } return 0; } -static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_span_t *span = spri->private_info; zap_channel_t *zchan = NULL; @@ -542,10 +542,10 @@ static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even zchan = span->channels[pevent->answer.channel]; if (zchan) { - zap_log(ZAP_LOG_DEBUG, "-- Answer on channel %d:%d\n", spri->span, pevent->answer.channel); + zap_log(ZAP_LOG_DEBUG, "-- Answer on channel %d:%d\n", spri->span->span_id, pevent->answer.channel); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_UP); } else { - zap_log(ZAP_LOG_DEBUG, "-- Answer on channel %d:%d %s but it's not in use?\n", spri->span, pevent->answer.channel, zchan->chan_id); + zap_log(ZAP_LOG_DEBUG, "-- Answer on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->answer.channel, zchan->chan_id); } @@ -553,7 +553,7 @@ static int on_answer(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even } -static int on_proceed(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_proceed(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_span_t *span = spri->private_info; zap_channel_t *zchan = NULL; @@ -561,10 +561,10 @@ static int on_proceed(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve zchan = span->channels[pevent->proceeding.channel]; if (zchan) { - zap_log(ZAP_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", spri->span, pevent->proceeding.channel); + zap_log(ZAP_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", spri->span->span_id, pevent->proceeding.channel); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS_MEDIA); } else { - zap_log(ZAP_LOG_DEBUG, "-- Proceeding on channel %d:%d %s but it's not in use?\n", spri->span, + zap_log(ZAP_LOG_DEBUG, "-- Proceeding on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->proceeding.channel, zchan->chan_id); } @@ -572,7 +572,7 @@ static int on_proceed(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve } -static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_span_t *span = spri->private_info; zap_channel_t *zchan = NULL; @@ -580,10 +580,10 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve zchan = span->channels[pevent->ringing.channel]; if (zchan) { - zap_log(ZAP_LOG_DEBUG, "-- Ringing on channel %d:%d\n", spri->span, pevent->ringing.channel); + zap_log(ZAP_LOG_DEBUG, "-- Ringing on channel %d:%d\n", spri->span->span_id, pevent->ringing.channel); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_PROGRESS); } else { - zap_log(ZAP_LOG_DEBUG, "-- Ringing on channel %d:%d %s but it's not in use?\n", spri->span, + zap_log(ZAP_LOG_DEBUG, "-- Ringing on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->ringing.channel, zchan->chan_id); } @@ -601,19 +601,19 @@ static int on_ring(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event zchan = span->channels[pevent->ring.channel]; if (!zchan || zchan->state != ZAP_CHANNEL_STATE_DOWN || zap_test_flag(zchan, ZAP_CHANNEL_INUSE)) { - zap_log(ZAP_LOG_WARNING, "--Duplicate Ring on channel %d:%d (ignored)\n", spri->span, pevent->ring.channel); + zap_log(ZAP_LOG_WARNING, "--Duplicate Ring on channel %d:%d (ignored)\n", spri->span->span_id, pevent->ring.channel); ret = 0; goto done; } if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) { - zap_log(ZAP_LOG_WARNING, "--Failure opening channel %d:%d (ignored)\n", spri->span, pevent->ring.channel); + zap_log(ZAP_LOG_WARNING, "--Failure opening channel %d:%d (ignored)\n", spri->span->span_id, pevent->ring.channel); ret = 0; goto done; } - zap_log(ZAP_LOG_NOTICE, "-- Ring on channel %d:%d (from %s to %s)\n", spri->span, pevent->ring.channel, + zap_log(ZAP_LOG_NOTICE, "-- Ring on channel %d:%d (from %s to %s)\n", spri->span->span_id, pevent->ring.channel, pevent->ring.callingnum, pevent->ring.callednum); memset(&zchan->caller_data, 0, sizeof(zchan->caller_data)); @@ -651,12 +651,12 @@ static int check_flags(lpwrap_pri_t *spri) return 0; } -static int on_restart(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_restart(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { zap_span_t *span = spri->private_info; zap_channel_t *zchan; - zap_log(ZAP_LOG_NOTICE, "-- Restarting %d:%d\n", spri->span, pevent->restart.channel); + zap_log(ZAP_LOG_NOTICE, "-- Restarting %d:%d\n", spri->span->span_id, pevent->restart.channel); zchan = span->channels[pevent->restart.channel]; @@ -673,45 +673,55 @@ static int on_restart(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve return 0; } -static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { if (!zap_test_flag(spri, LPWRAP_PRI_READY)) { - zap_log(ZAP_LOG_INFO, "Span %d D-Chan UP!\n", spri->span); + zap_log(ZAP_LOG_INFO, "Span %d D-Chan UP!\n", spri->span->span_id); zap_set_flag(spri, LPWRAP_PRI_READY); } return 0; } -static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { if (zap_test_flag(spri, LPWRAP_PRI_READY)) { - zap_log(ZAP_LOG_INFO, "Span %d D-Chan DOWN!\n", spri->span); + zap_log(ZAP_LOG_INFO, "Span %d D-Chan DOWN!\n", spri->span->span_id); zap_clear_flag(spri, LPWRAP_PRI_READY); } return 0; } -static int on_anything(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_anything(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { - zap_log(ZAP_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span, event_type, lpwrap_pri_event_str(event_type)); + zap_log(ZAP_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span->span_id, event_type, lpwrap_pri_event_str(event_type)); return 0; } -static int on_io_fail(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event * pevent) +static int on_io_fail(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { - zap_log(ZAP_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span, event_type, lpwrap_pri_event_str(event_type)); + zap_log(ZAP_LOG_DEBUG, "Caught Event span %d %u (%s)\n", spri->span->span_id, event_type, lpwrap_pri_event_str(event_type)); return 0; } +static int on_time_check(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) +{ + + if (!zap_running() || zap_test_flag(spri->span, ZAP_SPAN_STOP_THREAD)) { + return -1; + } + + return 0; +} + static void *zap_libpri_run(zap_thread_t *me, void *obj) { @@ -719,7 +729,9 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj) zap_libpri_data_t *isdn_data = span->signal_data; int x, i; - while(zap_running()) { + zap_set_flag(span, ZAP_SPAN_IN_THREAD); + + while(zap_running() && !zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) { x = 0; for(i = 1; i <= span->chan_count; i++) { @@ -734,12 +746,12 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj) } - if (x && lpwrap_init_pri(&isdn_data->spri, - span->span_id, // span - isdn_data->dchan, // dchan - isdn_data->pswitch, - isdn_data->node, - isdn_data->debug) < 0) { + if (!x || lpwrap_init_pri(&isdn_data->spri, + span, // span + isdn_data->dchan, // dchan + isdn_data->pswitch, + isdn_data->node, + isdn_data->debug) < 0) { snprintf(span->last_error, sizeof(span->last_error), "PRI init FAIL!"); } else { @@ -756,6 +768,7 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj) LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_info); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_IO_FAIL, on_io_fail); + LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_TIME_CHECK, on_time_check); isdn_data->spri.on_loop = check_flags; @@ -765,14 +778,28 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj) zap_channel_close(&isdn_data->dchan); } + if (!zap_running() || zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) { + break; + } + zap_log(ZAP_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span); zap_sleep(5000); } + zap_clear_flag(span, ZAP_SPAN_IN_THREAD); return NULL; } +static zap_status_t zap_libpri_stop(zap_span_t *span) +{ + zap_set_flag(span, ZAP_SPAN_STOP_THREAD); + while(zap_test_flag(span, ZAP_SPAN_IN_THREAD)) { + zap_sleep(100); + } + return ZAP_SUCCESS; +} + static zap_status_t zap_libpri_start(zap_span_t *span) { zap_status_t ret; @@ -934,6 +961,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) span->start = zap_libpri_start; + span->stop = zap_libpri_stop; isdn_data->sig_cb = sig_cb; //isdn_data->dchans[0] = dchans[0]; //isdn_data->dchans[1] = dchans[1]; diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index e10928a427..8b201853e5 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -219,11 +219,16 @@ static zap_status_t zap_span_destroy(zap_span_t *span) { zap_status_t status = ZAP_FAIL; - if (zap_test_flag(span, ZAP_SPAN_CONFIGURED) && span->zio && span->zio->span_destroy) { - zap_log(ZAP_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type); - status = span->zio->span_destroy(span); - zap_safe_free(span->type); - zap_safe_free(span->dtmf_hangup); + if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { + if (span->stop) { + span->stop(span); + } + if (span->zio && span->zio->span_destroy) { + zap_log(ZAP_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type); + status = span->zio->span_destroy(span); + zap_safe_free(span->type); + zap_safe_free(span->dtmf_hangup); + } } return status;