From 3c4453955d86f72611d4698f87b1ff44b34fb17f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 10 Sep 2008 15:25:02 +0000 Subject: [PATCH] change core of openzap to use dynamic allocation of spans and channels to reduce memory usage git-svn-id: http://svn.openzap.org/svn/openzap/trunk@552 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/freetdm/mod_openzap/mod_openzap.c | 30 +++--- libs/freetdm/src/include/openzap.h | 10 +- .../freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c | 35 +++---- .../freetdm/src/ozmod/ozmod_pika/ozmod_pika.c | 58 ++++++------ .../ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c | 36 +++---- .../src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c | 64 ++++++------- libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.c | 24 ++--- libs/freetdm/src/testanalog.c | 6 +- libs/freetdm/src/zap_io.c | 94 ++++++++++++------- libs/freetdm/src/zap_m3ua.c | 2 +- 10 files changed, 192 insertions(+), 167 deletions(-) diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index a74d3a26f6..0027451179 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/mod_openzap/mod_openzap.c @@ -1768,21 +1768,21 @@ void dump_chan(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *strea "dnis: %s\n" "rdnis: %s\n" "cause: %s\n\n", - span->channels[chan_id].span_id, - span->channels[chan_id].chan_id, - span->channels[chan_id].physical_span_id, - span->channels[chan_id].physical_chan_id, - zap_chan_type2str(span->channels[chan_id].type), - zap_channel_state2str(span->channels[chan_id].state), - zap_channel_state2str(span->channels[chan_id].last_state), - span->channels[chan_id].caller_data.cid_date, - span->channels[chan_id].caller_data.cid_name, - span->channels[chan_id].caller_data.cid_num.digits, - span->channels[chan_id].caller_data.ani.digits, - span->channels[chan_id].caller_data.aniII, - span->channels[chan_id].caller_data.dnis.digits, - span->channels[chan_id].caller_data.rdnis.digits, - switch_channel_cause2str(span->channels[chan_id].caller_data.hangup_cause) + span->channels[chan_id]->span_id, + span->channels[chan_id]->chan_id, + span->channels[chan_id]->physical_span_id, + span->channels[chan_id]->physical_chan_id, + zap_chan_type2str(span->channels[chan_id]->type), + zap_channel_state2str(span->channels[chan_id]->state), + zap_channel_state2str(span->channels[chan_id]->last_state), + span->channels[chan_id]->caller_data.cid_date, + span->channels[chan_id]->caller_data.cid_name, + span->channels[chan_id]->caller_data.cid_num.digits, + span->channels[chan_id]->caller_data.ani.digits, + span->channels[chan_id]->caller_data.aniII, + span->channels[chan_id]->caller_data.dnis.digits, + span->channels[chan_id]->caller_data.rdnis.digits, + switch_channel_cause2str(span->channels[chan_id]->caller_data.hangup_cause) ); } diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 48cffda0be..11381854aa 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -153,7 +153,7 @@ #define ZAP_MAX_CHANNELS_PHYSICAL_SPAN 32 #define ZAP_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN 16 #define ZAP_MAX_CHANNELS_SPAN ZAP_MAX_CHANNELS_PHYSICAL_SPAN * ZAP_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN -#define ZAP_MAX_SPANS_INTERFACE 33 +#define ZAP_MAX_SPANS_INTERFACE 128 #define GOTO_STATUS(label,st) status = st; goto label ; @@ -476,7 +476,7 @@ struct zap_span { char tone_map[ZAP_TONEMAP_INVALID+1][ZAP_TONEMAP_LEN]; teletone_tone_map_t tone_detect_map[ZAP_TONEMAP_INVALID+1]; teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1]; - zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN]; + zap_channel_t *channels[ZAP_MAX_CHANNELS_SPAN+1]; zio_channel_outgoing_call_t outgoing_call; zio_channel_request_t channel_request; zap_span_start_t start; @@ -610,7 +610,7 @@ static __inline__ void zap_set_state_all(zap_span_t *span, zap_channel_state_t s uint32_t j; zap_mutex_lock(span->mutex); for(j = 1; j <= span->chan_count; j++) { - zap_set_state_locked((&span->channels[j]), state); + zap_set_state_locked((span->channels[j]), state); } zap_mutex_unlock(span->mutex); } @@ -619,7 +619,7 @@ static __inline__ int zap_check_state_all(zap_span_t *span, zap_channel_state_t { uint32_t j; for(j = 1; j <= span->chan_count; j++) { - if (span->channels[j].state != state || zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) { + if (span->channels[j]->state != state || zap_test_flag(span->channels[j], ZAP_CHANNEL_STATE_CHANGE)) { return 0; } } @@ -632,7 +632,7 @@ static __inline__ void zap_set_flag_all(zap_span_t *span, uint32_t flag) uint32_t j; zap_mutex_lock(span->mutex); for(j = 1; j <= span->chan_count; j++) { - zap_set_flag_locked((&span->channels[j]), flag); + zap_set_flag_locked((span->channels[j]), flag); } zap_mutex_unlock(span->mutex); } diff --git a/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c b/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c index 2136ee36cf..ea39bf4285 100644 --- a/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c +++ b/libs/freetdm/src/ozmod/ozmod_isdn/ozmod_isdn.c @@ -81,7 +81,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request) /* * get codec type */ - zap_channel_command(&span->channels[chan_id], ZAP_COMMAND_GET_NATIVE_CODEC, &codec); + zap_channel_command(span->channels[chan_id], ZAP_COMMAND_GET_NATIVE_CODEC, &codec); /* * Q.931 Setup Message @@ -198,7 +198,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request) new_chan = NULL; if (caller_data->chan_id < ZAP_MAX_CHANNELS_SPAN && caller_data->chan_id <= span->chan_count) { - new_chan = &span->channels[caller_data->chan_id]; + new_chan = span->channels[caller_data->chan_id]; } if (new_chan && (status = zap_channel_open_chan(new_chan) == ZAP_SUCCESS)) { @@ -393,14 +393,14 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) case Q931mes_RESTART: { if (chan_id) { - zchan = &span->channels[chan_id]; + zchan = span->channels[chan_id]; } if (zchan) { zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); } else { uint32_t i; for (i = 0; i < span->chan_count; i++) { - zap_set_state_locked((&span->channels[i]), ZAP_CHANNEL_STATE_RESTART); + zap_set_state_locked((span->channels[i]), ZAP_CHANNEL_STATE_RESTART); } } } @@ -519,7 +519,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) * try to find a free channel */ for (x = 1; x <= span->chan_count; x++) { - zap_channel_t *zc = &span->channels[x]; + zap_channel_t *zc = span->channels[x]; if (!zap_test_flag(zc, ZAP_CHANNEL_INUSE) && zc->state == ZAP_CHANNEL_STATE_DOWN) { zchan = zc; @@ -543,7 +543,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) * by the TE side is already in use */ if (chan_id > 0 && chan_id < ZAP_MAX_CHANNELS_SPAN && chan_id <= span->chan_count) { - zchan = &span->channels[chan_id]; + zchan = span->channels[chan_id]; } else { /* invalid channel id */ @@ -939,7 +939,7 @@ static __inline__ void state_advance(zap_channel_t *zchan) /* * get codec type */ - zap_channel_command(&zchan->span->channels[zchan->chan_id], ZAP_COMMAND_GET_NATIVE_CODEC, &codec); + zap_channel_command(zchan->span->channels[zchan->chan_id], ZAP_COMMAND_GET_NATIVE_CODEC, &codec); /* * Q.931 Setup Message @@ -1125,12 +1125,12 @@ static __inline__ void check_state(zap_span_t *span) uint32_t j; zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE); for(j = 1; j <= span->chan_count; j++) { - if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) { - zap_mutex_lock(span->channels[j].mutex); - zap_clear_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); - state_advance(&span->channels[j]); - zap_channel_complete_state(&span->channels[j]); - zap_mutex_unlock(span->channels[j].mutex); + if (zap_test_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) { + zap_mutex_lock(span->channels[j]->mutex); + zap_clear_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); + state_advance(span->channels[j]); + zap_channel_complete_state(span->channels[j]); + zap_mutex_unlock(span->channels[j]->mutex); } } } @@ -1245,8 +1245,8 @@ static void *zap_isdn_tones_run(zap_thread_t *me, void *obj) /* get a tone generation friendly interval to avoid distortions */ for (x = 1; x <= span->chan_count; x++) { - if (span->channels[x].type != ZAP_CHAN_TYPE_DQ921) { - zap_channel_command(&span->channels[x], ZAP_COMMAND_GET_INTERVAL, &interval); + if (span->channels[x]->type != ZAP_CHAN_TYPE_DQ921) { + zap_channel_command(span->channels[x], ZAP_COMMAND_GET_INTERVAL, &interval); break; } } @@ -1270,7 +1270,7 @@ static void *zap_isdn_tones_run(zap_thread_t *me, void *obj) * check b-channel states and generate & send tones if neccessary */ for (x = 1; x <= span->chan_count; x++) { - zap_channel_t *zchan = &span->channels[x]; + zap_channel_t *zchan = span->channels[x]; zap_size_t len = sizeof(frame), rlen; if (zchan->type == ZAP_CHAN_TYPE_DQ921) { @@ -1389,6 +1389,7 @@ done: } zap_log(ZAP_LOG_DEBUG, "ISDN tone thread ended.\n"); + return NULL; } @@ -1697,7 +1698,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span) } for(i = 1; i <= span->chan_count; i++) { - if (span->channels[i].type == ZAP_CHAN_TYPE_DQ921) { + if (span->channels[i]->type == ZAP_CHAN_TYPE_DQ921) { if (x > 1) { snprintf(span->last_error, sizeof(span->last_error), "Span has more than 2 D-Channels!"); return ZAP_FAIL; diff --git a/libs/freetdm/src/ozmod/ozmod_pika/ozmod_pika.c b/libs/freetdm/src/ozmod/ozmod_pika/ozmod_pika.c index e3121309ec..c409f9535e 100644 --- a/libs/freetdm/src/ozmod/ozmod_pika/ozmod_pika.c +++ b/libs/freetdm/src/ozmod/ozmod_pika/ozmod_pika.c @@ -945,7 +945,7 @@ static ZIO_SPAN_POLL_EVENT_FUNCTION(pika_poll_event) zap_channel_t *zchan; pika_chan_data_t *chan_data; for(x = 1; x <= span->chan_count; x++) { - zchan = &span->channels[x]; + zchan = span->channels[x]; assert(zchan != NULL); chan_data = (pika_chan_data_t *) zchan->mod_data; assert(chan_data != NULL); @@ -983,11 +983,11 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) uint32_t i, event_id = 0; for(i = 1; i <= span->chan_count; i++) { - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { - pika_chan_data_t *chan_data = (pika_chan_data_t *) span->channels[i].mod_data; + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) { + pika_chan_data_t *chan_data = (pika_chan_data_t *) span->channels[i]->mod_data; PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; - zap_clear_flag((&span->channels[i]), ZAP_CHANNEL_EVENT); + zap_clear_flag(span->channels[i], ZAP_CHANNEL_EVENT); PKH_EVENT_GetText(chan_data->last_oob_event.id, event_text, sizeof(event_text)); @@ -1006,47 +1006,47 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) break; case PKH_EVENT_PHONE_OFFHOOK: - zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); + zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_OFFHOOK; break; case PKH_EVENT_TRUNK_BELOW_THRESHOLD: case PKH_EVENT_TRUNK_ABOVE_THRESHOLD: case PKH_EVENT_PHONE_ONHOOK: - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_ONHOOK; break; case PKH_EVENT_SPAN_ALARM_T1_RED: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RED); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "RED ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RED); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_T1_YELLOW: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_YELLOW); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "YELLOW ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_YELLOW); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "YELLOW ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_T1_AIS: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_AIS); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "AIS ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_AIS); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_E1_RED: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RED); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "RED ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RED); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_E1_RAI: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RAI); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "RAI ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RAI); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RAI ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_E1_AIS: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_AIS); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "AIS ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_AIS); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_E1_RMAI: @@ -1057,22 +1057,22 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) case PKH_EVENT_SPAN_LOSS_OF_SIGNAL: case PKH_EVENT_SPAN_OUT_OF_CRC_MF_SYNC: case PKH_EVENT_SPAN_OUT_OF_CAS_MF_SYNC: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_GENERAL); - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "GENERAL ALARM"); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_GENERAL); + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "GENERAL ALARM"); event_id = ZAP_OOB_ALARM_TRAP; break; case PKH_EVENT_SPAN_ALARM_T1_RED_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RED); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RED); case PKH_EVENT_SPAN_ALARM_T1_YELLOW_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_YELLOW); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_YELLOW); case PKH_EVENT_SPAN_ALARM_T1_AIS_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_AIS); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_AIS); case PKH_EVENT_SPAN_ALARM_E1_RED_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RED); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RED); case PKH_EVENT_SPAN_ALARM_E1_RAI_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_RAI); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_RAI); case PKH_EVENT_SPAN_ALARM_E1_AIS_CLEAR: - zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_AIS); + zap_set_alarm_flag(span->channels[i], ZAP_ALARM_AIS); case PKH_EVENT_SPAN_ALARM_E1_RMAI_CLEAR: case PKH_EVENT_SPAN_ALARM_E1_TS16AIS_CLEAR: case PKH_EVENT_SPAN_ALARM_E1_TS16LOS_CLEAR: @@ -1080,7 +1080,7 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) case PKH_EVENT_SPAN_LOSS_OF_SIGNAL_CLEAR: case PKH_EVENT_SPAN_IN_CRC_MF_SYNC: case PKH_EVENT_SPAN_IN_CAS_MF_SYNC: - zap_clear_alarm_flag((&span->channels[i]), ZAP_ALARM_GENERAL); + zap_clear_alarm_flag(span->channels[i], ZAP_ALARM_GENERAL); event_id = ZAP_OOB_ALARM_CLEAR; break; case PKH_EVENT_SPAN_MESSAGE: @@ -1104,10 +1104,10 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event) break; } - span->channels[i].last_event_time = 0; + span->channels[i]->last_event_time = 0; span->event_header.e_type = ZAP_EVENT_OOB; span->event_header.enum_id = event_id; - span->event_header.channel = &span->channels[i]; + span->event_header.channel = span->channels[i]; *event = &span->event_header; return ZAP_SUCCESS; } diff --git a/libs/freetdm/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c b/libs/freetdm/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c index 7a3e08d2ce..c93f254783 100644 --- a/libs/freetdm/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c +++ b/libs/freetdm/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c @@ -143,8 +143,8 @@ static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_short_event_t *event, i zap_mutex_lock(signal_mutex); for(i = 0; i <= span->chan_count; i++) { - if (span->channels[i].physical_span_id == event->span+1 && span->channels[i].physical_chan_id == event->chan+1) { - zchan = &span->channels[i]; + if (span->channels[i]->physical_span_id == event->span+1 && span->channels[i]->physical_chan_id == event->chan+1) { + zchan = span->channels[i]; if (force) { break; } @@ -152,10 +152,10 @@ static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_short_event_t *event, i if (zchan->state == ZAP_CHANNEL_STATE_DOWN || zchan->state >= ZAP_CHANNEL_STATE_TERMINATING) { int x = 0; zap_log(ZAP_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n", - span->channels[i].span_id, - span->channels[i].chan_id, - span->channels[i].physical_span_id, - span->channels[i].physical_chan_id); + span->channels[i]->span_id, + span->channels[i]->chan_id, + span->channels[i]->physical_span_id, + span->channels[i]->physical_chan_id); zap_mutex_unlock(signal_mutex); for (x = 0; x < 200; x++) { @@ -169,10 +169,10 @@ static zap_channel_t *find_zchan(zap_span_t *span, ss7bc_short_event_t *event, i if (zap_test_flag(zchan, ZAP_CHANNEL_INUSE)) { zchan = NULL; zap_log(ZAP_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n", - span->channels[i].span_id, - span->channels[i].chan_id, - span->channels[i].physical_span_id, - span->channels[i].physical_chan_id + span->channels[i]->span_id, + span->channels[i]->chan_id, + span->channels[i]->physical_span_id, + span->channels[i]->physical_chan_id ); } } @@ -811,15 +811,15 @@ static __inline__ void check_state(zap_span_t *span) uint32_t j; zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE); for(j = 1; j <= span->chan_count; j++) { - if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE) || susp) { - zap_mutex_lock(span->channels[j].mutex); - zap_clear_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); - if (susp && span->channels[j].state != ZAP_CHANNEL_STATE_DOWN) { - zap_channel_set_state(&span->channels[j], ZAP_CHANNEL_STATE_RESTART, 0); + if (zap_test_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE) || susp) { + zap_mutex_lock(span->channels[j]->mutex); + zap_clear_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); + if (susp && span->channels[j]->state != ZAP_CHANNEL_STATE_DOWN) { + zap_channel_set_state(span->channels[j], ZAP_CHANNEL_STATE_RESTART, 0); } - state_advance(&span->channels[j]); - zap_channel_complete_state(&span->channels[j]); - zap_mutex_unlock(span->channels[j].mutex); + state_advance(span->channels[j]); + zap_channel_complete_state(span->channels[j]); + zap_mutex_unlock(span->channels[j]->mutex); } } } diff --git a/libs/freetdm/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c b/libs/freetdm/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c index 19d74cdb19..e4f2023786 100644 --- a/libs/freetdm/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c +++ b/libs/freetdm/src/ozmod/ozmod_wanpipe/ozmod_wanpipe.c @@ -728,9 +728,9 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) int r; for(i = 1; i <= span->chan_count; i++) { - zap_channel_t *zchan = &span->channels[i]; + zap_channel_t *zchan = span->channels[i]; memset(&pfds[j], 0, sizeof(pfds[j])); - pfds[j].fd = span->channels[i].sockfd; + pfds[j].fd = span->channels[i]->sockfd; pfds[j].events = POLLPRI; /* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */ @@ -787,7 +787,7 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) } for(i = 1; i <= span->chan_count; i++) { - zap_channel_t *zchan = &span->channels[i]; + zap_channel_t *zchan = span->channels[i]; if (pfds[i-1].revents & POLLPRI) { zap_set_flag(zchan, ZAP_CHANNEL_EVENT); @@ -809,45 +809,45 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) zap_oob_event_t event_id; for(i = 1; i <= span->chan_count; i++) { - if (span->channels[i].last_event_time && !zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { - uint32_t diff = (uint32_t)(zap_current_time_in_ms() - span->channels[i].last_event_time); - /* XX printf("%u %u %u\n", diff, (unsigned)zap_current_time_in_ms(), (unsigned)span->channels[i].last_event_time); */ - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK)) { + if (span->channels[i]->last_event_time && !zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) { + uint32_t diff = (uint32_t)(zap_current_time_in_ms() - span->channels[i]->last_event_time); + /* XX printf("%u %u %u\n", diff, (unsigned)zap_current_time_in_ms(), (unsigned)span->channels[i]->last_event_time); */ + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_WINK)) { if (diff > wp_globals.wink_ms) { - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); - zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_WINK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH); + zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_OFFHOOK; goto event; } } - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) { + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_FLASH)) { if (diff > wp_globals.flash_ms) { - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_WINK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_ONHOOK; - if (span->channels[i].type == ZAP_CHAN_TYPE_FXO) { + if (span->channels[i]->type == ZAP_CHAN_TYPE_FXO) { wanpipe_tdm_api_t tdm_api; memset(&tdm_api, 0, sizeof(tdm_api)); tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK; tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; - wp_tdm_cmd_exec(&span->channels[i], &tdm_api); + wp_tdm_cmd_exec(span->channels[i], &tdm_api); } goto event; } } } - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) { wanpipe_tdm_api_t tdm_api; memset(&tdm_api, 0, sizeof(tdm_api)); - zap_clear_flag((&span->channels[i]), ZAP_CHANNEL_EVENT); + zap_clear_flag(span->channels[i], ZAP_CHANNEL_EVENT); tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT; - if (wp_tdm_cmd_exec(&span->channels[i], &tdm_api) != ZAP_SUCCESS) { + if (wp_tdm_cmd_exec(span->channels[i], &tdm_api) != ZAP_SUCCESS) { snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); return ZAP_FAIL; } @@ -855,25 +855,25 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) { case WP_TDMAPI_EVENT_RXHOOK: { - if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) { + if (span->channels[i]->type == ZAP_CHAN_TYPE_FXS) { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? ZAP_OOB_OFFHOOK : ZAP_OOB_ONHOOK; if (event_id == ZAP_OOB_OFFHOOK) { - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) { - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_FLASH)) { + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_WINK); event_id = ZAP_OOB_FLASH; goto event; } else { - zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); + zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_WINK); } } else { - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK)) { - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); - zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_WINK)) { + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_WINK); + zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH); event_id = ZAP_OOB_WINK; goto event; } else { - zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); + zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH); } } continue; @@ -883,8 +883,8 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT; tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK; tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; - if ((err = wp_tdm_cmd_exec(&span->channels[i], &tdm_api))) { - snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "ONHOOK Failed"); + if ((err = wp_tdm_cmd_exec(span->channels[i], &tdm_api))) { + snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "ONHOOK Failed"); return ZAP_FAIL; } event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? ZAP_OOB_ONHOOK : ZAP_OOB_NOOP; @@ -911,10 +911,10 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) event: - span->channels[i].last_event_time = 0; + span->channels[i]->last_event_time = 0; span->event_header.e_type = ZAP_EVENT_OOB; span->event_header.enum_id = event_id; - span->event_header.channel = &span->channels[i]; + span->event_header.channel = span->channels[i]; *event = &span->event_header; return ZAP_SUCCESS; } diff --git a/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.c b/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.c index 4b271ed6f5..a739300d1b 100644 --- a/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.c +++ b/libs/freetdm/src/ozmod/ozmod_zt/ozmod_zt.c @@ -571,7 +571,7 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) for(i = 1; i <= span->chan_count; i++) { memset(&pfds[j], 0, sizeof(pfds[j])); - pfds[j].fd = span->channels[i].sockfd; + pfds[j].fd = span->channels[i]->sockfd; pfds[j].events = POLLPRI; j++; } @@ -587,8 +587,8 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) for(i = 1; i <= span->chan_count; i++) { if (pfds[i-1].revents & POLLPRI) { - zap_set_flag((&span->channels[i]), ZAP_CHANNEL_EVENT); - span->channels[i].last_event_time = zap_current_time_in_ms(); + zap_set_flag(span->channels[i], ZAP_CHANNEL_EVENT); + span->channels[i]->last_event_time = zap_current_time_in_ms(); k++; } } @@ -606,9 +606,9 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) zap_oob_event_t zt_event_id = 0; for(i = 1; i <= span->chan_count; i++) { - if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { - zap_clear_flag((&span->channels[i]), ZAP_CHANNEL_EVENT); - if (ioctl(span->channels[i].sockfd, ZT_GETEVENT, &zt_event_id) == -1) { + if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) { + zap_clear_flag(span->channels[i], ZAP_CHANNEL_EVENT); + if (ioctl(span->channels[i]->sockfd, ZT_GETEVENT, &zt_event_id) == -1) { snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); return ZAP_FAIL; } @@ -636,7 +636,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) break; case ZT_EVENT_WINKFLASH: { - if (span->channels[i].state == ZAP_CHANNEL_STATE_DOWN) { + if (span->channels[i]->state == ZAP_CHANNEL_STATE_DOWN) { event_id = ZAP_OOB_WINK; } else { event_id = ZAP_OOB_FLASH; @@ -645,10 +645,10 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) break; case ZT_EVENT_RINGOFFHOOK: { - if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) { - zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); + if (span->channels[i]->type == ZAP_CHAN_TYPE_FXS) { + zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_OFFHOOK; - } else if (span->channels[i].type == ZAP_CHAN_TYPE_FXO) { + } else if (span->channels[i]->type == ZAP_CHAN_TYPE_FXO) { event_id = ZAP_OOB_RING_START; } } @@ -671,10 +671,10 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) break; } - span->channels[i].last_event_time = 0; + span->channels[i]->last_event_time = 0; span->event_header.e_type = ZAP_EVENT_OOB; span->event_header.enum_id = event_id; - span->event_header.channel = &span->channels[i]; + span->event_header.channel = span->channels[i]; *event = &span->event_header; return ZAP_SUCCESS; } diff --git a/libs/freetdm/src/testanalog.c b/libs/freetdm/src/testanalog.c index d816edb3be..274228dea0 100644 --- a/libs/freetdm/src/testanalog.c +++ b/libs/freetdm/src/testanalog.c @@ -98,16 +98,18 @@ int main(int argc, char *argv[]) if (zap_configure_span("analog", span, on_signal, - "tonemap", "te", + "tonemap", "us", "digit_timeout", &digit_timeout, "max_dialstr", &max_dialstr, TAG_END - ) == ZAP_SUCCESS) { + ) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Error configuring OpenZAP span\n"); goto done; } zap_span_start(span); + R = 1; + while(zap_running() && R) { zap_sleep(1 * 1000); } diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 67a9ae690f..69b920c3f1 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -77,7 +77,7 @@ static struct { zap_hash_t *interface_hash; zap_hash_t *module_hash; zap_mutex_t *mutex; - struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; + struct zap_span *spans[ZAP_MAX_SPANS_INTERFACE+1]; uint32_t span_index; uint32_t running; } globals; @@ -306,7 +306,13 @@ zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span) zap_mutex_lock(globals.mutex); if (globals.span_index < ZAP_MAX_SPANS_INTERFACE) { - new_span = &globals.spans[++globals.span_index]; + 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; + } memset(new_span, 0, sizeof(*new_span)); status = zap_mutex_create(&new_span->mutex); if (status != ZAP_SUCCESS) { @@ -337,10 +343,10 @@ zap_status_t zap_span_close_all(void) zap_mutex_lock(globals.mutex); for(i = 1; i <= globals.span_index; i++) { - span = &globals.spans[i]; + span = globals.spans[i]; if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { - for(j = 0; j <= span->chan_count; j++) { - zap_channel_destroy(&span->channels[j]); + for(j = 0; j <= span->chan_count && span->channels[j]; j++) { + zap_channel_destroy(span->channels[j]); } } } @@ -416,8 +422,15 @@ zap_status_t zap_span_load_tones(zap_span_t *span, const char *mapname) zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan) { if (span->chan_count < ZAP_MAX_CHANNELS_SPAN) { - zap_channel_t *new_chan; - new_chan = &span->channels[++span->chan_count]; + zap_channel_t *new_chan = span->channels[++span->chan_count]; + + if (!new_chan) { + if (!(new_chan = malloc(sizeof(*new_chan)))) { + return ZAP_FAIL; + } + span->channels[span->chan_count] = new_chan; + } + new_chan->type = type; new_chan->sockfd = sockfd; new_chan->zio = span->zio; @@ -455,10 +468,10 @@ zap_status_t zap_span_find(uint32_t id, zap_span_t **span) } zap_mutex_lock(globals.mutex); - fspan = &globals.spans[id]; + fspan = globals.spans[id]; zap_mutex_unlock(globals.mutex); - if (!zap_test_flag(fspan, ZAP_SPAN_CONFIGURED)) { + if (!fspan || !zap_test_flag(fspan, ZAP_SPAN_CONFIGURED)) { return ZAP_FAIL; } @@ -799,14 +812,14 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z return ZAP_FAIL; } - if (globals.spans[span_id].active_count >= globals.spans[span_id].chan_count) { + if (globals.spans[span_id]->active_count >= globals.spans[span_id]->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 (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); } span_max = span_id; @@ -831,7 +844,7 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z } } - span = &globals.spans[j]; + span = globals.spans[j]; zap_mutex_lock(span->mutex); if (!zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { @@ -856,7 +869,7 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z } } - check = &span->channels[i]; + check = span->channels[i]; if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_INUSE) && @@ -864,8 +877,8 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z check->state == ZAP_CHANNEL_STATE_DOWN ) { - if (globals.spans[span_id].channel_request) { - status = globals.spans[span_id].channel_request(&globals.spans[span_id], i, direction, caller_data, zchan); + if (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; } @@ -992,12 +1005,12 @@ zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t if (span_id < ZAP_MAX_SPANS_INTERFACE && chan_id < ZAP_MAX_CHANNELS_SPAN) { zap_channel_t *check; - if (globals.spans[span_id].channel_request) { + if (globals.spans[span_id]->channel_request) { zap_log(ZAP_LOG_ERROR, "Individual channel selection not implemented on this span.\n"); goto done; } - check = &globals.spans[span_id].channels[chan_id]; + check = globals.spans[span_id]->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) { @@ -2343,29 +2356,38 @@ zap_status_t zap_global_destroy(void) zap_sleep(1000); for(i = 1; i <= globals.span_index; i++) { - zap_span_t *cur_span = &globals.spans[i]; + zap_span_t *cur_span = globals.spans[i]; - if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { - zap_mutex_lock(cur_span->mutex); - zap_clear_flag(cur_span, ZAP_SPAN_CONFIGURED); - for(j = 1; j <= cur_span->chan_count; j++) { - zap_channel_t *cur_chan = &cur_span->channels[j]; - if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) { - zap_channel_destroy(cur_chan); + if (cur_span) { + if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { + zap_mutex_lock(cur_span->mutex); + zap_clear_flag(cur_span, ZAP_SPAN_CONFIGURED); + for(j = 1; j <= cur_span->chan_count && cur_span->channels[j]; j++) { + zap_channel_t *cur_chan = cur_span->channels[j]; + if (cur_chan) { + if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) { + zap_channel_destroy(cur_chan); + } + free(cur_chan); + cur_chan = NULL; + } } + zap_mutex_unlock(cur_span->mutex); + + if (cur_span->mutex) { + zap_mutex_destroy(&cur_span->mutex); + } + + zap_safe_free(cur_span->signal_data); + zap_span_destroy(cur_span); } - zap_mutex_unlock(cur_span->mutex); - - if (cur_span->mutex) { - zap_mutex_destroy(&cur_span->mutex); - } - - zap_safe_free(cur_span->signal_data); - zap_span_destroy(cur_span); - + zap_safe_free(cur_span->type); + free(cur_span); + cur_span = NULL; } } - + globals.span_index = 0; + zap_unload_modules(); zap_mutex_lock(globals.mutex); diff --git a/libs/freetdm/src/zap_m3ua.c b/libs/freetdm/src/zap_m3ua.c index c54e533eab..50736b75e4 100644 --- a/libs/freetdm/src/zap_m3ua.c +++ b/libs/freetdm/src/zap_m3ua.c @@ -689,4 +689,4 @@ zap_status_t m3ua_start(zap_span_t *span) * tab-width:4 * c-basic-offset:4 * End: -*/ \ No newline at end of file +*/