]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_media_gateway now specifies physical channel when opening TDM terminations
authorDavid Yat Sin <dyatsin@sangoma.com>
Tue, 11 Sep 2012 18:45:57 +0000 (14:45 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Tue, 11 Sep 2012 18:45:57 +0000 (14:45 -0400)
libs/freetdm/mod_freetdm/tdm.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/include/freetdm.h

index 0c7657301dc589abf4e2b33491d297b128802db8..0f8b5814c10c1def52da6b3d598ef340c793e46c 100644 (file)
@@ -158,7 +158,7 @@ static ftdm_channel_t *ctdm_get_channel_from_event(switch_event_t *event, ftdm_s
                return NULL;
        }
 
-       return ftdm_span_get_channel(span, chan_id);
+       return ftdm_span_get_channel_ph(span, chan_id);
 }
 
 
@@ -362,7 +362,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_channel_open_ph(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;
     }
index b3266e54f4339e92d1e561d0b62fd0af31761d35..f80ded35b8b60c27fea1a2bb679524631da33368 100644 (file)
@@ -1893,7 +1893,7 @@ done:
        return status;
 }
 
-static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
+static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan, uint8_t physical)
 {
        ftdm_channel_t *check = NULL;
        ftdm_span_t *span = NULL;
@@ -1922,14 +1922,46 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
                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 (physical) { /* Open by physical */
+               ftdm_channel_t *fchan = NULL;
+               ftdm_iterator_t *citer = NULL;
+               ftdm_iterator_t *curr = NULL;
 
-       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;
+               if (chan_id < 1) {
+                       ftdm_log(FTDM_LOG_ERROR, "Invalid physical channel %d to open in span %d\n", chan_id, span_id);
+                       status = FTDM_FAIL;
+                       goto done;
+               }
+
+               citer = ftdm_span_get_chan_iterator(span, NULL);
+               if (!citer) {
+                       status = ENOMEM;
+                       goto done;
+               }
+
+               for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
+                       fchan = ftdm_iterator_current(curr);
+                       if (fchan->physical_chan_id == chan_id) {
+                               check = fchan;
+                               break;
+                       }
+               }
+
+               ftdm_iterator_free(citer);
+               if (!check) {
+                       ftdm_log(FTDM_LOG_CRIT, "Wow, no physical channel %d in span %d\n", chan_id, span_id);
+                       goto done;
+               }
+       } else { /* Open by logical */
+               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);
@@ -2000,7 +2032,18 @@ done:
 FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
 {
        ftdm_status_t status;
-       status = _ftdm_channel_open(span_id, chan_id, ftdmchan);
+       status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 0);
+       if (status == FTDM_SUCCESS) {
+               ftdm_channel_t *fchan = *ftdmchan;
+               ftdm_channel_unlock(fchan);
+       }
+       return status;
+}
+
+FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
+{
+       ftdm_status_t status;
+       status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 1);
        if (status == FTDM_SUCCESS) {
                ftdm_channel_t *fchan = *ftdmchan;
                ftdm_channel_unlock(fchan);
@@ -2377,6 +2420,39 @@ FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint
        return chan;
 }
 
+FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid)
+{
+       ftdm_channel_t *chan = NULL;
+       ftdm_channel_t *fchan = NULL;
+       ftdm_iterator_t *citer = NULL;
+       ftdm_iterator_t *curr = NULL;
+
+       ftdm_mutex_lock(span->mutex);
+       if (chanid == 0) {
+               ftdm_mutex_unlock(span->mutex);
+               return NULL;
+       }
+
+       citer = ftdm_span_get_chan_iterator(span, NULL);
+       if (!citer) {
+               ftdm_mutex_unlock(span->mutex);
+               return NULL;
+       }
+
+       for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
+               fchan = ftdm_iterator_current(curr);
+               if (fchan->physical_chan_id == chanid) {
+                       chan = fchan;
+                       break;
+               }
+       }
+
+       ftdm_iterator_free(citer);
+
+       ftdm_mutex_unlock(span->mutex);
+       return chan;
+}
+
 FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span)
 {
        uint32_t count;
@@ -2673,7 +2749,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, i
                status = _ftdm_channel_open_by_group(hunting->mode_data.group.group_id, 
                                hunting->mode_data.group.direction, caller_data, &fchan);
        } else if (hunting->mode == FTDM_HUNT_CHAN) {
-               status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan);
+               status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan, 0);
        } else {
                ftdm_log(FTDM_LOG_ERROR, "Cannot make outbound call with invalid hunting mode %d\n", hunting->mode);
                return FTDM_EINVAL;
index 6f0ac503718034992bad57f556f30ed12d5771bf..18dfb7605b152d1f82d65bfcb4d3e735afd4e133 100755 (executable)
@@ -1370,7 +1370,7 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group);
  *     Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
  *
  * \param span_id The span id the channel belongs to
- * \param chan_id Channel id of the channel you want to open
+ * \param chan_id Logical channel id of the channel you want to open
  * \param ftdmchan Pointer to store the channel once is open
  *
  * \retval FTDM_SUCCESS success (the channel was found and is available)
@@ -1378,6 +1378,23 @@ 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);
 
+/*! 
+ * \brief Open a channel specifying the span id and physical chan id (required before placing a call on the channel)
+ *
+ * \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel
+ *
+ * \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards
+ *     Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
+ *
+ * \param span_id The span id the channel belongs to
+ * \param chan_id Physical channel id of the channel you want to open
+ * \param ftdmchan Pointer to store the channel once is open
+ *
+ * \retval FTDM_SUCCESS success (the channel was found and is available)
+ * \retval FTDM_FAIL failure (channel was not found or not available)
+ */
+FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan);
+
 /*! 
  * \brief Hunts and opens a channel specifying the span id only
  *
@@ -1759,15 +1776,25 @@ FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span);
 FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
 
 /*! 
- * \brief Return the channel identified by the provided id
+ * \brief Return the channel identified by the provided logical id
  *
  * \param span The span where the channel belongs
- * \param chanid The channel id within the span
+ * \param chanid The logical channel id within the span
  *
  * \return The channel pointer if found, NULL otherwise
  */
 FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint32_t chanid);
 
+/*! 
+ * \brief Return the channel identified by the provided physical id
+ *
+ * \param span The span where the channel belongs
+ * \param chanid The physical channel id within the span
+ *
+ * \return The channel pointer if found, NULL otherwise
+ */
+FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid);
+
 /*! \brief Return the channel count number for the given span */
 FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span);