diff --git a/libs/freetdm/src/include/zap_types.h b/libs/freetdm/src/include/zap_types.h index 818fed2af8..4055b0c931 100644 --- a/libs/freetdm/src/include/zap_types.h +++ b/libs/freetdm/src/include/zap_types.h @@ -277,6 +277,7 @@ typedef enum { ZAP_CHANNEL_STATE_DOWN, ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_HOLD, + ZAP_CHANNEL_STATE_SUSPENDED, ZAP_CHANNEL_STATE_DIALTONE, ZAP_CHANNEL_STATE_COLLECT, ZAP_CHANNEL_STATE_RING, @@ -294,7 +295,7 @@ typedef enum { ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_INVALID } zap_channel_state_t; -#define CHANNEL_STATE_STRINGS "DOWN", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \ +#define CHANNEL_STATE_STRINGS "DOWN", "HANGUP", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \ "RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \ "TERMINATING", "RESTART", "PROGRESS_MEDIA", "PROGRESS", "IDLE", "UP", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t) diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 77bd0ecc17..477bc8f04f 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -710,7 +710,7 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z check = &span->channels[i]; - if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_INUSE)) { + if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_INUSE) && !zap_test_flag(check, ZAP_CHANNEL_SUSPENDED)) { status = check->zio->open(check); @@ -787,6 +787,10 @@ zap_status_t zap_channel_open_chan(zap_channel_t *zchan) assert(zchan != NULL); + if (zap_test_flag(zchan, ZAP_CHANNEL_SUSPENDED)) { + return ZAP_FAIL; + } + if (!zap_test_flag(zchan, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(zchan->mutex)) != ZAP_SUCCESS) { return status; } @@ -815,7 +819,8 @@ zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t check = &globals.spans[span_id].channels[chan_id]; - if (!zap_test_flag(check, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { + if (zap_test_flag(check, ZAP_CHANNEL_SUSPENDED) || + !zap_test_flag(check, ZAP_CHANNEL_READY) || (status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { goto done; } diff --git a/libs/freetdm/src/zap_isdn.c b/libs/freetdm/src/zap_isdn.c index 8a3a14dd3d..af4f89d41f 100644 --- a/libs/freetdm/src/zap_isdn.c +++ b/libs/freetdm/src/zap_isdn.c @@ -85,17 +85,29 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen) case Q931mes_SERVICE: { Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf); - /* TODO: Handle this properly */ if (zchan) { switch (changestatus->NewStatus) { case 0: /* change status to "in service" */ - //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); - break; + zap_clear_flag_locked(zchan, ZAP_CHANNEL_SUSPENDED); + zap_log(ZAP_LOG_DEBUG, "Channel %d:%d in service\n", zchan->span_id, zchan->chan_id); + switch(zchan->state) { + case ZAP_CHANNEL_STATE_UP: + case ZAP_CHANNEL_STATE_IDLE: + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_TERMINATING); + break; + case ZAP_CHANNEL_STATE_DOWN: + break; + default: + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); + break; + } case 1: /* change status to "maintenance" */ - //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + zap_set_flag_locked(zchan, ZAP_CHANNEL_SUSPENDED); + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_SUSPENDED); break; case 2: /* change status to "out of service" */ - //zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RESTART); + zap_set_flag_locked(zchan, ZAP_CHANNEL_SUSPENDED); + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_SUSPENDED); break; default: /* unknown */ break;