diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index ee4ddf5dda..1b9f96ab45 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/mod_openzap/mod_openzap.c @@ -2184,16 +2184,16 @@ SWITCH_STANDARD_API(oz_function) stream->write_function(stream, "-ERR Usage: oz dump []\n"); goto end; } else { - uint32_t span_id, chan_id = 0; + uint32_t chan_id = 0; zap_span_t *span; - - span_id = atoi(argv[1]); - + + zap_span_find_by_name(argv[1], &span); + if (argc > 2) { chan_id = atoi(argv[2]); } - if (!(span_id && (span = SPAN_CONFIG[span_id].span))) { + if (!span) { stream->write_function(stream, "-ERR invalid span\n"); } else { if (chan_id) { @@ -2249,38 +2249,31 @@ SWITCH_STANDARD_API(oz_function) ); } } - } else if (!strcasecmp(argv[0], "bounce")) { - /* MSC testing "oz bounce" command */ - if (argc < 2) { - stream->write_function(stream, "-ERR Usage: oz bounce []\n"); + } else if (!strcasecmp(argv[0], "stop") || !strcasecmp(argv[0], "start")) { + char *span_name = argv[1]; + zap_span_t *span = NULL; + zap_status_t status; + + if (span_name) { + zap_span_find_by_name(span_name, &span); + } + + if (!span) { + stream->write_function(stream, "-ERR no span\n"); goto end; + } + + if (!strcasecmp(argv[0], "stop")) { + status = zap_span_stop(span); } else { - int32_t span_id, chan_id = 0; - zap_span_t *span; + status = zap_span_start(span); + } + + stream->write_function(stream, status == ZAP_SUCCESS ? "+OK\n" : "-ERR failure\n"); + + goto end; - span_id = atoi(argv[1]); - - if (argc > 2) { - chan_id = atoi(argv[2]); - } - - if (!(span_id && (span = SPAN_CONFIG[span_id].span))) { - stream->write_function(stream, "-ERR invalid span\n"); - } else { - if (chan_id) { - zap_log(ZAP_LOG_INFO,"Bounce span: %d, chan: %d\n", span_id, chan_id); - } else { - uint32_t j; - - stream->write_function(stream, "+OK\n"); - for (j = 1; j <= span->chan_count; j++) { - zap_log(ZAP_LOG_INFO,"Bounce span: %d, chan: %d\n", span_id, j); - } - - } - } - } - /*Q931ToPcap enhancement*/ + /*Q931ToPcap enhancement*/ } else if (!strcasecmp(argv[0], "q931_pcap")) { int32_t span_id = 0; zap_span_t *span; diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 88fd998b43..c85233a949 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -550,6 +550,7 @@ struct zap_span { size_t dtmf_hangup_len; int suggest_chan_id; zap_state_map_t *state_map; + struct zap_span *next; }; @@ -620,7 +621,7 @@ OZ_DECLARE(zap_time_t) zap_current_time_in_ms(void); OZ_DECLARE(zap_status_t) zap_span_poll_event(zap_span_t *span, uint32_t ms); OZ_DECLARE(zap_status_t) zap_span_next_event(zap_span_t *span, zap_event_t **event); OZ_DECLARE(zap_status_t) zap_span_find(uint32_t id, zap_span_t **span); -OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **span); +OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **span, const char *name); OZ_DECLARE(zap_status_t) zap_span_close_all(void); OZ_DECLARE(zap_status_t) zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan); OZ_DECLARE(zap_status_t) zap_span_set_event_callback(zap_span_t *span, zio_event_cb_t event_callback); @@ -654,6 +655,7 @@ OZ_DECLARE(int) zap_load_modules(void); OZ_DECLARE(zap_status_t) zap_unload_modules(void); OZ_DECLARE(zap_status_t) zap_configure_span(const char *type, zap_span_t *span, zio_signal_cb_t sig_cb, ...); OZ_DECLARE(zap_status_t) zap_span_start(zap_span_t *span); +OZ_DECLARE(zap_status_t) zap_span_stop(zap_span_t *span); OZ_DECLARE(int) zap_load_module(const char *name); OZ_DECLARE(int) zap_load_module_assume(const char *name); OZ_DECLARE(zap_status_t) zap_span_find_by_name(const char *name, zap_span_t **span); diff --git a/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.c index ce38d8ea76..bb7b9c3a85 100644 --- a/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.c @@ -99,7 +99,6 @@ static struct lpwrap_pri_event_list LPWRAP_PRI_EVENT_LIST[] = { {17, LPWRAP_PRI_EVENT_PROGRESS, "PROGRESS"}, {18, LPWRAP_PRI_EVENT_KEYPAD_DIGIT, "KEYPAD_DIGIT"}, {19, LPWRAP_PRI_EVENT_IO_FAIL, "IO_FAIL"}, - {20, LPWRAP_PRI_EVENT_TIME_CHECK, "TIME_CHECK"} }; #define LINE "--------------------------------------------------------------------------------" @@ -125,7 +124,7 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) res+=2; //print_bits(buf, res-2, bb, sizeof(bb), 1, 0); - //zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", res-2, LINE, bb); + //zap_log(ZAP_LOG_DEBUG, "READ %d\n", res-2); return res; } @@ -142,7 +141,7 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen) } //print_bits(buf, (int)buflen-2, bb, sizeof(bb), 1, 0); - //zap_log(ZAP_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)buflen-2, LINE, bb); + //zap_log(ZAP_LOG_DEBUG, "WRITE %d\n", (int)buflen-2); return (int) buflen; } @@ -156,10 +155,13 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, zap_span_t *span, zap_channel_t *dc spri->dchan = dchan; if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ + unsigned char buf[4] = { 0 }; + size_t buflen = sizeof(buf), len = 0; spri->span = span; pri_set_debug(spri->pri, debug); ret = 0; zap_set_flag(spri, LPWRAP_PRI_READY); + zap_channel_write(spri->dchan, buf, buflen, &len); } else { fprintf(stderr, "Unable to create PRI\n"); } @@ -177,7 +179,13 @@ int lpwrap_one_loop(struct lpwrap_pri *spri) int sel; if (spri->on_loop) { - spri->on_loop(spri); + if ((sel = spri->on_loop(spri)) < 0) { + return sel; + } + } + + if (!zap_test_flag(spri, LPWRAP_PRI_READY)) { + return -1; } FD_ZERO(&rfds); @@ -204,13 +212,6 @@ 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/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.h b/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.h index 5137ee4190..c3832626c1 100644 --- a/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.h +++ b/libs/freetdm/src/ozmod/ozmod_libpri/lpwrap_pri.h @@ -59,8 +59,7 @@ 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_TIME_CHECK = 20 + LPWRAP_PRI_EVENT_IO_FAIL = 19 } lpwrap_pri_event_t; typedef enum { diff --git a/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c b/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c index 494751a7ab..0693edd71c 100644 --- a/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c +++ b/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c @@ -131,7 +131,9 @@ static int parse_debug(const char *in) return flags; } +static zap_io_interface_t zap_libpri_interface; +static zap_status_t zap_libpri_start(zap_span_t *span); static ZIO_API_FUNCTION(zap_libpri_api) { @@ -143,14 +145,40 @@ static ZIO_API_FUNCTION(zap_libpri_api) argc = zap_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } - - if (argc > 2) { - if (!strcasecmp(argv[0], "debug")) { + if (argc == 2) { + if (!strcasecmp(argv[0], "kill")) { int span_id = atoi(argv[1]); zap_span_t *span = NULL; if (zap_span_find_by_name(argv[1], &span) == ZAP_SUCCESS || zap_span_find(span_id, &span) == ZAP_SUCCESS) { zap_libpri_data_t *isdn_data = span->signal_data; + + if (span->start != zap_libpri_start) { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + + zap_clear_flag((&isdn_data->spri), LPWRAP_PRI_READY); + stream->write_function(stream, "%s: +OK killed.\n", __FILE__); + goto done; + } else { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + } + } + + if (argc > 2) { + if (!strcasecmp(argv[0], "debug")) { + zap_span_t *span = NULL; + + if (zap_span_find_by_name(argv[1], &span) == ZAP_SUCCESS) { + zap_libpri_data_t *isdn_data = span->signal_data; + if (span->start != zap_libpri_start) { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + pri_set_debug(isdn_data->spri.pri, parse_debug(argv[2])); stream->write_function(stream, "%s: +OK debug set.\n", __FILE__); goto done; @@ -159,6 +187,7 @@ static ZIO_API_FUNCTION(zap_libpri_api) goto done; } } + } stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); @@ -171,8 +200,6 @@ static ZIO_API_FUNCTION(zap_libpri_api) } -static zap_io_interface_t zap_libpri_interface; - static ZIO_IO_LOAD_FUNCTION(zap_libpri_io_init) { assert(zio != NULL); @@ -190,7 +217,6 @@ static ZIO_SIG_LOAD_FUNCTION(zap_libpri_init) { pri_set_error(s_pri_error); pri_set_message(s_pri_message); - return ZAP_SUCCESS; } @@ -648,6 +674,10 @@ static int check_flags(lpwrap_pri_t *spri) check_state(span); + if (!zap_running() || zap_test_flag(span, ZAP_SPAN_STOP_THREAD)) { + return -1; + } + return 0; } @@ -712,22 +742,12 @@ static int on_io_fail(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve } -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) { zap_span_t *span = (zap_span_t *) obj; zap_libpri_data_t *isdn_data = span->signal_data; int x, i; + int down = 0; zap_set_flag(span, ZAP_SPAN_IN_THREAD); @@ -768,8 +788,12 @@ 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); - + + if (down) { + zap_log(ZAP_LOG_INFO, "PRI back up on span %d\n", isdn_data->spri.span->span_id); + zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); + down = 0; + } isdn_data->spri.on_loop = check_flags; isdn_data->spri.private_info = span; @@ -782,30 +806,54 @@ static void *zap_libpri_run(zap_thread_t *me, void *obj) break; } - zap_log(ZAP_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span); + zap_log(ZAP_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span->span_id); + zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); + check_state(span); + check_state(span); + down++; zap_sleep(5000); } + zap_log(ZAP_LOG_DEBUG, "PRI thread ended on span %d\n", isdn_data->spri.span->span_id); + zap_clear_flag(span, ZAP_SPAN_IN_THREAD); - + zap_clear_flag(isdn_data, OZMOD_LIBPRI_RUNNING); + return NULL; } + static zap_status_t zap_libpri_stop(zap_span_t *span) { + zap_libpri_data_t *isdn_data = span->signal_data; + + if (!zap_test_flag(isdn_data, OZMOD_LIBPRI_RUNNING)) { + return ZAP_FAIL; + } + + zap_set_state_all(span, ZAP_CHANNEL_STATE_RESTART); + check_state(span); zap_set_flag(span, ZAP_SPAN_STOP_THREAD); while(zap_test_flag(span, ZAP_SPAN_IN_THREAD)) { zap_sleep(100); } + check_state(span); + return ZAP_SUCCESS; } static zap_status_t zap_libpri_start(zap_span_t *span) { zap_status_t ret; - zap_libpri_data_t *isdn_data = span->signal_data; + if (zap_test_flag(isdn_data, OZMOD_LIBPRI_RUNNING)) { + return ZAP_FAIL; + } + + zap_clear_flag(span, ZAP_SPAN_STOP_THREAD); + zap_clear_flag(span, ZAP_SPAN_IN_THREAD); + zap_set_flag(isdn_data, OZMOD_LIBPRI_RUNNING); ret = zap_thread_create_detached(zap_libpri_run, span); @@ -817,7 +865,6 @@ static zap_status_t zap_libpri_start(zap_span_t *span) } - static int str2node(char *node) { if (!strcasecmp(node, "cpe") || !strcasecmp(node, "user")) diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 8b201853e5..c2219d309f 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -79,9 +79,10 @@ static struct { zap_hash_t *module_hash; zap_hash_t *span_hash; zap_mutex_t *mutex; - struct zap_span *spans[ZAP_MAX_SPANS_INTERFACE+1]; + zap_mutex_t *span_mutex; uint32_t span_index; uint32_t running; + zap_span_t *spans; } globals; @@ -309,7 +310,55 @@ OZ_DECLARE(zap_status_t) zap_channel_get_alarms(zap_channel_t *zchan) return status; } -OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **span) +static void zap_span_add(zap_span_t *span) +{ + zap_span_t *sp; + zap_mutex_lock(globals.span_mutex); + for (sp = globals.spans; sp && sp->next; sp = sp->next); + if (sp) { + sp->next = span; + } else { + globals.spans = span; + } + hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_NONE); + zap_mutex_unlock(globals.span_mutex); +} + +#if 0 +static void zap_span_del(zap_span_t *span) +{ + zap_span_t *last = NULL, *sp; + + zap_mutex_lock(globals.span_mutex); + for (sp = globals.spans; sp; sp = sp->next) { + + if (sp == span) { + if (last) { + last->next = sp->next; + } else { + globals.spans = sp->next; + } + hashtable_remove(globals.span_hash, (void *)sp->name); + break; + } + + last = sp; + } + zap_mutex_unlock(globals.span_mutex); +} +#endif + +OZ_DECLARE(zap_status_t) zap_span_stop(zap_span_t *span) +{ + if (span->stop) { + span->stop(span); + return ZAP_SUCCESS; + } + + return ZAP_FAIL; +} + +OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **span, const char *name) { zap_span_t *new_span = NULL; zap_status_t status = ZAP_FAIL; @@ -317,21 +366,16 @@ OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **s assert(zio != NULL); zap_mutex_lock(globals.mutex); + if (globals.span_index < ZAP_MAX_SPANS_INTERFACE) { - new_span = globals.spans[++globals.span_index]; - if (!new_span) { - if (!(new_span = malloc(sizeof(*new_span)))) { - goto done; - } - globals.spans[globals.span_index] = new_span; - } + new_span = malloc(sizeof(*new_span)); + assert(new_span); memset(new_span, 0, sizeof(*new_span)); status = zap_mutex_create(&new_span->mutex); - if (status != ZAP_SUCCESS) { - goto done; - } + assert(status == ZAP_SUCCESS); + zap_set_flag(new_span, ZAP_SPAN_CONFIGURED); - new_span->span_id = globals.span_index; + new_span->span_id = ++globals.span_index; new_span->zio = zio; zap_copy_string(new_span->tone_map[ZAP_TONEMAP_DIAL], "%(1000,0,350,440)", ZAP_TONEMAP_LEN); zap_copy_string(new_span->tone_map[ZAP_TONEMAP_RING], "%(2000,4000,440,480)", ZAP_TONEMAP_LEN); @@ -339,11 +383,24 @@ OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **s zap_copy_string(new_span->tone_map[ZAP_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", ZAP_TONEMAP_LEN); new_span->trunk_type = ZAP_TRUNK_NONE; new_span->data_type = ZAP_TYPE_SPAN; + + zap_mutex_lock(globals.span_mutex); + if (!zap_strlen_zero(name) && hashtable_search(globals.span_hash, (void *)name)) { + zap_log(ZAP_LOG_WARNING, "name %s is already used, substituting 'span%d' as the name\n", name, new_span->span_id); + name = NULL; + } + zap_mutex_unlock(globals.span_mutex); + + if (!name) { + char buf[128] = ""; + snprintf(buf, sizeof(buf), "span%d", new_span->span_id); + name = buf; + } + new_span->name = strdup(name); + zap_span_add(new_span); *span = new_span; status = ZAP_SUCCESS; } - -done: zap_mutex_unlock(globals.mutex); return status; } @@ -351,18 +408,18 @@ done: OZ_DECLARE(zap_status_t) zap_span_close_all(void) { zap_span_t *span; - uint32_t i, j; + uint32_t i = 0, j; - zap_mutex_lock(globals.mutex); - for(i = 1; i <= globals.span_index; i++) { - span = globals.spans[i]; + zap_mutex_lock(globals.span_mutex); + for (span = globals.spans; span; span = span->next) { if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { for(j = 1; j <= span->chan_count && span->channels[j]; j++) { zap_channel_destroy(span->channels[j]); + i++; } } } - zap_mutex_unlock(globals.mutex); + zap_mutex_unlock(globals.span_mutex); return i ? ZAP_SUCCESS : ZAP_FAIL; } @@ -482,26 +539,40 @@ OZ_DECLARE(zap_status_t) zap_span_find_by_name(const char *name, zap_span_t **sp { zap_status_t status = ZAP_FAIL; - zap_mutex_lock(globals.mutex); - if (!zap_strlen_zero(name) && (*span = hashtable_search(globals.span_hash, (void *)name))) { - status = ZAP_SUCCESS; - } - zap_mutex_unlock(globals.mutex); + zap_mutex_lock(globals.span_mutex); + if (!zap_strlen_zero(name)) { + if ((*span = hashtable_search(globals.span_hash, (void *)name))) { + status = ZAP_SUCCESS; + } else { + int span_id = atoi(name); + zap_span_find(span_id, span); + if (*span) { + status = ZAP_SUCCESS; + } + } + } + zap_mutex_unlock(globals.span_mutex); + return status; } OZ_DECLARE(zap_status_t) zap_span_find(uint32_t id, zap_span_t **span) { - zap_span_t *fspan; + zap_span_t *fspan = NULL, *sp; if (id > ZAP_MAX_SPANS_INTERFACE) { return ZAP_FAIL; } - zap_mutex_lock(globals.mutex); - fspan = globals.spans[id]; - zap_mutex_unlock(globals.mutex); + zap_mutex_lock(globals.span_mutex); + for (sp = globals.spans; sp; sp = sp->next) { + if (sp->span_id == id) { + fspan = sp; + break; + } + } + zap_mutex_unlock(globals.span_mutex); if (!fspan || !zap_test_flag(fspan, ZAP_SPAN_CONFIGURED)) { return ZAP_FAIL; @@ -840,122 +911,94 @@ OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t zap_status_t status = ZAP_FAIL; zap_channel_t *check; uint32_t i,j; - zap_span_t *span; + zap_span_t *span = NULL; uint32_t span_max; if (span_id) { - if (span_id > globals.span_index || !globals.spans[span_id]) { + zap_span_find(span_id, &span); + + if (!span || !zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { zap_log(ZAP_LOG_CRIT, "SPAN NOT DEFINED!\n"); *zchan = NULL; return ZAP_FAIL; } - if (globals.spans[span_id]->active_count >= globals.spans[span_id]->chan_count) { + if (span->active_count >= span->chan_count) { zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n"); *zchan = NULL; return ZAP_FAIL; } - if (globals.spans[span_id]->channel_request && !globals.spans[span_id]->suggest_chan_id) { - return globals.spans[span_id]->channel_request(globals.spans[span_id], 0, direction, caller_data, zchan); + if (span->channel_request && !span->suggest_chan_id) { + return span->channel_request(span, 0, direction, caller_data, zchan); } span_max = span_id; j = span_id; } else { - span_max = globals.span_index; - if (direction == ZAP_TOP_DOWN) { - j = 1; - } else { - j = span_max; - } + zap_log(ZAP_LOG_CRIT, "No span supplied\n"); + *zchan = NULL; + return ZAP_FAIL; } + zap_mutex_lock(span->mutex); + + if (direction == ZAP_TOP_DOWN) { + i = 1; + } else { + i = span->chan_count; + } + for(;;) { + if (direction == ZAP_TOP_DOWN) { - if (j > span_max) { - goto done; + if (i > span->chan_count) { + break; } } else { - if (j == 0) { - goto done; + if (i == 0) { + break; } } - - span = globals.spans[j]; - zap_mutex_lock(span->mutex); - - if (!zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { - goto next_loop; - } - - if (direction == ZAP_TOP_DOWN) { - i = 1; - } else { - i = span->chan_count; - } - - for(;;) { - - if (direction == ZAP_TOP_DOWN) { - if (i > span->chan_count) { - break; - } - } else { - if (i == 0) { - break; - } - } - if (!(check = span->channels[i])) { - status = ZAP_FAIL; + if (!(check = span->channels[i])) { + status = ZAP_FAIL; + zap_mutex_unlock(span->mutex); + goto done; + } + + if (zap_test_flag(check, ZAP_CHANNEL_READY) && + !zap_test_flag(check, ZAP_CHANNEL_INUSE) && + !zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) && + check->state == ZAP_CHANNEL_STATE_DOWN + ) { + + if (span && span->channel_request) { + status = span->channel_request(span, i, direction, caller_data, zchan); zap_mutex_unlock(span->mutex); goto done; } - - if (zap_test_flag(check, ZAP_CHANNEL_READY) && - !zap_test_flag(check, ZAP_CHANNEL_INUSE) && - !zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) && - check->state == ZAP_CHANNEL_STATE_DOWN - ) { - if (globals.spans[span_id] && globals.spans[span_id]->channel_request) { - status = globals.spans[span_id]->channel_request(globals.spans[span_id], i, direction, caller_data, zchan); - zap_mutex_unlock(span->mutex); - goto done; - } - - status = check->zio->open(check); + status = check->zio->open(check); - if (status == ZAP_SUCCESS) { - zap_set_flag(check, ZAP_CHANNEL_INUSE); - zap_channel_open_chan(check); - *zchan = check; - zap_mutex_unlock(span->mutex); - goto done; - } - } - - if (direction == ZAP_TOP_DOWN) { - i++; - } else { - i--; + if (status == ZAP_SUCCESS) { + zap_set_flag(check, ZAP_CHANNEL_INUSE); + zap_channel_open_chan(check); + *zchan = check; + zap_mutex_unlock(span->mutex); + goto done; } } - next_loop: - - zap_mutex_unlock(span->mutex); - if (direction == ZAP_TOP_DOWN) { - j++; + i++; } else { - j--; + i--; } } done: - + return status; } @@ -1048,22 +1091,24 @@ OZ_DECLARE(zap_status_t) zap_channel_open(uint32_t span_id, uint32_t chan_id, za { zap_channel_t *check; zap_status_t status = ZAP_FAIL; + zap_span_t *span = NULL; - zap_mutex_lock(globals.mutex); + zap_mutex_unlock(globals.mutex); + zap_span_find(span_id, &span); - if (span_id > globals.span_index || chan_id >= ZAP_MAX_CHANNELS_SPAN || !globals.spans[span_id]) { - zap_log(ZAP_LOG_ERROR, "SPAN NOT DEFINED!\n"); + if (!span || !zap_test_flag(span, ZAP_SPAN_CONFIGURED) || chan_id >= ZAP_MAX_CHANNELS_SPAN) { + zap_log(ZAP_LOG_CRIT, "SPAN NOT DEFINED!\n"); *zchan = NULL; - goto done; + goto done; } - if (globals.spans[span_id]->channel_request) { + if (span->channel_request) { zap_log(ZAP_LOG_ERROR, "Individual channel selection not implemented on this span.\n"); *zchan = NULL; goto done; } - check = globals.spans[span_id]->channels[chan_id]; + check = span->channels[chan_id]; if (zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) || !zap_test_flag(check, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { @@ -2202,25 +2247,10 @@ static zap_status_t load_config(void) continue; } - if (zap_span_create(zio, &span) == ZAP_SUCCESS) { + if (zap_span_create(zio, &span, name) == ZAP_SUCCESS) { span->type = strdup(type); d = 0; - zap_mutex_lock(globals.mutex); - if (!zap_strlen_zero(name) && hashtable_search(globals.span_hash, (void *)name)) { - zap_log(ZAP_LOG_WARNING, "name %s is already used, substituting 'span%d' as the name\n", name, span->span_id); - name = NULL; - } - - if (!name) { - char buf[128] = ""; - snprintf(buf, sizeof(buf), "span%d", span->span_id); - name = buf; - } - span->name = strdup(name); - hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_NONE); - zap_mutex_unlock(globals.mutex); - zap_log(ZAP_LOG_DEBUG, "created span %d (%s) of type %s\n", span->span_id, span->name, type); } else { @@ -2576,6 +2606,7 @@ OZ_DECLARE(zap_status_t) zap_global_init(void) globals.span_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys); modcount = 0; zap_mutex_create(&globals.mutex); + zap_mutex_create(&globals.span_mutex); modcount = zap_load_modules(); zap_log(ZAP_LOG_NOTICE, "Modules configured: %d \n", modcount); @@ -2597,15 +2628,19 @@ OZ_DECLARE(uint32_t) zap_running(void) OZ_DECLARE(zap_status_t) zap_global_destroy(void) { - unsigned int i,j; + unsigned int j; + zap_span_t *sp; + time_end(); globals.running = 0; zap_span_close_all(); zap_sleep(1000); - for(i = 1; i <= globals.span_index; i++) { - zap_span_t *cur_span = globals.spans[i]; + zap_mutex_lock(globals.span_mutex); + for (sp = globals.spans; sp;) { + zap_span_t *cur_span = sp; + sp = sp->next; if (cur_span) { if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { @@ -2630,15 +2665,17 @@ OZ_DECLARE(zap_status_t) zap_global_destroy(void) zap_safe_free(cur_span->signal_data); zap_span_destroy(cur_span); } - zap_mutex_lock(globals.mutex); + hashtable_remove(globals.span_hash, (void *)cur_span->name); - zap_mutex_unlock(globals.mutex); zap_safe_free(cur_span->type); zap_safe_free(cur_span->name); free(cur_span); cur_span = NULL; } } + globals.spans = NULL; + zap_mutex_unlock(globals.span_mutex); + globals.span_index = 0; zap_unload_modules(); @@ -2649,6 +2686,7 @@ OZ_DECLARE(zap_status_t) zap_global_destroy(void) hashtable_destroy(globals.span_hash); zap_mutex_unlock(globals.mutex); zap_mutex_destroy(&globals.mutex); + zap_mutex_destroy(&globals.span_mutex); memset(&globals, 0, sizeof(globals)); return ZAP_SUCCESS;