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
This commit is contained in:
Anthony Minessale 2008-09-10 15:25:02 +00:00
parent 11e185ee8e
commit fa8457c019
10 changed files with 192 additions and 167 deletions

View File

@ -1768,21 +1768,21 @@ void dump_chan(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *strea
"dnis: %s\n" "dnis: %s\n"
"rdnis: %s\n" "rdnis: %s\n"
"cause: %s\n\n", "cause: %s\n\n",
span->channels[chan_id].span_id, span->channels[chan_id]->span_id,
span->channels[chan_id].chan_id, span->channels[chan_id]->chan_id,
span->channels[chan_id].physical_span_id, span->channels[chan_id]->physical_span_id,
span->channels[chan_id].physical_chan_id, span->channels[chan_id]->physical_chan_id,
zap_chan_type2str(span->channels[chan_id].type), zap_chan_type2str(span->channels[chan_id]->type),
zap_channel_state2str(span->channels[chan_id].state), zap_channel_state2str(span->channels[chan_id]->state),
zap_channel_state2str(span->channels[chan_id].last_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_date,
span->channels[chan_id].caller_data.cid_name, span->channels[chan_id]->caller_data.cid_name,
span->channels[chan_id].caller_data.cid_num.digits, span->channels[chan_id]->caller_data.cid_num.digits,
span->channels[chan_id].caller_data.ani.digits, span->channels[chan_id]->caller_data.ani.digits,
span->channels[chan_id].caller_data.aniII, span->channels[chan_id]->caller_data.aniII,
span->channels[chan_id].caller_data.dnis.digits, span->channels[chan_id]->caller_data.dnis.digits,
span->channels[chan_id].caller_data.rdnis.digits, span->channels[chan_id]->caller_data.rdnis.digits,
switch_channel_cause2str(span->channels[chan_id].caller_data.hangup_cause) switch_channel_cause2str(span->channels[chan_id]->caller_data.hangup_cause)
); );
} }

View File

@ -153,7 +153,7 @@
#define ZAP_MAX_CHANNELS_PHYSICAL_SPAN 32 #define ZAP_MAX_CHANNELS_PHYSICAL_SPAN 32
#define ZAP_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN 16 #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_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 ; #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]; char tone_map[ZAP_TONEMAP_INVALID+1][ZAP_TONEMAP_LEN];
teletone_tone_map_t tone_detect_map[ZAP_TONEMAP_INVALID+1]; teletone_tone_map_t tone_detect_map[ZAP_TONEMAP_INVALID+1];
teletone_multi_tone_t tone_finder[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_outgoing_call_t outgoing_call;
zio_channel_request_t channel_request; zio_channel_request_t channel_request;
zap_span_start_t start; 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; uint32_t j;
zap_mutex_lock(span->mutex); zap_mutex_lock(span->mutex);
for(j = 1; j <= span->chan_count; j++) { 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); 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; uint32_t j;
for(j = 1; j <= span->chan_count; 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; return 0;
} }
} }
@ -632,7 +632,7 @@ static __inline__ void zap_set_flag_all(zap_span_t *span, uint32_t flag)
uint32_t j; uint32_t j;
zap_mutex_lock(span->mutex); zap_mutex_lock(span->mutex);
for(j = 1; j <= span->chan_count; j++) { 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); zap_mutex_unlock(span->mutex);
} }

View File

@ -81,7 +81,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
/* /*
* get codec type * 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 * Q.931 Setup Message
@ -198,7 +198,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
new_chan = NULL; new_chan = NULL;
if (caller_data->chan_id < ZAP_MAX_CHANNELS_SPAN && caller_data->chan_id <= span->chan_count) { 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)) { 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: case Q931mes_RESTART:
{ {
if (chan_id) { if (chan_id) {
zchan = &span->channels[chan_id]; zchan = span->channels[chan_id];
} }
if (zchan) { if (zchan) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART);
} else { } else {
uint32_t i; uint32_t i;
for (i = 0; i < span->chan_count; 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 * try to find a free channel
*/ */
for (x = 1; x <= span->chan_count; x++) { 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) { if (!zap_test_flag(zc, ZAP_CHANNEL_INUSE) && zc->state == ZAP_CHANNEL_STATE_DOWN) {
zchan = zc; 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 * by the TE side is already in use
*/ */
if (chan_id > 0 && chan_id < ZAP_MAX_CHANNELS_SPAN && chan_id <= span->chan_count) { 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 { else {
/* invalid channel id */ /* invalid channel id */
@ -939,7 +939,7 @@ static __inline__ void state_advance(zap_channel_t *zchan)
/* /*
* get codec type * 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 * Q.931 Setup Message
@ -1125,12 +1125,12 @@ static __inline__ void check_state(zap_span_t *span)
uint32_t j; uint32_t j;
zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE); zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) { for(j = 1; j <= span->chan_count; j++) {
if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) { if (zap_test_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE)) {
zap_mutex_lock(span->channels[j].mutex); zap_mutex_lock(span->channels[j]->mutex);
zap_clear_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); zap_clear_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE);
state_advance(&span->channels[j]); state_advance(span->channels[j]);
zap_channel_complete_state(&span->channels[j]); zap_channel_complete_state(span->channels[j]);
zap_mutex_unlock(span->channels[j].mutex); 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 */ /* get a tone generation friendly interval to avoid distortions */
for (x = 1; x <= span->chan_count; x++) { for (x = 1; x <= span->chan_count; x++) {
if (span->channels[x].type != ZAP_CHAN_TYPE_DQ921) { if (span->channels[x]->type != ZAP_CHAN_TYPE_DQ921) {
zap_channel_command(&span->channels[x], ZAP_COMMAND_GET_INTERVAL, &interval); zap_channel_command(span->channels[x], ZAP_COMMAND_GET_INTERVAL, &interval);
break; 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 * check b-channel states and generate & send tones if neccessary
*/ */
for (x = 1; x <= span->chan_count; x++) { 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; zap_size_t len = sizeof(frame), rlen;
if (zchan->type == ZAP_CHAN_TYPE_DQ921) { if (zchan->type == ZAP_CHAN_TYPE_DQ921) {
@ -1389,6 +1389,7 @@ done:
} }
zap_log(ZAP_LOG_DEBUG, "ISDN tone thread ended.\n"); zap_log(ZAP_LOG_DEBUG, "ISDN tone thread ended.\n");
return NULL; return NULL;
} }
@ -1697,7 +1698,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
} }
for(i = 1; i <= span->chan_count; i++) { 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) { if (x > 1) {
snprintf(span->last_error, sizeof(span->last_error), "Span has more than 2 D-Channels!"); snprintf(span->last_error, sizeof(span->last_error), "Span has more than 2 D-Channels!");
return ZAP_FAIL; return ZAP_FAIL;

View File

@ -945,7 +945,7 @@ static ZIO_SPAN_POLL_EVENT_FUNCTION(pika_poll_event)
zap_channel_t *zchan; zap_channel_t *zchan;
pika_chan_data_t *chan_data; pika_chan_data_t *chan_data;
for(x = 1; x <= span->chan_count; x++) { for(x = 1; x <= span->chan_count; x++) {
zchan = &span->channels[x]; zchan = span->channels[x];
assert(zchan != NULL); assert(zchan != NULL);
chan_data = (pika_chan_data_t *) zchan->mod_data; chan_data = (pika_chan_data_t *) zchan->mod_data;
assert(chan_data != NULL); assert(chan_data != NULL);
@ -983,11 +983,11 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event)
uint32_t i, event_id = 0; uint32_t i, event_id = 0;
for(i = 1; i <= span->chan_count; i++) { for(i = 1; i <= span->chan_count; i++) {
if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { 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; pika_chan_data_t *chan_data = (pika_chan_data_t *) span->channels[i]->mod_data;
PK_CHAR event_text[PKH_EVENT_MAX_NAME_LENGTH]; 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)); 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; break;
case PKH_EVENT_PHONE_OFFHOOK: 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; event_id = ZAP_OOB_OFFHOOK;
break; break;
case PKH_EVENT_TRUNK_BELOW_THRESHOLD: case PKH_EVENT_TRUNK_BELOW_THRESHOLD:
case PKH_EVENT_TRUNK_ABOVE_THRESHOLD: case PKH_EVENT_TRUNK_ABOVE_THRESHOLD:
case PKH_EVENT_PHONE_ONHOOK: 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; event_id = ZAP_OOB_ONHOOK;
break; break;
case PKH_EVENT_SPAN_ALARM_T1_RED: case PKH_EVENT_SPAN_ALARM_T1_RED:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_T1_YELLOW: case PKH_EVENT_SPAN_ALARM_T1_YELLOW:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "YELLOW ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_T1_AIS: case PKH_EVENT_SPAN_ALARM_T1_AIS:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_E1_RED: case PKH_EVENT_SPAN_ALARM_E1_RED:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RED ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_E1_RAI: case PKH_EVENT_SPAN_ALARM_E1_RAI:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "RAI ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_E1_AIS: case PKH_EVENT_SPAN_ALARM_E1_AIS:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "AIS ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_E1_RMAI: 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_LOSS_OF_SIGNAL:
case PKH_EVENT_SPAN_OUT_OF_CRC_MF_SYNC: case PKH_EVENT_SPAN_OUT_OF_CRC_MF_SYNC:
case PKH_EVENT_SPAN_OUT_OF_CAS_MF_SYNC: case PKH_EVENT_SPAN_OUT_OF_CAS_MF_SYNC:
zap_set_alarm_flag((&span->channels[i]), ZAP_ALARM_GENERAL); zap_set_alarm_flag(span->channels[i], ZAP_ALARM_GENERAL);
snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "GENERAL ALARM"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "GENERAL ALARM");
event_id = ZAP_OOB_ALARM_TRAP; event_id = ZAP_OOB_ALARM_TRAP;
break; break;
case PKH_EVENT_SPAN_ALARM_T1_RED_CLEAR: 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: 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: 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: 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: 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: 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_RMAI_CLEAR:
case PKH_EVENT_SPAN_ALARM_E1_TS16AIS_CLEAR: case PKH_EVENT_SPAN_ALARM_E1_TS16AIS_CLEAR:
case PKH_EVENT_SPAN_ALARM_E1_TS16LOS_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_LOSS_OF_SIGNAL_CLEAR:
case PKH_EVENT_SPAN_IN_CRC_MF_SYNC: case PKH_EVENT_SPAN_IN_CRC_MF_SYNC:
case PKH_EVENT_SPAN_IN_CAS_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; event_id = ZAP_OOB_ALARM_CLEAR;
break; break;
case PKH_EVENT_SPAN_MESSAGE: case PKH_EVENT_SPAN_MESSAGE:
@ -1104,10 +1104,10 @@ static ZIO_SPAN_NEXT_EVENT_FUNCTION(pika_next_event)
break; 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.e_type = ZAP_EVENT_OOB;
span->event_header.enum_id = event_id; 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; *event = &span->event_header;
return ZAP_SUCCESS; return ZAP_SUCCESS;
} }

View File

@ -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); zap_mutex_lock(signal_mutex);
for(i = 0; i <= span->chan_count; i++) { 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) { if (span->channels[i]->physical_span_id == event->span+1 && span->channels[i]->physical_chan_id == event->chan+1) {
zchan = &span->channels[i]; zchan = span->channels[i];
if (force) { if (force) {
break; 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) { if (zchan->state == ZAP_CHANNEL_STATE_DOWN || zchan->state >= ZAP_CHANNEL_STATE_TERMINATING) {
int x = 0; int x = 0;
zap_log(ZAP_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n", 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]->span_id,
span->channels[i].chan_id, span->channels[i]->chan_id,
span->channels[i].physical_span_id, span->channels[i]->physical_span_id,
span->channels[i].physical_chan_id); span->channels[i]->physical_chan_id);
zap_mutex_unlock(signal_mutex); zap_mutex_unlock(signal_mutex);
for (x = 0; x < 200; x++) { 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)) { if (zap_test_flag(zchan, ZAP_CHANNEL_INUSE)) {
zchan = NULL; zchan = NULL;
zap_log(ZAP_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n", zap_log(ZAP_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
span->channels[i].span_id, span->channels[i]->span_id,
span->channels[i].chan_id, span->channels[i]->chan_id,
span->channels[i].physical_span_id, span->channels[i]->physical_span_id,
span->channels[i].physical_chan_id span->channels[i]->physical_chan_id
); );
} }
} }
@ -811,15 +811,15 @@ static __inline__ void check_state(zap_span_t *span)
uint32_t j; uint32_t j;
zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE); zap_clear_flag_locked(span, ZAP_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) { for(j = 1; j <= span->chan_count; j++) {
if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE) || susp) { if (zap_test_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE) || susp) {
zap_mutex_lock(span->channels[j].mutex); zap_mutex_lock(span->channels[j]->mutex);
zap_clear_flag((&span->channels[j]), ZAP_CHANNEL_STATE_CHANGE); zap_clear_flag((span->channels[j]), ZAP_CHANNEL_STATE_CHANGE);
if (susp && span->channels[j].state != ZAP_CHANNEL_STATE_DOWN) { if (susp && span->channels[j]->state != ZAP_CHANNEL_STATE_DOWN) {
zap_channel_set_state(&span->channels[j], ZAP_CHANNEL_STATE_RESTART, 0); zap_channel_set_state(span->channels[j], ZAP_CHANNEL_STATE_RESTART, 0);
} }
state_advance(&span->channels[j]); state_advance(span->channels[j]);
zap_channel_complete_state(&span->channels[j]); zap_channel_complete_state(span->channels[j]);
zap_mutex_unlock(span->channels[j].mutex); zap_mutex_unlock(span->channels[j]->mutex);
} }
} }
} }

View File

@ -728,9 +728,9 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
int r; int r;
for(i = 1; i <= span->chan_count; i++) { 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])); 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; 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! */ /* 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++) { 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) { if (pfds[i-1].revents & POLLPRI) {
zap_set_flag(zchan, ZAP_CHANNEL_EVENT); 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; zap_oob_event_t event_id;
for(i = 1; i <= span->chan_count; i++) { for(i = 1; i <= span->chan_count; i++) {
if (span->channels[i].last_event_time && !zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { 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); 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); */ /* 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 (zap_test_flag(span->channels[i], ZAP_CHANNEL_WINK)) {
if (diff > wp_globals.wink_ms) { 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_WINK);
zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH);
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; event_id = ZAP_OOB_OFFHOOK;
goto event; 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) { 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_FLASH);
zap_clear_flag_locked((&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_OFFHOOK); zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_OFFHOOK);
event_id = ZAP_OOB_ONHOOK; 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; wanpipe_tdm_api_t tdm_api;
memset(&tdm_api, 0, sizeof(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.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_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; 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; 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; wanpipe_tdm_api_t tdm_api;
memset(&tdm_api, 0, sizeof(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; 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)); snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
return ZAP_FAIL; 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) { switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
case WP_TDMAPI_EVENT_RXHOOK: 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; 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 (event_id == ZAP_OOB_OFFHOOK) {
if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) { 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_FLASH);
zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_WINK);
event_id = ZAP_OOB_FLASH; event_id = ZAP_OOB_FLASH;
goto event; goto event;
} else { } else {
zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_WINK);
} }
} else { } else {
if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK)) { 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_WINK);
zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); zap_clear_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH);
event_id = ZAP_OOB_WINK; event_id = ZAP_OOB_WINK;
goto event; goto event;
} else { } else {
zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); zap_set_flag_locked(span->channels[i], ZAP_CHANNEL_FLASH);
} }
} }
continue; 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.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_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE; 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))) { 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"); snprintf(span->channels[i]->last_error, sizeof(span->channels[i]->last_error), "ONHOOK Failed");
return ZAP_FAIL; 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; 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: 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.e_type = ZAP_EVENT_OOB;
span->event_header.enum_id = event_id; 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; *event = &span->event_header;
return ZAP_SUCCESS; return ZAP_SUCCESS;
} }

View File

@ -571,7 +571,7 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
for(i = 1; i <= span->chan_count; i++) { for(i = 1; i <= span->chan_count; i++) {
memset(&pfds[j], 0, sizeof(pfds[j])); 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; pfds[j].events = POLLPRI;
j++; j++;
} }
@ -587,8 +587,8 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
for(i = 1; i <= span->chan_count; i++) { for(i = 1; i <= span->chan_count; i++) {
if (pfds[i-1].revents & POLLPRI) { if (pfds[i-1].revents & POLLPRI) {
zap_set_flag((&span->channels[i]), ZAP_CHANNEL_EVENT); zap_set_flag(span->channels[i], ZAP_CHANNEL_EVENT);
span->channels[i].last_event_time = zap_current_time_in_ms(); span->channels[i]->last_event_time = zap_current_time_in_ms();
k++; k++;
} }
} }
@ -606,9 +606,9 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
zap_oob_event_t zt_event_id = 0; zap_oob_event_t zt_event_id = 0;
for(i = 1; i <= span->chan_count; i++) { for(i = 1; i <= span->chan_count; i++) {
if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) { if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) {
zap_clear_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 (ioctl(span->channels[i]->sockfd, ZT_GETEVENT, &zt_event_id) == -1) {
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
return ZAP_FAIL; return ZAP_FAIL;
} }
@ -636,7 +636,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
break; break;
case ZT_EVENT_WINKFLASH: 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; event_id = ZAP_OOB_WINK;
} else { } else {
event_id = ZAP_OOB_FLASH; event_id = ZAP_OOB_FLASH;
@ -645,10 +645,10 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
break; break;
case ZT_EVENT_RINGOFFHOOK: case ZT_EVENT_RINGOFFHOOK:
{ {
if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) { if (span->channels[i]->type == ZAP_CHAN_TYPE_FXS) {
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; 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; event_id = ZAP_OOB_RING_START;
} }
} }
@ -671,10 +671,10 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
break; 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.e_type = ZAP_EVENT_OOB;
span->event_header.enum_id = event_id; 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; *event = &span->event_header;
return ZAP_SUCCESS; return ZAP_SUCCESS;
} }

View File

@ -98,16 +98,18 @@ int main(int argc, char *argv[])
if (zap_configure_span("analog", span, on_signal, if (zap_configure_span("analog", span, on_signal,
"tonemap", "te", "tonemap", "us",
"digit_timeout", &digit_timeout, "digit_timeout", &digit_timeout,
"max_dialstr", &max_dialstr, "max_dialstr", &max_dialstr,
TAG_END TAG_END
) == ZAP_SUCCESS) { ) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Error configuring OpenZAP span\n"); zap_log(ZAP_LOG_ERROR, "Error configuring OpenZAP span\n");
goto done; goto done;
} }
zap_span_start(span); zap_span_start(span);
R = 1;
while(zap_running() && R) { while(zap_running() && R) {
zap_sleep(1 * 1000); zap_sleep(1 * 1000);
} }

View File

@ -77,7 +77,7 @@ static struct {
zap_hash_t *interface_hash; zap_hash_t *interface_hash;
zap_hash_t *module_hash; zap_hash_t *module_hash;
zap_mutex_t *mutex; 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 span_index;
uint32_t running; uint32_t running;
} globals; } 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); zap_mutex_lock(globals.mutex);
if (globals.span_index < ZAP_MAX_SPANS_INTERFACE) { 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)); memset(new_span, 0, sizeof(*new_span));
status = zap_mutex_create(&new_span->mutex); status = zap_mutex_create(&new_span->mutex);
if (status != ZAP_SUCCESS) { if (status != ZAP_SUCCESS) {
@ -337,10 +343,10 @@ zap_status_t zap_span_close_all(void)
zap_mutex_lock(globals.mutex); zap_mutex_lock(globals.mutex);
for(i = 1; i <= globals.span_index; i++) { for(i = 1; i <= globals.span_index; i++) {
span = &globals.spans[i]; span = globals.spans[i];
if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
for(j = 0; j <= span->chan_count; j++) { for(j = 0; j <= span->chan_count && span->channels[j]; j++) {
zap_channel_destroy(&span->channels[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) 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) { if (span->chan_count < ZAP_MAX_CHANNELS_SPAN) {
zap_channel_t *new_chan; zap_channel_t *new_chan = span->channels[++span->chan_count];
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->type = type;
new_chan->sockfd = sockfd; new_chan->sockfd = sockfd;
new_chan->zio = span->zio; 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); zap_mutex_lock(globals.mutex);
fspan = &globals.spans[id]; fspan = globals.spans[id];
zap_mutex_unlock(globals.mutex); 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; 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; 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"); zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
*zchan = NULL; *zchan = NULL;
return ZAP_FAIL; return ZAP_FAIL;
} }
if (globals.spans[span_id].channel_request && !globals.spans[span_id].suggest_chan_id) { 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); return globals.spans[span_id]->channel_request(globals.spans[span_id], 0, direction, caller_data, zchan);
} }
span_max = span_id; 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); zap_mutex_lock(span->mutex);
if (!zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { 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) && if (zap_test_flag(check, ZAP_CHANNEL_READY) &&
!zap_test_flag(check, ZAP_CHANNEL_INUSE) && !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 check->state == ZAP_CHANNEL_STATE_DOWN
) { ) {
if (globals.spans[span_id].channel_request) { if (globals.spans[span_id]->channel_request) {
status = globals.spans[span_id].channel_request(&globals.spans[span_id], i, direction, caller_data, zchan); status = globals.spans[span_id]->channel_request(globals.spans[span_id], i, direction, caller_data, zchan);
zap_mutex_unlock(span->mutex); zap_mutex_unlock(span->mutex);
goto done; 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) { if (span_id < ZAP_MAX_SPANS_INTERFACE && chan_id < ZAP_MAX_CHANNELS_SPAN) {
zap_channel_t *check; 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"); zap_log(ZAP_LOG_ERROR, "Individual channel selection not implemented on this span.\n");
goto done; 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) || if (zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) ||
!zap_test_flag(check, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { !zap_test_flag(check, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) {
@ -2343,16 +2356,21 @@ zap_status_t zap_global_destroy(void)
zap_sleep(1000); zap_sleep(1000);
for(i = 1; i <= globals.span_index; i++) { 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 (cur_span) {
if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) {
zap_mutex_lock(cur_span->mutex); zap_mutex_lock(cur_span->mutex);
zap_clear_flag(cur_span, ZAP_SPAN_CONFIGURED); zap_clear_flag(cur_span, ZAP_SPAN_CONFIGURED);
for(j = 1; j <= cur_span->chan_count; j++) { for(j = 1; j <= cur_span->chan_count && cur_span->channels[j]; j++) {
zap_channel_t *cur_chan = &cur_span->channels[j]; zap_channel_t *cur_chan = cur_span->channels[j];
if (cur_chan) {
if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) { if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) {
zap_channel_destroy(cur_chan); zap_channel_destroy(cur_chan);
} }
free(cur_chan);
cur_chan = NULL;
}
} }
zap_mutex_unlock(cur_span->mutex); zap_mutex_unlock(cur_span->mutex);
@ -2362,9 +2380,13 @@ zap_status_t zap_global_destroy(void)
zap_safe_free(cur_span->signal_data); zap_safe_free(cur_span->signal_data);
zap_span_destroy(cur_span); 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_unload_modules();