From 7b7256b55f76c16184a60d8179d6b29254d78926 Mon Sep 17 00:00:00 2001 From: Kapil Date: Mon, 6 Aug 2012 10:20:02 -0400 Subject: [PATCH] fixing issues --- libs/freetdm/mod_freetdm/tdm.c | 2 +- libs/freetdm/src/ftdm_io.c | 135 ++++++++++++++++++ libs/freetdm/src/include/freetdm.h | 2 + .../media_gateway_cmd_handler.c | 6 +- .../mod_media_gateway/media_gateway_xml.c | 4 +- 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/mod_freetdm/tdm.c b/libs/freetdm/mod_freetdm/tdm.c index af39c655f0..7f44b640a9 100644 --- a/libs/freetdm/mod_freetdm/tdm.c +++ b/libs/freetdm/mod_freetdm/tdm.c @@ -327,7 +327,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi channel = switch_core_session_get_channel(*new_session); - if (ftdm_channel_open(span_id, chan_id, &chan) != FTDM_SUCCESS) { + if (ftdm_raw_channel_open(span_id, chan_id, &chan) != FTDM_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n"); goto fail; } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 4e110df659..6bc5471e5a 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1892,6 +1892,130 @@ done: return status; } +static ftdm_status_t _ftdm_raw_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) +{ + ftdm_channel_t *check = NULL; + ftdm_span_t *span = NULL; + ftdm_channel_t *best_rated = NULL; + ftdm_status_t status = FTDM_FAIL; + int best_rate = 0; + + *ftdmchan = NULL; + + ftdm_mutex_lock(globals.mutex); + + ftdm_span_find(span_id, &span); + + if (!span) { + ftdm_log(FTDM_LOG_CRIT, "Could not find span!\n"); + goto done; + } + + if (!ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) { + ftdm_log(FTDM_LOG_CRIT, "Span %d is not configured\n", span_id); + goto done; + } + + if (span->channel_request) { + ftdm_log(FTDM_LOG_ERROR, "Individual channel selection not implemented on this span.\n"); + goto done; + } + + if (chan_id < 1 || chan_id > span->chan_count) { + ftdm_log(FTDM_LOG_ERROR, "Invalid channel %d to open in span %d\n", chan_id, span_id); + goto done; + } + + if (!(check = span->channels[chan_id])) { + ftdm_log(FTDM_LOG_CRIT, "Wow, no channel %d in span %d\n", chan_id, span_id); + goto done; + } + + ftdm_channel_lock(check); + + if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { + /* let them know is already open, but return the channel anyway */ + status = FTDM_EBUSY; + *ftdmchan = check; + goto unlockchan; + } + + /* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */ + + /* if it is not a voice channel, nothing else to check to open it */ + if (!FTDM_IS_VOICE_CHANNEL(check)) { + goto openchan; + } + + /* if it's an FXS device with a call active and has callwaiting enabled, we allow to open it twice */ + if (check->type == FTDM_CHAN_TYPE_FXS + && check->token_count == 1 + && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING)) { + goto openchan; + } + + /* chan_is_avail API without signaling check */ + if (check->span->signal_type == FTDM_SIGTYPE_NONE) { + if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) || + ftdm_test_flag(check, FTDM_CHANNEL_INUSE) || + ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) || + ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) || + check->state != FTDM_CHANNEL_STATE_DOWN) { + + ftdm_log(FTDM_LOG_ERROR, "channel %d not available to open in span %d\n", chan_id, span_id); + goto done; + } + } else if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) || + ftdm_test_flag(check, FTDM_CHANNEL_INUSE) || + ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) || + ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) || + check->state != FTDM_CHANNEL_STATE_DOWN) { + ftdm_log(FTDM_LOG_ERROR, "channel %d not available to open in span %d\n", chan_id, span_id); + goto done; + }else { + /* channel is ready to open */ + ftdm_log(FTDM_LOG_INFO, "channel %d available to open in span %d\n", chan_id, span_id); + goto openchan; + } + + + /* not available, but still might be available ... */ + calculate_best_rate(check, &best_rated, &best_rate); + if (best_rated) { + goto openchan; + } + + /* channel is unavailable, do not open the channel */ + goto unlockchan; + +openchan: + if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { + status = check->fio->open(check); + if (status == FTDM_SUCCESS) { + ftdm_set_flag(check, FTDM_CHANNEL_OPEN); + } + } else { + status = FTDM_SUCCESS; + } + ftdm_set_flag(check, FTDM_CHANNEL_INUSE); + ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); + *ftdmchan = check; + + /* we've got the channel, do not unlock it */ + goto done; + +unlockchan: + ftdm_channel_unlock(check); + +done: + ftdm_mutex_unlock(globals.mutex); + if (status != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Failed to open channel %d:%d\n", span_id, chan_id); + } + + return status; +} + static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) { ftdm_channel_t *check = NULL; @@ -2007,6 +2131,17 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, return status; } +FT_DECLARE(ftdm_status_t) ftdm_raw_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) +{ + ftdm_status_t status; + status = _ftdm_raw_channel_open(span_id, chan_id, ftdmchan); + if (status == FTDM_SUCCESS) { + ftdm_channel_t *fchan = *ftdmchan; + ftdm_channel_unlock(fchan); + } + return status; +} + FT_DECLARE(uint32_t) ftdm_channel_get_id(const ftdm_channel_t *ftdmchan) { return ftdmchan->chan_id; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index e041e1f0e7..b875388ad8 100755 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1374,6 +1374,8 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group); */ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan); +FT_DECLARE(ftdm_status_t) ftdm_raw_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan); + /*! * \brief Hunts and opens a channel specifying the span id only * diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c index 42a77aba67..5d087298ea 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c @@ -1374,8 +1374,10 @@ switch_status_t handle_mg_subtract_cmd(megaco_profile_t* mg_profile, MgMgcoComma megaco_context_sub_termination(mg_ctxt, term); } - /* release context*/ - megaco_release_context(mg_ctxt); + if ((NULL == mg_ctxt->terminations[0]) && (NULL == mg_ctxt->terminations[1])) { + /* release context*/ + megaco_release_context(mg_ctxt); + } } /************************************************************************************************************************************************************/ diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c index 98b46a9302..44c716152a 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c @@ -102,7 +102,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) if(i && chanmap[0] && chanmap[1]) { startchan = atoi(chanmap[0]); endchan = atoi(chanmap[1]); - for (j = startchan; j < endchan; j++) { + for (j = startchan; j <= endchan; j++) { mg_create_tdm_term(profile, tech, channel_prefix, prefix, j); } } @@ -122,7 +122,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) startchan = atoi(chanmap[i]); endchan = atoi(p); - for (j = startchan; j < endchan; j++) { + for (j = startchan; j <= endchan; j++) { mg_create_tdm_term(profile, tech, channel_prefix, prefix, j); } }